I have just completed my first port of a small codebase (Xpact-core), an Eiffel XML parser project) with EiffelStudio 25.12, compiling under complete void-safety for the first time. The whole process went smoothly until one last error that took far longer to resolve than it should have, and I think it is worth sharing as a cautionary tale for anyone attempting the same migration, especially newcomers to the language.
The compiler reported:
My first reaction was that this must be an ECF configuration problem. I have a precompile clause referencing base-safe.ecf, and I spent a long time checking precompile paths, comparing my ECF against a colleague's, and verifying that base and its precompile spec agreed on capability settings. None of that was the actual problem, though along the way I did find a genuine issue worth a separate report: the base-safe.ecf precompile spec on Linux declares no void_safety element at all in its own capability block, despite its name. That is misleading and worth ISE's attention, but it turned out to be a red herring with respect to this particular error. Removing the precompile clause entirely and compiling base from source did not make the error go away.
The actual cause had nothing to do with ECF configuration. My class looked like this:
I had renamed the inherited make to make_sized, which is a perfectly ordinary thing to do, and exported only make_sized for creation. What I had not anticipated is that ARRAYED_LIST itself still contains an old, obsolete routine, new_filled_list, deprecated since 2018, which internally does create Result.make (n) on a like Current return type. So long as a descendant exports a creation procedure named make, this resolves fine. The moment a descendant renames it away, as I had, the polymorphic creation call inside new_filled_list (reached indirectly through duplicate) becomes invalid, and under void-safe creation-validity checking, that is a hard compile error, not a warning.
The fix was to re-export make alongside make_sized:
Nothing in the compiler's error message pointed anywhere near this. The error names new_filled_list, a routine I never call, marked obsolete since 2018, buried in ARRAYED_LIST. There is no hint that the actual fix is three inheritance levels away, in my own class's create clause, for a reason that has nothing to do with anything I had written directly. I have twenty five years with this language, and I needed AI assistance to walk back from the reported error to the actual cause. Without that, I would have spent considerably longer chasing ECF files and precompile settings, as I in fact did before getting to the real explanation.
I understand and agree with the underlying reasoning once it was explained to me. Void-safety has to reject a creation call that cannot be statically guaranteed valid on every possible descendant type, and renaming away the conventionally-named creation procedure is exactly the kind of thing that breaks that guarantee. The design is sound. But the diagnostic experience is not, and I think this is exactly the sort of thing that would put a newcomer off the language entirely. A beginner encountering this would have no realistic path from the reported error to the fix, since the error appears to implicate kernel code rather than their own class.
Two concrete things I think are worth raising with ISE: