Skip to content

Commit c2a7b08

Browse files
committed
Sema: Only diagnose explicit unavailable Clang enum elements.
#77236 caused a source compatibility regression because `extractEnumElement()` does not suppress its diagnostics in the context of pattern matching. Potentially unavailable enum elements should not be diagnosed when pattern matching since the generated code will not retrieve the potentially unavailable element value on versions where it is unavailable. Fixes rdar://138771328.
1 parent 2747057 commit c2a7b08

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

lib/Sema/TypeCheckPattern.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,15 @@ using namespace swift;
3939
static EnumElementDecl *
4040
extractEnumElement(DeclContext *DC, SourceLoc UseLoc,
4141
const VarDecl *constant) {
42-
diagnoseDeclAvailability(constant, UseLoc, nullptr,
43-
ExportContext::forFunctionBody(DC, UseLoc));
42+
auto &ctx = DC->getASTContext();
43+
auto availabilityContext = TypeChecker::availabilityAtLocation(UseLoc, DC);
44+
if (auto unmetRequirement =
45+
checkDeclarationAvailability(constant, DC, availabilityContext)) {
46+
// Only diagnose explicit unavailability.
47+
if (!unmetRequirement->getRequiredNewerAvailabilityRange(ctx))
48+
diagnoseDeclAvailability(constant, UseLoc, nullptr,
49+
ExportContext::forFunctionBody(DC, UseLoc));
50+
}
4451

4552
const FuncDecl *getter = constant->getAccessor(AccessorKind::Get);
4653
if (!getter)

test/ClangImporter/availability_macosx.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
// REQUIRES: OS=macosx
66

7+
import AppKit
78
import Foundation
89
import AvailabilityExtras
910

@@ -14,3 +15,35 @@ func test_unavailable_because_deprecated() {
1415
func test_swift_unavailable_wins() {
1516
unavailableWithOS() // expected-error {{'unavailableWithOS()' is unavailable in Swift}}
1617
}
18+
19+
func bezierPathElementToInteger(_ e: NSBezierPathElement) -> Int {
20+
switch e {
21+
case .moveTo: return 1
22+
case .lineTo: return 2
23+
case .curveTo: return 3 // no error
24+
case .cubicCurveTo: return 3
25+
case .closePath: return 4
26+
case .quadraticCurveTo: return 5
27+
@unknown default: return -1
28+
}
29+
}
30+
31+
func integerToBezierPathElement(_ i: Int) -> NSBezierPathElement {
32+
// expected-note@-1 2 {{add @available attribute to enclosing global function}}
33+
switch i {
34+
case 1:
35+
return .moveTo
36+
case 2:
37+
return .lineTo
38+
case 3:
39+
return .curveTo // expected-error {{'curveTo' is only available in}}
40+
// expected-note@-1 {{add 'if #available' version check}}
41+
case 4:
42+
return .closePath
43+
case 5:
44+
return .quadraticCurveTo // expected-error {{'quadraticCurveTo' is only available in}}
45+
// expected-note@-1 {{add 'if #available' version check}}
46+
default:
47+
fatalError()
48+
}
49+
}

test/Inputs/clang-importer-sdk/usr/include/AppKit.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,12 @@ typedef NSPoint *NSPointPointer;
306306
@interface NSDocument (URL)
307307
@property (copy,nonnull) NSURL *URL;
308308
@end
309+
310+
typedef NS_ENUM(NSUInteger, NSBezierPathElement) {
311+
NSBezierPathElementMoveTo,
312+
NSBezierPathElementLineTo,
313+
NSBezierPathElementCubicCurveTo __attribute__((availability(macosx,introduced=52))),
314+
NSBezierPathElementClosePath,
315+
NSBezierPathElementQuadraticCurveTo __attribute__((availability(macosx,introduced=52))),
316+
NSBezierPathElementCurveTo __attribute__((availability(macosx,introduced=51,deprecated=52,message="Use NSBezierPathElementCubicCurveTo"))) = NSBezierPathElementCubicCurveTo,
317+
};

0 commit comments

Comments
 (0)