March 29, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Thursday, 28 March 2013 at 18:24:19 UTC, Timon Gehr wrote: > Yes; DMD is buggy and the specification is insufficient. Currently the meaning of D code as interpreted by DMD may depend on the order the modules are passed to the compiler on the command line. > Can you have a look at http://wiki.dlang.org/DIP31 ? I have written a proposal to specify this, but it does currently not precise/complete enough. |
March 29, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Thursday, 28 March 2013 at 18:24:19 UTC, Timon Gehr wrote: > (...) > Indeed, the above code should not compile. My upcoming D front end currently reports the following after fixing the grammatical mistakes (For now. The error message text should maybe be improved. Ideas welcome.) > > tt.d:2:32: error: declaration of 'x' smells suspiciously fishy > static if (!is(typeof(y))) int x = 1; > ^ > tt.d:1:23: note: this lookup should have succeeded if it was valid > static if (!is(typeof(x))) int y = 1; > ^ > tt.d:1:32: error: declaration of 'y' smells suspiciously fishy > static if (!is(typeof(x))) int y = 1; > ^ > tt.d:2:23: note: this lookup should have succeeded if it was valid > static if (!is(typeof(y))) int x = 1; > ^ Surely it will be fun to work with (though 'this lookup' message is somewhat confusing)! > There are lots of similar analysis order issues without static if. (Luckily, they can be detected well enough conservatively in a quite general way.) The following is a simplified example from my test suite: > > class A{ int string; } > template Mixin(string s){ > mixin("alias "~s~" Mixin;"); > } > class D: Mixin!({D d = new D; return d.foo();}()){ > int foo(int x){ return 2;} > string foo(){ return "A"; } > } > > The problem is of course that 'string' has to be resolved in order to compute the parent of 'D'. However, that parent then changes the meaning of 'string' in the subclass scope. Therefore, the code is meaningless. I am lost here. Are 'int string' in A in and 'int foo(int)' in D relevant? Shouldn't this example fail simply because in order to process the declaration of D the compiler needs to instantiate D in the delegate body? So this would be similar to: template Mixin(bool b : true) { alias Object Mixin; } class D: Mixin!(new D == new D) {} Artur |
March 29, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Zawłocki | On 03/29/2013 12:33 PM, "Artur Zawłocki" <artur.zawlocki@gmail.com>" wrote: > On Thursday, 28 March 2013 at 18:24:19 UTC, Timon Gehr wrote: > >> (...) >> Indeed, the above code should not compile. My upcoming D front end >> currently reports the following after fixing the grammatical mistakes >> (For now. The error message text should maybe be improved. Ideas >> welcome.) >> >> tt.d:2:32: error: declaration of 'x' smells suspiciously fishy >> static if (!is(typeof(y))) int x = 1; >> ^ >> tt.d:1:23: note: this lookup should have succeeded if it was valid >> static if (!is(typeof(x))) int y = 1; >> ^ >> tt.d:1:32: error: declaration of 'y' smells suspiciously fishy >> static if (!is(typeof(x))) int y = 1; >> ^ >> tt.d:2:23: note: this lookup should have succeeded if it was valid >> static if (!is(typeof(y))) int x = 1; >> ^ > > Surely it will be fun to work with (though 'this lookup' message is > somewhat confusing)! > Yes. What would be a better message? >> There are lots of similar analysis order issues without static if. >> (Luckily, they can be detected well enough conservatively in a quite >> general way.) The following is a simplified example from my test suite: >> >> class A{ int string; } >> template Mixin(string s){ >> mixin("alias "~s~" Mixin;"); >> } >> class D: Mixin!({D d = new D; return d.foo();}()){ >> int foo(int x){ return 2;} >> string foo(){ return "A"; } >> } >> >> The problem is of course that 'string' has to be resolved in order to >> compute the parent of 'D'. However, that parent then changes the >> meaning of 'string' in the subclass scope. Therefore, the code is >> meaningless. > > I am lost here. Are 'int string' in A Yes. > in and 'int foo(int)' in D No. > relevant? > Shouldn't this example fail simply because in order to process > the declaration of D the compiler needs to instantiate D in the delegate > body? No, D's parent is not required to be known in order to execute what is in the delegate body. > So this would be similar to: > > template Mixin(bool b : true) { > alias Object Mixin; > } > class D: Mixin!(new D == new D) {} > > This fails because new D == new D is false. (Otherwise it would work.) |
March 29, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 03/29/2013 04:22 AM, deadalnix wrote:
> On Thursday, 28 March 2013 at 18:24:19 UTC, Timon Gehr wrote:
>> Yes; DMD is buggy and the specification is insufficient. Currently the
>> meaning of D code as interpreted by DMD may depend on the order the
>> modules are passed to the compiler on the command line.
>>
>
> Can you have a look at http://wiki.dlang.org/DIP31 ?
>
> I have written a proposal to specify this, but it does currently not
> precise/complete enough.
Poisoning is the right approach. However, the analysis order should be the order of potential dependencies between mixin expressions/static if conditions and potentially generated symbols. In case there is a cycle in the potential dependencies, the symbol lookups occuring in the connected component that appears first in a topological ordering of all connected components of the potential-dependency graph should poison the respective scopes. Analysis can then proceed, because the potential dependencies on the cycle are eliminated.
It is possible that your way of dealing with overloads is fine, however, I'd just have poisoned those overloads that would necessitate revisiting an already taken overload-resolution decision.
|
March 29, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 03/29/2013 03:01 PM, Timon Gehr wrote:
> On 03/29/2013 04:22 AM, deadalnix wrote:
>> On Thursday, 28 March 2013 at 18:24:19 UTC, Timon Gehr wrote:
>>> Yes; DMD is buggy and the specification is insufficient. Currently the
>>> meaning of D code as interpreted by DMD may depend on the order the
>>> modules are passed to the compiler on the command line.
>>>
>>
>> Can you have a look at http://wiki.dlang.org/DIP31 ?
>>
>> I have written a proposal to specify this, but it does currently not
>> precise/complete enough.
>
> Poisoning is the right approach. However, the analysis order should be
> the order of potential dependencies between mixin expressions/static if
> conditions and potentially generated symbols. In case there is a cycle
> in the potential dependencies, the symbol lookups occuring in the
> connected component that appears first in a topological ordering of all
> connected components of the potential-dependency graph should poison the
> respective scopes. Analysis can then proceed, because the potential
> dependencies on the cycle are eliminated.
> ...
I meant to write _strongly_ connected components, obviously.
|
March 29, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Friday, 29 March 2013 at 13:54:03 UTC, Timon Gehr wrote: > On 03/29/2013 12:33 PM, "Artur Zawłocki" <artur.zawlocki@gmail.com>" wrote: >> On Thursday, 28 March 2013 at 18:24:19 UTC, Timon Gehr wrote: >> >>> (...) >>> Indeed, the above code should not compile. My upcoming D front end >>> currently reports the following after fixing the grammatical mistakes >>> (For now. The error message text should maybe be improved. Ideas >>> welcome.) >>> >>> tt.d:2:32: error: declaration of 'x' smells suspiciously fishy >>> static if (!is(typeof(y))) int x = 1; >>> ^ >>> tt.d:1:23: note: this lookup should have succeeded if it was valid >>> static if (!is(typeof(x))) int y = 1; >>> ^ >>> tt.d:1:32: error: declaration of 'y' smells suspiciously fishy >>> static if (!is(typeof(x))) int y = 1; >>> ^ >>> tt.d:2:23: note: this lookup should have succeeded if it was valid >>> static if (!is(typeof(y))) int x = 1; >>> ^ >> >> Surely it will be fun to work with (though 'this lookup' message is >> somewhat confusing)! >> > > Yes. What would be a better message? > I don't know. >>> There are lots of similar analysis order issues without static if. >>> (Luckily, they can be detected well enough conservatively in a quite >>> general way.) The following is a simplified example from my test suite: >>> >>> class A{ int string; } >>> template Mixin(string s){ >>> mixin("alias "~s~" Mixin;"); >>> } >>> class D: Mixin!({D d = new D; return d.foo();}()){ >>> int foo(int x){ return 2;} >>> string foo(){ return "A"; } >>> } >>> >>> The problem is of course that 'string' has to be resolved in order to >>> compute the parent of 'D'. However, that parent then changes the >>> meaning of 'string' in the subclass scope. Therefore, the code is >>> meaningless. >> >> I am lost here. Are 'int string' in A > > Yes. > >> in and 'int foo(int)' in D > > No. > >> relevant? >> Shouldn't this example fail simply because in order to process >> the declaration of D the compiler needs to instantiate D in the delegate >> body? > > No, D's parent is not required to be known in order to execute what is in the delegate body. Knowing the parent of D is not required to create an instance of D? > >> So this would be similar to: >> >> template Mixin(bool b : true) { >> alias Object Mixin; >> } >> class D: Mixin!(new D == new D) {} >> >> > > This fails because new D == new D is false. (Otherwise it would work.) See my comment above. |
March 29, 2013 Re: In what order static if conditions are evaluated? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Zawłocki | On 03/29/2013 03:25 PM, "Artur Zawłocki" <artur.zawlocki@gmail.com>" wrote:
> ...
>
> Knowing the parent of D is not required to create an instance of D?
>...
In this case it is not necessary. The restriction will be introduced later. (I have not implemented super constructor calls yet. They will make it break down, because in general the subclass cannot know that the unknown super class does not define a constructor.)
This is a simpler case that possibly illustrates my actual point better:
class A{ alias int string; }
template Mixin(string s){
mixin("alias "~s~" Mixin;");
}
class B : Mixin!(B.x){
immutable string x = "A";
}
This still crashes DMD.
|
Copyright © 1999-2021 by the D Language Foundation