File: where_clause_contextually_generic_decls.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (167 lines) | stat: -rw-r--r-- 7,501 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// RUN: %target-typecheck-verify-swift -swift-version 4

func bet() where A : B {} // expected-error {{'where' clause cannot be applied to a non-generic top-level declaration}}

typealias gimel = Int where A : B // expected-error {{'where' clause cannot be applied to a non-generic top-level declaration}}

class dalet where A : B {} // expected-error {{'where' clause cannot be applied to a non-generic top-level declaration}}

struct Where {
  func bet() where A == B {}  // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
  typealias gimel = Int where A : B  // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
  class dalet where A : B {}  // expected-error {{'where' clause on non-generic member declaration requires a generic context}}
}

// Make sure Self: ... is correctly diagnosed in classes

class SelfInGenericClass<T> {
  // expected-error@+1 {{type 'Self' in conformance requirement does not refer to a generic parameter or associated type}}
  func foo() where Self: Equatable { }
  // expected-error@+1 {{generic signature requires types 'Self' and 'Bool' to be the same}}
  func bar() where Self == Bool { }
}

protocol Whereable {
  associatedtype Assoc
  associatedtype Bssoc

  // expected-error@+1 {{instance method requirement 'requirement1()' cannot add constraint 'Self.Assoc: Sequence' on 'Self'}}
  func requirement1() where Assoc: Sequence
  // expected-error@+1 {{instance method requirement 'requirement2()' cannot add constraint 'Self.Bssoc == Never' on 'Self'}}
  func requirement2() where Bssoc == Never
}

extension Whereable {
  // expected-note@+1 {{where 'Self' = 'T1'}}
  static func staticExtensionFunc(arg: Self.Element) -> Self.Element
    where Self: Sequence {
      return arg
  }

  // expected-note@+1 {{where 'Self.Assoc' = 'T1.Assoc', 'Self.Bssoc' = 'T1.Bssoc'}}
  func extensionFunc() where Assoc == Bssoc { }


  // expected-note@+1 {{where 'Self.Assoc' = 'T1.Assoc'}}
  subscript() -> Assoc where Assoc: Whereable {
    fatalError()
  }
}

func testProtocolExtensions<T1, T2, T3, T4>(t1: T1, t2: T2, t3: T3, t4: T4)
  where T1: Whereable,
        T2: Whereable & Sequence,
        T3: Whereable, T3.Assoc == T3.Bssoc,
        T4: Whereable, T4.Assoc: Whereable {
  _ = T1.staticExtensionFunc // expected-error {{static method 'staticExtensionFunc(arg:)' requires that 'T1' conform to 'Sequence'}}
  _ = T2.staticExtensionFunc

  t1.extensionFunc() // expected-error {{instance method 'extensionFunc()' requires the types 'T1.Assoc' and 'T1.Bssoc' be equivalent}}
  t3.extensionFunc()

  _ = t1[] // expected-error {{subscript 'subscript()' requires that 'T1.Assoc' conform to 'Whereable'}}
  _ = t4[]
}

class Class<T> {
  // expected-note@+1 {{where 'T' = 'T}} // expected-note@+1 {{where 'T.Assoc' = 'T.Assoc'}}
  static func staticFunc() where T: Whereable, T.Assoc == Int { }

  // expected-note@+1 {{candidate requires that the types 'T' and 'Bool' be equivalent}}
  func func1() where T == Bool { }
  // FIXME: The rhs type at the end of the error message is not persistent across compilations.
  // expected-note@+1 {{candidate requires that the types 'T' and 'Int' be equivalent (requirement specified as 'T' == }}
  func func1() where T == Int { }

  func func2() where T == Int { } // expected-note {{where 'T' = 'T'}}

  subscript() -> T.Element where T: Sequence { // expected-note {{where 'T' = 'T'}}
    fatalError()
  }
}

extension Class {
  static func staticExtensionFunc() where T: Class<Int> { } // expected-note {{where 'T' = 'T'}}

  subscript(arg: T.Element) -> T.Element where T == Array<Int> {
    fatalError()
  }
}

extension Class where T: Equatable {
  func extensionFunc() where T: Comparable { } // expected-note {{where 'T' = 'T'}}

