Skip to content

Commit e3e4399

Browse files
committed
[NFC] Strip witness checking of its type checker
Push dependencies down to their use sites and downgrade the TypeCheckers in witness matching to ASTContexts.
1 parent 3753a96 commit e3e4399

File tree

3 files changed

+52
-60
lines changed

3 files changed

+52
-60
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -896,9 +896,9 @@ static bool isBetterMatch(DeclContext *dc, ValueDecl *requirement,
896896
return false;
897897
}
898898

899-
WitnessChecker::WitnessChecker(TypeChecker &tc, ProtocolDecl *proto,
899+
WitnessChecker::WitnessChecker(ASTContext &ctx, ProtocolDecl *proto,
900900
Type adoptee, DeclContext *dc)
901-
: TC(tc), Proto(proto), Adoptee(adoptee), DC(dc) {}
901+
: Context(ctx), Proto(proto), Adoptee(adoptee), DC(dc) {}
902902

903903
void
904904
WitnessChecker::lookupValueWitnessesViaImplementsAttr(
@@ -981,6 +981,8 @@ bool WitnessChecker::findBestWitness(
981981
bool anyFromUnconstrainedExtension;
982982
numViable = 0;
983983

984+
// FIXME: Remove dependnecy on the lazy resolver.
985+
auto *TC = static_cast<TypeChecker *>(getASTContext().getLazyResolver());
984986
for (Attempt attempt = Regular; numViable == 0 && attempt != Done;
985987
attempt = static_cast<Attempt>(attempt + 1)) {
986988
SmallVector<ValueDecl *, 4> witnesses;
@@ -1028,8 +1030,8 @@ bool WitnessChecker::findBestWitness(
10281030
continue;
10291031
}
10301032

1031-
auto match = matchWitness(TC, ReqEnvironmentCache, Proto, conformance, DC,
1032-
requirement, witness);
1033+
auto match = matchWitness(*TC, ReqEnvironmentCache, Proto, conformance,
1034+
DC, requirement, witness);
10331035
if (match.isViable()) {
10341036
++numViable;
10351037
bestIdx = matches.size();
@@ -1053,7 +1055,7 @@ bool WitnessChecker::findBestWitness(
10531055
if (conformance && !conformance->isInvalid()) {
10541056
if (auto *SF = DC->getParentSourceFile()) {
10551057
if (SF->Kind == SourceFileKind::Interface) {
1056-
auto match = matchWitness(TC, ReqEnvironmentCache, Proto,
1058+
auto match = matchWitness(*TC, ReqEnvironmentCache, Proto,
10571059
conformance, DC, requirement, requirement);
10581060
assert(match.isViable());
10591061
numViable = 1;
@@ -1509,8 +1511,9 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
15091511
// conformance is invalid for other reasons, so emit diagnosis now.
15101512
if (revivedMissingWitnesses.empty()) {
15111513
// Emit any delayed diagnostics.
1512-
ConformanceChecker(TC, conformance, MissingWitnesses, false).
1513-
emitDelayedDiags();
1514+
ConformanceChecker(getASTContext(), conformance, MissingWitnesses,
1515+
false)
1516+
.emitDelayedDiags();
15141517
}
15151518
}
15161519

@@ -1712,7 +1715,7 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
17121715
return conformance;
17131716

17141717
// The conformance checker we're using.
1715-
AllUsedCheckers.emplace_back(TC, conformance, MissingWitnesses);
1718+
AllUsedCheckers.emplace_back(getASTContext(), conformance, MissingWitnesses);
17161719
MissingWitnesses.insert(revivedMissingWitnesses.begin(),
17171720
revivedMissingWitnesses.end());
17181721

@@ -2201,16 +2204,15 @@ diagnoseMatch(ModuleDecl *module, NormalProtocolConformance *conformance,
22012204
}
22022205

22032206
ConformanceChecker::ConformanceChecker(
2204-
TypeChecker &tc, NormalProtocolConformance *conformance,
2205-
llvm::SetVector<ValueDecl*> &GlobalMissingWitnesses,
2206-
bool suppressDiagnostics)
2207-
: WitnessChecker(tc, conformance->getProtocol(),
2208-
conformance->getType(),
2207+
ASTContext &ctx, NormalProtocolConformance *conformance,
2208+
llvm::SetVector<ValueDecl *> &GlobalMissingWitnesses,
2209+
bool suppressDiagnostics)
2210+
: WitnessChecker(ctx, conformance->getProtocol(), conformance->getType(),
22092211
conformance->getDeclContext()),
22102212
Conformance(conformance), Loc(conformance->getLoc()),
22112213
GlobalMissingWitnesses(GlobalMissingWitnesses),
22122214
LocalMissingWitnessesStartIndex(GlobalMissingWitnesses.size()),
2213-
SuppressDiagnostics(suppressDiagnostics) { }
2215+
SuppressDiagnostics(suppressDiagnostics) {}
22142216

22152217
ArrayRef<AssociatedTypeDecl *>
22162218
ConformanceChecker::getReferencedAssociatedTypes(ValueDecl *req) {
@@ -2562,8 +2564,9 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
25622564

25632565
auto overriddenRootConformance =
25642566
overriddenConformance.getConcrete()->getRootNormalConformance();
2565-
ConformanceChecker(TC, overriddenRootConformance, GlobalMissingWitnesses)
2566-
.recordTypeWitness(overridden, type, typeDecl);
2567+
ConformanceChecker(getASTContext(), overriddenRootConformance,
2568+
GlobalMissingWitnesses)
2569+
.recordTypeWitness(overridden, type, typeDecl);
25672570
}
25682571
}
25692572

@@ -3368,7 +3371,8 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDerivation(
33683371
return ResolveWitnessResult::ExplicitFailed;
33693372

33703373
// Try to match the derived requirement.
3371-
auto match = matchWitness(TC, ReqEnvironmentCache, Proto, Conformance, DC,
3374+
auto *TC = static_cast<TypeChecker *>(getASTContext().getLazyResolver());
3375+
auto match = matchWitness(*TC, ReqEnvironmentCache, Proto, Conformance, DC,
33723376
requirement, derived);
33733377
if (match.isViable()) {
33743378
recordWitness(requirement, match);
@@ -5231,9 +5235,8 @@ void TypeChecker::resolveTypeWitness(
52315235
AssociatedTypeDecl *assocType) {
52325236
llvm::SetVector<ValueDecl*> MissingWitnesses;
52335237
ConformanceChecker checker(
5234-
*this,
5235-
const_cast<NormalProtocolConformance*>(conformance),
5236-
MissingWitnesses);
5238+
Context, const_cast<NormalProtocolConformance *>(conformance),
5239+
MissingWitnesses);
52375240
checker.resolveSingleTypeWitness(assocType);
52385241
checker.diagnoseMissingWitnesses(MissingWitnessDiagnosisKind::ErrorFixIt);
52395242
}
@@ -5242,9 +5245,8 @@ void TypeChecker::resolveWitness(const NormalProtocolConformance *conformance,
52425245
ValueDecl *requirement) {
52435246
llvm::SetVector<ValueDecl*> MissingWitnesses;
52445247
ConformanceChecker checker(
5245-
*this,
5246-
const_cast<NormalProtocolConformance*>(conformance),
5247-
MissingWitnesses);
5248+
Context, const_cast<NormalProtocolConformance *>(conformance),
5249+
MissingWitnesses);
52485250
checker.resolveSingleWitness(requirement);
52495251
checker.diagnoseMissingWitnesses(MissingWitnessDiagnosisKind::ErrorFixIt);
52505252
}
@@ -5326,9 +5328,8 @@ namespace {
53265328
class DefaultWitnessChecker : public WitnessChecker {
53275329

53285330
public:
5329-
DefaultWitnessChecker(TypeChecker &tc,
5330-
ProtocolDecl *proto)
5331-
: WitnessChecker(tc, proto, proto->getDeclaredType(), proto) { }
5331+
DefaultWitnessChecker(ASTContext &ctx, ProtocolDecl *proto)
5332+
: WitnessChecker(ctx, proto, proto->getDeclaredType(), proto) {}
53325333

53335334
ResolveWitnessResult resolveWitnessViaLookup(ValueDecl *requirement);
53345335
void recordWitness(ValueDecl *requirement, const RequirementMatch &match);
@@ -5374,16 +5375,16 @@ void DefaultWitnessChecker::recordWitness(
53745375
}
53755376

53765377
void TypeChecker::inferDefaultWitnesses(ProtocolDecl *proto) {
5377-
DefaultWitnessChecker checker(*this, proto);
5378+
DefaultWitnessChecker checker(Context, proto);
53785379

53795380
// Find the default for the given associated type.
53805381
auto findAssociatedTypeDefault =
53815382
[&](AssociatedTypeDecl *assocType,
5382-
AssociatedTypeDecl **defaultedAssocTypeOut = nullptr) -> Type {
5383+
AssociatedTypeDecl **defaultedAssocTypeOut = nullptr) -> Type {
53835384
auto defaultedAssocType =
5384-
AssociatedTypeInference::findDefaultedAssociatedType(*this, assocType);
5385+
AssociatedTypeInference::findDefaultedAssociatedType(assocType);
53855386
if (!defaultedAssocType)
5386-
return nullptr;;
5387+
return nullptr;
53875388

53885389
Type defaultType = defaultedAssocType->getDefaultDefinitionType();
53895390
if (!defaultType)

lib/Sema/TypeCheckProtocol.h

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -474,13 +474,13 @@ class WitnessChecker {
474474
llvm::DenseMap<RequirementEnvironmentCacheKey, RequirementEnvironment>;
475475

476476
protected:
477-
TypeChecker &TC;
477+
ASTContext &Context;
478478
ProtocolDecl *Proto;
479479
Type Adoptee;
480480
// The conforming context, either a nominal type or extension.
481481
DeclContext *DC;
482482

483-
ASTContext &getASTContext() const { return TC.Context; }
483+
ASTContext &getASTContext() const { return Context; }
484484

485485
// An auxiliary lookup table to be used for witnesses remapped via
486486
// @_implements(Protocol, DeclName)
@@ -490,8 +490,8 @@ class WitnessChecker {
490490

491491
Optional<std::pair<AccessScope, bool>> RequiredAccessScopeAndUsableFromInline;
492492

493-
WitnessChecker(TypeChecker &tc, ProtocolDecl *proto,
494-
Type adoptee, DeclContext *dc);
493+
WitnessChecker(ASTContext &ctx, ProtocolDecl *proto, Type adoptee,
494+
DeclContext *dc);
495495

496496
bool isMemberOperator(FuncDecl *decl, Type type);
497497

@@ -676,8 +676,8 @@ class ConformanceChecker : public WitnessChecker {
676676
/// Emit any diagnostics that have been delayed.
677677
void emitDelayedDiags();
678678

679-
ConformanceChecker(TypeChecker &tc, NormalProtocolConformance *conformance,
680-
llvm::SetVector<ValueDecl*> &GlobalMissingWitnesses,
679+
ConformanceChecker(ASTContext &ctx, NormalProtocolConformance *conformance,
680+
llvm::SetVector<ValueDecl *> &GlobalMissingWitnesses,
681681
bool suppressDiagnostics = true);
682682

683683
/// Resolve all of the type witnesses.
@@ -712,7 +712,7 @@ class ConformanceChecker : public WitnessChecker {
712712
/// Captures the state needed to infer associated types.
713713
class AssociatedTypeInference {
714714
/// The type checker we'll need to validate declarations etc.
715-
TypeChecker &tc;
715+
ASTContext &ctx;
716716

717717
/// The conformance for which we are inferring associated types.
718718
NormalProtocolConformance *conformance;
@@ -752,12 +752,12 @@ class AssociatedTypeInference {
752752
unsigned numTypeWitnessesBeforeConflict = 0;
753753

754754
public:
755-
AssociatedTypeInference(TypeChecker &tc,
755+
AssociatedTypeInference(ASTContext &ctx,
756756
NormalProtocolConformance *conformance);
757757

758758
private:
759759
/// Retrieve the AST context.
760-
ASTContext &getASTContext() const { return tc.Context; }
760+
ASTContext &getASTContext() const { return ctx; }
761761

762762
/// Infer associated type witnesses for the given tentative
763763
/// requirement/witness match.
@@ -883,7 +883,6 @@ class AssociatedTypeInference {
883883

884884
/// Find an associated type declaration that provides a default definition.
885885
static AssociatedTypeDecl *findDefaultedAssociatedType(
886-
TypeChecker &tc,
887886
AssociatedTypeDecl *assocType);
888887
};
889888

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,9 @@ namespace {
133133
}
134134

135135
AssociatedTypeInference::AssociatedTypeInference(
136-
TypeChecker &tc,
137-
NormalProtocolConformance *conformance)
138-
: tc(tc), conformance(conformance), proto(conformance->getProtocol()),
139-
dc(conformance->getDeclContext()),
140-
adoptee(conformance->getType())
141-
{
142-
}
136+
ASTContext &ctx, NormalProtocolConformance *conformance)
137+
: ctx(ctx), conformance(conformance), proto(conformance->getProtocol()),
138+
dc(conformance->getDeclContext()), adoptee(conformance->getType()) {}
143139

144140
static bool associatedTypesAreSameEquivalenceClass(AssociatedTypeDecl *a,
145141
AssociatedTypeDecl *b) {
@@ -212,13 +208,14 @@ AssociatedTypeInference::inferTypeWitnessesViaValueWitnesses(
212208
// because those have to be explicitly declared on the type somewhere
213209
// so won't be affected by whatever answer inference comes up with.
214210
auto selfTy = extension->getSelfInterfaceType();
211+
auto *tc = static_cast<TypeChecker *>(getASTContext().getLazyResolver());
215212
for (const Requirement &reqt : extensionSig->getRequirements()) {
216213
switch (reqt.getKind()) {
217214
case RequirementKind::Conformance:
218215
case RequirementKind::Superclass:
219216
// FIXME: This is the wrong check
220-
if (selfTy->isEqual(reqt.getFirstType())
221-
&& !tc.isSubtypeOf(conformance->getType(),reqt.getSecondType(), dc))
217+
if (selfTy->isEqual(reqt.getFirstType()) &&
218+
!tc->isSubtypeOf(conformance->getType(), reqt.getSecondType(), dc))
222219
return false;
223220
break;
224221

@@ -489,8 +486,7 @@ static Type mapErrorTypeToOriginal(Type type) {
489486
}
490487

491488
/// Produce the type when matching a witness.
492-
static Type getWitnessTypeForMatching(TypeChecker &tc,
493-
NormalProtocolConformance *conformance,
489+
static Type getWitnessTypeForMatching(NormalProtocolConformance *conformance,
494490
ValueDecl *witness) {
495491
if (witness->isRecursiveValidation())
496492
return Type();
@@ -554,7 +550,6 @@ static Type getWitnessTypeForMatching(TypeChecker &tc,
554550
return resultType.transform(mapErrorTypeToOriginal);
555551
}
556552

557-
558553
/// Remove the 'self' type from the given type, if it's a method type.
559554
static Type removeSelfParam(ValueDecl *value, Type type) {
560555
if (auto func = dyn_cast<AbstractFunctionDecl>(value)) {
@@ -570,8 +565,6 @@ AssociatedTypeInference::inferTypeWitnessesViaAssociatedType(
570565
ConformanceChecker &checker,
571566
const llvm::SetVector<AssociatedTypeDecl *> &allUnresolved,
572567
AssociatedTypeDecl *assocType) {
573-
auto &tc = checker.TC;
574-
575568
// Form the default name _Default_Foo.
576569
Identifier defaultName;
577570
{
@@ -603,7 +596,7 @@ AssociatedTypeInference::inferTypeWitnessesViaAssociatedType(
603596
continue;
604597

605598
// Determine the witness type.
606-
Type witnessType = getWitnessTypeForMatching(tc, conformance, typeDecl);
599+
Type witnessType = getWitnessTypeForMatching(conformance, typeDecl);
607600
if (!witnessType) continue;
608601

609602
if (auto witnessMetaType = witnessType->getAs<AnyMetatypeType>())
@@ -651,7 +644,7 @@ AssociatedTypeInference::inferTypeWitnessesViaValueWitness(ValueDecl *req,
651644
inferred.Witness = witness;
652645

653646
// Compute the requirement and witness types we'll use for matching.
654-
Type fullWitnessType = getWitnessTypeForMatching(tc, conformance, witness);
647+
Type fullWitnessType = getWitnessTypeForMatching(conformance, witness);
655648
if (!fullWitnessType) {
656649
return inferred;
657650
}
@@ -764,7 +757,6 @@ AssociatedTypeInference::inferTypeWitnessesViaValueWitness(ValueDecl *req,
764757
}
765758

766759
AssociatedTypeDecl *AssociatedTypeInference::findDefaultedAssociatedType(
767-
TypeChecker &tc,
768760
AssociatedTypeDecl *assocType) {
769761
// If this associated type has a default, we're done.
770762
if (assocType->hasDefaultDefinitionType())
@@ -774,7 +766,7 @@ AssociatedTypeDecl *AssociatedTypeInference::findDefaultedAssociatedType(
774766
SmallPtrSet<CanType, 4> canonicalTypes;
775767
SmallVector<AssociatedTypeDecl *, 2> results;
776768
for (auto overridden : assocType->getOverriddenDecls()) {
777-
auto overriddenDefault = findDefaultedAssociatedType(tc, overridden);
769+
auto overriddenDefault = findDefaultedAssociatedType(overridden);
778770
if (!overriddenDefault) continue;
779771

780772
Type overriddenType =
@@ -824,7 +816,7 @@ Type AssociatedTypeInference::computeFixedTypeWitness(
824816
Type AssociatedTypeInference::computeDefaultTypeWitness(
825817
AssociatedTypeDecl *assocType) {
826818
// Go find a default definition.
827-
auto defaultedAssocType = findDefaultedAssociatedType(tc, assocType);
819+
auto defaultedAssocType = findDefaultedAssociatedType(assocType);
828820
if (!defaultedAssocType) return Type();
829821

830822
// If we don't have a default definition, we're done.
@@ -1984,7 +1976,7 @@ auto AssociatedTypeInference::solve(ConformanceChecker &checker)
19841976

19851977
void ConformanceChecker::resolveTypeWitnesses() {
19861978
// Attempt to infer associated type witnesses.
1987-
AssociatedTypeInference inference(TC, Conformance);
1979+
AssociatedTypeInference inference(getASTContext(), Conformance);
19881980
if (auto inferred = inference.solve(*this)) {
19891981
for (const auto &inferredWitness : *inferred) {
19901982
recordTypeWitness(inferredWitness.first, inferredWitness.second,

0 commit comments

Comments
 (0)