Skip to content

Commit 328143a

Browse files
committed
[ConstraintSystem] Align @dynamicCallable argument locators with regular calls
Having the same locators for `@dynamicCallable` and the regular calls make it much easier to produce diagnostics.
1 parent b0d01de commit 328143a

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3156,6 +3156,12 @@ bool ConstraintSystem::repairFailures(
31563156
// for this call, we can consider overload unrelated.
31573157
if (llvm::any_of(getFixes(), [&](const ConstraintFix *fix) {
31583158
auto *locator = fix->getLocator();
3159+
// Since arguments to @dynamicCallable form either an array
3160+
// or a dictionary and all have to match the same element type,
3161+
// let's allow multiple invalid arguments.
3162+
if (locator->findFirst<LocatorPathElt::DynamicCallable>())
3163+
return false;
3164+
31593165
return locator->findLast<LocatorPathElt::ApplyArgToParam>()
31603166
? locator->getAnchor() == anchor
31613167
: false;
@@ -7841,14 +7847,20 @@ ConstraintSystem::simplifyDynamicCallableApplicableFnConstraint(
78417847
addConstraint(ConstraintKind::Defaultable, argumentType,
78427848
ctx.TheAnyType, locator);
78437849

7850+
auto *baseArgLoc = getConstraintLocator(
7851+
loc->getAnchor(),
7852+
{ConstraintLocator::DynamicCallable, ConstraintLocator::ApplyArgument},
7853+
/*summaryFlags=*/0);
7854+
78447855
// All dynamic call parameter types must be convertible to the argument type.
78457856
for (auto i : indices(func1->getParams())) {
78467857
auto param = func1->getParams()[i];
78477858
auto paramType = param.getPlainType();
7848-
auto locatorBuilder =
7849-
locator.withPathElement(LocatorPathElt::TupleElement(i));
7850-
addConstraint(ConstraintKind::ArgumentConversion, paramType,
7851-
argumentType, locatorBuilder);
7859+
7860+
addConstraint(
7861+
ConstraintKind::ArgumentConversion, paramType, argumentType,
7862+
getConstraintLocator(baseArgLoc, LocatorPathElt::ApplyArgToParam(
7863+
i, 0, param.getParameterFlags())));
78527864
}
78537865

78547866
return SolutionKind::Solved;

test/attr/attr_dynamic_callable.swift

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,21 @@ func testCallable(
5252
func testCallableDiagnostics(
5353
a: Callable, b: DiscardableResult, c: Throwing, d: KeywordArgumentCallable
5454
) {
55-
a("hello", "world") // expected-error {{cannot invoke 'a' with an argument list of type '(String, String)'}}
56-
b("hello", "world") // expected-error {{cannot invoke 'b' with an argument list of type '(String, String)'}}
57-
try? c(1, 2, 3, 4) // expected-error {{cannot invoke 'c' with an argument list of type '(Int, Int, Int, Int)'}}
58-
d(x1: "hello", x2: "world") // expected-error {{cannot invoke 'd' with an argument list of type '(x1: String, x2: String)'}}
55+
a("hello", "world")
56+
// expected-error@-1:5 {{cannot convert value of type 'String' to expected argument type 'Int'}}
57+
// expected-error@-2:14 {{cannot convert value of type 'String' to expected argument type 'Int'}}
58+
b("hello", "world")
59+
// expected-error@-1:5 {{cannot convert value of type 'String' to expected argument type 'Double'}}
60+
// expected-error@-2:14 {{cannot convert value of type 'String' to expected argument type 'Double'}}
61+
try? c(1, 2, 3, 4)
62+
// expected-error@-1:10 {{cannot convert value of type 'Int' to expected argument type 'String'}}
63+
// expected-error@-2:13 {{cannot convert value of type 'Int' to expected argument type 'String'}}
64+
// expected-error@-3:16 {{cannot convert value of type 'Int' to expected argument type 'String'}}
65+
// expected-error@-4:19 {{cannot convert value of type 'Int' to expected argument type 'String'}}
66+
67+
d(x1: "hello", x2: "world")
68+
// expected-error@-1:9 {{cannot convert value of type 'String' to expected argument type 'Float'}}
69+
// expected-error@-2:22 {{cannot convert value of type 'String' to expected argument type 'Float'}}
5970
}
6071

6172
func testIUO(

0 commit comments

Comments
 (0)