Files
swift-mirror/test/decl/ext/generic.swift
Hamish Knight 2d7500eda6 [AST] Remove ParenType
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.
2024-10-31 11:32:40 +00:00

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()
}
}