File: near_miss_objc.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 (166 lines) | stat: -rw-r--r-- 7,008 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
// RUN: %target-typecheck-verify-swift -enable-objc-interop

// Test "near misses" where a member of a class or extension thereof
// nearly matches an optional requirement, but does not exactly match.

@objc protocol P1 {
  @objc optional func doSomething(a: Int, b: Double) // expected-note 2{{requirement 'doSomething(a:b:)' declared here}}
}

class C1a : P1 {
  @objc func doSomething(a: Int, c: Double) { }
  // expected-warning@-1{{instance method 'doSomething(a:c:)' nearly matches optional requirement 'doSomething(a:b:)' of protocol 'P1'}}
  // expected-note@-2{{rename to 'doSomething(a:b:)' to satisfy this requirement}}{{34-34=b }}
  // expected-note@-3{{move 'doSomething(a:c:)' to an extension to silence this warning}}
  // expected-note@-4{{make 'doSomething(a:c:)' private to silence this warning}}{{9-9=private }}
}

class C1b : P1 {
}

extension C1b {
  @objc func doSomething(a: Int, c: Double) { } // don't warn
}

class C1c {
}

extension C1c : P1 {
  func doSomething(a: Int, c: Double) { }
  // expected-warning@-1{{instance method 'doSomething(a:c:)' nearly matches optional requirement 'doSomething(a:b:)' of protocol 'P1'}}
  // expected-note@-2{{rename to 'doSomething(a:b:)' to satisfy this requirement}}{{28-28=b }}{{none}}
  // expected-note@-3{{move 'doSomething(a:c:)' to another extension to silence this warning}}
  // expected-note@-4{{make 'doSomething(a:c:)' private to silence this warning}}{{3-3=private }}
}

class C1d : P1 {
  @objc private func doSomething(a: Int, c: Double) { } // don't warn
}

class C1e : P1 {
  @nonobjc func doSomething(a: Int, c: Double) { } // don't warn
}

// Don't try to match an optional requirement against a declaration
// that already satisfies one witness.
@objc protocol P2 {
  @objc optional func doSomething(a: Int, b: Double)
  @objc optional func doSomething(a: Int, d: Double)
}

class C2a : P2 {
  @objc func doSomething(a: Int, b: Double) { } // don't warn: this matches something
}

// Cope with base names that change.
@objc protocol P3 {
  @objc optional func doSomethingWithPriority(_ a: Int, d: Double) // expected-note{{requirement 'doSomethingWithPriority(_:d:)' declared here}}
}

class C3a : P3 {
  func doSomething(priority: Int, d: Double) { }
  // expected-warning@-1{{instance method 'doSomething(priority:d:)' nearly matches optional requirement 'doSomethingWithPriority(_:d:)' of protocol 'P3'}}
  // expected-note@-2{{rename to 'doSomethingWithPriority(_:d:)' to satisfy this requirement}}{{20-20=_ }}
  // expected-note@-3{{move 'doSomething(priority:d:)' to an extension to silence this warning}}
  // expected-note@-4{{make 'doSomething(priority:d:)' private to silence this warning}}{{3-3=private }}
}

@objc protocol P4 {
  @objc optional func doSomething(priority: Int, d: Double) // expected-note{{requirement 'doSomething(priority:d:)' declared here}}
}

class C4a : P4 {
  func doSomethingWithPriority(_ a: Int, d: Double) { }
  // expected-warning@-1{{instance method 'doSomethingWithPriority(_:d:)' nearly matches optional requirement 'doSomething(priority:d:)' of protocol 'P4'}}
  // expected-note@-2{{rename to 'doSomething(priority:d:)' to satisfy this requirement}}{{32-33=priority}}
  // expected-note@-3{{move 'doSomethingWithPriority(_:d:)' to an extension to silence this warning}}
  // expected-note@-4{{make 'doSomethingWithPriority(_:d:)' private to silence this warning}}{{3-3=private }}
}

@objc class SomeClass { }

