Sema: Allow parameterized existential compositions

This commit is contained in:
Slava Pestov
2024-09-25 14:18:14 -04:00
parent 4338a55154
commit 1fa9afc460
5 changed files with 102 additions and 17 deletions

View File

@@ -6002,11 +6002,7 @@ TypeResolver::resolveCompositionType(CompositionTypeRepr *repr,
continue;
}
// FIXME: Support compositions involving parameterized protocol types,
// like 'any Collection<String> & Sendable', etc.
if (ty->is<ParameterizedProtocolType>() &&
!options.isConstraintImplicitExistential() &&
options.getContext() != TypeResolverContext::ExistentialConstraint) {
if (ty->is<ParameterizedProtocolType>()) {
checkMember(tyR->getStartLoc(), ty);
Members.push_back(ty);
continue;

View File

@@ -0,0 +1,61 @@
// RUN: %target-typecheck-verify-swift -disable-availability-checking
func f1(_ s: any Sequence<Int> & Hashable) -> any Sequence<Int> {
return s
}
func f2(_ s: any Sequence<Int> & Hashable) -> any Hashable {
return s
}
func f3(_ s: any Sequence<Int> & Hashable) -> any Sequence {
return s
}
func f4(_ s: any Sequence<Int> & Hashable) -> any Sequence & Hashable {
return s
}
func f5(_ s: any Sequence<Int> & Hashable) -> any Sequence<Int> & Equatable {
return s
}
func f6(_ s: any Sequence<Int> & Hashable) -> any Sequence<String> & Hashable {
return s // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}}
}
func f7(_ s: any Sequence<Int> & Hashable) -> any Sequence<String> {
return s // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}}
}
func f8(_ s: any Collection<Int> & Hashable) -> any Sequence<Int> & Hashable {
return s
}
// https://github.com/swiftlang/swift/issues/71012
protocol A<T> {
associatedtype T
}
protocol B {}
typealias C = A & B
typealias D<T> = A<T> & B
struct Foo: C {
typealias T = Int
}
struct Bar<Value> { // expected-note {{arguments to generic parameter 'Value' ('any C' (aka 'any A & B') and 'any A<Int> & B') are expected to be equal}}
let value: Value
}
struct Baz<U> {
let bar: Bar<any D<U>>
}
func run() {
let foo: any C = Foo()
let bar = Bar(value: foo)
_ = Baz<Int>(bar: bar)
// expected-error@-1 {{cannot convert value of type 'Bar<any C>' (aka 'Bar<any A & B>') to expected argument type 'Bar<any A<Int> & B>'}}
}

View File

@@ -0,0 +1,40 @@
// RUN: %target-swift-emit-silgen -disable-availability-checking %s | %FileCheck %s
protocol P<A> {
associatedtype A
}
protocol Q<B> {
associatedtype B
}
// All of these should have unique mangling.
func overload(_: any P<Int> & Q<String>) {}
func overload(_: any P<Float> & Q<String>) {}
func overload(_: any P & Q<String>) {}
func overload(_: any P<Int> & Q<Bool>) {}
func overload(_: any P<Float> & Q<Bool>) {}
func overload(_: any P & Q<Bool>) {}
func overload(_: any P<Int> & Q) {}
func overload(_: any P<Float> & Q) {}
func overload(_: any P & Q) {}
func overload(_: any P<Int>) {}
func overload(_: any P<Float>) {}
func overload(_: any P) {}
func overload(_: any Q<Bool>) {}
func overload(_: any Q) {}
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSi1AAaCPRts_SS1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P<Int> & Q<String>) -> () {
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSf1AAaCPRts_SS1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P<Float> & Q<String>) -> () {
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSS1BAaDPRts_XPF : $@convention(thin) (@in_guaranteed any P & Q<String>) -> () {
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSi1AAaCPRts_Sb1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P<Int> & Q<Bool>) -> () {
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSf1AAaCPRts_Sb1BAaDPRtsXPF : $@convention(thin) (@in_guaranteed any P<Float> & Q<Bool>) -> () {
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSb1BAaDPRts_XPF : $@convention(thin) (@in_guaranteed any P & Q<Bool>) -> () {
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSi1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P<Int> & Q) -> () {
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_AA1QpSf1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P<Float> & 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<Int>) -> () {
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1P_pSf1AAaCPRts_XPF : $@convention(thin) (@in_guaranteed any P<Float>) -> () {
// 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<Bool>) -> () {
// CHECK-LABEL: sil hidden [ossa] @$s37parameterized_existential_composition8overloadyyAA1Q_pF : $@convention(thin) (@in_guaranteed any Q) -> () {

View File

@@ -506,8 +506,6 @@ do {
func invariant11() -> Struct<${type}>.InnerGeneric<Void>
// 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

View File

@@ -82,16 +82,6 @@ func typeExpr() {
_ = (any Sequence<Int>).self
}
/// Not supported as a protocol composition term for now
protocol SomeProto {}
func protocolCompositionNotSupported1(_: SomeProto & Sequence<Int>) {}
// expected-error@-1 {{non-protocol, non-class type 'Sequence<Int>' cannot be used within a protocol-constrained type}}
func protocolCompositionNotSupported2(_: any SomeProto & Sequence<Int>) {}
// expected-error@-1 {{non-protocol, non-class type 'Sequence<Int>' cannot be used within a protocol-constrained type}}
func increment(_ n : any Collection<Float>) {
for value in n {
_ = value + 1