Skip to content

Commit 9831b0c

Browse files
committed
Sema: Stop recording missing witnesses in the ConformanceChecker
1 parent 60801bf commit 9831b0c

File tree

4 files changed

+28
-63
lines changed

4 files changed

+28
-63
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
499499
return ResolveWitnessResult::ExplicitFailed;
500500
}
501501
// Save the missing type witness for later diagnosis.
502-
GlobalMissingWitnesses.insert({assocType, {}});
502+
getASTContext().addDelayedMissingWitness(Conformance, {assocType, {}});
503503

504504
// None of the candidates were viable.
505505
getASTContext().addDelayedConformanceDiag(Conformance, true,
@@ -3653,7 +3653,7 @@ auto AssociatedTypeInference::solve(ConformanceChecker &checker)
36533653

36543654
// Save the missing type witnesses for later diagnosis.
36553655
for (auto assocType : unresolvedAssocTypes) {
3656-
checker.GlobalMissingWitnesses.insert({assocType, {}});
3656+
ctx.addDelayedMissingWitness(conformance, {assocType, {}});
36573657
}
36583658

36593659
return llvm::None;
@@ -3996,12 +3996,8 @@ TypeWitnessRequest::evaluate(Evaluator &eval,
39963996
NormalProtocolConformance *conformance,
39973997
AssociatedTypeDecl *requirement) const {
39983998
auto &ctx = requirement->getASTContext();
3999-
llvm::SetVector<ASTContext::MissingWitness> MissingWitnesses;
4000-
ConformanceChecker checker(ctx, conformance, MissingWitnesses);
3999+
ConformanceChecker checker(ctx, conformance);
40014000
checker.resolveSingleTypeWitness(requirement);
4002-
for (auto missing : MissingWitnesses) {
4003-
ctx.addDelayedMissingWitness(conformance, missing);
4004-
}
40054001

40064002
// FIXME: ConformanceChecker and the other associated WitnessCheckers have
40074003
// an extremely convoluted caching scheme that doesn't fit nicely into the

lib/Sema/CSDiagnostics.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3453,22 +3453,25 @@ bool ContextualFailure::tryProtocolConformanceFixIt(
34533453
{
34543454
llvm::SmallString<128> Text;
34553455
llvm::raw_svector_ostream SS(Text);
3456-
llvm::SetVector<ASTContext::MissingWitness> missingWitnesses;
3456+
llvm::SmallVector<NormalProtocolConformance *, 2> fakeConformances;
34573457
for (auto protocol : missingProtocols) {
3458-
auto conformance = NormalProtocolConformance(
3459-
nominal->getDeclaredType(), protocol, SourceLoc(), nominal,
3458+
auto conformance = getASTContext().getNormalConformance(
3459+
nominal->getSelfInterfaceType(), protocol, SourceLoc(), nominal,
34603460
ProtocolConformanceState::Incomplete, /*isUnchecked=*/false,
34613461
/*isPreconcurrency=*/false);
3462-
ConformanceChecker checker(getASTContext(), &conformance,
3463-
missingWitnesses);
3462+
ConformanceChecker checker(getASTContext(), conformance);
34643463
// Type witnesses must be resolved first.
34653464
checker.resolveTypeWitnesses();
34663465
checker.resolveValueWitnesses();
3466+
fakeConformances.push_back(conformance);
34673467
}
34683468

3469-
for (auto decl : missingWitnesses) {
3470-
swift::printRequirementStub(decl.requirement, nominal, nominal->getDeclaredType(),
3471-
nominal->getStartLoc(), SS);
3469+
for (auto conformance : fakeConformances) {
3470+
auto missingWitnesses = getASTContext().takeDelayedMissingWitnesses(conformance);
3471+
for (auto decl : missingWitnesses) {
3472+
swift::printRequirementStub(decl.requirement, nominal, nominal->getDeclaredType(),
3473+
nominal->getStartLoc(), SS);
3474+
}
34723475
}
34733476

34743477
if (!Text.empty()) {

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1884,7 +1884,6 @@ class MultiConformanceChecker {
18841884
llvm::SmallVector<ValueDecl*, 16> UnsatisfiedReqs;
18851885
llvm::SmallVector<ConformanceChecker, 4> AllUsedCheckers;
18861886
llvm::SmallVector<NormalProtocolConformance*, 4> AllConformances;
1887-
llvm::SetVector<ASTContext::MissingWitness> MissingWitnesses;
18881887
llvm::SmallPtrSet<ValueDecl *, 8> CoveredMembers;
18891888

18901889
/// Check one conformance.
@@ -1976,6 +1975,8 @@ static void diagnoseProtocolStubFixit(
19761975
ArrayRef<ASTContext::MissingWitness> missingWitnesses);
19771976

19781977
void MultiConformanceChecker::checkAllConformances() {
1978+
llvm::SetVector<ASTContext::MissingWitness> MissingWitnesses;
1979+
19791980
bool anyInvalid = false;
19801981
for (auto *conformance : AllConformances) {
19811982
checkIndividualConformance(conformance);
@@ -1995,16 +1996,12 @@ void MultiConformanceChecker::checkAllConformances() {
19951996
}
19961997
}
19971998

1998-
if (AllUsedCheckers.empty() ||
1999-
AllUsedCheckers.back().Conformance != conformance) {
2000-
continue;
2001-
}
2002-
2003-
auto &checker = AllUsedCheckers.back();
2004-
auto LocalMissing = checker.getLocalMissingWitness();
1999+
auto LocalMissing = Context.takeDelayedMissingWitnesses(conformance);
20052000
if (LocalMissing.empty())
20062001
continue;
20072002

2003+
MissingWitnesses.insert(LocalMissing.begin(), LocalMissing.end());
2004+
20082005
// Diagnose the missing witnesses.
20092006
for (auto &Missing : LocalMissing) {
20102007
auto requirement = Missing.requirement;
@@ -2031,10 +2028,9 @@ void MultiConformanceChecker::checkAllConformances() {
20312028

20322029
// Otherwise, backtrack to the last checker that has missing witnesses
20332030
// and diagnose missing witnesses from there.
2034-
for (auto &checker : llvm::reverse(AllUsedCheckers)) {
2035-
if (!checker.getLocalMissingWitness().empty()) {
2036-
diagnoseProtocolStubFixit(Context,
2037-
checker.Conformance,
2031+
for (auto *conformance : llvm::reverse(AllConformances)) {
2032+
if (Context.hasDelayedConformanceErrors(conformance)) {
2033+
diagnoseProtocolStubFixit(Context, conformance,
20382034
MissingWitnesses.getArrayRef());
20392035
break;
20402036
}
@@ -2408,15 +2404,8 @@ checkIndividualConformance(NormalProtocolConformance *conformance) {
24082404
if (conformance->isComplete())
24092405
return;
24102406

2411-
// Revive registered missing witnesses to handle it below.
2412-
auto revivedMissingWitnesses =
2413-
getASTContext().takeDelayedMissingWitnesses(conformance);
2414-
24152407
// The conformance checker we're using.
2416-
AllUsedCheckers.emplace_back(getASTContext(), conformance, MissingWitnesses);
2417-
MissingWitnesses.insert(revivedMissingWitnesses.begin(),
2418-
revivedMissingWitnesses.end());
2419-
2408+
AllUsedCheckers.emplace_back(getASTContext(), conformance);
24202409
AllUsedCheckers.back().checkConformance();
24212410
}
24222411

@@ -2959,13 +2948,10 @@ diagnoseMatch(ModuleDecl *module, NormalProtocolConformance *conformance,
29592948
}
29602949

29612950
ConformanceChecker::ConformanceChecker(
2962-
ASTContext &ctx, NormalProtocolConformance *conformance,
2963-
llvm::SetVector<ASTContext::MissingWitness> &GlobalMissingWitnesses)
2951+
ASTContext &ctx, NormalProtocolConformance *conformance)
29642952
: WitnessChecker(ctx, conformance->getProtocol(), conformance->getType(),
29652953
conformance->getDeclContext()),
2966-
Conformance(conformance), Loc(conformance->getLoc()),
2967-
GlobalMissingWitnesses(GlobalMissingWitnesses),
2968-
LocalMissingWitnessesStartIndex(GlobalMissingWitnesses.size()) {}
2954+
Conformance(conformance), Loc(conformance->getLoc()) {}
29692955

29702956
ConformanceChecker::~ConformanceChecker() {}
29712957

@@ -4340,7 +4326,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
43404326
if (!numViable) {
43414327
// Save the missing requirement for later diagnosis.
43424328
if (shouldRecordMissingWitness(Proto, Conformance, requirement))
4343-
GlobalMissingWitnesses.insert({requirement, matches});
4329+
getASTContext().addDelayedMissingWitness(Conformance, {requirement, matches});
43444330
return ResolveWitnessResult::Missing;
43454331
}
43464332

@@ -6458,12 +6444,8 @@ ValueWitnessRequest::evaluate(Evaluator &eval,
64586444
NormalProtocolConformance *conformance,
64596445
ValueDecl *requirement) const {
64606446
auto &ctx = requirement->getASTContext();
6461-
llvm::SetVector<ASTContext::MissingWitness> MissingWitnesses;
6462-
ConformanceChecker checker(ctx, conformance, MissingWitnesses);
6447+
ConformanceChecker checker(ctx, conformance);
64636448
checker.resolveSingleWitness(requirement);
6464-
for (auto missing : MissingWitnesses) {
6465-
ctx.addDelayedMissingWitness(conformance, missing);
6466-
}
64676449

64686450
// FIXME: ConformanceChecker and the other associated WitnessCheckers have
64696451
// an extremely convoluted caching scheme that doesn't fit nicely into the

lib/Sema/TypeCheckProtocol.h

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,6 @@ class ConformanceChecker : public WitnessChecker {
126126
NormalProtocolConformance *Conformance;
127127
SourceLoc Loc;
128128

129-
/// Keep track of missing witnesses, either type or value, for later
130-
/// diagnosis emits. This may contain witnesses that are external to the
131-
/// protocol under checking.
132-
llvm::SetVector<ASTContext::MissingWitness> &GlobalMissingWitnesses;
133-
134-
/// Keep track of the slice in GlobalMissingWitnesses that is local to
135-
/// this protocol under checking.
136-
unsigned LocalMissingWitnessesStartIndex;
137-
138129
/// Record a (non-type) witness for the given requirement.
139130
void recordWitness(ValueDecl *requirement, const RequirementMatch &match);
140131

@@ -184,14 +175,7 @@ class ConformanceChecker : public WitnessChecker {
184175
/// the chosen type witnesses.
185176
void ensureRequirementsAreSatisfied();
186177

187-
ArrayRef<ASTContext::MissingWitness> getLocalMissingWitness() {
188-
return GlobalMissingWitnesses.getArrayRef().
189-
slice(LocalMissingWitnessesStartIndex,
190-
GlobalMissingWitnesses.size() - LocalMissingWitnessesStartIndex);
191-
}
192-
193-
ConformanceChecker(ASTContext &ctx, NormalProtocolConformance *conformance,
194-
llvm::SetVector<ASTContext::MissingWitness> &GlobalMissingWitnesses);
178+
ConformanceChecker(ASTContext &ctx, NormalProtocolConformance *conformance);
195179

196180
~ConformanceChecker();
197181

0 commit comments

Comments
 (0)