www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 24528] New: Add offending member to "no size because of

https://issues.dlang.org/show_bug.cgi?id=24528

          Issue ID: 24528
           Summary: Add offending member to "no size because of forward
                    reference" error
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: johanengelen weka.io

I don't have a testcase (I hit it on a complex codebase), but improvement is
needed for the "no size because of forward reference" error reported by
`AggregateDeclaration.determineSize`
(https://github.com/dlang/dmd/blob/4414c2aeaa968ed0ce638a8162d3254dbf2ee2f5/compiler/src/dmd/aggregate.d#L237).

The error now reads:
`Error: struct `A` no size because of forward reference`
It is unclear what the forward reference is. Is there a forward reference
inside struct `A`? Is struct `A` referenced elsewhere (if yes, where?) which
constitutes the forward reference?

What helped me find the fwd reference quickly in the code, is hacking the
compiler to add extra diagnostics. All paths that lead to the error (`goto
LFail` or the "fallthrough" before `Lfail`) should store which struct member
field is causing trouble, such that it can be reported upon error.

1. `determineSize`
https://github.com/dlang/dmd/blob/4414c2aeaa968ed0ce638a8162d3254dbf2ee2f5/compiler/src/dmd/aggregate.d#L218
2. `determineFields`
https://github.com/dlang/dmd/blob/4414c2aeaa968ed0ce638a8162d3254dbf2ee2f5/compiler/src/dmd/aggregate.d#L224
3. `finalizeSize`
https://github.com/dlang/dmd/blob/4414c2aeaa968ed0ce638a8162d3254dbf2ee2f5/compiler/src/dmd/aggregate.d#L226

In my case, I added extra error output inside `finalizeSize`
(https://github.com/dlang/dmd/blob/4414c2aeaa968ed0ce638a8162d3254dbf2ee2f5/compiler/src/dmd/dstruct.d#L297)
which got me to the actual code problem.

Perhaps change this code:
```
        for (size_t i = 0; i < members.length; i++)
        {
            Dsymbol s = (*members)[i];
            s.setFieldOffset(this, &fieldState, isunion);
        }
        if (type.ty == Terror)
        {
            .error(loc, "finalizeSize err");
            errors = true;
            return;
        }
```

to this:

```
        for (size_t i = 0; i < members.length; i++)
        {
            Dsymbol s = (*members)[i];
            s.setFieldOffset(this, &fieldState, isunion);
            if (type.ty == Terror)
            {
                error(loc, "error on member `%s`", s.toPrettyChars);
                errors = true;
                return;
            }
        }
```

--
Apr 29