December 07, 2023
https://issues.dlang.org/show_bug.cgi?id=24273

          Issue ID: 24273
           Summary: Circular reference error flagged in valid code
           Product: D
           Version: D2
          Hardware: x86
                OS: Windows
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: bmqawsed4@gmail.com

// 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.
}

--