diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index ffa5c754eed40..11637c711304b 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -2837,11 +2837,7 @@ class NominalTypeDecl : public TypeDecl, public DeclContext, ArrayRef DelayedMembers; GenericParamList *GenericParams; - - /// Global declarations that were synthesized on this type's behalf, such as - /// default operator definitions derived for protocol conformances. - ArrayRef DerivedGlobalDecls; - + /// \brief The generic signature of this type. /// /// This is the semantic representation of a generic parameters and the @@ -3155,14 +3151,6 @@ class NominalTypeDecl : public TypeDecl, public DeclContext, return StoredPropertyRange(getMembers(), ToStoredProperty()); } - ArrayRef getDerivedGlobalDecls() const { - return DerivedGlobalDecls; - } - - void setDerivedGlobalDecls(MutableArrayRef decls) { - DerivedGlobalDecls = decls; - } - bool hasDelayedMemberDecls() { return DelayedMembers.size() != 0; } diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h index 6567fd63d8a4e..d53696bafb204 100644 --- a/include/swift/AST/DeclContext.h +++ b/include/swift/AST/DeclContext.h @@ -533,6 +533,10 @@ class IterableDeclContext { /// Lazy member loader context data. uint64_t LazyLoaderContextData = 0; + /// Global declarations that were synthesized on this declaration's behalf, + /// such as default operator definitions derived for protocol conformances. + ArrayRef DerivedGlobalDecls; + template friend struct ::llvm::cast_convert_val; @@ -577,6 +581,18 @@ class IterableDeclContext { /// Load all of the members of this context. void loadAllMembers() const; + /// Retrieve global declarations that were synthesized on this + /// declaration's behalf. + ArrayRef getDerivedGlobalDecls() const { + return DerivedGlobalDecls; + } + + /// Set global declarations that were synthesized on this + /// declaration's behalf. + void setDerivedGlobalDecls(MutableArrayRef decls) { + DerivedGlobalDecls = decls; + } + // Some Decls are IterableDeclContexts, but not all. static bool classof(const Decl *D); diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp index 688279e6963e1..1d9ff7b810140 100644 --- a/lib/SILGen/SILGenType.cpp +++ b/lib/SILGen/SILGenType.cpp @@ -543,6 +543,8 @@ class SILGenExtension : public TypeMemberVisitor { void emitExtension(ExtensionDecl *e) { for (Decl *member : e->getMembers()) visit(member); + for (Decl *member : e->getDerivedGlobalDecls()) + SGM.visit(member); if (!e->getExtendedType()->isExistentialType()) { // Emit witness tables for protocol conformances introduced by the diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp index 595a514fe8113..c7487758ed2d5 100644 --- a/lib/Sema/DerivedConformanceEquatableHashable.cpp +++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp @@ -288,7 +288,7 @@ deriveEquatable_enum_eq(TypeChecker &tc, EnumDecl *enumDecl) { tc.implicitlyDefinedFunctions.push_back(eqDecl); // Since it's an operator we insert the decl after the type at global scope. - return insertOperatorDecl(enumDecl, eqDecl); + return insertOperatorDecl(C, enumDecl, eqDecl); } ValueDecl *DerivedConformance::deriveEquatable(TypeChecker &tc, diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp index d25934d01eb3c..a72a067dfb419 100644 --- a/lib/Sema/DerivedConformances.cpp +++ b/lib/Sema/DerivedConformances.cpp @@ -21,11 +21,11 @@ using namespace swift; using namespace DerivedConformance; -void DerivedConformance::_insertOperatorDecl(NominalTypeDecl *scope, +void DerivedConformance::_insertOperatorDecl(ASTContext &C, + IterableDeclContext *scope, Decl *member) { // Find the module. - auto &C = scope->getASTContext(); - auto mod = scope->getModuleContext(); + auto mod = member->getModuleContext(); // Add it to the module in a DerivedFileUnit. mod->getDerivedFileUnit().addDerivedDecl(cast(member)); diff --git a/lib/Sema/DerivedConformances.h b/lib/Sema/DerivedConformances.h index 65a5ab863c221..1a448a326ee74 100644 --- a/lib/Sema/DerivedConformances.h +++ b/lib/Sema/DerivedConformances.h @@ -85,15 +85,19 @@ ValueDecl *deriveBridgedNSError(TypeChecker &tc, NominalTypeDecl *type, ValueDecl *requirement); -/// Insert an operator declaration associated with a nominal type. The -/// declaration is added at global scope. -void _insertOperatorDecl(NominalTypeDecl *scope, Decl *member); +/// Insert an operator declaration associated with a declaration +/// context. The operator declaration is added at global scope. +void _insertOperatorDecl(ASTContext &C, + IterableDeclContext *scope, + Decl *member); -/// Insert a declaration as a member of a nominal type. The declaration is -/// added at file scope as close as possible to the +/// Insert an operator declaration associated with a declaration +/// context. The operator declaration is added at global scope. template -inline SomeDecl *insertOperatorDecl(NominalTypeDecl *scope, SomeDecl *member) { - ::swift::DerivedConformance::_insertOperatorDecl(scope, member); +inline SomeDecl *insertOperatorDecl(ASTContext &C, + IterableDeclContext *scope, + SomeDecl *member) { + ::swift::DerivedConformance::_insertOperatorDecl(C, scope, member); return member; } diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index f9b4f7eeea17a..c69e0d8045958 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -3379,8 +3379,8 @@ class DeclChecker : public DeclVisitor { // Visit each of the members. for (Decl *Member : SD->getMembers()) visit(Member); - for (Decl *global : SD->getDerivedGlobalDecls()) - visit(global); + for (Decl *Global : SD->getDerivedGlobalDecls()) + visit(Global); if (!(IsFirstPass || SD->isInvalid())) { checkExplicitConformance(SD, SD->getDeclaredTypeInContext()); @@ -5341,6 +5341,8 @@ class DeclChecker : public DeclVisitor { if (!ED->isInvalid()) { for (Decl *Member : ED->getMembers()) visit(Member); + for (Decl *Global : ED->getDerivedGlobalDecls()) + visit(Global); } if (!IsFirstPass) {