Bug 24273 – Circular reference error flagged in valid code

Status
NEW
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2023-12-07T16:58:15Z
Last change time
2024-12-13T19:32:06Z
Assigned to
No Owner
Creator
bmqawsed4
Moved to GitHub: dmd#20367 →

Comments

Comment #0 by bmqawsed4 — 2023-12-07T16:58:15Z
// The code below is believed valid, but fails compilation with a circular // reference error. // If the string 'XVar' in mxnAdd is replaced with another string valid for a // variable (I used 'Pld'), in all the places marked 'Here', // the code compiles and runs ok. // I don't support the double-use of the same name (cropped up by accident) // but the code does seem unambiguous (if confusing), and does not // seem to break scope rules. string mxnAdd()(string strName) { return `(typeof(` ~ strName ~ `) XVar) { // Here import core.stdc.stdlib : malloc; struct Mst { typeof(` ~ strName ~ `) XVar; // Here int I1; } Mst* MstPtr; MstPtr = cast(Mst*)(malloc(Mst.sizeof)); if (MstPtr is null) { return null; } else { } MstPtr.XVar = XVar; // Here twice MstPtr.I1 = 1; return &MstPtr.XVar; // Here }(` ~ strName ~ `)`; } void main() { // Compile-time. // Establish simple variables: int IntFld1; int IntFld2; // Define a structure: struct X { int Fld1; int Fld2; } // Establish a structure variable: X XVar; // Establish a pointer to the structure: X* XPtr; // Execution-time. // Load variables: IntFld1 = 3; IntFld2 = 4; // Load the structure variable members: XVar.Fld1 = IntFld1; XVar.Fld2 = IntFld2; // Now execute the command: XPtr = mixin(mxnAdd("XVar")); // Now check the results: assert(XPtr !is null); // Returned pointer non-null, // so shows new datastructure added. assert(XPtr.Fld1 == 3); // Shows new datastructure holds original data item. assert(XPtr.Fld2 == 4); // Shows new datastructure holds original data item. }
Comment #1 by dkorpel — 2023-12-07T17:14:33Z
Reduced example: ```D int XVar; struct Mst { typeof(XVar) XVar; } ``` The issue seems that `typeof(XVar)` is resolved after adding `XVar` to the symbol table of `Mst`. I wonder if that's done deliberately to make something else work.
Comment #2 by dfj1esp02 — 2023-12-08T19:40:55Z
The problem usually happens as: alias int XVar; struct Mst { XVar XVar; } As you can see there's an ambiguity who is who. Usually it's possible to disambiguate with FQN: struct Mst { .XVar XVar; } Stack variables have no FQN, so give them a different name alias XVar XVar2; struct Mst { typeof(XVar2) XVar; }
Comment #3 by bmqawsed4 — 2023-12-09T17:18:09Z
(In reply to anonymous4 from comment #2) > The problem usually happens as: > > alias int XVar; > struct Mst > { > XVar XVar; > } > > As you can see there's an ambiguity who is who. > Usually it's possible to disambiguate with FQN: > > struct Mst > { > .XVar XVar; > } > > Stack variables have no FQN, so give them a different name > > alias XVar XVar2; > struct Mst > { > typeof(XVar2) XVar; > } Unfortunately I do not see any ambiguity in my original code. It _is_ confusing (the situation of the same name being used both in the main function and the sub-function was an accident, not intentional). But I cannot see what rule of D has been broken. To me, if nothing else, D's scope rules should have stopped any problems.
Comment #4 by robert.schadek — 2024-12-13T19:32:06Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/20367 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB