Skip to content

Commit e45a29c

Browse files
authored
Merge pull request #59075 from CodaFi/param-etricity
Enable SE-0353 By Default
2 parents 299d109 + b278d74 commit e45a29c

19 files changed

+68
-68
lines changed

CHANGELOG.md

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,26 @@ _**Note:** This is in reverse chronological order, so newer entries are added to
9191

9292
* [SE-0353][]:
9393

94-
Further generalizing the above, protocol-constrained types can also be used with `any`:
94+
Protocols with primary associated types can now be used in existential types,
95+
enabling same-type constraints on those associated types.
96+
97+
```
98+
let strings: any Collection<String> = [ "Hello" ]
99+
```
100+
101+
Note that language features requiring runtime support like dynamic casts
102+
(`is`, `as?`, `as!`), as well as generic usages of parameterized existentials
103+
in generic types (e.g. `Array<any Collection<Int>>`) involve additional
104+
availability checks to use. Back-deploying usages in generic position can be
105+
worked around with a generic type-erasing wrapper struct, which is now much
106+
simpler to implement:
95107

96108
```swift
97-
func findBestGraph(_: [any Graph<Int>]) -> any Graph<Int> {...}
109+
struct AnyCollection<T> {
110+
var wrapped: any Collection<T>
111+
}
112+
113+
let arrayOfCollections: [AnyCollection<T>] = [ /**/ ]
98114
```
99115

100116
* [SE-0358][]:

include/swift/Basic/LangOptions.h

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

329-
/// Enable support for parameterized protocol types in existential
330-
/// position.
331-
bool EnableParameterizedExistentialTypes = false;
332-
333329
/// Enable experimental flow-sensitive concurrent captures.
334330
bool EnableExperimentalFlowSensitiveConcurrentCaptures = false;
335331

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
@@ -456,9 +456,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
456456
Opts.EnableExperimentalNamedOpaqueTypes |=
457457
Args.hasArg(OPT_enable_experimental_named_opaque_types);
458458

459-
Opts.EnableParameterizedExistentialTypes |=
460-
Args.hasArg(OPT_enable_parameterized_existential_types);
461-
462459
Opts.EnableOpenedExistentialTypes =
463460
Args.hasFlag(OPT_enable_experimental_opened_existential_types,
464461
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
// This test requires the new existential shape metadata accessors which are

0 commit comments

Comments
 (0)