mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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:
16
CHANGELOG.md
16
CHANGELOG.md
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -439,6 +439,7 @@ UNINTERESTING_FEATURE(GlobalConcurrency)
|
||||
UNINTERESTING_FEATURE(FullTypedThrows)
|
||||
UNINTERESTING_FEATURE(ExistentialAny)
|
||||
UNINTERESTING_FEATURE(InferSendableFromCaptures)
|
||||
UNINTERESTING_FEATURE(ImplicitOpenExistentials)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// MARK: - Experimental Features
|
||||
|
||||
@@ -37,6 +37,7 @@ class SourceManager {
|
||||
}
|
||||
|
||||
/// MARK: Source file management
|
||||
|
||||
extension SourceManager {
|
||||
/// Inserts a new source file into the source manager.
|
||||
///
|
||||
|
||||
@@ -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();
|
||||
|
||||
20
test/Constraints/opened_existentials_feature.swift
Normal file
20
test/Constraints/opened_existentials_feature.swift
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user