Skip to content

Commit e089c58

Browse files
authored
Merge pull request #77258 from tshortli/discard-overloads-in-unavailable-extensions-in-constraint-solver
Sema: Correctly treat overloads in unavailable extensions as unavailable
2 parents 5d5a050 + 98b34c6 commit e089c58

File tree

5 files changed

+51
-19
lines changed

5 files changed

+51
-19
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,

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,6 +2206,8 @@ diagnosePotentialUnavailability(const ValueDecl *D, SourceRange ReferenceRange,
22062206
const AvailabilityRange &Availability,
22072207
bool WarnBeforeDeploymentTarget = false) {
22082208
ASTContext &Context = ReferenceDC->getASTContext();
2209+
if (Context.LangOpts.DisableAvailabilityChecking)
2210+
return false;
22092211

22102212
bool IsError;
22112213
{
@@ -3101,8 +3103,6 @@ swift::checkDeclarationAvailability(const Decl *decl,
31013103
const DeclContext *declContext,
31023104
AvailabilityContext availabilityContext) {
31033105
auto &ctx = declContext->getASTContext();
3104-
if (ctx.LangOpts.DisableAvailabilityChecking)
3105-
return std::nullopt;
31063106

31073107
// Generic parameters are always available.
31083108
if (isa<GenericTypeParamDecl>(decl))
@@ -4151,6 +4151,7 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
41514151

41524152
auto *DC = Where.getDeclContext();
41534153
auto &ctx = DC->getASTContext();
4154+
41544155
auto unmetRequirement =
41554156
checkDeclarationAvailability(D, DC, Where.getAvailability());
41564157
auto requiredRange =

stdlib/public/core/Assert.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
/// is called.
4040
@_transparent
4141
@_unavailableInEmbedded
42+
#if $Embedded
43+
@_disfavoredOverload
44+
#endif
4245
public func assert(
4346
_ condition: @autoclosure () -> Bool,
4447
_ message: @autoclosure () -> String = String(),
@@ -99,6 +102,9 @@ public func assert(
99102
/// `precondition(_:_:file:line:)` is called.
100103
@_transparent
101104
@_unavailableInEmbedded
105+
#if $Embedded
106+
@_disfavoredOverload
107+
#endif
102108
public func precondition(
103109
_ condition: @autoclosure () -> Bool,
104110
_ message: @autoclosure () -> String = String(),
@@ -162,6 +168,9 @@ public func precondition(
162168
@inlinable
163169
@inline(__always)
164170
@_unavailableInEmbedded
171+
#if $Embedded
172+
@_disfavoredOverload
173+
#endif
165174
public func assertionFailure(
166175
_ message: @autoclosure () -> String = String(),
167176
file: StaticString = #file, line: UInt = #line
@@ -221,6 +230,9 @@ public func assertionFailure(
221230
/// line number where `preconditionFailure(_:file:line:)` is called.
222231
@_transparent
223232
@_unavailableInEmbedded
233+
#if $Embedded
234+
@_disfavoredOverload
235+
#endif
224236
public func preconditionFailure(
225237
_ message: @autoclosure () -> String = String(),
226238
file: StaticString = #file, line: UInt = #line
@@ -264,6 +276,9 @@ public func preconditionFailure(
264276
/// line number where `fatalError(_:file:line:)` is called.
265277
@_transparent
266278
@_unavailableInEmbedded
279+
#if $Embedded
280+
@_disfavoredOverload
281+
#endif
267282
public func fatalError(
268283
_ message: @autoclosure () -> String = String(),
269284
file: StaticString = #file, line: UInt = #line

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+
}

test/embedded/availability.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ public func universally_unavailable() { }
2222
@_unavailableInEmbedded
2323
public func unused() { } // no error
2424

25-
public struct S1 {}
26-
public struct S2 {}
25+
public struct S1 {} // expected-note {{found this candidate}}
26+
public struct S2 {} // expected-note {{found this candidate}}
2727

2828
@_unavailableInEmbedded
2929
public func has_unavailable_in_embedded_overload(_ s1: S1) { }
@@ -48,11 +48,11 @@ public func available(
4848
@_unavailableInEmbedded
4949
public func also_unavailable_in_embedded(
5050
_ uie: UnavailableInEmbedded, // OK
51-
_ uu: UniverallyUnavailable // FIXME: should be an error
51+
_ uu: UniverallyUnavailable // OK
5252
) {
5353
unavailable_in_embedded() // OK
5454
universally_unavailable() // expected-error {{'universally_unavailable()' is unavailable: always unavailable}}
55-
has_unavailable_in_embedded_overload(.init()) // FIXME: should be ambiguous
55+
has_unavailable_in_embedded_overload(.init()) // expected-error {{ambiguous use of 'init()'}}
5656
has_universally_unavailable_overload(.init()) // not ambiguous, selects available overload
5757
}
5858

0 commit comments

Comments
 (0)