diff --git a/include/swift/AST/TypeDifferenceVisitor.h b/include/swift/AST/TypeDifferenceVisitor.h index 3492c33151e46..c9cc7a7f7c710 100644 --- a/include/swift/AST/TypeDifferenceVisitor.h +++ b/include/swift/AST/TypeDifferenceVisitor.h @@ -170,7 +170,8 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor { return asImpl().visitDifferentTypeStructure(type1, type2); return visitComponentArray(type1, type2, - type1.getGenericArgs(), type2.getGenericArgs()); + type1.getDirectGenericArgs(), + type2.getDirectGenericArgs()); } bool visitAnyMetatypeType(CanAnyMetatypeType type1, @@ -388,4 +389,4 @@ class CanTypeDifferenceVisitor : public CanTypePairVisitor { } -#endif \ No newline at end of file +#endif diff --git a/include/swift/AST/TypeMatcher.h b/include/swift/AST/TypeMatcher.h index 05fdd68f26ce8..f28987ea004bf 100644 --- a/include/swift/AST/TypeMatcher.h +++ b/include/swift/AST/TypeMatcher.h @@ -284,11 +284,10 @@ class TypeMatcher { sugaredFirstBGT->getParent())) return false; - for (unsigned i = 0, n = firstBGT->getGenericArgs().size(); - i != n; ++i) { - if (!this->visit(firstBGT.getGenericArgs()[i], - secondBGT->getGenericArgs()[i], - sugaredFirstBGT->getGenericArgs()[i])) + for (const auto i: indices(firstBGT->getDirectGenericArgs())) { + if (!this->visit(firstBGT.getDirectGenericArgs()[i], + secondBGT->getDirectGenericArgs()[i], + sugaredFirstBGT->getDirectGenericArgs()[i])) return false; } diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 4eec20e76b166..9280da88b4881 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -403,13 +403,6 @@ class alignas(1 << TypeAlignInBits) TypeBase { Count : 32 ); - SWIFT_INLINE_BITFIELD_FULL(BoundGenericType, TypeBase, 32, - : NumPadBits, - - /// The number of generic arguments. - GenericArgCount : 32 - ); - SWIFT_INLINE_BITFIELD_FULL(TypeAliasType, SugarType, 1+1, : NumPadBits, @@ -2205,33 +2198,37 @@ typedef ArrayRefView CanTypeArrayRef; /// given type arguments. class BoundGenericType : public NominalOrBoundGenericNominalType, public llvm::FoldingSetNode { - - /// Retrieve the intrusive pointer storage from the subtype - const Type *getTrailingObjectsPointer() const; - Type *getTrailingObjectsPointer() { - const BoundGenericType *temp = this; - return const_cast(temp->getTrailingObjectsPointer()); - } + const SubstitutionMap Substitutions; protected: - BoundGenericType(TypeKind theKind, NominalTypeDecl *theDecl, Type parent, - ArrayRef genericArgs, const ASTContext *context, - RecursiveTypeProperties properties); + BoundGenericType(TypeKind K, NominalTypeDecl *TheDecl, Type Parent, + SubstitutionMap Substitutions, const ASTContext *C, + RecursiveTypeProperties Properties) + : NominalOrBoundGenericNominalType(TheDecl, Parent, K, C, Properties), + Substitutions(Substitutions) {} public: - static BoundGenericType* get(NominalTypeDecl *TheDecl, Type Parent, - ArrayRef GenericArgs); + static BoundGenericType *get(NominalTypeDecl *TheDecl, Type Parent, + SubstitutionMap Substitutions); - /// Retrieve the set of generic arguments provided at this level. - ArrayRef getGenericArgs() const { - return {getTrailingObjectsPointer(), Bits.BoundGenericType.GenericArgCount}; + /// Deprecated version of the above . + static BoundGenericType *get(NominalTypeDecl *TheDecl, Type Parent, + ArrayRef GenericArgs, + ModuleDecl *M = nullptr); + + /// Retrieve the substitution map applied to the declaration's underlying + /// to produce the described type. + SubstitutionMap getSubstitutionMap() const { + return Substitutions; } - void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDecl(), getParent(), getGenericArgs()); + ArrayRef getDirectGenericArgs() const; + + void Profile(llvm::FoldingSetNodeID &ID) const { + Profile(ID, getDecl(), getParent(), Substitutions); } static void Profile(llvm::FoldingSetNodeID &ID, NominalTypeDecl *TheDecl, - Type Parent, ArrayRef GenericArgs); + Type Parent, SubstitutionMap Substitutions); // Implement isa/cast/dyncast/etc. static bool classof(const TypeBase *T) { @@ -2240,35 +2237,24 @@ class BoundGenericType : public NominalOrBoundGenericNominalType, } }; BEGIN_CAN_TYPE_WRAPPER(BoundGenericType, NominalOrBoundGenericNominalType) - CanTypeArrayRef getGenericArgs() const { - return CanTypeArrayRef(getPointer()->getGenericArgs()); + CanTypeArrayRef getDirectGenericArgs() const { + return CanTypeArrayRef(getPointer()->getDirectGenericArgs()); } END_CAN_TYPE_WRAPPER(BoundGenericType, NominalOrBoundGenericNominalType) /// BoundGenericClassType - A subclass of BoundGenericType for the case /// when the nominal type is a generic class type. -class BoundGenericClassType final : public BoundGenericType, - private llvm::TrailingObjects { - friend TrailingObjects; - -private: - BoundGenericClassType(ClassDecl *theDecl, Type parent, - ArrayRef genericArgs, const ASTContext *context, - RecursiveTypeProperties properties) +class BoundGenericClassType final : public BoundGenericType { + BoundGenericClassType(ClassDecl *TheDecl, Type Parent, + SubstitutionMap Substitutions, const ASTContext *C, + RecursiveTypeProperties Properties) : BoundGenericType(TypeKind::BoundGenericClass, - reinterpret_cast(theDecl), parent, - genericArgs, context, properties) {} + reinterpret_cast(TheDecl), Parent, + Substitutions, C, Properties) {} friend class BoundGenericType; public: - static BoundGenericClassType* get(ClassDecl *theDecl, Type parent, - ArrayRef genericArgs) { - return cast( - BoundGenericType::get(reinterpret_cast(theDecl), - parent, genericArgs)); - } - /// Returns the declaration that declares this type. ClassDecl *getDecl() const { return reinterpret_cast(BoundGenericType::getDecl()); @@ -2282,27 +2268,16 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(BoundGenericClassType, BoundGenericType) /// BoundGenericEnumType - A subclass of BoundGenericType for the case /// when the nominal type is a generic enum type. -class BoundGenericEnumType final : public BoundGenericType, - private llvm::TrailingObjects { - friend TrailingObjects; - -private: - BoundGenericEnumType(EnumDecl *theDecl, Type parent, - ArrayRef genericArgs, const ASTContext *context, - RecursiveTypeProperties properties) +class BoundGenericEnumType final : public BoundGenericType { + BoundGenericEnumType(EnumDecl *TheDecl, Type Parent, + SubstitutionMap Substitutions, const ASTContext *C, + RecursiveTypeProperties Properties) : BoundGenericType(TypeKind::BoundGenericEnum, - reinterpret_cast(theDecl), parent, - genericArgs, context, properties) {} + reinterpret_cast(TheDecl), Parent, + Substitutions, C, Properties) {} friend class BoundGenericType; public: - static BoundGenericEnumType* get(EnumDecl *theDecl, Type parent, - ArrayRef genericArgs) { - return cast( - BoundGenericType::get(reinterpret_cast(theDecl), - parent, genericArgs)); - } - /// Returns the declaration that declares this type. EnumDecl *getDecl() const { return reinterpret_cast(BoundGenericType::getDecl()); @@ -2316,27 +2291,16 @@ DEFINE_EMPTY_CAN_TYPE_WRAPPER(BoundGenericEnumType, BoundGenericType) /// BoundGenericStructType - A subclass of BoundGenericType for the case /// when the nominal type is a generic struct type. -class BoundGenericStructType final : public BoundGenericType, - private llvm::TrailingObjects { - friend TrailingObjects; - -private: - BoundGenericStructType(StructDecl *theDecl, Type parent, - ArrayRef genericArgs, const ASTContext *context, - RecursiveTypeProperties properties) +class BoundGenericStructType final : public BoundGenericType { + BoundGenericStructType(StructDecl *TheDecl, Type Parent, + SubstitutionMap Substitutions, const ASTContext *C, + RecursiveTypeProperties Properties) : BoundGenericType(TypeKind::BoundGenericStruct, - reinterpret_cast(theDecl), parent, - genericArgs, context, properties) {} + reinterpret_cast(TheDecl), Parent, + Substitutions, C, Properties) {} friend class BoundGenericType; public: - static BoundGenericStructType* get(StructDecl *theDecl, Type parent, - ArrayRef genericArgs) { - return cast( - BoundGenericType::get(reinterpret_cast(theDecl), - parent, genericArgs)); - } - /// Returns the declaration that declares this type. StructDecl *getDecl() const { return reinterpret_cast(BoundGenericType::getDecl()); @@ -6413,7 +6377,7 @@ inline Type TupleTypeElt::getVarargBaseTy() const { return AT->getBaseType(); if (auto *BGT = dyn_cast(T)) { // It's the stdlib Array. - return BGT->getGenericArgs()[0]; + return BGT->getDirectGenericArgs()[0]; } assert(T->hasError()); return T; @@ -6445,16 +6409,6 @@ inline ParameterTypeFlags ParameterTypeFlags::fromParameterType( return {isVariadic, isAutoClosure, isNonEphemeral, ownership, isNoDerivative}; } -inline const Type *BoundGenericType::getTrailingObjectsPointer() const { - if (auto ty = dyn_cast(this)) - return ty->getTrailingObjects(); - if (auto ty = dyn_cast(this)) - return ty->getTrailingObjects(); - if (auto ty = dyn_cast(this)) - return ty->getTrailingObjects(); - llvm_unreachable("Unhandled BoundGenericType!"); -} - inline ArrayRef AnyFunctionType::getParams() const { switch (getKind()) { case TypeKind::Function: diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index bf3b609c68d30..e321e2d9f130a 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2554,89 +2554,101 @@ get(GenericTypeDecl *TheDecl, Type Parent, const ASTContext &C) { return result; } -void BoundGenericType::Profile(llvm::FoldingSetNodeID &ID, - NominalTypeDecl *TheDecl, Type Parent, - ArrayRef GenericArgs) { - ID.AddPointer(TheDecl); - ID.AddPointer(Parent.getPointer()); - ID.AddInteger(GenericArgs.size()); - for (Type Arg : GenericArgs) { - ID.AddPointer(Arg.getPointer()); +BoundGenericType *BoundGenericType::get(NominalTypeDecl *TheDecl, + Type Parent, + ArrayRef GenericArgs, + ModuleDecl *M) { + assert(GenericArgs.size() == TheDecl->getGenericParams()->size() && + "generic parameter and argument count mismatch"); + + const auto Sig = TheDecl->getGenericSignature(); + assert(Sig); + + // Add any substitutions from the parent type. + TypeSubstitutionMap Subs; + if (Parent) + Subs = Parent->getContextSubstitutions(TheDecl->getDeclContext()); + + // Now, map the declaration's own generic parameters to + // the provided arguments. + const auto GenParams = Sig->getInnermostGenericParams(); + for (const auto I : indices(GenericArgs)) { + Subs[GenParams[I]->getCanonicalType()->castTo()] = + GenericArgs[I]; } -} -BoundGenericType::BoundGenericType(TypeKind theKind, - NominalTypeDecl *theDecl, - Type parent, - ArrayRef genericArgs, - const ASTContext *context, - RecursiveTypeProperties properties) - : NominalOrBoundGenericNominalType(theDecl, parent, theKind, context, - properties) { - Bits.BoundGenericType.GenericArgCount = genericArgs.size(); - // Subtypes are required to provide storage for the generic arguments - std::uninitialized_copy(genericArgs.begin(), genericArgs.end(), - getTrailingObjectsPointer()); + // If we haven't been given a module for conformance lookup, + // use the parent module of the referenced decl. + if (M == nullptr) + M = TheDecl->getParentModule(); + + // Form the substitution map. + const auto SubMap = SubstitutionMap::get( + Sig, QueryTypeSubstitutionMap{Subs}, LookUpConformanceInModule(M)); + + return get(TheDecl, Parent, SubMap); } BoundGenericType *BoundGenericType::get(NominalTypeDecl *TheDecl, Type Parent, - ArrayRef GenericArgs) { - assert(TheDecl->getGenericParams() && "must be a generic type decl"); + SubstitutionMap Substitutions) { + assert(Substitutions && "must have non-empty substitutions"); + assert(TheDecl->isGeneric() && "must be a generic type decl"); assert((!Parent || Parent->is() || Parent->is() || Parent->is()) && "parent must be a nominal type"); - ASTContext &C = TheDecl->getDeclContext()->getASTContext(); + const ASTContext &C = TheDecl->getDeclContext()->getASTContext(); llvm::FoldingSetNodeID ID; - BoundGenericType::Profile(ID, TheDecl, Parent, GenericArgs); - RecursiveTypeProperties properties; - if (Parent) properties |= Parent->getRecursiveProperties(); - for (Type Arg : GenericArgs) { - properties |= Arg->getRecursiveProperties(); - } + BoundGenericType::Profile(ID, TheDecl, Parent, Substitutions); + RecursiveTypeProperties Properties; + if (Parent) Properties |= Parent->getRecursiveProperties(); + for (const auto &substGP : Substitutions.getReplacementTypes()) + Properties |= substGP->getRecursiveProperties(); - auto arena = getArena(properties); + const auto Arena = getArena(Properties); void *InsertPos = nullptr; if (BoundGenericType *BGT = - C.getImpl().getArena(arena).BoundGenericTypes.FindNodeOrInsertPos(ID, + C.getImpl().getArena(Arena).BoundGenericTypes.FindNodeOrInsertPos(ID, InsertPos)) return BGT; - bool IsCanonical = !Parent || Parent->isCanonical(); - if (IsCanonical) { - for (Type Arg : GenericArgs) { - if (!Arg->isCanonical()) { - IsCanonical = false; - break; - } - } - } - - BoundGenericType *newType; - if (auto theClass = dyn_cast(TheDecl)) { - auto sz = BoundGenericClassType::totalSizeToAlloc(GenericArgs.size()); - auto mem = C.Allocate(sz, alignof(BoundGenericClassType), arena); - newType = new (mem) BoundGenericClassType( - theClass, Parent, GenericArgs, IsCanonical ? &C : nullptr, properties); - } else if (auto theStruct = dyn_cast(TheDecl)) { - auto sz =BoundGenericStructType::totalSizeToAlloc(GenericArgs.size()); - auto mem = C.Allocate(sz, alignof(BoundGenericStructType), arena); - newType = new (mem) BoundGenericStructType( - theStruct, Parent, GenericArgs, IsCanonical ? &C : nullptr, properties); - } else if (auto theEnum = dyn_cast(TheDecl)) { - auto sz = BoundGenericEnumType::totalSizeToAlloc(GenericArgs.size()); - auto mem = C.Allocate(sz, alignof(BoundGenericEnumType), arena); - newType = new (mem) BoundGenericEnumType( - theEnum, Parent, GenericArgs, IsCanonical ? &C : nullptr, properties); + const bool IsCanonical = + (!Parent || Parent->isCanonical()) && Substitutions.isCanonical(); + + BoundGenericType *BGT; + void *const Mem = C.Allocate(sizeof(BoundGenericType), + alignof(BoundGenericType), Arena); + const ASTContext *CanContext = IsCanonical ? &C : nullptr; + if (auto *const CD = dyn_cast(TheDecl)) { + BGT = new (Mem) BoundGenericClassType(CD, Parent, Substitutions, + CanContext, Properties); + } else if (auto *const SD = dyn_cast(TheDecl)) { + BGT = new (Mem) BoundGenericStructType(SD, Parent, Substitutions, + CanContext, Properties); + } else if (auto *const ED = dyn_cast(TheDecl)) { + BGT = new (Mem) BoundGenericEnumType(ED, Parent, Substitutions, + CanContext, Properties); } else { llvm_unreachable("Unhandled NominalTypeDecl"); } - C.getImpl().getArena(arena).BoundGenericTypes.InsertNode(newType, InsertPos); + C.getImpl().getArena(Arena).BoundGenericTypes.InsertNode(BGT, InsertPos); + + return BGT; +} + +ArrayRef BoundGenericType::getDirectGenericArgs() const { + return getSubstitutionMap().getInnermostReplacementTypes(); +} - return newType; +void BoundGenericType::Profile(llvm::FoldingSetNodeID &ID, + NominalTypeDecl *TheDecl, Type Parent, + SubstitutionMap Substitutions) { + ID.AddPointer(TheDecl); + ID.AddPointer(Parent.getPointer()); + Substitutions.profile(ID); } NominalType *NominalType::get(NominalTypeDecl *D, Type Parent, const ASTContext &C) { @@ -2990,7 +3002,8 @@ Type AnyFunctionType::Param::getParameterType(bool forCanonical, if (!arrayDecl) type = ErrorType::get(*ctx); else if (forCanonical) - type = BoundGenericType::get(arrayDecl, Type(), {type}); + type = + BoundGenericType::get(arrayDecl, Type(), {type})->getCanonicalType(); else type = ArraySliceType::get(type); } diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp index 57692d6be94cf..eee9721e14e38 100644 --- a/lib/AST/ASTDemangler.cpp +++ b/lib/AST/ASTDemangler.cpp @@ -292,8 +292,10 @@ Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl, if (!validateParentType(decl, parent)) return Type(); + // FIXME: This is the wrong module + auto *moduleDecl = decl->getParentModule(); if (auto *nominalDecl = dyn_cast(decl)) - return BoundGenericType::get(nominalDecl, parent, args); + return BoundGenericType::get(nominalDecl, parent, args, moduleDecl); // Combine the substitutions from our parent type with our generic // arguments. @@ -312,8 +314,6 @@ Type ASTBuilder::createBoundGenericType(GenericTypeDecl *decl, substTy; } - // FIXME: This is the wrong module - auto *moduleDecl = decl->getParentModule(); auto subMap = SubstitutionMap::get(genericSig, QueryTypeSubstitutionMap{subs}, LookUpConformanceInModule(moduleDecl)); @@ -693,8 +693,7 @@ Type ASTBuilder::createBoundGenericObjCClassType(StringRef name, parent = dc->getDeclaredInterfaceType(); } - return BoundGenericClassType::get(cast(typeDecl), - parent, args); + return BoundGenericType::get(cast(typeDecl), parent, args); } ProtocolDecl *ASTBuilder::createObjCProtocolDecl(StringRef name) { diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index df7b9e300fc23..6dd0065cdd08a 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -3868,7 +3868,7 @@ namespace { printField("decl", T->getDecl()->printRef()); if (T->getParent()) printRec("parent", T->getParent()); - for (auto arg : T->getGenericArgs()) + for (const auto &arg : T->getDirectGenericArgs()) printRec(arg); PrintWithColorRAII(OS, ParenthesisColor) << ')'; } @@ -3879,7 +3879,7 @@ namespace { printField("decl", T->getDecl()->printRef()); if (T->getParent()) printRec("parent", T->getParent()); - for (auto arg : T->getGenericArgs()) + for (const auto &arg : T->getDirectGenericArgs()) printRec(arg); PrintWithColorRAII(OS, ParenthesisColor) << ')'; } @@ -3889,7 +3889,7 @@ namespace { printField("decl", T->getDecl()->printRef()); if (T->getParent()) printRec("parent", T->getParent()); - for (auto arg : T->getGenericArgs()) + for (const auto &arg : T->getDirectGenericArgs()) printRec(arg); PrintWithColorRAII(OS, ParenthesisColor) << ')'; } diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 64c84455b14e3..0cfa067c3cbdb 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -1116,7 +1116,8 @@ void ASTMangler::appendType(Type type, const ValueDecl *forDecl) { return; if (Decl->isStdlibDecl() && Decl->getName().str() == "Optional") { - auto GenArgs = type->castTo()->getGenericArgs(); + const auto GenArgs = + type->castTo()->getDirectGenericArgs(); assert(GenArgs.size() == 1); appendType(GenArgs[0], forDecl); appendOperator("Sg"); @@ -1433,7 +1434,7 @@ void ASTMangler::appendBoundGenericArgs(Type type, bool &isFirstArgList) { appendBoundGenericArgs(parent->getDesugaredType(), isFirstArgList); } else { auto boundType = cast(typePtr); - genericArgs = boundType->getGenericArgs(); + genericArgs = boundType->getDirectGenericArgs(); if (Type parent = boundType->getParent()) { GenericTypeDecl *decl = boundType->getAnyGeneric(); if (!getSpecialManglingContext(decl, UseObjCRuntimeNames)) diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index d9e3b6f6960e3..3d4c5fd4ebfaf 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -2785,7 +2785,7 @@ void PrintAST::printOneParameter(const ParamDecl *param, // to strip off the added array type. if (param->isVariadic() && TheTypeLoc.getType()) { if (auto *BGT = TheTypeLoc.getType()->getAs()) - TheTypeLoc.setType(BGT->getGenericArgs()[0]); + TheTypeLoc.setType(BGT->getDirectGenericArgs()[0]); } if (!param->isVariadic() && @@ -3870,26 +3870,26 @@ class TypePrinter : public TypeVisitor { auto &Ctx = T->getASTContext(); if (NT == Ctx.getArrayDecl()) { Printer << "["; - visit(T->getGenericArgs()[0]); + visit(T->getDirectGenericArgs()[0]); Printer << "]"; return; } if (NT == Ctx.getDictionaryDecl()) { Printer << "["; - visit(T->getGenericArgs()[0]); + visit(T->getDirectGenericArgs()[0]); Printer << " : "; - visit(T->getGenericArgs()[1]); + visit(T->getDirectGenericArgs()[1]); Printer << "]"; return; } if (NT == Ctx.getOptionalDecl()) { - printWithParensIfNotSimple(T->getGenericArgs()[0]); + printWithParensIfNotSimple(T->getDirectGenericArgs()[0]); Printer << "?"; return; } } printQualifiedType(T); - printGenericArgs(T->getGenericArgs()); + printGenericArgs(T->getDirectGenericArgs()); } void visitParentType(Type T) { diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp index 20bd5fd7cc18f..bccaead43f050 100644 --- a/lib/AST/ASTVerifier.cpp +++ b/lib/AST/ASTVerifier.cpp @@ -2203,7 +2203,7 @@ class Verifier : public ASTWalker { } else if (auto bgt = keyPathTy->getAs()) { if (bgt->getDecl() == Ctx.getPartialKeyPathDecl()) { // PartialKeyPath application is rvalue T -> rvalue Any - if (!baseTy->isEqual(bgt->getGenericArgs()[0])) { + if (!baseTy->isEqual(bgt->getDirectGenericArgs()[0])) { Out << "PartialKeyPath application base doesn't match type\n"; abort(); } @@ -2214,11 +2214,11 @@ class Verifier : public ASTWalker { return; } else if (bgt->getDecl() == Ctx.getKeyPathDecl()) { // KeyPath application is rvalue T -> rvalue U - if (!baseTy->isEqual(bgt->getGenericArgs()[0])) { + if (!baseTy->isEqual(bgt->getDirectGenericArgs()[0])) { Out << "KeyPath application base doesn't match type\n"; abort(); } - if (!resultTy->isEqual(bgt->getGenericArgs()[1])) { + if (!resultTy->isEqual(bgt->getDirectGenericArgs()[1])) { Out << "KeyPath application result doesn't match type\n"; abort(); } @@ -2236,11 +2236,11 @@ class Verifier : public ASTWalker { resultTy = resultTy->getRValueType(); } - if (!baseTy->isEqual(bgt->getGenericArgs()[0])) { + if (!baseTy->isEqual(bgt->getDirectGenericArgs()[0])) { Out << "WritableKeyPath application base doesn't match type\n"; abort(); } - if (!resultTy->isEqual(bgt->getGenericArgs()[1])) { + if (!resultTy->isEqual(bgt->getDirectGenericArgs()[1])) { Out << "WritableKeyPath application result doesn't match type\n"; abort(); } @@ -2262,12 +2262,12 @@ class Verifier : public ASTWalker { resultTy = resultTy->getRValueType(); } - if (!baseTy->isEqual(bgt->getGenericArgs()[0])) { + if (!baseTy->isEqual(bgt->getDirectGenericArgs()[0])) { Out << "ReferenceWritableKeyPath application base doesn't " "match type\n"; abort(); } - if (!resultTy->isEqual(bgt->getGenericArgs()[1])) { + if (!resultTy->isEqual(bgt->getDirectGenericArgs()[1])) { Out << "ReferenceWritableKeyPath application result doesn't " "match type\n"; abort(); diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index 8c3bf3e7ec5d2..a09f87df7a623 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -1331,7 +1331,7 @@ static ValueDecl *getConvertUnownedUnsafeToGuaranteed(ASTContext &ctx, static ValueDecl *getPoundAssert(ASTContext &Context, Identifier Id) { auto int1Type = BuiltinIntegerType::get(1, Context); - auto optionalRawPointerType = BoundGenericEnumType::get( + auto optionalRawPointerType = BoundGenericType::get( Context.getOptionalDecl(), Type(), {Context.TheRawPointerType}); return getBuiltinFunction(Id, {int1Type, optionalRawPointerType}, Context.TheEmptyTupleType); diff --git a/lib/AST/ClangTypeConverter.cpp b/lib/AST/ClangTypeConverter.cpp index a0c7e71393b7e..bda8b669ca3e4 100644 --- a/lib/AST/ClangTypeConverter.cpp +++ b/lib/AST/ClangTypeConverter.cpp @@ -473,7 +473,7 @@ ClangTypeConverter::visitBoundGenericType(BoundGenericType *type) { // The only possibilities are *Pointer, SIMD* and Optional. if (type->getDecl()->isOptionalDecl()) { - auto args = type->getGenericArgs(); + const auto args = type->getDirectGenericArgs(); assert((args.size() == 1) && "Optional should have 1 generic argument."); clang::QualType innerTy = convert(args[0]); if (swift::canImportAsOptional(innerTy.getTypePtrOrNull())) @@ -501,7 +501,7 @@ ClangTypeConverter::visitBoundGenericType(BoundGenericType *type) { .StartsWith("SIMD", StructKind::SIMD) .Default(StructKind::Invalid); - auto args = type->getGenericArgs(); + const auto args = type->getDirectGenericArgs(); if (args.size() != 1) // Must've got something other than *Pointer or SIMD* return clang::QualType(); diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e377aa4789b49..893814db1549a 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -3759,15 +3759,9 @@ static Type computeNominalType(NominalTypeDecl *decl, DeclTypeKind kind) { case DeclTypeKind::DeclaredType: return UnboundGenericType::get(decl, ParentTy, ctx); case DeclTypeKind::DeclaredInterfaceType: { - // Note that here, we need to be able to produce a type - // before the decl has been validated, so we rely on - // the generic parameter list directly instead of looking - // at the signature. - SmallVector args; - for (auto param : decl->getGenericParams()->getParams()) - args.push_back(param->getDeclaredInterfaceType()); - - return BoundGenericType::get(decl, ParentTy, args); + const auto sig = decl->getGenericSignature(); + return BoundGenericType::get(decl, ParentTy, + sig->getIdentitySubstitutionMap()); } } @@ -4935,7 +4929,7 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type, // Bound generic types are invariant. if (auto boundGenericType = type->getAs()) { - for (auto paramType : boundGenericType->getGenericArgs()) { + for (const auto ¶mType : boundGenericType->getDirectGenericArgs()) { if (findProtocolSelfReferences(proto, paramType, skipAssocTypes)) { return SelfReferenceKind::Other(); @@ -6302,7 +6296,7 @@ Type ParamDecl::getVarargBaseTy(Type VarArgT) { return AT->getBaseType(); if (auto *BGT = dyn_cast(T)) { // It's the stdlib Array. - return BGT->getGenericArgs()[0]; + return BGT->getDirectGenericArgs()[0]; } return T; } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index ac5d26304f91d..3ae4032eb12a4 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -590,14 +590,14 @@ Type TypeBase::getRValueType() { Type TypeBase::getOptionalObjectType() { if (auto boundTy = getAs()) if (boundTy->getDecl()->isOptionalDecl()) - return boundTy->getGenericArgs()[0]; + return boundTy->getDirectGenericArgs()[0]; return Type(); } CanType CanType::getOptionalObjectTypeImpl(CanType type) { if (auto boundTy = dyn_cast(type)) if (boundTy->getDecl()->isOptionalDecl()) - return boundTy.getGenericArgs()[0]; + return boundTy.getDirectGenericArgs()[0]; return CanType(); } @@ -625,7 +625,7 @@ Type TypeBase::getAnyPointerElementType(PointerTypeKind &PTK) { } else { return Type(); } - return boundTy->getGenericArgs()[0]; + return boundTy->getDirectGenericArgs()[0]; } return Type(); } @@ -671,7 +671,7 @@ Type TypeBase::getAnyBufferPointerElementType(BufferPointerTypeKind &BPTK) { } else { return Type(); } - return boundTy->getGenericArgs()[0]; + return boundTy->getDirectGenericArgs()[0]; } return Type(); } @@ -1264,14 +1264,12 @@ CanType TypeBase::computeCanonicalType() { case TypeKind::BoundGenericClass: case TypeKind::BoundGenericEnum: case TypeKind::BoundGenericStruct: { - BoundGenericType *BGT = cast(this); - Type parentTy; - if (BGT->getParent()) - parentTy = BGT->getParent()->getCanonicalType(); - SmallVector CanGenericArgs; - for (Type Arg : BGT->getGenericArgs()) - CanGenericArgs.push_back(Arg->getCanonicalType()); - Result = BoundGenericType::get(BGT->getDecl(), parentTy, CanGenericArgs); + const auto *const BGT = cast(this); + Result = BoundGenericType::get(BGT->getDecl(), + BGT->getParent() + ? BGT->getParent()->getCanonicalType() + : Type(), + BGT->getSubstitutionMap().getCanonical()); break; } } @@ -1292,8 +1290,8 @@ TypeBase *TypeBase::reconstituteSugar(bool Recursive) { auto Func = [Recursive](Type Ty) -> Type { if (auto boundGeneric = dyn_cast(Ty.getPointer())) { - auto getGenericArg = [&](unsigned i) -> Type { - auto arg = boundGeneric->getGenericArgs()[i]; + const auto getGenericArg = [&](unsigned i) -> Type { + auto arg = boundGeneric->getDirectGenericArgs()[i]; if (Recursive) arg = arg->reconstituteSugar(Recursive); return arg; @@ -1921,12 +1919,14 @@ class IsBindableVisitor SmallVector newParams; bool didChange = newParent != substBGT.getParent(); - - auto depthStart = - genericSig->getGenericParams().size() - bgt->getGenericArgs().size(); - for (auto i : indices(bgt->getGenericArgs())) { - auto orig = bgt->getGenericArgs()[i]->getCanonicalType(); - auto subst = substBGT.getGenericArgs()[i]; + + const auto origGenericArgs = bgt->getDirectGenericArgs(); + const auto substGenericArgs = substBGT.getDirectGenericArgs(); + const auto depthStart = + genericSig->getGenericParams().size() - origGenericArgs.size(); + for (const auto i : range(origGenericArgs.size())) { + auto orig = origGenericArgs[i]->getCanonicalType(); + auto subst = substGenericArgs[i]; auto gp = genericSig->getGenericParams()[depthStart + i]; // The new type is upper-bounded by the constraints the nominal type @@ -2316,10 +2316,11 @@ getForeignRepresentable(Type type, ForeignLanguage language, auto boundGenericType = type->getAs(); // Note: works around a broken Unmanaged<> definition. - if (!boundGenericType || boundGenericType->getGenericArgs().size() != 1) + if (!boundGenericType || + boundGenericType->getDirectGenericArgs().size() != 1) return failure(); - auto typeArgument = boundGenericType->getGenericArgs()[0]; + const auto typeArgument = boundGenericType->getDirectGenericArgs()[0]; if (typeArgument->isTriviallyRepresentableIn(language, dc)) return { ForeignRepresentableKind::Trivial, nullptr }; @@ -2407,7 +2408,7 @@ getForeignRepresentable(Type type, ForeignLanguage language, // translated separately, whether they are trivially representable // or bridged representable doesn't impact our final result. if (auto boundGenericType = type->getAs()) { - for (auto typeArg : boundGenericType->getGenericArgs()) { + for (const auto &typeArg : boundGenericType->getDirectGenericArgs()) { // Type arguments cannot be optional. if (typeArg->getOptionalObjectType()) return failure(); @@ -3760,6 +3761,17 @@ static Type substType(Type derivedType, return None; } + // Special-case BoundGenericType; we need to substitute conformances. + if (const auto *bgt = dyn_cast(type)) { + Type parentTy; + if (const auto origParentTy = bgt->getParent()) + parentTy = substType(origParentTy, + substitutions, lookupConformances, options); + const auto subMap = bgt->getSubstitutionMap() + .subst(substitutions, lookupConformances, options); + return Type(BoundGenericType::get(bgt->getDecl(), parentTy, subMap)); + } + // Special-case TypeAliasType; we need to substitute conformances. if (auto aliasTy = dyn_cast(type)) { Type parentTy; @@ -3984,7 +3996,7 @@ TypeBase::getContextSubstitutions(const DeclContext *dc, // For a bound generic type, gather the generic parameter -> generic // argument substitutions. if (auto boundGeneric = baseTy->getAs()) { - auto args = boundGeneric->getGenericArgs(); + const auto args = boundGeneric->getDirectGenericArgs(); for (unsigned i = 0, e = args.size(); i < e; ++i) { substitutions[params[n - e + i]->getCanonicalType() ->castTo()] = args[i]; @@ -4406,8 +4418,7 @@ case TypeKind::Id: case TypeKind::BoundGenericClass: case TypeKind::BoundGenericEnum: case TypeKind::BoundGenericStruct: { - auto bound = cast(base); - SmallVector substArgs; + const auto *const bound = cast(base); bool anyChanged = false; Type substParentTy; if (auto parentTy = bound->getParent()) { @@ -4419,7 +4430,9 @@ case TypeKind::Id: anyChanged = true; } - for (auto arg : bound->getGenericArgs()) { + // Attempt to transform only the direct generic arguments. + SmallVector substArgs; + for (const auto &arg : bound->getDirectGenericArgs()) { Type substArg = arg.transformRec(fn); if (!substArg) return Type(); diff --git a/lib/AST/TypeWalker.cpp b/lib/AST/TypeWalker.cpp index f5be4e10b5223..94910a522e44e 100644 --- a/lib/AST/TypeWalker.cpp +++ b/lib/AST/TypeWalker.cpp @@ -181,7 +181,7 @@ class Traversal : public TypeVisitor if (doIt(parent)) return true; - for (auto arg : ty->getGenericArgs()) + for (const auto &arg : ty->getDirectGenericArgs()) if (doIt(arg)) return true; diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index c2ef408111f93..2da9d276be8c5 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -5618,8 +5618,9 @@ SwiftDeclConverter::importSwiftNewtype(const clang::TypedefNameDecl *decl, // to determine whether to use this new_type, or an Unmanaged type. if (auto genericType = storedUnderlyingType->getAs()) { if (genericType->getDecl() == Impl.SwiftContext.getUnmanagedDecl()) { - assert(genericType->getGenericArgs().size() == 1 && "other args?"); - storedUnderlyingType = genericType->getGenericArgs()[0]; + assert(genericType->getDirectGenericArgs().size() == 1 + && "other args?"); + storedUnderlyingType = genericType->getDirectGenericArgs()[0]; } } diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index 87c5518c3e1e3..6b1e86c77a31f 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -973,7 +973,7 @@ namespace { } } assert(importedTypeArgs.size() == typeParamCount); - importedType = BoundGenericClassType::get( + importedType = BoundGenericType::get( imported, nullptr, importedTypeArgs); } else { importedType = imported->getDeclaredType(); @@ -1289,10 +1289,10 @@ static Type maybeImportCFOutParameter(ClangImporter::Implementation &impl, if (boundGenericBase != impl.SwiftContext.getUnmanagedDecl()) return Type(); - assert(boundGenericTy->getGenericArgs().size() == 1 && + assert(boundGenericTy->getDirectGenericArgs().size() == 1 && "signature of Unmanaged has changed"); - auto resultTy = boundGenericTy->getGenericArgs().front(); + auto resultTy = boundGenericTy->getDirectGenericArgs().front(); if (isOptional) resultTy = OptionalType::get(resultTy); diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index aff9699acf673..93372fadede5f 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -5878,7 +5878,7 @@ void CodeCompletionCallbacksImpl::doneParsing() { case CompletionKind::KeyPathExprSwift: { auto KPE = dyn_cast(ParsedExpr); auto BGT = (*ExprType)->getAs(); - if (!KPE || !BGT || BGT->getGenericArgs().size() != 2) + if (!KPE || !BGT || BGT->getDirectGenericArgs().size() != 2) break; assert(!KPE->isObjC()); @@ -5888,7 +5888,7 @@ void CodeCompletionCallbacksImpl::doneParsing() { bool OnRoot = !KPE->getComponents().front().isValid(); Lookup.setIsSwiftKeyPathExpr(OnRoot); - Type baseType = BGT->getGenericArgs()[OnRoot ? 0 : 1]; + Type baseType = BGT->getDirectGenericArgs()[OnRoot ? 0 : 1]; if (OnRoot && baseType->is()) { // Infer the root type of the keypath from the context type. ExprContextInfo ContextInfo(CurDeclContext, ParsedExpr); @@ -5899,7 +5899,8 @@ void CodeCompletionCallbacksImpl::doneParsing() { // If the context type is any of the KeyPath types, use it. if (T->getAnyNominal() && T->getAnyNominal()->getKeyPathTypeKind() && !T->hasUnresolvedType() && T->is()) { - baseType = T->castTo()->getGenericArgs()[0]; + baseType = + T->castTo()->getDirectGenericArgs()[0]; break; } diff --git a/lib/IDE/ExprContextAnalysis.cpp b/lib/IDE/ExprContextAnalysis.cpp index 602f5f32b19c3..c21da114015f0 100644 --- a/lib/IDE/ExprContextAnalysis.cpp +++ b/lib/IDE/ExprContextAnalysis.cpp @@ -484,7 +484,8 @@ static void collectPossibleCalleesByQualifiedLookup( auto *kpDecl = Ctx.getKeyPathDecl(); Type kpTy = kpDecl->mapTypeIntoContext(kpDecl->getDeclaredInterfaceType()); - Type kpValueTy = kpTy->castTo()->getGenericArgs()[1]; + Type kpValueTy = + kpTy->castTo()->getDirectGenericArgs()[1]; kpTy = BoundGenericType::get(kpDecl, Type(), {baseTy, kpValueTy}); Type fnTy = FunctionType::get( @@ -787,12 +788,12 @@ class ExprContextAnalyzer { // let _: [Element] = [#HERE#] // In this case, 'Element' is the expected type. if (boundGenericT->getDecl() == Context.getArrayDecl()) - recordPossibleType(boundGenericT->getGenericArgs()[0]); + recordPossibleType(boundGenericT->getDirectGenericArgs()[0]); // let _: [Key : Value] = [#HERE#] // In this case, 'Key' is the expected type. if (boundGenericT->getDecl() == Context.getDictionaryDecl()) - recordPossibleType(boundGenericT->getGenericArgs()[0]); + recordPossibleType(boundGenericT->getDirectGenericArgs()[0]); } } break; @@ -812,14 +813,14 @@ class ExprContextAnalyzer { // '(Key,Value)' here, 'ExprKind::Tuple' branch can decide which // type in the tuple type is the exprected type. SmallVector elts; - for (auto genericArg : boundGenericT->getGenericArgs()) - elts.emplace_back(genericArg); + for (const auto &arg : boundGenericT->getDirectGenericArgs()) + elts.emplace_back(arg); recordPossibleType(TupleType::get(elts, DC->getASTContext())); } else { // let _: [Key : Value] = [key: val, #HERE#] // In this case, assume 'Key' is the expected type. if (boundGenericT->getDecl() == Context.getDictionaryDecl()) - recordPossibleType(boundGenericT->getGenericArgs()[0]); + recordPossibleType(boundGenericT->getDirectGenericArgs()[0]); } } } diff --git a/lib/IRGen/GenClangType.cpp b/lib/IRGen/GenClangType.cpp index bc788fab6904a..fe24c799547ac 100644 --- a/lib/IRGen/GenClangType.cpp +++ b/lib/IRGen/GenClangType.cpp @@ -480,7 +480,7 @@ GenClangType::visitBoundGenericType(CanBoundGenericType type) { .StartsWith("SIMD", StructKind::SIMD) .Default(StructKind::Invalid); - auto args = type.getGenericArgs(); + const auto args = type.getDirectGenericArgs(); assert(args.size() == 1 && "should have a single generic argument!"); auto loweredArgTy = IGM.getLoweredType(args[0]).getASTType(); diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index b15fb6a69a6a1..82ace4fdbf299 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -1018,7 +1018,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { /// resolved in the debugger without needing to query the Swift module. llvm::DINodeArray collectGenericParams(BoundGenericType *BGT) { SmallVector TemplateParams; - for (auto Param : BGT->getGenericArgs()) { + for (auto Param : BGT->getDirectGenericArgs()) { TemplateParams.push_back(DBuilder.createTemplateTypeParameter( TheCU, "", getOrCreateType(DebugTypeInfo::getForwardDecl(Param)))); } diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp index e69c72d0914ac..1682ad80ae575 100644 --- a/lib/IRGen/MetadataRequest.cpp +++ b/lib/IRGen/MetadataRequest.cpp @@ -2497,7 +2497,7 @@ static bool shouldAccessByMangledName(IRGenModule &IGM, CanType type) { // accessor. // // TODO: Also need to count the parent type's generic arguments. - for (auto arg : bgt->getGenericArgs()) { + for (const auto arg : bgt->getDirectGenericArgs()) { visit(arg); } NumCalls += 1; @@ -2913,9 +2913,9 @@ class EmitTypeMetadataRefForLayout auto payloadTy = visit(objectTy); if (payloadTy == objectTy) return ty; - auto &C = ty->getASTContext(); - auto optDecl = C.getOptionalDecl(); - return CanType(BoundGenericEnumType::get(optDecl, Type(), payloadTy)); + auto *const optDecl = ty->getASTContext().getOptionalDecl(); + return BoundGenericType::get(optDecl, Type(), payloadTy) + ->getCanonicalType(); } // Otherwise, generic arguments are not lowered. diff --git a/lib/PrintAsObjC/DeclAndTypePrinter.cpp b/lib/PrintAsObjC/DeclAndTypePrinter.cpp index 468b0c002230f..01bcd18c1fc6c 100644 --- a/lib/PrintAsObjC/DeclAndTypePrinter.cpp +++ b/lib/PrintAsObjC/DeclAndTypePrinter.cpp @@ -1045,10 +1045,11 @@ class DeclAndTypePrinter::Implementation if (!genericTy || genericTy->getDecl() != getASTContext().getArrayDecl()) return false; - assert(genericTy->getGenericArgs().size() == 1); + const auto genericArgs = genericTy->getDirectGenericArgs(); + assert(genericArgs.size() == 1); - auto argTy = genericTy->getGenericArgs().front(); - if (auto classDecl = argTy->getClassOrBoundGenericClass()) + if (const auto classDecl = + genericArgs.front()->getClassOrBoundGenericClass()) os << "IBOutletCollection(" << getNameForObjC(classDecl) << ") "; else os << "IBOutletCollection(id) "; @@ -1160,7 +1161,7 @@ class DeclAndTypePrinter::Implementation os << ", unsafe_unretained"; // Don't print unsafe_unretained twice. if (auto boundTy = copyTy->getAs()) { - ty = boundTy->getGenericArgs().front(); + ty = boundTy->getDirectGenericArgs().front(); if (isOptional) ty = OptionalType::get(ty); } @@ -1692,7 +1693,7 @@ class DeclAndTypePrinter::Implementation ASTContext &ctx = getASTContext(); if (SD == ctx.getUnmanagedDecl()) { - auto args = BGT->getGenericArgs(); + const auto args = BGT->getDirectGenericArgs(); assert(args.size() == 1); visitPart(args.front(), optionalKind); os << " __unsafe_unretained"; @@ -1711,7 +1712,7 @@ class DeclAndTypePrinter::Implementation return false; } - auto args = BGT->getGenericArgs(); + const auto args = BGT->getDirectGenericArgs(); assert(args.size() == 1); visitPart(args.front(), OTK_None); if (isConst) @@ -1724,7 +1725,7 @@ class DeclAndTypePrinter::Implementation void visitBoundGenericStructType(BoundGenericStructType *BGT, Optional optionalKind) { // Handle bridged types. - if (printIfObjCBridgeable(BGT->getDecl(), BGT->getGenericArgs(), + if (printIfObjCBridgeable(BGT->getDecl(), BGT->getDirectGenericArgs(), optionalKind)) return; @@ -1736,7 +1737,7 @@ class DeclAndTypePrinter::Implementation void printGenericArgs(BoundGenericType *BGT) { os << '<'; - interleave(BGT->getGenericArgs(), + interleave(BGT->getDirectGenericArgs(), [this](Type t) { print(t, None); }, [this] { os << ", "; }); os << '>'; @@ -1768,7 +1769,7 @@ class DeclAndTypePrinter::Implementation Optional optionalKind) { // Handle bridged types. if (!isa(BGT->getDecl()) && - printIfObjCBridgeable(BGT->getDecl(), BGT->getGenericArgs(), + printIfObjCBridgeable(BGT->getDecl(), BGT->getDirectGenericArgs(), optionalKind)) return; diff --git a/lib/PrintAsObjC/ModuleContentsWriter.cpp b/lib/PrintAsObjC/ModuleContentsWriter.cpp index ba703f28937cc..6918120ba1626 100644 --- a/lib/PrintAsObjC/ModuleContentsWriter.cpp +++ b/lib/PrintAsObjC/ModuleContentsWriter.cpp @@ -84,7 +84,7 @@ class ReferencedTypeFinder : public TypeDeclFinder { bool isObjCGeneric = decl->hasClangNode(); auto sig = decl->getGenericSignature(); - for_each(boundGeneric->getGenericArgs(), + for_each(boundGeneric->getDirectGenericArgs(), sig->getInnermostGenericParams(), [&](Type argTy, GenericTypeParamType *paramTy) { // FIXME: I think there's a bug here with recursive generic types. diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 0091d35779c08..c8a7bce3feaa8 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -3327,7 +3327,7 @@ static CanType copyOptionalityFromDerivedToBase(TypeConverter &tc, base = copyOptionalityFromDerivedToBase(tc, derived, base); auto optDecl = tc.Context.getOptionalDecl(); - return CanType(BoundGenericEnumType::get(optDecl, Type(), base)); + return BoundGenericType::get(optDecl, Type(), base)->getCanonicalType(); } // (T1, T2, ...) +> (S1, S2, ...) = (T1 +> S1, T2 +> S2, ...) @@ -3807,10 +3807,10 @@ class SILTypeSubstituter : return visitType(origType); } - CanType origObjectType = origType.getGenericArgs()[0]; - CanType substObjectType = visit(origObjectType); - return CanType(BoundGenericType::get(origType->getDecl(), Type(), - substObjectType)); + const CanType origObjectType = origType.getDirectGenericArgs()[0]; + const CanType substObjectType = visit(origObjectType); + return BoundGenericType::get(origType->getDecl(), Type(), substObjectType) + ->getCanonicalType(); } /// Any other type would be a valid type in the AST. Just apply the diff --git a/lib/SIL/IR/SILType.cpp b/lib/SIL/IR/SILType.cpp index 48ca1e5cbc47d..7d9ea6e8c75bb 100644 --- a/lib/SIL/IR/SILType.cpp +++ b/lib/SIL/IR/SILType.cpp @@ -71,9 +71,9 @@ SILType SILType::getBuiltinWordType(const ASTContext &C) { SILType SILType::getOptionalType(SILType type) { auto &ctx = type.getASTContext(); - auto optType = BoundGenericEnumType::get(ctx.getOptionalDecl(), Type(), - { type.getASTType() }); - return getPrimitiveType(CanType(optType), type.getCategory()); + auto optType = BoundGenericType::get(ctx.getOptionalDecl(), Type(), + { type.getASTType() }); + return getPrimitiveType(optType->getCanonicalType(), type.getCategory()); } SILType SILType::getSILTokenType(const ASTContext &C) { diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index fd3e8f28fe6d2..de0fa00f3ae77 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -1674,7 +1674,8 @@ static CanType computeLoweredOptionalType(TypeConverter &tc, } auto optDecl = tc.Context.getOptionalDecl(); - return CanType(BoundGenericEnumType::get(optDecl, Type(), loweredObjectType)); + return BoundGenericType::get(optDecl, Type(), loweredObjectType) + ->getCanonicalType(); } static CanType diff --git a/lib/SIL/Utils/DynamicCasts.cpp b/lib/SIL/Utils/DynamicCasts.cpp index fcdbd25fd0268..496028c051ac4 100644 --- a/lib/SIL/Utils/DynamicCasts.cpp +++ b/lib/SIL/Utils/DynamicCasts.cpp @@ -686,8 +686,8 @@ swift::classifyDynamicCast(ModuleDecl *M, // Both types have to be the same kind of collection. auto typeDecl = sourceStruct->getDecl(); if (typeDecl == targetStruct->getDecl()) { - auto sourceArgs = sourceStruct.getGenericArgs(); - auto targetArgs = targetStruct.getGenericArgs(); + const auto sourceArgs = sourceStruct.getDirectGenericArgs(); + const auto targetArgs = targetStruct.getDirectGenericArgs(); // Note that we can never say that a collection cast is impossible: // a cast can always succeed on an empty collection. diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 84e74fb9db4ee..d09e7ef066fb9 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -4571,14 +4571,14 @@ class SILVerifier : public SILVerifierBase { || kpBGT->getDecl() == C.getReferenceWritableKeyPathDecl(), "keypath result must be a key path type"); - auto baseTy = CanType(kpBGT->getGenericArgs()[0]); + auto baseTy = CanType(kpBGT->getDirectGenericArgs()[0]); auto pattern = KPI->getPattern(); SubstitutionMap patternSubs = KPI->getSubstitutions(); requireSameType( baseTy, pattern->getRootType().subst(patternSubs)->getCanonicalType(), "keypath root type should match root type of keypath pattern"); - auto leafTy = CanType(kpBGT->getGenericArgs()[1]); + const auto leafTy = CanType(kpBGT->getDirectGenericArgs()[1]); requireSameType( leafTy, pattern->getValueType().subst(patternSubs)->getCanonicalType(), "keypath value type should match value type of keypath pattern"); diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 631dd9f88bbf4..e834e3ebd70ac 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -3629,8 +3629,8 @@ RValue RValueEmitter::visitKeyPathExpr(KeyPathExpr *E, SGFContext C) { SmallVector loweredComponents; auto loweredTy = SGF.getLoweredType(E->getType()); - CanType rootTy = E->getType()->castTo()->getGenericArgs()[0] - ->getCanonicalType(); + CanType rootTy = E->getType()->castTo() + ->getDirectGenericArgs()[0]->getCanonicalType(); bool needsGenericContext = false; if (rootTy->hasArchetype()) { @@ -3829,7 +3829,7 @@ RValue RValueEmitter::visitCollectionExpr(CollectionExpr *E, SGFContext C) { arrayType = E->getType()->getCanonicalType(); auto genericType = cast(arrayType); assert(genericType->getDecl() == SGF.getASTContext().getArrayDecl()); - elementType = genericType.getGenericArgs()[0]; + elementType = genericType.getDirectGenericArgs()[0]; } VarargsInfo varargsInfo = diff --git a/lib/SILGen/SILGenLValue.cpp b/lib/SILGen/SILGenLValue.cpp index da8d723b8d4b4..553f7e8e8ff85 100644 --- a/lib/SILGen/SILGenLValue.cpp +++ b/lib/SILGen/SILGenLValue.cpp @@ -1924,7 +1924,7 @@ emitUpcastToKeyPath(SILGenFunction &SGF, SILLocation loc, auto derivedKeyPathTy = keyPath.getType().castTo(); auto baseKeyPathTy = BoundGenericType::get(SGF.getASTContext().getKeyPathDecl(), - Type(), derivedKeyPathTy->getGenericArgs()) + Type(), derivedKeyPathTy->getDirectGenericArgs()) ->getCanonicalType(); return SGF.B.createUpcast(loc, keyPath, SILType::getPrimitiveObjectType(baseKeyPathTy)); @@ -1966,11 +1966,13 @@ namespace { TypeKind == KPTK_ReferenceWritableKeyPath) { projectFn = SGF.getASTContext().getGetAtKeyPath(); - auto keyPathTy = keyPathValue.getType().castTo(); - assert(keyPathTy->getGenericArgs().size() == 2); - assert(keyPathTy->getGenericArgs()[0]->getCanonicalType() == + const auto genericArgs = keyPathValue.getType() + .castTo() + ->getDirectGenericArgs(); + assert(genericArgs.size() == 2); + assert(genericArgs[0]->getCanonicalType() == BaseFormalType->getCanonicalType()); - typeArgs.push_back(keyPathTy->getGenericArgs()[1]); + typeArgs.push_back(genericArgs[1]); keyPathValue = emitUpcastToKeyPath(SGF, loc, TypeKind, keyPathValue); } else { @@ -2005,7 +2007,7 @@ namespace { auto keyPathTy = keyPathValue.getType().castTo(); auto subs = SubstitutionMap::get(setFn->getGenericSignature(), - keyPathTy->getGenericArgs(), + keyPathTy->getDirectGenericArgs(), ArrayRef()); auto origType = AbstractionPattern::getOpaque(); @@ -2078,10 +2080,10 @@ namespace { auto projectFnRef = SGF.B.createManagedFunctionRef(loc, projectFn); auto projectFnType = projectFn->getLoweredFunctionType(); - auto keyPathTy = keyPathValue.getType().castTo(); - auto subs = SubstitutionMap::get( - projectFnType->getInvocationGenericSignature(), - keyPathTy->getGenericArgs(), {}); + const auto keyPathTy = keyPathValue.getType().castTo(); + const auto subs = SubstitutionMap::get( + projectFnType->getInvocationGenericSignature(), + ArrayRef(keyPathTy->getDirectGenericArgs()), {}); auto substFnType = projectFnType->substGenericArgs( SGF.SGM.M, subs, SGF.getTypeExpansionContext()); diff --git a/lib/SILOptimizer/Analysis/ArraySemantic.cpp b/lib/SILOptimizer/Analysis/ArraySemantic.cpp index abfd4510a4cbe..237746f17d054 100644 --- a/lib/SILOptimizer/Analysis/ArraySemantic.cpp +++ b/lib/SILOptimizer/Analysis/ArraySemantic.cpp @@ -586,7 +586,7 @@ bool swift::ArraySemanticsCall::mayHaveBridgedObjectElementType() const { if (auto BGT = Ty.getAs()) { // Check the array element type parameter. bool isClass = true; - for (auto EltTy : BGT->getGenericArgs()) { + for (const auto &EltTy : BGT->getDirectGenericArgs()) { if (EltTy->isBridgeableObjectType()) return true; isClass = false; diff --git a/lib/SILOptimizer/Analysis/DestructorAnalysis.cpp b/lib/SILOptimizer/Analysis/DestructorAnalysis.cpp index 73705b794edcf..50e0e536b1687 100644 --- a/lib/SILOptimizer/Analysis/DestructorAnalysis.cpp +++ b/lib/SILOptimizer/Analysis/DestructorAnalysis.cpp @@ -111,7 +111,7 @@ bool DestructorAnalysis::areTypeParametersSafe(CanType Ty) { return false; // Make sure all type parameters are safe. - for (auto TP : BGT->getGenericArgs()) { + for (const auto &TP : BGT->getDirectGenericArgs()) { if (!isSafeType(TP->getCanonicalType())) return false; } diff --git a/lib/SILOptimizer/Differentiation/PullbackEmitter.cpp b/lib/SILOptimizer/Differentiation/PullbackEmitter.cpp index 182c8862d2352..b234264054099 100644 --- a/lib/SILOptimizer/Differentiation/PullbackEmitter.cpp +++ b/lib/SILOptimizer/Differentiation/PullbackEmitter.cpp @@ -1428,7 +1428,8 @@ PullbackEmitter::getArrayAdjointElementBuffer(SILValue arrayAdjoint, auto &ctx = builder.getASTContext(); auto arrayTanType = cast(arrayAdjoint->getType().getASTType()); auto arrayType = arrayTanType->getParent()->castTo(); - auto eltTanType = arrayType->getGenericArgs().front()->getCanonicalType(); + auto eltTanType = + arrayType->getDirectGenericArgs().front()->getCanonicalType(); auto eltTanSILType = remapType(SILType::getPrimitiveAddressType(eltTanType)); // Get `function_ref` and generic signature of // `Array.TangentVector.subscript.getter`. diff --git a/lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp b/lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp index b734d134cf29e..793fa5517da1f 100644 --- a/lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp +++ b/lib/SILOptimizer/LoopTransforms/ArrayPropertyOpt.cpp @@ -368,7 +368,7 @@ class ArrayPropertiesAnalysis { if (auto BGT = Ty.getAs()) { // Check the array element type parameter. bool isClass = false; - for (auto EltTy : BGT->getGenericArgs()) { + for (const auto &EltTy : BGT->getDirectGenericArgs()) { if (!EltTy->hasReferenceSemantics()) return false; isClass = true; diff --git a/lib/SILOptimizer/Utils/ConstExpr.cpp b/lib/SILOptimizer/Utils/ConstExpr.cpp index 6829541fe2ff6..a0d5dab54afd2 100644 --- a/lib/SILOptimizer/Utils/ConstExpr.cpp +++ b/lib/SILOptimizer/Utils/ConstExpr.cpp @@ -819,7 +819,7 @@ extractStringOrStaticStringValue(SymbolicValue stringValue) { static Type getArrayElementType(Type ty) { if (auto bgst = ty->getAs()) if (bgst->getDecl() == bgst->getASTContext().getArrayDecl()) - return bgst->getGenericArgs()[0]; + return bgst->getDirectGenericArgs()[0]; return Type(); } diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index fab8829dc56c0..c707f4722fe26 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -93,8 +93,7 @@ static std::pair getTypeDepthAndWidth(Type t) { } ++Depth; unsigned MaxTypeDepth = 0; - auto GenericArgs = BGT->getGenericArgs(); - for (auto Ty : GenericArgs) { + for (const auto &Ty : BGT->getDirectGenericArgs()) { unsigned TypeWidth; unsigned TypeDepth; std::tie(TypeDepth, TypeWidth) = getTypeDepthAndWidth(Ty); diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 43bac6311dfda..967cd5526dae8 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -1657,8 +1657,8 @@ namespace { llvm_unreachable("unknown key path class!"); } } else { - auto keyPathBGT = keyPathTy->castTo(); - baseTy = keyPathBGT->getGenericArgs()[0]; + const auto keyPathBGT = keyPathTy->castTo(); + baseTy = keyPathBGT->getDirectGenericArgs()[0]; // Coerce the index to the key path's type indexKP = coerceToType(indexKP, keyPathTy, locator); @@ -1677,7 +1677,7 @@ namespace { } else { // *KeyPath is T -> U, with rvalueness based on mutability // of base and keypath - valueTy = keyPathBGT->getGenericArgs()[1]; + valueTy = keyPathBGT->getDirectGenericArgs()[1]; // The result may be an lvalue based on the base and key path kind. if (keyPathBGT->getDecl() == cs.getASTContext().getKeyPathDecl()) { @@ -4575,9 +4575,10 @@ namespace { leafTy = fnTy->getResult(); isFunctionType = true; } else { - auto keyPathTy = exprType->castTo(); - baseTy = keyPathTy->getGenericArgs()[0]; - leafTy = keyPathTy->getGenericArgs()[1]; + const auto genericArgs = + exprType->castTo()->getDirectGenericArgs(); + baseTy = genericArgs[0]; + leafTy = genericArgs[1]; } // Track the type of the current component. Once we finish projecting @@ -5990,9 +5991,9 @@ buildOpaqueElementConversion(ExprRewriter &rewriter, SourceRange srcRange, unsigned typeArgIndex) { // We don't need this stuff unless we've got generalized casts. Type srcType = srcCollectionType->castTo() - ->getGenericArgs()[typeArgIndex]; + ->getDirectGenericArgs()[typeArgIndex]; Type destType = destCollectionType->castTo() - ->getGenericArgs()[typeArgIndex]; + ->getDirectGenericArgs()[typeArgIndex]; // Build the conversion. auto &cs = rewriter.getConstraintSystem(); @@ -6310,8 +6311,8 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, TypeChecker::requireOptionalIntrinsics(cs.getASTContext(), expr->getLoc()); - Type valueType = toGenericType->getGenericArgs()[0]; - expr = coerceToType(expr, valueType, locator); + expr = coerceToType(expr, toGenericType->getDirectGenericArgs()[0], + locator); if (!expr) return nullptr; auto *result = @@ -6721,8 +6722,8 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, if (cs.getType(expr)->getOptionalObjectType()) return coerceOptionalToOptional(expr, toType, locator, typeFromPattern); - Type valueType = toGenericType->getGenericArgs()[0]; - expr = coerceToType(expr, valueType, locator); + expr = coerceToType(expr, toGenericType->getDirectGenericArgs()[0], + locator); if (!expr) return nullptr; auto *result = cs.cacheType(new (ctx) InjectIntoOptionalExpr(expr, toType)); diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 26a3d77a76f11..56d1eafaf19bd 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -636,8 +636,8 @@ void GenericArgumentsMismatchFailure::emitNoteForMismatch(int position) { auto genericTypeDecl = paramSourceTy->getAnyGeneric(); auto param = genericTypeDecl->getGenericParams()->getParams()[position]; - auto lhs = getActual()->getGenericArgs()[position]; - auto rhs = getRequired()->getGenericArgs()[position]; + const auto lhs = getActual()->getDirectGenericArgs()[position]; + const auto rhs = getRequired()->getDirectGenericArgs()[position]; auto noteLocation = param->getLoc(); diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 4af283a10d048..5478e257ef44c 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -1023,7 +1023,8 @@ namespace { if (isa(indexExpr)) { - outputTy = baseObjTy->getAs()->getGenericArgs()[0]; + outputTy = baseObjTy->getAs() + ->getDirectGenericArgs()[0]; if (isLValueBase) outputTy = LValueType::get(outputTy); @@ -1691,7 +1692,7 @@ namespace { if (AnyMetatypeType *meta = baseTy->getAs()) { if (BoundGenericType *bgt = meta->getInstanceType()->getAs()) { - ArrayRef typeVars = bgt->getGenericArgs(); + const ArrayRef typeVars = bgt->getDirectGenericArgs(); auto specializations = expr->getUnresolvedParams(); // If we have too many generic arguments, complain. diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 6341a41ea7237..5571c9de7a1ac 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -2213,8 +2213,8 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2, return result; } - auto args1 = bound1->getGenericArgs(); - auto args2 = bound2->getGenericArgs(); + const auto args1 = bound1->getDirectGenericArgs(); + const auto args2 = bound2->getDirectGenericArgs(); // Match up the generic arguments, exactly. @@ -7694,7 +7694,8 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1, if (auto fromBGT = unwrappedToType->getAs()) { if (fromBGT->getDecl() == ctx.getArrayDecl()) { // [AnyObject] - addConstraint(ConstraintKind::Bind, fromBGT->getGenericArgs()[0], + addConstraint(ConstraintKind::Bind, + fromBGT->getDirectGenericArgs()[0], ctx.getAnyObjectType(), getConstraintLocator(locator.withPathElement( LocatorPathElt::GenericArgument(0)))); @@ -7706,13 +7707,15 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1, return SolutionKind::Error; } - addConstraint(ConstraintKind::Bind, fromBGT->getGenericArgs()[0], + addConstraint(ConstraintKind::Bind, + fromBGT->getDirectGenericArgs()[0], nsObjectType, getConstraintLocator( locator.withPathElement( LocatorPathElt::GenericArgument(0)))); - addConstraint(ConstraintKind::Bind, fromBGT->getGenericArgs()[1], + addConstraint(ConstraintKind::Bind, + fromBGT->getDirectGenericArgs()[1], ctx.getAnyObjectType(), getConstraintLocator( locator.withPathElement( @@ -7723,7 +7726,8 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1, // Not a bridging case. Should we detect this earlier? return SolutionKind::Error; } - addConstraint(ConstraintKind::Bind, fromBGT->getGenericArgs()[0], + addConstraint(ConstraintKind::Bind, + fromBGT->getDirectGenericArgs()[0], nsObjectType, getConstraintLocator( locator.withPathElement( @@ -7863,14 +7867,14 @@ ConstraintSystem::simplifyKeyPathConstraint( if (bgt->getDecl() == getASTContext().getKeyPathDecl() || bgt->getDecl() == getASTContext().getWritableKeyPathDecl() || bgt->getDecl() == getASTContext().getReferenceWritableKeyPathDecl()) { - boundRoot = bgt->getGenericArgs()[0]; - boundValue = bgt->getGenericArgs()[1]; + boundRoot = bgt->getDirectGenericArgs()[0]; + boundValue = bgt->getDirectGenericArgs()[1]; } else if (bgt->getDecl() == getASTContext().getPartialKeyPathDecl()) { if (!allowPartial) return false; // We can still get the root from a PartialKeyPath. - boundRoot = bgt->getGenericArgs()[0]; + boundRoot = bgt->getDirectGenericArgs()[0]; } } @@ -8145,7 +8149,7 @@ ConstraintSystem::simplifyKeyPathApplicationConstraint( if (auto bgt = keyPathTy->getAs()) { // We have the key path type. Match it to the other ends of the constraint. - auto kpRootTy = bgt->getGenericArgs()[0]; + const auto kpRootTy = bgt->getDirectGenericArgs()[0]; // Try to match the root type. rootTy = getFixedTypeRecursive(rootTy, flags, /*wantRValue=*/false); @@ -8177,9 +8181,9 @@ ConstraintSystem::simplifyKeyPathApplicationConstraint( ConstraintKind::Bind, subflags, locator); } - if (bgt->getGenericArgs().size() < 2) + if (bgt->getDirectGenericArgs().size() < 2) return SolutionKind::Error; - auto kpValueTy = bgt->getGenericArgs()[1]; + const auto kpValueTy = bgt->getDirectGenericArgs()[1]; /// Solve for an rvalue base. auto solveRValue = [&]() -> ConstraintSystem::SolutionKind { @@ -9205,7 +9209,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl( if (auto generic2 = type2->getAs()) { if (generic2->getDecl()->isOptionalDecl()) { auto result = matchTypes( - type1, generic2->getGenericArgs()[0], matchKind, subflags, + type1, generic2->getDirectGenericArgs()[0], matchKind, subflags, locator.withPathElement(ConstraintLocator::OptionalPayload)); if (!(shouldAttemptFixes() && result.isFailure())) @@ -9233,7 +9237,8 @@ ConstraintSystem::simplifyRestrictedConstraintImpl( if (generic1->getDecl()->isOptionalDecl() && generic2->getDecl()->isOptionalDecl()) { auto result = matchTypes( - generic1->getGenericArgs()[0], generic2->getGenericArgs()[0], + generic1->getDirectGenericArgs()[0], + generic2->getDirectGenericArgs()[0], matchKind, subflags, locator.withPathElement(LocatorPathElt::GenericArgument(0))); diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp index 295400c49eb62..1e2623360f1e9 100644 --- a/lib/Sema/CSSolver.cpp +++ b/lib/Sema/CSSolver.cpp @@ -940,8 +940,8 @@ void ConstraintSystem::shrink(Expr *expr) { return boundGeneric; llvm::SmallVector params; - for (auto &type : boundGeneric->getGenericArgs()) { - // One of the generic arguments in invalid or unresolved. + for (const auto &type : boundGeneric->getDirectGenericArgs()) { + // One of the generic arguments is invalid or unresolved. if (isInvalidType(type)) return type; diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 940a4deb6923f..73f3d204bc261 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -852,7 +852,7 @@ FunctionType *ConstraintSystem::openFunctionType( Optional ConstraintSystem::isArrayType(Type type) { if (auto boundStruct = type->getAs()) { if (boundStruct->getDecl() == type->getASTContext().getArrayDecl()) - return boundStruct->getGenericArgs()[0]; + return boundStruct->getDirectGenericArgs()[0]; } return None; @@ -861,7 +861,7 @@ Optional ConstraintSystem::isArrayType(Type type) { Optional> ConstraintSystem::isDictionaryType(Type type) { if (auto boundStruct = type->getAs()) { if (boundStruct->getDecl() == type->getASTContext().getDictionaryDecl()) { - auto genericArgs = boundStruct->getGenericArgs(); + const auto genericArgs = boundStruct->getDirectGenericArgs(); return std::make_pair(genericArgs[0], genericArgs[1]); } } @@ -872,7 +872,7 @@ Optional> ConstraintSystem::isDictionaryType(Type type) { Optional ConstraintSystem::isSetType(Type type) { if (auto boundStruct = type->getAs()) { if (boundStruct->getDecl() == type->getASTContext().getSetDecl()) - return boundStruct->getGenericArgs()[0]; + return boundStruct->getDirectGenericArgs()[0]; } return None; @@ -2238,8 +2238,8 @@ void ConstraintSystem::bindOverloadType( auto *keyPathLoc = getConstraintLocator( locator, LocatorPathElt::KeyPathDynamicMember(keyPathDecl)); - auto rootTy = keyPathTy->getGenericArgs()[0]; - auto leafTy = keyPathTy->getGenericArgs()[1]; + const auto rootTy = keyPathTy->getDirectGenericArgs()[0]; + const auto leafTy = keyPathTy->getDirectGenericArgs()[1]; // Member would either point to mutable or immutable property, we // don't which at the moment, so let's allow its type to be l-value. diff --git a/lib/Sema/IDETypeCheckingRequests.cpp b/lib/Sema/IDETypeCheckingRequests.cpp index 739694f801205..4eae2cd537b78 100644 --- a/lib/Sema/IDETypeCheckingRequests.cpp +++ b/lib/Sema/IDETypeCheckingRequests.cpp @@ -125,8 +125,7 @@ RootAndResultTypeOfKeypathDynamicMemberRequest::evaluate(Evaluator &evaluator, auto keyPathType = param->getType()->getAs(); if (!keyPathType) return TypePair(); - auto genericArgs = keyPathType->getGenericArgs(); - assert(!genericArgs.empty() && genericArgs.size() == 2 && - "invalid keypath dynamic member"); + const auto genericArgs = keyPathType->getDirectGenericArgs(); + assert(genericArgs.size() == 2 && "invalid keypath dynamic member"); return TypePair(genericArgs[0], genericArgs[1]); } diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index 28c1b5b03e12c..cb68e6eda0f0d 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -4496,7 +4496,7 @@ static OmissionTypeName getTypeNameForOmission(Type type) { // If we have a collection, get the element type. if (auto bound = type->getAs()) { ASTContext &ctx = nominal->getASTContext(); - auto args = bound->getGenericArgs(); + const auto args = bound->getDirectGenericArgs(); if (!args.empty() && (bound->getDecl() == ctx.getArrayDecl() || bound->getDecl() == ctx.getSetDecl())) { diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index e2f05cfb4f7b4..78e4d99e52340 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -550,7 +550,7 @@ isAcceptableOutletType(Type type, bool &isArray, ASTContext &ctx) { // Handle Array. T must be an Objective-C class or protocol. auto boundTy = type->castTo(); - auto boundArgs = boundTy->getGenericArgs(); + const auto boundArgs = boundTy->getDirectGenericArgs(); assert(boundArgs.size() == 1 && "invalid Array declaration"); Type elementTy = boundArgs.front(); return isAcceptableOutletType(elementTy, isArray, ctx); diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index be05a54427f8a..5ee92bffdd9ee 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -2140,7 +2140,7 @@ bool isSubscriptReturningString(const ValueDecl *D, ASTContext &Context) { if (!inputTy) return false; - auto genericArgs = inputTy->getGenericArgs(); + const auto genericArgs = inputTy->getDirectGenericArgs(); if (genericArgs.size() != 1) return false; diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 145de572b43c3..42def5a3832de 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -2581,7 +2581,7 @@ bool TypeChecker::isPassThroughTypealias(TypeAliasDecl *typealias, // If our arguments line up with our innermost generic parameters, it's // a passthrough typealias. auto innermostGenericParams = typealiasSig->getInnermostGenericParams(); - auto boundArgs = boundGenericType->getGenericArgs(); + const auto boundArgs = boundGenericType->getDirectGenericArgs(); if (boundArgs.size() != innermostGenericParams.size()) return false; diff --git a/lib/Sema/TypeCheckExprObjC.cpp b/lib/Sema/TypeCheckExprObjC.cpp index 8fcd77a4de05c..5e47ec2af2899 100644 --- a/lib/Sema/TypeCheckExprObjC.cpp +++ b/lib/Sema/TypeCheckExprObjC.cpp @@ -101,7 +101,7 @@ Optional TypeChecker::checkObjCKeyPathExpr(DeclContext *dc, if (nominal == Context.getArrayDecl()) { // Further lookups into the element type. state = ResolvingArray; - currentType = boundGeneric->getGenericArgs()[0]; + currentType = boundGeneric->getDirectGenericArgs()[0]; return; } @@ -109,7 +109,7 @@ Optional TypeChecker::checkObjCKeyPathExpr(DeclContext *dc, if (nominal == Context.getSetDecl()) { // Further lookups into the element type. state = ResolvingSet; - currentType = boundGeneric->getGenericArgs()[0]; + currentType = boundGeneric->getDirectGenericArgs()[0]; return; } @@ -118,7 +118,7 @@ Optional TypeChecker::checkObjCKeyPathExpr(DeclContext *dc, // Key paths look into the keys of a dictionary; further // lookups into the value type. state = ResolvingDictionary; - currentType = boundGeneric->getGenericArgs()[1]; + currentType = boundGeneric->getDirectGenericArgs()[1]; return; } } diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp index c18cc16e3d965..08012dc6acf10 100644 --- a/lib/Sema/TypeCheckGeneric.cpp +++ b/lib/Sema/TypeCheckGeneric.cpp @@ -523,11 +523,11 @@ static Type formExtensionInterfaceType( // Form the result. Type resultType; - SmallVector genericArgs; if (!nominal->isGeneric() || isa(nominal)) { resultType = NominalType::get(nominal, parentType, nominal->getASTContext()); } else { + SmallVector genericArgs; auto currentBoundType = type->getAs(); // Form the bound generic type with the type parameters provided. @@ -540,7 +540,7 @@ static Type formExtensionInterfaceType( if (currentBoundType) { sameTypeReqs.emplace_back(RequirementKind::SameType, gpType, - currentBoundType->getGenericArgs()[gpIndex]); + currentBoundType->getDirectGenericArgs()[gpIndex]); } } diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index f24f3df0c0c0e..c1b10ded19e21 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -1084,7 +1084,8 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, } } else if (auto *BST = diagTy->getAs()) { if (BST->getDecl() == Context.getArrayDecl()) - shouldRequireType = BST->getGenericArgs()[0]->isEqual(Context.TheEmptyTupleType); + shouldRequireType = BST->getDirectGenericArgs()[0] + ->isEqual(Context.TheEmptyTupleType); } if (shouldRequireType && diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index c3f88e324c88d..5c15f9eba1bf3 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -591,8 +591,8 @@ static bool isPointerToVoid(ASTContext &Ctx, Type Ty, bool &IsMutable) { BGT->getDecl() != Ctx.getUnsafeMutablePointerDecl()) return false; IsMutable = BGT->getDecl() == Ctx.getUnsafeMutablePointerDecl(); - assert(BGT->getGenericArgs().size() == 1); - return BGT->getGenericArgs().front()->isVoid(); + assert(BGT->getDirectGenericArgs().size() == 1); + return BGT->getDirectGenericArgs().front()->isVoid(); } static Type checkContextualRequirements(Type type, @@ -809,7 +809,7 @@ Type TypeChecker::applyUnboundGenericArguments(GenericTypeDecl *decl, "invalid arguments, use applyGenericArguments for diagnostic emitting"); auto genericSig = decl->getGenericSignature(); - assert(!genericSig.isNull()); + assert(genericSig); TypeSubstitutionMap subs; diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index baebdbba93bd4..07c1a1b80069b 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -5291,10 +5291,10 @@ class TypeDeserializer { StringRef blobData) { DeclID declID; TypeID parentID; - ArrayRef rawArgumentIDs; + SubstitutionMapID substitutionsID; decls_block::BoundGenericTypeLayout::readRecord(scratch, declID, parentID, - rawArgumentIDs); + substitutionsID); auto nominalOrError = MF.getDeclChecked(declID); if (!nominalOrError) @@ -5304,16 +5304,12 @@ class TypeDeserializer { // FIXME: Check this? auto parentTy = MF.getType(parentID); - SmallVector genericArgs; - for (TypeID ID : rawArgumentIDs) { - auto argTy = MF.getTypeChecked(ID); - if (!argTy) - return argTy.takeError(); - - genericArgs.push_back(argTy.get()); - } + // Read the substitutions. + auto subMapOrError = MF.getSubstitutionMapChecked(substitutionsID); + if (!subMapOrError) + return subMapOrError.takeError(); - return BoundGenericType::get(nominal, parentTy, genericArgs); + return BoundGenericType::get(nominal, parentTy, subMapOrError.get()); } Expected deserializeSILBlockStorageType(ArrayRef scratch, diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 88c11081e8905..a86b3d8cf5dd5 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -55,7 +55,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 562; // base_addr_for_offset instruction +const uint16_t SWIFTMODULE_VERSION_MINOR = 563; // BoundGenericType layout; /// A standard hash seed used for all string hashes in a serialized module. /// @@ -1029,7 +1029,7 @@ namespace decls_block { BOUND_GENERIC_TYPE, DeclIDField, // generic decl TypeIDField, // parent - BCArray // generic arguments + SubstitutionMapIDField // the arguments >; using GenericFunctionTypeLayout = BCRecordLayout< diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 6b6d26d1e5646..eb04e79e6dcec 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -4288,16 +4288,12 @@ class Serializer::TypeSerializer : public TypeVisitor { void visitBoundGenericType(const BoundGenericType *generic) { using namespace decls_block; - SmallVector genericArgIDs; - - for (auto next : generic->getGenericArgs()) - genericArgIDs.push_back(S.addTypeRef(next)); - unsigned abbrCode = S.DeclTypeAbbrCodes[BoundGenericTypeLayout::Code]; - BoundGenericTypeLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode, - S.addDeclRef(generic->getDecl()), - S.addTypeRef(generic->getParent()), - genericArgIDs); + BoundGenericTypeLayout::emitRecord( + S.Out, S.ScratchRecord, abbrCode, + S.addDeclRef(generic->getDecl()), + S.addTypeRef(generic->getParent()), + S.addSubstitutionMapRef(generic->getSubstitutionMap())); } }; diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp index a48769a9bc2f0..4678648baaa58 100644 --- a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp +++ b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp @@ -1508,7 +1508,7 @@ SwiftDeclCollector::constructTypeNode(Type T, TypeInitInfo Info) { // Handle the case where Type has sub-types. if (auto BGT = T->getAs()) { - for (auto Arg : BGT->getGenericArgs()) { + for (auto Arg : BGT->getDirectGenericArgs()) { Root->addChild(constructTypeNode(Arg)); } } else if (auto Tup = T->getAs()) {