@@ -1503,7 +1503,7 @@ class swift::MultiConformanceChecker {
15031503 llvm::SmallVector<ValueDecl*, 16 > UnsatisfiedReqs;
15041504 llvm::SmallVector<ConformanceChecker, 4 > AllUsedCheckers;
15051505 llvm::SmallVector<NormalProtocolConformance*, 4 > AllConformances;
1506- llvm::SetVector<ValueDecl* > MissingWitnesses;
1506+ llvm::SetVector<MissingWitness > MissingWitnesses;
15071507 llvm::SmallPtrSet<ValueDecl *, 8 > CoveredMembers;
15081508
15091509 // / Check one conformance.
@@ -1733,13 +1733,17 @@ checkIndividualConformance(NormalProtocolConformance *conformance,
17331733 PrettyStackTraceConformance trace (getASTContext (), " type-checking" ,
17341734 conformance);
17351735
1736- std::vector<ValueDecl* > revivedMissingWitnesses;
1736+ std::vector<MissingWitness > revivedMissingWitnesses;
17371737 switch (conformance->getState ()) {
17381738 case ProtocolConformanceState::Incomplete:
17391739 if (conformance->isInvalid ()) {
17401740 // 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+ }
17431747
17441748 // If we have no missing witnesses for this invalid conformance, the
17451749 // conformance is invalid for other reasons, so emit diagnosis now.
@@ -2503,7 +2507,7 @@ diagnoseMatch(ModuleDecl *module, NormalProtocolConformance *conformance,
25032507
25042508ConformanceChecker::ConformanceChecker (
25052509 ASTContext &ctx, NormalProtocolConformance *conformance,
2506- llvm::SetVector<ValueDecl * > &GlobalMissingWitnesses,
2510+ llvm::SetVector<MissingWitness > &GlobalMissingWitnesses,
25072511 bool suppressDiagnostics)
25082512 : WitnessChecker(ctx, conformance->getProtocol (), conformance->getType(),
25092513 conformance->getDeclContext()),
@@ -3008,26 +3012,28 @@ printRequirementStub(ValueDecl *Requirement, DeclContext *Adopter,
30083012// / NoStubRequirements.
30093013static void
30103014printProtocolStubFixitString (SourceLoc TypeLoc, ProtocolConformance *Conf,
3011- ArrayRef<ValueDecl* > MissingWitnesses,
3015+ ArrayRef<MissingWitness > MissingWitnesses,
30123016 std::string &FixitString,
30133017 llvm::SetVector<ValueDecl*> &NoStubRequirements) {
30143018 llvm::raw_string_ostream FixitStream (FixitString);
30153019 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 );
30203025 }
30213026 });
30223027}
30233028
30243029// / Filter the given array of protocol requirements and produce a new vector
30253030// / containing the non-conflicting requirements to be implemented by the given
30263031// / \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 ()) {
30313037 return Filtered;
30323038 }
30333039
@@ -3039,10 +3045,11 @@ filterProtocolRequirements(ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
30393045
30403046 llvm::SmallDenseMap<DeclName, llvm::SmallVector<ValueDecl *, 2 >, 4 >
30413047 DeclsByName;
3042- for (auto *const Req : Reqs) {
3048+ for (const auto &Missing: MissingWitnesses) {
3049+ auto Req = Missing.requirement ;
30433050 if (DeclsByName.find (Req->getName ()) == DeclsByName.end ()) {
30443051 DeclsByName[Req->getName ()] = {Req};
3045- Filtered.push_back (Req );
3052+ Filtered.push_back (Missing );
30463053 continue ;
30473054 }
30483055
@@ -3068,7 +3075,7 @@ filterProtocolRequirements(ArrayRef<ValueDecl *> Reqs, Type Adoptee) {
30683075 }
30693076
30703077 DeclsByName[Req->getName ()].push_back (Req);
3071- Filtered.push_back (Req );
3078+ Filtered.push_back (Missing );
30723079 }
30733080
30743081 return Filtered;
@@ -3082,10 +3089,9 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
30823089 if (LocalMissing.empty ())
30833090 return ;
30843091
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) {
30893095 DeclContext *DC = Conf->getDeclContext ();
30903096 // The location where to insert stubs.
30913097 SourceLoc FixitLocation;
@@ -3119,7 +3125,9 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
31193125 }
31203126 auto &SM = DC->getASTContext ().SourceMgr ;
31213127 auto FixitBufferId = SM.findBufferContainingLoc (FixitLocation);
3122- for (auto VD : MissingWitnesses) {
3128+ for (const auto &Missing : MissingWitnesses) {
3129+ auto VD = Missing.requirement ;
3130+
31233131 // Don't ever emit a diagnostic for a requirement in the NSObject
31243132 // protocol. They're not implementable.
31253133 if (isNSObjectProtocol (VD->getDeclContext ()->getSelfProtocolDecl ()))
@@ -3189,18 +3197,22 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
31893197 // If the diagnostics are suppressed, we register these missing witnesses
31903198 // for later revisiting.
31913199 Conformance->setInvalid ();
3192- getASTContext ().addDelayedMissingWitnesses (Conformance, MissingWitnesses);
3200+ getASTContext ().addDelayedMissingWitnesses (
3201+ Conformance,
3202+ std::make_unique<DelayedMissingWitnesses>(MissingWitnesses));
31933203 } else {
31943204 diagnoseOrDefer (
3195- LocalMissing[0 ], true , [&](NormalProtocolConformance *Conf) {
3205+ LocalMissing[0 ].requirement , true ,
3206+ [&](NormalProtocolConformance *Conf) {
31963207 InsertFixit (Conf, Loc, IsEditorMode, std::move (MissingWitnesses));
31973208 });
31983209 }
31993210 clearGlobalMissingWitnesses ();
32003211 return ;
32013212 }
32023213 case MissingWitnessDiagnosisKind::ErrorOnly: {
3203- diagnoseOrDefer (LocalMissing[0 ], true , [](NormalProtocolConformance *) {});
3214+ diagnoseOrDefer (
3215+ LocalMissing[0 ].requirement , true , [](NormalProtocolConformance *) {});
32043216 return ;
32053217 }
32063218 case MissingWitnessDiagnosisKind::FixItOnly:
@@ -3705,7 +3717,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
37053717 return ResolveWitnessResult::Missing;
37063718 }
37073719
3708- // Diagnose the error.
3720+ // Diagnose the error.
37093721
37103722 // If there was an invalid witness that might have worked, just
37113723 // suppress the diagnostic entirely. This stops the diagnostic cascade.
@@ -3717,7 +3729,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
37173729
37183730 if (!numViable) {
37193731 // Save the missing requirement for later diagnosis.
3720- GlobalMissingWitnesses.insert (requirement);
3732+ GlobalMissingWitnesses.insert ({ requirement, matches} );
37213733 diagnoseOrDefer (requirement, true ,
37223734 [requirement, matches, nominal](NormalProtocolConformance *conformance) {
37233735 auto dc = conformance->getDeclContext ();
@@ -3810,8 +3822,7 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDefault(
38103822 recordOptionalWitness (requirement);
38113823 return ResolveWitnessResult::Success;
38123824 }
3813- // Save the missing requirement for later diagnosis.
3814- GlobalMissingWitnesses.insert (requirement);
3825+
38153826 return ResolveWitnessResult::ExplicitFailed;
38163827}
38173828
@@ -4036,7 +4047,7 @@ ResolveWitnessResult ConformanceChecker::resolveTypeWitnessViaLookup(
40364047 return ResolveWitnessResult::ExplicitFailed;
40374048 }
40384049 // Save the missing type witness for later diagnosis.
4039- GlobalMissingWitnesses.insert (assocType);
4050+ GlobalMissingWitnesses.insert ({ assocType, {}} );
40404051
40414052 // None of the candidates were viable.
40424053 diagnoseOrDefer (assocType, true ,
@@ -5692,7 +5703,7 @@ TypeWitnessAndDecl
56925703TypeWitnessRequest::evaluate (Evaluator &eval,
56935704 NormalProtocolConformance *conformance,
56945705 AssociatedTypeDecl *requirement) const {
5695- llvm::SetVector<ValueDecl* > MissingWitnesses;
5706+ llvm::SetVector<MissingWitness > MissingWitnesses;
56965707 ConformanceChecker checker (requirement->getASTContext (), conformance,
56975708 MissingWitnesses);
56985709 checker.resolveSingleTypeWitness (requirement);
@@ -5710,7 +5721,7 @@ Witness
57105721ValueWitnessRequest::evaluate (Evaluator &eval,
57115722 NormalProtocolConformance *conformance,
57125723 ValueDecl *requirement) const {
5713- llvm::SetVector<ValueDecl* > MissingWitnesses;
5724+ llvm::SetVector<MissingWitness > MissingWitnesses;
57145725 ConformanceChecker checker (requirement->getASTContext (), conformance,
57155726 MissingWitnesses);
57165727 checker.resolveSingleWitness (requirement);
0 commit comments