A proposal for better template constraint error reporting.
Simen Kjaeraas
simen.kjaras at gmail.com
Wed Oct 26 11:25:28 PDT 2011
On Wed, 26 Oct 2011 17:34:09 +0200, Gor Gyolchanyan
<gor.f.gyolchanyan at gmail.com> wrote:
> This idea is still raw, so don't expect me to be able to answer to all
> your question. This is just a general direction in which we could move
> to improve the error reports, that occur when templates can't be
> instantiated.
> What if one could add ddoc comments to parts of the constraint, so
> that both ddoc generator could output them in a neat way and the
> compiler would use them to report errors:
>
> /// Define a state machine transition types.
> template transition(ActionType)
> if
> {
> /// Must be a callable type.
> isCallable!ActionType &&
> /// Must return a state.
> is(ReturnType!ActionType : State) &&
> /// Must take exactly two parameters.
> ParameterTypeTuple!(ActionType).length == 2 &&
> /// The first parameter must be an event.
> is(ParameterTypeTuple!(ActionType)[0] : Event) &&
> /// The second parameter must be a state.
> is(ParameterTypeTuple!(ActionType)[1] : State);
> )
> {
> alias ParameterTypeTuple!(ActionType)[1] FromState;
> alias ReturnType!ActionType ToState;
> alias ParameterTypeTuple!(ActionType)[0] Event;
> }
>
> The ddoc comments, preceding parts of template constraints would be
> used to specify why exactly did the template fail to instantiate, for
> example:
>
> Error: Cannot instantiate template demo01.transition(ActionType)
> because "Must return a state." constraint is not satisfied.
> Writing specifications of the template with all different version of
> incorrect constraints just to static assert(0) it is too tedious to do
> every time.
As always with this type of proposal, the case of multiple non-matching
templates seems not to have been considered. Given:
template foo(T) if (
/// T must be an integer.
is(T : long)) {}
template foo(T) if (
/// T must be a string of some kind.
isSomeString!T) {}
template foo(T) if (
/// T must be an input range.
isInputRange!T) {}
Which template's error messages should be shown? All of them, preceded
by the template definition? e.g:
bar.d(17): Error: template instance foo!(float) does not match any
template declaration
bar.d(5): template instance foo(T) if (is(T : long)) error instantiating
bar.d(6): T must be an integer.
bar.d(7): template instance foo(T) if (isSomeString!T) error
instantiating
bar.d(8): T must be a string of some kind.
bar.d(79): template instance foo(T) if (isInputRange!T) error
instantiating
bar.d(10): T must be an input range.
I was gonna say this would bring problems with more complex constraints,
but after a brief look through Phobos, I have seen that most (~90%) of
constraints seem to be a single condition, with 2 making up the
majority of the remaining, and only one place have I found a constraint
with 3 conditions.
The reason for this is that it's often factored out to a separate
template or function, which helps some, but would perhaps reduce the
helpfulness of the error messages here proposed.
--
Simen
More information about the Digitalmars-d
mailing list