Skip to content

Commit e0fcec5

Browse files
committed
When evaluating candidates for closeness, make sure to consider UnresolvedType to be
a match, since it *could* be, and typically conforms to whatever the expression is. Fixing this improves the diagnostic in Constraints/closures.swift significantly, and fixes these bugs: <rdar://problem/21718970> QoI: [uninferred generic param] cannot invoke 'foo' with an argument list of type '(Int)' <rdar://problem/21718955> Swift useless error: cannot invoke 'foo' with no arguments where before we produced: error: cannot invoke 'foo' with an argument list of type '(Int)' and now produce: x.swift:5:10: error: generic parameter 'A' could not be inferred Whatever.foo(a: 23) ^ x.swift:1:7: note: 'A' declared as parameter to type 'Whatever' class Whatever<A: IntegerArithmetic, B: IntegerArithmetic> { ^
1 parent eabdc04 commit e0fcec5

File tree

3 files changed

+16
-3
lines changed

3 files changed

+16
-3
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,7 +1174,9 @@ CalleeCandidateInfo::evaluateCloseness(DeclContext *dc, Type candArgListType,
11741174

11751175
TypeSubstitutionMap archetypesMap;
11761176
bool matched;
1177-
if (paramType->hasUnresolvedType() || rArgType->hasTypeVariable())
1177+
if (paramType->hasUnresolvedType())
1178+
matched = true;
1179+
else if (rArgType->hasTypeVariable())
11781180
matched = false;
11791181
else {
11801182
auto matchType = paramType;
@@ -4452,7 +4454,6 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
44524454
if (calleeInfo.diagnoseSimpleErrors(callExpr))
44534455
return true;
44544456

4455-
44564457
// A common error is to apply an operator that only has inout forms (e.g. +=)
44574458
// to non-lvalues (e.g. a local let). Produce a nice diagnostic for this
44584459
// case.

test/Constraints/closures.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ struct S<T> {
192192

193193
func subscribe<Object: AnyObject where Object: Hashable>(object: Object?, method: (Object, T) -> ()) {
194194
let wrappedMethod = { (object: AnyObject, value: T) in }
195-
// expected-error @+1 {{cannot convert value of type '(AnyObject, T) -> ()' to expected argument type '(AnyObject, _) -> ()'}}
195+
// expected-error @+1 {{value of optional type 'Object?' not unwrapped; did you mean to use '!' or '?'?}}
196196
cs.forEach { $0.w.append(value: wrappedMethod, forKey: object) }
197197
}
198198
}

test/Constraints/generics.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,3 +226,15 @@ func test9215114<T: P19215114, U: Q19215114>(_ t: T) -> (U) -> () {
226226
return f
227227
}
228228

229+
// <rdar://problem/21718970> QoI: [uninferred generic param] cannot invoke 'foo' with an argument list of type '(Int)'
230+
class Whatever<A: IntegerArithmetic, B: IntegerArithmetic> { // expected-note 2 {{'A' declared as parameter to type 'Whatever'}}
231+
static func foo(a: B) {}
232+
233+
static func bar() {}
234+
235+
}
236+
Whatever.foo(a: 23) // expected-error {{generic parameter 'A' could not be inferred}}
237+
238+
// <rdar://problem/21718955> Swift useless error: cannot invoke 'foo' with no arguments
239+
Whatever.bar() // expected-error {{generic parameter 'A' could not be inferred}}
240+

0 commit comments

Comments
 (0)