Skip to content

Commit a93eff1

Browse files
[ConstraintSystem] Add getLocatorForAmbiguity helper for ambiguity logic
1 parent d5a9d6a commit a93eff1

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3249,6 +3249,12 @@ class ConstraintSystem {
32493249
ConstraintLocator *
32503250
getConstraintLocator(const ConstraintLocatorBuilder &builder);
32513251

3252+
/// Retrieves a locator that identifies where an overload ambiguity may be
3253+
/// present. In most cases this is a no-op, but may simplify locator e.g
3254+
/// coercions for ambiguities in the expression operand.
3255+
ConstraintLocator *
3256+
getConstraintLocatorForAmbiguity(ConstraintLocator *locator);
3257+
32523258
/// Compute a constraint locator for an implicit value-to-value
32533259
/// conversion rooted at the given location.
32543260
ConstraintLocator *

lib/Sema/ConstraintSystem.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,14 @@ ConstraintLocator *ConstraintSystem::getConstraintLocator(
422422
return getConstraintLocator(anchor, newPath);
423423
}
424424

425+
ConstraintLocator *
426+
ConstraintSystem::getConstraintLocatorForAmbiguity(ConstraintLocator *locator) {
427+
if (locator->findLast<LocatorPathElt::CoercionOperand>()) {
428+
return getConstraintLocator(simplifyLocatorToAnchor(locator));
429+
}
430+
return locator;
431+
}
432+
425433
ConstraintLocator *ConstraintSystem::getImplicitValueConversionLocator(
426434
ConstraintLocatorBuilder root, ConversionRestrictionKind restriction) {
427435
SmallVector<LocatorPathElt, 4> path;
@@ -4951,7 +4959,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
49514959
const auto &solution = *entry.first;
49524960
const auto *fix = entry.second;
49534961

4954-
auto *locator = fix->getLocator();
4962+
auto *locator = getConstraintLocatorForAmbiguity(fix->getLocator());
49554963

49564964
if (locator->isForContextualType()) {
49574965
contextualFixes.push_back({&solution, fix});
@@ -5473,6 +5481,19 @@ void constraints::simplifyLocator(ASTNode &anchor,
54735481
}
54745482
break;
54755483

5484+
case ConstraintLocator::CoercionOperand: {
5485+
auto *CE = castToExpr<CoerceExpr>(anchor);
5486+
anchor = CE->getSubExpr()->getValueProvidingExpr();
5487+
path = path.slice(1);
5488+
// When in a argument function type on a coercion context
5489+
// look past the argument, because is just for identify the
5490+
// argument type that is being matched.
5491+
if (!path.empty() && path[0].is<LocatorPathElt::FunctionArgument>()) {
5492+
path = path.slice(1);
5493+
}
5494+
continue;
5495+
}
5496+
54765497
case ConstraintLocator::GlobalActorType:
54775498
case ConstraintLocator::ContextualType: {
54785499
// This was just for identifying purposes, strip it off.

0 commit comments

Comments
 (0)