Bug 22981 – Another forward reference bug involving a string mixin

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-04-04T07:42:17Z
Last change time
2024-12-13T19:22:00Z
Keywords
pull, rejects-valid
Assigned to
No Owner
Creator
Max Samukha
See also
https://issues.dlang.org/show_bug.cgi?id=23598
Moved to GitHub: dmd#18097 →

Comments

Comment #0 by maxsamukha — 2022-04-04T07:42:17Z
A reduced test case: mixin ("enum E {", S.attr, "}"); struct S { E e; enum attr = "a"; } void main() { } onlineapp.d(7): Error: undefined identifier `E` The test case compiles if the enum is wrapped in a template: template E() { mixin ("enum E {", S.attr, "}"); } struct S { E!() e; enum attr = "a"; }
Comment #1 by maxsamukha — 2022-04-04T07:49:39Z
(In reply to Max Samukha from comment #0) > The test case compiles if the enum is wrapped in a template: However, it doesn't if the template instance is aliased: template E_() { mixin ("enum E_ {", S.attr, "}"); } alias E = E_!(); struct S { E e; enum attr = "a"; } onlineapp.d(12): Error: template instance `onlineapp.E_!()` is used as a type onlineapp.d(8): Error: template instance `onlineapp.E_!()` error instantiating
Comment #2 by maxsamukha — 2022-04-04T07:51:16Z
> However, it does if the template instance is aliased inside the type: template E_() { mixin ("enum E_ {", S.attr, "}"); } struct S { alias E = E_!(); E e; enum attr = "a"; }
Comment #3 by maxsamukha — 2022-04-04T07:59:49Z
(In reply to Max Samukha from comment #2) > > However, it does if the template instance is aliased inside the type: That wasn't supposed to be a quotation
Comment #4 by b2.temp — 2022-04-30T08:28:44Z
I think that the compiler should perform a "pre-dsymbolsem" pass in aggregate decls, that pass would only target `enum` and other `static` declarations. That could kill the fake cycle on `E` and other similar bugs.
Comment #5 by maxsamukha — 2022-04-30T16:04:29Z
(In reply to Basile-z from comment #4) > I think that the compiler should perform a "pre-dsymbolsem" pass in > aggregate decls, that pass would only target `enum` and other `static` > declarations. > > That could kill the fake cycle on `E` and other similar bugs. I am not competent to comment on this. FWIW, attributes, which are conceptually similar to static members, don't have this issue: mixin ("enum E {", __traits(getAttributes, S)[0], "}"); @("a") struct S { E e; } void main() { }
Comment #6 by b2.temp — 2022-04-30T16:15:40Z
(In reply to Max Samukha from comment #5) > I am not competent to comment on this. FWIW, attributes, which are > conceptually similar to static members, don't have this issue: > > mixin ("enum E {", __traits(getAttributes, S)[0], "}"); > > @("a") > struct S > { > E e; > } > > void main() > { > } Nah, attribs have the same problem, it's just that your test case does not reproduce it. For attribs this is more like ``` mixin ("enum E {", __traits(getAttributes, S)[0], "}"); @(S.a) struct S { E e; enum a = "dfgdf"; } void main() { } ``` output is then the same as the original test case, i.e > Error: undefined identifier `E`
Comment #7 by b2.temp — 2022-04-30T16:22:39Z
In `S` the non static member `E e` create a cycle but actually with a pass dedicated to "static members - only" , the internal enum `S.a` would not require `S` semantic to be complete.
Comment #8 by b2.temp — 2022-04-30T16:25:34Z
(In reply to Basile-z from comment #7) > In `S` the non static member `E e` create a cycle but actually with a pass > dedicated to "static members - only" , the internal enum `S.a` would not > require `S` semantic to be complete. reduced more ``` @(S.a) struct S { E e; enum a = "dfgdf"; } ```
Comment #9 by b2.temp — 2022-04-30T16:29:22Z
even better ``` enum E { e1 = S.a } struct S { E e; enum a = "string"; } ``` > /tmp/temp_7F3BFB9249F0.d:6:14: Error: cannot implicitly convert expression `"string"` of type `string` to `int`
Comment #10 by b2.temp — 2022-04-30T16:36:50Z
looks like enum being integral is assumed too early ;) for example if you change the infered type of S.a ``` enum E { e1 = S.a } struct S { E e; enum a = 123; // vs enum a = "string" } ``` no problems anymore
Comment #11 by maxsamukha — 2022-04-30T17:27:44Z
(In reply to Basile-z from comment #7) > In `S` the non static member `E e` create a cycle but actually with a pass > dedicated to "static members - only" , the internal enum `S.a` would not > require `S` semantic to be complete. Yes, I understand this. I meant UDAs are similar *in concept* to static members - they are things associated with the type's name but are not related to values of that type. Before D acquired proper UDAs, we used to emulate them with static fields and introspection.
Comment #12 by maxsamukha — 2022-04-30T17:31:15Z
(In reply to Basile-z from comment #10) > looks like enum being integral is assumed too early ;) > > for example if you change the infered type of S.a > > ``` > enum E { e1 = S.a } > > struct S > { > E e; > enum a = 123; // vs enum a = "string" > } > ``` > > no problems anymore Seems to be unrelated to the original issue. In the original test case, the enum is integral - it is the member's name that is mixed-in.
Comment #13 by b2.temp — 2022-04-30T23:37:59Z
alright, I'll open another one ;)
Comment #14 by maxsamukha — 2022-05-01T07:49:57Z
(In reply to Basile-z from comment #13) > alright, I'll open another one ;) Great, thanks!
Comment #15 by dlang-bot — 2023-01-16T01:26:08Z
@ibuclaw created dlang/dmd pull request #14826 "dmd.aggregate: Define importAll override for AggregateDeclaration" fixing this issue: - fix Issue 22981 - Another forward reference bug involving a string mixin https://github.com/dlang/dmd/pull/14826
Comment #16 by robert.schadek — 2024-12-13T19:22:00Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18097 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB