@@ -1270,15 +1270,20 @@ RValue SILGenFunction::emitRValueForStorageLoad(
1270
1270
}
1271
1271
1272
1272
// If the base is a reference type, just handle this as loading the lvalue.
1273
+ ManagedValue result;
1273
1274
if (baseFormalType->hasReferenceSemantics ()) {
1274
1275
LValue LV = emitPropertyLValue (loc, base, baseFormalType, field,
1275
1276
LValueOptions (), AccessKind::Read,
1276
1277
AccessSemantics::DirectToStorage);
1277
- return emitLoadOfLValue (loc, std::move (LV), C, isBaseGuaranteed);
1278
- }
1279
-
1280
- ManagedValue result;
1281
- if (!base.getType ().isAddress ()) {
1278
+ auto loaded = emitLoadOfLValue (loc, std::move (LV), C, isBaseGuaranteed);
1279
+ // If we don't have to reabstract, the load is sufficient.
1280
+ if (!hasAbstractionChange)
1281
+ return loaded;
1282
+
1283
+ // Otherwise, bring the component up to +1 so we can reabstract it.
1284
+ result = std::move (loaded).getAsSingleValue (*this , loc)
1285
+ .copyUnmanaged (*this , loc);
1286
+ } else if (!base.getType ().isAddress ()) {
1282
1287
// For non-address-only structs, we emit a struct_extract sequence.
1283
1288
result = B.createStructExtract (loc, base, field);
1284
1289
@@ -2511,7 +2516,7 @@ class NominalTypeMemberRefRValueEmitter {
2511
2516
// If the field is not a let, bail. We need to use the lvalue logic.
2512
2517
if (!Field->isLet ())
2513
2518
return None;
2514
-
2519
+
2515
2520
// If we are emitting a delegating init super and we have begun the
2516
2521
// super.init call, since self has been exclusively borrowed, we need to be
2517
2522
// conservative and use the lvalue machinery. This ensures that we properly
0 commit comments