diff --git a/CHANGELOG.md b/CHANGELOG.md index 92b332daa0593..e5802ca056e0c 100644 --- a/CHANGELOG.md +++ b/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(_ 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 diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index ebf2ba7012aac..a4d3538913713 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -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) diff --git a/lib/AST/FeatureSet.cpp b/lib/AST/FeatureSet.cpp index 7f591f0ffa372..b5ce3dde95a79 100644 --- a/lib/AST/FeatureSet.cpp +++ b/lib/AST/FeatureSet.cpp @@ -439,6 +439,7 @@ UNINTERESTING_FEATURE(GlobalConcurrency) UNINTERESTING_FEATURE(FullTypedThrows) UNINTERESTING_FEATURE(ExistentialAny) UNINTERESTING_FEATURE(InferSendableFromCaptures) +UNINTERESTING_FEATURE(ImplicitOpenExistentials) // ---------------------------------------------------------------------------- // MARK: - Experimental Features diff --git a/lib/ASTGen/Sources/ASTGen/SourceManager.swift b/lib/ASTGen/Sources/ASTGen/SourceManager.swift index 9bf7e2c0054ae..e1a13b7ddad07 100644 --- a/lib/ASTGen/Sources/ASTGen/SourceManager.swift +++ b/lib/ASTGen/Sources/ASTGen/SourceManager.swift @@ -37,6 +37,7 @@ class SourceManager { } /// MARK: Source file management + extension SourceManager { /// Inserts a new source file into the source manager. /// diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 3e8154b539f1c..7003fad42cdfb 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -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()) existentialObjectType = existentialMetaTy->getInstanceType(); diff --git a/test/Constraints/opened_existentials_feature.swift b/test/Constraints/opened_existentials_feature.swift new file mode 100644 index 0000000000000..b1fc362cd11f1 --- /dev/null +++ b/test/Constraints/opened_existentials_feature.swift @@ -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(_ val: T.Type) {} + +func bar(_ val: X.Type) { + // Only succeeds when we're allowed to open an @objc existential. + foo(val) +} +#endif + +func takeError(_ error: E) { } + +func passError(error: any Error) { + takeError(error) // okay +}