Skip to content

Commit ff04108

Browse files
committed
Update the interpreter to handle the new cases
1 parent d1b7322 commit ff04108

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

compiler/rustc_const_eval/src/interpret/terminator.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -294,17 +294,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
294294

295295
/// Unwrap types that are guaranteed a null-pointer-optimization
296296
fn unfold_npo(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
297-
// Check if this is `Option` wrapping some type.
298-
let inner = match layout.ty.kind() {
299-
ty::Adt(def, args) if self.tcx.is_diagnostic_item(sym::Option, def.did()) => {
300-
args[0].as_type().unwrap()
301-
}
302-
_ => {
303-
// Not an `Option`.
297+
// Check if this is `Option` wrapping some type or if this is `Result` wrapping a 1-ZST and
298+
// another type.
299+
let ty::Adt(def, args) = layout.ty.kind() else {
300+
// Not an `Option` or Result.
301+
return Ok(layout);
302+
};
303+
let inner = if self.tcx.is_diagnostic_item(sym::Option, def.did()) {
304+
// The wrapped type is the only arg.
305+
self.layout_of(args[0].as_type().unwrap())?
306+
} else if self.tcx.is_diagnostic_item(sym::Result, def.did()) {
307+
// We want to extract which (if any) of the args is not a 1-ZST.
308+
let lhs = self.layout_of(args[0].as_type().unwrap())?;
309+
let rhs = self.layout_of(args[1].as_type().unwrap())?;
310+
if lhs.is_1zst() {
311+
rhs
312+
} else if rhs.is_1zst() {
313+
lhs
314+
} else {
304315
return Ok(layout);
305316
}
317+
} else {
318+
return Ok(layout);
306319
};
307-
let inner = self.layout_of(inner)?;
320+
308321
// Check if the inner type is one of the NPO-guaranteed ones.
309322
// For that we first unpeel transparent *structs* (but not unions).
310323
let is_npo = |def: AdtDef<'tcx>| {

compiler/rustc_target/src/abi/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,8 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
299299
}
300300
found
301301
}
302+
303+
pub fn is_1zst(&self) -> bool {
304+
self.layout.size() == Size::ZERO && self.layout.align().abi == Align::ONE
305+
}
302306
}

0 commit comments

Comments
 (0)