mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Merge pull request #28630 from xedin/dynamic-member-diagnostics
[Diagnostics] Port/Improve diagnostics for `@dynamicCallable` and `callAsFunction`
This commit is contained in:
@@ -3167,6 +3167,12 @@ bool ConstraintSystem::repairFailures(
|
||||
// for this call, we can consider overload unrelated.
|
||||
if (llvm::any_of(getFixes(), [&](const ConstraintFix *fix) {
|
||||
auto *locator = fix->getLocator();
|
||||
// Since arguments to @dynamicCallable form either an array
|
||||
// or a dictionary and all have to match the same element type,
|
||||
// let's allow multiple invalid arguments.
|
||||
if (locator->findFirst<LocatorPathElt::DynamicCallable>())
|
||||
return false;
|
||||
|
||||
return locator->findLast<LocatorPathElt::ApplyArgToParam>()
|
||||
? locator->getAnchor() == anchor
|
||||
: false;
|
||||
@@ -7819,7 +7825,35 @@ ConstraintSystem::simplifyDynamicCallableApplicableFnConstraint(
|
||||
choices.push_back(
|
||||
OverloadChoice(type2, candidate, FunctionRefKind::SingleApply));
|
||||
}
|
||||
if (choices.empty()) return SolutionKind::Error;
|
||||
|
||||
if (choices.empty()) {
|
||||
if (!shouldAttemptFixes())
|
||||
return SolutionKind::Error;
|
||||
|
||||
// TODO(diagnostics): This is not going to be necessary once
|
||||
// `@dynamicCallable` uses existing `member` machinery.
|
||||
|
||||
auto memberName = DeclName(
|
||||
ctx, ctx.Id_dynamicallyCall,
|
||||
{useKwargsMethod ? ctx.Id_withKeywordArguments : ctx.Id_withArguments});
|
||||
|
||||
auto *fix = DefineMemberBasedOnUse::create(
|
||||
*this, desugar2, memberName,
|
||||
getConstraintLocator(loc, ConstraintLocator::DynamicCallable));
|
||||
|
||||
if (recordFix(fix))
|
||||
return SolutionKind::Error;
|
||||
|
||||
recordPotentialHole(tv);
|
||||
|
||||
Type(func1).visit([&](Type type) {
|
||||
if (auto *typeVar = type->getAs<TypeVariableType>())
|
||||
recordPotentialHole(typeVar);
|
||||
});
|
||||
|
||||
return SolutionKind::Solved;
|
||||
}
|
||||
|
||||
addOverloadSet(tv, choices, DC, loc);
|
||||
|
||||
// Create a type variable for the argument to the `dynamicallyCall` method.
|
||||
@@ -7852,14 +7886,20 @@ ConstraintSystem::simplifyDynamicCallableApplicableFnConstraint(
|
||||
addConstraint(ConstraintKind::Defaultable, argumentType,
|
||||
ctx.TheAnyType, locator);
|
||||
|
||||
auto *baseArgLoc = getConstraintLocator(
|
||||
loc->getAnchor(),
|
||||
{ConstraintLocator::DynamicCallable, ConstraintLocator::ApplyArgument},
|
||||
/*summaryFlags=*/0);
|
||||
|
||||
// All dynamic call parameter types must be convertible to the argument type.
|
||||
for (auto i : indices(func1->getParams())) {
|
||||
auto param = func1->getParams()[i];
|
||||
auto paramType = param.getPlainType();
|
||||
auto locatorBuilder =
|
||||
locator.withPathElement(LocatorPathElt::TupleElement(i));
|
||||
addConstraint(ConstraintKind::ArgumentConversion, paramType,
|
||||
argumentType, locatorBuilder);
|
||||
|
||||
addConstraint(
|
||||
ConstraintKind::ArgumentConversion, paramType, argumentType,
|
||||
getConstraintLocator(baseArgLoc, LocatorPathElt::ApplyArgToParam(
|
||||
i, 0, param.getParameterFlags())));
|
||||
}
|
||||
|
||||
return SolutionKind::Solved;
|
||||
|
||||
Reference in New Issue
Block a user