[ConstraintSystem] Handle InOut base introduced by diagnostic re-typecheck

While trying to lookup member reference on some base type, handle
base being an `InOutType`, which could be a result of previous
sub-expression re-typechecks made by diagnostics.

Resolves: rdar://problem/45771997
This commit is contained in:
Pavel Yaskevich
2018-12-06 12:23:45 -08:00
parent 1c07ab44ef
commit 694c89c090
2 changed files with 25 additions and 1 deletions

View File

@@ -1189,6 +1189,21 @@ ConstraintSystem::getTypeOfMemberReference(
OpenedTypeMap *replacementsPtr) {
// Figure out the instance type used for the base.
Type baseObjTy = getFixedTypeRecursive(baseTy, /*wantRValue=*/true);
ParameterTypeFlags baseFlags;
// FIXME(diagnostics): `InOutType` could appear here as a result
// of successful re-typecheck of the one of the sub-expressions e.g.
// `let _: Int = { (s: inout S) in s.bar() }`. On the first
// attempt to type-check whole expression `s.bar()` - is going
// to have a base which points directly to declaration of `S`.
// But when diagnostics attempts to type-check `s.bar()` standalone
// its base would be tranformed into `InOutExpr -> DeclRefExr`,
// and `InOutType` is going to be recorded in constraint system.
if (auto objType = baseObjTy->getInOutObjectType()) {
baseObjTy = objType;
baseFlags = baseFlags.withInOut(true);
}
bool isInstance = true;
if (auto baseMeta = baseObjTy->getAs<AnyMetatypeType>()) {
baseObjTy = baseMeta->getInstanceType();
@@ -1200,7 +1215,7 @@ ConstraintSystem::getTypeOfMemberReference(
return getTypeOfReference(value, functionRefKind, locator, useDC, base);
}
FunctionType::Param baseObjParam(baseObjTy);
FunctionType::Param baseObjParam(baseObjTy, Identifier(), baseFlags);
// Don't open existentials when accessing typealias members of
// protocols.