diff --git a/compiler/src/dmd/declaration.d b/compiler/src/dmd/declaration.d index 2abfe3fbb57a..ca332a891250 100644 --- a/compiler/src/dmd/declaration.d +++ b/compiler/src/dmd/declaration.d @@ -449,132 +449,6 @@ extern (C++) final class AliasDeclaration : Declaration return sa; } - override bool overloadInsert(Dsymbol s) - { - //printf("[%s] AliasDeclaration::overloadInsert('%s') s = %s %s @ [%s]\n", - // loc.toChars(), toChars(), s.kind(), s.toChars(), s.loc.toChars()); - - /** Aliases aren't overloadable themselves, but if their Aliasee is - * overloadable they are converted to an overloadable Alias (either - * FuncAliasDeclaration or OverDeclaration). - * - * This is done by moving the Aliasee into such an overloadable alias - * which is then used to replace the existing Aliasee. The original - * Alias (_this_) remains a useless shell. - * - * This is a horrible mess. It was probably done to avoid replacing - * existing AST nodes and references, but it needs a major - * simplification b/c it's too complex to maintain. - * - * A simpler approach might be to merge any colliding symbols into a - * simple Overload class (an array) and then later have that resolve - * all collisions. - */ - if (semanticRun >= PASS.semanticdone) - { - /* Semantic analysis is already finished, and the aliased entity - * is not overloadable. - */ - if (type) - { - /* - If type has been resolved already we could - still be inserting an alias from an import. - - If we are handling an alias then pretend - it was inserting and return true, if not then - false since we didn't even pretend to insert something. - */ - return this._import && this.equals(s); - } - - // https://issues.dlang.org/show_bug.cgi?id=23865 - // only insert if the symbol can be part of a set - const s1 = s.toAlias(); - const isInsertCandidate = s1.isFuncDeclaration() || s1.isOverDeclaration() || s1.isTemplateDeclaration(); - - /* When s is added in member scope by static if, mixin("code") or others, - * aliassym is determined already. See the case in: test/compilable/test61.d - */ - auto sa = aliassym.toAlias(); - - if (auto td = s.toAlias().isTemplateDeclaration()) - s = td.funcroot ? td.funcroot : td; - - if (auto fd = sa.isFuncDeclaration()) - { - auto fa = new FuncAliasDeclaration(ident, fd); - fa.visibility = visibility; - fa.parent = parent; - aliassym = fa; - if (isInsertCandidate) - return aliassym.overloadInsert(s); - } - if (auto td = sa.isTemplateDeclaration()) - { - auto od = new OverDeclaration(ident, td.funcroot ? td.funcroot : td); - od.visibility = visibility; - od.parent = parent; - aliassym = od; - if (isInsertCandidate) - return aliassym.overloadInsert(s); - } - if (auto od = sa.isOverDeclaration()) - { - if (sa.ident != ident || sa.parent != parent) - { - od = new OverDeclaration(ident, od); - od.visibility = visibility; - od.parent = parent; - aliassym = od; - } - if (isInsertCandidate) - return od.overloadInsert(s); - } - if (auto os = sa.isOverloadSet()) - { - if (sa.ident != ident || sa.parent != parent) - { - os = new OverloadSet(ident, os); - // TODO: visibility is lost here b/c OverloadSets have no visibility attribute - // Might no be a practical issue, b/c the code below fails to resolve the overload anyhow. - // ---- - // module os1; - // import a, b; - // private alias merged = foo; // private alias to overload set of a.foo and b.foo - // ---- - // module os2; - // import a, b; - // public alias merged = bar; // public alias to overload set of a.bar and b.bar - // ---- - // module bug; - // import os1, os2; - // void test() { merged(123); } // should only look at os2.merged - // - // os.visibility = visibility; - os.parent = parent; - aliassym = os; - } - if (isInsertCandidate) - { - os.push(s); - return true; - } - } - return false; - } - - /* Don't know yet what the aliased symbol is, so assume it can - * be overloaded and check later for correctness. - */ - if (overnext) - return overnext.overloadInsert(s); - if (s is this) - return true; - overnext = s; - return true; - } - override const(char)* kind() const { return "alias"; @@ -639,17 +513,6 @@ extern (C++) final class OverDeclaration : Declaration return this.aliassym == s; } - override bool overloadInsert(Dsymbol s) - { - //printf("OverDeclaration::overloadInsert('%s') aliassym = %p, overnext = %p\n", s.toChars(), aliassym, overnext); - if (overnext) - return overnext.overloadInsert(s); - if (s == this) - return true; - overnext = s; - return true; - } - override bool isOverloadable() const { return true; diff --git a/compiler/src/dmd/declaration.h b/compiler/src/dmd/declaration.h index 56d915c2bdaa..f31d0363e02a 100644 --- a/compiler/src/dmd/declaration.h +++ b/compiler/src/dmd/declaration.h @@ -200,7 +200,6 @@ class AliasDeclaration final : public Declaration static AliasDeclaration *create(Loc loc, Identifier *id, Type *type); AliasDeclaration *syntaxCopy(Dsymbol *) override; - bool overloadInsert(Dsymbol *s) override; const char *kind() const override; Type *getType() override; bool isOverloadable() const override; @@ -218,7 +217,6 @@ class OverDeclaration final : public Declaration const char *kind() const override; bool equals(const RootObject * const o) const override; - bool overloadInsert(Dsymbol *s) override; Dsymbol *isUnique(); bool isOverloadable() const override; @@ -699,7 +697,6 @@ class FuncDeclaration : public Declaration Expressions *fdensureParams(Expressions *fdep); bool equals(const RootObject * const o) const override final; - bool overloadInsert(Dsymbol *s) override; bool inUnittest(); LabelDsymbol *searchLabel(Identifier *ident, Loc loc); const char *toPrettyChars(bool QualifyTypes = false) override; @@ -787,7 +784,6 @@ class PostBlitDeclaration final : public FuncDeclaration bool isVirtual() const override; bool addPreInvariant() override; bool addPostInvariant() override; - bool overloadInsert(Dsymbol *s) override; void accept(Visitor *v) override { v->visit(this); } }; @@ -800,7 +796,6 @@ class DtorDeclaration final : public FuncDeclaration bool isVirtual() const override; bool addPreInvariant() override; bool addPostInvariant() override; - bool overloadInsert(Dsymbol *s) override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/compiler/src/dmd/dimport.d b/compiler/src/dmd/dimport.d index 66810cb35fdb..e634081e86fe 100644 --- a/compiler/src/dmd/dimport.d +++ b/compiler/src/dmd/dimport.d @@ -141,19 +141,6 @@ extern (C++) final class Import : Dsymbol scopesym.addAccessiblePackage(mod, visibility); // d } - override bool overloadInsert(Dsymbol s) - { - /* Allow multiple imports with the same package base, but disallow - * alias collisions - * https://issues.dlang.org/show_bug.cgi?id=5412 - */ - assert(ident && ident == s.ident); - if (aliasId) - return false; - const imp = s.isImport(); - return imp && !imp.aliasId; - } - override void accept(Visitor v) { v.visit(this); diff --git a/compiler/src/dmd/dsymbol.d b/compiler/src/dmd/dsymbol.d index 4b69a4aa0755..4248a6a18f16 100644 --- a/compiler/src/dmd/dsymbol.d +++ b/compiler/src/dmd/dsymbol.d @@ -677,12 +677,6 @@ extern (C++) class Dsymbol : ASTNode return "symbol"; } - bool overloadInsert(Dsymbol s) - { - //printf("Dsymbol::overloadInsert('%s')\n", s.toChars()); - return false; - } - /********************************* * Returns: * SIZE_INVALID when the size cannot be determined diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index 2d40657d3922..786ce4401fd2 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -98,6 +98,251 @@ void dsymbolSemantic(Dsymbol dsym, Scope* sc) dsym.accept(v); } +private bool aliasoOverloadInsert(AliasDeclaration ad, Dsymbol s) +{ + //printf("[%s] AliasDeclaration::overloadInsert('%s') s = %s %s @ [%s]\n", + // loc.toChars(), toChars(), s.kind(), s.toChars(), s.loc.toChars()); + + /** Aliases aren't overloadable themselves, but if their Aliasee is + * overloadable they are converted to an overloadable Alias (either + * FuncAliasDeclaration or OverDeclaration). + * + * This is done by moving the Aliasee into such an overloadable alias + * which is then used to replace the existing Aliasee. The original + * Alias (_this_) remains a useless shell. + * + * This is a horrible mess. It was probably done to avoid replacing + * existing AST nodes and references, but it needs a major + * simplification b/c it's too complex to maintain. + * + * A simpler approach might be to merge any colliding symbols into a + * simple Overload class (an array) and then later have that resolve + * all collisions. + */ + if (ad.semanticRun < PASS.semanticdone) + { + /* Don't know yet what the aliased symbol is, so assume it can + * be overloaded and check later for correctness. + */ + if (ad.overnext) + return ad.overnext.overloadInsert(s); + if (s is ad) + return true; + ad.overnext = s; + return true; + } + + /* Semantic analysis is already finished, and the aliased entity + * is not overloadable. + */ + if (ad.type) + { + /* + If type has been resolved already we could + still be inserting an alias from an import. + + If we are handling an alias then pretend + it was inserting and return true, if not then + false since we didn't even pretend to insert something. + */ + return ad._import && ad.equals(s); + } + + // https://issues.dlang.org/show_bug.cgi?id=23865 + // only insert if the symbol can be part of a set + const s1 = s.toAlias(); + const isInsertCandidate = s1.isFuncDeclaration() || s1.isOverDeclaration() || s1.isTemplateDeclaration(); + + /* When s is added in member scope by static if, mixin("code") or others, + * aliassym is determined already. See the case in: test/compilable/test61.d + */ + auto sa = ad.aliassym.toAlias(); + + if (auto td = s.toAlias().isTemplateDeclaration()) + s = td.funcroot ? td.funcroot : td; + + if (auto fd = sa.isFuncDeclaration()) + { + auto fa = new FuncAliasDeclaration(ad.ident, fd); + fa.visibility = ad.visibility; + fa.parent = ad.parent; + ad.aliassym = fa; + if (isInsertCandidate) + return ad.aliassym.overloadInsert(s); + } + if (auto td = sa.isTemplateDeclaration()) + { + auto od = new OverDeclaration(ad.ident, td.funcroot ? td.funcroot : td); + od.visibility = ad.visibility; + od.parent = ad.parent; + ad.aliassym = od; + if (isInsertCandidate) + return ad.aliassym.overloadInsert(s); + } + if (auto od = sa.isOverDeclaration()) + { + if (sa.ident != ad.ident || sa.parent != ad.parent) + { + od = new OverDeclaration(ad.ident, od); + od.visibility = ad.visibility; + od.parent = ad.parent; + ad.aliassym = od; + } + if (isInsertCandidate) + return od.overloadInsert(s); + } + if (auto os = sa.isOverloadSet()) + { + if (sa.ident != ad.ident || sa.parent != ad.parent) + { + os = new OverloadSet(ad.ident, os); + // TODO: visibility is lost here b/c OverloadSets have no visibility attribute + // Might no be a practical issue, b/c the code below fails to resolve the overload anyhow. + // ---- + // module os1; + // import a, b; + // private alias merged = foo; // private alias to overload set of a.foo and b.foo + // ---- + // module os2; + // import a, b; + // public alias merged = bar; // public alias to overload set of a.bar and b.bar + // ---- + // module bug; + // import os1, os2; + // void test() { merged(123); } // should only look at os2.merged + // + // os.visibility = visibility; + os.parent = ad.parent; + ad.aliassym = os; + } + if (isInsertCandidate) + { + os.push(s); + return true; + } + } + return false; +} + +/**************************************************** + * Overload this Dsymbol with the new one s. + * Return true if successful; i.e. no conflict. + */ +bool overloadInsert(Dsymbol _this, Dsymbol s) +{ + if (_this.isDtorDeclaration() || _this.isPostBlitDeclaration()) + { + return false; + } + if (auto od = _this.isOverDeclaration()) + { + //printf("OverDeclaration::overloadInsert('%s') aliassym = %p, overnext = %p\n", s.toChars(), aliassym, overnext); + if (od.overnext) + return od.overnext.overloadInsert(s); + if (s == od) + return true; + od.overnext = s; + return true; + } + if (auto fd = _this.isFuncDeclaration()) + { + //printf("FuncDeclaration::overloadInsert(s = %s) this = %s\n", s.toChars(), toChars()); + assert(s != fd); + if (AliasDeclaration ad = s.isAliasDeclaration()) + { + if (fd.overnext) + return fd.overnext.overloadInsert(ad); + if (!ad.aliassym && ad.type.ty != Tident && ad.type.ty != Tinstance && ad.type.ty != Ttypeof) + { + //printf("\tad = '%s'\n", ad.type.toChars()); + return false; + } + fd.overnext = ad; + //printf("\ttrue: no conflict\n"); + return true; + } + TemplateDeclaration td = s.isTemplateDeclaration(); + if (td) + { + if (!td.funcroot) + td.funcroot = fd; + if (fd.overnext) + return fd.overnext.overloadInsert(td); + fd.overnext = td; + return true; + } + FuncDeclaration fd2 = s.isFuncDeclaration(); + if (!fd) + return false; + + if (fd.overnext) + { + td = fd.overnext.isTemplateDeclaration(); + if (td) + fd2.overloadInsert(td); + else + return fd2.overnext.overloadInsert(fd); + } + fd.overnext = fd2; + //printf("\ttrue: no conflict\n"); + return true; + } + if (auto id = _this.isImport()) + { + /* Allow multiple imports with the same package base, but disallow + * alias collisions + * https://issues.dlang.org/show_bug.cgi?id=5412 + */ + assert(id.ident && id.ident == s.ident); + if (id.aliasId) + return false; + const imp = s.isImport(); + return imp && !imp.aliasId; + } + if (auto td = _this.isTemplateDeclaration()) + { + FuncDeclaration fd = s.isFuncDeclaration(); + if (fd) + { + if (td.funcroot) + return td.funcroot.overloadInsert(fd); + td.funcroot = fd; + return td.funcroot.overloadInsert(td); + } + + // https://issues.dlang.org/show_bug.cgi?id=15795 + // if candidate is an alias and its sema is not run then + // insertion can fail because the thing it alias is not known + if (AliasDeclaration ad = s.isAliasDeclaration()) + { + if (s._scope) + aliasSemantic(ad, s._scope); + if (ad.aliassym && ad.aliassym is td) + return false; + } + TemplateDeclaration td2 = s.toAlias().isTemplateDeclaration(); + if (!td2) + return false; + + TemplateDeclaration pthis = td; + TemplateDeclaration* ptd; + for (ptd = &pthis; *ptd; ptd = &(*ptd).overnext) + { + } + + td2.overroot = td; + *ptd = td2; + return true; + } + + if (auto ad = _this.isAliasDeclaration()) + { + return aliasoOverloadInsert(ad, s); + } + + return false; +} + /*************************************************** * Determine the numerical value of the AlignmentDeclaration * Params: diff --git a/compiler/src/dmd/dtemplate.d b/compiler/src/dmd/dtemplate.d index a4a0bc5124a9..13e353587a27 100644 --- a/compiler/src/dmd/dtemplate.d +++ b/compiler/src/dmd/dtemplate.d @@ -53,7 +53,7 @@ import dmd.dinterpret; import dmd.dmodule; import dmd.dscope; import dmd.dsymbol; -import dmd.dsymbolsem : aliasSemantic, oneMembers, toAlias; +import dmd.dsymbolsem : oneMembers, toAlias; import dmd.errors; import dmd.errorsink; import dmd.expression; @@ -483,56 +483,6 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol return new TemplateDeclaration(loc, ident, p, constraint ? constraint.syntaxCopy() : null, Dsymbol.arraySyntaxCopy(members), ismixin, literal); } - /********************************** - * Overload existing TemplateDeclaration 'this' with the new one 's'. - * Params: - * s = symbol to be inserted - * Return: true if successful; i.e. no conflict. - */ - override bool overloadInsert(Dsymbol s) - { - static if (LOG) - { - printf("TemplateDeclaration.overloadInsert('%s')\n", s.toChars()); - } - FuncDeclaration fd = s.isFuncDeclaration(); - if (fd) - { - if (funcroot) - return funcroot.overloadInsert(fd); - funcroot = fd; - return funcroot.overloadInsert(this); - } - - // https://issues.dlang.org/show_bug.cgi?id=15795 - // if candidate is an alias and its sema is not run then - // insertion can fail because the thing it alias is not known - if (AliasDeclaration ad = s.isAliasDeclaration()) - { - if (s._scope) - aliasSemantic(ad, s._scope); - if (ad.aliassym && ad.aliassym is this) - return false; - } - TemplateDeclaration td = s.toAlias().isTemplateDeclaration(); - if (!td) - return false; - - TemplateDeclaration pthis = this; - TemplateDeclaration* ptd; - for (ptd = &pthis; *ptd; ptd = &(*ptd).overnext) - { - } - - td.overroot = this; - *ptd = td; - static if (LOG) - { - printf("\ttrue: no conflict\n"); - } - return true; - } - override const(char)* kind() const { return (onemember && onemember.isAggregateDeclaration()) ? onemember.kind() : "template"; diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index 1d3b7cfadf1e..fc90f978a224 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -600,7 +600,6 @@ class Dsymbol : public ASTNode virtual Identifier* getIdent(); virtual const char* toPrettyChars(bool QualifyTypes = false); virtual const char* kind() const; - virtual bool overloadInsert(Dsymbol* s); virtual uint64_t size(Loc loc); virtual bool isforwardRef(); virtual AggregateDeclaration* isThis(); @@ -1769,7 +1768,6 @@ class TemplateDeclaration final : public ScopeDsymbol Array lastConstraintNegs; Array* lastConstraintTiargs; TemplateDeclaration* syntaxCopy(Dsymbol* __param_0_) override; - bool overloadInsert(Dsymbol* s) override; const char* kind() const override; const char* toCharsNoConstraints() const; Visibility visible() override; @@ -4063,7 +4061,6 @@ class FuncDeclaration : public Declaration Array* fdensureParams(Array* param); FuncDeclaration* syntaxCopy(Dsymbol* s) override; bool equals(const RootObject* const o) const final override; - bool overloadInsert(Dsymbol* s) override; bool inUnittest(); LabelDsymbol* searchLabel(Identifier* ident, Loc loc); enum : int32_t { LevelError = -2 }; @@ -4117,7 +4114,6 @@ class DtorDeclaration final : public FuncDeclaration bool isVirtual() const override; bool addPreInvariant() override; bool addPostInvariant() override; - bool overloadInsert(Dsymbol* s) override; void accept(Visitor* v) override; }; @@ -4176,7 +4172,6 @@ class PostBlitDeclaration final : public FuncDeclaration bool isVirtual() const override; bool addPreInvariant() override; bool addPostInvariant() override; - bool overloadInsert(Dsymbol* s) override; void accept(Visitor* v) override; }; @@ -6836,7 +6831,6 @@ class AliasDeclaration final : public Declaration Dsymbol* _import_; static AliasDeclaration* create(Loc loc, Identifier* id, Type* type); AliasDeclaration* syntaxCopy(Dsymbol* s) override; - bool overloadInsert(Dsymbol* s) override; const char* kind() const override; Type* getType() override; bool isOverloadable() const override; @@ -6850,7 +6844,6 @@ class OverDeclaration final : public Declaration Dsymbol* aliassym; const char* kind() const override; bool equals(const RootObject* const o) const override; - bool overloadInsert(Dsymbol* s) override; bool isOverloadable() const override; void accept(Visitor* v) override; }; @@ -7132,7 +7125,6 @@ class Import final : public Dsymbol const char* kind() const override; Visibility visible() override; Import* syntaxCopy(Dsymbol* s) override; - bool overloadInsert(Dsymbol* s) override; void accept(Visitor* v) override; }; diff --git a/compiler/src/dmd/func.d b/compiler/src/dmd/func.d index 7b28464e86f5..2a342237dde5 100644 --- a/compiler/src/dmd/func.d +++ b/compiler/src/dmd/func.d @@ -413,54 +413,6 @@ extern (C++) class FuncDeclaration : Declaration faf1.type.equals(faf2.type); } - /**************************************************** - * Overload this FuncDeclaration with the new one f. - * Return true if successful; i.e. no conflict. - */ - override bool overloadInsert(Dsymbol s) - { - //printf("FuncDeclaration::overloadInsert(s = %s) this = %s\n", s.toChars(), toChars()); - assert(s != this); - if (AliasDeclaration ad = s.isAliasDeclaration()) - { - if (overnext) - return overnext.overloadInsert(ad); - if (!ad.aliassym && ad.type.ty != Tident && ad.type.ty != Tinstance && ad.type.ty != Ttypeof) - { - //printf("\tad = '%s'\n", ad.type.toChars()); - return false; - } - overnext = ad; - //printf("\ttrue: no conflict\n"); - return true; - } - TemplateDeclaration td = s.isTemplateDeclaration(); - if (td) - { - if (!td.funcroot) - td.funcroot = this; - if (overnext) - return overnext.overloadInsert(td); - overnext = td; - return true; - } - FuncDeclaration fd = s.isFuncDeclaration(); - if (!fd) - return false; - - if (overnext) - { - td = overnext.isTemplateDeclaration(); - if (td) - fd.overloadInsert(td); - else - return overnext.overloadInsert(fd); - } - overnext = fd; - //printf("\ttrue: no conflict\n"); - return true; - } - /******************************************** * find function template root in overload list */ @@ -1404,11 +1356,6 @@ extern (C++) final class PostBlitDeclaration : FuncDeclaration return (isThis() && vthis && global.params.useInvariants == CHECKENABLE.on); } - override bool overloadInsert(Dsymbol s) - { - return false; // cannot overload postblits - } - override void accept(Visitor v) { v.visit(this); @@ -1461,11 +1408,6 @@ extern (C++) final class DtorDeclaration : FuncDeclaration return false; } - override bool overloadInsert(Dsymbol s) - { - return false; // cannot overload destructors - } - override void accept(Visitor v) { v.visit(this);