Skip to content

Commit d90117b

Browse files
committed
[Diagnostics] Remove argument handling from conformance failures
Argument-to-Parameter mismatch handles conformance failures related to arguments, so the logic in `MissingConformanceFailure` which wasn't entirely correct is now completely obsolete. Resolves: rdar://problem/56234611
1 parent 36c5c2f commit d90117b

19 files changed

+66
-90
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -542,26 +542,11 @@ void RequirementFailure::emitRequirementNote(const Decl *anchor, Type lhs,
542542

543543
bool MissingConformanceFailure::diagnoseAsError() {
544544
auto *anchor = getAnchor();
545-
auto ownerType = getOwnerType();
546545
auto nonConformingType = getLHS();
547546
auto protocolType = getRHS();
548547

549-
auto getArgumentAt = [](const ApplyExpr *AE, unsigned index) -> Expr * {
550-
assert(AE);
551-
552-
auto *arg = AE->getArg();
553-
if (auto *TE = dyn_cast<TupleExpr>(arg))
554-
return TE->getElement(index);
555-
556-
assert(index == 0);
557-
if (auto *PE = dyn_cast<ParenExpr>(arg))
558-
return PE->getSubExpr();
559-
560-
return arg;
561-
};
562-
563548
// If this is a requirement of a pattern-matching operator,
564-
// let's see whether argument is already has a fix associated
549+
// let's see whether argument already has a fix associated
565550
// with it and if so skip conformance error, otherwise we'd
566551
// produce an unrelated `<type> doesn't conform to Equatable protocol`
567552
// diagnostic.
@@ -588,43 +573,14 @@ bool MissingConformanceFailure::diagnoseAsError() {
588573
if (diagnoseAsAmbiguousOperatorRef())
589574
return true;
590575

591-
Optional<unsigned> atParameterPos;
592-
// Sometimes fix is recorded by type-checking sub-expression
593-
// during normal diagnostics, in such case call expression
594-
// is unavailable.
595-
if (Apply) {
596-
if (auto *fnType = ownerType->getAs<AnyFunctionType>()) {
597-
auto parameters = fnType->getParams();
598-
for (auto index : indices(parameters)) {
599-
if (parameters[index].getOldType()->isEqual(nonConformingType)) {
600-
atParameterPos = index;
601-
break;
602-
}
603-
}
604-
}
605-
}
606-
607576
if (nonConformingType->isObjCExistentialType()) {
608577
emitDiagnostic(anchor->getLoc(), diag::protocol_does_not_conform_static,
609578
nonConformingType, protocolType);
610579
return true;
611580
}
612581

613-
if (diagnoseTypeCannotConform((atParameterPos ?
614-
getArgumentAt(Apply, *atParameterPos) : anchor),
615-
nonConformingType, protocolType)) {
616-
return true;
617-
}
618-
619-
if (atParameterPos) {
620-
// Requirement comes from one of the parameter types,
621-
// let's try to point diagnostic to the argument expression.
622-
auto *argExpr = getArgumentAt(Apply, *atParameterPos);
623-
emitDiagnostic(argExpr->getLoc(),
624-
diag::cannot_convert_argument_value_protocol,
625-
nonConformingType, protocolType);
582+
if (diagnoseTypeCannotConform(anchor, nonConformingType, protocolType))
626583
return true;
627-
}
628584

629585
// If none of the special cases could be diagnosed,
630586
// let's fallback to the most general diagnostic.

test/ClangImporter/newtype_conformance.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ import MoreSwiftNewtypes
1313

1414
func acceptEquatable<T: Equatable>(_: T) {}
1515
func acceptHashable<T: Hashable>(_: T) {}
16+
// expected-note@-1 {{where 'T' = 'WrappedRef'}}
17+
// expected-note@-2 {{where 'T' = 'WrappedValue'}}
1618
func acceptComparable<T: Comparable>(_: T) {}
19+
// expected-note@-1 {{where 'T' = 'NSNotification.Name'}}
1720

1821
func testNewTypeWrapper(x: NSNotification.Name, y: NSNotification.Name) {
1922
acceptEquatable(x)
2023
acceptHashable(x)
21-
acceptComparable(x) // expected-error {{does not conform to expected type 'Comparable'}}
24+
acceptComparable(x) // expected-error {{global function 'acceptComparable' requires that 'NSNotification.Name' conform to 'Comparable'}}
2225

2326
_ = x == y
2427
_ = x != y
@@ -30,6 +33,6 @@ func testNewTypeWrapper(x: NSNotification.Name, y: NSNotification.Name) {
3033
func testCustomWrappers(wrappedRef: WrappedRef, wrappedValue: WrappedValue) {
3134
acceptEquatable(wrappedRef)
3235
acceptEquatable(wrappedValue)
33-
acceptHashable(wrappedRef) // expected-error {{does not conform to expected type 'Hashable'}}
34-
acceptHashable(wrappedValue) // expected-error {{does not conform to expected type 'Hashable'}}
36+
acceptHashable(wrappedRef) // expected-error {{global function 'acceptHashable' requires that 'WrappedRef' conform to 'Hashable'}}
37+
acceptHashable(wrappedValue) // expected-error {{global function 'acceptHashable' requires that 'WrappedValue' conform to 'Hashable'}}
3538
}

test/Constraints/diagnostics.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func f5<T : P2>(_ : T) { }
3131
// expected-note@-1 {{required by global function 'f5' where 'T' = '(Int) -> Int'}}
3232
// expected-note@-2 {{required by global function 'f5' where 'T' = '(Int, String)'}}
3333
// expected-note@-3 {{required by global function 'f5' where 'T' = 'Int.Type'}}
34+
// expected-note@-4 {{where 'T' = 'Int'}}
3435

3536
func f6<T : P, U : P>(_ t: T, _ u: U) where T.SomeType == U.SomeType {}
3637

@@ -75,10 +76,10 @@ i.wobble() // expected-error{{value of type 'Int' has no member 'wobble'}}
7576

7677
// Generic member does not conform.
7778
extension Int {
78-
func wibble<T: P2>(_ x: T, _ y: T) -> T { return x }
79+
func wibble<T: P2>(_ x: T, _ y: T) -> T { return x } // expected-note {{where 'T' = 'Int'}}
7980
func wubble<T>(_ x: (Int) -> T) -> T { return x(self) }
8081
}
81-
i.wibble(3, 4) // expected-error {{argument type 'Int' does not conform to expected type 'P2'}}
82+
i.wibble(3, 4) // expected-error {{instance method 'wibble' requires that 'Int' conform to 'P2'}}
8283

8384
// Generic member args correct, but return type doesn't match.
8485
struct A : P2 {
@@ -98,9 +99,9 @@ func f7() -> (c: Int, v: A) {
9899
return f6(g) // expected-error {{cannot convert return expression of type '(c: Int, i: A)' to return type '(c: Int, v: A)'}}
99100
}
100101

101-
func f8<T:P2>(_ n: T, _ f: @escaping (T) -> T) {}
102+
func f8<T:P2>(_ n: T, _ f: @escaping (T) -> T) {} // expected-note {{where 'T' = 'Int'}}
102103
// expected-note@-1 {{required by global function 'f8' where 'T' = 'Tup' (aka '(Int, Double)')}}
103-
f8(3, f4) // expected-error {{argument type 'Int' does not conform to expected type 'P2'}}
104+
f8(3, f4) // expected-error {{global function 'f8' requires that 'Int' conform to 'P2'}}
104105
typealias Tup = (Int, Double)
105106
func f9(_ x: Tup) -> Tup { return x }
106107
f8((1,2.0), f9) // expected-error {{type 'Tup' (aka '(Int, Double)') cannot conform to 'P2'; only struct/enum/class types can conform to protocols}}
@@ -111,7 +112,7 @@ f8((1,2.0), f9) // expected-error {{type 'Tup' (aka '(Int, Double)') cannot conf
111112
"awfawf".doesntExist(0) // expected-error {{value of type 'String' has no member 'doesntExist'}}
112113

113114
// Does not conform to protocol.
114-
f5(i) // expected-error {{argument type 'Int' does not conform to expected type 'P2'}}
115+
f5(i) // expected-error {{global function 'f5' requires that 'Int' conform to 'P2'}}
115116

116117
// Make sure we don't leave open existentials when diagnosing.
117118
// <rdar://problem/20598568>

test/Constraints/generics.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
infix operator +++
44

5-
protocol ConcatToAnything {
5+
protocol ConcatToAnything { // expected-note {{where 'Self' = 'U'}}
66
static func +++ <T>(lhs: Self, other: T)
77
}
88

@@ -14,7 +14,7 @@ func min<T : Comparable>(_ x: T, y: T) -> T {
1414
func weirdConcat<T : ConcatToAnything, U>(_ t: T, u: U) {
1515
t +++ u
1616
t +++ 1
17-
u +++ t // expected-error{{argument type 'U' does not conform to expected type 'ConcatToAnything'}}
17+
u +++ t // expected-error{{referencing operator function '+++' on 'ConcatToAnything' requires that 'U' conform to 'ConcatToAnything'}}
1818
}
1919

2020
// Make sure that the protocol operators don't get in the way.
@@ -647,7 +647,7 @@ struct BottleLayout {
647647
}
648648
let arr = [BottleLayout]()
649649
let layout = BottleLayout(count:1)
650-
let ix = arr.firstIndex(of:layout) // expected-error {{argument type 'BottleLayout' does not conform to expected type 'Equatable'}}
650+
let ix = arr.firstIndex(of:layout) // expected-error {{referencing instance method 'firstIndex(of:)' on 'Collection' requires that 'BottleLayout' conform to 'Equatable'}}
651651

652652
let _: () -> UInt8 = { .init("a" as Unicode.Scalar) } // expected-error {{missing argument label 'ascii:' in call}}
653653

test/Constraints/protocols.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,3 +414,10 @@ func rdar_50512161() {
414414
foo(item: item) // expected-error {{generic parameter 'I' could not be inferred}}
415415
}
416416
}
417+
418+
// SR-11609: Compiler crash on missing conformance for default param
419+
func test_sr_11609() {
420+
func foo<T : Initable>(_ x: T = .init()) -> T { x } // expected-note {{where 'T' = 'String'}}
421+
let _: String = foo()
422+
// expected-error@-1 {{local function 'foo' requires that 'String' conform to 'Initable'}}
423+
}

test/Constraints/rdar40002266.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ import Foundation
66
struct S {
77
init<T: NSNumber>(_ num: T) { // expected-note {{where 'T' = 'Bool'}}
88
self.init(num != 0) // expected-error {{initializer 'init(_:)' requires that 'Bool' inherit from 'NSNumber'}}
9-
// expected-error@-1 {{argument type 'T' does not conform to expected type 'BinaryInteger'}}
9+
// expected-error@-1 {{referencing operator function '!=' on 'BinaryInteger' requires that 'T' conform to 'BinaryInteger'}}
1010
}
1111
}

test/Constraints/tuple.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ variadicWithTrailingClosure(fn: +)
181181
func gcd_23700031<T>(_ a: T, b: T) {
182182
var a = a
183183
var b = b
184-
(a, b) = (b, a % b) // expected-error {{argument type 'T' does not conform to expected type 'BinaryInteger'}}
184+
(a, b) = (b, a % b) // expected-error {{protocol 'BinaryInteger' requires that 'T' conform to 'BinaryInteger'}}
185185
}
186186

187187
// <rdar://problem/24210190>

test/Generics/deduction.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ protocol IsBefore {
194194
func isBefore(_ other: Self) -> Bool
195195
}
196196

197-
func min2<T : IsBefore>(_ x: T, _ y: T) -> T {
197+
func min2<T : IsBefore>(_ x: T, _ y: T) -> T { // expected-note {{where 'T' = 'Float'}}
198198
if y.isBefore(x) { return y }
199199
return x
200200
}
@@ -205,7 +205,7 @@ extension Int : IsBefore {
205205

206206
func callMin(_ x: Int, y: Int, a: Float, b: Float) {
207207
_ = min2(x, y)
208-
min2(a, b) // expected-error{{argument type 'Float' does not conform to expected type 'IsBefore'}}
208+
min2(a, b) // expected-error{{global function 'min2' requires that 'Float' conform to 'IsBefore'}}
209209
}
210210

211211
func rangeOfIsBefore<R : IteratorProtocol>(_ range: R) where R.Element : IsBefore {} // expected-note {{where 'R.Element' = 'IndexingIterator<[Double]>.Element' (aka 'Double')}}
@@ -241,11 +241,11 @@ genericInheritsA(C_GI())
241241
//===----------------------------------------------------------------------===//
242242
// Deduction for member operators
243243
//===----------------------------------------------------------------------===//
244-
protocol Addable {
244+
protocol Addable { // expected-note {{where 'Self' = 'U'}}
245245
static func +(x: Self, y: Self) -> Self
246246
}
247247
func addAddables<T : Addable, U>(_ x: T, y: T, u: U) -> T {
248-
u + u // expected-error{{argument type 'U' does not conform to expected type 'Addable'}}
248+
u + u // expected-error{{protocol 'Addable' requires that 'U' conform to 'Addable'}}
249249
return x+y
250250
}
251251

@@ -314,7 +314,7 @@ func foo() {
314314
for i in min(1,2) { // expected-error{{type 'Int' does not conform to protocol 'Sequence'}}
315315
}
316316
let j = min(Int(3), Float(2.5)) // expected-error{{cannot convert value of type 'Float' to expected argument type 'Int'}}
317-
let k = min(A(), A()) // expected-error{{argument type 'A' does not conform to expected type 'Comparable'}}
317+
let k = min(A(), A()) // expected-error{{global function 'min' requires that 'A' conform to 'Comparable'}}
318318
let oi : Int? = 5
319319
let l = min(3, oi) // expected-error{{value of optional type 'Int?' must be unwrapped}}
320320
// expected-note@-1{{coalesce}}

test/Generics/unbound.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ class SomeClassWithInvalidMethod {
5959
// <rdar://problem/20792596> QoI: Cannot invoke with argument list (T), expected an argument list of (T)
6060
protocol r20792596P {}
6161

62-
func foor20792596<T: r20792596P>(x: T) -> T {
62+
func foor20792596<T: r20792596P>(x: T) -> T { // expected-note {{where 'T' = 'T'}}
6363
return x
6464
}
6565

6666
func callfoor20792596<T>(x: T) -> T {
6767
return foor20792596(x)
6868
// expected-error@-1 {{missing argument label 'x:' in call}}
69-
// expected-error@-2 {{argument type 'T' does not conform to expected type 'r20792596P'}}
69+
// expected-error@-2 {{global function 'foor20792596(x:)' requires that 'T' conform to 'r20792596P'}}
7070
}
7171

7272
// <rdar://problem/31181895> parameter "not used in function signature" when part of a superclass constraint

test/Sema/diag_ambiguous_overloads.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@ _ = sr7918_Suit.foo(&myRNG) // expected-error {{cannot pass immutable value as i
7171
//=-------------- SR-7786 --------------=/
7272
struct sr7786 {
7373
func foo() -> UInt { return 0 }
74-
func foo<T: UnsignedInteger>(bar: T) -> T {
74+
func foo<T: UnsignedInteger>(bar: T) -> T { // expected-note {{where 'T' = 'Int'}}
7575
return bar
7676
}
7777
}
7878

7979
let s = sr7786()
8080
let a = s.foo()
81-
let b = s.foo(bar: 123) // expected-error {{argument type 'Int' does not conform to expected type 'UnsignedInteger'}}
81+
let b = s.foo(bar: 123) // expected-error {{instance method 'foo(bar:)' requires that 'Int' conform to 'UnsignedInteger'}}
8282
let c: UInt = s.foo(bar: 123)
8383
let d = s.foo(bar: 123 as UInt)
8484

test/attr/attr_dynamic_member_lookup.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ func keypath_with_incorrect_return_type(_ arr: Lens<Array<Int>>) {
603603
// expected-error@-1 {{operator function '..<' requires that 'Lens<Int>' conform to 'Strideable'}}
604604
// expected-error@-2 {{operator function '..<' requires that 'Lens<Int>.Stride' conform to 'SignedInteger'}}
605605
// expected-error@-3 {{cannot convert value of type 'Int' to expected argument type 'Lens<Int>'}}
606-
// expected-error@-4 {{argument type 'Lens<Int>' does not conform to expected type 'Comparable'}}
606+
// expected-error@-4 {{referencing operator function '..<' on 'Comparable' requires that 'Lens<Int>' conform to 'Comparable'}}
607607
let _ = arr[idx]
608608
}
609609
}

test/decl/enum/objc_enum_Error.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import Foundation
66

7-
func acceptBridgeableNSError<E : _ObjectiveCBridgeableError>(_ e: E) { }
7+
func acceptBridgeableNSError<E : _ObjectiveCBridgeableError>(_ e: E) { } // expected-note {{where 'E' = 'E3'}}
88

99
@objc enum E2 : Int, Error {
1010
case A = 1
@@ -18,4 +18,4 @@ acceptBridgeableNSError(E2.A)
1818
}
1919

2020
acceptBridgeableNSError(E3.A)
21-
// expected-error@-1{{argument type 'E3' does not conform to expected type '_ObjectiveCBridgeableError'}}
21+
// expected-error@-1{{global function 'acceptBridgeableNSError' requires that 'E3' conform to '_ObjectiveCBridgeableError'}}

test/decl/ext/generic.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func intArray(_ x: [Int]) {
131131

132132
class GenericClass<T> { }
133133

134-
extension GenericClass where T : Equatable {
134+
extension GenericClass where T : Equatable { // expected-note {{where 'T' = 'T'}}
135135
func foo(_ x: T, y: T) -> Bool { return x == y }
136136
}
137137

@@ -140,7 +140,7 @@ func genericClassEquatable<T : Equatable>(_ gc: GenericClass<T>, x: T, y: T) {
140140
}
141141

142142
func genericClassNotEquatable<T>(_ gc: GenericClass<T>, x: T, y: T) {
143-
gc.foo(x, y: y) // expected-error{{argument type 'T' does not conform to expected type 'Equatable'}}
143+
gc.foo(x, y: y) // expected-error{{referencing instance method 'foo(_:y:)' on 'GenericClass' requires that 'T' conform to 'Equatable'}}
144144
}
145145

146146

test/expr/expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ func testNilCoalescePrecedence(cond: Bool, a: Int?, r: ClosedRange<Int>?) {
783783
// ?? should have lower precedence than range and arithmetic operators.
784784
let r1 = r ?? (0...42) // ok
785785
let r2 = (r ?? 0)...42 // not ok: expected-error 2 {{cannot convert value of type 'Int' to expected argument type 'ClosedRange<Int>'}}
786-
// expected-error@-1 {{argument type 'ClosedRange<Int>' does not conform to expected type 'Comparable'}}
786+
// expected-error@-1 {{referencing operator function '...' on 'Comparable' requires that 'ClosedRange<Int>' conform to 'Comparable'}}
787787
let r3 = r ?? 0...42 // parses as the first one, not the second.
788788

789789

test/expr/unary/keypath/salvage-with-other-type-errors.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct S {
1313

1414
protocol K { }
1515

16-
func + <Object>(lhs: KeyPath<A, Object>, rhs: String) -> P<Object> {
16+
func + <Object>(lhs: KeyPath<A, Object>, rhs: String) -> P<Object> { // expected-note {{where 'Object' = 'String'}}
1717
fatalError()
1818
}
1919

@@ -27,7 +27,7 @@ struct A {
2727
}
2828

2929
extension A: K {
30-
static let j = S(\A.id + "id") // expected-error {{argument type 'String' does not conform to expected type 'K'}}
30+
static let j = S(\A.id + "id") // expected-error {{operator function '+' requires that 'String' conform to 'K'}}
3131
}
3232

3333
// SR-5034

test/stdlib/StringDiagnostics.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,27 @@ func testStringDeprecation(hello: String) {
6363
func acceptsCollection<C: Collection>(_: C) {}
6464
func acceptsBidirectionalCollection<C: BidirectionalCollection>(_: C) {}
6565
func acceptsRandomAccessCollection<C: RandomAccessCollection>(_: C) {}
66+
// expected-note@-1 {{where 'C' = 'String.UTF8View'}}
67+
// expected-note@-2 {{where 'C' = 'String.UnicodeScalarView'}}
68+
// expected-note@-3 {{where 'C' = 'String.UTF16View'}}
69+
// expected-note@-4 {{where 'C' = 'String'}}
6670

6771
func testStringCollectionTypes(s: String) {
6872
acceptsCollection(s.utf8)
6973
acceptsBidirectionalCollection(s.utf8)
70-
acceptsRandomAccessCollection(s.utf8) // expected-error{{argument type 'String.UTF8View' does not conform to expected type 'RandomAccessCollection'}}
74+
acceptsRandomAccessCollection(s.utf8) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String.UTF8View' conform to 'RandomAccessCollection'}}
7175

7276
acceptsCollection(s.utf16)
7377
acceptsBidirectionalCollection(s.utf16)
74-
acceptsRandomAccessCollection(s.utf16) // expected-error{{argument type 'String.UTF16View' does not conform to expected type 'RandomAccessCollection'}}
78+
acceptsRandomAccessCollection(s.utf16) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String.UTF16View' conform to 'RandomAccessCollection'}}
7579

7680
acceptsCollection(s.unicodeScalars)
7781
acceptsBidirectionalCollection(s.unicodeScalars)
78-
acceptsRandomAccessCollection(s.unicodeScalars) // expected-error{{argument type 'String.UnicodeScalarView' does not conform to expected type 'RandomAccessCollection'}}
82+
acceptsRandomAccessCollection(s.unicodeScalars) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String.UnicodeScalarView' conform to 'RandomAccessCollection'}}
7983

8084
acceptsCollection(s)
8185
acceptsBidirectionalCollection(s)
82-
acceptsRandomAccessCollection(s) // expected-error{{argument type 'String' does not conform to expected type 'RandomAccessCollection'}}
86+
acceptsRandomAccessCollection(s) // expected-error{{global function 'acceptsRandomAccessCollection' requires that 'String' conform to 'RandomAccessCollection'}}
8387
}
8488

8589
// In previous versions of Swift, code would accidentally select

0 commit comments

Comments
 (0)