Skip to content

Commit 9847f5b

Browse files
committed
[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 (cherry picked from commit 694c89c)
1 parent b5e2b94 commit 9847f5b

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,21 @@ ConstraintSystem::getTypeOfMemberReference(
11891189
OpenedTypeMap *replacementsPtr) {
11901190
// Figure out the instance type used for the base.
11911191
Type baseObjTy = getFixedTypeRecursive(baseTy, /*wantRValue=*/true);
1192+
1193+
ParameterTypeFlags baseFlags;
1194+
// FIXME(diagnostics): `InOutType` could appear here as a result
1195+
// of successful re-typecheck of the one of the sub-expressions e.g.
1196+
// `let _: Int = { (s: inout S) in s.bar() }`. On the first
1197+
// attempt to type-check whole expression `s.bar()` - is going
1198+
// to have a base which points directly to declaration of `S`.
1199+
// But when diagnostics attempts to type-check `s.bar()` standalone
1200+
// its base would be tranformed into `InOutExpr -> DeclRefExr`,
1201+
// and `InOutType` is going to be recorded in constraint system.
1202+
if (auto objType = baseObjTy->getInOutObjectType()) {
1203+
baseObjTy = objType;
1204+
baseFlags = baseFlags.withInOut(true);
1205+
}
1206+
11921207
bool isInstance = true;
11931208
if (auto baseMeta = baseObjTy->getAs<AnyMetatypeType>()) {
11941209
baseObjTy = baseMeta->getInstanceType();
@@ -1200,7 +1215,7 @@ ConstraintSystem::getTypeOfMemberReference(
12001215
return getTypeOfReference(value, functionRefKind, locator, useDC, base);
12011216
}
12021217

1203-
FunctionType::Param baseObjParam(baseObjTy);
1218+
FunctionType::Param baseObjParam(baseObjTy, Identifier(), baseFlags);
12041219

12051220
// Don't open existentials when accessing typealias members of
12061221
// protocols.

test/Constraints/closures.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,3 +849,12 @@ func rdar_45659733() {
849849
}
850850
}
851851
}
852+
853+
func rdar45771997() {
854+
struct S {
855+
mutating func foo() {}
856+
}
857+
858+
let _: Int = { (s: inout S) in s.foo() }
859+
// expected-error@-1 {{cannot convert value of type '(inout S) -> ()' to specified type 'Int'}}
860+
}

0 commit comments

Comments
 (0)