Skip to content

Commit 91d73b2

Browse files
committed
Sema: Correctly treat overloads in unavailable extensions as unavailable.
Instead of checking for unavailability attributes directly in the solver, which does not correctly handle members of unavailable extensions, query `checkDeclarationAvailability()` instead. By using the same underlying logic as the availability checker the constraint solver can be confident in the accuracy of this result. Resolves rdar://87403752.
1 parent 26bd056 commit 91d73b2

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4676,20 +4676,14 @@ void ConstraintSystem::diagnoseFailureFor(SyntacticElementTarget target) {
46764676

46774677
bool ConstraintSystem::isDeclUnavailable(const Decl *D,
46784678
ConstraintLocator *locator) const {
4679-
// First check whether this declaration is universally unavailable.
4680-
if (D->getAttrs().isUnavailable(getASTContext()))
4681-
return true;
4682-
4683-
return TypeChecker::isDeclarationUnavailable(D, DC, [&] {
4684-
SourceLoc loc;
4685-
4686-
if (locator) {
4687-
if (auto anchor = locator->getAnchor())
4688-
loc = getLoc(anchor);
4689-
}
4679+
SourceLoc loc;
4680+
if (locator) {
4681+
if (auto anchor = locator->getAnchor())
4682+
loc = getLoc(anchor);
4683+
}
46904684

4691-
return TypeChecker::overApproximateAvailabilityAtLocation(loc, DC);
4692-
});
4685+
auto availabilityContext = TypeChecker::availabilityAtLocation(loc, DC);
4686+
return checkDeclarationAvailability(D, DC, availabilityContext).has_value();
46934687
}
46944688

46954689
bool ConstraintSystem::isConformanceUnavailable(ProtocolConformanceRef conformance,

test/Constraints/availability.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,25 @@ extension Box where T == Int {
6464
// memberwise initializer.
6565
_ = Box(value: 42)
6666
}
67+
68+
// rdar://87403752 - ambiguity with member declared in unavailable extension
69+
struct HasUnavailableExtesion {
70+
}
71+
72+
@available(*, unavailable)
73+
extension HasUnavailableExtesion {
74+
static var foo: Self = HasUnavailableExtesion()
75+
}
76+
77+
func test_contextual_member_with_unavailable_extension() {
78+
struct A {
79+
static var foo: A = A()
80+
}
81+
82+
struct Test {
83+
init(_: A) {}
84+
init(_: HasUnavailableExtesion) {}
85+
}
86+
87+
_ = Test(.foo) // Ok `A.foo` since `foo` from `HasUnavailableExtesion` is unavailable
88+
}

0 commit comments

Comments
 (0)