Implicit conversion of KeyPath<Root,Value> to (Root) -> Value.

Fix autoclosure param interface type when it involves archetypes.

Had some repeated locals from moving this block of code around - cleaned up.

Alternate implementation where KeyPathExpr is essentially a literal type and can be either a KeyPath(R,V) or (R)->V.

Some unneccessary code now.

Implicit closure pieces need valid sourceLocs in case a coerce expr needs to refer to the beginning of the closure in `\.foo as (A) -> B`.
Removed explicit noescape from function type so `let a: (A) -> B = \.foo` is valid.
Remove optimization that optional path is always read-only KP type in CSGen, since it can also now be of function type.
This commit is contained in:
gregomni
2018-09-20 21:39:13 -07:00
committed by Greg Titus
parent 529d784329
commit 5e98f3e8e5
4 changed files with 85 additions and 12 deletions

View File

@@ -5584,6 +5584,25 @@ ConstraintSystem::simplifyKeyPathConstraint(Type keyPathTy,
}
}
// If we're bound to a (Root) -> Value function type, use that for context.
if (auto fnTy = keyPathTy->getAs<FunctionType>()) {
if (fnTy->getParams().size() == 1) {
Type boundRoot = fnTy->getParams()[0].getPlainType();
Type boundValue = fnTy->getResult();
if (matchTypes(boundRoot, rootTy, ConstraintKind::Bind, subflags, locator)
.isFailure())
return SolutionKind::Error;
if (matchTypes(boundValue, valueTy, ConstraintKind::Bind, subflags,
locator)
.isFailure())
return SolutionKind::Error;
return SolutionKind::Solved;
}
}
// See if we resolved overloads for all the components involved.
enum {
ReadOnly,
@@ -5711,11 +5730,16 @@ done:
auto resolvedKPTy = BoundGenericType::get(kpDecl, nullptr,
{rootTy, valueTy});
// Let's check whether deduced key path type would match
// expected contextual one.
return matchTypes(
resolvedKPTy, keyPathTy, ConstraintKind::Bind, subflags,
locator.withPathElement(LocatorPathElt::getContextualType()));
Type fnType = FunctionType::get({AnyFunctionType::Param(rootTy)}, valueTy,
AnyFunctionType::ExtInfo().withThrows(false));
llvm::SmallVector<Constraint *, 2> constraints;
auto loc = locator.getBaseLocator();
constraints.push_back(Constraint::create(*this, ConstraintKind::Bind,
keyPathTy, resolvedKPTy, loc));
constraints.push_back(
Constraint::create(*this, ConstraintKind::Bind, keyPathTy, fnType, loc));
addDisjunctionConstraint(constraints, locator);
return SolutionKind::Solved;
}
ConstraintSystem::SolutionKind