@@ -1499,7 +1499,7 @@ class swift::MultiConformanceChecker {
1499
1499
llvm::SmallVector<ValueDecl*, 16 > UnsatisfiedReqs;
1500
1500
llvm::SmallVector<ConformanceChecker, 4 > AllUsedCheckers;
1501
1501
llvm::SmallVector<NormalProtocolConformance*, 4 > AllConformances;
1502
- llvm::SetVector<ValueDecl* > MissingWitnesses;
1502
+ llvm::SetVector<MissingWitness > MissingWitnesses;
1503
1503
llvm::SmallPtrSet<ValueDecl *, 8 > CoveredMembers;
1504
1504
1505
1505
// / Check one conformance.
@@ -1729,13 +1729,17 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
1729
1729
PrettyStackTraceConformance trace (getASTContext (), " type-checking" ,
1730
1730
conformance);
1731
1731
1732
- std::vector<ValueDecl* > revivedMissingWitnesses;
1732
+ std::vector<MissingWitness > revivedMissingWitnesses;
1733
1733
switch (conformance->getState ()) {
1734
1734
case ProtocolConformanceState::Incomplete:
1735
1735
if (conformance->isInvalid ()) {
1736
1736
// Revive registered missing witnesses to handle it below.
1737
- revivedMissingWitnesses =
1738
- getASTContext ().takeDelayedMissingWitnesses (conformance);
1737
+ if (auto delayed = getASTContext ().takeDelayedMissingWitnesses (
1738
+ conformance)) {
1739
+ revivedMissingWitnesses = std::move (
1740
+ static_cast <DelayedMissingWitnesses *>(
1741
+ delayed.get ())->missingWitnesses );
1742
+ }
1739
1743
1740
1744
// If we have no missing witnesses for this invalid conformance, the
1741
1745
// conformance is invalid for other reasons, so emit diagnosis now.
@@ -2481,7 +2485,7 @@ diagnoseMatch(ModuleDecl *module, NormalProtocolConformance *conformance,
2481
2485
2482
2486
ConformanceChecker::ConformanceChecker (
2483
2487
ASTContext &ctx, NormalProtocolConformance *conformance,
2484
- llvm::SetVector<ValueDecl * > &GlobalMissingWitnesses,
2488
+ llvm::SetVector<MissingWitness > &GlobalMissingWitnesses,
2485
2489
bool suppressDiagnostics)
2486
2490
: WitnessChecker(ctx, conformance->getProtocol (), conformance->getType(),
2487
2491
conformance->getDeclContext()),
@@ -2986,26 +2990,28 @@ printRequirementStub(ValueDecl *Requirement, DeclContext *Adopter,
2986
2990
// / NoStubRequirements.
2987
2991
static void
2988
2992
printProtocolStubFixitString (SourceLoc TypeLoc, ProtocolConformance *Conf,
2989
- ArrayRef<ValueDecl* > MissingWitnesses,
2993
+ ArrayRef<MissingWitness > MissingWitnesses,
2990
2994
std::string &FixitString,
2991
2995
llvm::SetVector<ValueDecl*> &NoStubRequirements) {
2992
2996
llvm::raw_string_ostream FixitStream (FixitString);
2993
2997
std::for_each (MissingWitnesses.begin (), MissingWitnesses.end (),
2994
- [&](ValueDecl* VD) {
2995
- if (!printRequirementStub (VD, Conf->getDeclContext (), Conf->getType (),
2996
- TypeLoc, FixitStream)) {
2997
- NoStubRequirements.insert (VD);
2998
+ [&](const MissingWitness &Missing) {
2999
+ if (!printRequirementStub (
3000
+ Missing.requirement , Conf->getDeclContext (), Conf->getType (),
3001
+ TypeLoc, FixitStream)) {
3002
+ NoStubRequirements.insert (Missing.requirement );
2998
3003
}
2999
3004
});
3000
3005
}
3001
3006
3002
3007
// / Filter the given array of protocol requirements and produce a new vector
3003
3008
// / containing the non-conflicting requirements to be implemented by the given
3004
3009
// / \c Adoptee type.
3005
- static llvm::SmallVector<ValueDecl *, 4 >
3006
- filterProtocolRequirements (ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
3007
- llvm::SmallVector<ValueDecl *, 4 > Filtered;
3008
- if (Reqs.empty ()) {
3010
+ static llvm::SmallVector<MissingWitness, 4 >
3011
+ filterProtocolRequirements (
3012
+ ArrayRef<MissingWitness> MissingWitnesses, Type Adoptee) {
3013
+ llvm::SmallVector<MissingWitness, 4 > Filtered;
3014
+ if (MissingWitnesses.empty ()) {
3009
3015
return Filtered;
3010
3016
}
3011
3017
@@ -3017,10 +3023,11 @@ filterProtocolRequirements(ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
3017
3023
3018
3024
llvm::SmallDenseMap<DeclName, llvm::SmallVector<ValueDecl *, 2 >, 4 >
3019
3025
DeclsByName;
3020
- for (auto *const Req : Reqs) {
3026
+ for (const auto &Missing: MissingWitnesses) {
3027
+ auto Req = Missing.requirement ;
3021
3028
if (DeclsByName.find (Req->getName ()) == DeclsByName.end ()) {
3022
3029
DeclsByName[Req->getName ()] = {Req};
3023
- Filtered.push_back (Req );
3030
+ Filtered.push_back (Missing );
3024
3031
continue ;
3025
3032
}
3026
3033
@@ -3046,7 +3053,7 @@ filterProtocolRequirements(ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
3046
3053
}
3047
3054
3048
3055
DeclsByName[Req->getName ()].push_back (Req);
3049
- Filtered.push_back (Req );
3056
+ Filtered.push_back (Missing );
3050
3057
}
3051
3058
3052
3059
return Filtered;
@@ -3060,10 +3067,9 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
3060
3067
if (LocalMissing.empty ())
3061
3068
return ;
3062
3069
3063
- const auto InsertFixit = [](NormalProtocolConformance *Conf,
3064
- SourceLoc ComplainLoc, bool EditorMode,
3065
- llvm::SmallVector<ValueDecl *, 4 >
3066
- MissingWitnesses) {
3070
+ const auto InsertFixit = [](
3071
+ NormalProtocolConformance *Conf, SourceLoc ComplainLoc, bool EditorMode,
3072
+ llvm::SmallVector<MissingWitness, 4 > MissingWitnesses) {
3067
3073
DeclContext *DC = Conf->getDeclContext ();
3068
3074
// The location where to insert stubs.
3069
3075
SourceLoc FixitLocation;
@@ -3097,7 +3103,9 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
3097
3103
}
3098
3104
auto &SM = DC->getASTContext ().SourceMgr ;
3099
3105
auto FixitBufferId = SM.findBufferContainingLoc (FixitLocation);
3100
- for (auto VD : MissingWitnesses) {
3106
+ for (const auto &Missing : MissingWitnesses) {
3107
+ auto VD = Missing.requirement ;
3108
+
3101
3109
// Don't ever emit a diagnostic for a requirement in the NSObject
3102
3110
// protocol. They're not implementable.
3103
3111
if (isNSObjectProtocol (VD->getDeclContext ()->getSelfProtocolDecl ()))
@@ -3167,18 +3175,22 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
3167
3175
// If the diagnostics are suppressed, we register these missing witnesses
3168
3176
// for later revisiting.
3169
3177
Conformance->setInvalid ();
3170
- getASTContext ().addDelayedMissingWitnesses (Conformance, MissingWitnesses);
3178
+ getASTContext ().addDelayedMissingWitnesses (
3179
+ Conformance,
3180
+ std::make_unique<DelayedMissingWitnesses>(MissingWitnesses));
3171
3181
} else {
3172
3182
diagnoseOrDefer (
3173
- LocalMissing[0 ], true , [&](NormalProtocolConformance *Conf) {
3183
+ LocalMissing[0 ].requirement , true ,
3184
+ [&](NormalProtocolConformance *Conf) {
3174
3185
InsertFixit (Conf, Loc, IsEditorMode, std::move (MissingWitnesses));
3175
3186
});
3176
3187
}
3177
3188
clearGlobalMissingWitnesses ();
3178
3189
return ;
3179
3190
}
3180
3191
case MissingWitnessDiagnosisKind::ErrorOnly: {
3181
- diagnoseOrDefer (LocalMissing[0 ], true , [](NormalProtocolConformance *) {});
3192
+ diagnoseOrDefer (
3193
+ LocalMissing[0 ].requirement , true , [](NormalProtocolConformance *) {});
3182
3194
return ;
3183
3195
}
3184
3196
case MissingWitnessDiagnosisKind::FixItOnly:
@@ -3683,7 +3695,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
3683
3695
return ResolveWitnessResult::Missing;
3684
3696
}
3685
3697
3686
- // Diagnose the error.
3698
+ // Diagnose the error.
3687
3699
3688
3700
// If there was an invalid witness that might have worked, just
3689
3701
// suppress the diagnostic entirely. This stops the diagnostic cascade.
@@ -3695,7 +3707,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
3695
3707
3696
3708
if (!numViable) {
3697
3709
// Save the missing requirement for later diagnosis.
3698
- GlobalMissingWitnesses.insert (requirement);
3710
+ GlobalMissingWitnesses.insert ({ requirement, matches} );
3699
3711
diagnoseOrDefer (requirement, true ,
3700
3712
[requirement, matches, nominal](NormalProtocolConformance *conformance) {
3701
3713
auto dc = conformance->getDeclContext ();
@@ -3789,7 +3801,7 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDefault(
3789
3801
return ResolveWitnessResult::Success;
3790
3802
}
3791
3803
// Save the missing requirement for later diagnosis.
3792
- GlobalMissingWitnesses.insert (requirement);
3804
+ GlobalMissingWitnesses.insert ({ requirement, {}} );
3793
3805
return ResolveWitnessResult::ExplicitFailed;
3794
3806
}
3795
3807
@@ -4014,7 +4026,7 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
4014
4026
return ResolveWitnessResult::ExplicitFailed;
4015
4027
}
4016
4028
// Save the missing type witness for later diagnosis.
4017
- GlobalMissingWitnesses.insert (assocType);
4029
+ GlobalMissingWitnesses.insert ({ assocType, {}} );
4018
4030
4019
4031
// None of the candidates were viable.
4020
4032
diagnoseOrDefer (assocType, true ,
@@ -5670,7 +5682,7 @@ TypeWitnessAndDecl
5670
5682
TypeWitnessRequest::evaluate (Evaluator &eval,
5671
5683
NormalProtocolConformance *conformance,
5672
5684
AssociatedTypeDecl *requirement) const {
5673
- llvm::SetVector<ValueDecl* > MissingWitnesses;
5685
+ llvm::SetVector<MissingWitness > MissingWitnesses;
5674
5686
ConformanceChecker checker (requirement->getASTContext (), conformance,
5675
5687
MissingWitnesses);
5676
5688
checker.resolveSingleTypeWitness (requirement);
@@ -5688,7 +5700,7 @@ Witness
5688
5700
ValueWitnessRequest::evaluate (Evaluator &eval,
5689
5701
NormalProtocolConformance *conformance,
5690
5702
ValueDecl *requirement) const {
5691
- llvm::SetVector<ValueDecl* > MissingWitnesses;
5703
+ llvm::SetVector<MissingWitness > MissingWitnesses;
5692
5704
ConformanceChecker checker (requirement->getASTContext (), conformance,
5693
5705
MissingWitnesses);
5694
5706
checker.resolveSingleWitness (requirement);
0 commit comments