Bug 20661 – opEquals not recognized for AA key (take two)

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-03-10T11:19:46Z
Last change time
2021-03-06T03:40:53Z
Keywords
pull, rejects-valid, safe
Assigned to
No Owner
Creator
ag0aep6g
Blocks
20655

Comments

Comment #0 by ag0aep6g — 2020-03-10T11:19:46Z
This is a slight variation of issue 20136, adding `@safe` and a pointer. Should compile: ---- class Context { size_t[const(Key)] aa; /* Error: AA key type Key does not have bool opEquals(ref const Key) const */ bool* checkAll; } struct Key { Context context; bool opEquals(ref const Key other) @safe const { auto c = context.checkAll; return true; } } ----
Comment #1 by moonlightsentinel — 2020-07-06T14:20:15Z
This seems to be a regression that was fixed for some time: Up to 2.064 : Success and no output 2.065.0: Failure with output: onlineapp.d(3): Error: associative array key type const(Key) does not have 'const int opCmp(ref const Key)' member function 2.066.0 to 2.079.1: Success and no output Since 2.080.1: Failure with output: onlineapp.d(3): Error: AA key type `Key` does not have `bool opEquals(ref const Key) const` The second regression was caused by https://github.com/dlang/dmd/pull/7982
Comment #2 by razvan.nitu1305 — 2021-02-18T16:20:49Z
This is very problematic. When `size_t[const(Key)] aa;` is analyzed it jumps to analyzing `Key` to see if it defines an opEquals that could be called in this scenario. During the semantic analysis of Key, xopEquals is also generated: if we have a `const bool opEquals(ref const S s);` that's fine, no need to do anything else, but opEquals might also be templated. In the latter situation an _xopEquals is generated that simply returns whether `this == param`. Because of that the body of xopEquals needs to be analyzed: to see if the template opEquals is callable in this fashion. If it is, then the AA key is valid, if not then it is assumed that the opEquals provided is not correct. This is the actual issue: for non-templated opEquals analyzing the body eagerly results in forward reference issues. That is what is happening here: we proceed to analyze Key, we identify the opEquals and we eagerly start analyzing it's body. When we get to the `auto c = context.checkAll;` line we need to analyze context, therefore we need to analyze `class Context` (because `checkAll` might be an overlapped pointer field) => forward reference error. I'm not sure how this can be fixed.
Comment #3 by dlang-bot — 2021-02-18T16:41:03Z
@RazvanN7 created dlang/dmd pull request #12207 "Fix Issue 20661 - opEquals not recognized for AA key (take two)" fixing this issue: - Fix Issue 20661 - opEquals not recognized for AA key (take two) https://github.com/dlang/dmd/pull/12207
Comment #4 by dlang-bot — 2021-03-02T13:01:55Z
dlang/dmd pull request #12207 "Fix Issue 20661 - opEquals not recognized for AA key (take two)" was merged into stable: - f5ad633f4ade8ccd1eb4193b6e054e369e5ec10e by RazvanN7: Fix Issue 20661 - opEquals not recognized for AA key (take two) https://github.com/dlang/dmd/pull/12207
Comment #5 by dlang-bot — 2021-03-06T03:40:53Z
dlang/dmd pull request #12253 "merge stable" was merged into master: - 096ff00fc324b7005bc569dbf311ea63551a1389 by RazvanN7: Fix Issue 20661 - opEquals not recognized for AA key (take two) https://github.com/dlang/dmd/pull/12253