@@ -1653,7 +1653,7 @@ bool WitnessChecker::findBestWitness(
1653
1653
for (auto match : matches) {
1654
1654
if (!match.isViable ()) {
1655
1655
checkedMatches.push_back (match);
1656
- } else if (checkWitness (requirement, match).Kind != CheckKind::Availability ) {
1656
+ } else if (! checkWitness (requirement, match).isLessAvailable () ) {
1657
1657
foundCheckedMatch = true ;
1658
1658
checkedMatches.push_back (match);
1659
1659
}
@@ -1835,20 +1835,15 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
1835
1835
if (!match.OptionalAdjustments .empty ())
1836
1836
return CheckKind::OptionalityConflict;
1837
1837
1838
- auto requiredAccessScope = evaluateOrDefault (
1838
+ auto [requiredAccessLevel, mustBeUsableFromInline] = evaluateOrDefault (
1839
1839
Context.evaluator , ConformanceAccessScopeRequest{DC, Proto},
1840
1840
std::make_pair (AccessScope::getPublic (), false ));
1841
1841
1842
1842
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);
1850
1845
1851
- if (requiredAccessScope. second ) {
1846
+ if (mustBeUsableFromInline ) {
1852
1847
bool witnessIsUsableFromInline = match.Witness ->getFormalAccessScope (
1853
1848
DC, /* usableFromInlineAsPublic*/ true ).isPublic ();
1854
1849
if (!witnessIsUsableFromInline)
@@ -1858,11 +1853,11 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
1858
1853
auto requiredAvailability = AvailabilityRange::alwaysAvailable ();
1859
1854
if (checkWitnessAvailability (requirement, match.Witness ,
1860
1855
&requiredAvailability)) {
1861
- return RequirementCheck (CheckKind::Availability, requiredAvailability);
1856
+ return RequirementCheck (requiredAvailability);
1862
1857
}
1863
1858
1864
1859
if (requirement->isUnavailable () && match.Witness ->getDeclContext () == DC) {
1865
- return RequirementCheck (CheckKind::Unavailable );
1860
+ return RequirementCheck (CheckKind::RequirementUnavailable );
1866
1861
}
1867
1862
1868
1863
// A non-failable initializer requirement cannot be satisfied
@@ -1901,7 +1896,7 @@ RequirementCheck WitnessChecker::checkWitness(ValueDecl *requirement,
1901
1896
1902
1897
// Allow unavailable nominals or extension to have unavailable witnesses.
1903
1898
if (!nominalOrExtensionIsUnavailable ())
1904
- return CheckKind::WitnessUnavailable ;
1899
+ return RequirementCheck ( AvailabilityRange::neverAvailable ()) ;
1905
1900
}
1906
1901
1907
1902
// Warn about deprecated default implementations if the requirement is
@@ -4412,12 +4407,11 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
4412
4407
4413
4408
auto check = checkWitness (requirement, best);
4414
4409
4415
- switch (check.Kind ) {
4410
+ switch (check.getKind () ) {
4416
4411
case CheckKind::Success:
4417
4412
break ;
4418
4413
4419
- case CheckKind::Access:
4420
- case CheckKind::AccessOfSetter: {
4414
+ case CheckKind::Access: {
4421
4415
// Swift 4.2 relaxed some rules for protocol witness matching.
4422
4416
//
4423
4417
// This meant that it was possible for an optional protocol requirement
@@ -4438,7 +4432,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
4438
4432
getASTContext ().addDelayedConformanceDiag (Conformance, false ,
4439
4433
[DC, witness, check, requirement](
4440
4434
NormalProtocolConformance *conformance) {
4441
- auto requiredAccessScope = check.RequiredAccessScope ;
4435
+ auto requiredAccessScope = check.getRequiredAccessScope () ;
4442
4436
AccessLevel requiredAccess =
4443
4437
requiredAccessScope.requiredAccessForDiagnostics ();
4444
4438
auto proto = conformance->getProtocol ();
@@ -4448,7 +4442,7 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
4448
4442
auto diagKind = protoForcesAccess
4449
4443
? diag::witness_not_accessible_proto
4450
4444
: diag::witness_not_accessible_type;
4451
- bool isSetter = ( check.Kind == CheckKind::AccessOfSetter );
4445
+ bool isSetter = check.isForSetterAccess ( );
4452
4446
4453
4447
auto &diags = DC->getASTContext ().Diags ;
4454
4448
diags.diagnose (getLocForDiagnosingWitness (conformance, witness),
@@ -4473,25 +4467,46 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
4473
4467
break ;
4474
4468
4475
4469
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
+ }
4491
4506
break ;
4492
4507
}
4493
4508
4494
- case CheckKind::Unavailable : {
4509
+ case CheckKind::RequirementUnavailable : {
4495
4510
diagnoseOverrideOfUnavailableDecl (
4496
4511
witness, requirement, requirement->getUnavailableAttr ().value ());
4497
4512
break ;
@@ -4544,21 +4559,6 @@ ConformanceChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
4544
4559
4545
4560
break ;
4546
4561
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
-
4562
4562
case CheckKind::DefaultWitnessDeprecated:
4563
4563
getASTContext ().addDelayedConformanceDiag (
4564
4564
Conformance, /* isError=*/ false ,
@@ -7213,7 +7213,7 @@ DefaultWitnessChecker::resolveWitnessViaLookup(ValueDecl *requirement) {
7213
7213
// Perform the same checks as conformance witness matching, but silently
7214
7214
// ignore the candidate instead of diagnosing anything.
7215
7215
auto check = checkWitness (requirement, best);
7216
- if (check.Kind != CheckKind::Success)
7216
+ if (check.getKind () != CheckKind::Success)
7217
7217
return ResolveWitnessResult::ExplicitFailed;
7218
7218
7219
7219
// Record the match.
0 commit comments