  // expected-error@+1 {{no type for 'T' can satisfy both 'T == Class<Int>' and 'T : Equatable'}}
  func badRequirement1() where T == Class<Int> { }
}

extension Class where T == Bool {
  // expected-error@+1 {{no type for 'T' can satisfy both 'T == Int' and 'T == Bool'}}
  func badRequirement2() where T == Int { }
}

func testMemberDeclarations<T, U: Comparable>(arg1: Class<T>, arg2: Class<U>) {
  // expected-error@+2 {{static method 'staticFunc()' requires the types 'T.Assoc' and 'Int' be equivalent}}
  // expected-error@+1 {{static method 'staticFunc()' requires that 'T' conform to 'Whereable'}}
  Class<T>.staticFunc()
  Class<T>.staticExtensionFunc() // expected-error {{static method 'staticExtensionFunc()' requires that 'T' inherit from 'Class<Int>'}}
  Class<Class<Int>>.staticExtensionFunc()

  arg1.func1() // expected-error {{no exact matches in call to instance method 'func1'}}
  arg1.func2() // expected-error {{instance method 'func2()' requires the types 'T' and 'Int' be equivalent}}
  arg1.extensionFunc() // expected-error {{instance method 'extensionFunc()' requires that 'T' conform to 'Comparable'}}
  arg2.extensionFunc()
  Class<Int>().func1()
  Class<Int>().func2()

  arg1[] // expected-error {{subscript 'subscript()' requires that 'T' conform to 'Sequence'}}
  _ = Class<Array<Int>>()[Int.zero]
}

// Test nested types and requirements.

struct Container<T> {
  typealias NestedAlias = Bool where T == Int
  // expected-note@-1 {{'NestedAlias' previously declared here}}
  typealias NestedAlias = Bool where T == Bool
  // expected-error@-1 {{invalid redeclaration of 'NestedAlias}}
  typealias NestedAlias2 = T.Magnitude where T: FixedWidthInteger

  typealias NestedAlias3 = T.Element where T: Sequence

  class NestedClass where T: Equatable {}
}

extension Container where T: Sequence {
  struct NestedStruct {}

  struct NestedStruct2 where T.Element: Comparable {
    enum NestedEnum where T.Element == Double {} // expected-note {{requirement specified as 'T.Element' == 'Double' [with T = String]}}
  }

  struct NestedStruct3<U: Whereable> {}
}

extension Container.NestedStruct3 {
  func foo(arg: U) where U.Assoc == T {}
}

_ = Container<String>.NestedAlias2.self // expected-error {{type 'String' does not conform to protocol 'FixedWidthInteger'}}
_ = Container<Container<Bool>>.NestedClass.self // expected-error {{type 'Container<Bool>' does not conform to protocol 'Equatable'}}
_ = Container<Void>.NestedStruct.self // expected-error {{type 'Void' does not conform to protocol 'Sequence'}}
_ = Container<Array<Void>>.NestedStruct2.self // expected-error {{type 'Void' does not conform to protocol 'Comparable'}}
_ = Container<String>.NestedStruct2.NestedEnum.self // expected-error {{'Container<T>.NestedStruct2.NestedEnum' requires the types 'String.Element' (aka 'Character') and 'Double' be equivalent}}
_ = Container<Int>.NestedAlias2.self
_ = Container<Bool>.NestedClass.self
_ = Container<String>.NestedStruct.self
_ = Container<Array<UInt8>>.NestedStruct2.self
_ = Container<Array<Double>>.NestedStruct2.NestedEnum.self

// Make sure the substitution here actually succeeds instead of producing an ErrorType
func sameType<T>(_: T.Type, _: T.Type) {}
sameType(Container<Array<Int>>.NestedAlias3.self, Int.self)
sameType(Container<Array<Bool>>.NestedAlias3.self, Int.self)
// expected-error@-1 {{cannot convert value of type 'Int.Type' to expected argument type 'Container<Array<Bool>>.NestedAlias3.Type' (aka 'Bool.Type')}}

sameType(Container<Array<Int>>.NestedAlias3.self, Bool.self)
// expected-error@-1 {{cannot convert value of type 'Bool.Type' to expected argument type 'Container<Array<Int>>.NestedAlias3.Type' (aka 'Int.Type')}}