@@ -1740,6 +1740,8 @@ checkWitnessAvailability(ValueDecl *requirement,
1740
1740
1741
1741
RequirementCheck WitnessChecker::checkWitness (ValueDecl *requirement,
1742
1742
const RequirementMatch &match) {
1743
+ auto &ctx = getASTContext ();
1744
+
1743
1745
if (!match.OptionalAdjustments .empty ())
1744
1746
return CheckKind::OptionalityConflict;
1745
1747
@@ -1769,7 +1771,7 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
1769
1771
return RequirementCheck (CheckKind::Availability, requiredAvailability);
1770
1772
}
1771
1773
1772
- if (requirement->getAttrs ().isUnavailable (getASTContext () ) &&
1774
+ if (requirement->getAttrs ().isUnavailable (ctx ) &&
1773
1775
match.Witness ->getDeclContext () == DC) {
1774
1776
return RequirementCheck (CheckKind::Unavailable);
1775
1777
}
@@ -1792,11 +1794,11 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
1792
1794
}
1793
1795
}
1794
1796
1795
- if (match.Witness ->getAttrs ().isUnavailable (getASTContext () ) &&
1796
- !requirement->getAttrs ().isUnavailable (getASTContext () )) {
1797
+ if (match.Witness ->getAttrs ().isUnavailable (ctx ) &&
1798
+ !requirement->getAttrs ().isUnavailable (ctx )) {
1797
1799
auto nominalOrExtensionIsUnavailable = [&]() {
1798
1800
if (auto extension = dyn_cast<ExtensionDecl>(DC)) {
1799
- if (extension->getAttrs ().isUnavailable (getASTContext () ))
1801
+ if (extension->getAttrs ().isUnavailable (ctx ))
1800
1802
return true ;
1801
1803
}
1802
1804
@@ -1813,6 +1815,20 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
1813
1815
return CheckKind::WitnessUnavailable;
1814
1816
}
1815
1817
1818
+ // Warn about deprecated default implementations if the requirement is
1819
+ // not deprecated, and the conformance is not deprecated.
1820
+ bool isDefaultWitness = false ;
1821
+ if (auto *nominal = match.Witness ->getDeclContext ()->getSelfNominalTypeDecl ())
1822
+ isDefaultWitness = isa<ProtocolDecl>(nominal);
1823
+ if (isDefaultWitness &&
1824
+ match.Witness ->getAttrs ().isDeprecated (ctx) &&
1825
+ !requirement->getAttrs ().isDeprecated (ctx)) {
1826
+ auto conformanceContext = ExportContext::forConformance (DC, Proto);
1827
+ if (!conformanceContext.isDeprecated ()) {
1828
+ return RequirementCheck (CheckKind::DefaultWitnessDeprecated);
1829
+ }
1830
+ }
1831
+
1816
1832
return CheckKind::Success;
1817
1833
}
1818
1834
@@ -4374,6 +4390,25 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
4374
4390
requirement->getName ());
4375
4391
});
4376
4392
break ;
4393
+
4394
+ case CheckKind::DefaultWitnessDeprecated:
4395
+ getASTContext ().addDelayedConformanceDiag (
4396
+ Conformance, /* isError=*/ false ,
4397
+ [witness, requirement](NormalProtocolConformance *conformance) {
4398
+ auto &ctx = witness->getASTContext ();
4399
+ auto &diags = ctx.Diags ;
4400
+ SourceLoc diagLoc = getLocForDiagnosingWitness (conformance, witness);
4401
+ auto *attr = witness->getAttrs ().getDeprecated (ctx);
4402
+ EncodedDiagnosticMessage EncodedMessage (attr->Message );
4403
+ diags.diagnose (diagLoc, diag::witness_deprecated,
4404
+ witness, conformance->getProtocol ()->getName (),
4405
+ EncodedMessage.Message );
4406
+ emitDeclaredHereIfNeeded (diags, diagLoc, witness);
4407
+ diags.diagnose (requirement, diag::kind_declname_declared_here,
4408
+ DescriptiveDeclKind::Requirement,
4409
+ requirement->getName ());
4410
+ });
4411
+ break ;
4377
4412
}
4378
4413
4379
4414
if (auto *classDecl = DC->getSelfClassDecl ()) {
0 commit comments