Skip to content

Commit a8e1c35

Browse files
committed
Sema: Introduce ResolveTypeWitnessesRequest
1 parent 7caf193 commit a8e1c35

File tree

6 files changed

+63
-43
lines changed

6 files changed

+63
-43
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,6 +2870,24 @@ class ReferencedAssociatedTypesRequest
28702870
bool isCached() const { return true; }
28712871
};
28722872

2873+
class ResolveTypeWitnessesRequest
2874+
: public SimpleRequest<ResolveTypeWitnessesRequest,
2875+
evaluator::SideEffect(NormalProtocolConformance *),
2876+
RequestFlags::Cached> {
2877+
public:
2878+
using SimpleRequest::SimpleRequest;
2879+
2880+
private:
2881+
friend SimpleRequest;
2882+
2883+
// Evaluation.
2884+
evaluator::SideEffect
2885+
evaluate(Evaluator &evaluator, NormalProtocolConformance *conformance) const;
2886+
2887+
public:
2888+
bool isCached() const { return true; }
2889+
};
2890+
28732891
class ValueWitnessRequest
28742892
: public SimpleRequest<ValueWitnessRequest,
28752893
Witness(NormalProtocolConformance *, ValueDecl *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,9 @@ SWIFT_REQUEST(TypeChecker, AssociatedConformanceRequest,
432432
SWIFT_REQUEST(TypeChecker, ReferencedAssociatedTypesRequest,
433433
TinyPtrVector<AssociatedTypeDecl *>(ValueDecl *),
434434
Cached, NoLocationInfo)
435+
SWIFT_REQUEST(TypeChecker, ResolveTypeWitnessesRequest,
436+
evaluator::SideEffect(NormalProtocolConformance *),
437+
Cached, NoLocationInfo)
435438
SWIFT_REQUEST(TypeChecker, ValueWitnessRequest,
436439
Witness(NormalProtocolConformance *, ValueDecl *),
437440
SeparatelyCached, NoLocationInfo)

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3947,64 +3947,62 @@ TypeWitnessSystem::compareResolvedTypes(Type ty1, Type ty2) {
39473947
return ResolvedTypeComparisonResult::EquivalentOrWorse;
39483948
}
39493949

3950-
void ConformanceChecker::resolveTypeWitnesses() {
3951-
PrettyStackTraceConformance trace("performing associated type inference on",
3952-
Conformance);
3953-
3950+
evaluator::SideEffect
3951+
ResolveTypeWitnessesRequest::evaluate(Evaluator &evaluator,
3952+
NormalProtocolConformance *conformance) const {
39543953
// Attempt to infer associated type witnesses.
3955-
AssociatedTypeInference inference(getASTContext(), Conformance);
3954+
auto &ctx = conformance->getDeclContext()->getASTContext();
3955+
3956+
AssociatedTypeInference inference(ctx, conformance);
39563957
if (auto inferred = inference.solve()) {
39573958
for (const auto &inferredWitness : *inferred) {
3958-
recordTypeWitness(Conformance,
3959+
recordTypeWitness(conformance,
39593960
inferredWitness.first,
39603961
inferredWitness.second,
39613962
/*typeDecl=*/nullptr);
39623963
}
39633964

3964-
return;
3965+
return evaluator::SideEffect();
39653966
}
39663967

39673968
// Conformance failed. Record errors for each of the witnesses.
3968-
Conformance->setInvalid();
3969+
conformance->setInvalid();
39693970

39703971
// We're going to produce an error below. Mark each unresolved
39713972
// associated type witness as erroneous.
3972-
for (auto assocType : Proto->getAssociatedTypeMembers()) {
3973+
for (auto assocType : conformance->getProtocol()->getAssociatedTypeMembers()) {
39733974
// If we already have a type witness, do nothing.
3974-
if (Conformance->hasTypeWitness(assocType))
3975+
if (conformance->hasTypeWitness(assocType))
39753976
continue;
39763977

3977-
recordTypeWitness(Conformance, assocType,
3978-
ErrorType::get(getASTContext()), nullptr);
3978+
recordTypeWitness(conformance, assocType, ErrorType::get(ctx), nullptr);
39793979
}
3980+
3981+
return evaluator::SideEffect();
39803982
}
39813983

3982-
void ConformanceChecker::resolveSingleTypeWitness(
3983-
AssociatedTypeDecl *assocType) {
3984-
switch (resolveTypeWitnessViaLookup(Conformance, assocType)) {
3984+
TypeWitnessAndDecl
3985+
TypeWitnessRequest::evaluate(Evaluator &eval,
3986+
NormalProtocolConformance *conformance,
3987+
AssociatedTypeDecl *requirement) const {
3988+
switch (resolveTypeWitnessViaLookup(conformance, requirement)) {
39853989
case ResolveWitnessResult::Success:
39863990
case ResolveWitnessResult::ExplicitFailed:
39873991
// We resolved this type witness one way or another.
3988-
return;
3992+
break;
39893993

3990-
case ResolveWitnessResult::Missing:
3994+
case ResolveWitnessResult::Missing: {
39913995
// The type witness is still missing. Resolve all of the type witnesses.
3992-
resolveTypeWitnesses();
3993-
return;
3996+
auto &ctx = requirement->getASTContext();
3997+
evaluateOrDefault(ctx.evaluator,
3998+
ResolveTypeWitnessesRequest{conformance},
3999+
evaluator::SideEffect());
4000+
break;
4001+
}
39944002
}
3995-
}
3996-
3997-
TypeWitnessAndDecl
3998-
TypeWitnessRequest::evaluate(Evaluator &eval,
3999-
NormalProtocolConformance *conformance,
4000-
AssociatedTypeDecl *requirement) const {
4001-
auto &ctx = requirement->getASTContext();
4002-
ConformanceChecker checker(ctx, conformance);
4003-
checker.resolveSingleTypeWitness(requirement);
40044003

4005-
// FIXME: ConformanceChecker and the other associated WitnessCheckers have
4006-
// an extremely convoluted caching scheme that doesn't fit nicely into the
4007-
// evaluator's model. All of this should be refactored away.
4004+
// FIXME: resolveTypeWitnessViaLookup() and ResolveTypeWitnessesRequest
4005+
// pre-populate the type witnesses in this manner. This should be cleaned up.
40084006
const auto known = conformance->TypeWitnesses.find(requirement);
40094007
assert(known != conformance->TypeWitnesses.end() &&
40104008
"Didn't resolve witness?");

lib/Sema/CSDiagnostics.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3459,9 +3459,11 @@ bool ContextualFailure::tryProtocolConformanceFixIt(
34593459
nominal->getSelfInterfaceType(), protocol, SourceLoc(), nominal,
34603460
ProtocolConformanceState::Incomplete, /*isUnchecked=*/false,
34613461
/*isPreconcurrency=*/false);
3462-
ConformanceChecker checker(getASTContext(), conformance);
34633462
// Type witnesses must be resolved first.
3464-
checker.resolveTypeWitnesses();
3463+
evaluateOrDefault(getASTContext().evaluator,
3464+
ResolveTypeWitnessesRequest{conformance},
3465+
evaluator::SideEffect());
3466+
ConformanceChecker checker(getASTContext(), conformance);
34653467
checker.resolveValueWitnesses();
34663468
fakeConformances.push_back(conformance);
34673469
}

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4014,7 +4014,9 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
40144014
auto *nominal = DC->getSelfNominalTypeDecl();
40154015

40164016
// Resolve all associated types before trying to resolve this witness.
4017-
resolveTypeWitnesses();
4017+
evaluateOrDefault(getASTContext().evaluator,
4018+
ResolveTypeWitnessesRequest{Conformance},
4019+
evaluator::SideEffect());
40184020

40194021
// If any of the type witnesses was erroneous, don't bother to check
40204022
// this value witness: it will fail.
@@ -4531,7 +4533,9 @@ void ConformanceChecker::resolveSingleWitness(ValueDecl *requirement) {
45314533
return;
45324534

45334535
// Resolve all associated types before trying to resolve this witness.
4534-
resolveTypeWitnesses();
4536+
evaluateOrDefault(getASTContext().evaluator,
4537+
ResolveTypeWitnessesRequest{Conformance},
4538+
evaluator::SideEffect());
45354539

45364540
// If any of the type witnesses was erroneous, don't bother to check
45374541
// this value witness: it will fail.
@@ -5048,7 +5052,9 @@ void ConformanceChecker::checkConformance() {
50485052
"check-conformance", Conformance);
50495053

50505054
// Resolve all of the type witnesses.
5051-
resolveTypeWitnesses();
5055+
evaluateOrDefault(getASTContext().evaluator,
5056+
ResolveTypeWitnessesRequest{Conformance},
5057+
evaluator::SideEffect());
50525058

50535059
// Check the requirements from the requirement signature.
50545060
ensureRequirementsAreSatisfied();

lib/Sema/TypeCheckProtocol.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,6 @@ class ConformanceChecker : public WitnessChecker {
175175

176176
~ConformanceChecker();
177177

178-
/// Resolve all of the type witnesses.
179-
void resolveTypeWitnesses();
180-
181178
/// Resolve all of the non-type witnesses.
182179
void resolveValueWitnesses();
183180

@@ -191,10 +188,6 @@ class ConformanceChecker : public WitnessChecker {
191188
/// conformance has been completed checked.
192189
void resolveSingleWitness(ValueDecl *requirement);
193190

194-
/// Resolve the type witness for the given associated type as
195-
/// directly as possible.
196-
void resolveSingleTypeWitness(AssociatedTypeDecl *assocType);
197-
198191
/// Check the entire protocol conformance.
199192
void checkConformance();
200193
};

0 commit comments

Comments
 (0)