diff --git a/src/dmd/access.d b/src/dmd/access.d index daeb87d3bf52..be55ae56aa94 100644 --- a/src/dmd/access.d +++ b/src/dmd/access.d @@ -547,8 +547,8 @@ public Dsymbol mostVisibleOverload(Dsymbol s) { if (!s.isOverloadable()) return s; - Dsymbol next, fstart = s, mostVisible = s, previous = null; - AliasDeclaration adOrig = null; + + Dsymbol next, fstart = s, mostVisible = s; for (; s; s = next) { // void func() {} @@ -571,7 +571,8 @@ public Dsymbol mostVisibleOverload(Dsymbol s) // private void name(int) {} else if (auto ad = s.isAliasDeclaration()) { - assert(ad.isOverloadable, "Non overloadable Aliasee in overload list"); + assert(ad.isOverloadable || ad.type && ad.type.ty == Terror, + "Non overloadable Aliasee in overload list"); // Yet unresolved aliases store overloads in overnext. if (ad.semanticRun < PASS.semanticdone) next = ad.overnext; @@ -593,13 +594,7 @@ public Dsymbol mostVisibleOverload(Dsymbol s) */ auto aliasee = ad.toAlias(); if (aliasee.isFuncAliasDeclaration || aliasee.isOverDeclaration) - { - if(ad.toChars() == aliasee.toChars()) - { - adOrig = ad; - } next = aliasee; - } else { /* A simple alias can be at the end of a function or template overload chain. @@ -619,15 +614,6 @@ public Dsymbol mostVisibleOverload(Dsymbol s) if (next && mostVisible.prot().isMoreRestrictiveThan(next.prot())) mostVisible = next; - - // fixes https://issues.dlang.org/show_bug.cgi?id=18480 - if(next && next == previous) - { - assert(adOrig); - error(adOrig.loc, "`alias X = X` not allowed (with `X = %s`)", adOrig.toChars()); - return next; - } - previous = s; } return mostVisible; } diff --git a/src/dmd/dsymbolsem.d b/src/dmd/dsymbolsem.d index 56801119b83a..b0102bb2334c 100644 --- a/src/dmd/dsymbolsem.d +++ b/src/dmd/dsymbolsem.d @@ -5492,6 +5492,19 @@ void aliasSemantic(AliasDeclaration ds, Scope* sc) global.gag = 0; } + // https://issues.dlang.org/show_bug.cgi?id=18480 + // Detect `alias sym = sym;` to prevent creating loops in overload overnext lists. + // Selective imports are allowed to alias to the same name `import mod : sym=sym`. + if (ds.type.ty == Tident && !ds._import) + { + auto tident = cast(TypeIdentifier)ds.type; + if (tident.ident is ds.ident && !tident.idents.dim) + { + error(ds.loc, "`alias %s = %s;` cannot alias itself, use a qualified name to create an overload set", + ds.ident.toChars(), tident.ident.toChars()); + ds.type = Type.terror; + } + } /* This section is needed because Type.resolve() will: * const x = 3; * alias y = x; diff --git a/test/fail_compilation/test18480.d b/test/fail_compilation/test18480.d index 45ab8b397624..49f306ba9884 100644 --- a/test/fail_compilation/test18480.d +++ b/test/fail_compilation/test18480.d @@ -2,7 +2,7 @@ /* TEST_OUTPUT: --- -fail_compilation/imports/test18480a.d(2): Error: `alias X = X` not allowed (with `X = TestTemplate`) +fail_compilation/imports/test18480a.d(2): Error: `alias TestTemplate = TestTemplate;` cannot alias itself, use a qualified name to create an overload set --- https://issues.dlang.org/show_bug.cgi?id=18480 */