Sema: Only use PreparedOverload::Change::AddedBindConstraint if the locator didn't change

For a Bind constraint generated by a same-type requirement, we must
preserve the locator so we need to record it like any other kind of
constraint.

This fixes a diagnostic regression with -solver-enable-prepared-overloads.
This commit is contained in:
Slava Pestov
2025-10-10 14:29:02 -04:00
parent 773d3271e9
commit 036db6fb08
3 changed files with 21 additions and 7 deletions

View File

@@ -104,9 +104,10 @@ struct PreparedOverloadChange {
/// For ChangeKind::AddedConstraint. /// For ChangeKind::AddedConstraint.
Constraint *TheConstraint; Constraint *TheConstraint;
/// For ChangeKind::AddedBindConstraint.
struct { struct {
TypeBase *FirstType; TypeBase *FirstType;
TypeBase * SecondType; TypeBase *SecondType;
} Bind; } Bind;
/// For ChangeKind::OpenedTypes. /// For ChangeKind::OpenedTypes.
@@ -187,6 +188,10 @@ public:
struct PreparedOverloadBuilder { struct PreparedOverloadBuilder {
SmallVector<PreparedOverload::Change, 8> Changes; SmallVector<PreparedOverload::Change, 8> Changes;
ConstraintLocator *Locator;
PreparedOverloadBuilder(ConstraintLocator *locator)
: Locator(locator) {}
void addedTypeVariable(TypeVariableType *typeVar) { void addedTypeVariable(TypeVariableType *typeVar) {
PreparedOverload::Change change; PreparedOverload::Change change;

View File

@@ -16529,14 +16529,22 @@ void ConstraintSystem::addConstraint(ConstraintKind kind, Type first,
PreparedOverloadBuilder *preparedOverload) { PreparedOverloadBuilder *preparedOverload) {
if (preparedOverload) { if (preparedOverload) {
ASSERT(PreparingOverload); ASSERT(PreparingOverload);
if (kind == ConstraintKind::Bind) {
auto *locatorPtr = getConstraintLocator(locator);
// Fast path to save on memory usage.
if (kind == ConstraintKind::Bind &&
locatorPtr == preparedOverload->Locator) {
ASSERT(!isFavored); ASSERT(!isFavored);
preparedOverload->addedBindConstraint(first, second); preparedOverload->addedBindConstraint(first, second);
return; return;
} }
auto c = Constraint::create(*this, kind, first, second,
getConstraintLocator(locator)); auto c = Constraint::create(*this, kind, first, second, locatorPtr);
if (isFavored) c->setFavored();
if (isFavored)
c->setFavored();
preparedOverload->addedConstraint(c); preparedOverload->addedConstraint(c);
return; return;
} }

View File

@@ -2811,7 +2811,8 @@ void ConstraintSystem::replayChanges(
addConstraint(ConstraintKind::Bind, addConstraint(ConstraintKind::Bind,
change.Bind.FirstType, change.Bind.FirstType,
change.Bind.SecondType, change.Bind.SecondType,
locator, /*isFavored=*/false); locator,
/*isFavored=*/false);
break; break;
case PreparedOverload::Change::OpenedTypes: { case PreparedOverload::Change::OpenedTypes: {
@@ -2890,7 +2891,7 @@ PreparedOverload *ConstraintSystem::prepareOverload(OverloadChoice choice,
ASSERT(!PreparingOverload); ASSERT(!PreparingOverload);
PreparingOverload = true; PreparingOverload = true;
PreparedOverloadBuilder builder; PreparedOverloadBuilder builder(locator);
Type openedType; Type openedType;
Type thrownErrorType; Type thrownErrorType;
std::tie(openedType, thrownErrorType) = prepareOverloadImpl( std::tie(openedType, thrownErrorType) = prepareOverloadImpl(