Skip to content

Commit 516662b

Browse files
committed
Sema: Clean up dodgy missing witness fixit logic
1 parent 9c077ec commit 516662b

File tree

3 files changed

+28
-39
lines changed

3 files changed

+28
-39
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3999,7 +3999,7 @@ TypeWitnessRequest::evaluate(Evaluator &eval,
39993999
ConformanceChecker checker(requirement->getASTContext(), conformance,
40004000
MissingWitnesses);
40014001
checker.resolveSingleTypeWitness(requirement);
4002-
checker.diagnoseMissingWitnesses(MissingWitnessDiagnosisKind::ErrorFixIt,
4002+
checker.diagnoseMissingWitnesses(MissingWitnessDiagnosisKind::ErrorOnly,
40034003
/*Delayed=*/true);
40044004
// FIXME: ConformanceChecker and the other associated WitnessCheckers have
40054005
// an extremely convoluted caching scheme that doesn't fit nicely into the

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,7 +1889,7 @@ class MultiConformanceChecker {
18891889

18901890
/// Check one conformance.
18911891
void checkIndividualConformance(
1892-
NormalProtocolConformance *conformance, bool issueFixit);
1892+
NormalProtocolConformance *conformance);
18931893

18941894
/// Determine whether the given requirement was left unsatisfied.
18951895
bool isUnsatisfiedReq(
@@ -1971,7 +1971,7 @@ void MultiConformanceChecker::checkAllConformances() {
19711971
for (unsigned I = 0, N = AllConformances.size(); I < N; ++I) {
19721972
auto *conformance = AllConformances[I];
19731973
// Check this conformance and emit fixits if this is the last one in the pool.
1974-
checkIndividualConformance(conformance, I == N - 1);
1974+
checkIndividualConformance(conformance);
19751975
anyInvalid |= conformance->isInvalid();
19761976
if (anyInvalid)
19771977
continue;
@@ -2006,17 +2006,14 @@ void MultiConformanceChecker::checkAllConformances() {
20062006

20072007
static void diagnoseConformanceImpliedByConditionalConformance(
20082008
DiagnosticEngine &Diags, NormalProtocolConformance *conformance,
2009-
NormalProtocolConformance *implyingConf, bool issueFixit) {
2009+
NormalProtocolConformance *implyingConf) {
20102010
auto proto = conformance->getProtocol();
20112011
Type protoType = proto->getDeclaredInterfaceType();
20122012
auto implyingProto = implyingConf->getProtocol()->getDeclaredInterfaceType();
20132013
auto loc = implyingConf->getLoc();
20142014
Diags.diagnose(loc, diag::conditional_conformances_cannot_imply_conformances,
20152015
conformance->getType(), implyingProto, protoType);
20162016

2017-
if (!issueFixit)
2018-
return;
2019-
20202017
// Now we get down to business: constructing a few options for new
20212018
// extensions. They all look like:
20222019
//
@@ -2136,8 +2133,7 @@ static bool hasAdditionalSemanticChecks(ProtocolDecl *proto) {
21362133
/// Determine whether the type \c T conforms to the protocol \c Proto,
21372134
/// recording the complete witness table if it does.
21382135
void MultiConformanceChecker::
2139-
checkIndividualConformance(NormalProtocolConformance *conformance,
2140-
bool issueFixit) {
2136+
checkIndividualConformance(NormalProtocolConformance *conformance) {
21412137
PrettyStackTraceConformance trace("type-checking", conformance);
21422138

21432139
switch (conformance->getState()) {
@@ -2321,7 +2317,6 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
23212317
ComplainLoc, diag::unchecked_conformance_not_special, ProtoType);
23222318
}
23232319

2324-
bool impliedDisablesMissingWitnessFixits = false;
23252320
if (conformance->getSourceKind() == ConformanceEntryKind::Implied &&
23262321
!Proto->isMarkerProtocol()) {
23272322
// We've got something like:
@@ -2341,13 +2336,13 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
23412336

23422337
auto implyingCondReqs = implyingConf->getConditionalRequirements();
23432338
if (!implyingCondReqs.empty()) {
2339+
// FIXME:
23442340
// We shouldn't suggest including witnesses for the conformance, because
23452341
// those suggestions will go in the current DeclContext, but really they
23462342
// should go into the new extension we (might) suggest here.
2347-
impliedDisablesMissingWitnessFixits = true;
23482343

23492344
diagnoseConformanceImpliedByConditionalConformance(
2350-
C.Diags, conformance, implyingConf, issueFixit);
2345+
C.Diags, conformance, implyingConf);
23512346

23522347
conformance->setInvalid();
23532348
}
@@ -2385,10 +2380,7 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
23852380
MissingWitnesses.insert(revivedMissingWitnesses.begin(),
23862381
revivedMissingWitnesses.end());
23872382

2388-
auto missingWitnessFixits = issueFixit && !impliedDisablesMissingWitnessFixits;
2389-
AllUsedCheckers.back().checkConformance(
2390-
missingWitnessFixits ? MissingWitnessDiagnosisKind::ErrorFixIt
2391-
: MissingWitnessDiagnosisKind::ErrorOnly);
2383+
AllUsedCheckers.back().checkConformance();
23922384
}
23932385

23942386
/// Add the next associated type deduction to the string representation
@@ -3830,7 +3822,19 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind, bool Delayed) {
38303822
return true;
38313823
}
38323824

3833-
if (Kind != MissingWitnessDiagnosisKind::FixItOnly) {
3825+
switch (Kind) {
3826+
case MissingWitnessDiagnosisKind::FixItOnly: {
3827+
const auto MissingWitnesses = filterProtocolRequirements(
3828+
GlobalMissingWitnesses.getArrayRef(), Adoptee);
3829+
getASTContext().addDelayedConformanceDiag(Conformance, true,
3830+
[MissingWitnesses](NormalProtocolConformance *Conf) {
3831+
diagnoseProtocolStubFixit(Conf, MissingWitnesses);
3832+
});
3833+
clearGlobalMissingWitnesses();
3834+
return true;
3835+
}
3836+
3837+
case MissingWitnessDiagnosisKind::ErrorOnly: {
38343838
// Diagnose the missing witnesses.
38353839
for (auto &Missing : LocalMissing) {
38363840
auto requirement = Missing.requirement;
@@ -3848,22 +3852,8 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind, bool Delayed) {
38483852
diagnoseMatch(dc->getParentModule(), conformance, requirement, match);
38493853
}
38503854
});
3855+
}
38513856
}
3852-
}
3853-
3854-
switch (Kind) {
3855-
case MissingWitnessDiagnosisKind::FixItOnly:
3856-
case MissingWitnessDiagnosisKind::ErrorFixIt: {
3857-
const auto MissingWitnesses = filterProtocolRequirements(
3858-
GlobalMissingWitnesses.getArrayRef(), Adoptee);
3859-
getASTContext().addDelayedConformanceDiag(Conformance, true,
3860-
[MissingWitnesses](NormalProtocolConformance *Conf) {
3861-
diagnoseProtocolStubFixit(Conf, MissingWitnesses);
3862-
});
3863-
clearGlobalMissingWitnesses();
3864-
return true;
3865-
}
3866-
case MissingWitnessDiagnosisKind::ErrorOnly:
38673857
return true;
38683858
}
38693859
}
@@ -5118,7 +5108,7 @@ void ConformanceChecker::resolveValueWitnesses() {
51185108
}
51195109
}
51205110

5121-
void ConformanceChecker::checkConformance(MissingWitnessDiagnosisKind Kind) {
5111+
void ConformanceChecker::checkConformance() {
51225112
assert(!Conformance->isComplete() && "Conformance is already complete");
51235113

51245114
FrontendStatsTracer statsTracer(getASTContext().Stats,
@@ -5134,7 +5124,8 @@ void ConformanceChecker::checkConformance(MissingWitnessDiagnosisKind Kind) {
51345124
resolveValueWitnesses();
51355125

51365126
// Diagnose any missing witnesses.
5137-
diagnoseMissingWitnesses(Kind, /*Delayed=*/false);
5127+
diagnoseMissingWitnesses(MissingWitnessDiagnosisKind::ErrorOnly,
5128+
/*Delayed=*/false);
51385129

51395130
// Except in specific hardcoded cases for Foundation/Swift
51405131
// standard library compatibility, an _ObjectiveCBridgeable
@@ -6527,7 +6518,7 @@ ValueWitnessRequest::evaluate(Evaluator &eval,
65276518
ConformanceChecker checker(requirement->getASTContext(), conformance,
65286519
MissingWitnesses);
65296520
checker.resolveSingleWitness(requirement);
6530-
checker.diagnoseMissingWitnesses(MissingWitnessDiagnosisKind::ErrorFixIt,
6521+
checker.diagnoseMissingWitnesses(MissingWitnessDiagnosisKind::ErrorOnly,
65316522
/*Delayed=*/true);
65326523
// FIXME: ConformanceChecker and the other associated WitnessCheckers have
65336524
// an extremely convoluted caching scheme that doesn't fit nicely into the

lib/Sema/TypeCheckProtocol.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ enum class ResolveWitnessResult {
120120
enum class MissingWitnessDiagnosisKind {
121121
FixItOnly,
122122
ErrorOnly,
123-
ErrorFixIt,
124123
};
125124

126125
/// The protocol conformance checker.
@@ -232,9 +231,8 @@ class ConformanceChecker : public WitnessChecker {
232231
/// directly as possible.
233232
void resolveSingleTypeWitness(AssociatedTypeDecl *assocType);
234233

235-
/// Check the entire protocol conformance, ensuring that all
236-
/// witnesses are resolved and emitting any diagnostics.
237-
void checkConformance(MissingWitnessDiagnosisKind Kind);
234+
/// Check the entire protocol conformance.
235+
void checkConformance();
238236
};
239237

240238
/// Match the given witness to the given requirement.

0 commit comments

Comments
 (0)