Last active
February 4, 2020 12:49
-
-
Save alexandrumc/6010b5da9def5957633c17a6675e4924 to your computer and use it in GitHub Desktop.
Dlang Unittest issue: Steven's bug: https://github.com/dlang/dmd/pull/8124#issuecomment-379825973
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TWO ways: 1) dmd importer.d | |
2) dmd -unittest importer.d | |
import importme; // *importme.d* is opened and semantic analysis on *importme.d* begins; | |
// now you should follow the comments from *importme.d* | |
//imports are solved now; semantic analysis continues | |
void main() | |
{ | |
foo(); // instantiate foo() which contains S!int x, so S!int will also be instantiated here. | |
} | |
// semantic analysis is finished | |
/** codegen phase begins: | |
for templates, there's a function inside dtemplate.d that is called `bool needsCodegen()` | |
this function returns true if we should generate code for a template instantiation; | |
inside this function, there's an `if (compiledWithUnittest) {} else {}` block. | |
The else{} branch says: | |
"Prefer instantiations from non-root module, to minimize object code size. | |
If a TemplateInstance is ever instantiated by non-root modules, | |
we do not have to generate code for it, | |
because it will be generated when the non-root module is compiled." | |
for ref: https://github.com/dlang/dmd/blob/master/src/dmd/dtemplate.d#L6179-L6183 | |
This is exactly the case when we run `dmd importer.d`: S!int is instantiated once in importme.d and once in | |
importer.d, as I mentioned above. Since an instance of S!int is found inside importme.d (which is not a root module) | |
there will be no code generation for S!int instantiated in importer.d so the linker failure -- `method` cannot be found. | |
Now let's take the if(compiledWithUnittest) {} branch, which says: | |
"Prefer instantiations from root modules, to maximize link-ability." | |
So if we run `dmd -unittest importer.d` there will be a codegen phase for S!int and there won't be a linker error. | |
*/ | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// semantic analysis begins | |
module importme; | |
struct S(T) | |
{ | |
T t; | |
void method() {} | |
} | |
void baz(S!int) {} // S!int is instantiated here when semantic analysis gets to the parameter of *buz* . | |
// the semantic analysis continues... | |
void foo()() | |
{ | |
S!int x; | |
x.method(); | |
} | |
// semantic analysis done; go back to *importer.d* |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment