summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_transmute
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_transmute')
-rw-r--r--compiler/rustc_transmute/src/layout/tree.rs22
-rw-r--r--compiler/rustc_transmute/src/lib.rs19
2 files changed, 28 insertions, 13 deletions
diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs
index 211c813b8..acd4fa63d 100644
--- a/compiler/rustc_transmute/src/layout/tree.rs
+++ b/compiler/rustc_transmute/src/layout/tree.rs
@@ -404,7 +404,7 @@ pub(crate) mod rustc {
.unwrap();
trace!(?discr_layout, "computed discriminant layout");
variant_layout = variant_layout.extend(discr_layout).unwrap().0;
- tree = tree.then(Self::from_disr(discr, tcx, layout_summary.discriminant_size));
+ tree = tree.then(Self::from_discr(discr, tcx, layout_summary.discriminant_size));
}
// Next come fields.
@@ -444,11 +444,21 @@ pub(crate) mod rustc {
Ok(tree)
}
- pub fn from_disr(discr: Discr<'tcx>, tcx: TyCtxt<'tcx>, size: usize) -> Self {
- // FIXME(@jswrenn): I'm certain this is missing needed endian nuance.
- let bytes = discr.val.to_ne_bytes();
- let bytes = &bytes[..size];
- Self::Seq(bytes.into_iter().copied().map(|b| Self::from_bits(b)).collect())
+ pub fn from_discr(discr: Discr<'tcx>, tcx: TyCtxt<'tcx>, size: usize) -> Self {
+ use rustc_target::abi::Endian;
+
+ let bytes: [u8; 16];
+ let bytes = match tcx.data_layout.endian {
+ Endian::Little => {
+ bytes = discr.val.to_le_bytes();
+ &bytes[..size]
+ }
+ Endian::Big => {
+ bytes = discr.val.to_be_bytes();
+ &bytes[bytes.len() - size..]
+ }
+ };
+ Self::Seq(bytes.iter().map(|&b| Self::from_bits(b)).collect())
}
}
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index 64cd70d36..f7cc94e53 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -80,11 +80,11 @@ mod rustc {
}
pub struct TransmuteTypeEnv<'cx, 'tcx> {
- infcx: &'cx InferCtxt<'cx, 'tcx>,
+ infcx: &'cx InferCtxt<'tcx>,
}
impl<'cx, 'tcx> TransmuteTypeEnv<'cx, 'tcx> {
- pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> Self {
+ pub fn new(infcx: &'cx InferCtxt<'tcx>) -> Self {
Self { infcx }
}
@@ -115,7 +115,7 @@ mod rustc {
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
c: Const<'tcx>,
- ) -> Self {
+ ) -> Option<Self> {
use rustc_middle::ty::ScalarInt;
use rustc_middle::ty::TypeVisitable;
use rustc_span::symbol::sym;
@@ -123,10 +123,15 @@ mod rustc {
let c = c.eval(tcx, param_env);
if let Some(err) = c.error_reported() {
- return Self { alignment: true, lifetimes: true, safety: true, validity: true };
+ return Some(Self {
+ alignment: true,
+ lifetimes: true,
+ safety: true,
+ validity: true,
+ });
}
- let adt_def = c.ty().ty_adt_def().expect("The given `Const` must be an ADT.");
+ let adt_def = c.ty().ty_adt_def()?;
assert_eq!(
tcx.require_lang_item(LangItem::TransmuteOpts, None),
@@ -148,12 +153,12 @@ mod rustc {
fields[field_idx].unwrap_leaf() == ScalarInt::TRUE
};
- Self {
+ Some(Self {
alignment: get_field(sym::alignment),
lifetimes: get_field(sym::lifetimes),
safety: get_field(sym::safety),
validity: get_field(sym::validity),
- }
+ })
}
}
}