Skip to content

Commit 3a77295

Browse files
committed
[QoI] Use information known about call parameters via failed constraint
This makes it a lot easier to diagnose contextual mismatch related to arguments used by the call without relying on the type of the function expression which is not always available.
1 parent 0e2f5ac commit 3a77295

File tree

4 files changed

+23
-8
lines changed

4 files changed

+23
-8
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6367,6 +6367,23 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
63676367
}
63686368
}
63696369

6370+
// If there is a failing constraint associated with current constraint
6371+
// system which points to the argument/parameter mismatch, let's use
6372+
// that information while re-typechecking argument expression, this
6373+
// makes it a lot easier to determine contextual mismatch.
6374+
if (CS->failedConstraint && !hasTrailingClosure) {
6375+
auto *constraint = CS->failedConstraint;
6376+
if (constraint->getKind() == ConstraintKind::ArgumentTupleConversion) {
6377+
if (auto *locator = constraint->getLocator()) {
6378+
if (locator->getAnchor() == callExpr) {
6379+
argType = constraint->getSecondType();
6380+
if (auto *typeVar = argType->getAs<TypeVariableType>())
6381+
argType = CS->getFixedType(typeVar);
6382+
}
6383+
}
6384+
}
6385+
}
6386+
63706387
// Get the expression result of type checking the arguments to the call
63716388
// independently, so we have some idea of what we're working with.
63726389
//

test/Compatibility/tuple_arguments.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1460,7 +1460,7 @@ enum DataSourcePage<T> {
14601460
}
14611461

14621462
let pages1: MutableProperty<(data: DataSourcePage<Int>, totalCount: Int)> = MutableProperty((
1463-
// expected-error@-1 {{cannot convert value of type 'MutableProperty<(data: _, totalCount: Int)>' to specified type 'MutableProperty<(data: DataSourcePage<Int>, totalCount: Int)>'}}
1463+
// expected-error@-1 {{expression type 'MutableProperty<(data: DataSourcePage<Int>, totalCount: Int)>' is ambiguous without more context}}
14641464
data: .notLoaded,
14651465
totalCount: 0
14661466
))

test/Constraints/function.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,12 @@ private class SR2657BlockClass<T> {
9090
init(f: T) { self.f = f }
9191
}
9292

93-
func foo(block: () -> ()) {
93+
func foo(block: () -> ()) { // expected-note 2 {{parameter 'block' is implicitly non-escaping}}
9494
let a = SR2657BlockClass(f: block) // No error
9595
let b = SR2657BlockClass<()->()>(f: block)
96-
// expected-error@-1 {{invalid conversion from non-escaping function of type '() -> ()' to potentially escaping function type '() -> ()'}}
96+
// expected-error@-1 {{passing non-escaping parameter 'block' to function expecting an @escaping closure}}
9797
let c: SR2657BlockClass<()->()> = SR2657BlockClass(f: block)
9898
// expected-error@-1 {{cannot convert value of type 'SR2657BlockClass<() -> ()>' to specified type 'SR2657BlockClass<() -> ()>'}}
9999
let d: SR2657BlockClass<()->()> = SR2657BlockClass<()->()>(f: block)
100-
// expected-error@-1 {{invalid conversion from non-escaping function of type '() -> ()' to potentially escaping function type '() -> ()'}}
100+
// expected-error@-1 {{passing non-escaping parameter 'block' to function expecting an @escaping closure}}
101101
}

test/Generics/invalid.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,8 @@ func eatDinnerConcrete(d: Pizzas<Pepper>.DeepDish,
5454
func badDiagnostic1() {
5555

5656
_ = Lunch<Pizzas<Pepper>.NewYork>.Dinner<HotDog>(
57-
leftovers: Pizzas<ChiliFlakes>.NewYork(),
58-
// FIXME: Quality of this diagnostic is related to the fact that failure analyzer
59-
// doesn't take advantage of informantion in constraint system such as failed constraint.
60-
transformation: { _ in HotDog() }) // expected-error {{cannot convert value of type '(_) -> HotDog' to expected argument type '(_) -> _'}}
57+
leftovers: Pizzas<ChiliFlakes>.NewYork(), // expected-error {{cannot convert value of type 'Pizzas<ChiliFlakes>.NewYork' to expected argument type 'Pizzas<Pepper>.NewYork'}}
58+
transformation: { _ in HotDog() })
6159
}
6260

6361
func badDiagnostic2() {

0 commit comments

Comments
 (0)