diff --git a/include/swift/AST/ASTContext.h b/include/swift/AST/ASTContext.h index 46a00561d51f8..1fb7ec26b3766 100644 --- a/include/swift/AST/ASTContext.h +++ b/include/swift/AST/ASTContext.h @@ -482,7 +482,10 @@ class ASTContext final { #define KNOWN_STDLIB_TYPE_DECL(NAME, DECL_CLASS, NUM_GENERIC_PARAMS) \ /** Retrieve the declaration of Swift.NAME. */ \ - DECL_CLASS *get##NAME##Decl() const; + DECL_CLASS *get##NAME##Decl() const; \ +\ + /** Retrieve the type of Swift.NAME. */ \ + Type get##NAME##Type() const; #include "swift/AST/KnownStdlibTypes.def" /// Retrieve the declaration of Swift.Optional.Some. @@ -491,15 +494,18 @@ class ASTContext final { /// Retrieve the declaration of Swift.Optional.None. EnumElementDecl *getOptionalNoneDecl() const; + /// Retrieve the declaration of Swift.Void. + TypeAliasDecl *getVoidDecl() const; + + /// Retrieve the type of Swift.Void. + Type getVoidType() const; + /// Retrieve the declaration of the "pointee" property of a pointer type. VarDecl *getPointerPointeePropertyDecl(PointerTypeKind ptrKind) const; /// Retrieve the type Swift.AnyObject. CanType getAnyObjectType() const; - /// Retrieve the type Swift.Never. - CanType getNeverType() const; - #define KNOWN_SDK_TYPE_DECL(MODULE, NAME, DECL_CLASS, NUM_GENERIC_PARAMS) \ /** Retrieve the declaration of MODULE.NAME. */ \ DECL_CLASS *get##NAME##Decl() const; \ diff --git a/include/swift/AST/KnownProtocols.def b/include/swift/AST/KnownProtocols.def index c996e37e5608c..93d2b937134ef 100644 --- a/include/swift/AST/KnownProtocols.def +++ b/include/swift/AST/KnownProtocols.def @@ -71,6 +71,7 @@ PROTOCOL(OptionSet) PROTOCOL(CaseIterable) PROTOCOL(SIMDScalar) PROTOCOL(BinaryInteger) +PROTOCOL(RangeReplaceableCollection) PROTOCOL_(BridgedNSError) PROTOCOL_(BridgedStoredNSError) diff --git a/include/swift/AST/KnownStdlibTypes.def b/include/swift/AST/KnownStdlibTypes.def index 93f99d43caa9b..190bcd5363692 100644 --- a/include/swift/AST/KnownStdlibTypes.def +++ b/include/swift/AST/KnownStdlibTypes.def @@ -25,8 +25,6 @@ #define KNOWN_STDLIB_TYPE_DECL(NAME, DECL_CLASS, NUM_GENERIC_PARAMS) #endif -KNOWN_STDLIB_TYPE_DECL(Void, TypeAliasDecl, 0) - KNOWN_STDLIB_TYPE_DECL(Bool, NominalTypeDecl, 0) KNOWN_STDLIB_TYPE_DECL(Int, NominalTypeDecl, 0) @@ -89,7 +87,6 @@ KNOWN_STDLIB_TYPE_DECL(Encoder, ProtocolDecl, 1) KNOWN_STDLIB_TYPE_DECL(Decoder, ProtocolDecl, 1) KNOWN_STDLIB_TYPE_DECL(KeyedEncodingContainer, NominalTypeDecl, 1) KNOWN_STDLIB_TYPE_DECL(KeyedDecodingContainer, NominalTypeDecl, 1) -KNOWN_STDLIB_TYPE_DECL(RangeReplaceableCollection, ProtocolDecl, 1) KNOWN_STDLIB_TYPE_DECL(EncodingError, NominalTypeDecl, 0) KNOWN_STDLIB_TYPE_DECL(DecodingError, NominalTypeDecl, 0) diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index 807fb1f216ffa..1496a5a1b1c80 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -792,8 +792,10 @@ class alignas(1 << TypeAlignInBits) TypeBase { /// Check if this type is equal to the empty tuple type. bool isVoid(); - /// Check if this type is equal to Swift.Bool. - bool isBool(); + #define KNOWN_STDLIB_TYPE_DECL(NAME, DECL_CLASS, NUM_GENERIC_PARAMS) \ + /** Check if this type is equal to Swift.NAME. */ \ + bool is##NAME(); + #include "swift/AST/KnownStdlibTypes.def" /// Check if this type is equal to Builtin.IntN. bool isBuiltinIntegerType(unsigned bitWidth); @@ -805,9 +807,6 @@ class alignas(1 << TypeAlignInBits) TypeBase { /// on macOS or Foundation on Linux. bool isCGFloatType(); - /// Check if this is a Double type from standard library. - bool isDoubleType(); - /// Check if this is either an Array, Set or Dictionary collection type defined /// at the top level of the Swift module bool isKnownStdlibCollectionType(); diff --git a/include/swift/Sema/ConstraintSystem.h b/include/swift/Sema/ConstraintSystem.h index 7779cef11e1e3..980ac5ad987e5 100644 --- a/include/swift/Sema/ConstraintSystem.h +++ b/include/swift/Sema/ConstraintSystem.h @@ -3793,9 +3793,6 @@ class ConstraintSystem { /// element type of the set. static Optional isSetType(Type t); - /// Determine if the type in question is AnyHashable. - static bool isAnyHashableType(Type t); - /// Call Expr::isTypeReference on the given expression, using a /// custom accessor for the type on the expression that reads the /// type from the ConstraintSystem expression type map. diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index ea0cd13e3f609..8460b9e4234c0 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -218,6 +218,9 @@ struct ASTContext::Implementation { /// The declaration of Swift.Optional.None. EnumElementDecl *OptionalNoneDecl = nullptr; + /// The declaration of Swift.Void. + TypeAliasDecl *VoidDecl = nullptr; + /// The declaration of Swift.UnsafeMutableRawPointer.memory. VarDecl *UnsafeMutableRawPointerMemoryDecl = nullptr; @@ -712,7 +715,8 @@ FuncDecl *ASTContext::getPlusFunctionOnRangeReplaceableCollection() const { continue; for (auto Req: FD->getGenericRequirements()) { if (Req.getKind() == RequirementKind::Conformance && - Req.getProtocolDecl() == getRangeReplaceableCollectionDecl()) { + Req.getProtocolDecl() == + getProtocol(KnownProtocolKind::RangeReplaceableCollection)) { getImpl().PlusFunctionOnRangeReplaceableCollection = FD; } } @@ -733,17 +737,13 @@ FuncDecl *ASTContext::getPlusFunctionOnString() const { if (!FD->getOperatorDecl()) continue; auto ResultType = FD->getResultInterfaceType(); - if (ResultType->getNominalOrBoundGenericNominal() != getStringDecl()) + if (!ResultType->isString()) continue; auto ParamList = FD->getParameters(); if (ParamList->size() != 2) continue; - auto CheckIfStringParam = [this](ParamDecl* Param) { - auto Type = Param->getInterfaceType()->getNominalOrBoundGenericNominal(); - return Type == getStringDecl(); - }; - if (CheckIfStringParam(ParamList->get(0)) && - CheckIfStringParam(ParamList->get(1))) { + if (ParamList->get(0)->getInterfaceType()->isString() && + ParamList->get(1)->getInterfaceType()->isString()) { getImpl().PlusFunctionOnString = FD; break; } @@ -803,22 +803,28 @@ FuncDecl *ASTContext::getAsyncSequenceMakeAsyncIterator() const { } #define KNOWN_STDLIB_TYPE_DECL(NAME, DECL_CLASS, NUM_GENERIC_PARAMS) \ - DECL_CLASS *ASTContext::get##NAME##Decl() const { \ - if (getImpl().NAME##Decl) \ - return getImpl().NAME##Decl; \ - SmallVector results; \ - lookupInSwiftModule(#NAME, results); \ - for (auto result : results) { \ - if (auto type = dyn_cast(result)) { \ - auto params = type->getGenericParams(); \ - if (NUM_GENERIC_PARAMS == (params == nullptr ? 0 : params->size())) { \ - getImpl().NAME##Decl = type; \ - return type; \ - } \ +DECL_CLASS *ASTContext::get##NAME##Decl() const { \ + if (getImpl().NAME##Decl) \ + return getImpl().NAME##Decl; \ + SmallVector results; \ + lookupInSwiftModule(#NAME, results); \ + for (auto result : results) { \ + if (auto type = dyn_cast(result)) { \ + auto params = type->getGenericParams(); \ + if (NUM_GENERIC_PARAMS == (params == nullptr ? 0 : params->size())) { \ + getImpl().NAME##Decl = type; \ + return type; \ } \ } \ - return nullptr; \ - } + } \ + return nullptr; \ +} \ +\ +Type ASTContext::get##NAME##Type() const { \ + if (!get##NAME##Decl()) \ + return Type(); \ + return get##NAME##Decl()->getDeclaredInterfaceType(); \ +} #include "swift/AST/KnownStdlibTypes.def" CanType ASTContext::getExceptionType() const { @@ -846,6 +852,30 @@ EnumElementDecl *ASTContext::getOptionalNoneDecl() const { return getImpl().OptionalNoneDecl; } +TypeAliasDecl *ASTContext::getVoidDecl() const { + if (getImpl().VoidDecl) { + return getImpl().VoidDecl; + } + + SmallVector results; + lookupInSwiftModule("Void", results); + for (auto result : results) { + if (auto typealias = dyn_cast(result)) { + getImpl().VoidDecl = typealias; + return typealias; + } + } + + return nullptr; +} + +Type ASTContext::getVoidType() const { + auto decl = getVoidDecl(); + if (!decl) + return Type(); + return decl->getDeclaredInterfaceType(); +} + static VarDecl *getPointeeProperty(VarDecl *&cache, NominalTypeDecl *(ASTContext::*getNominal)() const, const ASTContext &ctx) { @@ -911,13 +941,6 @@ CanType ASTContext::getAnyObjectType() const { return getImpl().AnyObjectType; } -CanType ASTContext::getNeverType() const { - auto neverDecl = getNeverDecl(); - if (!neverDecl) - return CanType(); - return neverDecl->getDeclaredInterfaceType()->getCanonicalType(); -} - #define KNOWN_SDK_TYPE_DECL(MODULE, NAME, DECLTYPE, GENERIC_ARGS) \ DECLTYPE *ASTContext::get##NAME##Decl() const { \ if (!getImpl().NAME##Decl) { \ @@ -1159,19 +1182,18 @@ FuncDecl *getBinaryComparisonOperatorIntDecl(const ASTContext &C, StringRef op, if (!C.getIntDecl() || !C.getBoolDecl()) return nullptr; - auto intType = C.getIntDecl()->getDeclaredInterfaceType(); auto isIntParam = [&](AnyFunctionType::Param param) { return (!param.isVariadic() && !param.isInOut() && - param.getPlainType()->isEqual(intType)); + param.getPlainType()->isInt()); }; - auto boolType = C.getBoolDecl()->getDeclaredInterfaceType(); - auto decl = lookupOperatorFunc(C, op, intType, - [=](FunctionType *type) { + + auto decl = lookupOperatorFunc(C, op, C.getIntType(), + [=](FunctionType *type) { // Check for the signature: (Int, Int) -> Bool if (type->getParams().size() != 2) return false; if (!isIntParam(type->getParams()[0]) || !isIntParam(type->getParams()[1])) return false; - return type->getResult()->isEqual(boolType); + return type->getResult()->isBool(); }); cached = decl; return decl; @@ -1226,11 +1248,8 @@ FuncDecl *ASTContext::getArrayAppendElementDecl() const { return nullptr; auto SelfInOutTy = SelfDecl->getInterfaceType(); - BoundGenericStructType *SelfGenericStructTy = - SelfInOutTy->getAs(); - if (!SelfGenericStructTy) - return nullptr; - if (SelfGenericStructTy->getDecl() != getArrayDecl()) + + if (!SelfInOutTy->isArray()) return nullptr; auto ParamList = FnDecl->getParameters(); @@ -1273,11 +1292,8 @@ FuncDecl *ASTContext::getArrayReserveCapacityDecl() const { return nullptr; auto SelfInOutTy = SelfDecl->getInterfaceType(); - BoundGenericStructType *SelfGenericStructTy = - SelfInOutTy->getAs(); - if (!SelfGenericStructTy) - return nullptr; - if (SelfGenericStructTy->getDecl() != getArrayDecl()) + + if (!SelfInOutTy->isArray()) return nullptr; auto ParamList = FnDecl->getParameters(); @@ -4631,7 +4647,7 @@ Type ASTContext::getBridgedToObjC(const DeclContext *dc, Type type, [&](KnownProtocolKind known) -> ProtocolConformanceRef { // Don't ascribe any behavior to Optional other than what we explicitly // give it. We don't want things like AnyObject?? to work. - if (type->getAnyNominal() == getOptionalDecl()) + if (type->isOptional()) return ProtocolConformanceRef::forInvalid(); // Find the protocol. diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 0a279313f339d..e1136540d8033 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -4517,15 +4517,13 @@ class TypePrinter : public TypeVisitor { void visitBoundGenericType(BoundGenericType *T) { if (Options.SynthesizeSugarOnTypes) { - auto *NT = T->getDecl(); - auto &Ctx = T->getASTContext(); - if (NT == Ctx.getArrayDecl()) { + if (T->isArray()) { Printer << "["; visit(T->getGenericArgs()[0]); Printer << "]"; return; } - if (NT == Ctx.getDictionaryDecl()) { + if (T->isDictionary()) { Printer << "["; visit(T->getGenericArgs()[0]); Printer << " : "; @@ -4533,7 +4531,7 @@ class TypePrinter : public TypeVisitor { Printer << "]"; return; } - if (NT == Ctx.getOptionalDecl()) { + if (T->isOptional()) { printWithParensIfNotSimple(T->getGenericArgs()[0]); Printer << "?"; return; diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp index c7cd012d11c1f..bf1c09cc01c17 100644 --- a/lib/AST/ASTVerifier.cpp +++ b/lib/AST/ASTVerifier.cpp @@ -1042,9 +1042,7 @@ class Verifier : public ASTWalker { case StmtConditionElement::CK_Boolean: { auto *E = elt.getBoolean(); if (shouldVerifyChecked(E)) - checkSameType(E->getType(), - Ctx.getBoolDecl()->getDeclaredInterfaceType(), - "condition type"); + checkSameType(E->getType(), Ctx.getBoolType(), "condition type"); break; } @@ -1386,8 +1384,7 @@ class Verifier : public ASTWalker { // Ensure we don't convert an array to a void pointer this way. - if (fromElement->getNominalOrBoundGenericNominal() == Ctx.getArrayDecl() - && toElement->isEqual(Ctx.TheEmptyTupleType)) { + if (fromElement->isArray() && toElement->isVoid()) { Out << "InOutToPointer is converting an array to a void pointer; " "ArrayToPointer should be used instead:\n"; E->dump(Out); @@ -1410,7 +1407,7 @@ class Verifier : public ASTWalker { // The source may be optionally inout. auto fromArray = E->getSubExpr()->getType()->getInOutObjectType(); - if (fromArray->getNominalOrBoundGenericNominal() != Ctx.getArrayDecl()) { + if (!fromArray->isArray()) { Out << "ArrayToPointer does not convert from array:\n"; E->dump(Out); Out << "\n"; @@ -1431,8 +1428,7 @@ class Verifier : public ASTWalker { PrettyStackTraceExpr debugStack(Ctx, "verifying StringToPointer", E); - if (E->getSubExpr()->getType()->getNominalOrBoundGenericNominal() - != Ctx.getStringDecl()) { + if (!E->getSubExpr()->getType()->isString()) { Out << "StringToPointer does not convert from string:\n"; E->dump(Out); Out << "\n"; @@ -2212,22 +2208,20 @@ class Verifier : public ASTWalker { auto keyPathTy = E->getKeyPath()->getType(); auto resultTy = E->getType(); - if (auto nom = keyPathTy->getAs()) { - if (nom->getDecl() == Ctx.getAnyKeyPathDecl()) { - // AnyKeyPath application is rvalue T -> rvalue Any? - if (baseTy->is()) { - Out << "AnyKeyPath application base is not an rvalue\n"; - abort(); - } - auto resultObjTy = resultTy->getOptionalObjectType(); - if (!resultObjTy || !resultObjTy->isAny()) { - Out << "AnyKeyPath application result must be Any?\n"; - abort(); - } - return; + if (keyPathTy->isAnyKeyPath()) { + // AnyKeyPath application is rvalue T -> rvalue Any? + if (baseTy->is()) { + Out << "AnyKeyPath application base is not an rvalue\n"; + abort(); } + auto resultObjTy = resultTy->getOptionalObjectType(); + if (!resultObjTy || !resultObjTy->isAny()) { + Out << "AnyKeyPath application result must be Any?\n"; + abort(); + } + return; } else if (auto bgt = keyPathTy->getAs()) { - if (bgt->getDecl() == Ctx.getPartialKeyPathDecl()) { + if (keyPathTy->isPartialKeyPath()) { // PartialKeyPath application is rvalue T -> rvalue Any if (!baseTy->isEqual(bgt->getGenericArgs()[0])) { Out << "PartialKeyPath application base doesn't match type\n"; @@ -2238,7 +2232,7 @@ class Verifier : public ASTWalker { abort(); } return; - } else if (bgt->getDecl() == Ctx.getKeyPathDecl()) { + } else if (keyPathTy->isKeyPath()) { // KeyPath application is rvalue T -> rvalue U if (!baseTy->isEqual(bgt->getGenericArgs()[0])) { Out << "KeyPath application base doesn't match type\n"; @@ -2249,7 +2243,7 @@ class Verifier : public ASTWalker { abort(); } return; - } else if (bgt->getDecl() == Ctx.getWritableKeyPathDecl()) { + } else if (keyPathTy->isWritableKeyPath()) { // WritableKeyPath application is // lvalue T -> lvalue U // or rvalue T -> rvalue U @@ -2271,7 +2265,7 @@ class Verifier : public ASTWalker { abort(); } return; - } else if (bgt->getDecl() == Ctx.getReferenceWritableKeyPathDecl()) { + } else if (keyPathTy->isReferenceWritableKeyPath()) { // ReferenceWritableKeyPath application is // rvalue T -> lvalue U // or lvalue T -> lvalue U @@ -2945,8 +2939,7 @@ class Verifier : public ASTWalker { // Verify that the optionality of the result type of the // initializer matches the failability of the initializer. if (!CD->isInvalid() && - CD->getDeclContext()->getDeclaredInterfaceType()->getAnyNominal() != - Ctx.getOptionalDecl()) { + !CD->getDeclContext()->getDeclaredInterfaceType()->isOptional()) { bool resultIsOptional = (bool) CD->getResultInterfaceType() ->getOptionalObjectType(); auto declIsOptional = CD->isFailable(); diff --git a/lib/AST/Builtins.cpp b/lib/AST/Builtins.cpp index 38b457199990e..4de40a0e65f95 100644 --- a/lib/AST/Builtins.cpp +++ b/lib/AST/Builtins.cpp @@ -1364,7 +1364,7 @@ static ValueDecl *getAutoDiffApplyTransposeFunction( static ValueDecl *getGlobalStringTablePointer(ASTContext &Context, Identifier Id) { // String -> Builtin.RawPointer - auto stringType = NominalType::get(Context.getStringDecl(), Type(), Context); + auto stringType = Context.getStringType(); return getBuiltinFunction(Id, {stringType}, Context.TheRawPointerType); } @@ -1427,8 +1427,7 @@ Type swift::getAsyncTaskAndContextType(ASTContext &ctx) { static ValueDecl *getCreateAsyncTaskFuture(ASTContext &ctx, Identifier id) { BuiltinFunctionBuilder builder(ctx); auto genericParam = makeGenericParam().build(builder); - builder.addParameter( - makeConcrete(ctx.getIntDecl()->getDeclaredInterfaceType())); + builder.addParameter(makeConcrete(ctx.getIntType())); auto extInfo = ASTExtInfoBuilder().withAsync().withThrows().build(); builder.addParameter( makeConcrete(FunctionType::get({ }, genericParam, extInfo))); @@ -1439,8 +1438,7 @@ static ValueDecl *getCreateAsyncTaskFuture(ASTContext &ctx, Identifier id) { static ValueDecl *getCreateAsyncTaskGroupFuture(ASTContext &ctx, Identifier id) { BuiltinFunctionBuilder builder(ctx); auto genericParam = makeGenericParam().build(builder); - builder.addParameter( - makeConcrete(ctx.getIntDecl()->getDeclaredInterfaceType())); // flags + builder.addParameter(makeConcrete(ctx.getIntType())); // flags builder.addParameter( makeConcrete(OptionalType::get(ctx.TheRawPointerType))); // group auto extInfo = ASTExtInfoBuilder().withAsync().withThrows().build(); diff --git a/lib/AST/ClangTypeConverter.cpp b/lib/AST/ClangTypeConverter.cpp index 053f1ae2444dd..ef6a9399e5f9e 100644 --- a/lib/AST/ClangTypeConverter.cpp +++ b/lib/AST/ClangTypeConverter.cpp @@ -361,13 +361,13 @@ ClangTypeConverter::reverseBuiltinTypeMapping(StructType *type) { // Handle Int and UInt specially. On Apple platforms, these map to // the NSInteger and NSUInteger typedefs. So try that if the typedefs // are available, to ensure we get consistent ObjC @encode strings. - if (swiftType->getAnyNominal() == Context.getIntDecl()) { + if (swiftType->isInt()) { auto NSIntegerTy = getClangBuiltinTypeFromTypedef(sema, "NSInteger"); if (!NSIntegerTy.isNull()) { Cache.insert({swiftType->getCanonicalType(), NSIntegerTy}); return; } - } else if (swiftType->getAnyNominal() == Context.getUIntDecl()) { + } else if (swiftType->isUInt()) { auto NSUIntegerTy = getClangBuiltinTypeFromTypedef(sema, "NSUInteger"); if (!NSUIntegerTy.isNull()) { Cache.insert({swiftType->getCanonicalType(), NSUIntegerTy}); diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index ac5f8d3d289fc..d38a1ad632b91 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -4902,12 +4902,11 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type, if (auto *const bgt = type->getAs()) { auto info = SelfReferenceInfo(); - const auto &ctx = bgt->getDecl()->getASTContext(); - if (ctx.getArrayDecl() == bgt->getDecl()) { + if (bgt->isArray()) { // Swift.Array preserves variance in its Value type. info |= findProtocolSelfReferences(proto, bgt->getGenericArgs().front(), position); - } else if (bgt->getDecl() == ctx.getDictionaryDecl()) { + } else if (bgt->isDictionary()) { // Swift.Dictionary preserves variance in its Element type. info |= findProtocolSelfReferences(proto, bgt->getGenericArgs().front(), SelfReferencePosition::Invariant); diff --git a/lib/AST/DiagnosticEngine.cpp b/lib/AST/DiagnosticEngine.cpp index 2eca92e84738d..649d65d1d9257 100644 --- a/lib/AST/DiagnosticEngine.cpp +++ b/lib/AST/DiagnosticEngine.cpp @@ -399,7 +399,7 @@ static bool isInterestingTypealias(Type type) { else return false; - if (aliasDecl == type->getASTContext().getVoidDecl()) + if (aliasDecl->getUnderlyingType()->isVoid()) return false; // The 'Swift.AnyObject' typealias is not 'interesting'. diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index b774da6fbff6c..54adaa1a53917 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -620,13 +620,17 @@ bool TypeBase::isVoid() { return false; } -/// Check if this type is equal to Swift.Bool. -bool TypeBase::isBool() { - if (auto NTD = getAnyNominal()) - if (isa(NTD)) - return getASTContext().getBoolDecl() == NTD; - return false; -} +#define KNOWN_STDLIB_TYPE_DECL(NAME, DECL_CLASS, NUM_GENERIC_PARAMS) \ +/** Check if this type is equal to Swift.NAME. */ \ +bool TypeBase::is##NAME() { \ + if (auto generic = getAnyGeneric()) { \ + if (isa(generic)) { \ + return getASTContext().get##NAME##Decl() == generic; \ + } \ + } \ + return false; \ +} +#include "swift/AST/KnownStdlibTypes.def" Type TypeBase::getRValueType() { // If the type is not an lvalue, this is a no-op. @@ -656,24 +660,20 @@ CanType CanType::getOptionalObjectTypeImpl(CanType type) { Type TypeBase::getAnyPointerElementType(PointerTypeKind &PTK) { auto &C = getASTContext(); - if (auto nominalTy = getAs()) { - if (nominalTy->getDecl() == C.getUnsafeMutableRawPointerDecl()) { - PTK = PTK_UnsafeMutableRawPointer; - return C.TheEmptyTupleType; - } - if (nominalTy->getDecl() == C.getUnsafeRawPointerDecl()) { - PTK = PTK_UnsafeRawPointer; - return C.TheEmptyTupleType; - } + if (isUnsafeMutableRawPointer()) { + PTK = PTK_UnsafeMutableRawPointer; + return C.TheEmptyTupleType; + } + if (isUnsafeRawPointer()) { + PTK = PTK_UnsafeRawPointer; + return C.TheEmptyTupleType; } if (auto boundTy = getAs()) { - if (boundTy->getDecl() == C.getUnsafeMutablePointerDecl()) { + if (boundTy->isUnsafeMutablePointer()) { PTK = PTK_UnsafeMutablePointer; - } else if (boundTy->getDecl() == C.getUnsafePointerDecl()) { + } else if (boundTy->isUnsafePointer()) { PTK = PTK_UnsafePointer; - } else if ( - boundTy->getDecl() == C.getAutoreleasingUnsafeMutablePointerDecl() - ) { + } else if (boundTy->isAutoreleasingUnsafeMutablePointer()) { PTK = PTK_AutoreleasingUnsafeMutablePointer; } else { return Type(); @@ -706,20 +706,18 @@ Type TypeBase::wrapInPointer(PointerTypeKind kind) { Type TypeBase::getAnyBufferPointerElementType(BufferPointerTypeKind &BPTK) { auto &C = getASTContext(); - if (auto nominalTy = getAs()) { - if (nominalTy->getDecl() == C.getUnsafeMutableRawBufferPointerDecl()) { - BPTK = BPTK_UnsafeMutableRawBufferPointer; - } else if (nominalTy->getDecl() == C.getUnsafeRawBufferPointerDecl()) { - BPTK = BPTK_UnsafeRawBufferPointer; - } else { - return Type(); - } + if (isUnsafeMutableRawBufferPointer()) { + BPTK = BPTK_UnsafeMutableRawBufferPointer; + return C.TheEmptyTupleType; + } + if (isUnsafeRawBufferPointer()) { + BPTK = BPTK_UnsafeRawBufferPointer; return C.TheEmptyTupleType; } if (auto boundTy = getAs()) { - if (boundTy->getDecl() == C.getUnsafeMutableBufferPointerDecl()) { + if (boundTy->isUnsafeMutableBufferPointer()) { BPTK = BPTK_UnsafeMutableBufferPointer; - } else if (boundTy->getDecl() == C.getUnsafeBufferPointerDecl()) { + } else if (boundTy->isUnsafeBufferPointer()) { BPTK = BPTK_UnsafeBufferPointer; } else { return Type(); @@ -830,18 +828,11 @@ bool TypeBase::isCGFloatType() { NTD->getName().is("CGFloat"); } -bool TypeBase::isDoubleType() { - auto *NTD = getAnyNominal(); - return NTD ? NTD->getDecl() == getASTContext().getDoubleDecl() : false; -} - bool TypeBase::isKnownStdlibCollectionType() { - if (auto *structType = getAs()) { - auto &ctx = getASTContext(); - auto *decl = structType->getDecl(); - return decl == ctx.getArrayDecl() || decl == ctx.getDictionaryDecl() || - decl == ctx.getSetDecl(); + if (isArray() || isDictionary() || isSet()) { + return true; } + return false; } @@ -1475,12 +1466,11 @@ TypeBase *TypeBase::reconstituteSugar(bool Recursive) { return arg; }; - auto &ctx = boundGeneric->getASTContext(); - if (boundGeneric->getDecl() == ctx.getArrayDecl()) + if (boundGeneric->isArray()) return ArraySliceType::get(getGenericArg(0)); - if (boundGeneric->getDecl() == ctx.getDictionaryDecl()) + if (boundGeneric->isDictionary()) return DictionaryType::get(getGenericArg(0), getGenericArg(1)); - if (boundGeneric->getDecl() == ctx.getOptionalDecl()) + if (boundGeneric->isOptional()) return OptionalType::get(getGenericArg(0)); } return Ty; @@ -2494,8 +2484,7 @@ getForeignRepresentable(Type type, ForeignLanguage language, // Unmanaged can be trivially represented in Objective-C if T // is trivially represented in Objective-C. - if (language == ForeignLanguage::ObjectiveC && - nominal == ctx.getUnmanagedDecl()) { + if (language == ForeignLanguage::ObjectiveC && type->isUnmanaged()) { auto boundGenericType = type->getAs(); // Note: works around a broken Unmanaged<> definition. diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 8b61d09f1413a..a4d5a34530ae2 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -1911,9 +1911,9 @@ static bool addErrorDomain(NominalTypeDecl *swiftDecl, auto &C = importer.SwiftContext; auto swiftValueDecl = dyn_cast_or_null( importer.importDecl(errorDomainDecl, importer.CurrentVersion)); - auto stringTy = C.getStringDecl()->getDeclaredInterfaceType(); + auto stringTy = C.getStringType(); assert(stringTy && "no string type available"); - if (!swiftValueDecl || !swiftValueDecl->getInterfaceType()->isEqual(stringTy)) { + if (!swiftValueDecl || !swiftValueDecl->getInterfaceType()->isString()) { // Couldn't actually import it as an error enum, fall back to enum return false; } @@ -6179,7 +6179,7 @@ SwiftDeclConverter::importSwiftNewtype(const clang::TypedefNameDecl *decl, // we will store the underlying type and leave it up to the use site // to determine whether to use this new_type, or an Unmanaged type. if (auto genericType = storedUnderlyingType->getAs()) { - if (genericType->getDecl() == Impl.SwiftContext.getUnmanagedDecl()) { + if (genericType->isUnmanaged()) { assert(genericType->getGenericArgs().size() == 1 && "other args?"); storedUnderlyingType = genericType->getGenericArgs()[0]; } diff --git a/lib/ClangImporter/ImportMacro.cpp b/lib/ClangImporter/ImportMacro.cpp index 075032c9573c1..1d8e03f934496 100644 --- a/lib/ClangImporter/ImportMacro.cpp +++ b/lib/ClangImporter/ImportMacro.cpp @@ -566,38 +566,38 @@ static ValueDecl *importMacro(ClangImporter::Implementation &impl, } else if (tokenI[1].is(clang::tok::pipepipe)) { bool result = firstValue.getBoolValue() || secondValue.getBoolValue(); resultValue = llvm::APSInt::get(result); - resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredInterfaceType(); + resultSwiftType = impl.SwiftContext.getBoolType(); // Logical AND. } else if (tokenI[1].is(clang::tok::ampamp)) { bool result = firstValue.getBoolValue() && secondValue.getBoolValue(); resultValue = llvm::APSInt::get(result); - resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredInterfaceType(); + resultSwiftType = impl.SwiftContext.getBoolType(); // Equality. } else if (tokenI[1].is(clang::tok::equalequal)) { resultValue = llvm::APSInt::get(firstValue == secondValue); - resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredInterfaceType(); + resultSwiftType = impl.SwiftContext.getBoolType(); // Less than. } else if (tokenI[1].is(clang::tok::less)) { resultValue = llvm::APSInt::get(firstValue < secondValue); - resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredInterfaceType(); + resultSwiftType = impl.SwiftContext.getBoolType(); // Less than or equal. } else if (tokenI[1].is(clang::tok::lessequal)) { resultValue = llvm::APSInt::get(firstValue <= secondValue); - resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredInterfaceType(); + resultSwiftType = impl.SwiftContext.getBoolType(); // Greater than. } else if (tokenI[1].is(clang::tok::greater)) { resultValue = llvm::APSInt::get(firstValue > secondValue); - resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredInterfaceType(); + resultSwiftType = impl.SwiftContext.getBoolType(); // Greater than or equal. } else if (tokenI[1].is(clang::tok::greaterequal)) { resultValue = llvm::APSInt::get(firstValue >= secondValue); - resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredInterfaceType(); + resultSwiftType = impl.SwiftContext.getBoolType(); // Unhandled operators. } else { diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp index da6baa36ade56..61a906dd3bc31 100644 --- a/lib/ClangImporter/ImportType.cpp +++ b/lib/ClangImporter/ImportType.cpp @@ -833,8 +833,7 @@ namespace { case ImportHint::NSUInteger: // NSUInteger might be imported as Int rather than UInt depending // on where the import lives. - if (underlyingResult.AbstractType->getAnyNominal() == - Impl.SwiftContext.getIntDecl()) + if (underlyingResult.AbstractType->isInt()) break; LLVM_FALLTHROUGH; default: @@ -1074,7 +1073,7 @@ namespace { if (auto objcClassDef = objcClass->getDefinition()) bridgedType = mapSwiftBridgeAttr(objcClassDef); else if (objcClass->getName() == "NSString") - bridgedType = Impl.SwiftContext.getStringDecl()->getDeclaredInterfaceType(); + bridgedType = Impl.SwiftContext.getStringType(); if (bridgedType) { // Gather the type arguments. @@ -1116,31 +1115,25 @@ namespace { // The first type argument for Dictionary or Set needs // to be Hashable. If something isn't Hashable, fall back // to AnyHashable as a key type. - if (unboundDecl == Impl.SwiftContext.getDictionaryDecl() || - unboundDecl == Impl.SwiftContext.getSetDecl()) { + if (unboundType->isDictionary() || unboundType->isSet()) { auto &keyType = importedTypeArgs[0]; - auto keyStructDecl = keyType->getStructOrBoundGenericStruct(); if (!Impl.matchesHashableBound(keyType) || // Dictionary and Array conditionally conform to Hashable, // but the conformance doesn't necessarily apply with the // imported versions of their type arguments. // FIXME: Import their non-Hashable type parameters as // AnyHashable in this context. - keyStructDecl == Impl.SwiftContext.getDictionaryDecl() || - keyStructDecl == Impl.SwiftContext.getArrayDecl()) { - if (auto anyHashable = Impl.SwiftContext.getAnyHashableDecl()) - keyType = anyHashable->getDeclaredInterfaceType(); - else - keyType = Type(); + keyType->isDictionary() || keyType->isArray()) { + keyType = Impl.SwiftContext.getAnyHashableType(); } } // Form the specialized type. - if (unboundDecl == Impl.SwiftContext.getArrayDecl()) { + if (unboundType->isArray()) { // Type sugar for arrays. assert(importedTypeArgs.size() == 1); bridgedType = ArraySliceType::get(importedTypeArgs[0]); - } else if (unboundDecl == Impl.SwiftContext.getDictionaryDecl()) { + } else if (unboundType->isDictionary()) { // Type sugar for dictionaries. assert(importedTypeArgs.size() == 2); bridgedType = DictionaryType::get(importedTypeArgs[0], @@ -1335,8 +1328,7 @@ static Type maybeImportCFOutParameter(ClangImporter::Implementation &impl, if (!boundGenericTy) return Type(); - auto boundGenericBase = boundGenericTy->getDecl(); - if (boundGenericBase != impl.SwiftContext.getUnmanagedDecl()) + if (!boundGenericTy->isUnmanaged()) return Type(); assert(boundGenericTy->getGenericArgs().size() == 1 && @@ -1462,14 +1454,14 @@ static ImportedType adjustTypeForConcreteImport( // Turn BOOL and DarwinBoolean into Bool in contexts that can bridge types // losslessly. if (bridging == Bridgeability::Full && canBridgeTypes(importKind)) - importedType = impl.SwiftContext.getBoolDecl()->getDeclaredInterfaceType(); + importedType = impl.SwiftContext.getBoolType(); break; case ImportHint::NSUInteger: // When NSUInteger is used as an enum's underlying type or if it does not // come from a system module, make sure it stays unsigned. if (importKind == ImportTypeKind::Enum || !allowNSUIntegerAsInt) - importedType = impl.SwiftContext.getUIntDecl()->getDeclaredInterfaceType(); + importedType = impl.SwiftContext.getUIntType(); break; case ImportHint::CFPointer: @@ -1775,7 +1767,7 @@ ImportedType ClangImporter::Implementation::importFunctionReturnType( switch (getClangASTContext().BuiltinInfo.getTypeString(builtinID)[0]) { case 'z': // size_t case 'Y': // ptrdiff_t - return {SwiftContext.getIntDecl()->getDeclaredInterfaceType(), false}; + return {SwiftContext.getIntType(), false}; default: break; } @@ -2193,7 +2185,7 @@ static Type decomposeCompletionHandlerType( switch (resultTypeElts.size()) { case 0: - return paramTy->getASTContext().getVoidDecl()->getDeclaredInterfaceType(); + return paramTy->getASTContext().getVoidType(); case 1: return resultTypeElts.front().getType(); @@ -2568,7 +2560,7 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType( *bodyParams = ParameterList::create(SwiftContext, swiftParams); if (clangDecl->hasAttr()) { - origSwiftResultTy = SwiftContext.getNeverType(); + origSwiftResultTy = SwiftContext.getNeverType()->getCanonicalType(); swiftResultTy = SwiftContext.getNeverType(); } @@ -2642,7 +2634,7 @@ ImportedType ClangImporter::Implementation::importAccessorParamsAndReturnType( paramInfo->setInterfaceType(propertyTy); *params = ParameterList::create(SwiftContext, paramInfo); - resultTy = SwiftContext.getVoidDecl()->getDeclaredInterfaceType(); + resultTy = SwiftContext.getVoidType(); isIUO = false; } diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index e95bbf64966b8..41b7e3255a3a8 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -1725,11 +1725,11 @@ static Type defaultTypeLiteralKind(CodeCompletionLiteralKind kind, ASTContext &Ctx) { switch (kind) { case CodeCompletionLiteralKind::BooleanLiteral: - return Ctx.getBoolDecl()->getDeclaredInterfaceType(); + return Ctx.getBoolType(); case CodeCompletionLiteralKind::IntegerLiteral: - return Ctx.getIntDecl()->getDeclaredInterfaceType(); + return Ctx.getIntType(); case CodeCompletionLiteralKind::StringLiteral: - return Ctx.getStringDecl()->getDeclaredInterfaceType(); + return Ctx.getStringType(); case CodeCompletionLiteralKind::ArrayLiteral: return Ctx.getArrayDecl()->getDeclaredType(); case CodeCompletionLiteralKind::DictionaryLiteral: @@ -4350,7 +4350,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { builder.addRightBracket(); }); - auto floatType = context.getFloatDecl()->getDeclaredInterfaceType(); + auto floatType = context.getFloatType(); addFromProto(LK::ColorLiteral, [&](Builder &builder) { builder.addBaseName("#colorLiteral"); builder.addLeftParen(); @@ -4364,7 +4364,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { builder.addRightParen(); }); - auto stringType = context.getStringDecl()->getDeclaredInterfaceType(); + auto stringType = context.getStringType(); addFromProto(LK::ImageLiteral, [&](Builder &builder) { builder.addBaseName("#imageLiteral"); builder.addLeftParen(); @@ -4414,7 +4414,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { } } - if (!addedKeyPath && T->getAnyNominal() == Ctx.getStringDecl()) { + if (!addedKeyPath && T->isString()) { addPoundKeyPath(needPound); if (addedSelector) break; diff --git a/lib/IDE/ExprContextAnalysis.cpp b/lib/IDE/ExprContextAnalysis.cpp index 43a5d0d95e7cd..868ef20f262c6 100644 --- a/lib/IDE/ExprContextAnalysis.cpp +++ b/lib/IDE/ExprContextAnalysis.cpp @@ -1016,12 +1016,12 @@ class ExprContextAnalyzer { if (auto boundGenericT = arrayT->getAs()) { // let _: [Element] = [#HERE#] // In this case, 'Element' is the expected type. - if (boundGenericT->getDecl() == Context.getArrayDecl()) + if (boundGenericT->isArray()) recordPossibleType(boundGenericT->getGenericArgs()[0]); // let _: [Key : Value] = [#HERE#] // In this case, 'Key' is the expected type. - if (boundGenericT->getDecl() == Context.getDictionaryDecl()) + if (boundGenericT->isDictionary()) recordPossibleType(boundGenericT->getGenericArgs()[0]); } } @@ -1033,7 +1033,7 @@ class ExprContextAnalyzer { for (auto dictT : dictCtxtInfo.getPossibleTypes()) { if (auto boundGenericT = dictT->getAs()) { - if (boundGenericT->getDecl() == Context.getDictionaryDecl()) { + if (boundGenericT->isDictionary()) { if (ParsedExpr->isImplicit() && isa(ParsedExpr)) { // let _: [Key : Value] = [#HERE#:] // let _: [Key : Value] = [#HERE#:val] @@ -1048,7 +1048,7 @@ class ExprContextAnalyzer { } else { // let _: [Key : Value] = [key: val, #HERE#] // In this case, assume 'Key' is the expected type. - if (boundGenericT->getDecl() == Context.getDictionaryDecl()) + if (boundGenericT->isDictionary()) recordPossibleType(boundGenericT->getGenericArgs()[0]); } } @@ -1061,7 +1061,7 @@ class ExprContextAnalyzer { if (IE->isFolded() && SM.rangeContains(IE->getCondExpr()->getSourceRange(), ParsedExpr->getSourceRange())) { - recordPossibleType(Context.getBoolDecl()->getDeclaredInterfaceType()); + recordPossibleType(Context.getBoolType()); break; } ExprContextInfo ternaryCtxtInfo(DC, Parent); @@ -1141,8 +1141,7 @@ class ExprContextAnalyzer { case StmtKind::ForEach: if (auto SEQ = cast(Parent)->getSequence()) { if (containsTarget(SEQ)) { - recordPossibleType( - Context.getSequenceDecl()->getDeclaredInterfaceType()); + recordPossibleType(Context.getSequenceType()); } } break; @@ -1151,7 +1150,7 @@ class ExprContextAnalyzer { case StmtKind::While: case StmtKind::Guard: if (isBoolConditionOf(Parent)) { - recordPossibleType(Context.getBoolDecl()->getDeclaredInterfaceType()); + recordPossibleType(Context.getBoolType()); } break; default: diff --git a/lib/IDE/Refactoring.cpp b/lib/IDE/Refactoring.cpp index a99730e7c74df..736b474c0e085 100644 --- a/lib/IDE/Refactoring.cpp +++ b/lib/IDE/Refactoring.cpp @@ -1888,20 +1888,20 @@ findConcatenatedExpressions(const ResolvedRangeInfo &Info, ASTContext &Ctx) { // FIXME: we should have ErrorType instead of null. if (E->getType().isNull()) return true; - auto ExprType = E->getType()->getNominalOrBoundGenericNominal(); + //Only binary concatenation operators should exist in expression if (E->getKind() == ExprKind::Binary) { auto *BE = dyn_cast(E); auto *OperatorDeclRef = BE->getSemanticFn()->getMemberOperatorRef(); - if (!(isConcatenationExpr(OperatorDeclRef) - && ExprType == Ctx.getStringDecl())) { + if (!(isConcatenationExpr(OperatorDeclRef) && + E->getType()->isString())) { IsValidInterpolation = false; return false; } return true; } // Everything that evaluates to string should be gathered. - if (ExprType == Ctx.getStringDecl()) { + if (E->getType()->isString()) { Bucket->insert(E); return false; } @@ -3897,15 +3897,6 @@ namespace asyncrefactorings { // TODO: Should probably split the refactorings into separate files -/// Whether the given type is the stdlib Result type -bool isResultType(Type Ty) { - if (!Ty) - return false; - if (auto *NTD = Ty->getAnyNominal()) - return NTD == NTD->getASTContext().getResultDecl(); - return false; -} - /// Whether the given type is (or conforms to) the stdlib Error type bool isErrorType(Type Ty, ModuleDecl *MD) { if (!Ty) @@ -4116,7 +4107,7 @@ struct AsyncHandlerDesc { if (HandlerParams.size() == 1) { auto ParamTy = HandlerParams.back().getPlainType()->getAs(); - if (isResultType(ParamTy)) { + if (ParamTy && ParamTy->isResult()) { auto GenericArgs = ParamTy->getGenericArgs(); assert(GenericArgs.size() == 2 && "Result should have two params"); HandlerDesc.Type = HandlerType::RESULT; @@ -4127,7 +4118,7 @@ struct AsyncHandlerDesc { if (HandlerDesc.Type != HandlerType::RESULT) { // Only handle non-result parameters for (auto &Param : HandlerParams) { - if (isResultType(Param.getPlainType())) + if (Param.getPlainType() && Param.getPlainType()->isResult()) return AsyncHandlerDesc(); } @@ -4336,7 +4327,8 @@ struct CallbackCondition { void initFromEnumPattern(const Decl *D, const EnumElementPattern *EEP) { if (auto *EED = EEP->getElementDecl()) { - if (!isResultType(EED->getParentEnum()->getDeclaredType())) + auto eedTy = EED->getParentEnum()->getDeclaredType(); + if (!eedTy || !eedTy->isResult()) return; if (EED->getNameStr() == StringRef("failure")) ErrorCase = true; @@ -4358,7 +4350,7 @@ struct CallbackCondition { return; auto *BaseDRE = dyn_cast(DSC->getBase()); - if (!isResultType(BaseDRE->getType())) + if (!BaseDRE->getType() || !BaseDRE->getType()->isResult()) return; auto *FnDRE = dyn_cast(DSC->getFn()); diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp index dce2864abcbc6..7f01c915256d4 100644 --- a/lib/IRGen/GenMeta.cpp +++ b/lib/IRGen/GenMeta.cpp @@ -5158,6 +5158,7 @@ SpecialProtocol irgen::getSpecialProtocolID(ProtocolDecl *P) { case KnownProtocolKind::Actor: case KnownProtocolKind::Sendable: case KnownProtocolKind::UnsafeSendable: + case KnownProtocolKind::RangeReplaceableCollection: return SpecialProtocol::None; } diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index 7c385386e3280..4278b9155845e 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -988,7 +988,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo { } else { // Discriminated union case without argument. Fallback to Int // as the element type; there is no storage here. - Type IntTy = IGM.Context.getIntDecl()->getDeclaredInterfaceType(); + Type IntTy = IGM.Context.getIntType(); ElemDbgTy = DebugTypeInfo(IntTy, DbgTy.getStorageType(), Size(0), Alignment(1), true, false); } diff --git a/lib/PrintAsObjC/DeclAndTypePrinter.cpp b/lib/PrintAsObjC/DeclAndTypePrinter.cpp index 5c78a1a1c5a06..c2476236ade8f 100644 --- a/lib/PrintAsObjC/DeclAndTypePrinter.cpp +++ b/lib/PrintAsObjC/DeclAndTypePrinter.cpp @@ -44,11 +44,8 @@ static bool isNSObjectOrAnyHashable(ASTContext &ctx, Type type) { == ctx.getSwiftId(KnownFoundationEntity::NSObject) && classDecl->getModuleContext()->getName() == ctx.Id_ObjectiveC; } - if (auto nomDecl = type->getAnyNominal()) { - return nomDecl == ctx.getAnyHashableDecl(); - } - return false; + return type->isAnyHashable(); } static bool isAnyObjectOrAny(Type type) { @@ -1075,7 +1072,7 @@ class DeclAndTypePrinter::Implementation ty = unwrapped; auto genericTy = ty->getAs(); - if (!genericTy || genericTy->getDecl() != getASTContext().getArrayDecl()) + if (!genericTy || !genericTy->isArray()) return false; assert(genericTy->getGenericArgs().size() == 1); @@ -1182,14 +1179,14 @@ class DeclAndTypePrinter::Implementation auto nominal = copyTy->getNominalOrBoundGenericNominal(); if (nominal && isa(nominal)) { - if (nominal == ctx.getArrayDecl() || - nominal == ctx.getDictionaryDecl() || - nominal == ctx.getSetDecl() || - nominal == ctx.getStringDecl() || + if (copyTy->isArray() || + copyTy->isDictionary() || + copyTy->isSet() || + copyTy->isString() || (!getKnownTypeInfo(nominal) && getObjCBridgedClass(nominal))) { // We fast-path the most common cases in the condition above. os << ", copy"; - } else if (nominal == ctx.getUnmanagedDecl()) { + } else if (copyTy->isUnmanaged()) { os << ", unsafe_unretained"; // Don't print unsafe_unretained twice. if (auto boundTy = copyTy->getAs()) { @@ -1721,10 +1718,7 @@ class DeclAndTypePrinter::Implementation const StructDecl *SD = ty->getStructOrBoundGenericStruct(); if (ty->isAny()) { ty = ctx.getAnyObjectType(); - } else if (SD != ctx.getArrayDecl() && - SD != ctx.getDictionaryDecl() && - SD != ctx.getSetDecl() && - !isSwiftNewtype(SD)) { + } else if (!ty->isKnownStdlibCollectionType() && !isSwiftNewtype(SD)) { ty = ctx.getBridgedToObjC(&owningPrinter.M, ty); } @@ -1737,13 +1731,9 @@ class DeclAndTypePrinter::Implementation /// it out. bool printIfKnownGenericStruct(const BoundGenericStructType *BGT, Optional optionalKind) { - StructDecl *SD = BGT->getDecl(); - if (!SD->getModuleContext()->isStdlibModule()) - return false; - - ASTContext &ctx = getASTContext(); + auto bgsTy = Type(const_cast(BGT)); - if (SD == ctx.getUnmanagedDecl()) { + if (bgsTy->isUnmanaged()) { auto args = BGT->getGenericArgs(); assert(args.size() == 1); visitPart(args.front(), optionalKind); @@ -1753,10 +1743,10 @@ class DeclAndTypePrinter::Implementation // Everything from here on is some kind of pointer type. bool isConst; - if (SD == ctx.getUnsafePointerDecl()) { + if (bgsTy->isUnsafePointer()) { isConst = true; - } else if (SD == ctx.getAutoreleasingUnsafeMutablePointerDecl() || - SD == ctx.getUnsafeMutablePointerDecl()) { + } else if (bgsTy->isAutoreleasingUnsafeMutablePointer() || + bgsTy->isUnsafeMutablePointer()) { isConst = false; } else { // Not a pointer. diff --git a/lib/SIL/IR/SILFunctionType.cpp b/lib/SIL/IR/SILFunctionType.cpp index 06f9b8e5be27b..68e720b306581 100644 --- a/lib/SIL/IR/SILFunctionType.cpp +++ b/lib/SIL/IR/SILFunctionType.cpp @@ -1445,8 +1445,7 @@ static bool isClangTypeMoreIndirectThanSubstType(TypeConverter &TC, return isClangTypeMoreIndirectThanSubstType(TC, clangTy->getPointeeType().getTypePtr(), CanType(eltTy)); - if (substTy->getAnyNominal() == - TC.Context.getOpaquePointerDecl()) + if (substTy->isOpaquePointer()) // TODO: We could conceivably have an indirect opaque ** imported // as COpaquePointer. That shouldn't ever happen today, though, // since we only ever indirect the 'self' parameter of functions @@ -2671,8 +2670,7 @@ class ObjCMethodConventions : public Conventions { return ResultConvention::UnownedInnerPointer; auto type = tl.getLoweredType(); - if (type.unwrapOptionalType().getStructOrBoundGenericStruct() - == type.getASTContext().getUnmanagedDecl()) + if (type.unwrapOptionalType().getASTType()->isUnmanaged()) return ResultConvention::UnownedInnerPointer; return ResultConvention::Unowned; } diff --git a/lib/SIL/Utils/DynamicCasts.cpp b/lib/SIL/Utils/DynamicCasts.cpp index 1da0d8702715a..aaceaac6f51e7 100644 --- a/lib/SIL/Utils/DynamicCasts.cpp +++ b/lib/SIL/Utils/DynamicCasts.cpp @@ -152,7 +152,7 @@ classifyDynamicCastToProtocol(ModuleDecl *M, CanType source, CanType target, // AnyHashable is a special case: although it's a struct, there maybe another // type conforming to it and to the TargetProtocol at the same time. - if (SourceNominalTy == SourceNominalTy->getASTContext().getAnyHashableDecl()) + if (source->isAnyHashable()) return DynamicCastFeasibility::MaySucceed; // If we are in a whole-module compilation and @@ -417,7 +417,7 @@ swift::classifyDynamicCast(ModuleDecl *M, // Casts from AnyHashable. if (auto sourceStruct = dyn_cast(source)) { - if (sourceStruct->getDecl() == M->getASTContext().getAnyHashableDecl()) { + if (sourceStruct->isAnyHashable()) { if (auto hashable = getHashableExistentialType(M)) { // Succeeds if Hashable can be cast to the target type. return classifyDynamicCastFromProtocol(M, hashable, target, @@ -428,7 +428,7 @@ swift::classifyDynamicCast(ModuleDecl *M, // Casts to AnyHashable. if (auto targetStruct = dyn_cast(target)) { - if (targetStruct->getDecl() == M->getASTContext().getAnyHashableDecl()) { + if (targetStruct->isAnyHashable()) { // Succeeds if the source type can be dynamically cast to Hashable. // Hashable is not actually a legal existential type right now, but // the check doesn't care about that. @@ -733,8 +733,7 @@ swift::classifyDynamicCast(ModuleDecl *M, if (auto sourceStruct = dyn_cast(source)) { if (auto targetStruct = dyn_cast(target)) { // Both types have to be the same kind of collection. - auto typeDecl = sourceStruct->getDecl(); - if (typeDecl == targetStruct->getDecl()) { + if (sourceStruct->getDecl() == targetStruct->getDecl()) { auto sourceArgs = sourceStruct.getGenericArgs(); auto targetArgs = targetStruct.getGenericArgs(); @@ -742,15 +741,14 @@ swift::classifyDynamicCast(ModuleDecl *M, // a cast can always succeed on an empty collection. // Arrays and sets. - if (typeDecl == M->getASTContext().getArrayDecl() || - typeDecl == M->getASTContext().getSetDecl()) { + if (sourceStruct->isArray() || sourceStruct->isSet()) { auto valueFeasibility = classifyDynamicCast(M, sourceArgs[0], targetArgs[0]); return atWorst(valueFeasibility, DynamicCastFeasibility::MaySucceed); // Dictionaries. - } else if (typeDecl == M->getASTContext().getDictionaryDecl()) { + } else if (sourceStruct->isDictionary()) { auto keyFeasibility = classifyDynamicCast(M, sourceArgs[0], targetArgs[0]); auto valueFeasibility = diff --git a/lib/SIL/Utils/MemAccessUtils.cpp b/lib/SIL/Utils/MemAccessUtils.cpp index e7fa5ac364c7d..2ce99b3618f99 100644 --- a/lib/SIL/Utils/MemAccessUtils.cpp +++ b/lib/SIL/Utils/MemAccessUtils.cpp @@ -1678,11 +1678,11 @@ bool swift::isExternalGlobalAddressor(ApplyInst *AI) { bool swift::isUnsafePointerExtraction(StructExtractInst *SEI) { if (!isa(SEI->getType().getASTType())) return false; - + auto &C = SEI->getModule().getASTContext(); auto *decl = SEI->getStructDecl(); - return decl == C.getUnsafeMutablePointerDecl() - || decl == C.getUnsafePointerDecl(); + return decl == C.getUnsafeMutablePointerDecl() || + decl == C.getUnsafePointerDecl(); } // Given a block argument address base, check if it is actually a box projected diff --git a/lib/SIL/Verifier/SILVerifier.cpp b/lib/SIL/Verifier/SILVerifier.cpp index 4cbefb15eb550..9fc9e5aed5d49 100644 --- a/lib/SIL/Verifier/SILVerifier.cpp +++ b/lib/SIL/Verifier/SILVerifier.cpp @@ -139,7 +139,6 @@ void verifyKeyPathComponent(SILModule &M, SubstitutionMap patternSubs, bool forPropertyDescriptor, bool hasIndices) { - auto &C = M.getASTContext(); auto expansion = typeExpansionContext.getResilienceExpansion(); auto opaque = AbstractionPattern::getOpaque(); auto loweredBaseTy = @@ -170,8 +169,7 @@ void verifyKeyPathComponent(SILModule &M, require(param.getConvention() == ParameterConvention::Direct_Unowned, "indices pointer should be trivial"); - require(param.getInterfaceType()->getAnyNominal() - == C.getUnsafeRawPointerDecl(), + require(param.getInterfaceType()->isUnsafeRawPointer(), "indices pointer should be an UnsafeRawPointer"); } @@ -181,9 +179,7 @@ void verifyKeyPathComponent(SILModule &M, require(substEqualsType->getResults()[0].getConvention() == ResultConvention::Unowned, "result should be unowned"); - require(substEqualsType->getResults()[0].getInterfaceType() - ->getAnyNominal() - == C.getBoolDecl(), + require(substEqualsType->getResults()[0].getInterfaceType()->isBool(), "result should be Bool"); } { @@ -202,8 +198,7 @@ void verifyKeyPathComponent(SILModule &M, require(param.getConvention() == ParameterConvention::Direct_Unowned, "indices pointer should be trivial"); - require(param.getInterfaceType()->getAnyNominal() - == C.getUnsafeRawPointerDecl(), + require(param.getInterfaceType()->isUnsafeRawPointer(), "indices pointer should be an UnsafeRawPointer"); require(substHashType->getResults().size() == 1, @@ -212,9 +207,7 @@ void verifyKeyPathComponent(SILModule &M, require(substHashType->getResults()[0].getConvention() == ResultConvention::Unowned, "result should be unowned"); - require(substHashType->getResults()[0].getInterfaceType() - ->getAnyNominal() - == C.getIntDecl(), + require(substHashType->getResults()[0].getInterfaceType()->isInt(), "result should be Int"); } } else { @@ -303,7 +296,7 @@ void verifyKeyPathComponent(SILModule &M, require( indicesParam .getArgumentType(M, substGetterType, typeExpansionContext) - ->getAnyNominal() == C.getUnsafeRawPointerDecl(), + ->isUnsafeRawPointer(), "indices pointer should be an UnsafeRawPointer"); } @@ -361,7 +354,7 @@ void verifyKeyPathComponent(SILModule &M, require( indicesParam .getArgumentType(M, substSetterType, typeExpansionContext) - ->getAnyNominal() == C.getUnsafeRawPointerDecl(), + ->isUnsafeRawPointer(), "indices pointer should be an UnsafeRawPointer"); } @@ -4844,10 +4837,9 @@ class SILVerifier : public SILVerifierBase { auto kpBGT = kpTy.getAs(); require(kpBGT, "keypath result must be a generic type"); - auto &C = F.getASTContext(); - require(kpBGT->getDecl() == C.getKeyPathDecl() - || kpBGT->getDecl() == C.getWritableKeyPathDecl() - || kpBGT->getDecl() == C.getReferenceWritableKeyPathDecl(), + require(kpBGT->isKeyPath() || + kpBGT->isWritableKeyPath() || + kpBGT->isReferenceWritableKeyPath(), "keypath result must be a key path type"); auto baseTy = CanType(kpBGT->getGenericArgs()[0]); diff --git a/lib/SILGen/SILGenDynamicCast.cpp b/lib/SILGen/SILGenDynamicCast.cpp index 99127c7862da8..c8304a2f53191 100644 --- a/lib/SILGen/SILGenDynamicCast.cpp +++ b/lib/SILGen/SILGenDynamicCast.cpp @@ -351,16 +351,15 @@ static RValue emitCollectionDowncastExpr(SILGenFunction &SGF, auto fromCollection = sourceType->getCanonicalType(); auto toCollection = destType->getCanonicalType(); // Get the intrinsic function. - auto &ctx = SGF.getASTContext(); FuncDecl *fn = nullptr; - if (fromCollection->getAnyNominal() == ctx.getArrayDecl()) { + if (fromCollection->isArray()) { fn = conditional ? SGF.SGM.getArrayConditionalCast(loc) : SGF.SGM.getArrayForceCast(loc); - } else if (fromCollection->getAnyNominal() == ctx.getDictionaryDecl()) { + } else if (fromCollection->isDictionary()) { fn = (conditional ? SGF.SGM.getDictionaryDownCastConditional(loc) : SGF.SGM.getDictionaryDownCast(loc)); - } else if (fromCollection->getAnyNominal() == ctx.getSetDecl()) { + } else if (fromCollection->isSet()) { fn = (conditional ? SGF.SGM.getSetDownCastConditional(loc) : SGF.SGM.getSetDownCast(loc)); diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 2e123a0a2bdb0..4ca3f4117490b 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -1389,13 +1389,12 @@ visitCollectionUpcastConversionExpr(CollectionUpcastConversionExpr *E, auto toCollection = E->getType()->getCanonicalType(); // Get the intrinsic function. - auto &ctx = SGF.getASTContext(); FuncDecl *fn = nullptr; - if (fromCollection->getAnyNominal() == ctx.getArrayDecl()) { + if (fromCollection->isArray()) { fn = SGF.SGM.getArrayForceCast(loc); - } else if (fromCollection->getAnyNominal() == ctx.getDictionaryDecl()) { + } else if (fromCollection->isDictionary()) { fn = SGF.SGM.getDictionaryUpCast(loc); - } else if (fromCollection->getAnyNominal() == ctx.getSetDecl()) { + } else if (fromCollection->isSet()) { fn = SGF.SGM.getSetUpCast(loc); } else { llvm_unreachable("unsupported collection upcast kind"); @@ -1868,8 +1867,7 @@ RValue SILGenFunction::emitAnyHashableErasure(SILLocation loc, // Ensure that the intrinsic function exists. auto convertFn = SGM.getConvertToAnyHashable(loc); if (!convertFn) - return emitUndefRValue( - loc, getASTContext().getAnyHashableDecl()->getDeclaredInterfaceType()); + return emitUndefRValue(loc, getASTContext().getAnyHashableType()); // Construct the substitution for T: Hashable. auto subMap = SubstitutionMap::getProtocolSubstitutions( @@ -2745,8 +2743,7 @@ static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM, params.push_back({loweredBaseTy, paramConvention}); auto &C = SGM.getASTContext(); if (!indexes.empty()) - params.push_back({C.getUnsafeRawPointerDecl()->getDeclaredInterfaceType() - ->getCanonicalType(), + params.push_back({C.getUnsafeRawPointerType()->getCanonicalType(), ParameterConvention::Direct_Unowned}); SILResultInfo result(loweredPropTy, ResultConvention::Indirect); @@ -2896,8 +2893,7 @@ static SILFunction *getOrCreateKeyPathSetter(SILGenModule &SGM, : paramConvention}); // indexes if (!indexes.empty()) - params.push_back({C.getUnsafeRawPointerDecl()->getDeclaredInterfaceType() - ->getCanonicalType(), + params.push_back({C.getUnsafeRawPointerType()->getCanonicalType(), ParameterConvention::Direct_Unowned}); return SILFunctionType::get(genericSig, @@ -3043,10 +3039,9 @@ getOrCreateKeyPathEqualsAndHash(SILGenModule &SGM, } auto &C = SGM.getASTContext(); - auto unsafeRawPointerTy = C.getUnsafeRawPointerDecl()->getDeclaredInterfaceType() - ->getCanonicalType(); - auto boolTy = C.getBoolDecl()->getDeclaredInterfaceType()->getCanonicalType(); - auto intTy = C.getIntDecl()->getDeclaredInterfaceType()->getCanonicalType(); + auto unsafeRawPointerTy = C.getUnsafeRawPointerType()->getCanonicalType(); + auto boolTy = C.getBoolType()->getCanonicalType(); + auto intTy = C.getIntType()->getCanonicalType(); auto hashableProto = C.getProtocol(KnownProtocolKind::Hashable); @@ -3858,7 +3853,7 @@ RValue RValueEmitter::visitCollectionExpr(CollectionExpr *E, SGFContext C) { } else { arrayType = E->getType()->getCanonicalType(); auto genericType = cast(arrayType); - assert(genericType->getDecl() == SGF.getASTContext().getArrayDecl()); + assert(genericType->isArray()); elementType = genericType.getGenericArgs()[0]; } diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp index a177cfb13fce1..19195df34fb18 100644 --- a/lib/SILGen/SILGenPoly.cpp +++ b/lib/SILGen/SILGenPoly.cpp @@ -511,12 +511,11 @@ ManagedValue Transform::transform(ManagedValue v, // Attempt collection upcast only if input and output declarations match. if (inputStruct == outputStruct) { FuncDecl *fn = nullptr; - auto &ctx = SGF.getASTContext(); - if (inputStruct == ctx.getArrayDecl()) { + if (inputSubstType->isArray()) { fn = SGF.SGM.getArrayForceCast(Loc); - } else if (inputStruct == ctx.getDictionaryDecl()) { + } else if (inputSubstType->isDictionary()) { fn = SGF.SGM.getDictionaryUpCast(Loc); - } else if (inputStruct == ctx.getSetDecl()) { + } else if (inputSubstType->isSet()) { fn = SGF.SGM.getSetUpCast(Loc); } else { llvm_unreachable("unsupported collection upcast kind"); @@ -608,9 +607,7 @@ ManagedValue Transform::transform(ManagedValue v, } // - T : Hashable to AnyHashable - if (isa(outputSubstType) && - outputSubstType->getAnyNominal() == - SGF.getASTContext().getAnyHashableDecl()) { + if (outputSubstType->isAnyHashable()) { auto *protocol = SGF.getASTContext().getProtocol( KnownProtocolKind::Hashable); auto conformance = SGF.SGM.M.getSwiftModule()->lookupConformance( diff --git a/lib/SILOptimizer/Differentiation/PullbackCloner.cpp b/lib/SILOptimizer/Differentiation/PullbackCloner.cpp index ff532efe08918..a16c48d94b6cf 100644 --- a/lib/SILOptimizer/Differentiation/PullbackCloner.cpp +++ b/lib/SILOptimizer/Differentiation/PullbackCloner.cpp @@ -1801,7 +1801,7 @@ bool PullbackCloner::Implementation::run() { // Do not diagnose `Optional`-typed values, which will have special-case // differentiation support. if (auto *enumDecl = type.getEnumOrBoundGenericEnum()) { - if (enumDecl != getContext().getASTContext().getOptionalDecl()) { + if (!type.getASTType()->isOptional()) { getContext().emitNondifferentiabilityError( v, getInvoker(), diag::autodiff_enums_unsupported); errorOccurred = true; @@ -2188,8 +2188,7 @@ void PullbackCloner::Implementation::accumulateAdjointForOptional( // Handle `switch_enum` on `Optional`. // `Optional` auto optionalTy = remapType(optionalValue->getType()); - assert(optionalTy.getASTType().getEnumOrBoundGenericEnum() == - getASTContext().getOptionalDecl()); + assert(optionalTy.getASTType()->isOptional()); // `T` auto wrappedType = optionalTy.getOptionalObjectType(); // `T.TangentVector` @@ -2431,10 +2430,8 @@ void PullbackCloner::Implementation::visitSILBasicBlock(SILBasicBlock *bb) { if (!termInst) return false; if (auto *sei = dyn_cast(termInst)) { - auto *optionalEnumDecl = ctx.getOptionalDecl(); auto operandTy = sei->getOperand()->getType(); - return operandTy.getASTType().getEnumOrBoundGenericEnum() == - optionalEnumDecl; + return operandTy.getASTType()->isOptional(); } return false; }; @@ -3026,7 +3023,7 @@ AllocStackInst *PullbackCloner::Implementation::getArrayAdjointElementBuffer( auto *eltIndexLiteral = builder.createIntegerLiteral(loc, builtinIntType, eltIndex); auto intType = SILType::getPrimitiveObjectType( - ctx.getIntDecl()->getDeclaredInterfaceType()->getCanonicalType()); + ctx.getIntType()->getCanonicalType()); // %index_int = struct $Int (%index_literal) auto *eltIndexInt = builder.createStruct(loc, intType, {eltIndexLiteral}); auto *swiftModule = getModule().getSwiftModule(); diff --git a/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp b/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp index 8a87c997343b6..03e211d45ec7a 100644 --- a/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp +++ b/lib/SILOptimizer/LoopTransforms/ArrayBoundsCheckOpts.cpp @@ -783,12 +783,6 @@ class AccessFunction { } }; -static bool hasArrayType(SILValue Value, SILModule &M) { - return Value->getType().getNominalOrBoundGenericNominal() == - M.getASTContext().getArrayDecl(); -} - - /// A dominating cond_fail on the same value ensures that this value is false. static bool isValueKnownFalseAt(SILValue Val, SILInstruction *At, DominanceInfo *DT) { @@ -1339,7 +1333,7 @@ bool ABCOpt::hoistChecksInLoop(DominanceInfoNode *DTNode, ABCAnalysis &ABC, // Check if the loop iterates from 0 to the count of this array. if (F.isZeroToCount(ArrayVal) && // This works only for Arrays but not e.g. for ArraySlice. - hasArrayType(ArrayVal, Header->getModule())) { + ArrayVal->getType().getASTType()->isArray()) { // We can remove the check. This is even possible if the block does not // dominate the loop exit block. Changed = true; diff --git a/lib/SILOptimizer/Mandatory/Differentiation.cpp b/lib/SILOptimizer/Mandatory/Differentiation.cpp index 1db8cfcfd400b..c7cb877bb03c6 100644 --- a/lib/SILOptimizer/Mandatory/Differentiation.cpp +++ b/lib/SILOptimizer/Mandatory/Differentiation.cpp @@ -864,9 +864,9 @@ static void emitFatalError(ADContext &context, SILFunction *f, if (arg->getOwnershipKind() == OwnershipKind::Owned) builder.emitDestroyOperation(loc, arg); // Fatal error with a nice message. - auto neverResultInfo = - SILResultInfo(context.getModule().getASTContext().getNeverType(), - ResultConvention::Unowned); + auto neverTy = + context.getModule().getASTContext().getNeverType()->getCanonicalType(); + auto neverResultInfo = SILResultInfo(neverTy, ResultConvention::Unowned); // Fatal error function must have type `@convention(thin) () -> Never`. auto fatalErrorFnType = SILFunctionType::get( /*genericSig*/ nullptr, SILFunctionType::ExtInfo::getThin(), diff --git a/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp b/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp index f03ab2f9dd996..bae8f7e459587 100644 --- a/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp +++ b/lib/SILOptimizer/Mandatory/OSLogOptimization.cpp @@ -243,18 +243,6 @@ static bool isIntegerOrBoolType(SILType silType, ASTContext &astContext) { return nominalDecl && isStdlibIntegerOrBoolDecl(nominalDecl, astContext); } -/// Return true if and only if the given SIL type represents a String type. -static bool isStringType(SILType silType, ASTContext &astContext) { - NominalTypeDecl *nominalDecl = silType.getNominalOrBoundGenericNominal(); - return nominalDecl && nominalDecl == astContext.getStringDecl(); -} - -/// Return true if and only if the given SIL type represents an Array type. -static bool isArrayType(SILType silType, ASTContext &astContext) { - NominalTypeDecl *nominalDecl = silType.getNominalOrBoundGenericNominal(); - return nominalDecl && nominalDecl == astContext.getArrayDecl(); -} - /// Decide if the given instruction (which could possibly be a call) should /// be constant evaluated. /// @@ -297,7 +285,7 @@ static bool isFoldableIntOrBool(SILValue value, ASTContext &astContext) { /// Return true iff the given value is a string and is not an initialization /// of an string from a string literal. static bool isFoldableString(SILValue value, ASTContext &astContext) { - return isStringType(value->getType(), astContext) && + return value->getType().getASTType()->isString() && (!isa(value) || !getStringMakeUTF8Init(cast(value))); } @@ -305,7 +293,7 @@ static bool isFoldableString(SILValue value, ASTContext &astContext) { /// Return true iff the given value is an array and is not an initialization /// of an array from an array literal. static bool isFoldableArray(SILValue value, ASTContext &astContext) { - if (!isArrayType(value->getType(), astContext)) + if (!value->getType().getASTType()->isArray()) return false; // If value is an initialization of an array from a literal or an empty array // initializer, it need not be folded. Arrays constructed from literals use a @@ -523,8 +511,7 @@ static SILValue emitCodeForConstantArray(ArrayRef elements, CanType arrayType, SILBuilder &builder, SILLocation loc) { ASTContext &astContext = builder.getASTContext(); - assert(astContext.getArrayDecl() == - arrayType->getNominalOrBoundGenericNominal()); + assert(arrayType->isArray()); SILModule &module = builder.getModule(); // Create a SILValue for the number of elements. @@ -672,8 +659,7 @@ static SILValue emitCodeForSymbolicValue(SymbolicValue symVal, switch (symVal.getKind()) { case SymbolicValue::String: { - assert(astContext.getStringDecl() == - expectedType->getNominalOrBoundGenericNominal()); + assert(expectedType->isString()); StringRef stringVal = symVal.getStringValue(); StringLiteralInst *stringLitInst = builder.createStringLiteral( diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp index 909a06ca6f10c..e93cb8083ae89 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp @@ -416,7 +416,7 @@ bool SILCombiner::tryOptimizeKeypathKVCString(ApplyInst *AI, // Method should return `String?` auto &C = calleeFn->getASTContext(); auto objTy = AI->getType().getOptionalObjectType(); - if (!objTy || objTy.getStructOrBoundGenericStruct() != C.getStringDecl()) + if (!objTy || !objTy.getASTType()->isString()) return false; auto objcString = kp->getPattern()->getObjCString(); diff --git a/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp index f29b6409b2457..75d5dc94a5c93 100644 --- a/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp +++ b/lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp @@ -294,11 +294,8 @@ bool ArrayAllocation::replaceAppendContentOf() { ArraySemanticsCall AppendContentsOf(AppendContentOfCall); assert(AppendContentsOf && "Must be AppendContentsOf call"); - NominalTypeDecl *AppendSelfArray = AppendContentsOf.getSelf()->getType(). - getASTType()->getAnyNominal(); - // In case if it's not an Array, but e.g. an ContiguousArray - if (AppendSelfArray != Ctx.getArrayDecl()) + if (!AppendContentsOf.getSelf()->getType().getASTType()->isArray()) continue; SILType ArrayType = ArrayValue->getType(); diff --git a/lib/SILOptimizer/Transforms/SILSROA.cpp b/lib/SILOptimizer/Transforms/SILSROA.cpp index 64e2a51ae2799..62221114446b8 100644 --- a/lib/SILOptimizer/Transforms/SILSROA.cpp +++ b/lib/SILOptimizer/Transforms/SILSROA.cpp @@ -289,9 +289,10 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector &Worklist /// by a high-level SIL optimization. Values of that type must not be split /// so that those high-level optimizations can analyze the code. static bool isSemanticType(ASTContext &ctxt, SILType ty) { - NominalTypeDecl *stringDecl = ctxt.getStringDecl(); - if (ty.getStructOrBoundGenericStruct() == stringDecl) + if (ty.getASTType()->isString()) { return true; + } + return false; } diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp index d1eabfc551803..e1acc2bd97e38 100644 --- a/lib/SILOptimizer/Utils/CastOptimizer.cpp +++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp @@ -260,10 +260,8 @@ CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) { // AnyHashable is a special case that we do not handle since we only handle // objc targets in this function. Bailout early. - if (auto dt = target.getNominalOrBoundGenericNominal()) { - if (dt == mod.getASTContext().getAnyHashableDecl()) { - return nullptr; - } + if (target->isAnyHashable()) { + return nullptr; } SILValue src = dynamicCast.getSource(); diff --git a/lib/SILOptimizer/Utils/ConstExpr.cpp b/lib/SILOptimizer/Utils/ConstExpr.cpp index 8246f99684d8b..d76242be0deae 100644 --- a/lib/SILOptimizer/Utils/ConstExpr.cpp +++ b/lib/SILOptimizer/Utils/ConstExpr.cpp @@ -822,7 +822,7 @@ extractStringOrStaticStringValue(SymbolicValue stringValue) { /// element type. Otherwise, return a null Type. static Type getArrayElementType(Type ty) { if (auto bgst = ty->getAs()) - if (bgst->getDecl() == bgst->getASTContext().getArrayDecl()) + if (bgst->isArray()) return bgst->getGenericArgs()[0]; return Type(); } @@ -832,20 +832,16 @@ static Type getArrayElementType(Type ty) { /// type, \c true if it is a signed integer type and \c false if it is an /// unsigned integer type. static Optional getSignIfStdlibIntegerType(Type ty) { - StructDecl *decl = ty->getStructOrBoundGenericStruct(); - if (!decl) - return None; - ASTContext &astCtx = ty->getASTContext(); - if (decl == astCtx.getIntDecl() || decl == astCtx.getInt8Decl() || - decl == astCtx.getInt16Decl() || decl == astCtx.getInt32Decl() || - decl == astCtx.getInt64Decl()) { + if (ty->isInt() || ty->isInt8() || ty->isInt16() || ty->isInt32() || + ty->isInt64()) { return true; } - if (decl == astCtx.getUIntDecl() || decl == astCtx.getUInt8Decl() || - decl == astCtx.getUInt16Decl() || decl == astCtx.getUInt32Decl() || - decl == astCtx.getUInt64Decl()) { + + if (ty->isUInt() || ty->isUInt8() || ty->isUInt16() || ty->isUInt32() || + ty->isUInt64()) { return false; } + return None; } diff --git a/lib/SILOptimizer/Utils/ConstantFolding.cpp b/lib/SILOptimizer/Utils/ConstantFolding.cpp index 5f8baf31846cd..e2ef2e19c863a 100644 --- a/lib/SILOptimizer/Utils/ConstantFolding.cpp +++ b/lib/SILOptimizer/Utils/ConstantFolding.cpp @@ -1117,9 +1117,7 @@ bool maybeExplicitFPCons(BuiltinInst *BI, const BuiltinInfo &Builtin) { // intermediate step. So we conservatively assume that an implicit // construction of Double could be a part of an explicit conversion // and suppress the warning. - auto &astCtx = BI->getModule().getASTContext(); - auto *typeDecl = callExpr->getType()->getCanonicalType().getAnyNominal(); - return (typeDecl && typeDecl == astCtx.getDoubleDecl()); + return callExpr->getType()->isDouble(); } static SILValue foldFPTrunc(BuiltinInst *BI, const BuiltinInfo &Builtin, diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index b60faeed02ca5..efb1259b840b0 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -520,7 +520,7 @@ namespace { /*implicit*/ true); cs.setType( stringExpr, - cs.getASTContext().getStringDecl()->getDeclaredInterfaceType()); + cs.getASTContext().getStringType()); keyPath->setObjCStringLiteralExpr(stringExpr); } } @@ -1978,7 +1978,7 @@ namespace { if (auto nom = keyPathTy->getAs()) { // AnyKeyPath is rvalue T -> rvalue Any? - if (nom->getDecl() == cs.getASTContext().getAnyKeyPathDecl()) { + if (nom->isAnyKeyPath()) { valueTy = ProtocolCompositionType::get(cs.getASTContext(), {}, /*explicit anyobject*/ false); valueTy = OptionalType::get(valueTy); @@ -2008,8 +2008,7 @@ namespace { if (!baseTy->isEqual(cs.getType(base)->getRValueType())) base = coerceToType(base, baseTy, locator); - if (keyPathBGT->getDecl() - == cs.getASTContext().getPartialKeyPathDecl()) { + if (keyPathBGT->isPartialKeyPath()) { // PartialKeyPath is rvalue T -> rvalue Any valueTy = ProtocolCompositionType::get(cs.getASTContext(), {}, /*explicit anyobject*/ false); @@ -2021,14 +2020,12 @@ namespace { valueTy = keyPathBGT->getGenericArgs()[1]; // The result may be an lvalue based on the base and key path kind. - if (keyPathBGT->getDecl() == cs.getASTContext().getKeyPathDecl()) { + if (keyPathBGT->isKeyPath()) { resultIsLValue = false; base = cs.coerceToRValue(base); - } else if (keyPathBGT->getDecl() == - cs.getASTContext().getWritableKeyPathDecl()) { + } else if (keyPathBGT->isWritableKeyPath()) { resultIsLValue = cs.getType(base)->hasLValueType(); - } else if (keyPathBGT->getDecl() == - cs.getASTContext().getReferenceWritableKeyPathDecl()) { + } else if (keyPathBGT->isReferenceWritableKeyPath()) { resultIsLValue = true; base = cs.coerceToRValue(base); } else { @@ -2848,7 +2845,7 @@ namespace { // Make the integer literals for the parameters. auto buildExprFromUnsigned = [&](unsigned value) { LiteralExpr *expr = IntegerLiteralExpr::createFromUnsigned(ctx, value); - cs.setType(expr, ctx.getIntDecl()->getDeclaredInterfaceType()); + cs.setType(expr, ctx.getIntType()); return handleIntegerLiteralExpr(expr); }; @@ -3851,10 +3848,7 @@ namespace { ctx.Diags.diagnose(SourceLoc(), diag::broken_bool); } - cs.setType(isSomeExpr, - boolDecl - ? boolDecl->getDeclaredInterfaceType() - : Type()); + cs.setType(isSomeExpr, boolDecl ? ctx.getBoolType() : Type()); return isSomeExpr; } @@ -7142,8 +7136,7 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, case TypeKind::BoundGenericStruct: { auto toStruct = cast(desugaredToType); - if (toStruct->getDecl() != ctx.getArrayDecl() && - toStruct->getDecl() != ctx.getDictionaryDecl()) + if (!toStruct->isArray() && !toStruct->isDictionary()) break; if (toStruct->getDecl() == cs.getType(expr)->getAnyNominal()) @@ -8633,7 +8626,7 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) { return None; // FIXME: Feels like we could leverage existing code more. - Type boolType = cs.getASTContext().getBoolDecl()->getDeclaredInterfaceType(); + Type boolType = cs.getASTContext().getBoolType(); guardExpr = solution.coerceToType( guardExpr, boolType, cs.getConstraintLocator(info.guardExpr)); if (!guardExpr) diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index a67936e6d27f9..1276de22da4cd 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -550,11 +550,11 @@ void BindingSet::addBinding(PotentialBinding binding) { if (type->isCGFloatType() && llvm::any_of(Bindings, [](const PotentialBinding &binding) { - return binding.BindingType->isDoubleType(); + return binding.BindingType->isDouble(); })) return; - if (type->isDoubleType()) { + if (type->isDouble()) { auto inferredCGFloat = llvm::find_if(Bindings, [](const PotentialBinding &binding) { return binding.BindingType->isCGFloatType(); @@ -1114,7 +1114,7 @@ PotentialBindings::inferFromRelational(Constraint *constraint) { if (locator->isKeyPathType()) { auto *BGT = type->lookThroughAllOptionalTypes()->getAs(); - if (!BGT || !isKnownKeyPathDecl(CS.getASTContext(), BGT->getDecl())) + if (!BGT || !isKnownKeyPathType(BGT)) return None; } diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index a140d231df512..efd2d4654d357 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -1978,15 +1978,11 @@ AssignmentFailure::resolveImmutableBase(Expr *expr) const { auto indexType = resolveType(argType->getElementType(0)); - if (auto bgt = indexType->getAs()) { - // In Swift versions lower than 5, this check will fail as read only - // key paths can masquerade as writable for compatibilty reasons. - // This is fine as in this case we just fall back on old diagnostics. - auto &ctx = getASTContext(); - if (bgt->getDecl() == ctx.getKeyPathDecl() || - bgt->getDecl() == ctx.getPartialKeyPathDecl()) { - return {expr, member}; - } + // In Swift versions lower than 5, this check will fail as read only + // key paths can masquerade as writable for compatibilty reasons. + // This is fine as in this case we just fall back on old diagnostics. + if (indexType->isKeyPath() || indexType->isPartialKeyPath()) { + return {expr, member}; } } } @@ -2837,13 +2833,10 @@ bool ContextualFailure::trySequenceSubsequenceFixIts( if (!getASTContext().getStdlibModule()) return false; - auto String = getASTContext().getStringDecl()->getDeclaredInterfaceType(); - auto Substring = getASTContext().getSubstringDecl()->getDeclaredInterfaceType(); - // Substring -> String conversion // Wrap in String.init - if (getFromType()->isEqual(Substring)) { - if (getToType()->isEqual(String)) { + if (getFromType()->isSubstring()) { + if (getToType()->isString()) { auto *anchor = castToExpr(getAnchor())->getSemanticsProvidingExpr(); if (auto *CE = dyn_cast(anchor)) { anchor = CE->getSubExpr(); @@ -6891,13 +6884,11 @@ bool MultiArgFuncKeyPathFailure::diagnoseAsError() { bool UnableToInferKeyPathRootFailure::diagnoseAsError() { assert(isExpr(getAnchor()) && "Expected key path expression"); - auto &ctx = getASTContext(); auto contextualType = getContextualType(getAnchor()); auto *keyPathExpr = castToExpr(getAnchor()); auto emitKeyPathDiagnostic = [&]() { - if (contextualType && - contextualType->getAnyNominal() == ctx.getAnyKeyPathDecl()) { + if (contextualType && contextualType->isAnyKeyPath()) { return emitDiagnostic( diag::cannot_infer_keypath_root_anykeypath_context); } diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index d85889325d466..c7d439ff7ccd4 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -383,7 +383,7 @@ namespace { return true; // Don't favor narrowing conversions. - if (argTy->isDoubleType() && paramTy->isCGFloatType()) + if (argTy->isDouble() && paramTy->isCGFloatType()) return false; llvm::SmallSetVector literalProtos; @@ -420,7 +420,7 @@ namespace { // it is the same as the parameter type. // Check whether there is a default type to compare against. if (paramTy->isEqual(defaultType) || - (defaultType->isDoubleType() && paramTy->isCGFloatType())) + (defaultType->isDouble() && paramTy->isCGFloatType())) return true; } } @@ -570,7 +570,7 @@ namespace { // in order to preserve current behavior, let's not favor overloads // which would result in conversion from CGFloat to Double; otherwise // it would lead to ambiguities. - if (argTy->isCGFloatType() && paramTy->isDoubleType()) + if (argTy->isCGFloatType() && paramTy->isDouble()) return false; return isFavoredParamAndArg(CS, paramTy, argTy) && @@ -733,10 +733,10 @@ namespace { // Avoid favoring overloads that would require narrowing conversion // to match the arguments. { - if (firstArgTy->isDoubleType() && firstParamTy->isCGFloatType()) + if (firstArgTy->isDouble() && firstParamTy->isCGFloatType()) return false; - if (secondArgTy->isDoubleType() && secondParamTy->isCGFloatType()) + if (secondArgTy->isDouble() && secondParamTy->isCGFloatType()) return false; } @@ -1148,8 +1148,7 @@ namespace { if (TypeChecker::requirePointerArgumentIntrinsics(ctx, expr->getLoc())) return nullptr; - auto unsafeRawPointer = ctx.getUnsafeRawPointerDecl(); - return unsafeRawPointer->getDeclaredInterfaceType(); + return ctx.getUnsafeRawPointerType(); } default: @@ -2366,7 +2365,7 @@ namespace { } case PatternKind::Bool: - return setType(CS.getASTContext().getBoolDecl()->getDeclaredInterfaceType()); + return setType(CS.getASTContext().getBoolType()); case PatternKind::EnumElement: { auto enumPattern = cast(pattern); @@ -3045,7 +3044,7 @@ namespace { } Type visitEnumIsCaseExpr(EnumIsCaseExpr *expr) { - return CS.getASTContext().getBoolDecl()->getDeclaredInterfaceType(); + return CS.getASTContext().getBoolType(); } Type visitLazyInitializerExpr(LazyInitializerExpr *expr) { diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 6a9eb0a52e445..332599c576b5e 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -2876,11 +2876,11 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2, static bool isStringCompatiblePointerBaseType(ASTContext &ctx, Type baseType) { // Allow strings to be passed to pointer-to-byte or pointer-to-void types. - if (baseType->isEqual(ctx.getInt8Decl()->getDeclaredInterfaceType())) + if (baseType->isInt8()) return true; - if (baseType->isEqual(ctx.getUInt8Decl()->getDeclaredInterfaceType())) + if (baseType->isUInt8()) return true; - if (baseType->isEqual(ctx.TheEmptyTupleType)) + if (baseType->isVoid()) return true; return false; @@ -5194,7 +5194,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, if (kind >= ConstraintKind::Subtype && nominal1->getDecl() != nominal2->getDecl() && ((nominal1->isCGFloatType() || nominal2->isCGFloatType()) && - (nominal1->isDoubleType() || nominal2->isDoubleType()))) { + (nominal1->isDouble() || nominal2->isDouble()))) { ConstraintLocatorBuilder location{locator}; // Look through all value-to-optional promotions to allow // conversions like Double -> CGFloat?? and vice versa. @@ -5490,7 +5490,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, } // T -> AnyHashable. - if (isAnyHashableType(desugar2)) { + if (desugar2->isAnyHashable()) { // Don't allow this in operator contexts or we'll end up allowing // 'T() == U()' for unrelated T and U that just happen to be Hashable. // We can remove this special case when we implement operator hiding. @@ -5673,8 +5673,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, // The pointer can be converted from a string, if the element // type is compatible. auto &ctx = getASTContext(); - if (type1->isEqual( - ctx.getStringDecl()->getDeclaredInterfaceType())) { + if (type1->isString()) { auto baseTy = getFixedTypeRecursive(pointeeTy, false); if (baseTy->isTypeVariableOrMember() || @@ -7098,7 +7097,7 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName, // If the instance type is String bridged to NSString, compute // the type we'll look in for bridging. Type bridgedType; - if (baseObjTy->getAnyNominal() == ctx.getStringDecl()) { + if (baseObjTy->isString()) { if (Type classType = ctx.getBridgedToObjC(DC, instanceTy)) { bridgedType = classType; } @@ -9071,13 +9070,13 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1, // FIXME: This should be an associated type of the protocol. auto &ctx = getASTContext(); if (auto fromBGT = unwrappedToType->getAs()) { - if (fromBGT->getDecl() == ctx.getArrayDecl()) { + if (fromBGT->isArray()) { // [AnyObject] addConstraint(ConstraintKind::Bind, fromBGT->getGenericArgs()[0], ctx.getAnyObjectType(), getConstraintLocator(locator.withPathElement( LocatorPathElt::GenericArgument(0)))); - } else if (fromBGT->getDecl() == ctx.getDictionaryDecl()) { + } else if (fromBGT->isDictionary()) { // [NSObject : AnyObject] auto nsObjectType = ctx.getNSObjectType(); if (!nsObjectType) { @@ -9096,7 +9095,7 @@ ConstraintSystem::simplifyBridgingConstraint(Type type1, getConstraintLocator( locator.withPathElement( LocatorPathElt::GenericArgument(1)))); - } else if (fromBGT->getDecl() == ctx.getSetDecl()) { + } else if (fromBGT->isSet()) { auto nsObjectType = ctx.getNSObjectType(); if (!nsObjectType) { // Not a bridging case. Should we detect this earlier? @@ -9239,12 +9238,12 @@ ConstraintSystem::simplifyKeyPathConstraint( definitelyKeyPathType = true; // We can get root and value from a concrete key path type. - if (bgt->getDecl() == getASTContext().getKeyPathDecl() || - bgt->getDecl() == getASTContext().getWritableKeyPathDecl() || - bgt->getDecl() == getASTContext().getReferenceWritableKeyPathDecl()) { + if (bgt->isKeyPath() || + bgt->isWritableKeyPath() || + bgt->isReferenceWritableKeyPath()) { boundRoot = bgt->getGenericArgs()[0]; boundValue = bgt->getGenericArgs()[1]; - } else if (bgt->getDecl() == getASTContext().getPartialKeyPathDecl()) { + } else if (bgt->isPartialKeyPath()) { if (!allowPartial) return false; @@ -9480,11 +9479,9 @@ ConstraintSystem::simplifyKeyPathConstraint( // FIXME: Allow the type to be upcast if the type system has a concrete // KeyPath type assigned to the expression already. if (auto keyPathBGT = keyPathTy->getAs()) { - if (keyPathBGT->getDecl() == getASTContext().getKeyPathDecl()) + if (keyPathBGT->isKeyPath()) kpDecl = getASTContext().getKeyPathDecl(); - else if (keyPathBGT->getDecl() == - getASTContext().getWritableKeyPathDecl() && - capability >= Writable) + else if (keyPathBGT->isWritableKeyPath() && capability >= Writable) kpDecl = getASTContext().getWritableKeyPathDecl(); } @@ -9534,16 +9531,14 @@ ConstraintSystem::simplifyKeyPathApplicationConstraint( return SolutionKind::Error; } - if (auto clas = keyPathTy->getAs()) { - if (clas->getDecl() == getASTContext().getAnyKeyPathDecl()) { - // Read-only keypath, whose projected value is upcast to `Any?`. - // The root type can be anything. - Type resultTy = ProtocolCompositionType::get(getASTContext(), {}, - /*explicit AnyObject*/ false); - resultTy = OptionalType::get(resultTy); - return matchTypes(resultTy, valueTy, ConstraintKind::Bind, - subflags, locator); - } + if (keyPathTy->isAnyKeyPath()) { + // Read-only keypath, whose projected value is upcast to `Any?`. + // The root type can be anything. + Type resultTy = ProtocolCompositionType::get(getASTContext(), {}, + /*explicit AnyObject*/ false); + resultTy = OptionalType::get(resultTy); + return matchTypes(resultTy, valueTy, ConstraintKind::Bind, + subflags, locator); } if (auto bgt = keyPathTy->getAs()) { @@ -9568,7 +9563,7 @@ ConstraintSystem::simplifyKeyPathApplicationConstraint( llvm_unreachable("unhandled match"); }; - if (bgt->getDecl() == getASTContext().getPartialKeyPathDecl()) { + if (bgt->isPartialKeyPath()) { // Read-only keypath, whose projected value is upcast to `Any`. auto resultTy = ProtocolCompositionType::get(getASTContext(), {}, /*explicit AnyObject*/ false); @@ -9603,14 +9598,14 @@ ConstraintSystem::simplifyKeyPathApplicationConstraint( ConstraintKind::Bind, subflags, locator); }; - if (bgt->getDecl() == getASTContext().getKeyPathDecl()) { + if (bgt->isKeyPath()) { // Read-only keypath. if (!matchRoot(ConstraintKind::Conversion)) return SolutionKind::Error; return solveRValue(); } - if (bgt->getDecl() == getASTContext().getWritableKeyPathDecl()) { + if (bgt->isWritableKeyPath()) { // Writable keypath. The result can be an lvalue if the root was. // We can't convert the base without giving up lvalue-ness, though. if (!matchRoot(ConstraintKind::Equal)) @@ -9623,7 +9618,7 @@ ConstraintSystem::simplifyKeyPathApplicationConstraint( return solveUnknown(); return solveRValue(); } - if (bgt->getDecl() == getASTContext().getReferenceWritableKeyPathDecl()) { + if (bgt->isReferenceWritableKeyPath()) { if (!matchRoot(ConstraintKind::Conversion)) return SolutionKind::Error; @@ -10740,11 +10735,11 @@ ConstraintSystem::simplifyRestrictedConstraintImpl( auto &ctx = getASTContext(); auto int8Con = Constraint::create(*this, ConstraintKind::Bind, baseType2, - ctx.getInt8Decl()->getDeclaredInterfaceType(), + ctx.getInt8Type(), getConstraintLocator(locator)); auto uint8Con = Constraint::create(*this, ConstraintKind::Bind, baseType2, - ctx.getUInt8Decl()->getDeclaredInterfaceType(), + ctx.getUInt8Type(), getConstraintLocator(locator)); auto voidCon = Constraint::create(*this, ConstraintKind::Bind, baseType2, ctx.TheEmptyTupleType, @@ -10857,8 +10852,7 @@ ConstraintSystem::simplifyRestrictedConstraintImpl( case ConversionRestrictionKind::HashableToAnyHashable: { // We never want to do this if the LHS is already AnyHashable. type1 = simplifyType(type1); - if (isAnyHashableType( - type1->getRValueType()->lookThroughAllOptionalTypes())) { + if (type1->getRValueType()->lookThroughAllOptionalTypes()->isAnyHashable()) { return SolutionKind::Error; } diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp index 7c383c8695bcd..1814e79175afe 100644 --- a/lib/Sema/CodeSynthesis.cpp +++ b/lib/Sema/CodeSynthesis.cpp @@ -184,7 +184,7 @@ static void maybeAddMemberwiseDefaultArg(ParamDecl *arg, VarDecl *var, bool isNilInitialized = var->getAttrs().hasAttribute() || (!isExplicitlyInitialized && isDefaultInitializable && - var->getValueInterfaceType()->getAnyNominal() == ctx.getOptionalDecl() && + var->getValueInterfaceType()->isOptional() && (var->getAttachedPropertyWrappers().empty() || var->isPropertyMemberwiseInitializedWithWrappedType())); if (isNilInitialized) { diff --git a/lib/Sema/ConstantnessSemaDiagnostics.cpp b/lib/Sema/ConstantnessSemaDiagnostics.cpp index 8f29be5752d5f..476022b05058a 100644 --- a/lib/Sema/ConstantnessSemaDiagnostics.cpp +++ b/lib/Sema/ConstantnessSemaDiagnostics.cpp @@ -201,47 +201,17 @@ static Expr *checkConstantness(Expr *expr) { return nullptr; } -/// Return true iff the norminal type decl \c numberDecl is a known stdlib -/// integer decl. -static bool isStdlibInteger(NominalTypeDecl *numberDecl) { - ASTContext &astCtx = numberDecl->getASTContext(); - return (numberDecl == astCtx.getIntDecl() || - numberDecl == astCtx.getInt8Decl() || - numberDecl == astCtx.getInt16Decl() || - numberDecl == astCtx.getInt32Decl() || - numberDecl == astCtx.getInt64Decl() || - numberDecl == astCtx.getUIntDecl() || - numberDecl == astCtx.getUInt8Decl() || - numberDecl == astCtx.getUInt16Decl() || - numberDecl == astCtx.getUInt32Decl() || - numberDecl == astCtx.getUInt64Decl()); -} - /// Return true iff the given \p type is a Stdlib integer type. static bool isIntegerType(Type type) { - NominalTypeDecl *nominalDecl = type->getNominalOrBoundGenericNominal(); - return nominalDecl && isStdlibInteger(nominalDecl); -} - -/// Return true iff the norminal type decl \c numberDecl is a known stdlib float -/// decl. -static bool isStdlibFloat(NominalTypeDecl *numberDecl) { - ASTContext &astCtx = numberDecl->getASTContext(); - return (numberDecl == astCtx.getFloatDecl() || - numberDecl == astCtx.getFloat80Decl() || - numberDecl == astCtx.getDoubleDecl()); + return type->isInt() || type->isInt8() || type->isInt16() || + type->isInt32() || type->isInt64() || type->isUInt() || + type->isUInt8() || type->isUInt16() || type->isUInt32() || + type->isUInt64(); } -/// Return true iff the given \p type is a Bool type. +/// Return true iff the given \p type is a Float type. static bool isFloatType(Type type) { - NominalTypeDecl *nominalDecl = type->getNominalOrBoundGenericNominal(); - return nominalDecl && isStdlibFloat(nominalDecl); -} - -/// Return true iff the given \p type is a String type. -static bool isStringType(Type type) { - NominalTypeDecl *nominalDecl = type->getNominalOrBoundGenericNominal(); - return nominalDecl && nominalDecl == type->getASTContext().getStringDecl(); + return type->isFloat() || type->isDouble() || type->isFloat80(); } /// Given an error expression \p errorExpr, diagnose the error based on the type @@ -276,7 +246,7 @@ static void diagnoseError(Expr *errorExpr, const ASTContext &astContext, diags.diagnose(errorLoc, diag::oslog_arg_must_be_bool_literal); return; } - if (isStringType(exprType)) { + if (exprType->isString()) { diags.diagnose(errorLoc, diag::oslog_arg_must_be_string_literal); return; } diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index 595b2df262501..998e6de542ca4 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -893,15 +893,6 @@ Optional ConstraintSystem::isSetType(Type type) { return None; } -bool ConstraintSystem::isAnyHashableType(Type type) { - if (auto st = type->getAs()) { - auto &ctx = type->getASTContext(); - return st->getDecl() == ctx.getAnyHashableDecl(); - } - - return false; -} - Type ConstraintSystem::getFixedTypeRecursive(Type type, TypeMatchOptions &flags, bool wantRValue) const { @@ -2651,7 +2642,7 @@ void ConstraintSystem::bindOverloadType( fnType->getParams()[0].getPlainType()->castTo(); auto *keyPathDecl = keyPathTy->getAnyNominal(); - assert(isKnownKeyPathDecl(getASTContext(), keyPathDecl) && + assert(isKnownKeyPathType(keyPathTy) && "parameter is supposed to be a keypath"); auto *keyPathLoc = getConstraintLocator( @@ -2721,8 +2712,8 @@ void ConstraintSystem::bindOverloadType( // form additional `applicable fn` constraint here and bind it to a // function type, but it would create inconsistency with how properties // are handled, which means more special handling in CSApply. - if (keyPathDecl == getASTContext().getWritableKeyPathDecl() || - keyPathDecl == getASTContext().getReferenceWritableKeyPathDecl()) + if (keyPathTy->isWritableKeyPath() || + keyPathTy->isReferenceWritableKeyPath()) dynamicResultTy->getImpl().setCanBindToLValue(getSavedBindings(), /*enabled=*/true); @@ -4737,15 +4728,9 @@ Solution::getFunctionArgApplyInfo(ConstraintLocator *locator) const { } bool constraints::isKnownKeyPathType(Type type) { - if (auto *BGT = type->getAs()) - return isKnownKeyPathDecl(type->getASTContext(), BGT->getDecl()); - return false; -} - -bool constraints::isKnownKeyPathDecl(ASTContext &ctx, ValueDecl *decl) { - return decl == ctx.getKeyPathDecl() || decl == ctx.getWritableKeyPathDecl() || - decl == ctx.getReferenceWritableKeyPathDecl() || - decl == ctx.getPartialKeyPathDecl() || decl == ctx.getAnyKeyPathDecl(); + return type->isKeyPath() || type->isWritableKeyPath() || + type->isReferenceWritableKeyPath() || type->isPartialKeyPath() || + type->isAnyKeyPath(); } bool constraints::hasExplicitResult(ClosureExpr *closure) { diff --git a/lib/Sema/DerivedConformanceCodable.cpp b/lib/Sema/DerivedConformanceCodable.cpp index b5d8b56e3d560..78228fc2463ec 100644 --- a/lib/Sema/DerivedConformanceCodable.cpp +++ b/lib/Sema/DerivedConformanceCodable.cpp @@ -1190,7 +1190,7 @@ static FuncDecl *deriveEncodable_encode(DerivedConformance &derived) { // output: () // Create from the inside out: - auto encoderType = C.getEncoderDecl()->getDeclaredInterfaceType(); + auto encoderType = C.getEncoderType(); auto returnType = TupleType::getEmpty(C); // Params: (Encoder) @@ -1832,7 +1832,7 @@ static ValueDecl *deriveDecodable_init(DerivedConformance &derived) { // Compute from the inside out: // Params: (Decoder) - auto decoderType = C.getDecoderDecl()->getDeclaredInterfaceType(); + auto decoderType = C.getDecoderType(); auto *decoderParamDecl = new (C) ParamDecl( SourceLoc(), SourceLoc(), C.Id_from, SourceLoc(), C.Id_decoder, conformanceDC); diff --git a/lib/Sema/DerivedConformanceCodingKey.cpp b/lib/Sema/DerivedConformanceCodingKey.cpp index 3cdce3974cb82..132853b53ae59 100644 --- a/lib/Sema/DerivedConformanceCodingKey.cpp +++ b/lib/Sema/DerivedConformanceCodingKey.cpp @@ -78,7 +78,7 @@ deriveRawValueInit(AbstractFunctionDecl *initDecl, void *) { auto *rawValueDecl = new (C) ParamDecl( SourceLoc(), SourceLoc(), C.Id_rawValue, SourceLoc(), C.Id_rawValue, parentDC); - rawValueDecl->setInterfaceType(C.getIntDecl()->getDeclaredInterfaceType()); + rawValueDecl->setInterfaceType(C.getIntType()); rawValueDecl->setSpecifier(ParamSpecifier::Default); rawValueDecl->setImplicit(); auto *paramList = ParameterList::createWithoutLoc(rawValueDecl); @@ -332,10 +332,9 @@ static bool canSynthesizeCodingKey(DerivedConformance &derived) { auto *parentDC = derived.getConformanceContext(); rawType = parentDC->mapTypeIntoContext(rawType); - auto &C = derived.Context; - auto *nominal = rawType->getCanonicalType()->getAnyNominal(); - if (nominal != C.getStringDecl() && nominal != C.getIntDecl()) + if (!rawType->isString() && !rawType->isInt()) { return false; + } } auto inherited = enumDecl->getInherited(); @@ -363,9 +362,9 @@ ValueDecl *DerivedConformance::deriveCodingKey(ValueDecl *requirement) { auto name = requirement->getBaseName(); if (name == Context.Id_stringValue) { // Synthesize `var stringValue: String { get }` - auto stringType = Context.getStringDecl()->getDeclaredInterfaceType(); - auto synth = [rawType, stringType](AbstractFunctionDecl *getterDecl) { - if (rawType && rawType->isEqual(stringType)) { + auto stringType = Context.getStringType(); + auto synth = [rawType](AbstractFunctionDecl *getterDecl) { + if (rawType && rawType->isString()) { // enum SomeStringEnum : String { // case A, B, C // @derived var stringValue: String { @@ -394,11 +393,11 @@ ValueDecl *DerivedConformance::deriveCodingKey(ValueDecl *requirement) { } else if (name == Context.Id_intValue) { // Synthesize `var intValue: Int? { get }` - auto intType = Context.getIntDecl()->getDeclaredInterfaceType(); + auto intType = Context.getIntType(); auto optionalIntType = OptionalType::get(intType); - auto synth = [rawType, intType](AbstractFunctionDecl *getterDecl) { - if (rawType && rawType->isEqual(intType)) { + auto synth = [rawType](AbstractFunctionDecl *getterDecl) { + if (rawType && rawType->isInt()) { // enum SomeIntEnum : Int { // case A = 1, B = 2, C = 3 // @derived var intValue: Int? { @@ -423,9 +422,9 @@ ValueDecl *DerivedConformance::deriveCodingKey(ValueDecl *requirement) { if (argumentNames.size() == 1) { if (argumentNames[0] == Context.Id_stringValue) { // Derive `init?(stringValue:)` - auto stringType = Context.getStringDecl()->getDeclaredInterfaceType(); - auto synth = [rawType, stringType](AbstractFunctionDecl *initDecl) { - if (rawType && rawType->isEqual(stringType)) { + auto stringType = Context.getStringType(); + auto synth = [rawType](AbstractFunctionDecl *initDecl) { + if (rawType && rawType->isString()) { // enum SomeStringEnum : String { // case A = "a", B = "b", C = "c" // @derived init?(stringValue: String) { @@ -456,9 +455,9 @@ ValueDecl *DerivedConformance::deriveCodingKey(ValueDecl *requirement) { return deriveInitDecl(*this, stringType, Context.Id_stringValue, synth); } else if (argumentNames[0] == Context.Id_intValue) { // Synthesize `init?(intValue:)` - auto intType = Context.getIntDecl()->getDeclaredInterfaceType(); - auto synthesizer = [rawType, intType](AbstractFunctionDecl *initDecl) { - if (rawType && rawType->isEqual(intType)) { + auto intType = Context.getIntType(); + auto synthesizer = [rawType](AbstractFunctionDecl *initDecl) { + if (rawType && rawType->isInt()) { // enum SomeIntEnum : Int { // case A = 1, B = 2, C = 3 // @derived init?(intValue: Int) { diff --git a/lib/Sema/DerivedConformanceComparable.cpp b/lib/Sema/DerivedConformanceComparable.cpp index 483191a4a7056..44929c7defada 100644 --- a/lib/Sema/DerivedConformanceComparable.cpp +++ b/lib/Sema/DerivedConformanceComparable.cpp @@ -245,7 +245,7 @@ deriveComparable_lt( getParamDecl("b") }); - auto boolTy = C.getBoolDecl()->getDeclaredInterfaceType(); + auto boolTy = C.getBoolType(); Identifier generatedIdentifier; if (parentDC->getParentModule()->isResilient()) { diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp index df2f05e6e4916..b2d16ffbb60f0 100644 --- a/lib/Sema/DerivedConformanceEquatableHashable.cpp +++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp @@ -398,7 +398,7 @@ deriveEquatable_eq( getParamDecl("b") }); - auto boolTy = C.getBoolDecl()->getDeclaredInterfaceType(); + auto boolTy = C.getBoolType(); Identifier generatedIdentifier; if (parentDC->getParentModule()->isResilient()) { @@ -863,7 +863,7 @@ static ValueDecl *deriveHashable_hashValue(DerivedConformance &derived) { ASTContext &C = derived.Context; auto parentDC = derived.getConformanceContext(); - Type intType = C.getIntDecl()->getDeclaredInterfaceType(); + Type intType = C.getIntType(); // We can't form a Hashable conformance if Int isn't Hashable or // ExpressibleByIntegerLiteral. diff --git a/lib/Sema/DerivedConformanceError.cpp b/lib/Sema/DerivedConformanceError.cpp index 8d5388243c862..539d44164604a 100644 --- a/lib/Sema/DerivedConformanceError.cpp +++ b/lib/Sema/DerivedConformanceError.cpp @@ -91,7 +91,7 @@ deriveBridgedNSError_enum_nsErrorDomain( // } // } - auto stringTy = derived.Context.getStringDecl()->getDeclaredInterfaceType(); + auto stringTy = derived.Context.getStringType(); // Define the property. VarDecl *propDecl; diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp index 199e220c911b0..1d5db73224d7d 100644 --- a/lib/Sema/DerivedConformanceRawRepresentable.cpp +++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp @@ -292,8 +292,7 @@ deriveBodyRawRepresentable_init(AbstractFunctionDecl *initDecl, void *) { assert(rawTy); rawTy = initDecl->mapTypeIntoContext(rawTy); - bool isStringEnum = - (rawTy->getNominalOrBoundGenericNominal() == C.getStringDecl()); + bool isStringEnum = rawTy->isString(); llvm::SmallVector stringExprs; Type enumType = parentDC->getDeclaredTypeInContext(); diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp index a3b31ff458a58..bc6fcdeddc7d0 100644 --- a/lib/Sema/DerivedConformances.cpp +++ b/lib/Sema/DerivedConformances.cpp @@ -126,11 +126,7 @@ bool DerivedConformance::derivesProtocolConformance(DeclContext *DC, case KnownDerivableProtocolKind::CodingKey: { Type rawType = enumDecl->getRawType(); if (rawType) { - auto parentDC = enumDecl->getDeclContext(); - ASTContext &C = parentDC->getASTContext(); - - auto nominal = rawType->getAnyNominal(); - return nominal == C.getStringDecl() || nominal == C.getIntDecl(); + return rawType->isString() || rawType->isInt(); } // hasOnlyCasesWithoutAssociatedValues will return true for empty enums; @@ -590,7 +586,7 @@ GuardStmt *DerivedConformance::returnComparisonIfNotEqualGuard(ASTContext &C, /// Build a type-checked integer literal. static IntegerLiteralExpr *buildIntegerLiteral(ASTContext &C, unsigned index) { - Type intType = C.getIntDecl()->getDeclaredInterfaceType(); + Type intType = C.getIntType(); auto literal = IntegerLiteralExpr::createFromUnsigned(C, index); literal->setType(intType); @@ -615,7 +611,7 @@ DeclRefExpr *DerivedConformance::convertEnumToIndex(SmallVectorImpl &st const char *indexName) { ASTContext &C = enumDecl->getASTContext(); Type enumType = enumVarDecl->getType(); - Type intType = C.getIntDecl()->getDeclaredInterfaceType(); + Type intType = C.getIntType(); auto indexVar = new (C) VarDecl(/*IsStatic*/false, VarDecl::Introducer::Var, SourceLoc(), C.getIdentifier(indexName), diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index 30405c75a44e1..d9ba8be92da86 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -3107,13 +3107,11 @@ void VarDeclUsageChecker::markStoredOrInOutExpr(Expr *E, unsigned Flags) { // reads and writes its base; an application of a ReferenceWritableKeyPath // only reads its base; the other KeyPath types cannot be written at all. if (auto *KPA = dyn_cast(E)) { - auto &C = KPA->getType()->getASTContext(); KPA->getKeyPath()->walk(*this); bool isMutating = (Flags & RK_Written) && - KPA->getKeyPath()->getType()->getAnyNominal() - == C.getWritableKeyPathDecl(); + KPA->getKeyPath()->getType()->isWritableKeyPath(); markBaseOfStorageUse(KPA->getBase(), isMutating); return; } @@ -4364,9 +4362,8 @@ static void diagnoseDeprecatedWritableKeyPath(const Expr *E, return; if (auto *keyPathExpr = dyn_cast(E->getKeyPath())) { - auto *decl = keyPathExpr->getType()->getNominalOrBoundGenericNominal(); - if (decl != Ctx.getWritableKeyPathDecl() && - decl != Ctx.getReferenceWritableKeyPathDecl()) + if (!keyPathExpr->getType()->isWritableKeyPath() && + !keyPathExpr->getType()->isReferenceWritableKeyPath()) return; assert(keyPathExpr->getComponents().size() > 0); @@ -4822,9 +4819,6 @@ static OmissionTypeName getTypeNameForOmission(Type type) { return ""; ASTContext &ctx = type->getASTContext(); - Type boolType; - if (auto boolDecl = ctx.getBoolDecl()) - boolType = boolDecl->getDeclaredInterfaceType(); auto objcBoolType = ctx.getObjCBoolType(); /// Determine the options associated with the given type. @@ -4833,7 +4827,7 @@ static OmissionTypeName getTypeNameForOmission(Type type) { OmissionTypeOptions options; // Look for Boolean types. - if (boolType && type->isEqual(boolType)) { + if (type->isBool()) { // Swift.Bool options |= OmissionTypeFlags::Boolean; } else if (objcBoolType && type->isEqual(objcBoolType)) { @@ -4881,11 +4875,8 @@ static OmissionTypeName getTypeNameForOmission(Type type) { if (auto nominal = type->getAnyNominal()) { // If we have a collection, get the element type. if (auto bound = type->getAs()) { - ASTContext &ctx = nominal->getASTContext(); auto args = bound->getGenericArgs(); - if (!args.empty() && - (bound->getDecl() == ctx.getArrayDecl() || - bound->getDecl() == ctx.getSetDecl())) { + if (!args.empty() && (bound->isArray() || bound->isSet())) { return OmissionTypeName(nominal->getName().str(), getOptions(bound), getTypeNameForOmission(args[0]).Name); diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index de889526622a3..794819189e947 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -568,13 +568,13 @@ isAcceptableOutletType(Type type, bool &isArray, ASTContext &ctx) { return diag::iboutlet_nonobjc_class; } - if (nominal == ctx.getStringDecl()) { + if (type->isString()) { // String is okay because it is bridged to NSString. // FIXME: BridgesTypes.def is almost sufficient for this. return None; } - if (nominal == ctx.getArrayDecl()) { + if (type->isArray()) { // Arrays of arrays are not allowed. if (isArray) return diag::iboutlet_nonobject_type; @@ -1365,13 +1365,10 @@ bool swift::isValidKeyPathDynamicMemberLookup(SubscriptDecl *decl, ignoreLabel)) return false; - const auto *param = decl->getIndices()->get(0); - if (auto NTD = param->getInterfaceType()->getAnyNominal()) { - return NTD == ctx.getKeyPathDecl() || - NTD == ctx.getWritableKeyPathDecl() || - NTD == ctx.getReferenceWritableKeyPathDecl(); - } - return false; + auto paramTy = decl->getIndices()->get(0)->getInterfaceType(); + return paramTy->isKeyPath() || + paramTy->isWritableKeyPath() || + paramTy->isReferenceWritableKeyPath(); } /// The @dynamicMemberLookup attribute is only allowed on types that have at diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index 4a2ca52d228fb..bad30eff8b6e5 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -2462,19 +2462,18 @@ bool isSubscriptReturningString(const ValueDecl *D, ASTContext &Context) { // The subscripts taking T do not return Substring, and our // special fixit does not help here. - auto intDecl = Context.getIntDecl(); auto nominalTypeParam = genericArgs[0]->getAs(); if (!nominalTypeParam) return false; - if (nominalTypeParam->getDecl() == intDecl) + if (nominalTypeParam->isInt()) return false; auto resultTy = fnTy->getResult()->getAs(); if (!resultTy) return false; - return resultTy->getDecl() == stringDecl; + return resultTy->isString(); } bool swift::diagnoseExplicitUnavailability( diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 215e36c61f242..b540b5494772a 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -1800,8 +1800,7 @@ CheckedCastKind TypeChecker::typeCheckCheckedCast(Type fromType, } } - if (ConstraintSystem::isAnyHashableType(toType) || - ConstraintSystem::isAnyHashableType(fromType)) { + if (toType->isAnyHashable() || fromType->isAnyHashable()) { return CheckedCastKind::ValueCast; } diff --git a/lib/Sema/TypeCheckDeclObjC.cpp b/lib/Sema/TypeCheckDeclObjC.cpp index a7b8a6ad526a3..42ad5f6af6ddb 100644 --- a/lib/Sema/TypeCheckDeclObjC.cpp +++ b/lib/Sema/TypeCheckDeclObjC.cpp @@ -535,7 +535,7 @@ static bool isValidObjectiveCErrorResultType(DeclContext *dc, Type type) { // Special case: If the type is Unmanaged, then return true, because // Unmanaged can be represented in Objective-C (if T can be). if (auto BGT = type->getAs()) { - if (BGT->getDecl() == dc->getASTContext().getUnmanagedDecl()) { + if (BGT->isUnmanaged()) { return true; } } diff --git a/lib/Sema/TypeCheckExprObjC.cpp b/lib/Sema/TypeCheckExprObjC.cpp index 324e044ce1a75..11f9e507f49ce 100644 --- a/lib/Sema/TypeCheckExprObjC.cpp +++ b/lib/Sema/TypeCheckExprObjC.cpp @@ -95,10 +95,8 @@ Optional TypeChecker::checkObjCKeyPathExpr(DeclContext *dc, // We're updating to a property. Determine whether we're looking // into a bridged Swift collection of some sort. if (auto boundGeneric = newType->getAs()) { - auto nominal = boundGeneric->getDecl(); - // Array - if (nominal == Context.getArrayDecl()) { + if (boundGeneric->isArray()) { // Further lookups into the element type. state = ResolvingArray; currentType = boundGeneric->getGenericArgs()[0]; @@ -106,7 +104,7 @@ Optional TypeChecker::checkObjCKeyPathExpr(DeclContext *dc, } // Set - if (nominal == Context.getSetDecl()) { + if (boundGeneric->isSet()) { // Further lookups into the element type. state = ResolvingSet; currentType = boundGeneric->getGenericArgs()[0]; @@ -114,7 +112,7 @@ Optional TypeChecker::checkObjCKeyPathExpr(DeclContext *dc, } // Dictionary - if (nominal == Context.getDictionaryDecl()) { + if (boundGeneric->isDictionary()) { // Key paths look into the keys of a dictionary; further // lookups into the value type. state = ResolvingDictionary; diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp index 4e1e98e7ccf48..873fc08caf012 100644 --- a/lib/Sema/TypeCheckPattern.cpp +++ b/lib/Sema/TypeCheckPattern.cpp @@ -1155,8 +1155,8 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, "unknown structurally uninhabited type"); } } else if (auto *BST = diagTy->getAs()) { - if (BST->getDecl() == Context.getArrayDecl()) - shouldRequireType = BST->getGenericArgs()[0]->isEqual(Context.TheEmptyTupleType); + if (BST->isArray()) + shouldRequireType = BST->getGenericArgs()[0]->isVoid(); } if (shouldRequireType && @@ -1265,7 +1265,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, case PatternKind::Expr: { assert(cast(P)->isResolved() && "coercing unresolved expr pattern!"); - if (type->getAnyNominal() == Context.getBoolDecl()) { + if (type->isBool()) { // The type is Bool. // Check if the pattern is a Bool literal auto EP = cast(P); @@ -1328,7 +1328,7 @@ Pattern *TypeChecker::coercePatternToType(ContextualPattern pattern, auto extraOpts = llvm::drop_begin(inputTypeOptionals, castTypeOptionals.size()); for (auto extraOptTy : llvm::reverse(extraOpts)) { - auto some = Context.getOptionalDecl()->getUniqueElement(/*hasVal*/true); + auto some = Context.getOptionalSomeDecl(); auto *base = TypeExpr::createImplicit(extraOptTy, Context); sub = new (Context) EnumElementPattern( base, IP->getStartLoc(), DeclNameLoc(IP->getEndLoc()), diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 15c10e58637b7..62b17fe985a0a 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -604,10 +604,9 @@ static bool isPointerToVoid(ASTContext &Ctx, Type Ty, bool &IsMutable) { auto *BGT = Ty->getAs(); if (!BGT) return false; - if (BGT->getDecl() != Ctx.getUnsafePointerDecl() && - BGT->getDecl() != Ctx.getUnsafeMutablePointerDecl()) + if (!BGT->isUnsafePointer() && !BGT->isUnsafeMutablePointer()) return false; - IsMutable = BGT->getDecl() == Ctx.getUnsafeMutablePointerDecl(); + IsMutable = BGT->isUnsafeMutablePointer(); assert(BGT->getGenericArgs().size() == 1); return BGT->getGenericArgs().front()->isVoid(); }