Skip to content

Commit 0b880f6

Browse files
committed
Sema: Remove ConformanceChecker::diagnoseOrDefer()
1 parent 525b6ef commit 0b880f6

File tree

5 files changed

+46
-73
lines changed

5 files changed

+46
-73
lines changed

include/swift/AST/ASTContext.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,9 +1313,8 @@ class ASTContext final {
13131313
/// conformance itself, along with a bit indicating whether this diagnostic
13141314
/// produces an error.
13151315
struct DelayedConformanceDiag {
1316-
const ValueDecl *Requirement;
1317-
std::function<void()> Callback;
13181316
bool IsError;
1317+
std::function<void(NormalProtocolConformance *)> Callback;
13191318
};
13201319

13211320
/// Check whether current context has any errors associated with
@@ -1330,8 +1329,9 @@ class ASTContext final {
13301329

13311330
/// Add a delayed diagnostic produced while type-checking a
13321331
/// particular protocol conformance.
1333-
void addDelayedConformanceDiag(NormalProtocolConformance *conformance,
1334-
DelayedConformanceDiag fn);
1332+
void addDelayedConformanceDiag(
1333+
NormalProtocolConformance *conformance, bool isError,
1334+
std::function<void(NormalProtocolConformance *)> callback);
13351335

13361336
/// Retrieve the delayed-conformance diagnostic callbacks for the
13371337
/// given normal protocol conformance.

lib/AST/ASTContext.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2775,11 +2775,14 @@ bool ASTContext::hasDelayedConformanceErrors(
27752775
MissingWitnessesBase::~MissingWitnessesBase() { }
27762776

27772777
void ASTContext::addDelayedConformanceDiag(
2778-
NormalProtocolConformance *conformance,
2779-
DelayedConformanceDiag fn) {
2778+
NormalProtocolConformance *conformance, bool isError,
2779+
std::function<void(NormalProtocolConformance *)> callback) {
2780+
if (isError)
2781+
conformance->setInvalid();
2782+
27802783
auto &diagnostics = getImpl().DelayedConformanceDiags[conformance];
27812784

2782-
if (fn.IsError && !diagnostics.HadError) {
2785+
if (isError && !diagnostics.HadError) {
27832786
diagnostics.HadError = true;
27842787

27852788
auto *proto = conformance->getProtocol();
@@ -2814,7 +2817,7 @@ void ASTContext::addDelayedConformanceDiag(
28142817
}
28152818
}
28162819

2817-
diagnostics.Diags.push_back(std::move(fn));
2820+
diagnostics.Diags.push_back({isError, callback});
28182821
}
28192822

28202823
void ASTContext::addDelayedMissingWitnesses(

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3876,7 +3876,7 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind, bool Delayed) {
38763876
auto matches = Missing.matches;
38773877
auto nominal = DC->getSelfNominalTypeDecl();
38783878

3879-
diagnoseOrDefer(requirement, true,
3879+
getASTContext().addDelayedConformanceDiag(Conformance, true,
38803880
[requirement, matches, nominal](NormalProtocolConformance *conformance) {
38813881
auto dc = conformance->getDeclContext();
38823882
auto *protocol = conformance->getProtocol();
@@ -4010,8 +4010,7 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind, bool Delayed) {
40104010
std::make_unique<DelayedMissingWitnesses>(MissingWitnesses));
40114011
} else {
40124012
auto Loc = this->Loc;
4013-
diagnoseOrDefer(
4014-
LocalMissing[0].requirement, true,
4013+
getASTContext().addDelayedConformanceDiag(Conformance, true,
40154014
[InsertFixit, Loc, IsEditorMode, MissingWitnesses](NormalProtocolConformance *Conf) {
40164015
InsertFixit(Conf, Loc, IsEditorMode, MissingWitnesses);
40174016
});
@@ -4020,8 +4019,8 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind, bool Delayed) {
40204019
return true;
40214020
}
40224021
case MissingWitnessDiagnosisKind::ErrorOnly: {
4023-
diagnoseOrDefer(
4024-
LocalMissing[0].requirement, true, [](NormalProtocolConformance *) {});
4022+
getASTContext().addDelayedConformanceDiag(Conformance, true,
4023+
[](NormalProtocolConformance *) {});
40254024
return true;
40264025
}
40274026
case MissingWitnessDiagnosisKind::FixItOnly:
@@ -4125,7 +4124,7 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
41254124
!ctor->hasClangNode()) {
41264125
// FIXME: We're not recovering (in the AST), so the Fix-It
41274126
// should move.
4128-
diagnoseOrDefer(requirement, false,
4127+
getASTContext().addDelayedConformanceDiag(Conformance, false,
41294128
[ctor, requirement](NormalProtocolConformance *conformance) {
41304129
bool inExtension = isa<ExtensionDecl>(ctor->getDeclContext());
41314130
auto &diags = ctor->getASTContext().Diags;
@@ -4159,7 +4158,7 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
41594158
// References to Self in a position where subclasses cannot do
41604159
// the right thing. Complain if the adoptee is a non-final
41614160
// class.
4162-
diagnoseOrDefer(requirement, false,
4161+
getASTContext().addDelayedConformanceDiag(Conformance, false,
41634162
[witness, requirement](NormalProtocolConformance *conformance) {
41644163
auto proto = conformance->getProtocol();
41654164
auto &diags = proto->getASTContext().Diags;
@@ -4187,7 +4186,7 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
41874186
}();
41884187

41894188
if (!hasDynamicSelfResult) {
4190-
diagnoseOrDefer(requirement, false,
4189+
getASTContext().addDelayedConformanceDiag(Conformance, false,
41914190
[witness, requirement](NormalProtocolConformance *conformance) {
41924191
auto proto = conformance->getProtocol();
41934192
auto &diags = proto->getASTContext().Diags;
@@ -4236,7 +4235,7 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
42364235
if (isa<FuncDecl>(witness) || isa<SubscriptDecl>(witness)) {
42374236
if (witness->getDeclContext()->getExtendedProtocolDecl()) {
42384237
if (selfRefInfo.hasCovariantSelfResult && selfRefInfo.assocTypeRef) {
4239-
diagnoseOrDefer(requirement, false,
4238+
getASTContext().addDelayedConformanceDiag(Conformance, false,
42404239
[witness, requirement](NormalProtocolConformance *conformance) {
42414240
auto proto = conformance->getProtocol();
42424241
auto &diags = proto->getASTContext().Diags;
@@ -4318,7 +4317,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
43184317
requirement->getName() != best.Witness->getName() &&
43194318
!witnessHasImplementsAttrForRequiredName(best.Witness, requirement)) {
43204319

4321-
diagnoseOrDefer(requirement, false,
4320+
getASTContext().addDelayedConformanceDiag(Conformance, false,
43224321
[witness, requirement](NormalProtocolConformance *conformance) {
43234322
auto proto = conformance->getProtocol();
43244323
auto &diags = proto->getASTContext().Diags;
@@ -4350,7 +4349,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
43504349

43514350
// Avoid relying on the lifetime of 'this'.
43524351
const DeclContext *DC = this->DC;
4353-
diagnoseOrDefer(requirement, isError,
4352+
getASTContext().addDelayedConformanceDiag(Conformance, isError,
43544353
[DC, requirement, witness, sendFrom](
43554354
NormalProtocolConformance *conformance) {
43564355
diagnoseSendabilityErrorBasedOn(conformance->getProtocol(), sendFrom,
@@ -4393,7 +4392,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
43934392

43944393
// Avoid relying on the lifetime of 'this'.
43954394
const DeclContext *DC = this->DC;
4396-
diagnoseOrDefer(requirement, false,
4395+
getASTContext().addDelayedConformanceDiag(Conformance, false,
43974396
[DC, witness, check, requirement](
43984397
NormalProtocolConformance *conformance) {
43994398
auto requiredAccessScope = check.RequiredAccessScope;
@@ -4426,11 +4425,12 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
44264425
}
44274426

44284427
case CheckKind::UsableFromInline:
4429-
diagnoseOrDefer(requirement, false, DiagnoseUsableFromInline(witness));
4428+
getASTContext().addDelayedConformanceDiag(Conformance, false,
4429+
DiagnoseUsableFromInline(witness));
44304430
break;
44314431

44324432
case CheckKind::Availability: {
4433-
diagnoseOrDefer(requirement, false,
4433+
getASTContext().addDelayedConformanceDiag(Conformance, false,
44344434
[witness, requirement, check](
44354435
NormalProtocolConformance *conformance) {
44364436
// FIXME: The problem may not be the OS version.
@@ -4459,7 +4459,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
44594459
case CheckKind::OptionalityConflict: {
44604460
auto adjustments = best.OptionalAdjustments;
44614461

4462-
diagnoseOrDefer(requirement, false,
4462+
getASTContext().addDelayedConformanceDiag(Conformance, false,
44634463
[witness, adjustments, requirement](NormalProtocolConformance *conformance) {
44644464
auto proto = conformance->getProtocol();
44654465
auto &ctx = witness->getASTContext();
@@ -4490,7 +4490,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
44904490
}
44914491

44924492
case CheckKind::ConstructorFailability:
4493-
diagnoseOrDefer(requirement, false,
4493+
getASTContext().addDelayedConformanceDiag(Conformance, false,
44944494
[witness, requirement](NormalProtocolConformance *conformance) {
44954495
auto ctor = cast<ConstructorDecl>(requirement);
44964496
auto witnessCtor = cast<ConstructorDecl>(witness);
@@ -4505,9 +4505,8 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
45054505
break;
45064506

45074507
case CheckKind::WitnessUnavailable:
4508-
diagnoseOrDefer(requirement, /*isError=*/true,
4509-
[witness, requirement](
4510-
NormalProtocolConformance *conformance) {
4508+
getASTContext().addDelayedConformanceDiag(Conformance, true,
4509+
[witness, requirement](NormalProtocolConformance *conformance) {
45114510
auto &diags = witness->getASTContext().Diags;
45124511
SourceLoc diagLoc = getLocForDiagnosingWitness(conformance, witness);
45134512
auto *attr = AvailableAttr::isUnavailable(witness);
@@ -4572,7 +4571,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
45724571
return ResolveWitnessResult::Missing;
45734572
}
45744573

4575-
diagnoseOrDefer(requirement, true,
4574+
getASTContext().addDelayedConformanceDiag(Conformance, true,
45764575
[requirement, matches, ignoringNames](
45774576
NormalProtocolConformance *conformance) {
45784577
auto dc = conformance->getDeclContext();
@@ -4632,7 +4631,7 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDerivation(
46324631
}
46334632

46344633
// Derivation failed.
4635-
diagnoseOrDefer(requirement, true,
4634+
getASTContext().addDelayedConformanceDiag(Conformance, true,
46364635
[](NormalProtocolConformance *conformance) {
46374636
auto proto = conformance->getProtocol();
46384637
auto &diags = proto->getASTContext().Diags;
@@ -4911,7 +4910,7 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
49114910

49124911
// If we had multiple viable types, diagnose the ambiguity.
49134912
if (!viable.empty()) {
4914-
diagnoseOrDefer(assocType, true,
4913+
getASTContext().addDelayedConformanceDiag(Conformance, true,
49154914
[assocType, viable](NormalProtocolConformance *conformance) {
49164915
auto &diags = assocType->getASTContext().Diags;
49174916
diags.diagnose(assocType, diag::ambiguous_witnesses_type,
@@ -4927,7 +4926,7 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
49274926
GlobalMissingWitnesses.insert({assocType, {}});
49284927

49294928
// None of the candidates were viable.
4930-
diagnoseOrDefer(assocType, true,
4929+
getASTContext().addDelayedConformanceDiag(Conformance, true,
49314930
[nonViable](NormalProtocolConformance *conformance) {
49324931
auto &diags = conformance->getDeclContext()->getASTContext().Diags;
49334932
for (auto candidate : nonViable) {
@@ -5112,7 +5111,7 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
51125111
if (!Conformance->isInvalid()) {
51135112
if (result.getKind() == CheckRequirementsResult::RequirementFailure) {
51145113
auto Loc = this->Loc;
5115-
diagnoseOrDefer(nullptr, /*isError=*/true,
5114+
getASTContext().addDelayedConformanceDiag(Conformance, /*isError=*/true,
51165115
[Loc, result, proto, substitutions, module](NormalProtocolConformance *conformance) {
51175116
TypeChecker::diagnoseRequirementFailure(
51185117
result.getRequirementFailureInfo(), Loc, Loc,
@@ -5147,7 +5146,7 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
51475146
const DeclContext *DC = this->DC;
51485147
auto requiredAccessScope = getRequiredAccessScope();
51495148

5150-
diagnoseOrDefer(assocType, false,
5149+
getASTContext().addDelayedConformanceDiag(Conformance, false,
51515150
[DC, requiredAccessScope, typeDecl](
51525151
NormalProtocolConformance *conformance) {
51535152
AccessLevel requiredAccess =
@@ -5170,7 +5169,8 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
51705169
bool witnessIsUsableFromInline = typeDecl->getFormalAccessScope(
51715170
DC, /*usableFromInlineAsPublic*/true).isPublic();
51725171
if (!witnessIsUsableFromInline)
5173-
diagnoseOrDefer(assocType, false, DiagnoseUsableFromInline(typeDecl));
5172+
getASTContext().addDelayedConformanceDiag(Conformance, false,
5173+
DiagnoseUsableFromInline(typeDecl));
51745174
}
51755175
}
51765176

@@ -5707,20 +5707,6 @@ void swift::diagnoseConformanceFailure(Type T,
57075707
T, Proto->getDeclaredInterfaceType());
57085708
}
57095709

5710-
void ConformanceChecker::diagnoseOrDefer(
5711-
const ValueDecl *requirement, bool isError,
5712-
std::function<void(NormalProtocolConformance *)> fn) {
5713-
if (isError)
5714-
Conformance->setInvalid();
5715-
5716-
// Stash this in the ASTContext for later emission.
5717-
auto conformance = Conformance;
5718-
5719-
getASTContext().addDelayedConformanceDiag(
5720-
conformance,
5721-
{requirement, [conformance, fn] { fn(conformance); }, isError});
5722-
}
5723-
57245710
void ConformanceChecker::emitDelayedDiags() {
57255711
auto diags = getASTContext().takeDelayedConformanceDiags(Conformance);
57265712

@@ -5731,7 +5717,7 @@ void ConformanceChecker::emitDelayedDiags() {
57315717
AlreadyComplained = true;
57325718
}
57335719

5734-
diag.Callback();
5720+
diag.Callback(Conformance);
57355721
}
57365722
}
57375723

lib/Sema/TypeCheckProtocol.h

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -857,18 +857,6 @@ class ConformanceChecker : public WitnessChecker {
857857
/// the chosen type witnesses.
858858
void ensureRequirementsAreSatisfied();
859859

860-
/// Diagnose or defer a diagnostic, as appropriate.
861-
///
862-
/// \param requirement The requirement with which this diagnostic is
863-
/// associated, if any.
864-
///
865-
/// \param isError Whether this diagnostic is an error.
866-
///
867-
/// \param fn A function to call to emit the actual diagnostic. If
868-
/// diagnostics are being deferred,
869-
void diagnoseOrDefer(const ValueDecl *requirement, bool isError,
870-
std::function<void(NormalProtocolConformance *)> fn);
871-
872860
ArrayRef<MissingWitness> getLocalMissingWitness() {
873861
return GlobalMissingWitnesses.getArrayRef().
874862
slice(LocalMissingWitnessesStartIndex,
@@ -1220,15 +1208,13 @@ class AssociatedTypeInference {
12201208
///
12211209
/// \returns true if a diagnostic was emitted, false otherwise.
12221210
bool diagnoseNoSolutions(
1223-
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes,
1224-
ConformanceChecker &checker);
1211+
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes);
12251212

12261213
/// Emit a diagnostic when there are multiple solutions.
12271214
///
12281215
/// \returns true if a diagnostic was emitted, false otherwise.
12291216
bool diagnoseAmbiguousSolutions(
12301217
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes,
1231-
ConformanceChecker &checker,
12321218
SmallVectorImpl<InferredTypeWitnessesSolution> &solutions);
12331219

12341220
/// We may need to determine a type witness, regardless of the existence of a

lib/Sema/TypeCheckProtocolInference.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,15 +2227,14 @@ namespace {
22272227
} // end anonymous namespace
22282228

22292229
bool AssociatedTypeInference::diagnoseNoSolutions(
2230-
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes,
2231-
ConformanceChecker &checker) {
2230+
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes) {
22322231
// If a defaulted type witness failed, diagnose it.
22332232
if (failedDefaultedAssocType) {
22342233
auto failedDefaultedAssocType = this->failedDefaultedAssocType;
22352234
auto failedDefaultedWitness = this->failedDefaultedWitness;
22362235
auto failedDefaultedResult = this->failedDefaultedResult;
22372236

2238-
checker.diagnoseOrDefer(failedDefaultedAssocType, true,
2237+
ctx.addDelayedConformanceDiag(conformance, true,
22392238
[failedDefaultedAssocType, failedDefaultedWitness,
22402239
failedDefaultedResult](NormalProtocolConformance *conformance) {
22412240
auto proto = conformance->getProtocol();
@@ -2304,7 +2303,7 @@ bool AssociatedTypeInference::diagnoseNoSolutions(
23042303
return false;
23052304

23062305
auto failedSet = std::move(known->second);
2307-
checker.diagnoseOrDefer(assocType, true,
2306+
ctx.addDelayedConformanceDiag(conformance, true,
23082307
[assocType, failedSet](NormalProtocolConformance *conformance) {
23092308
auto proto = conformance->getProtocol();
23102309
auto &diags = proto->getASTContext().Diags;
@@ -2411,7 +2410,7 @@ bool AssociatedTypeInference::diagnoseNoSolutions(
24112410
if (typeWitnessConflict) {
24122411
auto typeWitnessConflict = this->typeWitnessConflict;
24132412

2414-
checker.diagnoseOrDefer(typeWitnessConflict->AssocType, true,
2413+
ctx.addDelayedConformanceDiag(conformance, true,
24152414
[typeWitnessConflict](NormalProtocolConformance *conformance) {
24162415
auto &diags = conformance->getDeclContext()->getASTContext().Diags;
24172416
diags.diagnose(typeWitnessConflict->AssocType,
@@ -2438,7 +2437,6 @@ bool AssociatedTypeInference::diagnoseNoSolutions(
24382437

24392438
bool AssociatedTypeInference::diagnoseAmbiguousSolutions(
24402439
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes,
2441-
ConformanceChecker &checker,
24422440
SmallVectorImpl<InferredTypeWitnessesSolution> &solutions) {
24432441
for (auto assocType : unresolvedAssocTypes) {
24442442
// Find two types that conflict.
@@ -2474,7 +2472,7 @@ bool AssociatedTypeInference::diagnoseAmbiguousSolutions(
24742472
continue;
24752473

24762474
// We found an ambiguity. diagnose it.
2477-
checker.diagnoseOrDefer(assocType, true,
2475+
ctx.addDelayedConformanceDiag(conformance, true,
24782476
[assocType, firstType, firstMatch, secondType, secondMatch](
24792477
NormalProtocolConformance *conformance) {
24802478
auto &diags = assocType->getASTContext().Diags;
@@ -2660,12 +2658,12 @@ auto AssociatedTypeInference::solve(ConformanceChecker &checker)
26602658

26612659
// Diagnose the complete lack of solutions.
26622660
if (solutions.empty() &&
2663-
diagnoseNoSolutions(unresolvedAssocTypes.getArrayRef(), checker))
2661+
diagnoseNoSolutions(unresolvedAssocTypes.getArrayRef()))
26642662
return llvm::None;
26652663

26662664
// Diagnose ambiguous solutions.
26672665
if (!solutions.empty() &&
2668-
diagnoseAmbiguousSolutions(unresolvedAssocTypes.getArrayRef(), checker,
2666+
diagnoseAmbiguousSolutions(unresolvedAssocTypes.getArrayRef(),
26692667
solutions))
26702668
return llvm::None;
26712669

0 commit comments

Comments
 (0)