[Issue 17548] New: Forward reference error with scope function parameters
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Sat Jun 24 17:30:29 PDT 2017
https://issues.dlang.org/show_bug.cgi?id=17548
Issue ID: 17548
Summary: Forward reference error with scope function parameters
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: major
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: syniurge at gmail.com
//---------------------fwdref1.d--------------
// import fwdref2;
struct S1 {
void foo(scope S2 arg) {}
int myField;
}
enum cnst = 4321;
import fwdref2;
//---------------------fwdref2.d--------------
import fwdref1;
struct S2 {
void bar(int arg = .fwdref1.cnst) {}
S1 s;
}
//--------------------------------------------
$ dmd fwdref1.d
fwdref2.d(3): Error: struct fwdref2.S2 has forward references
The error disappears if "scope" is removed from fwdref1.d, or if the first dot
in ".fwdref1.cnst" i.e the module scope operator is removed.
What seems to happen:
- in TypeFunction.semantic for S1.foo, the right hand of
if (fparam.storageClass & STCscope && !fparam.type.hasPointers())
gets evaluated.
- hasPointers() calls .size() on S2 which then calls .determineSize()
- S2 having _scope set, .determineSize() calls StructDeclaration.semantic() on
S2
- the default argument of S2.bar() gets semantic'd(), and DsymbolExp.resolve()
calls semantic() on the fwdref2 module
- since fwdref2.semanticRun is still at PASSinit, Module.semantic() calls
semantic() for each of its members, including S2
- S2 doesn't have _scope set anymore, scx remains null, so
StructDeclaration.semantic() ends with:
else if (symtab && !scx)
{
semanticRun = PASSsemanticdone;
return;
}
(while we're clearly not done, the first call is ongoing)
- back to the first semantic() call on S2, after determineFields() it then
checks that for every field with a struct type, the struct symbol is at
PASSsemanticdone. But since S1 is still at PASSsemantic, it hits:
_scope = scx ? scx : sc.copy();
_scope.setNoFree();
_scope._module.addDeferredSemantic(this);
//printf("\tdeferring %s\n", toChars());
return;
- so now S2 has _scope set yet is at PASSsemanticdone. The deferred semantic()
call returns immediately, and then semantic2() greets S2 with our error:
if (_scope)
{
error("has forward references");
return;
}
Sorry if this a little too detailed.
I'm not entirely sure what the proper fix is. Is Module.semantic() always
supposed to get called before any semantic-ing of its members? (this would have
prevented "." from disrupting StructDeclaration.semantic()'s assumptions)
Placing "import fwdref2;" on top also produces an error, but a different one:
"struct fwdref2.S2 no size because of forward reference".
--
More information about the Digitalmars-d-bugs
mailing list