@@ -1653,7 +1653,7 @@ bool WitnessChecker::findBestWitness(
16531653 for (auto match : matches) {
16541654 if (!match.isViable ()) {
16551655 checkedMatches.push_back (match);
1656- } else if (checkWitness (requirement, match).Kind != CheckKind::Availability ) {
1656+ } else if (! checkWitness (requirement, match).isLessAvailable () ) {
16571657 foundCheckedMatch = true ;
16581658 checkedMatches.push_back (match);
16591659 }
@@ -1835,20 +1835,15 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
18351835 if (!match.OptionalAdjustments .empty ())
18361836 return CheckKind::OptionalityConflict;
18371837
1838- auto requiredAccessScope = evaluateOrDefault (
1838+ auto [requiredAccessLevel, mustBeUsableFromInline] = evaluateOrDefault (
18391839 Context.evaluator , ConformanceAccessScopeRequest{DC, Proto},
18401840 std::make_pair (AccessScope::getPublic (), false ));
18411841
18421842 bool isSetter = false ;
1843- if (checkWitnessAccess (DC, requirement, match.Witness , &isSetter)) {
1844- CheckKind kind = (isSetter
1845- ? CheckKind::AccessOfSetter
1846- : CheckKind::Access);
1847-
1848- return RequirementCheck (kind, requiredAccessScope.first );
1849- }
1843+ if (checkWitnessAccess (DC, requirement, match.Witness , &isSetter))
1844+ return RequirementCheck (requiredAccessLevel, isSetter);
18501845
1851- if (requiredAccessScope. second ) {
1846+ if (mustBeUsableFromInline ) {
18521847 bool witnessIsUsableFromInline = match.Witness ->getFormalAccessScope (
18531848 DC, /* usableFromInlineAsPublic*/ true ).isPublic ();
18541849 if (!witnessIsUsableFromInline)
@@ -1858,11 +1853,11 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
18581853 auto requiredAvailability = AvailabilityRange::alwaysAvailable ();
18591854 if (checkWitnessAvailability (requirement, match.Witness ,
18601855 &requiredAvailability)) {
1861- return RequirementCheck (CheckKind::Availability, requiredAvailability);
1856+ return RequirementCheck (requiredAvailability);
18621857 }
18631858
18641859 if (requirement->isUnavailable () && match.Witness ->getDeclContext () == DC) {
1865- return RequirementCheck (CheckKind::Unavailable );
1860+ return RequirementCheck (CheckKind::RequirementUnavailable );
18661861 }
18671862
18681863 // A non-failable initializer requirement cannot be satisfied
@@ -1901,7 +1896,7 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
19011896
19021897 // Allow unavailable nominals or extension to have unavailable witnesses.
19031898 if (!nominalOrExtensionIsUnavailable ())
1904- return CheckKind::WitnessUnavailable ;
1899+ return RequirementCheck ( AvailabilityRange::neverAvailable ()) ;
19051900 }
19061901
19071902 // Warn about deprecated default implementations if the requirement is
@@ -4412,12 +4407,11 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
44124407
44134408 auto check = checkWitness (requirement, best);
44144409
4415- switch (check.Kind ) {
4410+ switch (check.getKind () ) {
44164411 case CheckKind::Success:
44174412 break ;
44184413
4419- case CheckKind::Access:
4420- case CheckKind::AccessOfSetter: {
4414+ case CheckKind::Access: {
44214415 // Swift 4.2 relaxed some rules for protocol witness matching.
44224416 //
44234417 // This meant that it was possible for an optional protocol requirement
@@ -4438,7 +4432,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
44384432 getASTContext ().addDelayedConformanceDiag (Conformance, false ,
44394433 [DC, witness, check, requirement](
44404434 NormalProtocolConformance *conformance) {
4441- auto requiredAccessScope = check.RequiredAccessScope ;
4435+ auto requiredAccessScope = check.getRequiredAccessScope () ;
44424436 AccessLevel requiredAccess =
44434437 requiredAccessScope.requiredAccessForDiagnostics ();
44444438 auto proto = conformance->getProtocol ();
@@ -4448,7 +4442,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
44484442 auto diagKind = protoForcesAccess
44494443 ? diag::witness_not_accessible_proto
44504444 : diag::witness_not_accessible_type;
4451- bool isSetter = ( check.Kind == CheckKind::AccessOfSetter );
4445+ bool isSetter = check.isForSetterAccess ( );
44524446
44534447 auto &diags = DC->getASTContext ().Diags ;
44544448 diags.diagnose (getLocForDiagnosingWitness (conformance, witness),
@@ -4473,25 +4467,46 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
44734467 break ;
44744468
44754469 case CheckKind::Availability: {
4476- getASTContext ().addDelayedConformanceDiag (Conformance, false ,
4477- [witness, requirement, check](
4478- NormalProtocolConformance *conformance) {
4479- // FIXME: The problem may not be the OS version.
4480- ASTContext &ctx = witness->getASTContext ();
4481- auto &diags = ctx.Diags ;
4482- SourceLoc diagLoc = getLocForDiagnosingWitness (conformance, witness);
4483- diags.diagnose (diagLoc, diag::availability_protocol_requires_version,
4484- conformance->getProtocol (), witness,
4485- ctx.getTargetAvailabilityDomain (),
4486- check.RequiredAvailability );
4487- emitDeclaredHereIfNeeded (diags, diagLoc, witness);
4488- diags.diagnose (requirement,
4489- diag::availability_protocol_requirement_here);
4490- });
4470+ if (check.isLessAvailable ()) {
4471+ ASSERT (check.getRequiredAvailabilityRange ().hasMinimumVersion ());
4472+ getASTContext ().addDelayedConformanceDiag (
4473+ Conformance, false ,
4474+ [witness, requirement,
4475+ check](NormalProtocolConformance *conformance) {
4476+ ASTContext &ctx = witness->getASTContext ();
4477+ auto &diags = ctx.Diags ;
4478+ SourceLoc diagLoc =
4479+ getLocForDiagnosingWitness (conformance, witness);
4480+ diags.diagnose (diagLoc,
4481+ diag::availability_protocol_requires_version,
4482+ conformance->getProtocol (), witness,
4483+ ctx.getTargetAvailabilityDomain (),
4484+ check.getRequiredAvailabilityRange ());
4485+ emitDeclaredHereIfNeeded (diags, diagLoc, witness);
4486+ diags.diagnose (requirement,
4487+ diag::availability_protocol_requirement_here);
4488+ });
4489+ } else {
4490+ getASTContext ().addDelayedConformanceDiag (
4491+ Conformance, true ,
4492+ [witness, requirement](NormalProtocolConformance *conformance) {
4493+ auto &diags = witness->getASTContext ().Diags ;
4494+ auto diagLoc = getLocForDiagnosingWitness (conformance, witness);
4495+ // FIXME: [availability] Get the original constraint.
4496+ auto attr = witness->getUnavailableAttr ();
4497+ EncodedDiagnosticMessage EncodedMessage (attr->getMessage ());
4498+ diags.diagnose (diagLoc, diag::witness_unavailable, witness,
4499+ conformance->getProtocol (),
4500+ EncodedMessage.Message );
4501+ emitDeclaredHereIfNeeded (diags, diagLoc, witness);
4502+ diags.diagnose (requirement, diag::requirement_declared_here,
4503+ requirement);
4504+ });
4505+ }
44914506 break ;
44924507 }
44934508
4494- case CheckKind::Unavailable : {
4509+ case CheckKind::RequirementUnavailable : {
44954510 diagnoseOverrideOfUnavailableDecl (
44964511 witness, requirement, requirement->getUnavailableAttr ().value ());
44974512 break ;
@@ -4544,21 +4559,6 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
45444559
45454560 break ;
45464561
4547- case CheckKind::WitnessUnavailable:
4548- getASTContext ().addDelayedConformanceDiag (Conformance, true ,
4549- [witness, requirement](NormalProtocolConformance *conformance) {
4550- auto &diags = witness->getASTContext ().Diags ;
4551- SourceLoc diagLoc = getLocForDiagnosingWitness (conformance, witness);
4552- auto attr = witness->getUnavailableAttr ();
4553- EncodedDiagnosticMessage EncodedMessage (attr->getMessage ());
4554- diags.diagnose (diagLoc, diag::witness_unavailable, witness,
4555- conformance->getProtocol (), EncodedMessage.Message );
4556- emitDeclaredHereIfNeeded (diags, diagLoc, witness);
4557- diags.diagnose (requirement, diag::requirement_declared_here,
4558- requirement);
4559- });
4560- break ;
4561-
45624562 case CheckKind::DefaultWitnessDeprecated:
45634563 getASTContext ().addDelayedConformanceDiag (
45644564 Conformance, /* isError=*/ false ,
@@ -7213,7 +7213,7 @@ DefaultWitnessChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
72137213 // Perform the same checks as conformance witness matching, but silently
72147214 // ignore the candidate instead of diagnosing anything.
72157215 auto check = checkWitness (requirement, best);
7216- if (check.Kind != CheckKind::Success)
7216+ if (check.getKind () != CheckKind::Success)
72177217 return ResolveWitnessResult::ExplicitFailed;
72187218
72197219 // Record the match.
0 commit comments