Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
September 05, 2013 Re: finding errors with templates without instantiating them | ||||
---|---|---|---|---|
| ||||
On 9/5/13, Timothee Cour <thelastmammoth@gmail.com> wrote:
> So would it be possible to detect such kind of errors (ie CT error regardless of template params) without having to instantiate the template?
How would you semantically analyze the following without instantiating it?:
-----
template T(X)
{
enum T = X.foo;
}
-----
Note how the above can be both valid and invalid based on the template parameters:
-----
class C
{
enum int foo = 1;
}
class D
{
int foo = 1;
}
void main()
{
enum foo = T!C; // ok
enum foo = T!D; // fail
}
-----
There's so much context-dependent semantics in a template that eager semantic analysis of templates which haven't been instantiated would be limited to work for only very simple templates. So I don't think it would be worth even trying to analyze without instantiating.
Also, I think it would likely be extremely hard to implement in the
compiler, and could possible lead to false-positives (compiles) or
false-negatives (doesn't compile) cases.
And finally, compile times would literally explode with eager semantic analysis.
|
September 05, 2013 Re: finding errors with templates without instantiating them | ||||
---|---|---|---|---|
| ||||
On Thu, Sep 05, 2013 at 10:14:01AM -0700, Timothee Cour wrote: > Currently D will compile templated code that is syntactically correct > but semantically always incorrect (ie regardless of template > parameters), eg the following: > regardless of T, b is not in scope and hence this template cannot be > instantiated without CT error. > > So would it be possible to detect such kind of errors (ie CT error regardless of template params) without having to instantiate the template? Sure this could be detected with unittests in a perfect world but that gives an additional level of safety. > > Likewise with template constraints, where the code wouldn't be able to compile given template constraints, but this case is harder. > > ---- > void fun(T)(){ > int a=b; > } > > void main(){ > //fun!double; //uncomment for CT error > } > ---- I don't know enough about DMD internals to be able to say for sure, but at least in theory, this should be doable by checking if each identifier either refers to a template parameter (e.g., T.a, T.b, in which case we let it pass, since we wouldn't know until instantiation time whether or not that reference will actually succeed), or to an identifier in the containing scopes (which may be themselves template parameters). If it refers to neither, reject it as invalid. The idea being, given some identifier x.y in the template body, x.y must either be defined either in the global scope, in the containing lexical scope, or x is a template parameter and y refers to an as-yet unknown member of that parameter. If none of this holds, then no matter what template parameters are given, the template can't possibly compile. I'd say file an enhancement request for this. T -- Unix was not designed to stop people from doing stupid things, because that would also stop them from doing clever things. -- Doug Gwyn |
September 05, 2013 Re: finding errors with templates without instantiating them | ||||
---|---|---|---|---|
| ||||
On Thu, Sep 05, 2013 at 07:41:14PM +0200, Andrej Mitrovic wrote: > On 9/5/13, Timothee Cour <thelastmammoth@gmail.com> wrote: > > So would it be possible to detect such kind of errors (ie CT error regardless of template params) without having to instantiate the template? > > How would you semantically analyze the following without instantiating it?: > > ----- > template T(X) > { > enum T = X.foo; > } > ----- > > Note how the above can be both valid and invalid based on the template parameters: In this case, we temporarily accept it until instantiation time. [...] > There's so much context-dependent semantics in a template that eager semantic analysis of templates which haven't been instantiated would be limited to work for only very simple templates. So I don't think it would be worth even trying to analyze without instantiating. It's actually not that hard. Consider if the template body refers to identifier X, but X is neither a template parameter, nor is X defined in any of the containing scopes of the template. Then no matter how you instantiate the template, it can't possibly work. So it can be rejected before instantiation is even attempted. > Also, I think it would likely be extremely hard to implement in the > compiler, and could possible lead to false-positives (compiles) or > false-negatives (doesn't compile) cases. > > And finally, compile times would literally explode with eager semantic analysis. My proposal requires only lookup of identifiers in the containing lexical scopes and a trivial check for whether it refers to a template parameter (or a member thereof). It's a one-pass algorithm. It can't be *that* bad. T -- My program has no bugs! Only undocumented features... |
September 05, 2013 Re: finding errors with templates without instantiating them | ||||
---|---|---|---|---|
| ||||
Attachments:
| On Thu, Sep 5, 2013 at 10:41 AM, Andrej Mitrovic <andrej.mitrovich@gmail.com > wrote: > On 9/5/13, Timothee Cour <thelastmammoth@gmail.com> wrote: > > So would it be possible to detect such kind of errors (ie CT error regardless of template params) without having to instantiate the > template? > > How would you semantically analyze the following without instantiating it?: > > ----- > template T(X) > { > enum T = X.foo; > } > ----- > > Note how the above can be both valid and invalid based on the template parameters: > > ----- > class C > { > enum int foo = 1; > } > > class D > { > int foo = 1; > } > > void main() > { > enum foo = T!C; // ok > enum foo = T!D; // fail > } > ----- > I specifically said I was only considering semantically always incorrect code (ie regardless of template parameters), so that example doesn't fly. > > There's so much context-dependent semantics in a template that eager semantic analysis of templates which haven't been instantiated would be limited to work for only very simple templates. So I don't think it would be worth even trying to analyze without instantiating. > > Also, I think it would likely be extremely hard to implement in the > compiler, and could possible lead to false-positives (compiles) or > false-negatives (doesn't compile) cases. > > And finally, compile times would literally explode with eager semantic analysis. > As HS Teoh explained, this could actually be done at very little cost for symbol scope resolution. It is done once per template. |
September 11, 2013 Re: finding errors with templates without instantiating them | ||||
---|---|---|---|---|
| ||||
On Thu, Sep 05, 2013 at 10:14:01AM -0700, Timothee Cour wrote: > Currently D will compile templated code that is syntactically correct > but semantically always incorrect (ie regardless of template > parameters), eg the following: > regardless of T, b is not in scope and hence this template cannot be > instantiated without CT error. > > So would it be possible to detect such kind of errors (ie CT error regardless of template params) without having to instantiate the template? Sure this could be detected with unittests in a perfect world but that gives an additional level of safety. > > Likewise with template constraints, where the code wouldn't be able to compile given template constraints, but this case is harder. > > ---- > void fun(T)(){ > int a=b; > } > > void main(){ > //fun!double; //uncomment for CT error > } > ---- This thread has been dormant for a while. Has an enhancement request been filed yet? T -- Chance favours the prepared mind. -- Louis Pasteur |
Copyright © 1999-2021 by the D Language Foundation