Skip to content

Commit eefb3a6

Browse files
authored
Merge pull request #59076 from CodaFi/parambulate
[5.7] Enable SE-0353 By Default
2 parents 8e29f27 + e959573 commit eefb3a6

19 files changed

+83
-66
lines changed

CHANGELOG.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,42 @@ _**Note:** This is in reverse chronological order, so newer entries are added to
55

66
## Swift 5.7
77

8+
* [SE-0353][]:
9+
10+
Protocols with primary associated types can now be used in existential types,
11+
enabling same-type constraints on those associated types.
12+
13+
```
14+
let strings: any Collection<String> = [ "Hello" ]
15+
```
16+
17+
Note that language features requiring runtime support like dynamic casts
18+
(`is`, `as?`, `as!`), as well as generic usages of parameterized existentials
19+
in generic types (e.g. `Array<any Collection<Int>>`) involve additional
20+
availability checks to use. Back-deploying usages in generic position can be
21+
worked around with a generic type-erasing wrapper struct, which is now much
22+
simpler to implement:
23+
24+
```swift
25+
struct AnyCollection<T> {
26+
var wrapped: any Collection<T>
27+
}
28+
29+
let arrayOfCollections: [AnyCollection<T>] = [ /**/ ]
30+
```
31+
832
* [SE-0329][]:
933
New types representing time and clocks were introduced. This includes a protocol `Clock` defining clocks which allow for defining a concept of now and a way to wake up after a given instant. Additionally a new protocol `InstantProtocol` for defining instants in time was added. Furthermore a new protocol `DurationProtocol` was added to define an elapsed duration between two given `InstantProtocol` types. Most commonly the `Clock` types for general use are the `SuspendingClock` and `ContinuousClock` which represent the most fundamental clocks for the system. The `SuspendingClock` type does not progress while the machine is suspended whereas the `ContinuousClock` progresses no matter the state of the machine.
1034

