Skip to content

Commit

Permalink
Update the interpreter to handle the new cases
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Jun 4, 2024
1 parent d1b7322 commit ff04108
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
29 changes: 21 additions & 8 deletions compiler/rustc_const_eval/src/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,17 +294,30 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {

/// Unwrap types that are guaranteed a null-pointer-optimization
fn unfold_npo(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, TyAndLayout<'tcx>> {
// Check if this is `Option` wrapping some type.
let inner = match layout.ty.kind() {
ty::Adt(def, args) if self.tcx.is_diagnostic_item(sym::Option, def.did()) => {
args[0].as_type().unwrap()
}
_ => {
// Not an `Option`.
// Check if this is `Option` wrapping some type or if this is `Result` wrapping a 1-ZST and
// another type.
let ty::Adt(def, args) = layout.ty.kind() else {
// Not an `Option` or Result.
return Ok(layout);
};
let inner = if self.tcx.is_diagnostic_item(sym::Option, def.did()) {
// The wrapped type is the only arg.
self.layout_of(args[0].as_type().unwrap())?
} else if self.tcx.is_diagnostic_item(sym::Result, def.did()) {
// We want to extract which (if any) of the args is not a 1-ZST.
let lhs = self.layout_of(args[0].as_type().unwrap())?;
let rhs = self.layout_of(args[1].as_type().unwrap())?;
if lhs.is_1zst() {
rhs
} else if rhs.is_1zst() {
lhs
} else {
return Ok(layout);
}
} else {
return Ok(layout);
};
let inner = self.layout_of(inner)?;

// Check if the inner type is one of the NPO-guaranteed ones.
// For that we first unpeel transparent *structs* (but not unions).
let is_npo = |def: AdtDef<'tcx>| {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_target/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,4 +299,8 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
}
found
}

pub fn is_1zst(&self) -> bool {
self.layout.size() == Size::ZERO && self.layout.align().abi == Align::ONE
}
}

0 comments on commit ff04108

Please sign in to comment.