Skip to content

Commit 14d1fcb

Browse files
committed
AST: TypeChecker::conformsToProtocol() => ModuleDecl::checkConformance()
1 parent 1e950b1 commit 14d1fcb

35 files changed

+151
-193
lines changed

include/swift/AST/Module.h

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -823,10 +823,7 @@ class ModuleDecl
823823
DeclName name,
824824
SmallVectorImpl<ValueDecl*> &results) const;
825825

826-
/// Look for the conformance of the given type to the given protocol.
827-
///
828-
/// This routine determines whether the given \c type conforms to the given
829-
/// \c protocol.
826+
/// Global conformance lookup, does not check conditional requirements.
830827
///
831828
/// \param type The type for which we are computing conformance.
832829
///
@@ -836,23 +833,33 @@ class ModuleDecl
836833
/// might include "missing" conformances, which are synthesized for some
837834
/// protocols as an error recovery mechanism.
838835
///
839-
/// \returns The result of the conformance search, which will be
840-
/// None if the type does not conform to the protocol or contain a
841-
/// ProtocolConformanceRef if it does conform.
836+
/// \returns An invalid conformance if the search failed, otherwise an
837+
/// abstract, concrete or pack conformance, depending on the lookup type.
842838
ProtocolConformanceRef lookupConformance(Type type, ProtocolDecl *protocol,
843839
bool allowMissing = false);
844840

841+
/// Global conformance lookup, checks conditional requirements.
842+
///
843+
/// \param type The type for which we are computing conformance. Must not
844+
/// contain type parameters.
845+
///
846+
/// \param protocol The protocol to which we are computing conformance.
847+
///
848+
/// \param allowMissing When \c true, the resulting conformance reference
849+
/// might include "missing" conformances, which are synthesized for some
850+
/// protocols as an error recovery mechanism.
851+
///
852+
/// \returns An invalid conformance if the search failed, otherwise an
853+
/// abstract, concrete or pack conformance, depending on the lookup type.
854+
ProtocolConformanceRef checkConformance(Type type, ProtocolDecl *protocol,
855+
// Note: different default than above
856+
bool allowMissing = true);
857+
845858
/// Look for the conformance of the given existential type to the given
846859
/// protocol.
847860
ProtocolConformanceRef lookupExistentialConformance(Type type,
848861
ProtocolDecl *protocol);
849862

850-
/// Exposes TypeChecker functionality for querying protocol conformance.
851-
/// Returns a valid ProtocolConformanceRef only if all conditional
852-
/// requirements are successfully resolved.
853-
ProtocolConformanceRef conformsToProtocol(Type sourceTy,
854-
ProtocolDecl *targetProtocol);
855-
856863
/// Collect the conformances of \c fromType to each of the protocols of an
857864
/// existential type's layout.
858865
///

lib/AST/Module.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2249,6 +2249,31 @@ LookupConformanceInModuleRequest::evaluate(
22492249
return ProtocolConformanceRef(conformance);
22502250
}
22512251

