Skip to content

Commit 52b3ba1

Browse files
committed
SILGen: Use emitOpenExistentialLValue() when lowering OpaqueValueExprs as lvalues
This is part of allowing lvalue access on class existential payloads.
1 parent f4741aa commit 52b3ba1

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

lib/SILGen/SILGenLValue.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -587,12 +587,26 @@ namespace {
587587
"base for open existential component must be an existential");
588588
assert(base.getType().isAddress() &&
589589
"base value of open-existential component was not an address?");
590-
assert(base.getType().getPreferredExistentialRepresentation(SGF.SGM.M)
591-
== ExistentialRepresentation::Opaque);
590+
SILValue addr;
592591

593-
SILValue addr = SGF.B.createOpenExistentialAddr(
592+
auto rep = base.getType().getPreferredExistentialRepresentation(SGF.SGM.M);
593+
switch (rep) {
594+
case ExistentialRepresentation::Opaque:
595+
addr = SGF.B.createOpenExistentialAddr(
594596
loc, base.getValue(), getTypeOfRValue().getAddressType(),
595597
getOpenedExistentialAccessFor(accessKind));
598+
break;
599+
case ExistentialRepresentation::Boxed: {
600+
auto &TL = SGF.getTypeLowering(base.getType());
601+
auto error = SGF.emitLoad(loc, base.getValue(), TL,
602+
SGFContext(), IsNotTake);
603+
addr = SGF.B.createOpenExistentialBox(
604+
loc, error.getValue(), getTypeOfRValue().getAddressType());
605+
break;
606+
}
607+
default:
608+
llvm_unreachable("Bad existential representation for address-only type");
609+
}
596610

597611
SGF.setArchetypeOpeningSite(cast<ArchetypeType>(getSubstFormalType()),
598612
addr);
@@ -1997,9 +2011,11 @@ LValue SILGenLValue::visitOpaqueValueExpr(OpaqueValueExpr *e,
19972011
SGF.OpaqueValueExprs.erase(known);
19982012

19992013
// Do formal evaluation of the underlying existential lvalue.
2000-
LValue lv = visitRec(opened->getExistentialValue(), accessKind);
2001-
lv.add<OpenOpaqueExistentialComponent>(
2002-
cast<ArchetypeType>(opened->getOpenedArchetype()->getCanonicalType()));
2014+
auto lv = visitRec(opened->getExistentialValue(), accessKind);
2015+
lv = SGF.emitOpenExistentialLValue(
2016+
opened, std::move(lv),
2017+
CanArchetypeType(opened->getOpenedArchetype()),
2018+
accessKind);
20032019
return lv;
20042020
}
20052021

@@ -2909,7 +2925,8 @@ SILGenFunction::emitOpenExistentialLValue(SILLocation loc,
29092925
auto rep = lv.getTypeOfRValue()
29102926
.getPreferredExistentialRepresentation(SGM.M);
29112927
switch (rep) {
2912-
case ExistentialRepresentation::Opaque: {
2928+
case ExistentialRepresentation::Opaque:
2929+
case ExistentialRepresentation::Boxed: {
29132930
lv.add<OpenOpaqueExistentialComponent>(openedArchetype);
29142931
break;
29152932
}

0 commit comments

Comments
 (0)