Bug 23414 – Import order emits "Error: no size because of forward references"

Status
NEW
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2022-10-14T15:31:16Z
Last change time
2024-12-13T19:25:01Z
Keywords
industry
Assigned to
No Owner
Creator
Richard (Rikki) Andrew Cattermole
Moved to GitHub: dmd#18129 →

Comments

Comment #0 by alphaglosined — 2022-10-14T15:31:16Z
ldc2 1.30.0-beta1 which is dmd v2.100.0. Windows MSVC 64bit. Depending on import order I am getting a lot of: "Error: no size because of forward references". Works: ```d import sidero.base.text.unicode.builder; import sidero.base.text.unicode.readonly; ``` Doesn't: ```d import sidero.base.text.unicode.readonly; import sidero.base.text.unicode.builder; ``` Both modules in question import each other but neither depends on the other for their size of any type (but are used for method parameters). https://github.com/Project-Sidero/basic_memory/commit/bf45c72c3840bf57ad33acfacfaa1d87f6c831a9#diff-cf3c4ca35e19d963f077c9d3af6f4bbb806d6123715dc22a1b1cb53fea609859R5 I am using a lot of scope and scope + ref in parameters, so this could be related to https://issues.dlang.org/show_bug.cgi?id=21667
Comment #1 by alphaglosined — 2022-11-25T15:22:55Z
I have since removed all inter-dependency imports between the modules and forced them to import the package module (which in turn publically imports them all). That has fixed it.
Comment #2 by bugzilla — 2024-01-23T03:50:24Z
It would be nice if this could be reduced to the two modules, and then removing everything that is not necessary to trigger the error.
Comment #3 by alphaglosined — 2024-01-23T04:09:00Z
It probably isn't limited to two modules. There is a possibility of it being upwards of nine modules. Unfortunately, dustmite doesn't like this project, it gets stuck and requires a lot of help, and minimizing isn't a fast thing to do, I had to do it a few times around the time of this bug report.
Comment #4 by bugzilla — 2024-01-26T21:54:03Z
I would like to fix this, once a smallish test case can be devised. But keep in mind some things cannot be fixed. At least the compiler issues an error for those cases. An example: struct S { static if (S.sizeof == 0) { int x; } } It's impossible for the compiler to resolve it. While the example looks trivial and ridiculous, sometimes these cases are hidden behind a thicket of complex templates. When module A imports module B, and B also imports A, there's always the potential for an ordering issue. I try to solve as many as possible, but they cannot always be fixed. These are commonly the result of two declarations with a mutual dependence. A solution that works is to refactor A and B so that the mutually dependent portions are extracted and placed into module C. Then, A and B import C.
Comment #5 by alphaglosined — 2024-01-26T22:00:30Z
My assumption has been that this isn't fixable, but worth documenting. Each module has one public declaration a struct. Which in turn uses similar structs in other modules. ASCII, UTF-8, UTF-16, UTF-32 each having a read only slice and a builder. Then there are the raw slices too. Not much you can do to break that up, except for using something like implicitly constructed sum types at the declaration level to break up the dependency. Right now the package module is ensuring the imports are all in the right order and every module goes through that which works. Not ideal, however, I haven't had any further issues so not a bad workaround.
Comment #6 by maxsamukha — 2024-01-29T19:18:44Z
(In reply to Walter Bright from comment #4) > struct S > { > static if (S.sizeof == 0) > { > int x; > } > } > > It's impossible for the compiler to resolve it. While the example looks > trivial and ridiculous, sometimes these cases are hidden behind a thicket of > complex templates. > While there is often a real circular dependence, D still fails in many cases when there is not, like: ``` struct S(alias self) { alias Outer = __traits(parent, self); ref Outer outer() => *cast(Outer*)(cast(ubyte*)&this - self.offsetof); } struct S2 { S!s s; } ``` Error: circular reference to variable `a.S2.s It would be immensely cool if that worked.
Comment #7 by robert.schadek — 2024-12-13T19:25:01Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18129 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB