mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
When emitting a requirement for a same-type-to-concrete constraint, use the known concrete source for just the first of the component anchors. For the rest, we need to explicitly model the constraint lest it get lost. Fixes rdar://problem/30478915.
216 lines
5.8 KiB
Swift
216 lines
5.8 KiB
Swift
// RUN: %target-typecheck-verify-swift -typecheck %s -verify
|
|
// RUN: %target-typecheck-verify-swift -typecheck -debug-generic-signatures %s > %t.dump 2>&1
|
|
// RUN: %FileCheck %s < %t.dump
|
|
|
|
protocol P1 {
|
|
func p1()
|
|
}
|
|
|
|
protocol P2 : P1 { }
|
|
|
|
|
|
struct X1<T : P1> {
|
|
func getT() -> T { }
|
|
}
|
|
|
|
class X2<T : P1> {
|
|
func getT() -> T { }
|
|
}
|
|
|
|
class X3 { }
|
|
|
|
struct X4<T : X3> {
|
|
func getT() -> T { }
|
|
}
|
|
|
|
struct X5<T : P2> { }
|
|
|
|
// Infer protocol requirements from the parameter type of a generic function.
|
|
func inferFromParameterType<T>(_ x: X1<T>) {
|
|
x.getT().p1()
|
|
}
|
|
|
|
// Infer protocol requirements from the return type of a generic function.
|
|
func inferFromReturnType<T>(_ x: T) -> X1<T> {
|
|
x.p1()
|
|
}
|
|
|
|
// Infer protocol requirements from the superclass of a generic parameter.
|
|
func inferFromSuperclass<T, U : X2<T>>(_ t: T, u: U) -> T {
|
|
t.p1()
|
|
}
|
|
|
|
|
|
// Infer protocol requirements from the parameter type of a constructor.
|
|
struct InferFromConstructor {
|
|
init<T> (x : X1<T>) {
|
|
x.getT().p1()
|
|
}
|
|
}
|
|
|
|
|
|
// Don't infer requirements for outer generic parameters.
|
|
class Fox : P1 {
|
|
func p1() {}
|
|
}
|
|
|
|
class Box<T : Fox> {
|
|
// CHECK-LABEL: .unpack@
|
|
// CHECK-NEXT: Requirements:
|
|
// CHECK-NEXT: τ_0_0 : Fox [explicit]
|
|
func unpack(_ x: X1<T>) {}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Superclass requirements
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Compute meet of two superclass requirements correctly.
|
|
class Carnivora {}
|
|
class Canidae : Carnivora {}
|
|
|
|
struct U<T : Carnivora> {}
|
|
|
|
struct V<T : Canidae> {}
|
|
|
|
// CHECK-LABEL: .inferSuperclassRequirement1@
|
|
// CHECK-NEXT: Requirements:
|
|
// CHECK-NEXT: τ_0_0 : Canidae
|
|
func inferSuperclassRequirement1<T : Carnivora>(_ v: V<T>) {}
|
|
|
|
// CHECK-LABEL: .inferSuperclassRequirement2@
|
|
// CHECK-NEXT: Requirements:
|
|
// CHECK-NEXT: τ_0_0 : Canidae
|
|
func inferSuperclassRequirement2<T : Canidae>(_ v: U<T>) {}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Same-type requirements
|
|
// ----------------------------------------------------------------------------
|
|
|
|
protocol P3 {
|
|
associatedtype P3Assoc : P2
|
|
}
|
|
|
|
protocol P4 {
|
|
associatedtype P4Assoc : P1
|
|
}
|
|
|
|
protocol PCommonAssoc1 {
|
|
associatedtype CommonAssoc
|
|
}
|
|
|
|
protocol PCommonAssoc2 {
|
|
associatedtype CommonAssoc
|
|
}
|
|
|
|
protocol PAssoc {
|
|
associatedtype Assoc
|
|
}
|
|
|
|
struct Model_P3_P4_Eq<T : P3, U : P4> where T.P3Assoc == U.P4Assoc {}
|
|
|
|
// CHECK-LABEL: .inferSameType1@
|
|
// CHECK-NEXT: Requirements:
|
|
// CHECK-NEXT: τ_0_0 : P3 [inferred @ {{.*}}:32]
|
|
// CHECK-NEXT: τ_0_1 : P4 [inferred @ {{.*}}:32]
|
|
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [protocol @ {{.*}}:32]
|
|
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P2 [protocol @ {{.*}}:32]
|
|
func inferSameType1<T, U>(_ x: Model_P3_P4_Eq<T, U>) { }
|
|
|
|
// CHECK-LABEL: .inferSameType2@
|
|
// CHECK-NEXT: Requirements:
|
|
// CHECK-NEXT: τ_0_0 : P3 [inferred]
|
|
// CHECK-NEXT: τ_0_1 : P4 [inferred]
|
|
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P1 [protocol @ {{.*}}requirement_inference.swift:{{.*}}:25]
|
|
// CHECK-NEXT: τ_0_0[.P3].P3Assoc : P2 [protocol @ {{.*}}requirement_inference.swift:{{.*}}:25]
|
|
// CHECK-NEXT: τ_0_0[.P3].P3Assoc == τ_0_1[.P4].P4Assoc [explicit]
|
|
func inferSameType2<T : P3, U : P4>(_: T, _: U) where U.P4Assoc : P2, T.P3Assoc == U.P4Assoc {}
|
|
|
|
// CHECK-LABEL: .inferSameType3@
|
|
// CHECK-NEXT: Requirements:
|
|
// CHECK-NEXT: τ_0_0 : PCommonAssoc1 [inferred]
|
|
// CHECK-NEXT: τ_0_0 : PCommonAssoc2 [explicit @ {{.*}}requirement_inference.swift:{{.*}}:76]
|
|
// CHECK-NEXT: τ_0_0[.PCommonAssoc1].CommonAssoc : P1 [explicit @ {{.*}}requirement_inference.swift:{{.*}}:68]
|
|
// CHECK-NEXT: Potential archetypes
|
|
func inferSameType3<T : PCommonAssoc1>(_: T) where T.CommonAssoc : P1, T : PCommonAssoc2 {}
|
|
|
|
protocol P5 {
|
|
associatedtype Element
|
|
}
|
|
|
|
protocol P6 {
|
|
associatedtype AssocP6 : P5
|
|
}
|
|
|
|
protocol P7 : P6 {
|
|
associatedtype AssocP7: P6
|
|
}
|
|
|
|
// CHECK-LABEL: P7.nestedSameType1()@
|
|
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P7, τ_0_0.AssocP6.Element : P6, τ_0_0.AssocP6.Element == τ_0_0.AssocP7.AssocP6.Element>
|
|
extension P7 where AssocP6.Element : P6,
|
|
AssocP7.AssocP6.Element : P6,
|
|
AssocP6.Element == AssocP7.AssocP6.Element {
|
|
func nestedSameType1() { }
|
|
}
|
|
|
|
protocol P8 {
|
|
associatedtype A
|
|
associatedtype B
|
|
}
|
|
|
|
protocol P9 : P8 {
|
|
associatedtype A
|
|
associatedtype B
|
|
}
|
|
|
|
protocol P10 {
|
|
associatedtype A
|
|
associatedtype C
|
|
}
|
|
|
|
// CHECK-LABEL: sameTypeConcrete1@
|
|
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.A == X3, τ_0_0.B == Int, τ_0_0.C == Int>
|
|
func sameTypeConcrete1<T : P9 & P10>(_: T) where T.A == X3, T.C == T.B, T.C == Int { }
|
|
|
|
// CHECK-LABEL: sameTypeConcrete2@
|
|
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.B == X3, τ_0_0.C == X3>
|
|
func sameTypeConcrete2<T : P9 & P10>(_: T) where T.B : X3, T.C == T.B, T.C == X3 { }
|
|
|
|
// Note: a standard-library-based stress test to make sure we don't inject
|
|
// any additional requirements.
|
|
// CHECK-LABEL: RangeReplaceableCollection.f()@
|
|
// CHECK: <τ_0_0 where τ_0_0 : MutableCollection, τ_0_0 : RangeReplaceableCollection, τ_0_0.SubSequence == MutableRangeReplaceableSlice<τ_0_0>>
|
|
extension RangeReplaceableCollection where
|
|
Self: MutableCollection,
|
|
Self.SubSequence == MutableRangeReplaceableSlice<Self>
|
|
{
|
|
func f() { }
|
|
}
|
|
|
|
// rdar://problem/30478915
|
|
protocol P11 {
|
|
associatedtype A
|
|
}
|
|
|
|
protocol P12 {
|
|
associatedtype B: P11
|
|
}
|
|
|
|
struct X6 { }
|
|
|
|
struct X7 : P11 {
|
|
typealias A = X6
|
|
}
|
|
|
|
struct X8 : P12 {
|
|
typealias B = X7
|
|
}
|
|
|
|
struct X9<T: P12, U: P12> where T.B == U.B {
|
|
// CHECK-LABEL: X9.upperSameTypeConstraint
|
|
// CHECK: Generic signature: <T, U, V where T == X8, U : P12, U.B == X8.B>
|
|
// CHECK: Canonical generic signature: <τ_0_0, τ_0_1, τ_1_0 where τ_0_0 == X8, τ_0_1 : P12, τ_0_1.B == X7>
|
|
func upperSameTypeConstraint<V>(_: V) where T == X8 { }
|
|
}
|