2252+
ProtocolConformanceRef
2253+
ModuleDecl::checkConformance(Type type, ProtocolDecl *proto,
2254+
bool allowMissing) {
2255+
auto lookupResult = lookupConformance(type, proto, allowMissing);
2256+
if (lookupResult.isInvalid()) {
2257+
return ProtocolConformanceRef::forInvalid();
2258+
}
2259+
2260+
auto condReqs = lookupResult.getConditionalRequirements();
2261+
2262+
// If we have a conditional requirements that we need to check, do so now.
2263+
if (!condReqs.empty()) {
2264+
switch (checkRequirements(condReqs)) {
2265+
case CheckRequirementsResult::Success:
2266+
break;
2267+
2268+
case CheckRequirementsResult::RequirementFailure:
2269+
case CheckRequirementsResult::SubstitutionFailure:
2270+
return ProtocolConformanceRef::forInvalid();
2271+
}
2272+
}
2273+
2274+
return lookupResult;
2275+
}
2276+
22522277
Fingerprint SourceFile::getInterfaceHash() const {
22532278
assert(hasInterfaceHash() && "Interface hash not enabled");
22542279
auto &eval = getASTContext().evaluator;

lib/IDE/ConformingMethodList.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ void ConformingMethodListCallbacks::getMatchingMethods(
179179

180180
// The return type conforms to any of the requested protocols.
181181
for (auto Proto : ExpectedTypes) {
182-
if (CurModule->conformsToProtocol(resultTy, Proto))
182+
if (CurModule->checkConformance(resultTy, Proto))
183183
return true;
184184
}
185185

lib/IDE/IDETypeChecking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ class ExpressionTypeCollector: public SourceEntityWalker {
689689

690690
// Collecting protocols conformed by this expressions that are in the list.
691691
for (auto Proto: InterestedProtocols) {
692-
if (Module.conformsToProtocol(E->getType(), Proto.first)) {
692+
if (Module.checkConformance(E->getType(), Proto.first)) {
693693
Conformances.push_back(Proto.second);
694694
}
695695
}

lib/Refactoring/Async/AsyncHandlerDesc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ using namespace swift::refactoring::asyncrefactorings;
1919
static bool isErrorType(Type Ty, ModuleDecl *MD) {
2020
if (!Ty)
2121
return false;
22-
return !MD->conformsToProtocol(Ty, Ty->getASTContext().getErrorDecl())
22+
return !MD->checkConformance(Ty, Ty->getASTContext().getErrorDecl())
2323
.isInvalid();
2424
}
2525

lib/SIL/IR/SILType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ SILType SILType::removingMoveOnlyWrapperToBoxedType(const SILFunction *fn) {
12521252

12531253
ProtocolConformanceRef
12541254
SILType::conformsToProtocol(SILFunction *fn, ProtocolDecl *protocol) const {
1255-
return fn->getParentModule()->conformsToProtocol(getASTType(), protocol);
1255+
return fn->getParentModule()->checkConformance(getASTType(), protocol);
12561256
}
12571257

12581258
bool SILType::isSendable(SILFunction *fn) const {

lib/SIL/IR/TypeLowering.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3027,7 +3027,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
30273027
if (!bitwiseCopyableProtocol)
30283028
return;
30293029

3030-
auto conformance = M.conformsToProtocol(substType, bitwiseCopyableProtocol);
3030+
auto conformance = M.checkConformance(substType, bitwiseCopyableProtocol);
30313031

30323032
if (lowering.isTrivial() && !conformance) {
30333033
// 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,
30633063

30643064
// A BitwiseCopyable conformer appearing within its layout doesn't
30653065
// explain why substType doesn't itself conform.
3066-
if (M.conformsToProtocol(ty, bitwiseCopyableProtocol))
3066+
if (M.checkConformance(ty, bitwiseCopyableProtocol))
30673067
return true;
30683068

30693069
// ModuleTypes are trivial but don't warrant being given a conformance
@@ -3143,7 +3143,7 @@ void TypeConverter::verifyTrivialLowering(const TypeLowering &lowering,
31433143

31443144
// Unfortunately, the type parameter's conformance may not be visible
31453145
// here.
3146-
assert(M.conformsToProtocol(ty, bitwiseCopyableProtocol) &&
3146+
assert(M.checkConformance(ty, bitwiseCopyableProtocol) &&
31473147
"leaf of non-trivial BitwiseCopyable type that doesn't "
31483148
"conform to BitwiseCopyable!?");
31493149

lib/SIL/Utils/DynamicCasts.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,17 @@ classifyDynamicCastToProtocol(ModuleDecl *M, CanType source, CanType target,
103103
if (!TargetProtocol)
104104
return DynamicCastFeasibility::MaySucceed;
105105

106-
// If the target is a parameterized protocol type, conformsToProtocol
106+
// If the target is a parameterized protocol type, checkConformance
107107
// is insufficient to prove the feasibility of the cast as it does not
108108
// check the additional requirements.
109109
// FIXME: This is a weak predicate that doesn't take into account
110110
// class compositions - since any C & P<T> doesn't work yet anyways.
111111
if (isa<ParameterizedProtocolType>(unwrapExistential(target)))
112112
return DynamicCastFeasibility::MaySucceed;
113113

114-
// If conformsToProtocol returns a valid conformance, then all requirements
115-
// were proven by the type checker.
116-
if (M->conformsToProtocol(source, TargetProtocol))
114+
// If checkConformance() returns a valid conformance, then all conditional
115+
// requirements were satisfied.
116+
if (M->checkConformance(source, TargetProtocol))
117117
return DynamicCastFeasibility::WillSucceed;
118118

119119
auto *SourceNominalTy = source.getAnyNominal();
@@ -141,14 +141,14 @@ classifyDynamicCastToProtocol(ModuleDecl *M, CanType source, CanType target,
141141
}
142142

143143
// The WillFail conditions below assume any possible conformance on the
144-
// nominal source type has been ruled out. The prior conformsToProtocol query
144+
// nominal source type has been ruled out. The prior checkConformance query
145145
// identified any definite conformance. Now check if there is already a known
146146
// conditional conformance on the nominal type with requirements that were
147147
// not proven.
148148
//
149149
// TODO: The TypeChecker can easily prove that some requirements cannot be
150150
// met. Returning WillFail in those cases would be more optimal. To do that,
151-
// the conformsToProtocol interface needs to be reformulated as a query, and
151+
// the checkConformance interface needs to be reformulated as a query, and
152152
// the implementation, including checkGenericArguments, needs to be taught to
153153
// recognize that types with archetypes may potentially succeed.
154154
if (auto conformance = M->lookupConformance(source, TargetProtocol)) {

lib/SILGen/SILGenApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5866,7 +5866,7 @@ SILValue SILGenFunction::emitApplyWithRethrow(SILLocation loc, SILValue fn,
58665866
assert(outerErrorType == SILType::getExceptionType(getASTContext()));
58675867

58685868
ProtocolConformanceRef conformances[1] = {
5869-
getModule().getSwiftModule()->conformsToProtocol(
5869+
getModule().getSwiftModule()->checkConformance(
58705870
innerError->getType().getASTType(),
58715871
getASTContext().getErrorDecl())
58725872
};

lib/SILGen/SILGenExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5949,7 +5949,7 @@ static void diagnoseImplicitRawConversion(Type sourceTy, Type pointerTy,
59495949
auto *SM = SGF.getModule().getSwiftModule();
59505950
if (auto *fixedWidthIntegerDecl = SM->getASTContext().getProtocol(
59515951
KnownProtocolKind::FixedWidthInteger)) {
5952-
if (SM->conformsToProtocol(eltTy, fixedWidthIntegerDecl))
5952+
if (SM->checkConformance(eltTy, fixedWidthIntegerDecl))
59535953
return;
59545954
}
59555955

0 commit comments

Comments
 (0)