mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Today ParenType is used: 1. As the type of ParenExpr 2. As the payload type of an unlabeled single associated value enum case (and the type of ParenPattern). 3. As the type for an `(X)` TypeRepr For 1, this leads to some odd behavior, e.g the type of `(5.0 * 5).squareRoot()` is `(Double)`. For 2, we should be checking the arity of the enum case constructor parameters and the presence of ParenPattern respectively. Eventually we ought to consider replacing Paren/TuplePattern with a PatternList node, similar to ArgumentList. 3 is one case where it could be argued that there's some utility in preserving the sugar of the type that the user wrote. However it's really not clear to me that this is particularly desirable since a bunch of diagnostic logic is already stripping ParenTypes. In cases where we care about how the type was written in source, we really ought to be consulting the TypeRepr.
233 lines
4.4 KiB
Swift
233 lines
4.4 KiB
Swift
// RUN: %target-typecheck-verify-swift
|
|
|
|
protocol P1 { associatedtype AssocType }
|
|
protocol P2 : P1 { }
|
|
protocol P3 { }
|
|
|
|
struct X<T : P1, U : P2, V> {
|
|
struct Inner<A, B : P3> { }
|
|
|
|
struct NonGenericInner { }
|
|
}
|
|
|
|
extension Int : P1 {
|
|
typealias AssocType = Int
|
|
}
|
|
|
|
extension Double : P2 {
|
|
typealias AssocType = Double
|
|
}
|
|
|
|
extension X<Int, Double, String> {
|
|
let x = 0
|
|
// expected-error@-1 {{extensions must not contain stored properties}}
|
|
static let x = 0
|
|
func f() -> Int {}
|
|
class C<W> {}
|
|
}
|
|
|
|
typealias GGG = X<Int, Double, String>
|
|
|
|
extension GGG { } // okay through a typealias
|
|
|
|
// Lvalue check when the archetypes are not the same.
|
|
struct LValueCheck<T> {
|
|
let x = 0
|
|
}
|
|
|
|
extension LValueCheck {
|
|
init(newY: Int) {
|
|
x = 42
|
|
}
|
|
}
|
|
|
|
// Member type references into another extension.
|
|
struct MemberTypeCheckA<T> { }
|
|
|
|
protocol MemberTypeProto {
|
|
associatedtype AssocType
|
|
|
|
func foo(_ a: AssocType)
|
|
init(_ assoc: MemberTypeCheckA<AssocType>)
|
|
}
|
|
|
|
struct MemberTypeCheckB<T> : MemberTypeProto {
|
|
func foo(_ a: T) {}
|
|
|
|
typealias Element = T
|
|
var t1: T
|
|
}
|
|
|
|
extension MemberTypeCheckB {
|
|
typealias Underlying = MemberTypeCheckA<T>
|
|
}
|
|
|
|
extension MemberTypeCheckB {
|
|
init(_ x: Underlying) { }
|
|
}
|
|
|
|
extension MemberTypeCheckB {
|
|
var t2: Element { return t1 }
|
|
}
|
|
|
|
// rdar://problem/19795284
|
|
extension Array {
|
|
var pairs: [(Element, Element)] {
|
|
get {
|
|
return []
|
|
}
|
|
}
|
|
}
|
|
|
|
// rdar://problem/21001937
|
|
struct GenericOverloads<T, U> {
|
|
var t: T
|
|
var u: U
|
|
|
|
init(t: T, u: U) { self.t = t; self.u = u }
|
|
|
|
func foo() { }
|
|
|
|
var prop: Int { return 0 }
|
|
|
|
subscript (i: Int) -> Int { return i }
|
|
}
|
|
|
|
extension GenericOverloads where T : P1, U : P2 {
|
|
init(t: T, u: U) { self.t = t; self.u = u }
|
|
|
|
func foo() { }
|
|
|
|
var prop: Int { return 1 }
|
|
|
|
subscript (i: Int) -> Int { return i }
|
|
}
|
|
|
|
extension Array where Element : Hashable { // expected-note {{where 'Element' = 'T'}}
|
|
var worseHashEver: Int {
|
|
var result = 0
|
|
for elt in self {
|
|
result = (result << 1) ^ elt.hashValue
|
|
}
|
|
return result
|
|
}
|
|
}
|
|
|
|
func notHashableArray<T>(_ x: [T]) {
|
|
x.worseHashEver // expected-error{{property 'worseHashEver' requires that 'T' conform to 'Hashable'}}
|
|
}
|
|
|
|
func hashableArray<T : Hashable>(_ x: [T]) {
|
|
// expected-warning @+1 {{unused}}
|
|
x.worseHashEver // okay
|
|
}
|
|
|
|
func intArray(_ x: [Int]) {
|
|
// expected-warning @+1 {{unused}}
|
|
x.worseHashEver
|
|
}
|
|
|
|
class GenericClass<T> { }
|
|
|
|
extension GenericClass where T : Equatable { // expected-note {{where 'T' = 'T'}}
|
|
func foo(_ x: T, y: T) -> Bool { return x == y }
|
|
}
|
|
|
|
func genericClassEquatable<T : Equatable>(_ gc: GenericClass<T>, x: T, y: T) {
|
|
_ = gc.foo(x, y: y)
|
|
}
|
|
|
|
func genericClassNotEquatable<T>(_ gc: GenericClass<T>, x: T, y: T) {
|
|
gc.foo(x, y: y) // expected-error{{referencing instance method 'foo(_:y:)' on 'GenericClass' requires that 'T' conform to 'Equatable'}}
|
|
}
|
|
|
|
|
|
extension Array where Element == String { }
|
|
|
|
extension GenericClass : P3 where T : P3 { }
|
|
|
|
extension GenericClass where Self : P3 { }
|
|
// expected-error@-1{{covariant 'Self' or 'Self?' can only appear as the type of a property, subscript or method result; did you mean 'GenericClass'?}} {{30-34=GenericClass}}
|
|
|
|
protocol P4 {
|
|
associatedtype T
|
|
init(_: T)
|
|
}
|
|
|
|
protocol P5 { }
|
|
|
|
struct S4<Q>: P4 {
|
|
init(_: Q) { }
|
|
}
|
|
|
|
extension S4 where T : P5 {}
|
|
|
|
struct S5<Q> {
|
|
init(_: Q) { }
|
|
}
|
|
|
|
extension S5 : P4 {}
|
|
|
|
// rdar://problem/21607421
|
|
public typealias Array2 = Array
|
|
extension Array2 where QQQ : VVV {}
|
|
// expected-error@-1 {{cannot find type 'QQQ' in scope}}
|
|
// expected-error@-2 {{cannot find type 'VVV' in scope}}
|
|
|
|
// https://github.com/apple/swift/issues/51512
|
|
func foo() {
|
|
extension Array where Element : P1 {
|
|
// expected-error@-1 {{declaration is only valid at file scope}}
|
|
func foo() -> Element.AssocType {}
|
|
}
|
|
}
|
|
|
|
// Deeply nested
|
|
protocol P6 {
|
|
associatedtype Assoc1
|
|
associatedtype Assoc2
|
|
}
|
|
|
|
struct A<T, U, V> {
|
|
struct B<W, X, Y> {
|
|
struct C<Z: P6> {
|
|
}
|
|
}
|
|
}
|
|
|
|
extension A.B.C where T == V, X == Z.Assoc2 {
|
|
func f() { }
|
|
}
|
|
|
|
// Extensions of nested non-generics within generics.
|
|
extension A.B {
|
|
struct D { }
|
|
}
|
|
|
|
extension A.B.D {
|
|
func g() { }
|
|
}
|
|
|
|
// rdar://problem/43955962
|
|
struct OldGeneric<T> {}
|
|
typealias NewGeneric<T> = OldGeneric<T>
|
|
|
|
extension NewGeneric {
|
|
static func oldMember() -> OldGeneric {
|
|
return OldGeneric()
|
|
}
|
|
|
|
static func newMember() -> NewGeneric {
|
|
return NewGeneric()
|
|
}
|
|
}
|
|
extension (NewGeneric) {
|
|
static func oldMember2() -> OldGeneric {
|
|
return OldGeneric()
|
|
}
|
|
|
|
static func newMember2() -> NewGeneric {
|
|
return NewGeneric()
|
|
}
|
|
}
|