[CS] NFC: Factor out matchPackElementType

This commit is contained in:
Hamish Knight
2025-02-20 21:31:46 +00:00
parent 29e9f429e3
commit 9c04fd8cd3
2 changed files with 50 additions and 40 deletions

View File

@@ -5024,6 +5024,11 @@ private:
TypeMatchOptions flags, TypeMatchOptions flags,
ConstraintLocatorBuilder locator); ConstraintLocatorBuilder locator);
/// Attempt to match a pack element type with the fully resolved pattern type
/// for the pack expansion.
SolutionKind matchPackElementType(Type elementType, Type patternType,
ConstraintLocatorBuilder locator);
/// Attempt to simplify a PackElementOf constraint. /// Attempt to simplify a PackElementOf constraint.
/// ///
/// Solving this constraint is delayed until the element type is fully /// Solving this constraint is delayed until the element type is fully

View File

@@ -9626,6 +9626,49 @@ ConstraintSystem::simplifyBindTupleOfFunctionParamsConstraint(
return SolutionKind::Solved; return SolutionKind::Solved;
} }
ConstraintSystem::SolutionKind
ConstraintSystem::matchPackElementType(Type elementType, Type patternType,
ConstraintLocatorBuilder locator) {
auto *loc = getConstraintLocator(locator);
auto shapeClass = patternType->getReducedShape();
auto *elementEnv = getPackElementEnvironment(loc, shapeClass);
// Without an opened element environment, we cannot derive the
// element binding.
if (!elementEnv) {
if (!shouldAttemptFixes())
return SolutionKind::Error;
// `each` was applied to a concrete type.
if (!shapeClass->is<PackArchetypeType>()) {
if (recordFix(AllowInvalidPackElement::create(*this, patternType, loc)))
return SolutionKind::Error;
} else {
auto envShape = PackExpansionEnvironments.find(loc);
if (envShape == PackExpansionEnvironments.end()) {
return SolutionKind::Error;
}
auto *fix = SkipSameShapeRequirement::create(
*this, envShape->second.second, shapeClass,
getConstraintLocator(loc, ConstraintLocator::PackShape));
if (recordFix(fix)) {
return SolutionKind::Error;
}
}
recordAnyTypeVarAsPotentialHole(elementType);
return SolutionKind::Solved;
}
auto expectedElementTy =
elementEnv->mapContextualPackTypeIntoElementContext(patternType);
assert(!expectedElementTy->is<PackType>());
addConstraint(ConstraintKind::Equal, elementType, expectedElementTy,
locator);
return SolutionKind::Solved;
}
ConstraintSystem::SolutionKind ConstraintSystem::SolutionKind
ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second, ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
TypeMatchOptions flags, TypeMatchOptions flags,
@@ -9660,46 +9703,8 @@ ConstraintSystem::simplifyPackElementOfConstraint(Type first, Type second,
} }
// Let's try to resolve element type based on the pattern type. // Let's try to resolve element type based on the pattern type.
if (!patternType->hasTypeVariable()) { if (!patternType->hasTypeVariable())
auto *loc = getConstraintLocator(locator); return matchPackElementType(elementType, patternType, locator);
auto shapeClass = patternType->getReducedShape();
auto *elementEnv = getPackElementEnvironment(loc, shapeClass);
// Without an opened element environment, we cannot derive the
// element binding.
if (!elementEnv) {
if (!shouldAttemptFixes())
return SolutionKind::Error;
// `each` was applied to a concrete type.
if (!shapeClass->is<PackArchetypeType>()) {
if (recordFix(AllowInvalidPackElement::create(*this, patternType, loc)))
return SolutionKind::Error;
} else {
auto envShape = PackExpansionEnvironments.find(loc);
if (envShape == PackExpansionEnvironments.end()) {
return SolutionKind::Error;
}
auto *fix = SkipSameShapeRequirement::create(
*this, envShape->second.second, shapeClass,
getConstraintLocator(loc, ConstraintLocator::PackShape));
if (recordFix(fix)) {
return SolutionKind::Error;
}
}
recordAnyTypeVarAsPotentialHole(elementType);
return SolutionKind::Solved;
}
auto expectedElementTy =
elementEnv->mapContextualPackTypeIntoElementContext(patternType);
assert(!expectedElementTy->is<PackType>());
addConstraint(ConstraintKind::Equal, elementType, expectedElementTy,
locator);
return SolutionKind::Solved;
}
// Otherwise we are inferred or checking pattern type. // Otherwise we are inferred or checking pattern type.