diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:06:31 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:06:31 +0000 |
commit | 2ff14448863ac1a1dd9533461708e29aae170c2d (patch) | |
tree | 85b9fea2bbfe3f06473cfa381eed11f273b57c5c /compiler/rustc_transmute | |
parent | Adding debian version 1.64.0+dfsg1-1. (diff) | |
download | rustc-2ff14448863ac1a1dd9533461708e29aae170c2d.tar.xz rustc-2ff14448863ac1a1dd9533461708e29aae170c2d.zip |
Adding debian version 1.65.0+dfsg1-2.debian/1.65.0+dfsg1-2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_transmute')
-rw-r--r-- | compiler/rustc_transmute/Cargo.toml | 5 | ||||
-rw-r--r-- | compiler/rustc_transmute/src/layout/dfa.rs | 1 | ||||
-rw-r--r-- | compiler/rustc_transmute/src/layout/nfa.rs | 6 | ||||
-rw-r--r-- | compiler/rustc_transmute/src/layout/tree.rs | 36 | ||||
-rw-r--r-- | compiler/rustc_transmute/src/lib.rs | 73 | ||||
-rw-r--r-- | compiler/rustc_transmute/src/maybe_transmutable/mod.rs | 6 | ||||
-rw-r--r-- | compiler/rustc_transmute/src/maybe_transmutable/query_context.rs | 2 | ||||
-rw-r--r-- | compiler/rustc_transmute/src/maybe_transmutable/tests.rs | 4 |
8 files changed, 87 insertions, 46 deletions
diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index 9dc96e08a..aa6fe7d24 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -7,7 +7,8 @@ edition = "2021" [dependencies] tracing = "0.1" -rustc_data_structures = { path = "../rustc_data_structures", optional = true} +rustc_data_structures = { path = "../rustc_data_structures"} +rustc_hir = { path = "../rustc_hir", optional = true} rustc_infer = { path = "../rustc_infer", optional = true} rustc_macros = { path = "../rustc_macros", optional = true} rustc_middle = { path = "../rustc_middle", optional = true} @@ -17,7 +18,7 @@ rustc_target = { path = "../rustc_target", optional = true} [features] rustc = [ "rustc_middle", - "rustc_data_structures", + "rustc_hir", "rustc_infer", "rustc_macros", "rustc_span", diff --git a/compiler/rustc_transmute/src/layout/dfa.rs b/compiler/rustc_transmute/src/layout/dfa.rs index b60ea6e7a..b8922696e 100644 --- a/compiler/rustc_transmute/src/layout/dfa.rs +++ b/compiler/rustc_transmute/src/layout/dfa.rs @@ -104,7 +104,6 @@ where } #[instrument(level = "debug")] - #[cfg_attr(feature = "rustc", allow(rustc::potential_query_instability))] pub(crate) fn from_nfa(nfa: Nfa<R>) -> Self { let Nfa { transitions: nfa_transitions, start: nfa_start, accepting: nfa_accepting } = nfa; diff --git a/compiler/rustc_transmute/src/layout/nfa.rs b/compiler/rustc_transmute/src/layout/nfa.rs index f25e3c1fd..c2bc47bc0 100644 --- a/compiler/rustc_transmute/src/layout/nfa.rs +++ b/compiler/rustc_transmute/src/layout/nfa.rs @@ -119,8 +119,6 @@ where let mut transitions: Map<State, Map<Transition<R>, Set<State>>> = self.transitions; - // the iteration order doesn't matter - #[cfg_attr(feature = "rustc", allow(rustc::potential_query_instability))] for (source, transition) in other.transitions { let fix_state = |state| if state == other.start { self.accepting } else { state }; let entry = transitions.entry(fix_state(source)).or_default(); @@ -142,8 +140,6 @@ where let mut transitions: Map<State, Map<Transition<R>, Set<State>>> = self.transitions.clone(); - // the iteration order doesn't matter - #[cfg_attr(feature = "rustc", allow(rustc::potential_query_instability))] for (&(mut source), transition) in other.transitions.iter() { // if source is starting state of `other`, replace with starting state of `self` if source == other.start { @@ -152,8 +148,6 @@ where let entry = transitions.entry(source).or_default(); for (edge, destinations) in transition { let entry = entry.entry(edge.clone()).or_default(); - // the iteration order doesn't matter - #[cfg_attr(feature = "rustc", allow(rustc::potential_query_instability))] for &(mut destination) in destinations { // if dest is accepting state of `other`, replace with accepting state of `self` if destination == other.accepting { diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 70b3ba02b..211c813b8 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -1,4 +1,5 @@ use super::{Byte, Def, Ref}; +use std::ops::ControlFlow; #[cfg(test)] mod tests; @@ -86,17 +87,18 @@ where F: Fn(D) -> bool, { match self { - Self::Seq(elts) => elts - .into_iter() - .map(|elt| elt.prune(f)) - .try_fold(Tree::unit(), |elts, elt| { + Self::Seq(elts) => match elts.into_iter().map(|elt| elt.prune(f)).try_fold( + Tree::unit(), + |elts, elt| { if elt == Tree::uninhabited() { - Err(Tree::uninhabited()) + ControlFlow::Break(Tree::uninhabited()) } else { - Ok(elts.then(elt)) + ControlFlow::Continue(elts.then(elt)) } - }) - .into_ok_or_err(), + }, + ) { + ControlFlow::Break(node) | ControlFlow::Continue(node) => node, + }, Self::Alt(alts) => alts .into_iter() .map(|alt| alt.prune(f)) @@ -315,7 +317,7 @@ pub(crate) mod rustc { tcx, )?, AdtKind::Enum => { - tracing::trace!(?adt_def, "treeifying enum"); + trace!(?adt_def, "treeifying enum"); let mut tree = Tree::uninhabited(); for (idx, discr) in adt_def.discriminants(tcx) { @@ -379,7 +381,7 @@ pub(crate) mod rustc { let clamp = |align: Align| align.clamp(min_align, max_align).bytes().try_into().unwrap(); - let variant_span = tracing::trace_span!( + let variant_span = trace_span!( "treeifying variant", min_align = ?min_align, max_align = ?max_align, @@ -394,27 +396,27 @@ pub(crate) mod rustc { // The layout of the variant is prefixed by the discriminant, if any. if let Some(discr) = discr { - tracing::trace!(?discr, "treeifying discriminant"); + trace!(?discr, "treeifying discriminant"); let discr_layout = alloc::Layout::from_size_align( layout_summary.discriminant_size, clamp(layout_summary.discriminant_align), ) .unwrap(); - tracing::trace!(?discr_layout, "computed discriminant layout"); + 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)); } // Next come fields. - let fields_span = tracing::trace_span!("treeifying fields").entered(); + let fields_span = trace_span!("treeifying fields").entered(); for field_def in variant_def.fields.iter() { let field_ty = field_def.ty(tcx, substs_ref); - let _span = tracing::trace_span!("treeifying field", field = ?field_ty).entered(); + let _span = trace_span!("treeifying field", field = ?field_ty).entered(); // begin with the field's visibility tree = tree.then(Self::def(Def::Field(field_def))); - // compute the field's layout charactaristics + // compute the field's layout characteristics let field_layout = layout_of(tcx, field_ty)?.clamp_align(min_align, max_align); // next comes the field's padding @@ -432,7 +434,7 @@ pub(crate) mod rustc { drop(fields_span); // finally: padding - let padding_span = tracing::trace_span!("adding trailing padding").entered(); + let padding_span = trace_span!("adding trailing padding").entered(); let padding_needed = layout_summary.total_size - variant_layout.size(); if padding_needed > 0 { tree = tree.then(Self::padding(padding_needed)); @@ -465,7 +467,7 @@ pub(crate) mod rustc { layout.align().abi.bytes().try_into().unwrap(), ) .unwrap(); - tracing::trace!(?ty, ?layout, "computed layout for type"); + trace!(?ty, ?layout, "computed layout for type"); Ok(layout) } } diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index cfc7c752a..64cd70d36 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -1,21 +1,12 @@ -#![feature( - alloc_layout_extra, - control_flow_enum, - decl_macro, - iterator_try_reduce, - never_type, - result_into_ok_or_err -)] +#![feature(alloc_layout_extra, control_flow_enum, decl_macro, iterator_try_reduce, never_type)] #![allow(dead_code, unused_variables)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate tracing; -#[cfg(feature = "rustc")] -pub(crate) use rustc_data_structures::fx::{FxHashMap as Map, FxHashSet as Set}; - -#[cfg(not(feature = "rustc"))] -pub(crate) use std::collections::{HashMap as Map, HashSet as Set}; +pub(crate) use rustc_data_structures::fx::{FxIndexMap as Map, FxIndexSet as Set}; pub(crate) mod layout; pub(crate) mod maybe_transmutable; @@ -24,8 +15,8 @@ pub(crate) mod maybe_transmutable; pub struct Assume { pub alignment: bool, pub lifetimes: bool, + pub safety: bool, pub validity: bool, - pub visibility: bool, } /// The type encodes answers to the question: "Are these types transmutable?" @@ -67,11 +58,17 @@ pub enum Reason { #[cfg(feature = "rustc")] mod rustc { + use super::*; + + use rustc_hir::lang_items::LangItem; use rustc_infer::infer::InferCtxt; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::Binder; + use rustc_middle::ty::Const; + use rustc_middle::ty::ParamEnv; use rustc_middle::ty::Ty; + use rustc_middle::ty::TyCtxt; /// The source and destination types of a transmutation. #[derive(TypeFoldable, TypeVisitable, Debug, Clone, Copy)] @@ -111,6 +108,54 @@ mod rustc { .answer() } } + + impl Assume { + /// Constructs an `Assume` from a given const-`Assume`. + pub fn from_const<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + c: Const<'tcx>, + ) -> Self { + use rustc_middle::ty::ScalarInt; + use rustc_middle::ty::TypeVisitable; + use rustc_span::symbol::sym; + + let c = c.eval(tcx, param_env); + + if let Some(err) = c.error_reported() { + return 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."); + + assert_eq!( + tcx.require_lang_item(LangItem::TransmuteOpts, None), + adt_def.did(), + "The given `Const` was not marked with the `{}` lang item.", + LangItem::TransmuteOpts.name(), + ); + + let variant = adt_def.non_enum_variant(); + let fields = c.to_valtree().unwrap_branch(); + + let get_field = |name| { + let (field_idx, _) = variant + .fields + .iter() + .enumerate() + .find(|(_, field_def)| name == field_def.name) + .expect(&format!("There were no fields named `{name}`.")); + fields[field_idx].unwrap_leaf() == ScalarInt::TRUE + }; + + Self { + alignment: get_field(sym::alignment), + lifetimes: get_field(sym::lifetimes), + safety: get_field(sym::safety), + validity: get_field(sym::validity), + } + } + } } #[cfg(feature = "rustc")] diff --git a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs index 076d922d1..1186eac37 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/mod.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/mod.rs @@ -105,12 +105,12 @@ where #[inline(always)] #[instrument(level = "debug", skip(self), fields(src = ?self.src, dst = ?self.dst))] pub(crate) fn answer(self) -> Answer<<C as QueryContext>::Ref> { - let assume_visibility = self.assume.visibility; + let assume_visibility = self.assume.safety; let query_or_answer = self.map_layouts(|src, dst, scope, context| { // Remove all `Def` nodes from `src`, without checking their visibility. let src = src.prune(&|def| true); - tracing::trace!(?src, "pruned src"); + trace!(?src, "pruned src"); // Remove all `Def` nodes from `dst`, additionally... let dst = if assume_visibility { @@ -121,7 +121,7 @@ where dst.prune(&|def| context.is_accessible_from(def, scope)) }; - tracing::trace!(?dst, "pruned dst"); + trace!(?dst, "pruned dst"); // Convert `src` from a tree-based representation to an NFA-based representation. // If the conversion fails because `src` is uninhabited, conclude that the transmutation diff --git a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs index 9c2cf4c9a..adab343ac 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/query_context.rs @@ -82,7 +82,7 @@ mod rustc { false }; - tracing::trace!(?ret, "ret"); + trace!(?ret, "ret"); ret } diff --git a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs index d9d125687..4d5772a4f 100644 --- a/compiler/rustc_transmute/src/maybe_transmutable/tests.rs +++ b/compiler/rustc_transmute/src/maybe_transmutable/tests.rs @@ -13,7 +13,7 @@ mod bool { layout::Tree::<Def, !>::bool(), layout::Tree::<Def, !>::bool(), (), - crate::Assume { alignment: false, lifetimes: false, validity: true, visibility: false }, + crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false }, UltraMinimal, ) .answer(); @@ -26,7 +26,7 @@ mod bool { layout::Dfa::<!>::bool(), layout::Dfa::<!>::bool(), (), - crate::Assume { alignment: false, lifetimes: false, validity: true, visibility: false }, + crate::Assume { alignment: false, lifetimes: false, validity: true, safety: false }, UltraMinimal, ) .answer(); |