Skip to content

Commit fe7f3a3

Browse files
committed
Update the interpreter to handle the new cases
1 parent f4b060e commit fe7f3a3

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

compiler/rustc_const_eval/src/interpret/terminator.rs

+21-8
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>| {

0 commit comments

Comments
 (0)