Propagating Errors
FeepingCreature
feepingcreature at gmail.com
Wed Mar 6 12:48:08 UTC 2019
On Monday, 4 March 2019 at 15:47:12 UTC, H. S. Teoh wrote:
> On Mon, Mar 04, 2019 at 02:50:11PM +0000, Adam D. Ruppe via
> Digitalmars-d wrote: [...]
>> How many template constraint messages would be nice if it just
>> said "missing popFront" instead of 40 lines of overload failed
>> spam?
> [...]
>
> This is why I'm starting to think sig constraints are not the
> genius idea they first appeared to be. The basic problem is
> that when you write a sig constraint, you're basically saying
> "I only accept template arguments if they don't cause an error,
> otherwise it's not my problem and somebody else can pick up the
> tab", whereas the essence of user-friendly error-reporting is
> "I accept everything that looks like it ought to work, and if
> something breaks, I'll tell you why it didn't work".
>
Personally, I think the problem comes down to this: we have no
way of propagating errors from inside template constraints to
the user.
I think the way to go is instead of returning `false`, have
__traits(compiles) (which is really the core source of these
difficulties) return an "error object" that evaluates to false,
but also encodes additional information about the problem,
recursively.
Propagate this through short-circuiting - ErrorObject && bla =
true, bla && ErrorObject = ErrorObject, etc.
The compiler can then pick up on the fact that an error object
was the reason why a template constraint failed to give a highly
informative error message.
For instance:
struct Foo
{
void bar() { }
}
enum hasFooCall(T) = __traits(compiles, T.init.foo());
void callFoo(T)(T t)
if (hasFooCall!T)
{
t.foo();
}
callFoo!Foo(Foo.init);
then errors with
Error: template onlineapp.callFoo cannot deduce function from
argument types !()(Foo), candidates are:
onlineapp.callFoo(T)(T t) if (hasFooCall!T)
Failed because:
hasFooCall(Foo): no property foo for type Foo
More information about the Digitalmars-d
mailing list