From 1fa9afc46007500146815b503bfa2e48dd58a63d Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Wed, 25 Sep 2024 14:18:14 -0400 Subject: [PATCH] Sema: Allow parameterized existential compositions --- lib/Sema/TypeCheckType.cpp | 6 +- ...arameterized_existential_composition.swift | 61 +++++++++++++++++++ ...arameterized_existential_composition.swift | 40 ++++++++++++ .../existential_member_access/basic.swift | 2 - test/type/parameterized_existential.swift | 10 --- 5 files changed, 102 insertions(+), 17 deletions(-) create mode 100644 test/Constraints/parameterized_existential_composition.swift create mode 100644 test/SILGen/parameterized_existential_composition.swift diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index fb4a10055eb..ea57c66aec8 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -6002,11 +6002,7 @@ TypeResolver::resolveCompositionType(CompositionTypeRepr *repr, continue; } - // FIXME: Support compositions involving parameterized protocol types, - // like 'any Collection & Sendable', etc. - if (ty->is() && - !options.isConstraintImplicitExistential() && - options.getContext() != TypeResolverContext::ExistentialConstraint) { + if (ty->is()) { checkMember(tyR->getStartLoc(), ty); Members.push_back(ty); continue; diff --git a/test/Constraints/parameterized_existential_composition.swift b/test/Constraints/parameterized_existential_composition.swift new file mode 100644 index 00000000000..b666d22cb25 --- /dev/null +++ b/test/Constraints/parameterized_existential_composition.swift @@ -0,0 +1,61 @@ +// RUN: %target-typecheck-verify-swift -disable-availability-checking + +func f1(_ s: any Sequence & Hashable) -> any Sequence { + return s +} + +func f2(_ s: any Sequence & Hashable) -> any Hashable { + return s +} + +func f3(_ s: any Sequence & Hashable) -> any Sequence { + return s +} + +func f4(_ s: any Sequence & Hashable) -> any Sequence & Hashable { + return s +} + +func f5(_ s: any Sequence & Hashable) -> any Sequence & Equatable { + return s +} + +func f6(_ s: any Sequence & Hashable) -> any Sequence & Hashable { + return s // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}} +} + +func f7(_ s: any Sequence & Hashable) -> any Sequence { + return s // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}} +} + +func f8(_ s: any Collection & Hashable) -> any Sequence & Hashable { + return s +} + +// https://github.com/swiftlang/swift/issues/71012 + +protocol A { + associatedtype T +} +protocol B {} +typealias C = A & B +typealias D = A & B + +struct Foo: C { + typealias T = Int +} + +struct Bar { // expected-note {{arguments to generic parameter 'Value' ('any C' (aka 'any A & B') and 'any A & B') are expected to be equal}} + let value: Value +} + +struct Baz { + let bar: Bar> +} + +func run() { + let foo: any C = Foo() + let bar = Bar(value: foo) + _ = Baz(bar: bar) + // expected-error@-1 {{cannot convert value of type 'Bar' (aka 'Bar') to expected argument type 'Bar & B>'}} +} \ No newline at end of file diff --git a/test/SILGen/parameterized_existential_composition.swift b/test/SILGen/parameterized_existential_composition.swift new file mode 100644 index 00000000000..e14a3a48a0c --- /dev/null +++ b/test/SILGen/parameterized_existential_composition.swift @@ -0,0 +1,40 @@ +// RUN: %target-swift-emit-silgen -disable-availability-checking %s | %FileCheck %s + +protocol P { + associatedtype A +} + +protocol Q { + associatedtype B +} + +// All of these should have unique mangling. +func overload(_: any P & Q) {} +func overload(_: any P & Q) {} +func overload(_: any P & Q) {} +func overload(_: any P & Q) {} +func overload(_: any P & Q) {} +func overload(_: any P & Q) {} +func overload(_: any P & Q) {} +func overload(_: any P & Q) {} +func overload(_: any P & Q) {} +func overload(_: any P) {} +func overload(_: any P) {} +func overload(_: any P) {} +func overload(_: any Q) {} +func overload(_: any Q) {} + +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSi1AAaCPRts_SS1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P & Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSf1AAaCPRts_SS1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P & Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSS1BAaDPRts_XPF : $@convention(thin) (@in_guaranteed any P & Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSi1AAaCPRts_Sb1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P & Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSf1AAaCPRts_Sb1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P & Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSb1BAaDPRts_XPF : $@convention(thin) (@in_guaranteed any P & Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSi1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P & Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSf1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P & Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpF : $@convention(thin) (@in_guaranteed any P & Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_pSi1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_pSf1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_pF : $@convention(thin) (@in_guaranteed any P) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1Q_pSb1BAaCPRts_XPF : $@convention(thin) (@in_guaranteed any Q) -> () { +// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1Q_pF : $@convention(thin) (@in_guaranteed any Q) -> () { diff --git a/test/decl/protocol/existential_member_access/basic.swift b/test/decl/protocol/existential_member_access/basic.swift index e5590a15347..c9122f4de11 100644 --- a/test/decl/protocol/existential_member_access/basic.swift +++ b/test/decl/protocol/existential_member_access/basic.swift @@ -506,8 +506,6 @@ do { func invariant11() -> Struct<${type}>.InnerGeneric // https://github.com/apple/swift/issues/61934 func invariant12() -> any Sequence<${type}> - // FIXME - // expected-error@+1 {{non-protocol, non-class type 'Sequence<${type}>' cannot be used within a protocol-constrained type}} func invariant13() -> any P & Sequence<${type}> func invariant14() -> (any Sequence<${type}>).Type func invariant15() -> any (P & Class<${type}>).Type diff --git a/test/type/parameterized_existential.swift b/test/type/parameterized_existential.swift index 55032bcf3c6..0d9acb20d1f 100644 --- a/test/type/parameterized_existential.swift +++ b/test/type/parameterized_existential.swift @@ -82,16 +82,6 @@ func typeExpr() { _ = (any Sequence).self } -/// Not supported as a protocol composition term for now - -protocol SomeProto {} - -func protocolCompositionNotSupported1(_: SomeProto & Sequence) {} -// expected-error@-1 {{non-protocol, non-class type 'Sequence' cannot be used within a protocol-constrained type}} - -func protocolCompositionNotSupported2(_: any SomeProto & Sequence) {} -// expected-error@-1 {{non-protocol, non-class type 'Sequence' cannot be used within a protocol-constrained type}} - func increment(_ n : any Collection) { for value in n { _ = value + 1