Skip to content

[5.6][SE-0309] Disable SE-0309 in Swift 5.6. #41131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -4647,6 +4647,9 @@ ERROR(unchecked_not_inheritance_clause,none,
ERROR(unchecked_not_existential,none,
"'unchecked' attribute cannot apply to non-protocol type %0", (Type))

ERROR(unsupported_existential_type,none,
"protocol %0 can only be used as a generic constraint because it has "
"Self or associated type requirements", (Identifier))
ERROR(any_not_existential,none,
"'any' has no effect on %select{concrete type|type parameter}0 %1",
(bool, Type))
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ namespace swift {
/// keyword.
bool EnableExplicitExistentialTypes = true;

/// Enable experimental support for universal existential types
/// as proposed in SE-0309.
bool EnableExperimentalUniversalExistentials = false;

/// Enable experimental flow-sensitive concurrent captures.
bool EnableExperimentalFlowSensitiveConcurrentCaptures = false;

Expand Down
4 changes: 4 additions & 0 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,10 @@ def enable_explicit_existential_types :
Flag<["-"], "enable-explicit-existential-types">,
HelpText<"Enable experimental support for explicit existential types">;

def enable_experimental_universal_existentials :
Flag<["-"], "enable-experimental-universal-existentials">,
HelpText<"Enable experimental support for universal existential types">;

def enable_deserialization_recovery :
Flag<["-"], "enable-deserialization-recovery">,
HelpText<"Attempt to recover from missing xrefs (etc) in swiftmodules">;
Expand Down
3 changes: 3 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.EnableExplicitExistentialTypes |=
Args.hasArg(OPT_enable_explicit_existential_types);

Opts.EnableExperimentalUniversalExistentials |=
Args.hasArg(OPT_enable_experimental_universal_existentials);

Opts.EnableExperimentalDistributed |=
Args.hasArg(OPT_enable_experimental_distributed);

Expand Down
35 changes: 25 additions & 10 deletions lib/Sema/TypeCheckType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3966,7 +3966,8 @@ class ExistentialTypeVisitor
return false;

// Arbitrary protocol constraints are okay for 'any' types.
if (isa<ExistentialTypeRepr>(T))
if (Ctx.LangOpts.EnableExperimentalUniversalExistentials &&
isa<ExistentialTypeRepr>(T))
return false;

visit(T);
Expand All @@ -3991,16 +3992,23 @@ class ExistentialTypeVisitor
}

void visitIdentTypeRepr(IdentTypeRepr *T) {
if (T->isInvalid() || !Ctx.LangOpts.EnableExplicitExistentialTypes)
if (T->isInvalid())
return;

auto comp = T->getComponentRange().back();
if (auto *proto = dyn_cast_or_null<ProtocolDecl>(comp->getBoundDecl())) {
if (proto->existentialRequiresAny()) {
Ctx.Diags.diagnose(comp->getNameLoc(),
diag::existential_requires_any,
proto->getName())
.limitBehavior(DiagnosticBehavior::Warning);
if (!Ctx.LangOpts.EnableExperimentalUniversalExistentials) {
Ctx.Diags.diagnose(comp->getNameLoc(),
diag::unsupported_existential_type,
proto->getName());
T->setInvalid();
} else if (Ctx.LangOpts.EnableExplicitExistentialTypes) {
Ctx.Diags.diagnose(comp->getNameLoc(),
diag::existential_requires_any,
proto->getName())
.limitBehavior(DiagnosticBehavior::Warning);
}
}
} else if (auto *alias = dyn_cast_or_null<TypeAliasDecl>(comp->getBoundDecl())) {
auto type = Type(alias->getDeclaredInterfaceType()->getDesugaredType());
Expand All @@ -4014,10 +4022,17 @@ class ExistentialTypeVisitor
if (!protoDecl->existentialRequiresAny())
continue;

Ctx.Diags.diagnose(comp->getNameLoc(),
diag::existential_requires_any,
protoDecl->getName())
.limitBehavior(DiagnosticBehavior::Warning);
if (!Ctx.LangOpts.EnableExperimentalUniversalExistentials) {
Ctx.Diags.diagnose(comp->getNameLoc(),
diag::unsupported_existential_type,
protoDecl->getName());
T->setInvalid();
} else if (Ctx.LangOpts.EnableExplicitExistentialTypes) {
Ctx.Diags.diagnose(comp->getNameLoc(),
diag::existential_requires_any,
protoDecl->getName())
.limitBehavior(DiagnosticBehavior::Warning);
}
}
}
return false;
Expand Down
2 changes: 1 addition & 1 deletion test/Generics/function_defs.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift
// RUN: %target-typecheck-verify-swift -enable-experimental-universal-existentials

