@@ -1499,7 +1499,7 @@ class swift::MultiConformanceChecker {
14991499 llvm::SmallVector<ValueDecl*, 16 > UnsatisfiedReqs;
15001500 llvm::SmallVector<ConformanceChecker, 4 > AllUsedCheckers;
15011501 llvm::SmallVector<NormalProtocolConformance*, 4 > AllConformances;
1502- llvm::SetVector<ValueDecl* > MissingWitnesses;
1502+ llvm::SetVector<MissingWitness > MissingWitnesses;
15031503 llvm::SmallPtrSet<ValueDecl *, 8 > CoveredMembers;
15041504
15051505 // / Check one conformance.
@@ -1729,13 +1729,17 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
17291729 PrettyStackTraceConformance trace (getASTContext (), " type-checking" ,
17301730 conformance);
17311731
1732- std::vector<ValueDecl* > revivedMissingWitnesses;
1732+ std::vector<MissingWitness > revivedMissingWitnesses;
17331733 switch (conformance->getState ()) {
17341734 case ProtocolConformanceState::Incomplete:
17351735 if (conformance->isInvalid ()) {
17361736 // 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+ }
17391743
17401744 // If we have no missing witnesses for this invalid conformance, the
17411745 // conformance is invalid for other reasons, so emit diagnosis now.
@@ -2481,7 +2485,7 @@ diagnoseMatch(ModuleDecl *module, NormalProtocolConformance *conformance,
24812485
24822486ConformanceChecker::ConformanceChecker (
24832487 ASTContext &ctx, NormalProtocolConformance *conformance,
2484- llvm::SetVector<ValueDecl * > &GlobalMissingWitnesses,
2488+ llvm::SetVector<MissingWitness > &GlobalMissingWitnesses,
24852489 bool suppressDiagnostics)
24862490 : WitnessChecker(ctx, conformance->getProtocol (), conformance->getType(),
24872491 conformance->getDeclContext()),
@@ -2986,26 +2990,28 @@ printRequirementStub(ValueDecl *Requirement, DeclContext *Adopter,
29862990// / NoStubRequirements.
29872991static void
29882992printProtocolStubFixitString (SourceLoc TypeLoc, ProtocolConformance *Conf,
2989- ArrayRef<ValueDecl* > MissingWitnesses,
2993+ ArrayRef<MissingWitness > MissingWitnesses,
29902994 std::string &FixitString,
29912995 llvm::SetVector<ValueDecl*> &NoStubRequirements) {
29922996 llvm::raw_string_ostream FixitStream (FixitString);
29932997 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 );
29983003 }
29993004 });
30003005}
30013006
30023007// / Filter the given array of protocol requirements and produce a new vector
30033008// / containing the non-conflicting requirements to be implemented by the given
30043009// / \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 ()) {
30093015 return Filtered;
30103016 }
30113017
@@ -3017,10 +3023,11 @@ filterProtocolRequirements(ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
30173023
30183024 llvm::SmallDenseMap<DeclName, llvm::SmallVector<ValueDecl *, 2 >, 4 >
30193025 DeclsByName;
3020- for (auto *const Req : Reqs) {
3026+ for (const auto &Missing: MissingWitnesses) {
3027+ auto Req = Missing.requirement ;
30213028 if (DeclsByName.find (Req->getName ()) == DeclsByName.end ()) {
30223029 DeclsByName[Req->getName ()] = {Req};
3023- Filtered.push_back (Req );
3030+ Filtered.push_back (Missing );
30243031 continue ;
30253032 }
30263033
@@ -3046,7 +3053,7 @@ filterProtocolRequirements(ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
30463053 }
30473054
30483055 DeclsByName[Req->getName ()].push_back (Req);
3049- Filtered.push_back (Req );
3056+ Filtered.push_back (Missing );
30503057 }
30513058
30523059 return Filtered;
@@ -3060,10 +3067,9 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
30603067 if (LocalMissing.empty ())
30613068 return ;
30623069
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) {
30673073 DeclContext *DC = Conf->getDeclContext ();
30683074 // The location where to insert stubs.
30693075 SourceLoc FixitLocation;
@@ -3097,7 +3103,9 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
30973103 }
30983104 auto &SM = DC->getASTContext ().SourceMgr ;
30993105 auto FixitBufferId = SM.findBufferContainingLoc (FixitLocation);
3100- for (auto VD : MissingWitnesses) {
3106+ for (const auto &Missing : MissingWitnesses) {
3107+ auto VD = Missing.requirement ;
3108+
31013109 // Don't ever emit a diagnostic for a requirement in the NSObject
31023110 // protocol. They're not implementable.
31033111 if (isNSObjectProtocol (VD->getDeclContext ()->getSelfProtocolDecl ()))
@@ -3167,18 +3175,22 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
31673175 // If the diagnostics are suppressed, we register these missing witnesses
31683176 // for later revisiting.
31693177 Conformance->setInvalid ();
3170- getASTContext ().addDelayedMissingWitnesses (Conformance, MissingWitnesses);
3178+ getASTContext ().addDelayedMissingWitnesses (
3179+ Conformance,
3180+ std::make_unique<DelayedMissingWitnesses>(MissingWitnesses));
31713181 } else {
31723182 diagnoseOrDefer (
3173- LocalMissing[0 ], true , [&](NormalProtocolConformance *Conf) {
3183+ LocalMissing[0 ].requirement , true ,
3184+ [&](NormalProtocolConformance *Conf) {
31743185 InsertFixit (Conf, Loc, IsEditorMode, std::move (MissingWitnesses));
31753186 });
31763187 }
31773188 clearGlobalMissingWitnesses ();
31783189 return ;
31793190 }
31803191 case MissingWitnessDiagnosisKind::ErrorOnly: {
3181- diagnoseOrDefer (LocalMissing[0 ], true , [](NormalProtocolConformance *) {});
3192+ diagnoseOrDefer (
3193+ LocalMissing[0 ].requirement , true , [](NormalProtocolConformance *) {});
31823194 return ;
31833195 }
31843196 case MissingWitnessDiagnosisKind::FixItOnly:
@@ -3683,7 +3695,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
36833695 return ResolveWitnessResult::Missing;
36843696 }
36853697
3686- // Diagnose the error.
3698+ // Diagnose the error.
36873699
36883700 // If there was an invalid witness that might have worked, just
36893701 // suppress the diagnostic entirely. This stops the diagnostic cascade.
@@ -3695,7 +3707,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
36953707
36963708 if (!numViable) {
36973709 // Save the missing requirement for later diagnosis.
3698- GlobalMissingWitnesses.insert (requirement);
3710+ GlobalMissingWitnesses.insert ({ requirement, matches} );
36993711 diagnoseOrDefer (requirement, true ,
37003712 [requirement, matches, nominal](NormalProtocolConformance *conformance) {
37013713 auto dc = conformance->getDeclContext ();
@@ -3789,7 +3801,7 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDefault(
37893801 return ResolveWitnessResult::Success;
37903802 }
37913803 // Save the missing requirement for later diagnosis.
3792- GlobalMissingWitnesses.insert (requirement);
3804+ GlobalMissingWitnesses.insert ({ requirement, {}} );
37933805 return ResolveWitnessResult::ExplicitFailed;
37943806}
37953807
@@ -4014,7 +4026,7 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
40144026 return ResolveWitnessResult::ExplicitFailed;
40154027 }
40164028 // Save the missing type witness for later diagnosis.
4017- GlobalMissingWitnesses.insert (assocType);
4029+ GlobalMissingWitnesses.insert ({ assocType, {}} );
40184030
40194031 // None of the candidates were viable.
40204032 diagnoseOrDefer (assocType, true ,
@@ -5670,7 +5682,7 @@ TypeWitnessAndDecl
56705682TypeWitnessRequest::evaluate (Evaluator &eval,
56715683 NormalProtocolConformance *conformance,
56725684 AssociatedTypeDecl *requirement) const {
5673- llvm::SetVector<ValueDecl* > MissingWitnesses;
5685+ llvm::SetVector<MissingWitness > MissingWitnesses;
56745686 ConformanceChecker checker (requirement->getASTContext (), conformance,
56755687 MissingWitnesses);
56765688 checker.resolveSingleTypeWitness (requirement);
@@ -5688,7 +5700,7 @@ Witness
56885700ValueWitnessRequest::evaluate (Evaluator &eval,
56895701 NormalProtocolConformance *conformance,
56905702 ValueDecl *requirement) const {
5691- llvm::SetVector<ValueDecl* > MissingWitnesses;
5703+ llvm::SetVector<MissingWitness > MissingWitnesses;
56925704 ConformanceChecker checker (requirement->getASTContext (), conformance,
56935705 MissingWitnesses);
56945706 checker.resolveSingleWitness (requirement);
0 commit comments