Skip to content

Commit b6def6e

Browse files
Merge pull request #77892 from AnthonyLatsis/magnolia-grandiflora
Sema: Subscript called with opened existential cannot produce lvalue if result is type-erased
2 parents 28d090f + 6612c9c commit b6def6e

File tree

5 files changed

+36
-35
lines changed

5 files changed

+36
-35
lines changed

lib/Sema/CSApply.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -1005,8 +1005,14 @@ namespace {
10051005
auto *env = record.Archetype->getGenericEnvironment();
10061006

10071007
if (resultTy->hasLocalArchetypeFromEnvironment(env)) {
1008-
Type erasedTy = typeEraseOpenedArchetypesFromEnvironment(
1009-
resultTy, env);
1008+
Type erasedTy = typeEraseOpenedArchetypesFromEnvironment(resultTy, env);
1009+
ASSERT(erasedTy.getPointer() != resultTy.getPointer());
1010+
1011+
// We currently cannot keep lvalueness if the object type changed.
1012+
if (auto *lvalueTy = dyn_cast<LValueType>(erasedTy.getPointer())) {
1013+
erasedTy = lvalueTy->getObjectType();
1014+
}
1015+
10101016
auto range = result->getSourceRange();
10111017
result = coerceToType(result, erasedTy, locator);
10121018
// FIXME: Implement missing tuple-to-tuple conversion

lib/Sema/CSSimplify.cpp

+12-2
Original file line numberDiff line numberDiff line change
@@ -13405,9 +13405,19 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyApplicableFnConstraint(
1340513405
Type result2 = func2->getResult();
1340613406
if (result2->hasTypeVariable() && !openedExistentials.empty()) {
1340713407
for (const auto &opened : openedExistentials) {
13408-
result2 = typeEraseOpenedExistentialReference(
13409-
result2, opened.second->getExistentialType(), opened.first,
13408+
auto originalTy = result2;
13409+
if (auto *lvalueTy = dyn_cast<LValueType>(originalTy.getPointer())) {
13410+
originalTy = lvalueTy->getObjectType();
13411+
}
13412+
13413+
const auto erasedTy = typeEraseOpenedExistentialReference(
13414+
originalTy, opened.second->getExistentialType(), opened.first,
1341013415
TypePosition::Covariant);
13416+
13417+
if (originalTy.getPointer() != erasedTy.getPointer()) {
13418+
// We currently cannot keep lvalueness if the object type changed.
13419+
result2 = erasedTy;
13420+
}
1341113421
}
1341213422
}
1341313423

lib/Sema/OpenedExistentials.cpp

-14
Original file line numberDiff line numberDiff line change
@@ -800,20 +800,6 @@ static Type typeEraseExistentialSelfReferences(
800800
return parameterized->getBaseType();
801801
}
802802
}
803-
/*
804-
if (auto lvalue = dyn_cast<LValueType>(t)) {
805-
auto objTy = lvalue->getObjectType();
806-
auto erasedTy =
807-
typeEraseExistentialSelfReferences(
808-
objTy, currPos,
809-
containsFn, predicateFn, eraseFn);
810-
811-
if (erasedTy.getPointer() == objTy.getPointer())
812-
return Type(lvalue);
813-
814-
return erasedTy;
815-
}
816-
*/
817803

818804
if (!predicateFn(t)) {
819805
// Recurse.
+15-17
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
// RUN: %target-typecheck-verify-swift
22

3-
// rdar://121214563
43
// https://github.com/swiftlang/swift/issues/60619
5-
// REQUIRES: rdar121214563
6-
7-
protocol Q {}
4+
do {
5+
protocol P {
6+
associatedtype A
7+
}
8+
struct S {
9+
subscript<T: P>(_: T) -> T {
10+
get {} set {}
11+
}
12+
}
813

9-
func takesAny(x: any Q) {}
10-
func takesRValue(x: any Q) {}
11-
func takesInOut(x: inout any Q) {}
14+
func takesInOut(_: inout any P) {}
1215

13-
struct S {
14-
subscript<T: Q>(_ ct: T.Type) -> T {
15-
get { fatalError() }
16-
set { fatalError() }
17-
}
18-
}
16+
var s: S
17+
let p: any P
1918

20-
func f(s: inout S, t: any Q.Type) -> (any Q) {
21-
takesAny(x: s[t])
22-
takesRValue(x: s[t])
23-
takesInOut(x: &s[t]) // expected-error {{cannot pass immutable value as inout argument: 's' is immutable}}
19+
let _ = s[p]
20+
s[p] = p // expected-error {{cannot assign through subscript: 's' is immutable}}
21+
takesInOut(&s[p]) // expected-error {{cannot pass immutable value as inout argument: 's' is immutable}}
2422
}

test/decl/protocol/existential_member_access/storage.swift

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %target-typecheck-verify-swift -target %target-swift-5.9-abi-triple
22

3+
// rdar://121214563
34
// https://github.com/apple/swift/issues/62219
45

56
// nonmutating get mutating set

0 commit comments

Comments
 (0)