//===----------------------------------------------------------------------===//
// Type-check function definitions
Expand Down
2 changes: 1 addition & 1 deletion test/decl/nested/protocol.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -parse-as-library
// RUN: %target-typecheck-verify-swift -parse-as-library -enable-experimental-universal-existentials

// Protocols cannot be nested inside other types, and types cannot
// be nested inside protocols
Expand Down
2 changes: 1 addition & 1 deletion test/decl/protocol/conforms/inherited.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift
// RUN: %target-typecheck-verify-swift -enable-experimental-universal-existentials

// Inheritable: method with 'Self' in contravariant position.
protocol P1 {
Expand Down
2 changes: 1 addition & 1 deletion test/decl/protocol/protocols.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -enable-objc-interop
// RUN: %target-typecheck-verify-swift -enable-objc-interop -enable-experimental-universal-existentials
protocol EmptyProtocol { }

protocol DefinitionsInProtocols {
Expand Down
2 changes: 1 addition & 1 deletion test/decl/protocol/protocols_with_self_or_assoc_reqs.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift -disable-availability-checking
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-universal-existentials

//===----------------------------------------------------------------------===//
// Use of protocols with Self or associated type requirements
Expand Down
2 changes: 1 addition & 1 deletion test/decl/protocol/recursive_requirement.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift
// RUN: %target-typecheck-verify-swift -enable-experimental-universal-existentials

// -----

Expand Down
2 changes: 1 addition & 1 deletion test/stmt/foreach.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift
// RUN: %target-typecheck-verify-swift -enable-experimental-universal-existentials

// Bad containers and ranges
struct BadContainer1 {
Expand Down
38 changes: 19 additions & 19 deletions test/type/explicit_existential.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
protocol HasSelfRequirements {
func foo(_ x: Self)

func returnsOwnProtocol() -> any HasSelfRequirements
func returnsOwnProtocol() -> HasSelfRequirements // expected-error {{protocol 'HasSelfRequirements' can only be used as a generic constraint because it has Self or associated type requirements}}
}
protocol Bar {
init()
Expand Down Expand Up @@ -35,10 +35,10 @@ func useCompoAsWhereRequirement<T>(_ x: T) where T: HasSelfRequirements & Bar {}
func useCompoAliasAsWhereRequirement<T>(_ x: T) where T: Compo {}
func useNestedCompoAliasAsWhereRequirement<T>(_ x: T) where T: CompoAssocType.Compo {}

func useAsType(_: any HasSelfRequirements,
_: any HasSelfRequirements & Bar,
_: any Compo,
_: any CompoAssocType.Compo) { }
func useAsType(_: any HasSelfRequirements, // expected-error {{protocol 'HasSelfRequirements' can only be used as a generic constraint because it has Self or associated type requirements}}
_: any HasSelfRequirements & Bar, // expected-error {{protocol 'HasSelfRequirements' can only be used as a generic constraint because it has Self or associated type requirements}}
_: any Compo, // expected-error {{protocol 'HasSelfRequirements' can only be used as a generic constraint because it has Self or associated type requirements}}
_: any CompoAssocType.Compo) { } // expected-error {{protocol 'HasSelfRequirements' can only be used as a generic constraint because it has Self or associated type requirements}}

struct TypeRequirement<T: HasSelfRequirements> {}
struct CompoTypeRequirement<T: HasSelfRequirements & Bar> {}
Expand Down Expand Up @@ -66,7 +66,7 @@ do {

func checkIt(_ js: Any) throws {
switch js {
case let dbl as any HasAssoc:
case let dbl as any HasAssoc: // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}
throw MyError.bad(dbl)

default:
Expand All @@ -75,25 +75,25 @@ do {
}
}

func testHasAssoc(_ x: Any, _: any HasAssoc) {
if let p = x as? any HasAssoc {
func testHasAssoc(_ x: Any, _: any HasAssoc) { // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}
if let p = x as? any HasAssoc { // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}
p.foo()
}

struct ConformingType : HasAssoc {
typealias Assoc = Int
func foo() {}

func method() -> any HasAssoc {}
func method() -> any HasAssoc {} // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}
}
}

var b: any HasAssoc
var b: any HasAssoc // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}

protocol P {}
typealias MoreHasAssoc = HasAssoc & P
func testHasMoreAssoc(_ x: Any) {
if let p = x as? any MoreHasAssoc {
if let p = x as? any MoreHasAssoc { // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}
p.foo()
}
}
Expand All @@ -102,36 +102,36 @@ typealias X = Struct1<any Pub & Bar>
_ = Struct1<any Pub & Bar>.self

typealias AliasWhere<T> = T
where T: HasAssoc, T.Assoc == any HasAssoc
where T: HasAssoc, T.Assoc == any HasAssoc // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}

struct StructWhere<T>
where T: HasAssoc,
T.Assoc == any HasAssoc {}
T.Assoc == any HasAssoc {} // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}

protocol ProtocolWhere where T == any HasAssoc {
protocol ProtocolWhere where T == any HasAssoc { // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}
associatedtype T

associatedtype U: HasAssoc
where U.Assoc == any HasAssoc
where U.Assoc == any HasAssoc // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}
}

extension HasAssoc where Assoc == any HasAssoc {}
extension HasAssoc where Assoc == any HasAssoc {} // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}

func FunctionWhere<T>(_: T)
where T : HasAssoc,
T.Assoc == any HasAssoc {}
T.Assoc == HasAssoc {} // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}

struct SubscriptWhere {
subscript<T>(_: T) -> Int
where T : HasAssoc,
T.Assoc == any HasAssoc {
T.Assoc == HasAssoc { // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}
get {}
set {}
}
}

struct OuterGeneric<T> {
func contextuallyGenericMethod() where T == any HasAssoc {}
func contextuallyGenericMethod() where T == HasAssoc {} // expected-error {{protocol 'HasAssoc' can only be used as a generic constraint because it has Self or associated type requirements}}
}

func testInvalidAny() {
Expand Down
2 changes: 1 addition & 1 deletion test/type/protocol_types.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-typecheck-verify-swift
// RUN: %target-typecheck-verify-swift -enable-experimental-universal-existentials

protocol HasSelfRequirements {
func foo(_ x: Self)
Expand Down
4 changes: 2 additions & 2 deletions utils/build-windows-toolchain.bat
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ cmake ^
-D LLVM_VERSION_SUFFIX="" ^

-D SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY=YES ^
-D SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED=YES ^
-D SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED=NO ^
-D SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING=YES ^
-D SWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING=YES ^

Expand Down Expand Up @@ -229,7 +229,7 @@ cmake ^
-D SWIFT_PATH_TO_LIBDISPATCH_SOURCE=%SourceRoot%\swift-corelibs-libdispatch ^

-D SWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY=YES ^
-D SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED=YES ^
-D SWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED=NO ^
-D SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING=YES ^
-D SWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING=YES ^

Expand Down
2 changes: 1 addition & 1 deletion utils/build-windows.bat
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ cmake^
-DSWIFT_BUILD_SOURCEKIT:BOOL=YES^
-DSWIFT_ENABLE_SOURCEKIT_TESTS:BOOL=YES^
-DSWIFT_ENABLE_EXPERIMENTAL_CONCURRENCY=YES^
-DSWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED=YES^
-DSWIFT_ENABLE_EXPERIMENTAL_DISTRIBUTED=NO^
-DSWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING=YES^
-DSWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING=YES^
-DSWIFT_INSTALL_COMPONENTS="autolink-driver;compiler;clang-resource-dir-symlink;stdlib;sdk-overlay;editor-integration;tools;testsuite-tools;sourcekit-inproc;swift-remote-mirror;swift-remote-mirror-headers"^
Expand Down
2 changes: 1 addition & 1 deletion utils/build_swift/build_swift/driver_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -1188,7 +1188,7 @@ def create_argument_parser():
help='Enable experimental Swift concurrency model.')

option('--enable-experimental-distributed', toggle_true,
default=True,
default=False,
help='Enable experimental Swift distributed actors.')

option('--enable-experimental-string-processing', toggle_true,
Expand Down
2 changes: 1 addition & 1 deletion utils/build_swift/tests/expected_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
'enable_asan': False,
'enable_experimental_differentiable_programming': True,
'enable_experimental_concurrency': True,
'enable_experimental_distributed': True,
'enable_experimental_distributed': False,
'enable_experimental_string_processing': True,
'enable_lsan': False,
'enable_sanitize_coverage': False,
Expand Down