Proposal: prettify template constraints failure messages

Jonathan M Davis jmdavisProg at gmx.com
Fri Jan 4 12:10:54 PST 2013


On Friday, January 04, 2013 18:16:44 Dmitry Olshansky wrote:
> I think we should just introduce an "else" or "default" constraint. For
> example:
> 
> void chain(Ranges...)(Ranges rs) default
> {
> static assert("std.range.chain requires: Any number of Input Ranges
> all having a common type among types of their elements.");
> }
> 
> 
> ie, the default is used only if all template constraints fail.
> 
> /end of message
> 
> Which could be a more coherent way to solve it. The problem I see is
> that messages are disconnected from signatures of failed templates (that
> can change later and then message is easily out sync).

Doing that wouldn't be all that different from using your suggestion with a 
single point of entry (e.g. using an outer template or wrapper function with a 
simplified template constraint with the separate functions having the more 
detailed constraints required to separate them). And with your suggestion, you 
could give each candidate an informative message if you wanted multiple points 
of entry (though I'd favor listing the message in addition to the constraint 
rather than instead of like you proposed).

> Either way what about just removing the constraints on the second error
> message here:
> 
> bug.d(11): Error: template std.range.chain does not match any function
> template declaration. Candidates are:
> std/range.d(2018): std.range.chain(Ranges...)(Ranges rs) if
> (Ranges.length > 0 && allSatisfy!(isInputRange, staticMap!(Unqual,
> Ranges)) && !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual,
> Ranges))) == void))
> 
> That was the first, it list candidates. It's relatively new thing, nice
> to have it.
> 
> bug.d(11): Error: template std.range.chain(Ranges...)(Ranges rs) if
> (Ranges.length > 0 && allSatisfy!(isInputRange, staticMap!(Unqual,
> Ranges)) && !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual,
> Ranges))) == void)) cannot deduce template function from argument types
> !()(MapResult!(__lambda2, Foo[]),string)
> 
> The second need not to realist constraints here, they are obvious from
> above, what needed is the last line - template arguments. So just make it:
> 
> bug.d(11): Error: template std.range.chain(Ranges...)(Ranges rs) cannot
> deduce template function from argument types !()(MapResult!(__lambda2,
> Foo[]),string)
> 
> Bugzilla worthy?

Duplicate errors are definitely bugzilla worthy, and duplicated information 
within errors is bugzilla worthy - _especially_ in template error messages. 
We want them to be informative, but let's not make them longer than they need 
to be. It's the error messages that generally scare people away from 
templates.

- Jonathan M Davis


More information about the Digitalmars-d mailing list