@objc protocol P5 {
  @objc optional func methodWithInt(_: Int, forSomeClass: SomeClass, dividingDouble: Double)
  // expected-note@-1{{requirement 'methodWithInt(_:forSomeClass:dividingDouble:)' declared here}}
}

class C5a : P5 {
  func method(_: Int, for someClass: SomeClass, dividing double: Double) { }
  // expected-warning@-1{{instance method 'method(_:for:dividing:)' nearly matches optional requirement 'methodWithInt(_:forSomeClass:dividingDouble:)' of protocol 'P5'}}
  // expected-note@-2{{rename to 'methodWithInt(_:forSomeClass:dividingDouble:)' to satisfy this requirement}}{{8-14=methodWithInt}}{{23-26=forSomeClass}}{{49-57=dividingDouble}}{{none}}
  // expected-note@-3{{move 'method(_:for:dividing:)' to an extension to silence this warning}}
  // expected-note@-4{{make 'method(_:for:dividing:)' private to silence this warning}}{{3-3=private }}
}

@objc protocol P6 {
  @objc optional func method(_: Int, for someClass: SomeClass, dividing double: Double)
  // expected-note@-1{{requirement 'method(_:for:dividing:)' declared here}}
}

class C6a : P6 {
  func methodWithInt(_: Int, forSomeClass: SomeClass, dividingDouble: Double) { }
  // expected-warning@-1{{instance method 'methodWithInt(_:forSomeClass:dividingDouble:)' nearly matches optional requirement 'method(_:for:dividing:)' of protocol 'P6'}}
  // expected-note@-2{{rename to 'method(_:for:dividing:)' to satisfy this requirement}}{{8-21=method}}{{30-30=for }}{{55-55=dividing }}{{none}}
  // expected-note@-3{{move 'methodWithInt(_:forSomeClass:dividingDouble:)' to an extension to silence this warning}}
  // expected-note@-4{{make 'methodWithInt(_:forSomeClass:dividingDouble:)' private to silence this warning}}{{3-3=private }}
}

// Use the first note to always describe why it didn't match.
@objc protocol P7 {
  @objc optional func method(foo: Float)
  // expected-note@-1{{requirement 'method(foo:)' declared here}}
}

class C7a : P7 {
  @objc func method(foo: Double) { }
  // expected-warning@-1{{instance method 'method(foo:)' nearly matches optional requirement 'method(foo:)' of protocol 'P7'}}
  // expected-note@-2{{candidate has non-matching type '(Double) -> ()'}}
  // expected-note@-3{{move 'method(foo:)' to an extension to silence this warning}}
  // expected-note@-4{{make 'method(foo:)' private to silence this warning}}
}

// Don't complain about near misses that satisfy other protocol
// requirements.
@objc protocol P8 {
  @objc optional func foo(exactMatch: Int)
}

@objc protocol P9 : P8 {
  @objc optional func foo(nearMatch: Int)
}

class C8Super : P8 { }

class C9Sub : C8Super, P9 {
  func foo(exactMatch: Int) { }
}

// Don't complain about overriding methods that are near misses;
// the user cannot make it satisfy the protocol requirement.
class C10Super {
  func foo(nearMatch: Int) { }
}

class C10Sub : C10Super, P8 {
  override func foo(nearMatch: Int) { }
}

// Be more strict about near misses than we had previously.
@objc protocol P11 {
  @objc optional func foo(wibble: Int)
}

class C11 : P11 {
  func f(waggle: Int) { } // no warning
}

@objc protocol P12 {
  @objc optional var prop: Bool { get set } // expected-note {{requirement 'prop' declared here}}
}
class C12: P12 {
  var prop: Bool { true }
  // expected-warning@-1 {{property 'prop' nearly matches optional requirement 'prop' of protocol 'P12'}}
  // expected-note@-2 {{candidate is not settable, but protocol requires it}}
  // expected-note@-3 {{move 'prop' to an extension to silence this warning}}
  // expected-note@-4 {{make 'prop' private to silence this warning}}
}