mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
SIL: Fix bug in AbstractionPattern::getFunctionThrownErrorType()
When storing a closure with type `() throws(any Error) -> ()` as a fully opaque error, we want to leave it unchanged, instead of re-abstracting it to throw the error indirectly. Thus, we had a special carveout here. However, the carveout was too broad, because if the thrown error type contained type parameters, the resulting AbstractionPattern was invalid. While fixing this I realized this entire hack is unsound in some cases, if you view the same value as a `() throws(U) -> ()` vs an `() -> throws(any Error) -> ()`. Perhaps we should always box the thrown error when maximally abstracting a closure, but that would also be an ABI break. - Fixes https://github.com/swiftlang/swift/issues/84051
This commit is contained in:
@@ -1366,7 +1366,14 @@ AbstractionPattern::getFunctionThrownErrorType(
|
||||
if (!substErrorType)
|
||||
return std::nullopt;
|
||||
|
||||
return std::make_pair(AbstractionPattern(*substErrorType),
|
||||
// FIXME: This is actually unsound. The most opaque form of
|
||||
// `(T) throws(U) -> V` should actually be
|
||||
// `(T) throws(any Error) -> V`.
|
||||
auto pattern = ((*substErrorType)->isErrorExistentialType()
|
||||
? AbstractionPattern(*substErrorType)
|
||||
: AbstractionPattern::getOpaque());
|
||||
|
||||
return std::make_pair(pattern,
|
||||
(*substErrorType)->getCanonicalType());
|
||||
}
|
||||
|
||||
|
||||
8
test/SILGen/keypath_typed_throws.swift
Normal file
8
test/SILGen/keypath_typed_throws.swift
Normal file
@@ -0,0 +1,8 @@
|
||||
// RUN: %target-swift-emit-silgen %s
|
||||
// RUN: %target-swift-emit-silgen %s -enable-library-evolution
|
||||
// RUN: %target-swift-emit-silgen %s -enable-testing
|
||||
// RUN: %target-swift-emit-silgen %s -enable-library-evolution -enable-testing
|
||||
|
||||
public struct Visitor<Node, Failure: Error> {
|
||||
public var visit: (Node) throws(Failure) -> Void
|
||||
}
|
||||
Reference in New Issue
Block a user