Skip to content

Commit 7812f5e

Browse files
committed
[CSSimplify] NFC: More non-functional changes in KeyPath simplification
1 parent f84b3d4 commit 7812f5e

File tree

1 file changed

+41
-37
lines changed

1 file changed

+41
-37
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12180,8 +12180,6 @@ ConstraintSystem::simplifyKeyPathConstraint(
1218012180
TypeMatchOptions flags,
1218112181
ConstraintLocatorBuilder locator) {
1218212182
auto subflags = getDefaultDecompositionOptions(flags);
12183-
// The constraint ought to have been anchored on a KeyPathExpr.
12184-
auto keyPath = castToExpr<KeyPathExpr>(locator.getAnchor());
1218512183
keyPathTy = getFixedTypeRecursive(keyPathTy, /*want rvalue*/ true);
1218612184

1218712185
auto formUnsolved = [&]() -> SolutionKind {
@@ -12197,49 +12195,48 @@ ConstraintSystem::simplifyKeyPathConstraint(
1219712195
if (keyPathTy->isTypeVariableOrMember())
1219812196
return formUnsolved();
1219912197

12200-
auto tryMatchRootAndValueFromType = [&](Type type) -> bool {
12201-
Type boundRoot = Type(), boundValue = Type();
12198+
auto tryMatchRootAndValueFromContextualType = [&](Type contextualTy) -> bool {
12199+
Type contextualRootTy = Type(), contextualValueTy = Type();
1220212200

12203-
if (auto bgt = type->getAs<BoundGenericType>()) {
12201+
// Placeholders are only allowed in the diagnostic mode so it's
12202+
// okay to simply return `true` here.
12203+
if (contextualTy->isPlaceholder())
12204+
return true;
12205+
12206+
// If there are no other options the solver might end up picking
12207+
// `AnyKeyPath` or `PartialKeyPath` based on a contextual conversion.
12208+
// This is an error during normal type-checking but okay in
12209+
// diagnostic mode because root and value are allowed to be holes.
12210+
if (contextualTy->isAnyKeyPath() || contextualTy->isPartialKeyPath())
12211+
return shouldAttemptFixes();
12212+
12213+
if (auto bgt = contextualTy->getAs<BoundGenericType>()) {
1220412214
// We can get root and value from a concrete key path type.
12205-
if (bgt->isKeyPath() ||
12206-
bgt->isWritableKeyPath() ||
12207-
bgt->isReferenceWritableKeyPath()) {
12208-
boundRoot = bgt->getGenericArgs()[0];
12209-
boundValue = bgt->getGenericArgs()[1];
12210-
} else {
12211-
return false;
12212-
}
12215+
assert(bgt->isKeyPath() || bgt->isWritableKeyPath() ||
12216+
bgt->isReferenceWritableKeyPath());
12217+
12218+
contextualRootTy = bgt->getGenericArgs()[0];
12219+
contextualValueTy = bgt->getGenericArgs()[1];
1221312220
}
1221412221

12215-
if (auto fnTy = type->getAs<FunctionType>()) {
12222+
if (auto fnTy = contextualTy->getAs<FunctionType>()) {
1221612223
assert(fnTy->getParams().size() == 1);
1221712224
// Match up the root and value types to the function's param and return
1221812225
// types. Note that we're using the type of the parameter as referenced
1221912226
// from inside the function body as we'll be transforming the code into:
1222012227
// { root in root[keyPath: kp] }.
12221-
boundRoot = fnTy->getParams()[0].getParameterType();
12222-
boundValue = fnTy->getResult();
12223-
12224-
// Key paths never throw, so if the function has a thrown error type
12225-
// that is a type variable, infer it to be Never.
12226-
if (auto thrownError = fnTy->getThrownError()) {
12227-
if (thrownError->isTypeVariableOrMember()) {
12228-
(void)matchTypes(
12229-
thrownError, getASTContext().getNeverType(),
12230-
ConstraintKind::Equal, TMF_GenerateConstraints, locator);
12231-
}
12232-
}
12228+
contextualRootTy = fnTy->getParams()[0].getParameterType();
12229+
contextualValueTy = fnTy->getResult();
1223312230
}
1223412231

12235-
if (boundRoot &&
12236-
matchTypes(rootTy, boundRoot, ConstraintKind::Bind, subflags,
12232+
assert(contextualRootTy && contextualValueTy);
12233+
12234+
if (matchTypes(rootTy, contextualRootTy, ConstraintKind::Bind, subflags,
1223712235
locator.withPathElement(ConstraintLocator::KeyPathRoot))
1223812236
.isFailure())
1223912237
return false;
1224012238

12241-
if (boundValue &&
12242-
matchTypes(valueTy, boundValue, ConstraintKind::Bind, subflags,
12239+
if (matchTypes(valueTy, contextualValueTy, ConstraintKind::Bind, subflags,
1224312240
locator.withPathElement(ConstraintLocator::KeyPathValue))
1224412241
.isFailure())
1224512242
return false;
@@ -12252,6 +12249,16 @@ ConstraintSystem::simplifyKeyPathConstraint(
1225212249
if (auto *fnTy = keyPathTy->getAs<FunctionType>()) {
1225312250
increaseScore(SK_FunctionConversion, locator);
1225412251

12252+
// Key paths never throw, so if the function has a thrown error type
12253+
// that is a type variable, infer it to be Never.
12254+
if (auto thrownError = fnTy->getThrownError()) {
12255+
if (thrownError->isTypeVariableOrMember()) {
12256+
(void)matchTypes(thrownError, getASTContext().getNeverType(),
12257+
ConstraintKind::Equal, TMF_GenerateConstraints,
12258+
locator);
12259+
}
12260+
}
12261+
1225512262
if (fnTy->getParams().size() != 1) {
1225612263
if (!shouldAttemptFixes())
1225712264
return SolutionKind::Error;
@@ -12269,8 +12276,7 @@ ConstraintSystem::simplifyKeyPathConstraint(
1226912276
// If we have a hole somewhere in the key path, the solver won't be able to
1227012277
// infer the key path type. So let's just assume this is solved.
1227112278
if (shouldAttemptFixes()) {
12272-
if (keyPathTy->isPlaceholder())
12273-
return SolutionKind::Solved;
12279+
auto keyPath = castToExpr<KeyPathExpr>(locator.getAnchor());
1227412280

1227512281
if (hasFixFor(getConstraintLocator(keyPath),
1227612282
FixKind::AllowKeyPathWithoutComponents))
@@ -12281,11 +12287,9 @@ ConstraintSystem::simplifyKeyPathConstraint(
1228112287
return SolutionKind::Solved;
1228212288
}
1228312289

12284-
// If we're fixed to a bound generic type, trying harvesting context from it.
12285-
// However, we don't want a solution that fixes the expression type to
12286-
// PartialKeyPath; we'd rather that be represented using an upcast conversion.
12287-
return tryMatchRootAndValueFromType(keyPathTy) ? SolutionKind::Solved
12288-
: SolutionKind::Error;
12290+
return tryMatchRootAndValueFromContextualType(keyPathTy)
12291+
? SolutionKind::Solved
12292+
: SolutionKind::Error;
1228912293
}
1229012294

1229112295
ConstraintSystem::SolutionKind

0 commit comments

Comments
 (0)