Add tag_for_variant
query
This query allows for sharing code between `rustc_const_eval` and `rustc_transmutability`. Also moves `DummyMachine` to `rustc_const_eval`.
This commit is contained in:
parent
9023f908cf
commit
2de9010f66
13 changed files with 347 additions and 292 deletions
|
@ -174,10 +174,10 @@ pub(crate) mod rustc {
|
|||
use crate::layout::rustc::{Def, Ref};
|
||||
|
||||
use rustc_middle::ty::layout::LayoutError;
|
||||
use rustc_middle::ty::util::Discr;
|
||||
use rustc_middle::ty::AdtDef;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::ParamEnv;
|
||||
use rustc_middle::ty::ScalarInt;
|
||||
use rustc_middle::ty::VariantDef;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::ErrorGuaranteed;
|
||||
|
@ -331,14 +331,15 @@ pub(crate) mod rustc {
|
|||
trace!(?adt_def, "treeifying enum");
|
||||
let mut tree = Tree::uninhabited();
|
||||
|
||||
for (idx, discr) in adt_def.discriminants(tcx) {
|
||||
for (idx, variant) in adt_def.variants().iter_enumerated() {
|
||||
let tag = tcx.tag_for_variant((ty, idx));
|
||||
tree = tree.or(Self::from_repr_c_variant(
|
||||
ty,
|
||||
*adt_def,
|
||||
args_ref,
|
||||
&layout_summary,
|
||||
Some(discr),
|
||||
adt_def.variant(idx),
|
||||
tag,
|
||||
variant,
|
||||
tcx,
|
||||
)?);
|
||||
}
|
||||
|
@ -393,7 +394,7 @@ pub(crate) mod rustc {
|
|||
adt_def: AdtDef<'tcx>,
|
||||
args_ref: GenericArgsRef<'tcx>,
|
||||
layout_summary: &LayoutSummary,
|
||||
discr: Option<Discr<'tcx>>,
|
||||
tag: Option<ScalarInt>,
|
||||
variant_def: &'tcx VariantDef,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Result<Self, Err> {
|
||||
|
@ -403,9 +404,6 @@ pub(crate) mod rustc {
|
|||
let min_align = repr.align.unwrap_or(Align::ONE);
|
||||
let max_align = repr.pack.unwrap_or(Align::MAX);
|
||||
|
||||
let clamp =
|
||||
|align: Align| align.clamp(min_align, max_align).bytes().try_into().unwrap();
|
||||
|
||||
let variant_span = trace_span!(
|
||||
"treeifying variant",
|
||||
min_align = ?min_align,
|
||||
|
@ -419,17 +417,12 @@ pub(crate) mod rustc {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
// The layout of the variant is prefixed by the discriminant, if any.
|
||||
if let Some(discr) = discr {
|
||||
trace!(?discr, "treeifying discriminant");
|
||||
let discr_layout = alloc::Layout::from_size_align(
|
||||
layout_summary.discriminant_size,
|
||||
clamp(layout_summary.discriminant_align),
|
||||
)
|
||||
.unwrap();
|
||||
trace!(?discr_layout, "computed discriminant layout");
|
||||
variant_layout = variant_layout.extend(discr_layout).unwrap().0;
|
||||
tree = tree.then(Self::from_discr(discr, tcx, layout_summary.discriminant_size));
|
||||
// The layout of the variant is prefixed by the tag, if any.
|
||||
if let Some(tag) = tag {
|
||||
let tag_layout =
|
||||
alloc::Layout::from_size_align(tag.size().bytes_usize(), 1).unwrap();
|
||||
tree = tree.then(Self::from_tag(tag, tcx));
|
||||
variant_layout = variant_layout.extend(tag_layout).unwrap().0;
|
||||
}
|
||||
|
||||
// Next come fields.
|
||||
|
@ -469,18 +462,19 @@ pub(crate) mod rustc {
|
|||
Ok(tree)
|
||||
}
|
||||
|
||||
pub fn from_discr(discr: Discr<'tcx>, tcx: TyCtxt<'tcx>, size: usize) -> Self {
|
||||
pub fn from_tag(tag: ScalarInt, tcx: TyCtxt<'tcx>) -> Self {
|
||||
use rustc_target::abi::Endian;
|
||||
|
||||
let size = tag.size();
|
||||
let bits = tag.to_bits(size).unwrap();
|
||||
let bytes: [u8; 16];
|
||||
let bytes = match tcx.data_layout.endian {
|
||||
Endian::Little => {
|
||||
bytes = discr.val.to_le_bytes();
|
||||
&bytes[..size]
|
||||
bytes = bits.to_le_bytes();
|
||||
&bytes[..size.bytes_usize()]
|
||||
}
|
||||
Endian::Big => {
|
||||
bytes = discr.val.to_be_bytes();
|
||||
&bytes[bytes.len() - size..]
|
||||
bytes = bits.to_be_bytes();
|
||||
&bytes[bytes.len() - size.bytes_usize()..]
|
||||
}
|
||||
};
|
||||
Self::Seq(bytes.iter().map(|&b| Self::from_bits(b)).collect())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue