diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index a952e37affb..97940bb8f94 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -823,10 +823,7 @@ public: DeclName name, SmallVectorImpl &results) const; - /// Look for the conformance of the given type to the given protocol. - /// - /// This routine determines whether the given \c type conforms to the given - /// \c protocol. + /// Global conformance lookup, does not check conditional requirements. /// /// \param type The type for which we are computing conformance. /// @@ -836,23 +833,33 @@ public: /// might include "missing" conformances, which are synthesized for some /// protocols as an error recovery mechanism. /// - /// \returns The result of the conformance search, which will be - /// None if the type does not conform to the protocol or contain a - /// ProtocolConformanceRef if it does conform. + /// \returns An invalid conformance if the search failed, otherwise an + /// abstract, concrete or pack conformance, depending on the lookup type. ProtocolConformanceRef lookupConformance(Type type, ProtocolDecl *protocol, bool allowMissing = false); + /// Global conformance lookup, checks conditional requirements. + /// + /// \param type The type for which we are computing conformance. Must not + /// contain type parameters. + /// + /// \param protocol The protocol to which we are computing conformance. + /// + /// \param allowMissing When \c true, the resulting conformance reference + /// might include "missing" conformances, which are synthesized for some + /// protocols as an error recovery mechanism. + /// + /// \returns An invalid conformance if the search failed, otherwise an + /// abstract, concrete or pack conformance, depending on the lookup type. + ProtocolConformanceRef checkConformance(Type type, ProtocolDecl *protocol, + // Note: different default than above + bool allowMissing = true); + /// Look for the conformance of the given existential type to the given /// protocol. ProtocolConformanceRef lookupExistentialConformance(Type type, ProtocolDecl *protocol); - /// Exposes TypeChecker functionality for querying protocol conformance. - /// Returns a valid ProtocolConformanceRef only if all conditional - /// requirements are successfully resolved. - ProtocolConformanceRef conformsToProtocol(Type sourceTy, - ProtocolDecl *targetProtocol); - /// Collect the conformances of \c fromType to each of the protocols of an /// existential type's layout. /// diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index d2218154998..2f7c8e596fe 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -2249,6 +2249,31 @@ LookupConformanceInModuleRequest::evaluate( return ProtocolConformanceRef(conformance); } +ProtocolConformanceRef +ModuleDecl::checkConformance(Type type, ProtocolDecl *proto, + bool allowMissing) { + auto lookupResult = lookupConformance(type, proto, allowMissing); + if (lookupResult.isInvalid()) { + return ProtocolConformanceRef::forInvalid(); + } + + auto condReqs = lookupResult.getConditionalRequirements(); + + // If we have a conditional requirements that we need to check, do so now. + if (!condReqs.empty()) { + switch (checkRequirements(condReqs)) { + case CheckRequirementsResult::Success: + break; + + case CheckRequirementsResult::RequirementFailure: + case CheckRequirementsResult::SubstitutionFailure: + return ProtocolConformanceRef::forInvalid(); + } + } + + return lookupResult; +} + Fingerprint SourceFile::getInterfaceHash() const { assert(hasInterfaceHash() && "Interface hash not enabled"); auto &eval = getASTContext().evaluator; diff --git a/lib/IDE/ConformingMethodList.cpp b/lib/IDE/ConformingMethodList.cpp index e5420539e6e..6518111602d 100644 --- a/lib/IDE/ConformingMethodList.cpp +++ b/lib/IDE/ConformingMethodList.cpp @@ -179,7 +179,7 @@ void ConformingMethodListCallbacks::getMatchingMethods( // The return type conforms to any of the requested protocols. for (auto Proto : ExpectedTypes) { - if (CurModule->conformsToProtocol(resultTy, Proto)) + if (CurModule->checkConformance(resultTy, Proto)) return true; } diff --git a/lib/IDE/IDETypeChecking.cpp b/lib/IDE/IDETypeChecking.cpp index 0ff2bc7f5fd..105a1f96bbe 100644 --- a/lib/IDE/IDETypeChecking.cpp +++ b/lib/IDE/IDETypeChecking.cpp @@ -689,7 +689,7 @@ class ExpressionTypeCollector: public SourceEntityWalker { // Collecting protocols conformed by this expressions that are in the list. for (auto Proto: InterestedProtocols) { - if (Module.conformsToProtocol(E->getType(), Proto.first)) { + if (Module.checkConformance(E->getType(), Proto.first)) { Conformances.push_back(Proto.second); } } diff --git a/lib/Refactoring/Async/AsyncHandlerDesc.cpp b/lib/Refactoring/Async/AsyncHandlerDesc.cpp index ecaee73a676..beac11d3702 100644 --- a/lib/Refactoring/Async/AsyncHandlerDesc.cpp +++ b/lib/Refactoring/Async/AsyncHandlerDesc.cpp @@ -19,7 +19,7 @@ using namespace swift::refactoring::asyncrefactorings; static bool isErrorType(Type Ty, ModuleDecl *MD) { if (!Ty) return false; - return !MD->conformsToProtocol(Ty, Ty->getASTContext().getErrorDecl()) + return !MD->checkConformance(Ty, Ty->getASTContext().getErrorDecl()) .isInvalid(); } diff --git a/lib/SIL/IR/SILType.cpp b/lib/SIL/IR/SILType.cpp index ed03001e84e..be029f84241 100644 --- a/lib/SIL/IR/SILType.cpp +++ b/lib/SIL/IR/SILType.cpp @@ -1252,7 +1252,7 @@ SILType SILType::removingMoveOnlyWrapperToBoxedType(const SILFunction *fn) { ProtocolConformanceRef SILType::conformsToProtocol(SILFunction *fn, ProtocolDecl *protocol) const { - return fn->getParentModule()->conformsToProtocol(getASTType(), protocol); + return fn->getParentModule()->checkConformance(getASTType(), protocol); } bool SILType::isSendable(SILFunction *fn) const { diff --git a/lib/SIL/IR/TypeLowering.cpp b/lib/SIL/IR/TypeLowering.cpp index c33fd3a85d9..0aecd703f55 100644 --- a/lib/SIL/IR/TypeLowering.cpp +++ b/lib/SIL/IR/TypeLowering.cpp @@ -3027,7 +3027,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering, if (!bitwiseCopyableProtocol) return; - auto conformance = M.conformsToProtocol(substType, bitwiseCopyableProtocol); + auto conformance = M.checkConformance(substType, bitwiseCopyableProtocol); if (lowering.isTrivial() && !conformance) { // A trivial type can only lack a conformance if one of its leaves is a @@ -3063,7 +3063,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering, // A BitwiseCopyable conformer appearing within its layout doesn't // explain why substType doesn't itself conform. - if (M.conformsToProtocol(ty, bitwiseCopyableProtocol)) + if (M.checkConformance(ty, bitwiseCopyableProtocol)) return true; // ModuleTypes are trivial but don't warrant being given a conformance @@ -3143,7 +3143,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering, // Unfortunately, the type parameter's conformance may not be visible // here. - assert(M.conformsToProtocol(ty, bitwiseCopyableProtocol) && + assert(M.checkConformance(ty, bitwiseCopyableProtocol) && "leaf of non-trivial BitwiseCopyable type that doesn't " "conform to BitwiseCopyable!?"); diff --git a/lib/SIL/Utils/DynamicCasts.cpp b/lib/SIL/Utils/DynamicCasts.cpp index 1f51c2c6b36..e5de5e1ee16 100644 --- a/lib/SIL/Utils/DynamicCasts.cpp +++ b/lib/SIL/Utils/DynamicCasts.cpp @@ -103,7 +103,7 @@ classifyDynamicCastToProtocol(ModuleDecl *M, CanType source, CanType target, if (!TargetProtocol) return DynamicCastFeasibility::MaySucceed; - // If the target is a parameterized protocol type, conformsToProtocol + // If the target is a parameterized protocol type, checkConformance // is insufficient to prove the feasibility of the cast as it does not // check the additional requirements. // FIXME: This is a weak predicate that doesn't take into account @@ -111,9 +111,9 @@ classifyDynamicCastToProtocol(ModuleDecl *M, CanType source, CanType target, if (isa(unwrapExistential(target))) return DynamicCastFeasibility::MaySucceed; - // If conformsToProtocol returns a valid conformance, then all requirements - // were proven by the type checker. - if (M->conformsToProtocol(source, TargetProtocol)) + // If checkConformance() returns a valid conformance, then all conditional + // requirements were satisfied. + if (M->checkConformance(source, TargetProtocol)) return DynamicCastFeasibility::WillSucceed; auto *SourceNominalTy = source.getAnyNominal(); @@ -141,14 +141,14 @@ classifyDynamicCastToProtocol(ModuleDecl *M, CanType source, CanType target, } // The WillFail conditions below assume any possible conformance on the - // nominal source type has been ruled out. The prior conformsToProtocol query + // nominal source type has been ruled out. The prior checkConformance query // identified any definite conformance. Now check if there is already a known // conditional conformance on the nominal type with requirements that were // not proven. // // TODO: The TypeChecker can easily prove that some requirements cannot be // met. Returning WillFail in those cases would be more optimal. To do that, - // the conformsToProtocol interface needs to be reformulated as a query, and + // the checkConformance interface needs to be reformulated as a query, and // the implementation, including checkGenericArguments, needs to be taught to // recognize that types with archetypes may potentially succeed. if (auto conformance = M->lookupConformance(source, TargetProtocol)) { diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index b44ef977513..8203fb7c567 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -5866,7 +5866,7 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn, assert(outerErrorType == SILType::getExceptionType(getASTContext())); ProtocolConformanceRef conformances[1] = { - getModule().getSwiftModule()->conformsToProtocol( + getModule().getSwiftModule()->checkConformance( innerError->getType().getASTType(), getASTContext().getErrorDecl()) }; diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index b5f34dbfdb0..b6aba4cab13 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -5949,7 +5949,7 @@ static void diagnoseImplicitRawConversion(Type sourceTy, Type pointerTy, auto *SM = SGF.getModule().getSwiftModule(); if (auto *fixedWidthIntegerDecl = SM->getASTContext().getProtocol( KnownProtocolKind::FixedWidthInteger)) { - if (SM->conformsToProtocol(eltTy, fixedWidthIntegerDecl)) + if (SM->checkConformance(eltTy, fixedWidthIntegerDecl)) return; } diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp index 1babb747197..0ec337e81a5 100644 --- a/lib/SILGen/SILGenStmt.cpp +++ b/lib/SILGen/SILGenStmt.cpp @@ -1606,7 +1606,7 @@ void SILGenFunction::emitThrow(SILLocation loc, ManagedValue exnMV, assert(destErrorType == SILType::getExceptionType(getASTContext())); ProtocolConformanceRef conformances[1] = { - getModule().getSwiftModule()->conformsToProtocol( + getModule().getSwiftModule()->checkConformance( exn->getType().getASTType(), getASTContext().getErrorDecl()) }; diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp index c026a6c97e3..2b531c1f1ac 100644 --- a/lib/SILOptimizer/Utils/CastOptimizer.cpp +++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp @@ -1461,14 +1461,14 @@ static bool optimizeStaticallyKnownProtocolConformance( // SourceType is a non-existential type with a non-conditional // conformance to a protocol represented by the TargetType. // - // TypeChecker::conformsToProtocol checks any conditional conformances. If + // ModuleDecl::checkConformance() checks any conditional conformances. If // they depend on information not known until runtime, the conformance // will not be returned. For instance, if `X: P` where `T == Int` in `func // foo(_: T) { ... X() as? P ... }`, the cast will succeed for // `foo(0)` but not for `foo("string")`. There are many cases where // everything is completely static (`X() as? P`), in which case a // valid conformance will be returned. - auto Conformance = SM->conformsToProtocol(SourceType, Proto); + auto Conformance = SM->checkConformance(SourceType, Proto); if (Conformance.isInvalid()) return false; diff --git a/lib/SILOptimizer/Utils/Existential.cpp b/lib/SILOptimizer/Utils/Existential.cpp index a42ab032cd1..02ea36edce8 100644 --- a/lib/SILOptimizer/Utils/Existential.cpp +++ b/lib/SILOptimizer/Utils/Existential.cpp @@ -389,7 +389,7 @@ ConcreteExistentialInfo::ConcreteExistentialInfo(SILValue existential, // We have the open_existential; we still need the conformance. auto ConformanceRef = - M->getSwiftModule()->conformsToProtocol(ConcreteTypeCandidate, Protocol); + M->getSwiftModule()->checkConformance(ConcreteTypeCandidate, Protocol); if (ConformanceRef.isInvalid()) return; diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index 5bb525e18e8..6e595d6321e 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -113,8 +113,8 @@ Solution::computeSubstitutions(GenericSignature sig, } // FIXME: Retrieve the conformance from the solution itself. - return TypeChecker::conformsToProtocol(replacement, protoType, - getConstraintSystem().DC->getParentModule()); + return getConstraintSystem().DC->getParentModule()->checkConformance( + replacement, protoType); }; return SubstitutionMap::get(sig, @@ -565,7 +565,7 @@ namespace { // the protocol requirement with Self == the concrete type, and SILGen // (or later) can devirtualize as appropriate. auto conformance = - TypeChecker::conformsToProtocol(baseTy, proto, dc->getParentModule()); + dc->getParentModule()->checkConformance(baseTy, proto); if (conformance.isConcrete()) { if (auto witness = conformance.getConcrete()->getWitnessDecl(decl)) { bool isMemberOperator = witness->getDeclContext()->isTypeContext(); @@ -2459,9 +2459,7 @@ namespace { // Try to find the conformance of the value type to _BridgedToObjectiveC. auto bridgedToObjectiveCConformance - = TypeChecker::conformsToProtocol(valueType, - bridgedProto, - dc->getParentModule()); + = dc->getParentModule()->checkConformance(valueType, bridgedProto); FuncDecl *fn = nullptr; @@ -2722,7 +2720,7 @@ namespace { ProtocolDecl *protocol = TypeChecker::getProtocol( ctx, expr->getLoc(), KnownProtocolKind::ExpressibleByStringLiteral); - if (!TypeChecker::conformsToProtocol(type, protocol, dc->getParentModule())) { + if (!dc->getParentModule()->checkConformance(type, protocol)) { // If the type does not conform to ExpressibleByStringLiteral, it should // be ExpressibleByExtendedGraphemeClusterLiteral. protocol = TypeChecker::getProtocol( @@ -2731,7 +2729,7 @@ namespace { isStringLiteral = false; isGraphemeClusterLiteral = true; } - if (!TypeChecker::conformsToProtocol(type, protocol, dc->getParentModule())) { + if (!dc->getParentModule()->checkConformance(type, protocol)) { // ... or it should be ExpressibleByUnicodeScalarLiteral. protocol = TypeChecker::getProtocol( cs.getASTContext(), expr->getLoc(), @@ -2846,7 +2844,7 @@ namespace { assert(proto && "Missing string interpolation protocol?"); auto conformance = - TypeChecker::conformsToProtocol(type, proto, dc->getParentModule()); + dc->getParentModule()->checkConformance(type, proto); assert(conformance && "string interpolation type conforms to protocol"); DeclName constrName(ctx, DeclBaseName::createConstructor(), argLabels); @@ -2987,8 +2985,7 @@ namespace { auto proto = TypeChecker::getLiteralProtocol(ctx, expr); assert(proto && "Missing object literal protocol?"); auto conformance = - TypeChecker::conformsToProtocol(conformingType, proto, - dc->getParentModule()); + dc->getParentModule()->checkConformance(conformingType, proto); assert(conformance && "object literal type conforms to protocol"); auto constrName = TypeChecker::getObjectLiteralConstructorName(ctx, expr); @@ -3686,8 +3683,7 @@ namespace { assert(arrayProto && "type-checked array literal w/o protocol?!"); auto conformance = - TypeChecker::conformsToProtocol(arrayTy, arrayProto, - dc->getParentModule()); + dc->getParentModule()->checkConformance(arrayTy, arrayProto); assert(conformance && "Type does not conform to protocol?"); DeclName name(ctx, DeclBaseName::createConstructor(), @@ -3733,8 +3729,7 @@ namespace { KnownProtocolKind::ExpressibleByDictionaryLiteral); auto conformance = - TypeChecker::conformsToProtocol(dictionaryTy, dictionaryProto, - dc->getParentModule()); + dc->getParentModule()->checkConformance(dictionaryTy, dictionaryProto); if (conformance.isInvalid()) return nullptr; @@ -5345,8 +5340,7 @@ namespace { // verified by the solver, we just need to get it again // with all of the generic parameters resolved. auto hashableConformance = - TypeChecker::conformsToProtocol(indexType, hashable, - dc->getParentModule()); + dc->getParentModule()->checkConformance(indexType, hashable); assert(hashableConformance); conformances.push_back(hashableConformance); @@ -6905,8 +6899,8 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType, // Find the conformance of the source type to Hashable. auto hashable = ctx.getProtocol(KnownProtocolKind::Hashable); auto conformance = - TypeChecker::conformsToProtocol( - cs.getType(expr), hashable, dc->getParentModule()); + dc->getParentModule()->checkConformance( + cs.getType(expr), hashable); assert(conformance && "must conform to Hashable"); return cs.cacheType( @@ -7692,8 +7686,8 @@ Expr *ExprRewriter::convertLiteralInPlace( // Check whether this literal type conforms to the builtin protocol. If so, // initialize via the builtin protocol. if (builtinProtocol) { - auto builtinConformance = TypeChecker::conformsToProtocol( - type, builtinProtocol, dc->getParentModule()); + auto builtinConformance = dc->getParentModule()->checkConformance( + type, builtinProtocol); if (builtinConformance) { // Find the witness that we'll use to initialize the type via a builtin // literal. @@ -7716,8 +7710,7 @@ Expr *ExprRewriter::convertLiteralInPlace( // This literal type must conform to the (non-builtin) protocol. assert(protocol && "requirements should have stopped recursion"); - auto conformance = TypeChecker::conformsToProtocol(type, protocol, - dc->getParentModule()); + auto conformance = dc->getParentModule()->checkConformance(type, protocol); assert(conformance && "must conform to literal protocol"); // Dig out the literal type and perform a builtin literal conversion to it. @@ -7841,8 +7834,7 @@ std::pair ExprRewriter::buildDynamicCallable( auto dictLitProto = ctx.getProtocol(KnownProtocolKind::ExpressibleByDictionaryLiteral); auto conformance = - TypeChecker::conformsToProtocol(argumentType, dictLitProto, - dc->getParentModule()); + dc->getParentModule()->checkConformance(argumentType, dictLitProto); auto keyType = conformance.getTypeWitnessByName(argumentType, ctx.Id_Key); auto valueType = conformance.getTypeWitnessByName(argumentType, ctx.Id_Value); @@ -9192,8 +9184,8 @@ static llvm::Optional applySolutionToForEachStmt( parsedSequence, LocatorPathElt::ContextualType(CTP_ForEachSequence)); type = Type(solution.OpenedExistentialTypes[contextualLoc]); } - auto sequenceConformance = TypeChecker::conformsToProtocol( - type, sequenceProto, dc->getParentModule()); + auto sequenceConformance = dc->getParentModule()->checkConformance( + type, sequenceProto); assert(!sequenceConformance.isInvalid() && "Couldn't find sequence conformance"); stmt->setSequenceConformance(sequenceConformance); diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index e6ed30b8beb..81ea3dc7a21 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -3162,8 +3162,8 @@ bool ContextualFailure::diagnoseThrowsTypeMismatch() const { if (auto errorCodeProtocol = Ctx.getProtocol(KnownProtocolKind::ErrorCodeProtocol)) { Type errorCodeType = getFromType(); - auto conformance = TypeChecker::conformsToProtocol( - errorCodeType, errorCodeProtocol, getParentModule()); + auto conformance = getParentModule()->checkConformance( + errorCodeType, errorCodeProtocol); if (conformance && toErrorExistential) { Type errorType = conformance @@ -3403,8 +3403,7 @@ bool ContextualFailure::tryProtocolConformanceFixIt( SmallVector missingProtoTypeStrings; SmallVector missingProtocols; for (auto protocol : layout.getProtocols()) { - if (!TypeChecker::conformsToProtocol(fromType, protocol, - getParentModule())) { + if (!getParentModule()->checkConformance(fromType, protocol)) { auto protoTy = protocol->getDeclaredInterfaceType(); missingProtoTypeStrings.push_back(protoTy->getString()); missingProtocols.push_back(protocol); @@ -9035,8 +9034,7 @@ bool CheckedCastToUnrelatedFailure::diagnoseAsError() { auto *protocol = TypeChecker::getLiteralProtocol(ctx, sub); // Special handle for literals conditional checked cast when they can // be statically coerced to the cast type. - if (protocol && TypeChecker::conformsToProtocol(toType, protocol, - dc->getParentModule())) { + if (protocol && dc->getParentModule()->checkConformance(toType, protocol)) { emitDiagnostic(diag::literal_conditional_downcast_to_coercion, fromType, toType); return true; diff --git a/lib/Sema/CodeSynthesisDistributedActor.cpp b/lib/Sema/CodeSynthesisDistributedActor.cpp index c466d30c3ac..8cc4696a593 100644 --- a/lib/Sema/CodeSynthesisDistributedActor.cpp +++ b/lib/Sema/CodeSynthesisDistributedActor.cpp @@ -928,7 +928,7 @@ VarDecl *GetDistributedActorSystemPropertyRequest::evaluate( auto DistributedActorProto = C.getDistributedActorDecl(); for (auto system : DistributedActorProto->lookupDirect(C.Id_actorSystem)) { if (auto var = dyn_cast(system)) { - auto conformance = module->conformsToProtocol( + auto conformance = module->checkConformance( proto->mapTypeIntoContext(var->getInterfaceType()), DAS); diff --git a/lib/Sema/DerivedConformanceAdditiveArithmetic.cpp b/lib/Sema/DerivedConformanceAdditiveArithmetic.cpp index f637f71281a..dac2dddf7ef 100644 --- a/lib/Sema/DerivedConformanceAdditiveArithmetic.cpp +++ b/lib/Sema/DerivedConformanceAdditiveArithmetic.cpp @@ -77,8 +77,7 @@ bool DerivedConformance::canDeriveAdditiveArithmetic(NominalTypeDecl *nominal, if (v->getInterfaceType()->hasError()) return false; auto varType = DC->mapTypeIntoContext(v->getValueInterfaceType()); - return (bool)TypeChecker::conformsToProtocol(varType, proto, - DC->getParentModule()); + return (bool) DC->getParentModule()->checkConformance(varType, proto); }); } diff --git a/lib/Sema/DerivedConformanceCodable.cpp b/lib/Sema/DerivedConformanceCodable.cpp index ce93920e71a..a3fffc21044 100644 --- a/lib/Sema/DerivedConformanceCodable.cpp +++ b/lib/Sema/DerivedConformanceCodable.cpp @@ -269,8 +269,7 @@ static EnumDecl *validateCodingKeysType(const DerivedConformance &derived, // Ensure that the type we found conforms to the CodingKey protocol. auto *codingKeyProto = C.getProtocol(KnownProtocolKind::CodingKey); - if (!TypeChecker::conformsToProtocol(codingKeysType, codingKeyProto, - derived.getParentModule())) { + if (!derived.getParentModule()->checkConformance(codingKeysType, codingKeyProto)) { // If CodingKeys is a typealias which doesn't point to a valid nominal type, // codingKeysTypeDecl will be nullptr here. In that case, we need to warn on // the location of the usage, since there isn't an underlying type to @@ -337,8 +336,7 @@ static bool validateCodingKeysEnum(const DerivedConformance &derived, // We have a property to map to. Ensure it's {En,De}codable. auto target = derived.getConformanceContext()->mapTypeIntoContext( it->second->getValueInterfaceType()); - if (TypeChecker::conformsToProtocol(target, derived.Protocol, - derived.getParentModule()) + if (derived.getParentModule()->checkConformance(target, derived.Protocol) .isInvalid()) { TypeLoc typeLoc = { it->second->getTypeReprOrParentPatternTypeRepr(), @@ -1944,8 +1942,7 @@ static bool canSynthesize(DerivedConformance &derived, ValueDecl *requirement, if (auto *superclassDecl = classDecl->getSuperclassDecl()) { DeclName memberName; auto superType = superclassDecl->getDeclaredInterfaceType(); - if (TypeChecker::conformsToProtocol(superType, proto, - derived.getParentModule())) { + if (derived.getParentModule()->checkConformance(superType, proto)) { // super.init(from:) must be accessible. memberName = cast(requirement)->getName(); } else { diff --git a/lib/Sema/DerivedConformanceDifferentiable.cpp b/lib/Sema/DerivedConformanceDifferentiable.cpp index 852c54e624a..9bc9243e40d 100644 --- a/lib/Sema/DerivedConformanceDifferentiable.cpp +++ b/lib/Sema/DerivedConformanceDifferentiable.cpp @@ -83,8 +83,8 @@ getStoredPropertiesForDifferentiation( if (vd->getInterfaceType()->hasError()) continue; auto varType = DC->mapTypeIntoContext(vd->getValueInterfaceType()); - auto conformance = TypeChecker::conformsToProtocol( - varType, diffableProto, DC->getParentModule()); + auto conformance = DC->getParentModule()->checkConformance( + varType, diffableProto); if (!conformance) continue; // Skip `let` stored properties with a mutating `move(by:)` if requested. @@ -117,8 +117,7 @@ static Type getTangentVectorInterfaceType(Type contextualType, auto *diffableProto = C.getProtocol(KnownProtocolKind::Differentiable); assert(diffableProto && "`Differentiable` protocol not found"); auto conf = - TypeChecker::conformsToProtocol(contextualType, diffableProto, - DC->getParentModule()); + DC->getParentModule()->checkConformance(contextualType, diffableProto); assert(conf && "Contextual type must conform to `Differentiable`"); if (!conf) return nullptr; @@ -140,8 +139,7 @@ static bool canDeriveTangentVectorAsSelf(NominalTypeDecl *nominal, auto *diffableProto = C.getProtocol(KnownProtocolKind::Differentiable); auto *addArithProto = C.getProtocol(KnownProtocolKind::AdditiveArithmetic); // `Self` must conform to `AdditiveArithmetic`. - if (!TypeChecker::conformsToProtocol(nominalTypeInContext, addArithProto, - DC->getParentModule())) + if (!DC->getParentModule()->checkConformance(nominalTypeInContext, addArithProto)) return false; for (auto *field : nominal->getStoredProperties()) { // `Self` must not have any `@noDerivative` stored properties. @@ -149,8 +147,7 @@ static bool canDeriveTangentVectorAsSelf(NominalTypeDecl *nominal, return false; // `Self` must have all stored properties satisfy `Self == TangentVector`. auto fieldType = DC->mapTypeIntoContext(field->getValueInterfaceType()); - auto conf = TypeChecker::conformsToProtocol(fieldType, diffableProto, - DC->getParentModule()); + auto conf = DC->getParentModule()->checkConformance(fieldType, diffableProto); if (!conf) return false; auto tangentType = conf.getTypeWitnessByName(fieldType, C.Id_TangentVector); @@ -213,8 +210,7 @@ bool DerivedConformance::canDeriveDifferentiable(NominalTypeDecl *nominal, if (v->getInterfaceType()->hasError()) return false; auto varType = DC->mapTypeIntoContext(v->getValueInterfaceType()); - return (bool)TypeChecker::conformsToProtocol(varType, diffableProto, - DC->getParentModule()); + return (bool) DC->getParentModule()->checkConformance(varType, diffableProto); }); } @@ -556,8 +552,7 @@ static void checkAndDiagnoseImplicitNoDerivative(ASTContext &Context, // Check whether to diagnose stored property. auto varType = DC->mapTypeIntoContext(vd->getValueInterfaceType()); auto diffableConformance = - TypeChecker::conformsToProtocol(varType, diffableProto, - DC->getParentModule()); + DC->getParentModule()->checkConformance(varType, diffableProto); // If stored property should not be diagnosed, continue. if (diffableConformance && canInvokeMoveByOnProperty(vd, diffableConformance)) diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp index 45ce73f2c7f..37469638035 100644 --- a/lib/Sema/DerivedConformances.cpp +++ b/lib/Sema/DerivedConformances.cpp @@ -184,8 +184,8 @@ DerivedConformance::storedPropertiesNotConformingToProtocol( if (!type) nonconformingProperties.push_back(propertyDecl); - if (!TypeChecker::conformsToProtocol(DC->mapTypeIntoContext(type), protocol, - DC->getParentModule())) { + if (!DC->getParentModule()->checkConformance(DC->mapTypeIntoContext(type), + protocol)) { nonconformingProperties.push_back(propertyDecl); } } @@ -839,9 +839,8 @@ DerivedConformance::associatedValuesNotConformingToProtocol( for (auto param : *PL) { auto type = param->getInterfaceType(); - if (TypeChecker::conformsToProtocol(DC->mapTypeIntoContext(type), - protocol, DC->getParentModule()) - .isInvalid()) { + if (DC->getParentModule()->checkConformance(DC->mapTypeIntoContext(type), + protocol).isInvalid()) { nonconformingAssociatedValues.push_back(param); } } diff --git a/lib/Sema/LookupVisibleDecls.cpp b/lib/Sema/LookupVisibleDecls.cpp index d6049e07b68..e5bceed69bc 100644 --- a/lib/Sema/LookupVisibleDecls.cpp +++ b/lib/Sema/LookupVisibleDecls.cpp @@ -453,7 +453,7 @@ static void lookupDeclsFromProtocolsBeingConformedTo( // couldn't be computed, so assume they conform in such cases. if (!BaseTy->hasUnboundGenericType()) { if (auto res = Conformance->getConditionalRequirementsIfAvailable()) { - if (!res->empty() && !Module->conformsToProtocol(BaseTy, Proto)) + if (!res->empty() && !Module->checkConformance(BaseTy, Proto)) continue; } } diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp index 5b327296313..f931a8b1569 100644 --- a/lib/Sema/MiscDiagnostics.cpp +++ b/lib/Sema/MiscDiagnostics.cpp @@ -2940,9 +2940,10 @@ public: .getRequirements(), [&exprType, this](auto requirement) { if (requirement.getKind() == RequirementKind::Conformance) { - auto conformance = TypeChecker::conformsToProtocol( - exprType->getRValueType(), requirement.getProtocolDecl(), - Implementation->getModuleContext(), + auto conformance = Implementation->getModuleContext() + ->checkConformance( + exprType->getRValueType(), + requirement.getProtocolDecl(), /*allowMissing=*/false); return !conformance.isInvalid(); } diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 8aea01fa336..8063ecfcdf5 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -1726,7 +1726,7 @@ bool swift::isValidDynamicCallableMethod(FuncDecl *decl, ModuleDecl *module, if (!hasKeywordArguments) { auto arrayLitProto = ctx.getProtocol(KnownProtocolKind::ExpressibleByArrayLiteral); - return (bool)TypeChecker::conformsToProtocol(argType, arrayLitProto, module); + return (bool) module->checkConformance(argType, arrayLitProto); } // If keyword arguments, check that argument type conforms to // `ExpressibleByDictionaryLiteral` and that the `Key` associated type @@ -1735,11 +1735,11 @@ bool swift::isValidDynamicCallableMethod(FuncDecl *decl, ModuleDecl *module, ctx.getProtocol(KnownProtocolKind::ExpressibleByStringLiteral); auto dictLitProto = ctx.getProtocol(KnownProtocolKind::ExpressibleByDictionaryLiteral); - auto dictConf = TypeChecker::conformsToProtocol(argType, dictLitProto, module); + auto dictConf = module->checkConformance(argType, dictLitProto); if (dictConf.isInvalid()) return false; auto keyType = dictConf.getTypeWitnessByName(argType, ctx.Id_Key); - return (bool)TypeChecker::conformsToProtocol(keyType, stringLitProtocol, module); + return (bool) module->checkConformance(keyType, stringLitProtocol); } /// Returns true if the given nominal type has a valid implementation of a @@ -2567,9 +2567,8 @@ void AttributeChecker::checkApplicationMainAttribute(DeclAttribute *attr, } if (!ApplicationDelegateProto || - !TypeChecker::conformsToProtocol(CD->getDeclaredInterfaceType(), - ApplicationDelegateProto, - CD->getParentModule())) { + !CD->getParentModule()->checkConformance(CD->getDeclaredInterfaceType(), + ApplicationDelegateProto)) { diagnose(attr->getLocation(), diag::attr_ApplicationMain_not_ApplicationDelegate, applicationMainKind); @@ -3689,7 +3688,7 @@ TypeEraserHasViableInitRequest::evaluate(Evaluator &evaluator, } // The type eraser must conform to the annotated protocol - if (!TypeChecker::conformsToProtocol(typeEraser, protocol, module)) { + if (!module->checkConformance(typeEraser, protocol)) { diags.diagnose(attr->getLoc(), diag::type_eraser_does_not_conform, typeEraser, protocolType); diags.diagnose(nominalTypeDecl->getLoc(), diag::type_eraser_declared_here); @@ -4910,7 +4909,7 @@ static bool conformsToDifferentiable(Type type, ModuleDecl *module, auto &ctx = module->getASTContext(); auto *differentiableProto = ctx.getProtocol(KnownProtocolKind::Differentiable); - auto conf = TypeChecker::conformsToProtocol(type, differentiableProto, module); + auto conf = module->checkConformance(type, differentiableProto); if (conf.isInvalid()) return false; if (!tangentVectorEqualsSelf) diff --git a/lib/Sema/TypeCheckBitwise.cpp b/lib/Sema/TypeCheckBitwise.cpp index 2326af58ad4..93f46f597f4 100644 --- a/lib/Sema/TypeCheckBitwise.cpp +++ b/lib/Sema/TypeCheckBitwise.cpp @@ -131,7 +131,7 @@ bool BitwiseCopyableStorageVisitor::visitMemberDecl(ValueDecl *decl, Type ty) { } bool BitwiseCopyableStorageVisitor::visitMemberType(Type ty, SourceLoc loc) { - auto conformance = TypeChecker::conformsToProtocol(ty, protocol, module); + auto conformance = module->checkConformance(ty, protocol); if (conformance.isInvalid() || conformance.hasUnavailableConformance()) { return visitNonconformingMemberType(ty, loc); } diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index 4e745776be3..e8f153a1ca5 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -691,12 +691,12 @@ bool swift::isSendableType(ModuleDecl *module, Type type) { // First check if we have a function type. If we do, check if it is // Sendable. We do this since functions cannot conform to protocols. - if (auto *fas = type->getCanonicalType()->getAs()) + if (auto *fas = type->getAs()) return fas->isSendable(); - if (auto *fas = type->getCanonicalType()->getAs()) + if (auto *fas = type->getAs()) return fas->isSendable(); - auto conformance = TypeChecker::conformsToProtocol(type, proto, module); + auto conformance = module->checkConformance(type, proto); if (conformance.isInvalid()) return false; @@ -1074,7 +1074,7 @@ bool swift::diagnoseNonSendableTypes( return false; // FIXME: More detail for unavailable conformances. - auto conformance = TypeChecker::conformsToProtocol(type, proto, module); + auto conformance = module->checkConformance(type, proto); if (conformance.isInvalid() || conformance.hasUnavailableConformance()) { return diagnoseSingleNonSendableType( type, fromContext, inDerivedConformance, loc, diagnose); @@ -1271,8 +1271,7 @@ namespace { return true; auto module = nominal->getParentModule(); - auto conformance = TypeChecker::conformsToProtocol( - type, sendableProto, module); + auto conformance = module->checkConformance(type, sendableProto); if (conformance.isInvalid()) return true; @@ -4642,7 +4641,7 @@ ActorIsolation ActorIsolationRequest::evaluate( auto &ctx = value->getASTContext(); auto conformsTo = [&](KnownProtocolKind kind) { if (auto *proto = ctx.getProtocol(kind)) - return value->getModuleContext()->conformsToProtocol(paramType, proto); + return value->getModuleContext()->checkConformance(paramType, proto); return ProtocolConformanceRef::forInvalid(); }; @@ -5595,9 +5594,9 @@ ProtocolConformance *swift::deriveImplicitSendableConformance( if (classDecl) { if (Type superclass = classDecl->getSuperclass()) { auto classModule = classDecl->getParentModule(); - auto inheritedConformance = TypeChecker::conformsToProtocol( + auto inheritedConformance = classModule->checkConformance( classDecl->mapTypeIntoContext(superclass), - proto, classModule, /*allowMissing=*/false); + proto, /*allowMissing=*/false); if (inheritedConformance.hasUnavailableConformance()) inheritedConformance = ProtocolConformanceRef::forInvalid(); diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 8f56b098d97..5708c8a1973 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -2218,7 +2218,7 @@ TypeChecker::typeCheckCheckedCast(Type fromType, Type toType, auto nsErrorTy = Context.getNSErrorType(); if (auto errorTypeProto = Context.getProtocol(KnownProtocolKind::Error)) { - if (conformsToProtocol(toType, errorTypeProto, module)) { + if (module->checkConformance(toType, errorTypeProto)) { if (nsErrorTy) { if (isSubtypeOf(fromType, nsErrorTy, dc) // Don't mask "always true" warnings if NSError is cast to @@ -2228,7 +2228,7 @@ TypeChecker::typeCheckCheckedCast(Type fromType, Type toType, } } - if (conformsToProtocol(fromType, errorTypeProto, module)) { + if (module->checkConformance(fromType, errorTypeProto)) { // Cast of an error-conforming type to NSError or NSObject. if ((nsObject && toType->isEqual(nsObject)) || (nsErrorTy && toType->isEqual(nsErrorTy))) diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 3cd036a32cd..8c8b4c38c18 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -2721,8 +2721,8 @@ InterfaceTypeRequest::evaluate(Evaluator &eval, ValueDecl *D) const { ProtocolDecl *errorProto = Context.getErrorDecl(); if (thrownTy && errorProto) { Type thrownTyInContext = AFD->mapTypeIntoContext(thrownTy); - if (!TypeChecker::conformsToProtocol( - thrownTyInContext, errorProto, AFD->getParentModule())) { + if (!AFD->getParentModule()->checkConformance( + thrownTyInContext, errorProto)) { SourceLoc loc; if (auto thrownTypeRepr = AFD->getThrownTypeRepr()) loc = thrownTypeRepr->getLoc(); diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index 43dda76c2a5..a291fb572d1 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -1396,8 +1396,8 @@ static void diagnoseClassWithoutInitializers(ClassDecl *classDecl) { if (auto *superclassDecl = classDecl->getSuperclassDecl()) { auto *decodableProto = C.getProtocol(KnownProtocolKind::Decodable); auto superclassType = superclassDecl->getDeclaredInterfaceType(); - auto ref = TypeChecker::conformsToProtocol( - superclassType, decodableProto, classDecl->getParentModule()); + auto ref = classDecl->getParentModule()->checkConformance( + superclassType, decodableProto); if (ref) { // super conforms to Decodable, so we've failed to inherit init(from:). // Let's suggest overriding it here. @@ -1425,8 +1425,8 @@ static void diagnoseClassWithoutInitializers(ClassDecl *classDecl) { // likely that the user forgot to override its encode(to:). In this case, // we can produce a slightly different diagnostic to suggest doing so. auto *encodableProto = C.getProtocol(KnownProtocolKind::Encodable); - auto ref = TypeChecker::conformsToProtocol( - superclassType, encodableProto, classDecl->getParentModule()); + auto ref = classDecl->getParentModule()->checkConformance( + superclassType, encodableProto); if (ref) { // We only want to produce this version of the diagnostic if the // subclass doesn't directly implement encode(to:). @@ -1653,8 +1653,8 @@ static void diagnoseRetroactiveConformances( proto->walkInheritedProtocols([&](ProtocolDecl *decl) { // Get the original conformance of the extended type to this protocol. - auto conformanceRef = TypeChecker::conformsToProtocol( - extendedType, decl, ext->getParentModule()); + auto conformanceRef = ext->getParentModule()->checkConformance( + extendedType, decl); if (!conformanceRef.isConcrete()) { return TypeWalker::Action::Continue; diff --git a/lib/Sema/TypeCheckDistributed.cpp b/lib/Sema/TypeCheckDistributed.cpp index 027c17f214b..309ae3f20e9 100644 --- a/lib/Sema/TypeCheckDistributed.cpp +++ b/lib/Sema/TypeCheckDistributed.cpp @@ -427,7 +427,7 @@ static bool checkDistributedTargetResultType( for (auto serializationReq: serializationRequirements) { auto conformance = - TypeChecker::conformsToProtocol(resultType, serializationReq, module); + module->checkConformance(resultType, serializationReq); if (conformance.isInvalid()) { if (diagnose) { llvm::StringRef conformanceToSuggest = isCodableRequirement ? @@ -538,7 +538,7 @@ bool CheckDistributedFunctionRequest::evaluate( auto srl = serializationReqType->getExistentialLayout(); for (auto req: srl.getProtocols()) { - if (TypeChecker::conformsToProtocol(paramTy, req, module).isInvalid()) { + if (module->checkConformance(paramTy, req).isInvalid()) { auto diag = func->diagnose( diag::distributed_actor_func_param_not_codable, param->getArgumentName().str(), param->getInterfaceType(), diff --git a/lib/Sema/TypeCheckInvertible.cpp b/lib/Sema/TypeCheckInvertible.cpp index f220d8801a0..1f6ea10d821 100644 --- a/lib/Sema/TypeCheckInvertible.cpp +++ b/lib/Sema/TypeCheckInvertible.cpp @@ -183,9 +183,8 @@ static bool conformsToInvertible(CanType type, InvertibleProtocolKind ip) { SILTokenType>())); const bool conforms = - (bool)TypeChecker::conformsToProtocol(type, - invertible, - invertible->getParentModule(), + (bool) invertible->getParentModule()->checkConformance( + type, invertible, /*allowMissing=*/false); return conforms; diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 3327109940c..f7b77c57c58 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -4324,8 +4324,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) { // a member that could in turn satisfy *this* requirement. auto derivableProto = cast(derivable->getDeclContext()); auto conformance = - TypeChecker::conformsToProtocol(Adoptee, derivableProto, - DC->getParentModule()); + DC->getParentModule()->checkConformance(Adoptee, derivableProto); if (conformance.isConcrete()) { (void)conformance.getConcrete()->getWitnessDecl(derivable); } @@ -5762,8 +5761,7 @@ TypeChecker::containsProtocol(Type T, ProtocolDecl *Proto, ModuleDecl *M, auto result = (skipConditionalRequirements ? M->lookupConformance(superclass, Proto, /*allowMissing=*/false) - : TypeChecker::conformsToProtocol(superclass, Proto, M, - /*allowMissing=*/false)); + : M->checkConformance(superclass, Proto, /*allowMissing=*/false)); if (result) { return result; } @@ -5788,33 +5786,7 @@ TypeChecker::containsProtocol(Type T, ProtocolDecl *Proto, ModuleDecl *M, // For non-existential types, this is equivalent to checking conformance. return (skipConditionalRequirements ? M->lookupConformance(T, Proto, allowMissing) - : TypeChecker::conformsToProtocol(T, Proto, M, allowMissing)); -} - -ProtocolConformanceRef -TypeChecker::conformsToProtocol(Type T, ProtocolDecl *Proto, ModuleDecl *M, - bool allowMissing) { - // Look up conformance in the module. - auto lookupResult = M->lookupConformance(T, Proto, allowMissing); - if (lookupResult.isInvalid()) { - return ProtocolConformanceRef::forInvalid(); - } - - auto condReqs = lookupResult.getConditionalRequirements(); - - // If we have a conditional requirements that we need to check, do so now. - if (!condReqs.empty()) { - switch (checkRequirements(condReqs)) { - case CheckRequirementsResult::Success: - break; - - case CheckRequirementsResult::RequirementFailure: - case CheckRequirementsResult::SubstitutionFailure: - return ProtocolConformanceRef::forInvalid(); - } - } - - return lookupResult; + : M->checkConformance(T, Proto, allowMissing)); } bool TypeChecker::conformsToKnownProtocol( @@ -5822,8 +5794,7 @@ bool TypeChecker::conformsToKnownProtocol( bool allowMissing) { if (auto *proto = TypeChecker::getProtocol(module->getASTContext(), SourceLoc(), protocol)) - return (bool)TypeChecker::conformsToProtocol( - type, proto, module, allowMissing); + return (bool) module->checkConformance(type, proto, allowMissing); return false; } @@ -5864,15 +5835,7 @@ TypeChecker::couldDynamicallyConformToProtocol(Type type, ProtocolDecl *Proto, if (type->isKnownStdlibCollectionType()) return !M->lookupConformance(type, Proto, /*allowMissing=*/true) .isInvalid(); - return !conformsToProtocol(type, Proto, M).isInvalid(); -} - -/// Exposes TypeChecker functionality for querying protocol conformance. -/// Returns a valid ProtocolConformanceRef only if all conditional -/// requirements are successfully resolved. -ProtocolConformanceRef -ModuleDecl::conformsToProtocol(Type sourceTy, ProtocolDecl *targetProtocol) { - return TypeChecker::conformsToProtocol(sourceTy, targetProtocol, this); + return !M->checkConformance(type, Proto).isInvalid(); } void TypeChecker::checkConformance(NormalProtocolConformance *conformance) { @@ -7324,8 +7287,8 @@ void TypeChecker::inferDefaultWitnesses(ProtocolDecl *proto) { Type defaultAssocTypeInContext = proto->mapTypeIntoContext(defaultAssocType); auto requirementProto = req.getProtocolDecl(); - auto conformance = conformsToProtocol(defaultAssocTypeInContext, - requirementProto, module); + auto conformance = module->checkConformance(defaultAssocTypeInContext, + requirementProto); if (conformance.isInvalid()) { // Diagnose the lack of a conformance. This is potentially an ABI // incompatibility. diff --git a/lib/Sema/TypeCheckProtocolInference.cpp b/lib/Sema/TypeCheckProtocolInference.cpp index 6c644345175..5ae57921e39 100644 --- a/lib/Sema/TypeCheckProtocolInference.cpp +++ b/lib/Sema/TypeCheckProtocolInference.cpp @@ -344,8 +344,7 @@ static bool isExtensionUsableForInference(const ExtensionDecl *extension, auto *module = conformanceDC->getParentModule(); auto checkConformance = [&](ProtocolDecl *proto) { auto typeInContext = conformanceDC->mapTypeIntoContext(conformance->getType()); - auto otherConf = TypeChecker::conformsToProtocol( - typeInContext, proto, module); + auto otherConf = module->checkConformance(typeInContext, proto); return !otherConf.isInvalid(); }; diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp index 255a2685d02..58b86d3034e 100644 --- a/lib/Sema/TypeCheckStorage.cpp +++ b/lib/Sema/TypeCheckStorage.cpp @@ -1313,8 +1313,7 @@ static ProtocolConformanceRef checkConformanceToNSCopying(VarDecl *var, auto proto = ctx.getNSCopyingDecl(); if (proto) { - if (auto result = TypeChecker::conformsToProtocol(type, proto, - dc->getParentModule())) + if (auto result = dc->getParentModule()->checkConformance(type, proto)) return result; } diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index fb51214aace..4424b922c7b 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -3726,9 +3726,8 @@ NeverNullType TypeResolver::resolveASTFunctionType( thrownTy = Type(); } else if (!options.contains(TypeResolutionFlags::SilenceErrors) && !thrownTy->hasTypeParameter() && - !TypeChecker::conformsToProtocol( - thrownTy, ctx.getErrorDecl(), - resolution.getDeclContext()->getParentModule())) { + !resolution.getDeclContext()->getParentModule()->checkConformance( + thrownTy, ctx.getErrorDecl())) { diagnoseInvalid( thrownTypeRepr, thrownTypeRepr->getLoc(), diag::thrown_type_not_error, thrownTy); @@ -3996,9 +3995,8 @@ NeverNullType TypeResolver::resolveSILFunctionType( selfType = next; } - witnessMethodConformance = TypeChecker::conformsToProtocol( - selfType, protocolType->getDecl(), - getDeclContext()->getParentModule()); + witnessMethodConformance = getDeclContext()->getParentModule() + ->checkConformance(selfType, protocolType->getDecl()); assert(witnessMethodConformance && "found witness_method without matching conformance"); } diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index d8876a8b77e..1fb0e470911 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -799,17 +799,6 @@ ProtocolConformanceRef containsProtocol(Type T, ProtocolDecl *Proto, bool skipConditionalRequirements=false, bool allowMissing=false); -/// Determine whether the given type conforms to the given protocol. -/// -/// Unlike subTypeOfProtocol(), this will return false for existentials of -/// non-self conforming protocols. -/// -/// \returns The protocol conformance, if \c T conforms to the -/// protocol \c Proto, or \c None. -ProtocolConformanceRef conformsToProtocol(Type T, ProtocolDecl *Proto, - ModuleDecl *M, - bool allowMissing = true); - /// Check whether the type conforms to a given known protocol. bool conformsToKnownProtocol(Type type, KnownProtocolKind protocol, ModuleDecl *module, bool allowMissing = true);