D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 20488 - AA.length in multiple modules causes opDispatch failure
Summary: AA.length in multiple modules causes opDispatch failure
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P1 regression
Assignee: No Owner
URL:
Keywords: pull
Depends on:
Blocks:
 
Reported: 2020-01-08 09:09 UTC by Andrej Mitrovic
Modified: 2020-02-07 04:15 UTC (History)
3 users (show)

See Also:


Attachments
test case (1.91 KB, application/zip)
2020-01-08 09:09 UTC, Andrej Mitrovic
Details

Note You need to log in before you can comment on or make changes to this issue.
Description Andrej Mitrovic 2020-01-08 09:09:08 UTC
Created attachment 1771 [details]
test case

This is the weirdest bug I have ever filed. I couldn't reduce it further, and I reduced it to this stage manually because Dustmite took way too long.

It seems that whatever I touch, the bug will fail to reproduce. For example, changing a hashmap into an array in the offending line makes the bug disappear.

The attachment has the source files and a simple run.sh script.

Tested on MacOS Mojave & DMD v2.089.1
Comment 1 Simen Kjaeraas 2020-01-08 13:53:49 UTC
Further reduced:

foo.d:
///////////////////////////
struct Foo {
    bool[int] aa;
    void fun() {
        int i = aa.length;
    }
}
///////////////////////////

bar.d:
///////////////////////////
struct Bar {
    int[int] aa;
    void fun() {
        this.f(aa.length);
    }
    void opDispatch (string s, Args...) (Args args) {
    }
}
///////////////////////////

Compile with 'dmd foo bar', and you get
  bar.d(4): Error: no property f for type bar.Bar

If the two AA types are identical it compiles.

Adding 'int j = (int[int]).init.length;' to S1.fun() does make it compile, but only if it's before the 'int i = ...' line (wat).
Comment 2 moonlightsentinel 2020-01-08 16:51:43 UTC
Digger blames https://github.com/dlang/dmd/pull/8584
Comment 3 FeepingCreature 2020-01-09 07:39:12 UTC
Further reduction:

struct Bar {
    void opDispatch(string s, Args...) (Args args) {
    }
    void fun() {
        (bool[int]).init.length;
        this.f((int[int]).init.length);
    }
}

Looking into it.
Comment 4 Dlang Bot 2020-01-09 08:05:12 UTC
@FeepingCreature created dlang/dmd pull request #10718 "Fix issue 20488: opDispatch: copy call expression before checking for semantically valid parameters" fixing this issue:

- opDispatch: copy call expression before checking for semantically valid parameters.
  This may avoid accidentally resolving future occurrences to the wrong type, not sure.
  Fixes issue 20488.

https://github.com/dlang/dmd/pull/10718
Comment 5 Dlang Bot 2020-01-13 03:52:30 UTC
dlang/dmd pull request #10718 "Fix issue 20488: opDispatch: copy call expression before checking for semantically valid parameters" was merged into stable:

- 78e214e75b464a2703115890ba6d3c60384c668b by Mathis Beer:
  opDispatch: only validate parameters if we've already seen indication of a semantic failure.
  This avoids double evaluation of parameter semantic in some situations.
  Fixes issue 20488.

https://github.com/dlang/dmd/pull/10718
Comment 6 Dlang Bot 2020-02-07 04:15:19 UTC
dlang/dmd pull request #10753 "Merge remote-tracking branch 'upstream/stable' into merge_stable" was merged into master:

- 65237abf9323434f5072a3f8b95a0824655522a8 by Mathis Beer:
  opDispatch: only validate parameters if we've already seen indication of a semantic failure.
  This avoids double evaluation of parameter semantic in some situations.
  Fixes issue 20488.

https://github.com/dlang/dmd/pull/10753