Allow inout closure param type to be inferred from context or usage.

Introduce a new constraint kind, BindParam, which relates the type of a
function parameter to the type of a reference to it from within the
function body. If the param type is an inout type, the ref type is an
lvalue type with the same underlying object type; otherwise the two
types must be the same. This prevents DeclRefExprs from being inferred
to have inout type in some cases.

<rdar://problem/15998821> Fail to infer types for closure that takes an inout argument

Swift SVN r32183
This commit is contained in:
Chris Willmore
2015-09-23 18:46:12 +00:00
parent e8b85ac4de
commit 49e5130103
7 changed files with 113 additions and 2 deletions

View File

@@ -919,6 +919,20 @@ ConstraintSystem::getTypeOfReference(ValueDecl *value,
Type valueType = TC.getUnopenedTypeOfReference(value, Type(), DC, base,
/*wantInterfaceType=*/true);
// If this is a let-param whose type is a type variable, this is an untyped
// closure param that may be bound to an inout type later. References to the
// param should have lvalue type instead. Express the relationship with a new
// constraint.
if (auto *param = dyn_cast<ParamDecl>(value)) {
if (param->isLet() && valueType->is<TypeVariableType>()) {
Type paramType = valueType;
valueType = createTypeVariable(getConstraintLocator(locator),
TVO_CanBindToLValue);
addConstraint(ConstraintKind::BindParam, paramType, valueType,
getConstraintLocator(locator));
}
}
// Adjust the type of the reference.
valueType = openType(valueType, locator,
replacements,