Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
August 28, 2006 Proposal: Treat static assert in template as instantiation error | ||||
---|---|---|---|---|
| ||||
Currently, in dmd, if there is an error instantiating a template, the compiler will quite helpfully print out a traceback to the original point of instantiation:
[temp_test.d]
import std.stdio;
void func1(T) (T t) {
writefln(t + 1); // Line 4
}
void func2(T) (T t) {
func1(t); // Line 8
}
void main() {
func2("Hello".dup); // Line 12
}
$ dmd temp_test
temp_test.d(4): incompatible types for ((t) + (1)): 'char[]' and 'int'
temp_test.d(8): template instance temp_test.func1!(char[]) error instantiating
temp_test.d(12): template instance temp_test.func2!(char[]) error instantiating
It is then pretty clear what the problem is. (You can't pass a char[] to func2.)
It has become a common idiom with D's templates to test a template parameter against a series of static if/else static if statements, and if none of them match, to set a static assert(false). For example:
[temp_test2.d]
import std.stdio;
void func1(T) (T t) {
static if (is(T == int)) {
writefln(t + 1);
} else static if (is(T == char[])) {
writefln(t ~ "1");
} else static assert(false, "I don't know how to handle this!");
}
void func2(T) (T t) {
func1(t);
}
void main() {
func2("Hello".dup);
func2(25.5);
}
$ dmd temp_test2
temp_test2.d(8): static assert (0) is false, "I don't know how to handle this!"
By throwing a static assert, the compiler aborts compilation immediately, and the traceback information is lost. It is no longer obvious where the template was originally instantiated from.
I propose that if a static assert is thrown from within a template, that it be treated as a failed template instantiation. This would (the hope is) result in the instantiation traceback being printed out. It would allow coders to explicitly cause their templates to fail in a way that is informative: Users would get both the message in the static assert as well as the traceback information. I am sure this would be a great boon to anyone writing or using template code.
--
Kirk McDonald
Pyd: Wrapping Python with D
http://pyd.dsource.org
|
August 29, 2006 Re: Proposal: Treat static assert in template as instantiation error | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald | I agree 100% I was actually planning to post about that myself but you were quicker :) -- Tomasz Stachowiak |
August 29, 2006 Re: Proposal: Treat static assert in template as instantiation error | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald | On Mon, 28 Aug 2006 14:25:27 -0700, Kirk McDonald wrote: > I propose that if a static assert is thrown from within a template, that it be treated as a failed template instantiation. This would (the hope is) result in the instantiation traceback being printed out. It would allow coders to explicitly cause their templates to fail in a way that is informative: Users would get both the message in the static assert as well as the traceback information. I am sure this would be a great boon to anyone writing or using template code. Amen to that! A great suggestion. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 29/08/2006 11:01:32 AM |
August 29, 2006 Re: Proposal: Treat static assert in template as instantiation error | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald |
On Mon, 28 Aug 2006 23:25:27 +0200, Kirk McDonald <kirklin.mcdonald@gmail.com> wrote:
> It has become a common idiom with D's templates to test a template parameter against a series of static if/else static if statements, and if none of them match, to set a static assert(false). For example:
>
> [temp_test2.d]
> import std.stdio;
>
> void func1(T) (T t) {
> static if (is(T == int)) {
> writefln(t + 1);
> } else static if (is(T == char[])) {
> writefln(t ~ "1");
> } else static assert(false, "I don't know how to handle this!");
> }
What about
[temp_test3.d]
import std.stdio;
void func1(T : int) (T t) {
writefln(t + 1);
}
void func1(T : char[]) (T t) {
writefln(t ~ "1");
}
void func2(T) (T t) {
func1!(typeof(T))(t); // line 12
}
void main() {
func2("Hello".dup);
func2(25.5); // line 17
}
Here the compiler output is
test.d(12): template instance func1!(double) does not match any template declaration
test.d(12): template instance 'func1!(double)' is not a variable
test.d(12): function expected before (), not func1!(double) of type int
test.d(17): template instance test.func2!(double) error instantiating
However, maybe I'm missing the point here, since there are probably things you can do with static if that won't work through specializations. Also, it could be redundant if you want to specialize for all numeric types for example. Finally, this circumvents the 'specialized parameters can't be implicitly deducted' rule, which likely has some ambiguity rationale.
Cheers,
Christian
|
August 29, 2006 Re: Proposal: Treat static assert in template as instantiation error | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald | "Kirk McDonald" <kirklin.mcdonald@gmail.com> wrote in message news:ecvn03$1nm5$1@digitaldaemon.com... > By throwing a static assert, the compiler aborts compilation immediately, and the traceback information is lost. It is no longer obvious where the template was originally instantiated from. > > I propose that if a static assert is thrown from within a template, that it be treated as a failed template instantiation. This would (the hope is) result in the instantiation traceback being printed out. It would allow coders to explicitly cause their templates to fail in a way that is informative: Users would get both the message in the static assert as well as the traceback information. I am sure this would be a great boon to anyone writing or using template code. vote++ |
August 29, 2006 Re: Proposal: Treat static assert in template as instantiation error | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kirk McDonald | Kirk McDonald wrote: > Currently, in dmd, if there is an error instantiating a template, the compiler will quite helpfully print out a traceback to the original point of instantiation: > It is then pretty clear what the problem is. (You can't pass a char[] to [snip] > By throwing a static assert, the compiler aborts compilation immediately, and the traceback information is lost. It is no longer obvious where the template was originally instantiated from. I was also going to post on the same issue. The 'sudden death' static assert was my idea, but we still need to know how it was triggered. One problem with a naive traceback is that if you're not careful, you get the same kind of verbal diarrhea that C++ suffers from (and those error messages really are excrement). In particular, once a static assert has failed, *all* that should be printed is the traceback, not any new error messages. As a minimum, a failed static assert should print the file and line number that the outermost template was originally instantiated from; that would probably be adequate for users of template libraries. A proper traceback would be even better, except for recursive template instantiations. But I think that it's important that once an assert has failed, no new errors should be generated ('error instantiating' is OK, but nothing else), and the compiler should not attempt to compile any further templates. > I propose that if a static assert is thrown from within a template, that it be treated as a failed template instantiation. This would (the hope is) result in the instantiation traceback being printed out. It would allow coders to explicitly cause their templates to fail in a way that is informative: Users would get both the message in the static assert as well as the traceback information. I am sure this would be a great boon to anyone writing or using template code. |
August 29, 2006 Re: Proposal: Treat static assert in template as instantiation error | ||||
---|---|---|---|---|
| ||||
Posted in reply to Don Clugston | Don Clugston wrote:
> Kirk McDonald wrote:
>
>> Currently, in dmd, if there is an error instantiating a template, the compiler will quite helpfully print out a traceback to the original point of instantiation:
>> It is then pretty clear what the problem is. (You can't pass a char[] to
>
> [snip]
>
>> By throwing a static assert, the compiler aborts compilation immediately, and the traceback information is lost. It is no longer obvious where the template was originally instantiated from.
>
>
> I was also going to post on the same issue. The 'sudden death' static assert was my idea, but we still need to know how it was triggered.
> One problem with a naive traceback is that if you're not careful, you get the same kind of verbal diarrhea that C++ suffers from (and those error messages really are excrement). In particular, once a static assert has failed, *all* that should be printed is the traceback, not any new error messages.
>
> As a minimum, a failed static assert should print the file and line number that the outermost template was originally instantiated from; that would probably be adequate for users of template libraries. A proper traceback would be even better, except for recursive template instantiations. But I think that it's important that once an assert has failed, no new errors should be generated ('error instantiating' is OK, but nothing else), and the compiler should not attempt to compile any further templates.
>
What about
template foo(int i)
{ // v---
static assert(i>0, "value "~itoa!(i) ~" !> 0");
}
|
August 29, 2006 Re: Proposal: Treat static assert in template as instantiation error | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | BCS wrote:
> Don Clugston wrote:
>> Kirk McDonald wrote:
>>
>>> Currently, in dmd, if there is an error instantiating a template, the compiler will quite helpfully print out a traceback to the original point of instantiation:
>>> It is then pretty clear what the problem is. (You can't pass a char[] to
>>
>> [snip]
>>
>>> By throwing a static assert, the compiler aborts compilation immediately, and the traceback information is lost. It is no longer obvious where the template was originally instantiated from.
>>
>>
>> I was also going to post on the same issue. The 'sudden death' static assert was my idea, but we still need to know how it was triggered.
>> One problem with a naive traceback is that if you're not careful, you get the same kind of verbal diarrhea that C++ suffers from (and those error messages really are excrement). In particular, once a static assert has failed, *all* that should be printed is the traceback, not any new error messages.
>>
>> As a minimum, a failed static assert should print the file and line number that the outermost template was originally instantiated from; that would probably be adequate for users of template libraries. A proper traceback would be even better, except for recursive template instantiations. But I think that it's important that once an assert has failed, no new errors should be generated ('error instantiating' is OK, but nothing else), and the compiler should not attempt to compile any further templates.
>>
>
> What about
>
> template foo(int i)
> { // v---
> static assert(i>0, "value "~itoa!(i) ~" !> 0");
> }
I believe that is evaluated before the static assert triggers.
|
Copyright © 1999-2021 by the D Language Foundation