@@ -1708,9 +1708,18 @@ diagnoseMatch(TypeChecker &tc, Module *module,
1708
1708
withAssocTypes);
1709
1709
break ;
1710
1710
1711
- case MatchKind::RenamedMatch:
1712
- tc.diagnose (match.Witness , diag::protocol_witness_renamed, withAssocTypes);
1711
+ case MatchKind::RenamedMatch: {
1712
+ auto diag = tc.diagnose (match.Witness , diag::protocol_witness_renamed,
1713
+ req->getFullName (), withAssocTypes);
1714
+
1715
+ // Fix the name.
1716
+ fixDeclarationName (diag, match.Witness , req->getFullName ());
1717
+
1718
+ // Also fix the Objective-C name, if needed.
1719
+ if (req->isObjC ())
1720
+ fixDeclarationObjCName (diag, match.Witness , req->getObjCRuntimeName ());
1713
1721
break ;
1722
+ }
1714
1723
1715
1724
case MatchKind::KindConflict:
1716
1725
tc.diagnose (match.Witness , diag::protocol_witness_kind_conflict,
@@ -4344,7 +4353,9 @@ static bool shouldWarnAboutPotentialWitness(ValueDecl *req,
4344
4353
}
4345
4354
4346
4355
// / Diagnose a potential witness.
4347
- static void diagnosePotentialWitness (TypeChecker &tc, ValueDecl *req,
4356
+ static void diagnosePotentialWitness (TypeChecker &tc,
4357
+ NormalProtocolConformance *conformance,
4358
+ ValueDecl *req,
4348
4359
ValueDecl *witness,
4349
4360
Accessibility accessibility) {
4350
4361
auto proto = cast<ProtocolDecl>(req->getDeclContext ());
@@ -4356,20 +4367,18 @@ static void diagnosePotentialWitness(TypeChecker &tc, ValueDecl *req,
4356
4367
req->getFullName (),
4357
4368
proto->getFullName ());
4358
4369
4359
- if (req->getFullName () != witness->getFullName ()) {
4360
- // Note to fix the names.
4361
- auto diag = tc.diagnose (witness, diag::optional_req_near_match_rename,
4362
- req->getFullName ());
4363
- fixDeclarationName (diag, witness, req->getFullName ());
4364
-
4365
- // Also fix the Objective-C name, if needed.
4366
- if (req->isObjC ())
4367
- fixDeclarationObjCName (diag, witness, req->getObjCRuntimeName ());
4368
- } else if (req->isObjC () && !witness->isObjC ()) {
4369
- // Note to add @objc.
4370
+ // Describe why the witness didn't satisfy the requirement.
4371
+ auto match = matchWitness (tc, conformance->getProtocol (), conformance,
4372
+ conformance->getDeclContext (), req, witness);
4373
+ if (match.Kind == MatchKind::ExactMatch &&
4374
+ req->isObjC () && !witness->isObjC ()) {
4375
+ // Special case: note to add @objc.
4370
4376
auto diag = tc.diagnose (witness,
4371
4377
diag::optional_req_nonobjc_near_match_add_objc);
4372
- fixDeclarationObjCName (diag, witness, req->getObjCRuntimeName ());
4378
+ fixDeclarationObjCName (diag, witness, req->getObjCRuntimeName ());
4379
+ } else {
4380
+ diagnoseMatch (tc, conformance->getDeclContext ()->getParentModule (),
4381
+ conformance, req, match);
4373
4382
}
4374
4383
4375
4384
// If moving the declaration can help, suggest that.
@@ -4559,7 +4568,18 @@ void TypeChecker::checkConformancesInContext(DeclContext *dc,
4559
4568
// If we have something to complain about, do so.
4560
4569
if (!bestOptionalReqs.empty ()) {
4561
4570
auto req = bestOptionalReqs[0 ];
4562
- diagnosePotentialWitness (*this , req, value, defaultAccessibility);
4571
+ bool diagnosed = false ;
4572
+ for (auto conformance : conformances) {
4573
+ if (conformance->getProtocol () == req->getDeclContext ()) {
4574
+ diagnosePotentialWitness (*this ,
4575
+ conformance->getRootNormalConformance (),
4576
+ req, value, defaultAccessibility);
4577
+ diagnosed = true ;
4578
+ break ;
4579
+ }
4580
+ }
4581
+ assert (diagnosed && " Failed to find conformance to diagnose?" );
4582
+ (void )diagnosed;
4563
4583
4564
4584
// Remove this optional requirement from the list. We don't want to
4565
4585
// complain about it twice.
0 commit comments