Skip to content

Commit b68ecdc

Browse files
authored
Merge pull request #74971 from DougGregor/typed-throws-backdeploy-fixes-6.0
[6.0] Typed throws back-deployment fixes
2 parents 9b77dd4 + 210bafc commit b68ecdc

File tree

9 files changed

+92
-3
lines changed

9 files changed

+92
-3
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ class ASTMangler : public Mangler {
8383
/// a critical role.
8484
bool AllowIsolatedAny = true;
8585

86+
/// If enabled, typed throws can be encoded in the mangled name.
87+
/// Suppressing type attributes this way is generally questionable ---
88+
/// for example, it does not interact properly with substitutions ---
89+
/// and should only be done in situations where it is just going to be
90+
/// interpreted as a type and the exact string value does not play
91+
/// a critical role.
92+
bool AllowTypedThrows = true;
93+
8694
/// If enabled, declarations annotated with @_originallyDefinedIn are mangled
8795
/// as if they're part of their original module. Disabled for debug mangling,
8896
/// because lldb wants to find declarations in the modules they're currently

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6688,6 +6688,11 @@ ERROR(availability_isolated_any_only_version_newer, none,
66886688
"%0 %1 or newer",
66896689
(StringRef, llvm::VersionTuple))
66906690

6691+
ERROR(availability_typed_throws_only_version_newer, none,
6692+
"runtime support for typed throws function types is only available in "
6693+
"%0 %1 or newer",
6694+
(StringRef, llvm::VersionTuple))
6695+
66916696
ERROR(availability_variadic_type_only_version_newer, none,
66926697
"parameter packs in generic types are only available in %0 %1 or newer",
66936698
(StringRef, llvm::VersionTuple))

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3055,7 +3055,8 @@ void ASTMangler::appendFunctionSignature(AnyFunctionType *fn,
30553055
if (fn->isSendable())
30563056
appendOperator("Yb");
30573057
if (auto thrownError = fn->getEffectiveThrownErrorType()) {
3058-
if ((*thrownError)->isEqual(fn->getASTContext().getErrorExistentialType())){
3058+
if ((*thrownError)->isEqual(fn->getASTContext().getErrorExistentialType())
3059+
|| !AllowTypedThrows) {
30593060
appendOperator("K");
30603061
} else {
30613062
appendType(*thrownError, sig);

lib/IRGen/IRGenMangler.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,18 +161,23 @@ IRGenMangler::mangleTypeForReflection(IRGenModule &IGM,
161161
llvm::SaveAndRestore<bool> savedConcurrencyStandardSubstitutions(
162162
AllowConcurrencyStandardSubstitutions);
163163
llvm::SaveAndRestore<bool> savedIsolatedAny(AllowIsolatedAny);
164+
llvm::SaveAndRestore<bool> savedTypedThrows(AllowTypedThrows);
164165
if (auto runtimeCompatVersion = getSwiftRuntimeCompatibilityVersionForTarget(
165166
ctx.LangOpts.Target)) {
167+
166168
if (*runtimeCompatVersion < llvm::VersionTuple(5, 5))
167169
AllowConcurrencyStandardSubstitutions = false;
168170

169-
// Suppress @isolated(any) if we're mangling for pre-6.0 runtimes.
171+
// Suppress @isolated(any) and typed throws if we're mangling for pre-6.0
172+
// runtimes.
170173
// This is unprincipled but, because of the restrictions in e.g.
171174
// mangledNameIsUnknownToDeployTarget, should only happen when
172175
// mangling for certain reflective uses where we have to hope that
173176
// the exact type identity is generally unimportant.
174-
if (*runtimeCompatVersion < llvm::VersionTuple(6, 0))
177+
if (*runtimeCompatVersion < llvm::VersionTuple(6, 0)) {
175178
AllowIsolatedAny = false;
179+
AllowTypedThrows = false;
180+
}
176181
}
177182

178183
llvm::SaveAndRestore<bool> savedAllowStandardSubstitutions(

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3031,6 +3031,15 @@ static bool diagnoseIsolatedAnyAvailability(
30313031
ReferenceDC);
30323032
}
30333033

3034+
static bool diagnoseTypedThrowsAvailability(
3035+
SourceRange ReferenceRange, const DeclContext *ReferenceDC) {
3036+
return TypeChecker::checkAvailability(
3037+
ReferenceRange,
3038+
ReferenceDC->getASTContext().getTypedThrowsAvailability(),
3039+
diag::availability_typed_throws_only_version_newer,
3040+
ReferenceDC);
3041+
}
3042+
30343043
static bool checkTypeMetadataAvailabilityInternal(CanType type,
30353044
SourceRange refLoc,
30363045
const DeclContext *refDC) {
@@ -3041,6 +3050,8 @@ static bool checkTypeMetadataAvailabilityInternal(CanType type,
30413050
auto isolation = fnType->getIsolation();
30423051
if (isolation.isErased())
30433052
return diagnoseIsolatedAnyAvailability(refLoc, refDC);
3053+
if (fnType.getThrownError())
3054+
return diagnoseTypedThrowsAvailability(refLoc, refDC);
30443055
}
30453056
return false;
30463057
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %target-swift-frontend -emit-ir -target %target-cpu-apple-macos99.99 %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-PRESENT %s
2+
// RUN: %target-swift-frontend -emit-ir -target %target-cpu-apple-macos14.4 %s | %FileCheck --check-prefix=CHECK --check-prefix=CHECK-SUPPRESSED %s
3+
4+
// REQUIRES: OS=macosx
5+
// UNSUPPORTED: CPU=arm64e
6+
7+
// Make sure that a dangling-based type description involving typed throws is
8+
// only used when deploying to runtimes that support it.
9+
10+
// Closure capture metadata:
11+
12+
enum MyError: Error {
13+
case fail
14+
}
15+
16+
// CHECK-LABEL: @"\01l__swift5_reflection_descriptor" = private constant
17+
// CHECK-PRESENT-SAME: ptr @"symbolic Si_____Ieghdzo_ 32reflection_metadata_typed_throws7MyErrorO"
18+
// CHECK-SUPPRESSED-SAME: ptr @"symbolic Si_____Ieghdzo_ 32reflection_metadata_typed_throws7MyErrorO"
19+
// CHECK-LABEL: @metadata = private constant %swift.full_boxmetadata { {{.*}}, ptr @"\01l__swift5_reflection_descriptor" }, align
20+
func makeClosure(fn: @escaping @Sendable () throws(MyError) -> Int) -> (() throws(MyError) -> Int) {
21+
return { try fn() + 1 }
22+
}
23+
24+
// Struct field metadata:
25+
26+
public struct MyStruct {
27+
let fn: () throws (MyError) -> ()
28+
}
29+
30+
// CHECK-LABEL: @"$s32reflection_metadata_typed_throws8MyStructVMF" = internal constant
31+
// CHECK-PRESENT-SAME: ptr @"symbolic yy_____YKc 32reflection_metadata_typed_throws7MyErrorO"
32+
// CHECK-SUPPRESSED-SAME: ptr @"get_type_metadata yy32reflection_metadata_typed_throws7MyErrorOYKc.1"

test/IRGen/typed_throws.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ public enum MyBigError: Error {
1313

1414

1515
// CHECK-MANGLE: @"$s12typed_throws1XVAA1PAAWP" = hidden global [2 x ptr] [ptr @"$s12typed_throws1XVAA1PAAMc", ptr getelementptr inbounds (i8, ptr @"symbolic ySi_____YKc 12typed_throws10MyBigErrorO", {{i32|i64}} 1)]
16+
@available(SwiftStdlib 6.0, *)
1617
struct X: P {
1718
typealias A = (Int) throws(MyBigError) -> Void
1819
}
1920

2021
func requiresP<T: P>(_: T.Type) { }
22+
23+
@available(SwiftStdlib 6.0, *)
2124
func createsP() {
2225
requiresP(X.self)
2326
}
@@ -27,6 +30,7 @@ func createsP() {
2730

2831

2932
// CHECK-LABEL: define {{.*}}hidden swiftcc ptr @"$s12typed_throws13buildMetatypeypXpyF"()
33+
@available(SwiftStdlib 6.0, *)
3034
func buildMetatype() -> Any.Type {
3135
typealias Fn = (Int) throws(MyBigError) -> Void
3236

test/Parse/typed_throws.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func testClosures() {
2020
let _ = { (x: Int, y: Int) throws(MyError) -> Int in x + y }
2121
}
2222

23+
@available(SwiftStdlib 6.0, *)
2324
func testTypes() {
2425
let _ = [(Int, Int) throws(MyError) -> Int]()
2526
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5 -module-name test
2+
3+
// REQUIRES: OS=macosx
4+
5+
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macos14.4
6+
7+
enum MyError: Error {
8+
case fail
9+
}
10+
11+
func bad() -> Any.Type {
12+
// expected-note@-1{{add @available attribute to enclosing global function}}
13+
typealias Fn = () throws(MyError) -> ()
14+
// expected-error@+2{{runtime support for typed throws function types is only available in macOS 15.0.0 or newer}}
15+
// expected-note@+1{{add 'if #available' version check}}
16+
return Fn.self
17+
}
18+
19+
func good() -> Any.Type {
20+
typealias Fn = () throws(any Error) -> ()
21+
return Fn.self
22+
}

0 commit comments

Comments
 (0)