Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
December 12, 2019 [Issue 20443] Case where code compiles depending on order of declaration | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20443 Daniel X <redapple82570@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |redapple82570@gmail.com --- Comment #1 from Daniel X <redapple82570@gmail.com> --- further reduced, thanks to Paul Backus (author of 'sumtype' who generously looked into this issue for us) --- struct SumType(T) { import std.traits: isCopyable; static if (!isCopyable!T) @disable this(this); } struct CallbackType1 { bool[Class1] func; // changing to Class1[] compiles OK } // moving Class1 above CallbackType1 compiles OK class Class1 { SumType!CallbackType1 _callback; this(SumType!CallbackType1 callback) { // commenting out this ctor compiles OK _callback = callback; } } -- |
December 12, 2019 [Issue 20443] Case where code compiles depending on order of declaration | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20443 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla@digitalmars.com --- Comment #3 from Walter Bright <bugzilla@digitalmars.com> --- (In reply to Daniel X from comment #1) > import std.traits: isCopyable; Test cases are much better if they don't import libraries (which can be very large). It's also undesirable to have Phobos dependencies in the test suite. -- |
December 12, 2019 [Issue 20443] Case where code compiles depending on order of declaration | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20443 --- Comment #4 from Walter Bright <bugzilla@digitalmars.com> --- https://github.com/pbackus/sumtype/issues/35#issuecomment-563452054 reproduced here for convenience: ------------------------------ Here's my best attempt at an explanation: During semantic analysis of CallbackType1, the forward reference to Class1 triggers on-demand semantic analysis of Class1, which in turn triggers on-demand semantic analysis of SumType!CallbackType1. Normally, this would trigger on-demand analysis of CallbackType1, but the compiler notices it's already started analyzing CallbackType1 and terminates the recursion. While analyzing SumType!CallbackType1, the compiler evaluates isCopyable!CallbackType1. The source code for isCopyable looks like this: enum isCopyable(S) = is(typeof( { S foo = S.init; S copy = foo; } )); When the lambda inside isCopyable attempts to declare an instance of CallbackType1 as a local variable, it fails, because semantic analysis of CallbackType1 is still in progress and its size is not yet known. You can verify this by copy & pasting the lambda above into the reduced version of SumType, before the static if statement. Doing so will produce the following error: Error: struct `onlineapp.CallbackType1` no size because of forward reference Because of this error, compilation of the lambda fails, and isCopyable!CallbackType1 evaluates to false. Swapping the order of the declarations fixes the issue because it changes DMD's semantic-analysis "call stack" from this: CallbackType1 → Class1 → SumType!CallbackType1 to this: Class1 → SumType!CallbackType1 → CallbackType1 As long as SumType!CallbackType1 is encountered before CallbackType1, DMD is able to finish analyzing CallbackType1 before it evaluates isCopyable!CallbackType1, and thus does not encounter the error described above. Fixing this in DMD is likely to be quite difficult. However, it may be possible to find a workaround for isCopyable that allows it to work with incomplete types. -- |
December 13, 2019 [Issue 20443] Case where code compiles depending on order of declaration | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20443 --- Comment #5 from Daniel X <redapple82570@gmail.com> --- (In reply to Walter Bright from comment #3) > Test cases are much better if they don't import libraries Gotcha. Updated for convenience: ------ enum isCopyable(S) = is(typeof( { S foo = S.init; S copy = foo; } )); struct SumType(T) { static if (!isCopyable!T) @disable this(this); } struct CallbackType1 { bool[Class1] func; // changing to Class1[] compiles OK } // moving Class1 above CallbackType1 compiles OK class Class1 { SumType!CallbackType1 _callback; this(SumType!CallbackType1 callback) { // commenting out this ctor compiles OK _callback = callback; } } -- |
September 23, 2022 [Issue 20443] Case where code compiles depending on order of declaration | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20443 Tomoya Tanjo <ttanjo@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ttanjo@gmail.com --- Comment #6 from Tomoya Tanjo <ttanjo@gmail.com> --- I have a similar issue as reported in the issue 22184. run.dlang.io: https://run.dlang.io/is/VZtiPO ```dlang class A { static if (isHashable!B) {} } class B { static if (isHashable!C) {} } class C { static if (isHashable!B && isHashable!int) {} } enum isHashable(T) = __traits(compiles, () { T.init; } ); void main(){} ``` I confirmed it does not work with dmd 2.100.2. It works when the order of declaration is `C`, `A`, and `B`. -- |
Copyright © 1999-2021 by the D Language Foundation