diff --git a/src/ddmd/expressionsem.d b/src/ddmd/expressionsem.d index 145c0b83e62c..86bf6f9f57cb 100644 --- a/src/ddmd/expressionsem.d +++ b/src/ddmd/expressionsem.d @@ -1353,6 +1353,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor // try one last attempt by checking whether the 'wthis' object supports // dynamic dispatching via opDispatch. // This is done by rewriting this expression as wthis.ident. + // The innermost with() scope of the hierarchy to satisfy the condition + // above wins. + // https://issues.dlang.org/show_bug.cgi?id=6400 for (Scope* sc2 = sc; sc2; sc2 = sc2.enclosing) { if (!sc2.scopesym) @@ -1372,7 +1375,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } } - break; } } diff --git a/test/compilable/b6400.d b/test/compilable/b6400.d deleted file mode 100644 index 2c71107e9131..000000000000 --- a/test/compilable/b6400.d +++ /dev/null @@ -1,37 +0,0 @@ -/* TEST_OUTPUT: ---- -Foo -Bar ---- -*/ -class Foo -{ - void opDispatch(string name)() { pragma(msg, "Foo"); } -} -class Bar -{ - void opDispatch(string name)() { pragma(msg, "Bar"); } -} -class Baz -{ -} - -void main() -{ - auto foo = new Foo; - auto bar = new Bar; - auto baz = new Baz; - - with (foo) - { - f0(); - with (bar) - { - f1(); - } - with (baz) - { - static assert(!__traits(compiles, f2())); - } - } -} diff --git a/test/runnable/b6400.d b/test/runnable/b6400.d new file mode 100644 index 000000000000..8b1018400f2b --- /dev/null +++ b/test/runnable/b6400.d @@ -0,0 +1,69 @@ +/* TEST_OUTPUT: +--- +Foo +Bar +Foo +Bar +Bar +Foo +Bar +--- +*/ + +// https://issues.dlang.org/show_bug.cgi?id=6400 + +enum int base(string name) = 10 * (name[$-1] - '0'); +struct Foo { int opDispatch(string name)() { pragma(msg, "Foo"); return base!name + 1; } } +struct Bar { int opDispatch(string name)() { pragma(msg, "Bar"); return base!name + 2; } } +struct Baz { } + +void main() +{ + assert(test()); + static assert(test()); +} + +bool test() +{ + auto foo = new Foo; + auto bar = new Bar; + auto baz = new Baz; + + with (foo) + { + assert(f1() == 11); + with (baz) assert(f1() == 11); + with (bar) + { + assert(f2() == 22); + with (baz) assert(f2() == 22); + with (foo) + { + assert(f3() == 31); + with (baz) assert(f3() == 31); + with (bar) + { + assert(f4() == 42); + with (baz) assert(f4() == 42); + with (baz) + { + assert(f5() == 52); + with (baz) assert(f5() == 52); + } + with (foo) + { + assert(f6() == 61); + with (baz) assert(f6() == 61); + } + with (bar) + { + assert(f7() == 72); + with (baz) assert(f7() == 72); + } + } + } + } + } + + return true; +}