Difference between "can call" and "can compile"
snarwin at gmail.com
Mon Sep 7 16:12:02 UTC 2020
On Monday, 7 September 2020 at 14:57:24 UTC, Steven Schveighoffer
> I get a compilation error. But it's not in foo, it's in bar. It
> Error: template instance onlineapp.bar!(foo) does not match
> template declaration bar(alias x)()
> with x = foo(T)(T v)
> must satisfy the following constraint:
> __traits(compiles, x(1))
> The problem is, if the intention is for it to pass, but the
> implementation is bugged, the error message is useless. If the
> thing I'm passing is a type with 200 LOC, and there's an error
> buried in there somewhere, the compiler is telling me
> "somewhere in this, it doesn't work". And sometimes those
> function signatures and their constraints are hairy themselves.
> My usual steps taken at this point are to extract the
> constraint template and actually try to call the functions in
> the constraints with that type, and see what fails. This is
> somewhat annoying, and sometimes difficult to do based on where
> the code that implements the constraint actually is, and where
> the code actually calling it is (I may have to duplicate a lot
> of stuff).
The tedious-but-reliable way to handle this is to recompile with
`-verrors=spec`, search the output for the original error
message, and then scroll up until you find what you're looking
for in the speculative errors. The only issue is that you have to
wade through a lot of useless chaff to find the information you
actually care about.
IMO the best way to make this easier would be to have the
compiler provide a "stack trace" of speculative errors for each
failed constraint whenever a template fails to instantiate--maybe
behind a switch (`-verrors=constraints`) to avoid clogging up the
output in the common case.
This has the advantage of working for *all* indirect errors like
this, not just ones involving IFTI. To give a concrete example,
`-verrors=constraints` would have helped me a lot with the
problems I had to debug in SumType's copy constructors recently
, whereas __traits(canCall) would have been completely useless.
More information about the Digitalmars-d