35+
* [SE-0309][]:
36+
37+
Protocols with associated types and `Self` requirements can now be used as the
38+
types of values with the `any` keyword.
39+
40+
Protocol methods that return associated types can be called on an `any` type;
41+
the result is type-erased to the associated type's upper bound, which is another
42+
`any` type having the same constraints as the associated type. For example:
43+
1144
```swift
1245
func delayedHello() async throws {
1346
try await Task.sleep(until: .now + .milliseconds(123), clock: .continuous)

include/swift/Basic/LangOptions.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,6 @@ namespace swift {
338338
/// in calls to generic functions.
339339
bool EnableOpenedExistentialTypes = false;
340340

341-
/// Enable support for parameterized protocol types in existential
342-
/// position.
343-
bool EnableParameterizedExistentialTypes = false;
344-
345341
/// Enable experimental flow-sensitive concurrent captures.
346342
bool EnableExperimentalFlowSensitiveConcurrentCaptures = false;
347343

include/swift/Option/FrontendOptions.td

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,10 +543,6 @@ def enable_explicit_existential_types :
543543
Flag<["-"], "enable-explicit-existential-types">,
544544
HelpText<"Enable experimental support for explicit existential types">;
545545

546-
def enable_parameterized_existential_types :
547-
Flag<["-"], "enable-parameterized-existential-types">,
548-
HelpText<"Enable experimental support for parameterized existential types">;
549-
550546
def enable_experimental_opened_existential_types :
551547
Flag<["-"], "enable-experimental-opened-existential-types">,
552548
HelpText<"Enable experimental support for implicitly opened existentials">;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
448448
Opts.EnableExperimentalNamedOpaqueTypes |=
449449
Args.hasArg(OPT_enable_experimental_named_opaque_types);
450450

451-
Opts.EnableParameterizedExistentialTypes |=
452-
Args.hasArg(OPT_enable_parameterized_existential_types);
453-
454451
Opts.EnableOpenedExistentialTypes =
455452
Args.hasFlag(OPT_enable_experimental_opened_existential_types,
456453
OPT_disable_experimental_opened_existential_types,

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
632632
// Build ParameterizedProtocolType if the protocol has a primary associated
633633
// type and we're in a supported context (for now just generic requirements,
634634
// inheritance clause, extension binding).
635-
if (!resolution.getOptions().isParameterizedProtocolSupported(ctx.LangOpts)) {
635+
if (!resolution.getOptions().isParameterizedProtocolSupported()) {
636636
diags.diagnose(loc, diag::parameterized_protocol_not_supported);
637637
return ErrorType::get(ctx);
638638
}

lib/Sema/TypeCheckType.h

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,18 +284,14 @@ class TypeResolutionOptions {
284284
}
285285

286286
/// Whether parameterized protocol types are supported in this context.
287-
///
288-
/// FIXME: Remove LangOptions parameter once EnableParameterizedExistentialTypes
289-
/// staging flag is gone.
290-
bool isParameterizedProtocolSupported(const LangOptions &opts) const {
287+
bool isParameterizedProtocolSupported() const {
291288
switch (context) {
292289
case Context::Inherited:
293290
case Context::ExtensionBinding:
294291
case Context::GenericRequirement:
295-
return true;
296292
case Context::ExistentialConstraint:
297293
case Context::MetatypeBase:
298-
return opts.EnableParameterizedExistentialTypes;
294+
return true;
299295
case Context::None:
300296
case Context::TypeAliasDecl:
301297
case Context::GenericTypeAliasDecl:

test/Constraints/existential_metatypes.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,33 @@ func testP3(_ p: P3, something: Something) {
9090
func testIUOToAny(_ t: AnyObject.Type!) {
9191
let _: Any = t
9292
}
93+
94+
protocol P4<T> {
95+
associatedtype T
96+
}
97+
98+
protocol Q4<T> {
99+
associatedtype T
100+
}
101+
102+
protocol PP4<U>: P4<Self.U.T> {
103+
associatedtype U: P4<U>
104+
}
105+
106+
func parameterizedExistentials() {
107+
var qp: (any Q4<Int>).Type
108+
var pp: (any P4<Int>).Type = qp // expected-error{{cannot convert value of type '(any Q4<Int>).Type' to specified type '(any P4<Int>).Type'}}
109+
110+
var qt: any Q4<Int>.Type
111+
qt = qp // expected-error{{cannot assign value of type '(any Q4<Int>).Type' to type 'any Q4<Int>.Type'}}
112+
qp = qt // expected-error{{cannot assign value of type 'any Q4<Int>.Type' to type '(any Q4<Int>).Type'}}
113+
var pt: any P4<Int>.Type = qt // expected-error{{cannot convert value of type 'any Q4<Int>.Type' to specified type 'any P4<Int>.Type'}}
114+
pt = pp // expected-error{{cannot assign value of type '(any P4<Int>).Type' to type 'any P4<Int>.Type'}}
115+
pp = pt // expected-error{{cannot assign value of type 'any P4<Int>.Type' to type '(any P4<Int>).Type'}}
116+
117+
var ppp: (any PP4<Int>).Type
118+
pp = ppp // expected-error{{cannot assign value of type '(any PP4<Int>).Type' to type '(any P4<Int>).Type'}}
119+
120+
var ppt: any PP4<Int>.Type
121+
pt = ppt
122+
}

test/Constraints/parameterized_existential_metatypes.swift

Lines changed: 0 additions & 31 deletions
This file was deleted.

test/IRGen/existential_shape_metadata.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -emit-ir %s -swift-version 5 -disable-availability-checking -enable-parameterized-existential-types | %IRGenFileCheck %s
1+
// RUN: %target-swift-frontend -emit-ir %s -swift-version 5 -disable-availability-checking | %IRGenFileCheck %s
22

33
// CHECK-LABEL: @"$sl26existential_shape_metadata2Q0_pyxXPXGMq" = linkonce_odr hidden constant
44
// CHECK-SAME: { i32 {{.*}}sub ([[INT]] ptrtoint (i8** @{{[0-9]+}} to [[INT]])

test/Interpreter/parameterized_existentials.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-run-simple-swift(-Xfrontend -enable-parameterized-existential-types -Xfrontend -disable-availability-checking)
1+
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking)
22
// REQUIRES: executable_test
33

44
import StdlibUnittest

test/RemoteAST/parameterized_existentials.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-remoteast-test -enable-parameterized-existential-types -disable-availability-checking %s | %FileCheck %s
1+
// RUN: %target-swift-remoteast-test -disable-availability-checking %s | %FileCheck %s
22

33
// REQUIRES: swift-remoteast-test
44

test/SILGen/parameterized_existentials.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-emit-silgen -module-name parameterized -enable-parameterized-existential-types -disable-availability-checking %s | %FileCheck %s
1+
// RUN: %target-swift-emit-silgen -module-name parameterized -disable-availability-checking %s | %FileCheck %s
22

33
protocol P<T, U, V> {
44
associatedtype T

test/SILOptimizer/cast_folding_parameterized_protocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend %s -emit-sil -enable-parameterized-existential-types -disable-availability-checking -O -o - | %FileCheck %s
1+
// RUN: %target-swift-frontend %s -emit-sil -disable-availability-checking -O -o - | %FileCheck %s
22

33
public protocol P<T> {
44
associatedtype T

test/Sema/availability_parameterized_existential.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -enable-parameterized-existential-types
2-
// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -enable-parameterized-existential-types -typecheck %s 2>&1 | %FileCheck %s '--implicit-check-not=<unknown>:0'
1+
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module
2+
// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -disable-objc-attr-requires-foundation-module -typecheck %s 2>&1 | %FileCheck %s '--implicit-check-not=<unknown>:0'
33

44
// Make sure we do not emit availability errors or warnings when -disable-availability-checking is passed
5-
// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -typecheck -disable-objc-attr-requires-foundation-module -enable-parameterized-existential-types -disable-availability-checking %s 2>&1 | %FileCheck %s '--implicit-check-not=error:'
5+
// RUN: not %target-swift-frontend -target %target-cpu-apple-macosx10.50 -typecheck -disable-objc-attr-requires-foundation-module -disable-availability-checking %s 2>&1 | %FileCheck %s '--implicit-check-not=error:'
66

77
// REQUIRES: OS=macosx
88

test/Serialization/parameterized_protocol.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend -enable-parameterized-existential-types -emit-module %S/Inputs/parameterized_protocol_other.swift -emit-module-path %t/parameterized_protocol_other.swiftmodule
3-
// RUN: %target-typecheck-verify-swift -enable-parameterized-existential-types -I%t
2+
// RUN: %target-swift-frontend -emit-module %S/Inputs/parameterized_protocol_other.swift -emit-module-path %t/parameterized_protocol_other.swiftmodule
3+
// RUN: %target-typecheck-verify-swift -I%t
44

55
import parameterized_protocol_other
66

test/type/opaque_parameterized_existential.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-swift-frontend -enable-parameterized-existential-types -disable-availability-checking -typecheck -verify %s
1+
// RUN: %target-swift-frontend -disable-availability-checking -typecheck -verify %s
22

33
// I do not like nested some type params,
44
// I do not like them Σam-i-am

test/type/parameterized_existential.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on -disable-availability-checking -enable-parameterized-existential-types
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=on -requirement-machine-inferred-signatures=on -disable-availability-checking
22

33
protocol Sequence<Element> {
44
associatedtype Element

test/type/parameterized_protocol.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ protocol Invalid5<Element, Element> {
2929

3030
/// Test semantics
3131

32-
protocol Sequence<Element> {
32+
protocol Sequence<Element> { // expected-note {{'Sequence' declared here}}
3333
associatedtype Element
3434
// expected-note@-1 {{protocol requires nested type 'Element'; do you want to add it?}}
3535
}
@@ -189,17 +189,17 @@ func returnsSequenceOfInt1() -> Sequence<Int> {}
189189
// expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}}
190190

191191
func takesSequenceOfInt2(_: any Sequence<Int>) {}
192-
// expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}}
193192

194193
func returnsSequenceOfInt2() -> any Sequence<Int> {}
195-
// expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}}
196194

197195
func typeExpr() {
198196
_ = Sequence<Int>.self
199197
// expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}}
200198

201199
_ = any Sequence<Int>.self
202-
// expected-error@-1 {{protocol type with type arguments can only be used as a generic constraint}}
200+
// expected-error@-1 {{'self' is not a member type of protocol 'parameterized_protocol.Sequence<Swift.Int>'}}
201+
202+
_ = (any Sequence<Int>).self
203203
}
204204

205205
/// Not supported as a protocol composition term for now

validation-test/compiler_crashers_2_fixed/unsupported_recursive_opaque_conformance.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: not %target-swift-frontend -disable-availability-checking -emit-ir -enable-parameterized-existential-types %s
1+
// RUN: not %target-swift-frontend -disable-availability-checking -emit-ir %s
22

33
protocol P<X, Y> {
44
associatedtype X : P

0 commit comments

Comments
 (0)