@@ -1503,7 +1503,7 @@ class swift::MultiConformanceChecker {
1503
1503
llvm::SmallVector<ValueDecl*, 16 > UnsatisfiedReqs;
1504
1504
llvm::SmallVector<ConformanceChecker, 4 > AllUsedCheckers;
1505
1505
llvm::SmallVector<NormalProtocolConformance*, 4 > AllConformances;
1506
- llvm::SetVector<ValueDecl* > MissingWitnesses;
1506
+ llvm::SetVector<MissingWitness > MissingWitnesses;
1507
1507
llvm::SmallPtrSet<ValueDecl *, 8 > CoveredMembers;
1508
1508
1509
1509
// / Check one conformance.
@@ -1733,13 +1733,17 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
1733
1733
PrettyStackTraceConformance trace (getASTContext (), " type-checking" ,
1734
1734
conformance);
1735
1735
1736
- std::vector<ValueDecl* > revivedMissingWitnesses;
1736
+ std::vector<MissingWitness > revivedMissingWitnesses;
1737
1737
switch (conformance->getState ()) {
1738
1738
case ProtocolConformanceState::Incomplete:
1739
1739
if (conformance->isInvalid ()) {
1740
1740
// Revive registered missing witnesses to handle it below.
1741
- revivedMissingWitnesses =
1742
- getASTContext ().takeDelayedMissingWitnesses (conformance);
1741
+ if (auto delayed = getASTContext ().takeDelayedMissingWitnesses (
1742
+ conformance)) {
1743
+ revivedMissingWitnesses = std::move (
1744
+ static_cast <DelayedMissingWitnesses *>(
1745
+ delayed.get ())->missingWitnesses );
1746
+ }
1743
1747
1744
1748
// If we have no missing witnesses for this invalid conformance, the
1745
1749
// conformance is invalid for other reasons, so emit diagnosis now.
@@ -2503,7 +2507,7 @@ diagnoseMatch(ModuleDecl *module, NormalProtocolConformance *conformance,
2503
2507
2504
2508
ConformanceChecker::ConformanceChecker (
2505
2509
ASTContext &ctx, NormalProtocolConformance *conformance,
2506
- llvm::SetVector<ValueDecl * > &GlobalMissingWitnesses,
2510
+ llvm::SetVector<MissingWitness > &GlobalMissingWitnesses,
2507
2511
bool suppressDiagnostics)
2508
2512
: WitnessChecker(ctx, conformance->getProtocol (), conformance->getType(),
2509
2513
conformance->getDeclContext()),
@@ -3008,26 +3012,28 @@ printRequirementStub(ValueDecl *Requirement, DeclContext *Adopter,
3008
3012
// / NoStubRequirements.
3009
3013
static void
3010
3014
printProtocolStubFixitString (SourceLoc TypeLoc, ProtocolConformance *Conf,
3011
- ArrayRef<ValueDecl* > MissingWitnesses,
3015
+ ArrayRef<MissingWitness > MissingWitnesses,
3012
3016
std::string &FixitString,
3013
3017
llvm::SetVector<ValueDecl*> &NoStubRequirements) {
3014
3018
llvm::raw_string_ostream FixitStream (FixitString);
3015
3019
std::for_each (MissingWitnesses.begin (), MissingWitnesses.end (),
3016
- [&](ValueDecl* VD) {
3017
- if (!printRequirementStub (VD, Conf->getDeclContext (), Conf->getType (),
3018
- TypeLoc, FixitStream)) {
3019
- NoStubRequirements.insert (VD);
3020
+ [&](const MissingWitness &Missing) {
3021
+ if (!printRequirementStub (
3022
+ Missing.requirement , Conf->getDeclContext (), Conf->getType (),
3023
+ TypeLoc, FixitStream)) {
3024
+ NoStubRequirements.insert (Missing.requirement );
3020
3025
}
3021
3026
});
3022
3027
}
3023
3028
3024
3029
// / Filter the given array of protocol requirements and produce a new vector
3025
3030
// / containing the non-conflicting requirements to be implemented by the given
3026
3031
// / \c Adoptee type.
3027
- static llvm::SmallVector<ValueDecl *, 4 >
3028
- filterProtocolRequirements (ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
3029
- llvm::SmallVector<ValueDecl *, 4 > Filtered;
3030
- if (Reqs.empty ()) {
3032
+ static llvm::SmallVector<MissingWitness, 4 >
3033
+ filterProtocolRequirements (
3034
+ ArrayRef<MissingWitness> MissingWitnesses, Type Adoptee) {
3035
+ llvm::SmallVector<MissingWitness, 4 > Filtered;
3036
+ if (MissingWitnesses.empty ()) {
3031
3037
return Filtered;
3032
3038
}
3033
3039
@@ -3039,10 +3045,11 @@ filterProtocolRequirements(ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
3039
3045
3040
3046
llvm::SmallDenseMap<DeclName, llvm::SmallVector<ValueDecl *, 2 >, 4 >
3041
3047
DeclsByName;
3042
- for (auto *const Req : Reqs) {
3048
+ for (const auto &Missing: MissingWitnesses) {
3049
+ auto Req = Missing.requirement ;
3043
3050
if (DeclsByName.find (Req->getName ()) == DeclsByName.end ()) {
3044
3051
DeclsByName[Req->getName ()] = {Req};
3045
- Filtered.push_back (Req );
3052
+ Filtered.push_back (Missing );
3046
3053
continue ;
3047
3054
}
3048
3055
@@ -3068,7 +3075,7 @@ filterProtocolRequirements(ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
3068
3075
}
3069
3076
3070
3077
DeclsByName[Req->getName ()].push_back (Req);
3071
- Filtered.push_back (Req );
3078
+ Filtered.push_back (Missing );
3072
3079
}
3073
3080
3074
3081
return Filtered;
@@ -3082,10 +3089,9 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
3082
3089
if (LocalMissing.empty ())
3083
3090
return ;
3084
3091
3085
- const auto InsertFixit = [](NormalProtocolConformance *Conf,
3086
- SourceLoc ComplainLoc, bool EditorMode,
3087
- llvm::SmallVector<ValueDecl *, 4 >
3088
- MissingWitnesses) {
3092
+ const auto InsertFixit = [](
3093
+ NormalProtocolConformance *Conf, SourceLoc ComplainLoc, bool EditorMode,
3094
+ llvm::SmallVector<MissingWitness, 4 > MissingWitnesses) {
3089
3095
DeclContext *DC = Conf->getDeclContext ();
3090
3096
// The location where to insert stubs.
3091
3097
SourceLoc FixitLocation;
@@ -3119,7 +3125,9 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
3119
3125
}
3120
3126
auto &SM = DC->getASTContext ().SourceMgr ;
3121
3127
auto FixitBufferId = SM.findBufferContainingLoc (FixitLocation);
3122
- for (auto VD : MissingWitnesses) {
3128
+ for (const auto &Missing : MissingWitnesses) {
3129
+ auto VD = Missing.requirement ;
3130
+
3123
3131
// Don't ever emit a diagnostic for a requirement in the NSObject
3124
3132
// protocol. They're not implementable.
3125
3133
if (isNSObjectProtocol (VD->getDeclContext ()->getSelfProtocolDecl ()))
@@ -3189,18 +3197,22 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
3189
3197
// If the diagnostics are suppressed, we register these missing witnesses
3190
3198
// for later revisiting.
3191
3199
Conformance->setInvalid ();
3192
- getASTContext ().addDelayedMissingWitnesses (Conformance, MissingWitnesses);
3200
+ getASTContext ().addDelayedMissingWitnesses (
3201
+ Conformance,
3202
+ std::make_unique<DelayedMissingWitnesses>(MissingWitnesses));
3193
3203
} else {
3194
3204
diagnoseOrDefer (
3195
- LocalMissing[0 ], true , [&](NormalProtocolConformance *Conf) {
3205
+ LocalMissing[0 ].requirement , true ,
3206
+ [&](NormalProtocolConformance *Conf) {
3196
3207
InsertFixit (Conf, Loc, IsEditorMode, std::move (MissingWitnesses));
3197
3208
});
3198
3209
}
3199
3210
clearGlobalMissingWitnesses ();
3200
3211
return ;
3201
3212
}
3202
3213
case MissingWitnessDiagnosisKind::ErrorOnly: {
3203
- diagnoseOrDefer (LocalMissing[0 ], true , [](NormalProtocolConformance *) {});
3214
+ diagnoseOrDefer (
3215
+ LocalMissing[0 ].requirement , true , [](NormalProtocolConformance *) {});
3204
3216
return ;
3205
3217
}
3206
3218
case MissingWitnessDiagnosisKind::FixItOnly:
@@ -3705,7 +3717,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
3705
3717
return ResolveWitnessResult::Missing;
3706
3718
}
3707
3719
3708
- // Diagnose the error.
3720
+ // Diagnose the error.
3709
3721
3710
3722
// If there was an invalid witness that might have worked, just
3711
3723
// suppress the diagnostic entirely. This stops the diagnostic cascade.
@@ -3717,7 +3729,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
3717
3729
3718
3730
if (!numViable) {
3719
3731
// Save the missing requirement for later diagnosis.
3720
- GlobalMissingWitnesses.insert (requirement);
3732
+ GlobalMissingWitnesses.insert ({ requirement, matches} );
3721
3733
diagnoseOrDefer (requirement, true ,
3722
3734
[requirement, matches, nominal](NormalProtocolConformance *conformance) {
3723
3735
auto dc = conformance->getDeclContext ();
@@ -3810,8 +3822,7 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDefault(
3810
3822
recordOptionalWitness (requirement);
3811
3823
return ResolveWitnessResult::Success;
3812
3824
}
3813
- // Save the missing requirement for later diagnosis.
3814
- GlobalMissingWitnesses.insert (requirement);
3825
+
3815
3826
return ResolveWitnessResult::ExplicitFailed;
3816
3827
}
3817
3828
@@ -4036,7 +4047,7 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
4036
4047
return ResolveWitnessResult::ExplicitFailed;
4037
4048
}
4038
4049
// Save the missing type witness for later diagnosis.
4039
- GlobalMissingWitnesses.insert (assocType);
4050
+ GlobalMissingWitnesses.insert ({ assocType, {}} );
4040
4051
4041
4052
// None of the candidates were viable.
4042
4053
diagnoseOrDefer (assocType, true ,
@@ -5692,7 +5703,7 @@ TypeWitnessAndDecl
5692
5703
TypeWitnessRequest::evaluate (Evaluator &eval,
5693
5704
NormalProtocolConformance *conformance,
5694
5705
AssociatedTypeDecl *requirement) const {
5695
- llvm::SetVector<ValueDecl* > MissingWitnesses;
5706
+ llvm::SetVector<MissingWitness > MissingWitnesses;
5696
5707
ConformanceChecker checker (requirement->getASTContext (), conformance,
5697
5708
MissingWitnesses);
5698
5709
checker.resolveSingleTypeWitness (requirement);
@@ -5710,7 +5721,7 @@ Witness
5710
5721
ValueWitnessRequest::evaluate (Evaluator &eval,
5711
5722
NormalProtocolConformance *conformance,
5712
5723
ValueDecl *requirement) const {
5713
- llvm::SetVector<ValueDecl* > MissingWitnesses;
5724
+ llvm::SetVector<MissingWitness > MissingWitnesses;
5714
5725
ConformanceChecker checker (requirement->getASTContext (), conformance,
5715
5726
MissingWitnesses);
5716
5727
checker.resolveSingleWitness (requirement);
0 commit comments