Skip to content

Commit 689b47a

Browse files
authored
Merge pull request #21222 from xedin/rdar-46459603-5.0
[5.0][ConstraintSystem] Erase `InOutExpr` from member base
2 parents 7f2a58a + 8b3210f commit 689b47a

File tree

3 files changed

+41
-15
lines changed

3 files changed

+41
-15
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,20 +1190,6 @@ ConstraintSystem::getTypeOfMemberReference(
11901190
// Figure out the instance type used for the base.
11911191
Type baseObjTy = getFixedTypeRecursive(baseTy, /*wantRValue=*/true);
11921192

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-
12071193
bool isInstance = true;
12081194
if (auto baseMeta = baseObjTy->getAs<AnyMetatypeType>()) {
12091195
baseObjTy = baseMeta->getInstanceType();
@@ -1215,7 +1201,7 @@ ConstraintSystem::getTypeOfMemberReference(
12151201
return getTypeOfReference(value, functionRefKind, locator, useDC, base);
12161202
}
12171203

1218-
FunctionType::Param baseObjParam(baseObjTy, Identifier(), baseFlags);
1204+
FunctionType::Param baseObjParam(baseObjTy);
12191205

12201206
// Don't open existentials when accessing typealias members of
12211207
// protocols.

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,6 +984,30 @@ namespace {
984984
CallArgs.insert(arg);
985985
}
986986

987+
// FIXME(diagnostics): `InOutType` could appear here as a result
988+
// of successful re-typecheck of the one of the sub-expressions e.g.
989+
// `let _: Int = { (s: inout S) in s.bar() }`. On the first
990+
// attempt to type-check whole expression `s.bar()` - is going
991+
// to have a base which points directly to declaration of `S`.
992+
// But when diagnostics attempts to type-check `s.bar()` standalone
993+
// its base would be tranformed into `InOutExpr -> DeclRefExr`,
994+
// and `InOutType` is going to be recorded in constraint system.
995+
// One possible way to fix this (if diagnostics still use typecheck)
996+
// might be to make it so self is not wrapped into `InOutExpr`
997+
// but instead used as @lvalue type in some case of mutable members.
998+
if (!expr->isImplicit()) {
999+
if (isa<MemberRefExpr>(expr) || isa<DynamicMemberRefExpr>(expr)) {
1000+
auto *LE = cast<LookupExpr>(expr);
1001+
if (auto *IOE = dyn_cast<InOutExpr>(LE->getBase()))
1002+
LE->setBase(IOE->getSubExpr());
1003+
}
1004+
1005+
if (auto *DSCE = dyn_cast<DotSyntaxCallExpr>(expr)) {
1006+
if (auto *IOE = dyn_cast<InOutExpr>(DSCE->getBase()))
1007+
DSCE->setBase(IOE->getSubExpr());
1008+
}
1009+
}
1010+
9871011
// Local function used to finish up processing before returning. Every
9881012
// return site should call through here.
9891013
auto finish = [&](bool recursive, Expr *expr) {

test/Constraints/operator.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,19 @@ func ??= <T>(lhs: inout T?, rhs: T?) {}
208208
var c: Int = 0
209209
c ??= 5 // expected-error{{binary operator '??=' cannot be applied to two 'Int' operands}}
210210
// expected-note@-1{{expected an argument list of type '(inout T?, T?)'}}
211+
212+
func rdar46459603() {
213+
enum E {
214+
case foo(value: String)
215+
}
216+
217+
let e = E.foo(value: "String")
218+
var arr = ["key": e]
219+
220+
_ = arr.values == [e]
221+
// expected-error@-1 {{binary operator '==' cannot be applied to operands of type 'Dictionary<String, E>.Values' and '[E]'}}
222+
// expected-note@-2 {{expected an argument list of type '(Self, Self)'}}
223+
_ = [arr.values] == [[e]]
224+
// expected-error@-1 {{binary operator '==' cannot be applied to operands of type '[Dictionary<String, E>.Values]' and '[[E]]'}}
225+
// expected-note@-2 {{expected an argument list of type '(Self, Self)'}}
226+
}

0 commit comments

Comments
 (0)