Add upcoming feature ImplicitOpenExistentials for SE-0352

To maintain source compatibility, SE-0352 does not open existentials
with "self-conforming" type, such as `any Error` or existentials based
on `@objc` protocols. The proposal specified that this behavior would
change in Swift 6. Implement that behavior change, which can be
enabled prior to Swift 6 with the upcoming feature
`ImplicitOpenExistentials` (as documented in SE-0362).

Fixes #70873 / rdar://120902975.
This commit is contained in:
Doug Gregor
2024-03-01 11:34:16 -08:00
parent f1adf99349
commit 6075de1b62
6 changed files with 47 additions and 3 deletions

View File

@@ -4,6 +4,22 @@
> This is in reverse chronological order, so newer entries are added to the top.
## Swift 6.0
* [SE-0352][]:
The Swift 6 language mode will open existential values with
"self-conforming" types (such as `any Error` or `@objc` protocols)
passed to generic functions. For example:
```swift
func takeError<E: Error>(_ error: E) { }
func passError(error: any Error) {
takeError(error) // Swift 5 does not open `any Error`, Swift 6 does
}
```
This behavior can be enabled prior to the Swift 6 language mode
using the upcoming language feature `ImplicitOpenExistentials`.
* [SE-0422][]:
Non-built-in expression macros can now be used as default arguments that
expand at each call site. For example, a custom `#CurrentFile` macro used as

View File

@@ -129,6 +129,7 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(Extern, 0, "@_extern")
LANGUAGE_FEATURE(ExpressionMacroDefaultArguments, 422, "Expression macro as caller-side default argument")
LANGUAGE_FEATURE(BuiltinStoreRaw, 0, "Builtin.storeRaw")
// Swift 6
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
UPCOMING_FEATURE(ForwardTrailingClosures, 286, 6)
UPCOMING_FEATURE(StrictConcurrency, 0337, 6)
@@ -140,9 +141,11 @@ UPCOMING_FEATURE(InternalImportsByDefault, 409, 6)
UPCOMING_FEATURE(IsolatedDefaultValues, 411, 6)
UPCOMING_FEATURE(GlobalConcurrency, 412, 6)
UPCOMING_FEATURE(FullTypedThrows, 413, 6)
UPCOMING_FEATURE(ExistentialAny, 335, 7)
UPCOMING_FEATURE(InferSendableFromCaptures, 418, 6)
UPCOMING_FEATURE(ImplicitOpenExistentials, 352, 6)
// Swift 7
UPCOMING_FEATURE(ExistentialAny, 335, 7)
EXPERIMENTAL_FEATURE(StaticAssert, false)
EXPERIMENTAL_FEATURE(NamedOpaqueTypes, false)

View File

@@ -439,6 +439,7 @@ UNINTERESTING_FEATURE(GlobalConcurrency)
UNINTERESTING_FEATURE(FullTypedThrows)
UNINTERESTING_FEATURE(ExistentialAny)
UNINTERESTING_FEATURE(InferSendableFromCaptures)
UNINTERESTING_FEATURE(ImplicitOpenExistentials)
// ----------------------------------------------------------------------------
// MARK: - Experimental Features

View File

@@ -37,6 +37,7 @@ class SourceManager {
}
/// MARK: Source file management
extension SourceManager {
/// Inserts a new source file into the source manager.
///

View File

@@ -1578,10 +1578,13 @@ shouldOpenExistentialCallArgument(ValueDecl *callee, unsigned paramIdx,
return std::nullopt;
// If the existential argument conforms to all of protocol requirements on
// the formal parameter's type, don't open.
// the formal parameter's type, don't open unless ImplicitOpenExistentials is
// enabled.
// If all of the conformance requirements on the formal parameter's type
// are self-conforming, don't open.
{
ASTContext &ctx = argTy->getASTContext();
if (!ctx.LangOpts.hasFeature(Feature::ImplicitOpenExistentials)) {
Type existentialObjectType;
if (auto existentialMetaTy = argTy->getAs<ExistentialMetatypeType>())
existentialObjectType = existentialMetaTy->getInstanceType();

View File

@@ -0,0 +1,20 @@
// RUN: %target-typecheck-verify-swift -enable-upcoming-feature ImplicitOpenExistentials
// RUN: %target-typecheck-verify-swift -swift-version 6
#if _runtime(_ObjC)
@objc
protocol X {}
func foo<T: X>(_ val: T.Type) {}
func bar(_ val: X.Type) {
// Only succeeds when we're allowed to open an @objc existential.
foo(val)
}
#endif
func takeError<E: Error>(_ error: E) { }
func passError(error: any Error) {
takeError(error) // okay
}