From 2052d2b17c05fa250206f123fb7c120067bea8d4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 22 Nov 2023 08:41:39 +1100 Subject: [PATCH 01/30] Remove unused feature. --- compiler/rustc_mir_dataflow/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index eea0e030e7d..b0c67c7f251 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -4,7 +4,6 @@ #![feature(let_chains)] #![feature(min_specialization)] #![feature(stmt_expr_attributes)] -#![feature(trusted_step)] #![recursion_limit = "256"] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] From 36b25f5386344a89cecf0718acefc090098881ce Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 22 Nov 2023 08:47:28 +1100 Subject: [PATCH 02/30] Reorder some `use` items. The current order is a mess. --- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index f9468c8e8cc..05d82b0fcb4 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -1,11 +1,3 @@ -use rustc_span::symbol::sym; -use rustc_span::Span; - -use rustc_index::bit_set::ChunkedBitSet; -use rustc_middle::mir::MirPass; -use rustc_middle::mir::{self, Body, Local, Location}; -use rustc_middle::ty::{self, Ty, TyCtxt}; - use crate::errors::{ PeekArgumentNotALocal, PeekArgumentUntracked, PeekBitNotSet, PeekMustBeNotTemporary, PeekMustBePlaceOrRefPlace, StopAfterDataFlowEndedCompilation, @@ -18,6 +10,12 @@ use crate::move_paths::{HasMoveData, MoveData}; use crate::move_paths::{LookupResult, MovePathIndex}; use crate::MoveDataParamEnv; use crate::{Analysis, JoinSemiLattice, ResultsCursor}; +use rustc_index::bit_set::ChunkedBitSet; +use rustc_middle::mir::MirPass; +use rustc_middle::mir::{self, Body, Local, Location}; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::symbol::sym; +use rustc_span::Span; pub struct SanityCheck; From e7781c75f8e3281906a1eac7b7e033c0e25b36d5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 22 Nov 2023 08:49:37 +1100 Subject: [PATCH 03/30] Move `has_rustc_mir_with`. `lib.rs` is a strange place for it, and it's only used within `rustc_peek.rs`, so it doesn't need to be `pub`. --- compiler/rustc_mir_dataflow/src/lib.rs | 18 +----------------- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index b0c67c7f251..b38a3a2b4b2 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -13,12 +13,9 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; -use rustc_ast::MetaItem; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; -use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, TyCtxt}; -use rustc_span::symbol::{sym, Symbol}; +use rustc_middle::ty; pub use self::drop_flag_effects::{ drop_flag_effects_for_function_entry, drop_flag_effects_for_location, @@ -55,16 +52,3 @@ pub struct MoveDataParamEnv<'tcx> { pub move_data: MoveData<'tcx>, pub param_env: ty::ParamEnv<'tcx>, } - -pub fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option { - for attr in tcx.get_attrs(def_id, sym::rustc_mir) { - let items = attr.meta_item_list(); - for item in items.iter().flat_map(|l| l.iter()) { - match item.meta_item() { - Some(mi) if mi.has_name(name) => return Some(mi.clone()), - _ => continue, - } - } - } - None -} diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index 05d82b0fcb4..82917c42ae4 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -10,19 +10,33 @@ use crate::move_paths::{HasMoveData, MoveData}; use crate::move_paths::{LookupResult, MovePathIndex}; use crate::MoveDataParamEnv; use crate::{Analysis, JoinSemiLattice, ResultsCursor}; +use rustc_ast::MetaItem; +use rustc_hir::def_id::DefId; use rustc_index::bit_set::ChunkedBitSet; use rustc_middle::mir::MirPass; use rustc_middle::mir::{self, Body, Local, Location}; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_span::symbol::sym; +use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; pub struct SanityCheck; +pub fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option { + for attr in tcx.get_attrs(def_id, sym::rustc_mir) { + let items = attr.meta_item_list(); + for item in items.iter().flat_map(|l| l.iter()) { + match item.meta_item() { + Some(mi) if mi.has_name(name) => return Some(mi.clone()), + _ => continue, + } + } + } + None +} + // FIXME: This should be a `MirLint`, but it needs to be moved back to `rustc_mir_transform` first. impl<'tcx> MirPass<'tcx> for SanityCheck { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - use crate::has_rustc_mir_with; let def_id = body.source.def_id(); if !tcx.has_attr(def_id, sym::rustc_mir) { debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); From ca741945f401d05d9fa2b7a535e1be7da03a5887 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 22 Nov 2023 08:53:45 +1100 Subject: [PATCH 04/30] Remove `indexes` module. It's not useful, and only obfuscates things. --- compiler/rustc_mir_dataflow/src/drop_flag_effects.rs | 3 +-- compiler/rustc_mir_dataflow/src/lib.rs | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs index 163d74cc9cf..81c1a50a5dd 100644 --- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs +++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs @@ -3,8 +3,7 @@ use rustc_middle::mir::{self, Body, Location, Terminator, TerminatorKind}; use rustc_middle::ty::TyCtxt; use rustc_target::abi::VariantIdx; -use super::indexes::MovePathIndex; -use super::move_paths::{InitKind, LookupResult, MoveData}; +use super::move_paths::{InitKind, LookupResult, MoveData, MovePathIndex}; use super::MoveDataParamEnv; pub fn move_path_children_matching<'tcx, F>( diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index b38a3a2b4b2..cb871ca8d5d 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -44,10 +44,6 @@ pub mod value_analysis; fluent_messages! { "../messages.ftl" } -pub(crate) mod indexes { - pub(crate) use super::move_paths::MovePathIndex; -} - pub struct MoveDataParamEnv<'tcx> { pub move_data: MoveData<'tcx>, pub param_env: ty::ParamEnv<'tcx>, From c16d3f32a489ef92e7812445ecf6dd6d5070439d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 22 Nov 2023 10:25:52 +1100 Subject: [PATCH 05/30] Avoid unnecessary exports. --- compiler/rustc_mir_dataflow/src/drop_flag_effects.rs | 2 +- compiler/rustc_mir_dataflow/src/framework/mod.rs | 2 +- compiler/rustc_mir_dataflow/src/lib.rs | 10 +++++----- compiler/rustc_mir_dataflow/src/un_derefer.rs | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs index 81c1a50a5dd..90c4de1b9c5 100644 --- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs +++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs @@ -128,7 +128,7 @@ pub fn drop_flag_effects_for_location<'tcx, F>( for_location_inits(tcx, body, move_data, loc, |mpi| callback(mpi, DropFlagState::Present)); } -pub fn for_location_inits<'tcx, F>( +fn for_location_inits<'tcx, F>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, move_data: &MoveData<'tcx>, diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index 5020a1cf0b2..a5ae1edf221 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -45,7 +45,7 @@ pub mod graphviz; pub mod lattice; mod visitor; -pub use self::cursor::{AnalysisResults, ResultsClonedCursor, ResultsCursor, ResultsRefCursor}; +pub use self::cursor::{ResultsClonedCursor, ResultsCursor, ResultsRefCursor}; pub use self::direction::{Backward, Direction, Forward}; pub use self::engine::{Engine, EntrySets, Results, ResultsCloned}; pub use self::lattice::{JoinSemiLattice, MaybeReachable}; diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index cb871ca8d5d..81149793c5a 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -22,12 +22,12 @@ pub use self::drop_flag_effects::{ move_path_children_matching, on_all_children_bits, on_lookup_result_bits, }; pub use self::framework::{ - fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, AnalysisResults, Backward, - CloneAnalysis, Direction, Engine, Forward, GenKill, GenKillAnalysis, JoinSemiLattice, - MaybeReachable, Results, ResultsCloned, ResultsClonedCursor, ResultsCursor, ResultsRefCursor, - ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects, + fmt, lattice, visit_results, Analysis, AnalysisDomain, Direction, GenKill, GenKillAnalysis, + JoinSemiLattice, MaybeReachable, Results, ResultsCursor, ResultsVisitable, ResultsVisitor, +}; +use self::framework::{ + Backward, CloneAnalysis, Forward, ResultsClonedCursor, SwitchIntEdgeEffects, }; - use self::move_paths::MoveData; pub mod debuginfo; diff --git a/compiler/rustc_mir_dataflow/src/un_derefer.rs b/compiler/rustc_mir_dataflow/src/un_derefer.rs index 874d50ffd0e..b803ecc575e 100644 --- a/compiler/rustc_mir_dataflow/src/un_derefer.rs +++ b/compiler/rustc_mir_dataflow/src/un_derefer.rs @@ -3,13 +3,13 @@ use rustc_middle::mir::*; /// Used for reverting changes made by `DerefSeparator` #[derive(Default, Debug)] -pub struct UnDerefer<'tcx> { +pub(crate) struct UnDerefer<'tcx> { deref_chains: FxHashMap>>, } impl<'tcx> UnDerefer<'tcx> { #[inline] - pub fn insert(&mut self, local: Local, reffed: PlaceRef<'tcx>) { + pub(crate) fn insert(&mut self, local: Local, reffed: PlaceRef<'tcx>) { let mut chain = self.deref_chains.remove(&reffed.local).unwrap_or_default(); chain.push(reffed); self.deref_chains.insert(local, chain); @@ -17,7 +17,7 @@ impl<'tcx> UnDerefer<'tcx> { /// Returns the chain of places behind `DerefTemp` locals #[inline] - pub fn deref_chain(&self, local: Local) -> &[PlaceRef<'tcx>] { + pub(crate) fn deref_chain(&self, local: Local) -> &[PlaceRef<'tcx>] { self.deref_chains.get(&local).map(Vec::as_slice).unwrap_or_default() } @@ -25,7 +25,7 @@ impl<'tcx> UnDerefer<'tcx> { /// /// See [`PlaceRef::iter_projections`] #[inline] - pub fn iter_projections( + pub(crate) fn iter_projections( &self, place: PlaceRef<'tcx>, ) -> impl Iterator, PlaceElem<'tcx>)> + '_ { From 64a8c4ddda0f73050e3c76eb5a29f8f2eb66008b Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 22 Nov 2023 14:01:52 +1100 Subject: [PATCH 06/30] Reduce `pub` usage. --- .../rustc_mir_dataflow/src/framework/graphviz.rs | 8 ++++---- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 12 +++++------- compiler/rustc_mir_dataflow/src/value_analysis.rs | 2 +- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index c12ccba1e5c..832d1cba9a7 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -15,7 +15,7 @@ use super::fmt::{DebugDiffWithAdapter, DebugWithAdapter, DebugWithContext}; use super::{Analysis, CallReturnPlaces, Direction, Results, ResultsRefCursor, ResultsVisitor}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum OutputStyle { +pub(crate) enum OutputStyle { AfterOnly, BeforeAndAfter, } @@ -29,7 +29,7 @@ impl OutputStyle { } } -pub struct Formatter<'res, 'mir, 'tcx, A> +pub(crate) struct Formatter<'res, 'mir, 'tcx, A> where A: Analysis<'tcx>, { @@ -43,7 +43,7 @@ impl<'res, 'mir, 'tcx, A> Formatter<'res, 'mir, 'tcx, A> where A: Analysis<'tcx>, { - pub fn new( + pub(crate) fn new( body: &'mir Body<'tcx>, results: &'res mut Results<'tcx, A>, style: OutputStyle, @@ -55,7 +55,7 @@ where /// A pair of a basic block and an index into that basic blocks `successors`. #[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub struct CfgEdge { +pub(crate) struct CfgEdge { source: BasicBlock, index: usize, } diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index 82917c42ae4..21fa676ebde 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -21,7 +21,7 @@ use rustc_span::Span; pub struct SanityCheck; -pub fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option { +fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option { for attr in tcx.get_attrs(def_id, sym::rustc_mir) { let items = attr.meta_item_list(); for item in items.iter().flat_map(|l| l.iter()) { @@ -101,10 +101,8 @@ impl<'tcx> MirPass<'tcx> for SanityCheck { /// (If there are any calls to `rustc_peek` that do not match the /// expression form above, then that emits an error as well, but those /// errors are not intended to be used for unit tests.) -pub fn sanity_check_via_rustc_peek<'tcx, A>( - tcx: TyCtxt<'tcx>, - mut cursor: ResultsCursor<'_, 'tcx, A>, -) where +fn sanity_check_via_rustc_peek<'tcx, A>(tcx: TyCtxt<'tcx>, mut cursor: ResultsCursor<'_, 'tcx, A>) +where A: RustcPeekAt<'tcx>, { let def_id = cursor.body().source.def_id(); @@ -185,7 +183,7 @@ impl PeekCallKind { } #[derive(Clone, Copy, Debug)] -pub struct PeekCall { +struct PeekCall { arg: Local, kind: PeekCallKind, span: Span, @@ -233,7 +231,7 @@ impl PeekCall { } } -pub trait RustcPeekAt<'tcx>: Analysis<'tcx> { +trait RustcPeekAt<'tcx>: Analysis<'tcx> { fn peek_at( &self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 025d2ddfd4f..45da1ab9e18 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -921,7 +921,7 @@ impl Map { } /// Locates the given place, if it exists in the tree. - pub fn find_extra( + fn find_extra( &self, place: PlaceRef<'_>, extra: impl IntoIterator, From b8d340db1409e4a8275788597d1e8caab99f053d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 22 Nov 2023 14:15:26 +1100 Subject: [PATCH 07/30] Remove unnecessary `ValueAnalysisWrapper::Direction`. `Forward` is the default. --- compiler/rustc_mir_dataflow/src/lib.rs | 4 +--- compiler/rustc_mir_dataflow/src/value_analysis.rs | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 81149793c5a..cd3378375d8 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -25,9 +25,7 @@ pub use self::framework::{ fmt, lattice, visit_results, Analysis, AnalysisDomain, Direction, GenKill, GenKillAnalysis, JoinSemiLattice, MaybeReachable, Results, ResultsCursor, ResultsVisitable, ResultsVisitor, }; -use self::framework::{ - Backward, CloneAnalysis, Forward, ResultsClonedCursor, SwitchIntEdgeEffects, -}; +use self::framework::{Backward, CloneAnalysis, ResultsClonedCursor, SwitchIntEdgeEffects}; use self::move_paths::MoveData; pub mod debuginfo; diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 45da1ab9e18..addea2c9b87 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -332,8 +332,6 @@ pub struct ValueAnalysisWrapper(pub T); impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper { type Domain = State; - type Direction = crate::Forward; - const NAME: &'static str = T::NAME; fn bottom_value(&self, _body: &Body<'tcx>) -> Self::Domain { From 62ffb14c3d3882efdc93c5e18e2ac843f218b725 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 23 Nov 2023 09:16:08 +1100 Subject: [PATCH 08/30] Remove unnecessary and misleading `..` in a pattern. All the fields are named. --- compiler/rustc_mir_dataflow/src/framework/engine.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index 204e854235f..ef7fe3a8e28 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -239,7 +239,6 @@ where tcx, apply_statement_trans_for_block, pass_name, - .. } = self; let mut dirty_queue: WorkQueue = WorkQueue::with_none(body.basic_blocks.len()); From a65e68a43bc9e71cad3c71ff826d820be7a44260 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 22 Nov 2023 14:36:44 +1100 Subject: [PATCH 09/30] Remove unnecessary things from `State` and `Map`. --- .../rustc_mir_dataflow/src/value_analysis.rs | 29 +++---------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index addea2c9b87..9dcd5f22a2d 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -474,26 +474,10 @@ impl State { } } - pub fn is_reachable(&self) -> bool { + fn is_reachable(&self) -> bool { matches!(&self.0, StateData::Reachable(_)) } - pub fn mark_unreachable(&mut self) { - self.0 = StateData::Unreachable; - } - - pub fn flood_all(&mut self) - where - V: HasTop, - { - self.flood_all_with(V::TOP) - } - - pub fn flood_all_with(&mut self, value: V) { - let StateData::Reachable(values) = &mut self.0 else { return }; - values.raw.fill(value); - } - /// Assign `value` to all places that are contained in `place` or may alias one. pub fn flood_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) { self.flood_with_tail_elem(place, None, map, value) @@ -508,7 +492,7 @@ impl State { } /// Assign `value` to the discriminant of `place` and all places that may alias it. - pub fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) { + fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) { self.flood_with_tail_elem(place, Some(TrackElem::Discriminant), map, value) } @@ -544,7 +528,7 @@ impl State { /// This does nothing if the place is not tracked. /// /// The target place must have been flooded before calling this method. - pub fn insert_idx(&mut self, target: PlaceIndex, result: ValueOrPlace, map: &Map) { + fn insert_idx(&mut self, target: PlaceIndex, result: ValueOrPlace, map: &Map) { match result { ValueOrPlace::Value(value) => self.insert_value_idx(target, value, map), ValueOrPlace::Place(source) => self.insert_place_idx(target, source, map), @@ -908,11 +892,6 @@ impl Map { self.inner_values[root] = start..end; } - /// Returns the number of tracked places, i.e., those for which a value can be stored. - pub fn tracked_places(&self) -> usize { - self.value_count - } - /// Applies a single projection element, yielding the corresponding child. pub fn apply(&self, place: PlaceIndex, elem: TrackElem) -> Option { self.projections.get(&(place, elem)).copied() @@ -952,7 +931,7 @@ impl Map { } /// Iterate over all direct children. - pub fn children(&self, parent: PlaceIndex) -> impl Iterator + '_ { + fn children(&self, parent: PlaceIndex) -> impl Iterator + '_ { Children::new(self, parent) } From f450bf49c033f534de22ac026fd10f035f1af3d0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 23 Nov 2023 09:41:33 +1100 Subject: [PATCH 10/30] Use `'mir` lifetime name more. Some types have a `body: &'mir Body<'tcx>` and some have `body: &'a Body<'tcx>`. The former is more readable, so this commit converts some fo the latter to the former. --- compiler/rustc_borrowck/src/dataflow.rs | 34 +++++++++---------- .../src/framework/direction.rs | 14 ++++---- .../src/framework/engine.rs | 14 ++++---- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 8676d2ba7c4..9b21db9c3ec 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -120,24 +120,24 @@ rustc_index::newtype_index! { /// `BorrowIndex`, and maps each such index to a `BorrowData` /// describing the borrow. These indexes are used for representing the /// borrows in compact bitvectors. -pub struct Borrows<'a, 'tcx> { +pub struct Borrows<'mir, 'tcx> { tcx: TyCtxt<'tcx>, - body: &'a Body<'tcx>, + body: &'mir Body<'tcx>, - borrow_set: &'a BorrowSet<'tcx>, + borrow_set: &'mir BorrowSet<'tcx>, borrows_out_of_scope_at_location: FxIndexMap>, } -struct OutOfScopePrecomputer<'a, 'tcx> { +struct OutOfScopePrecomputer<'mir, 'tcx> { visited: BitSet, visit_stack: Vec, - body: &'a Body<'tcx>, - regioncx: &'a RegionInferenceContext<'tcx>, + body: &'mir Body<'tcx>, + regioncx: &'mir RegionInferenceContext<'tcx>, borrows_out_of_scope_at_location: FxIndexMap>, } -impl<'a, 'tcx> OutOfScopePrecomputer<'a, 'tcx> { - fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self { +impl<'mir, 'tcx> OutOfScopePrecomputer<'mir, 'tcx> { + fn new(body: &'mir Body<'tcx>, regioncx: &'mir RegionInferenceContext<'tcx>) -> Self { OutOfScopePrecomputer { visited: BitSet::new_empty(body.basic_blocks.len()), visit_stack: vec![], @@ -240,17 +240,17 @@ pub fn calculate_borrows_out_of_scope_at_location<'tcx>( prec.borrows_out_of_scope_at_location } -struct PoloniusOutOfScopePrecomputer<'a, 'tcx> { +struct PoloniusOutOfScopePrecomputer<'mir, 'tcx> { visited: BitSet, visit_stack: Vec, - body: &'a Body<'tcx>, - regioncx: &'a RegionInferenceContext<'tcx>, + body: &'mir Body<'tcx>, + regioncx: &'mir RegionInferenceContext<'tcx>, loans_out_of_scope_at_location: FxIndexMap>, } -impl<'a, 'tcx> PoloniusOutOfScopePrecomputer<'a, 'tcx> { - fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self { +impl<'mir, 'tcx> PoloniusOutOfScopePrecomputer<'mir, 'tcx> { + fn new(body: &'mir Body<'tcx>, regioncx: &'mir RegionInferenceContext<'tcx>) -> Self { Self { visited: BitSet::new_empty(body.basic_blocks.len()), visit_stack: vec![], @@ -403,12 +403,12 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> { } } -impl<'a, 'tcx> Borrows<'a, 'tcx> { +impl<'mir, 'tcx> Borrows<'mir, 'tcx> { pub fn new( tcx: TyCtxt<'tcx>, - body: &'a Body<'tcx>, - regioncx: &'a RegionInferenceContext<'tcx>, - borrow_set: &'a BorrowSet<'tcx>, + body: &'mir Body<'tcx>, + regioncx: &'mir RegionInferenceContext<'tcx>, + borrow_set: &'mir BorrowSet<'tcx>, ) -> Self { let mut borrows_out_of_scope_at_location = calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set); diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 04c9f7a016c..08b7b1a2619 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -287,12 +287,12 @@ impl Direction for Backward { } } -struct BackwardSwitchIntEdgeEffectsApplier<'a, 'tcx, D, F> { - body: &'a mir::Body<'tcx>, +struct BackwardSwitchIntEdgeEffectsApplier<'mir, 'tcx, D, F> { + body: &'mir mir::Body<'tcx>, pred: BasicBlock, - exit_state: &'a mut D, + exit_state: &'mir mut D, bb: BasicBlock, - propagate: &'a mut F, + propagate: &'mir mut F, effects_applied: bool, } @@ -523,9 +523,9 @@ impl Direction for Forward { } } -struct ForwardSwitchIntEdgeEffectsApplier<'a, D, F> { - exit_state: &'a mut D, - targets: &'a SwitchTargets, +struct ForwardSwitchIntEdgeEffectsApplier<'mir, D, F> { + exit_state: &'mir mut D, + targets: &'mir SwitchTargets, propagate: F, effects_applied: bool, diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index ef7fe3a8e28..ed82b1e8cdc 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -128,12 +128,12 @@ where } /// A solver for dataflow problems. -pub struct Engine<'a, 'tcx, A> +pub struct Engine<'mir, 'tcx, A> where A: Analysis<'tcx>, { tcx: TyCtxt<'tcx>, - body: &'a mir::Body<'tcx>, + body: &'mir mir::Body<'tcx>, entry_sets: IndexVec, pass_name: Option<&'static str>, analysis: A, @@ -147,14 +147,14 @@ where apply_statement_trans_for_block: Option>, } -impl<'a, 'tcx, A, D, T> Engine<'a, 'tcx, A> +impl<'mir, 'tcx, A, D, T> Engine<'mir, 'tcx, A> where A: GenKillAnalysis<'tcx, Idx = T, Domain = D>, D: Clone + JoinSemiLattice + GenKill + BitSetExt, T: Idx, { /// Creates a new `Engine` to solve a gen-kill dataflow problem. - pub fn new_gen_kill(tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, mut analysis: A) -> Self { + pub fn new_gen_kill(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, mut analysis: A) -> Self { // If there are no back-edges in the control-flow graph, we only ever need to apply the // transfer function for each block exactly once (assuming that we process blocks in RPO). // @@ -186,7 +186,7 @@ where } } -impl<'a, 'tcx, A, D> Engine<'a, 'tcx, A> +impl<'mir, 'tcx, A, D> Engine<'mir, 'tcx, A> where A: Analysis<'tcx, Domain = D>, D: Clone + JoinSemiLattice, @@ -196,13 +196,13 @@ where /// /// Gen-kill problems should use `new_gen_kill`, which will coalesce transfer functions for /// better performance. - pub fn new_generic(tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, analysis: A) -> Self { + pub fn new_generic(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, analysis: A) -> Self { Self::new(tcx, body, analysis, None) } fn new( tcx: TyCtxt<'tcx>, - body: &'a mir::Body<'tcx>, + body: &'mir mir::Body<'tcx>, analysis: A, apply_statement_trans_for_block: Option>, ) -> Self { From e4fc5df7cca4d18a9ccce0d6d735a4cf2643aecd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 23 Nov 2023 16:46:44 +1100 Subject: [PATCH 11/30] Remove an unneeded local variable. `body` is already a `&Body`. --- compiler/rustc_mir_transform/src/coroutine.rs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index aa4d8ddad56..6fe73b03e40 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -651,36 +651,34 @@ fn locals_live_across_suspend_points<'tcx>( always_live_locals: &BitSet, movable: bool, ) -> LivenessInfo { - let body_ref: &Body<'_> = body; - // Calculate when MIR locals have live storage. This gives us an upper bound of their // lifetimes. let mut storage_live = MaybeStorageLive::new(std::borrow::Cow::Borrowed(always_live_locals)) - .into_engine(tcx, body_ref) + .into_engine(tcx, body) .iterate_to_fixpoint() - .into_results_cursor(body_ref); + .into_results_cursor(body); // Calculate the MIR locals which have been previously // borrowed (even if they are still active). let borrowed_locals_results = - MaybeBorrowedLocals.into_engine(tcx, body_ref).pass_name("coroutine").iterate_to_fixpoint(); + MaybeBorrowedLocals.into_engine(tcx, body).pass_name("coroutine").iterate_to_fixpoint(); - let mut borrowed_locals_cursor = borrowed_locals_results.cloned_results_cursor(body_ref); + let mut borrowed_locals_cursor = borrowed_locals_results.cloned_results_cursor(body); // Calculate the MIR locals that we actually need to keep storage around // for. let mut requires_storage_results = MaybeRequiresStorage::new(borrowed_locals_results.cloned_results_cursor(body)) - .into_engine(tcx, body_ref) + .into_engine(tcx, body) .iterate_to_fixpoint(); - let mut requires_storage_cursor = requires_storage_results.as_results_cursor(body_ref); + let mut requires_storage_cursor = requires_storage_results.as_results_cursor(body); // Calculate the liveness of MIR locals ignoring borrows. let mut liveness = MaybeLiveLocals - .into_engine(tcx, body_ref) + .into_engine(tcx, body) .pass_name("coroutine") .iterate_to_fixpoint() - .into_results_cursor(body_ref); + .into_results_cursor(body); let mut storage_liveness_map = IndexVec::from_elem(None, &body.basic_blocks); let mut live_locals_at_suspension_points = Vec::new(); @@ -746,7 +744,7 @@ fn locals_live_across_suspend_points<'tcx>( .collect(); let storage_conflicts = compute_storage_conflicts( - body_ref, + body, &saved_locals, always_live_locals.clone(), requires_storage_results, From dc365e8c37bf07fa25bb263711c359333c9808e8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 24 Nov 2023 06:13:00 +1100 Subject: [PATCH 12/30] Remove unneeded derives from `MaybeLiveLocals`. --- compiler/rustc_mir_dataflow/src/impls/liveness.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index bdfb6a6ff6b..c3fdca1641a 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -23,7 +23,6 @@ use crate::{Analysis, AnalysisDomain, Backward, GenKill, GenKillAnalysis}; /// [`MaybeBorrowedLocals`]: super::MaybeBorrowedLocals /// [flow-test]: https://github.com/rust-lang/rust/blob/a08c47310c7d49cbdc5d7afb38408ba519967ecd/src/test/ui/mir-dataflow/liveness-ptr.rs /// [liveness]: https://en.wikipedia.org/wiki/Live_variable_analysis -#[derive(Clone, Copy)] pub struct MaybeLiveLocals; impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals { From 118308ee0385e98f0ad3709061281d139835b606 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 24 Nov 2023 06:15:32 +1100 Subject: [PATCH 13/30] Remove unused `EverInitializedPlaces::tcx` field. --- compiler/rustc_borrowck/src/lib.rs | 2 +- compiler/rustc_mir_dataflow/src/impls/initialized.rs | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 0bfd2e7e710..804060d00ed 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -288,7 +288,7 @@ fn do_mir_borrowck<'tcx>( .into_engine(tcx, body) .pass_name("borrowck") .iterate_to_fixpoint(); - let flow_ever_inits = EverInitializedPlaces::new(tcx, body, &mdpe) + let flow_ever_inits = EverInitializedPlaces::new(body, &mdpe) .into_engine(tcx, body) .pass_name("borrowck") .iterate_to_fixpoint(); diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index 61be100d70e..daf479bdb4f 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -250,15 +250,13 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { /// } /// ``` pub struct EverInitializedPlaces<'a, 'tcx> { - #[allow(dead_code)] - tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>, } impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { - EverInitializedPlaces { tcx, body, mdpe } + pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { + EverInitializedPlaces { body, mdpe } } } From 0f12da17c0b04a16963ea749186d9db2e50027b8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 24 Nov 2023 06:26:15 +1100 Subject: [PATCH 14/30] Remove unused arguments from `on_all_children_bits`. `on_all_children_bits` has two arguments that are unused: `tcx` and `body`. This was not detected by the compiler because it's a recursive function. This commit removes them, and removes lots of other arguments and fields that are no longer necessary. --- .../src/drop_flag_effects.rs | 42 ++++----------- .../src/impls/initialized.rs | 37 +++++--------- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 2 +- .../src/elaborate_drops.rs | 51 +++++++------------ 4 files changed, 42 insertions(+), 90 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs index 90c4de1b9c5..de1ca8d823b 100644 --- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs +++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs @@ -1,6 +1,5 @@ use crate::elaborate_drops::DropFlagState; use rustc_middle::mir::{self, Body, Location, Terminator, TerminatorKind}; -use rustc_middle::ty::TyCtxt; use rustc_target::abi::VariantIdx; use super::move_paths::{InitKind, LookupResult, MoveData, MovePathIndex}; @@ -29,8 +28,6 @@ where } pub fn on_lookup_result_bits<'tcx, F>( - tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, move_data: &MoveData<'tcx>, lookup_result: LookupResult, each_child: F, @@ -41,13 +38,11 @@ pub fn on_lookup_result_bits<'tcx, F>( LookupResult::Parent(..) => { // access to untracked value - do not touch children } - LookupResult::Exact(e) => on_all_children_bits(tcx, body, move_data, e, each_child), + LookupResult::Exact(e) => on_all_children_bits(move_data, e, each_child), } } pub fn on_all_children_bits<'tcx, F>( - tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, move_data: &MoveData<'tcx>, move_path_index: MovePathIndex, mut each_child: F, @@ -55,8 +50,6 @@ pub fn on_all_children_bits<'tcx, F>( F: FnMut(MovePathIndex), { fn on_all_children_bits<'tcx, F>( - tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, move_data: &MoveData<'tcx>, move_path_index: MovePathIndex, each_child: &mut F, @@ -67,15 +60,14 @@ pub fn on_all_children_bits<'tcx, F>( let mut next_child_index = move_data.move_paths[move_path_index].first_child; while let Some(child_index) = next_child_index { - on_all_children_bits(tcx, body, move_data, child_index, each_child); + on_all_children_bits(move_data, child_index, each_child); next_child_index = move_data.move_paths[child_index].next_sibling; } } - on_all_children_bits(tcx, body, move_data, move_path_index, &mut each_child); + on_all_children_bits(move_data, move_path_index, &mut each_child); } pub fn drop_flag_effects_for_function_entry<'tcx, F>( - tcx: TyCtxt<'tcx>, body: &Body<'tcx>, ctxt: &MoveDataParamEnv<'tcx>, mut callback: F, @@ -86,14 +78,13 @@ pub fn drop_flag_effects_for_function_entry<'tcx, F>( for arg in body.args_iter() { let place = mir::Place::from(arg); let lookup_result = move_data.rev_lookup.find(place.as_ref()); - on_lookup_result_bits(tcx, body, move_data, lookup_result, |mpi| { + on_lookup_result_bits(move_data, lookup_result, |mpi| { callback(mpi, DropFlagState::Present) }); } } pub fn drop_flag_effects_for_location<'tcx, F>( - tcx: TyCtxt<'tcx>, body: &Body<'tcx>, ctxt: &MoveDataParamEnv<'tcx>, loc: Location, @@ -109,7 +100,7 @@ pub fn drop_flag_effects_for_location<'tcx, F>( let path = mi.move_path_index(move_data); debug!("moving out of path {:?}", move_data.move_paths[path]); - on_all_children_bits(tcx, body, move_data, path, |mpi| callback(mpi, DropFlagState::Absent)) + on_all_children_bits(move_data, path, |mpi| callback(mpi, DropFlagState::Absent)) } // Drop does not count as a move but we should still consider the variable uninitialized. @@ -117,24 +108,17 @@ pub fn drop_flag_effects_for_location<'tcx, F>( body.stmt_at(loc).right() { if let LookupResult::Exact(mpi) = move_data.rev_lookup.find(place.as_ref()) { - on_all_children_bits(tcx, body, move_data, mpi, |mpi| { - callback(mpi, DropFlagState::Absent) - }) + on_all_children_bits(move_data, mpi, |mpi| callback(mpi, DropFlagState::Absent)) } } debug!("drop_flag_effects: assignment for location({:?})", loc); - for_location_inits(tcx, body, move_data, loc, |mpi| callback(mpi, DropFlagState::Present)); + for_location_inits(move_data, loc, |mpi| callback(mpi, DropFlagState::Present)); } -fn for_location_inits<'tcx, F>( - tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, - move_data: &MoveData<'tcx>, - loc: Location, - mut callback: F, -) where +fn for_location_inits<'tcx, F>(move_data: &MoveData<'tcx>, loc: Location, mut callback: F) +where F: FnMut(MovePathIndex), { for ii in &move_data.init_loc_map[loc] { @@ -143,7 +127,7 @@ fn for_location_inits<'tcx, F>( InitKind::Deep => { let path = init.path; - on_all_children_bits(tcx, body, move_data, path, &mut callback) + on_all_children_bits(move_data, path, &mut callback) } InitKind::Shallow => { let mpi = init.path; @@ -160,8 +144,6 @@ fn for_location_inits<'tcx, F>( /// NOTE: If there are no move paths corresponding to an inactive variant, /// `handle_inactive_variant` will not be called for that variant. pub(crate) fn on_all_inactive_variants<'tcx>( - tcx: TyCtxt<'tcx>, - body: &mir::Body<'tcx>, move_data: &MoveData<'tcx>, enum_place: mir::Place<'tcx>, active_variant: VariantIdx, @@ -184,9 +166,7 @@ pub(crate) fn on_all_inactive_variants<'tcx>( }; if variant_idx != active_variant { - on_all_children_bits(tcx, body, move_data, variant_mpi, |mpi| { - handle_inactive_variant(mpi) - }); + on_all_children_bits(move_data, variant_mpi, |mpi| handle_inactive_variant(mpi)); } } } diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs index daf479bdb4f..b050e963d8e 100644 --- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs +++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> { ) -> bool { if let LookupResult::Exact(path) = self.move_data().rev_lookup.find(place.as_ref()) { let mut maybe_live = false; - on_all_children_bits(self.tcx, self.body, self.move_data(), path, |child| { + on_all_children_bits(self.move_data(), path, |child| { maybe_live |= state.contains(child); }); !maybe_live @@ -203,14 +203,13 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> { /// this data and `MaybeInitializedPlaces` yields the set of places /// that would require a dynamic drop-flag at that statement. pub struct DefinitelyInitializedPlaces<'a, 'tcx> { - tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>, } impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> { - pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { - DefinitelyInitializedPlaces { tcx, body, mdpe } + pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self { + DefinitelyInitializedPlaces { body, mdpe } } } @@ -317,7 +316,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) { *state = MaybeReachable::Reachable(ChunkedBitSet::new_empty(self.move_data().move_paths.len())); - drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| { + drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| { assert!(s == DropFlagState::Present); state.gen(path); }); @@ -337,7 +336,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { statement: &mir::Statement<'tcx>, location: Location, ) { - drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { Self::update_bits(trans, path, s) }); @@ -349,7 +348,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { | mir::Rvalue::AddressOf(_, place) = rvalue && let LookupResult::Exact(mpi) = self.move_data().rev_lookup.find(place.as_ref()) { - on_all_children_bits(self.tcx, self.body, self.move_data(), mpi, |child| { + on_all_children_bits(self.move_data(), mpi, |child| { trans.gen(child); }) } @@ -369,7 +368,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { { edges = TerminatorEdges::Single(target); } - drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { Self::update_bits(state, path, s) }); edges @@ -385,8 +384,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). on_lookup_result_bits( - self.tcx, - self.body, self.move_data(), self.move_data().rev_lookup.find(place.as_ref()), |mpi| { @@ -430,8 +427,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> { // Kill all move paths that correspond to variants we know to be inactive along this // particular outgoing edge of a `SwitchInt`. drop_flag_effects::on_all_inactive_variants( - self.tcx, - self.body, self.move_data(), enum_place, variant, @@ -456,7 +451,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { // set all bits to 1 (uninit) before gathering counter-evidence state.insert_all(); - drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| { + drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| { assert!(s == DropFlagState::Present); state.remove(path); }); @@ -476,7 +471,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { _statement: &mir::Statement<'tcx>, location: Location, ) { - drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { Self::update_bits(trans, path, s) }); @@ -490,7 +485,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { terminator: &'mir mir::Terminator<'tcx>, location: Location, ) -> TerminatorEdges<'mir, 'tcx> { - drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { Self::update_bits(trans, path, s) }); if self.skip_unreachable_unwind.contains(location.block) { @@ -512,8 +507,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { // when a call returns successfully, that means we need to set // the bits for that dest_place to 0 (initialized). on_lookup_result_bits( - self.tcx, - self.body, self.move_data(), self.move_data().rev_lookup.find(place.as_ref()), |mpi| { @@ -561,8 +554,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { // Mark all move paths that correspond to variants other than this one as maybe // uninitialized (in reality, they are *definitely* uninitialized). drop_flag_effects::on_all_inactive_variants( - self.tcx, - self.body, self.move_data(), enum_place, variant, @@ -587,7 +578,7 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> { fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) { state.0.clear(); - drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| { + drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| { assert!(s == DropFlagState::Present); state.0.insert(path); }); @@ -607,7 +598,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { _statement: &mir::Statement<'tcx>, location: Location, ) { - drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { Self::update_bits(trans, path, s) }) } @@ -618,7 +609,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { terminator: &'mir mir::Terminator<'tcx>, location: Location, ) -> TerminatorEdges<'mir, 'tcx> { - drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| { + drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| { Self::update_bits(trans, path, s) }); terminator.edges() @@ -634,8 +625,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). on_lookup_result_bits( - self.tcx, - self.body, self.move_data(), self.move_data().rev_lookup.find(place.as_ref()), |mpi| { diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index 21fa676ebde..b592b2f5d41 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -66,7 +66,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck { } if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_definite_init).is_some() { - let flow_def_inits = DefinitelyInitializedPlaces::new(tcx, body, &mdpe) + let flow_def_inits = DefinitelyInitializedPlaces::new(body, &mdpe) .into_engine(tcx, body) .iterate_to_fixpoint(); diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index d4e40a1b57c..83517aef7e2 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -172,19 +172,13 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { let mut some_live = false; let mut some_dead = false; let mut children_count = 0; - on_all_children_bits( - self.tcx(), - self.body(), - self.ctxt.move_data(), - path, - |child| { - let (live, dead) = self.ctxt.init_data.maybe_live_dead(child); - debug!("elaborate_drop: state({:?}) = {:?}", child, (live, dead)); - some_live |= live; - some_dead |= dead; - children_count += 1; - }, - ); + on_all_children_bits(self.ctxt.move_data(), path, |child| { + let (live, dead) = self.ctxt.init_data.maybe_live_dead(child); + debug!("elaborate_drop: state({:?}) = {:?}", child, (live, dead)); + some_live |= live; + some_dead |= dead; + children_count += 1; + }); ((some_live, some_dead), children_count != 1) } }; @@ -202,13 +196,9 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { self.ctxt.set_drop_flag(loc, path, DropFlagState::Absent); } DropFlagMode::Deep => { - on_all_children_bits( - self.tcx(), - self.body(), - self.ctxt.move_data(), - path, - |child| self.ctxt.set_drop_flag(loc, child, DropFlagState::Absent), - ); + on_all_children_bits(self.ctxt.move_data(), path, |child| { + self.ctxt.set_drop_flag(loc, child, DropFlagState::Absent) + }); } } } @@ -268,10 +258,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } fn create_drop_flag(&mut self, index: MovePathIndex, span: Span) { - let tcx = self.tcx; let patch = &mut self.patch; debug!("create_drop_flag({:?})", self.body.span); - self.drop_flags[index].get_or_insert_with(|| patch.new_temp(tcx.types.bool, span)); + self.drop_flags[index].get_or_insert_with(|| patch.new_temp(self.tcx.types.bool, span)); } fn drop_flag(&mut self, index: MovePathIndex) -> Option> { @@ -304,7 +293,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { match path { LookupResult::Exact(path) => { self.init_data.seek_before(self.body.terminator_loc(bb)); - on_all_children_bits(self.tcx, self.body, self.move_data(), path, |child| { + on_all_children_bits(self.move_data(), path, |child| { let (maybe_live, maybe_dead) = self.init_data.maybe_live_dead(child); debug!( "collect_drop_flags: collecting {:?} from {:?}@{:?} - {:?}", @@ -444,7 +433,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let loc = Location { block: tgt, statement_index: 0 }; let path = self.move_data().rev_lookup.find(destination.as_ref()); - on_lookup_result_bits(self.tcx, self.body, self.move_data(), path, |child| { + on_lookup_result_bits(self.move_data(), path, |child| { self.set_drop_flag(loc, child, DropFlagState::Present) }); } @@ -453,14 +442,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn drop_flags_for_args(&mut self) { let loc = Location::START; - rustc_mir_dataflow::drop_flag_effects_for_function_entry( - self.tcx, - self.body, - self.env, - |path, ds| { - self.set_drop_flag(loc, path, ds); - }, - ) + rustc_mir_dataflow::drop_flag_effects_for_function_entry(self.body, self.env, |path, ds| { + self.set_drop_flag(loc, path, ds); + }) } fn drop_flags_for_locs(&mut self) { @@ -492,7 +476,6 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } let loc = Location { block: bb, statement_index: i }; rustc_mir_dataflow::drop_flag_effects_for_location( - self.tcx, self.body, self.env, loc, @@ -515,7 +498,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let loc = Location { block: bb, statement_index: data.statements.len() }; let path = self.move_data().rev_lookup.find(destination.as_ref()); - on_lookup_result_bits(self.tcx, self.body, self.move_data(), path, |child| { + on_lookup_result_bits(self.move_data(), path, |child| { self.set_drop_flag(loc, child, DropFlagState::Present) }); } From 406c0b8ae4f1f1f8406b30890cbbc0062ca2505c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 24 Nov 2023 13:12:08 +1100 Subject: [PATCH 15/30] Remove unnecessary `mut`. `mut_results` immediately below is the `&mut self` version, this one should be `&self`. --- compiler/rustc_mir_dataflow/src/framework/cursor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs index c978bddfef5..6285199e5b6 100644 --- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs @@ -147,7 +147,7 @@ where } /// Returns the underlying `Results`. - pub fn results(&mut self) -> &Results<'tcx, A, R::EntrySets> { + pub fn results(&self) -> &Results<'tcx, A, R::EntrySets> { self.results.borrow() } From 912eb1f7c196c840536b45b2a2781639552ff884 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 24 Nov 2023 13:13:09 +1100 Subject: [PATCH 16/30] Remove `ResultsCursor::get_with_analysis`. We can just call `ResultsCursor::state` and `ResultsCursor::analysis` separately. --- compiler/rustc_mir_dataflow/src/framework/cursor.rs | 5 ----- compiler/rustc_mir_dataflow/src/rustc_peek.rs | 3 ++- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs index 6285199e5b6..c9bce80853d 100644 --- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs +++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs @@ -166,11 +166,6 @@ where &mut self.results.borrow_mut().analysis } - /// Returns both the dataflow state at the current location and the `Analysis`. - pub fn get_with_analysis(&mut self) -> (&A::Domain, &mut A) { - (&self.state, &mut self.results.borrow_mut().analysis) - } - /// Resets the cursor to hold the entry set for the given basic block. /// /// For forward dataflow analyses, this is the dataflow state prior to the first statement. diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs index b592b2f5d41..448128b6993 100644 --- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs +++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs @@ -139,7 +139,8 @@ where ) => { let loc = Location { block: bb, statement_index }; cursor.seek_before_primary_effect(loc); - let (state, analysis) = cursor.get_with_analysis(); + let state = cursor.get(); + let analysis = cursor.analysis(); analysis.peek_at(tcx, *place, state, call); } From 8cc7073d64578c81f5e6ed23120733040a22d78a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 24 Nov 2023 08:49:37 -0800 Subject: [PATCH 17/30] Replace `option.map(cond) == Some(true)` with `option.is_some_and(cond)` --- .../scripts/rustc-clif.rs | 2 +- .../scripts/rustdoc-clif.rs | 2 +- compiler/rustc_expand/src/tests.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 10 ++++++---- .../error_reporting/nice_region_error/util.rs | 3 +-- compiler/rustc_lint/src/non_fmt_panic.rs | 16 ++++++---------- src/librustdoc/html/render/print_item.rs | 6 ++++-- src/tools/compiletest/src/header.rs | 2 +- 8 files changed, 21 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs b/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs index 33d51bdddea..550f2051553 100644 --- a/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs +++ b/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs @@ -27,7 +27,7 @@ fn main() { args.push(codegen_backend_arg); } if !passed_args.iter().any(|arg| { - arg == "--sysroot" || arg.to_str().map(|s| s.starts_with("--sysroot=")) == Some(true) + arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot=")) }) { args.push(OsString::from("--sysroot")); args.push(OsString::from(sysroot.to_str().unwrap())); diff --git a/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs b/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs index 10582cc7bb3..f7d1bdbc4c6 100644 --- a/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs +++ b/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs @@ -27,7 +27,7 @@ fn main() { args.push(codegen_backend_arg); } if !passed_args.iter().any(|arg| { - arg == "--sysroot" || arg.to_str().map(|s| s.starts_with("--sysroot=")) == Some(true) + arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot=")) }) { args.push(OsString::from("--sysroot")); args.push(OsString::from(sysroot.to_str().unwrap())); diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 9f52669e188..b4724b0e9d0 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -135,7 +135,7 @@ pub(crate) fn matches_codepattern(a: &str, b: &str) -> bool { /// Advances the given peekable `Iterator` until it reaches a non-whitespace character. fn scan_for_non_ws_or_end>(iter: &mut Peekable) { - while iter.peek().copied().map(rustc_lexer::is_whitespace) == Some(true) { + while iter.peek().copied().is_some_and(rustc_lexer::is_whitespace) { iter.next(); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 78e755378f5..773f184472b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2293,12 +2293,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let clone_trait = self.tcx.require_lang_item(LangItem::Clone, Some(segment.ident.span)); if args.is_empty() - && self.typeck_results.borrow().type_dependent_def_id(expr.hir_id).map( - |did| { + && self + .typeck_results + .borrow() + .type_dependent_def_id(expr.hir_id) + .is_some_and(|did| { let ai = self.tcx.associated_item(did); ai.trait_container(self.tcx) == Some(clone_trait) - }, - ) == Some(true) + }) && segment.ident.name == sym::clone { // If this expression had a clone call when suggesting borrowing diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 7252a812466..b26ce464486 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -161,7 +161,6 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { && self .tcx() .opt_associated_item(scope_def_id.to_def_id()) - .map(|i| i.fn_has_self_parameter) - == Some(true) + .is_some_and(|i| i.fn_has_self_parameter) } } diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index b218cc5789d..f0e415492ae 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -154,17 +154,13 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc let infcx = cx.tcx.infer_ctxt().build(); let suggest_display = is_str - || cx - .tcx - .get_diagnostic_item(sym::Display) - .map(|t| infcx.type_implements_trait(t, [ty], cx.param_env).may_apply()) - == Some(true); + || cx.tcx.get_diagnostic_item(sym::Display).is_some_and(|t| { + infcx.type_implements_trait(t, [ty], cx.param_env).may_apply() + }); let suggest_debug = !suggest_display - && cx - .tcx - .get_diagnostic_item(sym::Debug) - .map(|t| infcx.type_implements_trait(t, [ty], cx.param_env).may_apply()) - == Some(true); + && cx.tcx.get_diagnostic_item(sym::Debug).is_some_and(|t| { + infcx.type_implements_trait(t, [ty], cx.param_env).may_apply() + }); let suggest_panic_any = !is_str && panic == sym::std_panic_macro; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index ce9e1bcf488..14387e0d45d 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -596,8 +596,10 @@ fn extra_info_tags<'a, 'tcx: 'a>( // The "rustc_private" crates are permanently unstable so it makes no sense // to render "unstable" everywhere. - if item.stability(tcx).as_ref().map(|s| s.is_unstable() && s.feature != sym::rustc_private) - == Some(true) + if item + .stability(tcx) + .as_ref() + .is_some_and(|s| s.is_unstable() && s.feature != sym::rustc_private) { write!(f, "{}", tag_html("unstable", "", "Experimental"))?; } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index d6516cff63f..f85f9e674ab 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -632,7 +632,7 @@ fn iter_header_extra( it(None, directive, 0); } - let comment = if testfile.extension().map(|e| e == "rs") == Some(true) { "//" } else { "#" }; + let comment = if testfile.extension().is_some_and(|e| e == "rs") { "//" } else { "#" }; let mut rdr = BufReader::new(rdr); let mut ln = String::new(); From 7a6dce3305d296daa1d77f8716923faa461a135e Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 24 Nov 2023 09:12:05 -0800 Subject: [PATCH 18/30] Request that rust-analyzer changes are sent upstream first if possible --- triagebot.toml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index a72338d1950..9ff4f73bcb5 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -533,6 +533,12 @@ message = "The Miri subtree was changed" cc = ["@rust-lang/miri"] [mentions."src/tools/rust-analyzer"] +message = """ +rust-analyzer is developed in its own repository. If possible, consider making \ +this change to [rust-lang/rust-analyzer] instead. + +[rust-lang/rust-analyzer]: https://github.com/rust-lang/rust-analyzer +""" cc = ["@rust-lang/rust-analyzer"] [mentions."src/tools/rustfmt"] From 1b7b9540fe15c8c7681a47a701e57b9de22b8aba Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 24 Nov 2023 09:47:55 -0700 Subject: [PATCH 19/30] rustdoc-search: avoid infinite where clause unbox Fixes #118242 --- src/librustdoc/html/static/js/search.js | 32 ++++++++++++++++------ tests/rustdoc-js/assoc-type-loop.js | 9 +++++++ tests/rustdoc-js/assoc-type-loop.rs | 35 +++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 tests/rustdoc-js/assoc-type-loop.js create mode 100644 tests/rustdoc-js/assoc-type-loop.rs diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 4822690fd04..0bb56cd9710 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1755,17 +1755,26 @@ function initSearch(rawSearchIndex) { if (mgens && mgens.has(fnType.id) && mgens.get(fnType.id) !== 0) { return false; } + // Where clauses can represent cyclical data. + // `null` prevents it from trying to unbox in an infinite loop + const mgensTmp = new Map(mgens); + mgensTmp.set(fnType.id, null); // This is only a potential unbox if the search query appears in the where clause // for example, searching `Read -> usize` should find // `fn read_all(R) -> Result` // generic `R` is considered "unboxed" - return checkIfInList(whereClause[(-fnType.id) - 1], queryElem, whereClause); + return checkIfInList( + whereClause[(-fnType.id) - 1], + queryElem, + whereClause, + mgensTmp + ); } else if (fnType.generics.length > 0 || fnType.bindings.size > 0) { const simplifiedGenerics = [ ...fnType.generics, ...Array.from(fnType.bindings.values()).flat(), ]; - return checkIfInList(simplifiedGenerics, queryElem, whereClause); + return checkIfInList(simplifiedGenerics, queryElem, whereClause, mgens); } return false; } @@ -1777,12 +1786,13 @@ function initSearch(rawSearchIndex) { * @param {Array} list * @param {QueryElement} elem - The element from the parsed query. * @param {[FunctionType]} whereClause - Trait bounds for generic items. + * @param {Map|null} mgens - Map functions generics to query generics. * * @return {boolean} - Returns true if found, false otherwise. */ - function checkIfInList(list, elem, whereClause) { + function checkIfInList(list, elem, whereClause, mgens) { for (const entry of list) { - if (checkType(entry, elem, whereClause)) { + if (checkType(entry, elem, whereClause, mgens)) { return true; } } @@ -1796,23 +1806,29 @@ function initSearch(rawSearchIndex) { * @param {Row} row * @param {QueryElement} elem - The element from the parsed query. * @param {[FunctionType]} whereClause - Trait bounds for generic items. + * @param {Map|null} mgens - Map functions generics to query generics. * * @return {boolean} - Returns true if the type matches, false otherwise. */ - function checkType(row, elem, whereClause) { + function checkType(row, elem, whereClause, mgens) { if (row.bindings.size === 0 && elem.bindings.size === 0) { if (elem.id < 0) { - return row.id < 0 || checkIfInList(row.generics, elem, whereClause); + return row.id < 0 || checkIfInList(row.generics, elem, whereClause, mgens); } if (row.id > 0 && elem.id > 0 && elem.pathWithoutLast.length === 0 && typePassesFilter(elem.typeFilter, row.ty) && elem.generics.length === 0 && // special case elem.id !== typeNameIdOfArrayOrSlice ) { - return row.id === elem.id || checkIfInList(row.generics, elem, whereClause); + return row.id === elem.id || checkIfInList( + row.generics, + elem, + whereClause, + mgens + ); } } - return unifyFunctionTypes([row], [elem], whereClause); + return unifyFunctionTypes([row], [elem], whereClause, mgens); } function checkPath(contains, ty, maxEditDistance) { diff --git a/tests/rustdoc-js/assoc-type-loop.js b/tests/rustdoc-js/assoc-type-loop.js new file mode 100644 index 00000000000..f0192371ab4 --- /dev/null +++ b/tests/rustdoc-js/assoc-type-loop.js @@ -0,0 +1,9 @@ +// Crash reduction of +// https://github.com/rust-lang/rust/issues/118242 + +const EXPECTED = [ + { + 'query': 't', + 'correction': null, + }, +]; diff --git a/tests/rustdoc-js/assoc-type-loop.rs b/tests/rustdoc-js/assoc-type-loop.rs new file mode 100644 index 00000000000..f123c83f50f --- /dev/null +++ b/tests/rustdoc-js/assoc-type-loop.rs @@ -0,0 +1,35 @@ +#![crate_name="foo"] + +// reduced from sqlx 0.7.3 +use std::future::Future; +use std::pin::Pin; +use std::ops::{Deref, DerefMut}; +pub enum Error {} +pub trait Acquire<'c> { + type Database: Database; + type Connection: Deref::Connection> + DerefMut + Send; +} +pub trait Database { + type Connection: Connection; +} +pub trait Connection { + type Database: Database; + type Options: ConnectionOptions; + fn begin( + &mut self + ) -> Pin, Error>> + Send + '_>> + where + Self: Sized; +} +pub trait ConnectionOptions { + type Connection: Connection; +} +pub struct Transaction<'c, DB: Database> { + _db: &'c DB, +} +impl<'t, 'c, DB: Database> Acquire<'t> for &'t mut Transaction<'c, DB> + where ::Connection: Send +{ + type Database = DB; + type Connection = &'t mut ::Connection; +} From 798d2cb6e229f241a068e4aafcdd7ea672072945 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 24 Nov 2023 11:23:45 -0300 Subject: [PATCH 20/30] Move EagerResolution to rustc_infer::infer::resolve --- compiler/rustc_infer/src/infer/resolve.rs | 82 ++++++++++++++++++ .../src/solve/eval_ctxt/canonical.rs | 85 ++----------------- 2 files changed, 87 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 18a9cb6b44b..ece30bbba12 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -260,3 +260,85 @@ impl<'a, 'tcx> FallibleTypeFolder> for FullTypeResolver<'a, 'tcx> { } } } + +/////////////////////////////////////////////////////////////////////////// +// EAGER RESOLUTION + +/// Resolves ty, region, and const vars to their inferred values or their root vars. +pub struct EagerResolver<'a, 'tcx> { + infcx: &'a InferCtxt<'tcx>, +} + +impl<'a, 'tcx> EagerResolver<'a, 'tcx> { + pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { + EagerResolver { infcx } + } +} + +impl<'tcx> TypeFolder> for EagerResolver<'_, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + match *t.kind() { + ty::Infer(ty::TyVar(vid)) => match self.infcx.probe_ty_var(vid) { + Ok(t) => t.fold_with(self), + Err(_) => Ty::new_var(self.infcx.tcx, self.infcx.root_var(vid)), + }, + ty::Infer(ty::IntVar(vid)) => self.infcx.opportunistic_resolve_int_var(vid), + ty::Infer(ty::FloatVar(vid)) => self.infcx.opportunistic_resolve_float_var(vid), + _ => { + if t.has_infer() { + t.super_fold_with(self) + } else { + t + } + } + } + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + match *r { + ty::ReVar(vid) => self + .infcx + .inner + .borrow_mut() + .unwrap_region_constraints() + .opportunistic_resolve_var(self.infcx.tcx, vid), + _ => r, + } + } + + fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { + match c.kind() { + ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { + // FIXME: we need to fold the ty too, I think. + match self.infcx.probe_const_var(vid) { + Ok(c) => c.fold_with(self), + Err(_) => { + ty::Const::new_var(self.infcx.tcx, self.infcx.root_const_var(vid), c.ty()) + } + } + } + ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => { + debug_assert_eq!(c.ty(), self.infcx.tcx.types.bool); + match self.infcx.probe_effect_var(vid) { + Some(c) => c.as_const(self.infcx.tcx), + None => ty::Const::new_infer( + self.infcx.tcx, + ty::InferConst::EffectVar(self.infcx.root_effect_var(vid)), + self.infcx.tcx.types.bool, + ), + } + } + _ => { + if c.has_infer() { + c.super_fold_with(self) + } else { + c + } + } + } + } +} diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index ae7f6ca2f7a..da2f16e9760 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -18,6 +18,7 @@ use rustc_index::IndexVec; use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; +use rustc_infer::infer::resolve::EagerResolver; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; use rustc_middle::infer::canonical::Canonical; use rustc_middle::traits::query::NoSolution; @@ -25,10 +26,7 @@ use rustc_middle::traits::solve::{ ExternalConstraintsData, MaybeCause, PredefinedOpaquesData, QueryInput, }; use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{ - self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitableExt, -}; +use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable}; use rustc_span::DUMMY_SP; use std::iter; use std::ops::Deref; @@ -58,7 +56,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { ) -> (Vec>, CanonicalInput<'tcx, T>) { let opaque_types = self.infcx.clone_opaque_types_for_query_response(); let (goal, opaque_types) = - (goal, opaque_types).fold_with(&mut EagerResolver { infcx: self.infcx }); + (goal, opaque_types).fold_with(&mut EagerResolver::new(self.infcx)); let mut orig_values = Default::default(); let canonical_goal = Canonicalizer::canonicalize( @@ -115,7 +113,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let external_constraints = self.compute_external_query_constraints()?; let (var_values, mut external_constraints) = - (var_values, external_constraints).fold_with(&mut EagerResolver { infcx: self.infcx }); + (var_values, external_constraints).fold_with(&mut EagerResolver::new(self.infcx)); // Remove any trivial region constraints once we've resolved regions external_constraints .region_constraints @@ -364,86 +362,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } } -/// Resolves ty, region, and const vars to their inferred values or their root vars. -struct EagerResolver<'a, 'tcx> { - infcx: &'a InferCtxt<'tcx>, -} - -impl<'tcx> TypeFolder> for EagerResolver<'_, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - match *t.kind() { - ty::Infer(ty::TyVar(vid)) => match self.infcx.probe_ty_var(vid) { - Ok(t) => t.fold_with(self), - Err(_) => Ty::new_var(self.infcx.tcx, self.infcx.root_var(vid)), - }, - ty::Infer(ty::IntVar(vid)) => self.infcx.opportunistic_resolve_int_var(vid), - ty::Infer(ty::FloatVar(vid)) => self.infcx.opportunistic_resolve_float_var(vid), - _ => { - if t.has_infer() { - t.super_fold_with(self) - } else { - t - } - } - } - } - - fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { - match *r { - ty::ReVar(vid) => self - .infcx - .inner - .borrow_mut() - .unwrap_region_constraints() - .opportunistic_resolve_var(self.infcx.tcx, vid), - _ => r, - } - } - - fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { - match c.kind() { - ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { - // FIXME: we need to fold the ty too, I think. - match self.infcx.probe_const_var(vid) { - Ok(c) => c.fold_with(self), - Err(_) => { - ty::Const::new_var(self.infcx.tcx, self.infcx.root_const_var(vid), c.ty()) - } - } - } - ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => { - debug_assert_eq!(c.ty(), self.infcx.tcx.types.bool); - match self.infcx.probe_effect_var(vid) { - Some(c) => c.as_const(self.infcx.tcx), - None => ty::Const::new_infer( - self.infcx.tcx, - ty::InferConst::EffectVar(self.infcx.root_effect_var(vid)), - self.infcx.tcx.types.bool, - ), - } - } - _ => { - if c.has_infer() { - c.super_fold_with(self) - } else { - c - } - } - } - } -} - impl<'tcx> inspect::ProofTreeBuilder<'tcx> { pub fn make_canonical_state>>( ecx: &EvalCtxt<'_, 'tcx>, data: T, ) -> inspect::CanonicalState<'tcx, T> { let state = inspect::State { var_values: ecx.var_values, data }; - let state = state.fold_with(&mut EagerResolver { infcx: ecx.infcx }); + let state = state.fold_with(&mut EagerResolver::new(ecx.infcx)); Canonicalizer::canonicalize( ecx.infcx, CanonicalizeMode::Response { max_input_universe: ecx.max_input_universe }, From f57e1843f3596f842e6b0c594566f3326f008083 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 24 Nov 2023 09:56:55 -0300 Subject: [PATCH 21/30] Make PlaceholderReplacer shallow_resolver when folding const and ty and recur if contain infer vars --- .../src/traits/project.rs | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 06f65e414da..8f5afdf0a1f 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1001,7 +1001,7 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { - if !t.has_placeholders() && !t.has_infer_regions() { + if !t.has_placeholders() && !t.has_infer() { return t; } self.current_index.shift_in(1); @@ -1048,6 +1048,7 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + let ty = self.infcx.shallow_resolve(ty); match *ty.kind() { ty::Placeholder(p) => { let replace_var = self.mapped_types.get(&p); @@ -1063,16 +1064,23 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { ); Ty::new_bound(self.infcx.tcx, db, *replace_var) } - None => ty, + None => { + if ty.has_infer() { + ty.super_fold_with(self) + } else { + ty + } + } } } - _ if ty.has_placeholders() || ty.has_infer_regions() => ty.super_fold_with(self), + _ if ty.has_placeholders() || ty.has_infer() => ty.super_fold_with(self), _ => ty, } } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + let ct = self.infcx.shallow_resolve(ct); if let ty::ConstKind::Placeholder(p) = ct.kind() { let replace_var = self.mapped_consts.get(&p); match replace_var { @@ -1087,7 +1095,13 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { ); ty::Const::new_bound(self.infcx.tcx, db, *replace_var, ct.ty()) } - None => ct, + None => { + if ct.has_infer() { + ct.super_fold_with(self) + } else { + ct + } + } } } else { ct.super_fold_with(self) From 6713f295e2cb03010145d213f3010eed61e7441f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 20 Nov 2023 23:10:22 -0300 Subject: [PATCH 22/30] We should call eq instead of sup as we're relating Ty directly and not Binder --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 102c83751aa..ff92d4c4a3e 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1674,10 +1674,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let impl_ty = ocx.normalize(&cause, param_env, impl_ty); // Check that the self types can be related. - // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses - // `sup` for this situtation, too. What for? To constrain inference variables? - if ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() - { + if ocx.eq(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() { return false; } From 6d881a9946e18cd2ded346e6819332c63808e61c Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 23 Nov 2023 23:53:24 +0300 Subject: [PATCH 23/30] add change information for PR#117813 Signed-off-by: onur-ozkan --- config.example.toml | 2 +- src/bootstrap/src/lib.rs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/config.example.toml b/config.example.toml index 5f9ae039b25..c91222169d9 100644 --- a/config.example.toml +++ b/config.example.toml @@ -30,7 +30,7 @@ # # If `change-id` does not match the version that is currently running, # `x.py` will prompt you to update it and check the related PR for more details. -change-id = 116881 +change-id = 117813 # ============================================================================= # Tweaking how LLVM is compiled diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 736a9b312f0..785a293b45a 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -124,6 +124,11 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "Default value of `download-ci-llvm` was changed for `codegen` profile.", }, + ChangeInfo { + change_id: 117813, + severity: ChangeSeverity::Info, + summary: "Use of the `if-available` value for `download-ci-llvm` is deprecated; prefer using the new `if-unchanged` value.", + }, ]; /// Extra --check-cfg to add when building From 38aba2cb193cdde1a235a31f301842f950b55665 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 23 Nov 2023 23:54:15 +0300 Subject: [PATCH 24/30] use the change-id from source instead of the one from config.tom This fixes the problem of not being able to see bootstrap config changes unless the change-id in config.toml changes. Signed-off-by: onur-ozkan --- src/bootstrap/src/bin/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 35010bea818..f9b3ca2c3fb 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -120,7 +120,7 @@ fn check_version(config: &Config) -> Option { } if let Ok(last_warned_id) = fs::read_to_string(&warned_id_path) { - if id.to_string() == last_warned_id { + if latest_change_id.to_string() == last_warned_id { return None; } } @@ -144,7 +144,7 @@ fn check_version(config: &Config) -> Option { )); if io::stdout().is_terminal() { - t!(fs::write(warned_id_path, id.to_string())); + t!(fs::write(warned_id_path, latest_change_id.to_string())); } } } else { From 576a17ecdbd30ed427c25343942f43185ebc6d98 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 24 Nov 2023 00:18:57 +0300 Subject: [PATCH 25/30] move CONFIG_CHANGE_HISTORY to its own module Because bootstrap lib is already large and complicated, this should make the "bumping change-id" process easier. Signed-off-by: onur-ozkan --- src/bootstrap/README.md | 2 +- src/bootstrap/src/core/build_steps/setup.rs | 3 +- src/bootstrap/src/lib.rs | 93 +-------------------- src/bootstrap/src/utils/change_tracker.rs | 89 ++++++++++++++++++++ src/bootstrap/src/utils/mod.rs | 1 + triagebot.toml | 18 +++- 6 files changed, 112 insertions(+), 94 deletions(-) create mode 100644 src/bootstrap/src/utils/change_tracker.rs diff --git a/src/bootstrap/README.md b/src/bootstrap/README.md index e7998a40a65..d0a069f45e1 100644 --- a/src/bootstrap/README.md +++ b/src/bootstrap/README.md @@ -183,7 +183,7 @@ Some general areas that you may be interested in modifying are: If you make a major change on bootstrap configuration, please remember to: -+ Update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/lib.rs`. ++ Update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/utils/change_tracker.rs`. * Update `change-id = {pull-request-id}` in `config.example.toml`. A 'major change' includes diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index bbbdb4c3186..49373177abe 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -1,6 +1,7 @@ use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::t; +use crate::utils::change_tracker::CONFIG_CHANGE_HISTORY; use crate::Config; -use crate::{t, CONFIG_CHANGE_HISTORY}; use sha2::Digest; use std::env::consts::EXE_SUFFIX; use std::fmt::Write as _; diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 785a293b45a..480dd757915 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -47,9 +47,10 @@ use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, syml mod core; mod utils; -pub use crate::core::builder::PathSet; -pub use crate::core::config::flags::Subcommand; -pub use crate::core::config::Config; +pub use core::builder::PathSet; +pub use core::config::flags::Subcommand; +pub use core::config::Config; +pub use utils::change_tracker::{find_recent_config_change_ids, CONFIG_CHANGE_HISTORY}; const LLVM_TOOLS: &[&str] = &[ "llvm-cov", // used to generate coverage report @@ -70,67 +71,6 @@ const LLVM_TOOLS: &[&str] = &[ /// LLD file names for all flavors. const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"]; -#[derive(Clone, Debug)] -pub struct ChangeInfo { - /// Represents the ID of PR caused major change on bootstrap. - pub change_id: usize, - pub severity: ChangeSeverity, - /// Provides a short summary of the change that will guide developers - /// on "how to handle/behave" in response to the changes. - pub summary: &'static str, -} - -#[derive(Clone, Debug)] -pub enum ChangeSeverity { - /// Used when build configurations continue working as before. - Info, - /// Used when the default value of an option changes, or support for an option is removed entirely, - /// potentially requiring developers to update their build configurations. - Warning, -} - -impl ToString for ChangeSeverity { - fn to_string(&self) -> String { - match self { - ChangeSeverity::Info => "INFO".to_string(), - ChangeSeverity::Warning => "WARNING".to_string(), - } - } -} - -/// Keeps track of major changes made to the bootstrap configuration. -/// -/// If you make any major changes (such as adding new values or changing default values), -/// please ensure adding `ChangeInfo` to the end(because the list must be sorted by the merge date) -/// of this list. -pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ - ChangeInfo { - change_id: 115898, - severity: ChangeSeverity::Info, - summary: "Implementation of this change-tracking system. Ignore this.", - }, - ChangeInfo { - change_id: 116998, - severity: ChangeSeverity::Info, - summary: "Removed android-ndk r15 support in favor of android-ndk r25b.", - }, - ChangeInfo { - change_id: 117435, - severity: ChangeSeverity::Info, - summary: "New option `rust.parallel-compiler` added to config.toml.", - }, - ChangeInfo { - change_id: 116881, - severity: ChangeSeverity::Warning, - summary: "Default value of `download-ci-llvm` was changed for `codegen` profile.", - }, - ChangeInfo { - change_id: 117813, - severity: ChangeSeverity::Info, - summary: "Use of the `if-available` value for `download-ci-llvm` is deprecated; prefer using the new `if-unchanged` value.", - }, -]; - /// Extra --check-cfg to add when building /// (Mode restriction, config name, config values (if any)) const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ @@ -1900,31 +1840,6 @@ fn envify(s: &str) -> String { .collect() } -pub fn find_recent_config_change_ids(current_id: usize) -> Vec { - if !CONFIG_CHANGE_HISTORY.iter().any(|config| config.change_id == current_id) { - // If the current change-id is greater than the most recent one, return - // an empty list (it may be due to switching from a recent branch to an - // older one); otherwise, return the full list (assuming the user provided - // the incorrect change-id by accident). - if let Some(config) = CONFIG_CHANGE_HISTORY.iter().max_by_key(|config| config.change_id) { - if ¤t_id > &config.change_id { - return Vec::new(); - } - } - - return CONFIG_CHANGE_HISTORY.to_vec(); - } - - let index = - CONFIG_CHANGE_HISTORY.iter().position(|config| config.change_id == current_id).unwrap(); - - CONFIG_CHANGE_HISTORY - .iter() - .skip(index + 1) // Skip the current_id and IDs before it - .cloned() - .collect() -} - /// Computes a hash representing the state of a repository/submodule and additional input. /// /// It uses `git diff` for the actual changes, and `git status` for including the untracked diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs new file mode 100644 index 00000000000..887b596b786 --- /dev/null +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -0,0 +1,89 @@ +//! This module facilitates the tracking system for major changes made to the bootstrap, +//! with the goal of keeping developers synchronized with important modifications in +//! the bootstrap. + +#[derive(Clone, Debug)] +pub struct ChangeInfo { + /// Represents the ID of PR caused major change on bootstrap. + pub change_id: usize, + pub severity: ChangeSeverity, + /// Provides a short summary of the change that will guide developers + /// on "how to handle/behave" in response to the changes. + pub summary: &'static str, +} + +#[derive(Clone, Debug)] +pub enum ChangeSeverity { + /// Used when build configurations continue working as before. + Info, + /// Used when the default value of an option changes, or support for an option is removed entirely, + /// potentially requiring developers to update their build configurations. + Warning, +} + +impl ToString for ChangeSeverity { + fn to_string(&self) -> String { + match self { + ChangeSeverity::Info => "INFO".to_string(), + ChangeSeverity::Warning => "WARNING".to_string(), + } + } +} + +pub fn find_recent_config_change_ids(current_id: usize) -> Vec { + if !CONFIG_CHANGE_HISTORY.iter().any(|config| config.change_id == current_id) { + // If the current change-id is greater than the most recent one, return + // an empty list (it may be due to switching from a recent branch to an + // older one); otherwise, return the full list (assuming the user provided + // the incorrect change-id by accident). + if let Some(config) = CONFIG_CHANGE_HISTORY.iter().max_by_key(|config| config.change_id) { + if ¤t_id > &config.change_id { + return Vec::new(); + } + } + + return CONFIG_CHANGE_HISTORY.to_vec(); + } + + let index = + CONFIG_CHANGE_HISTORY.iter().position(|config| config.change_id == current_id).unwrap(); + + CONFIG_CHANGE_HISTORY + .iter() + .skip(index + 1) // Skip the current_id and IDs before it + .cloned() + .collect() +} + +/// Keeps track of major changes made to the bootstrap configuration. +/// +/// If you make any major changes (such as adding new values or changing default values), +/// please ensure adding `ChangeInfo` to the end(because the list must be sorted by the merge date) +/// of this list. +pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ + ChangeInfo { + change_id: 115898, + severity: ChangeSeverity::Info, + summary: "Implementation of this change-tracking system. Ignore this.", + }, + ChangeInfo { + change_id: 116998, + severity: ChangeSeverity::Info, + summary: "Removed android-ndk r15 support in favor of android-ndk r25b.", + }, + ChangeInfo { + change_id: 117435, + severity: ChangeSeverity::Info, + summary: "New option `rust.parallel-compiler` added to config.toml.", + }, + ChangeInfo { + change_id: 116881, + severity: ChangeSeverity::Warning, + summary: "Default value of `download-ci-llvm` was changed for `codegen` profile.", + }, + ChangeInfo { + change_id: 117813, + severity: ChangeSeverity::Info, + summary: "Use of the `if-available` value for `download-ci-llvm` is deprecated; prefer using the new `if-unchanged` value.", + }, +]; diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs index 8ca22d00865..cb535f0e163 100644 --- a/src/bootstrap/src/utils/mod.rs +++ b/src/bootstrap/src/utils/mod.rs @@ -4,6 +4,7 @@ pub(crate) mod cache; pub(crate) mod cc_detect; +pub(crate) mod change_tracker; pub(crate) mod channel; pub(crate) mod dylib; pub(crate) mod exec; diff --git a/triagebot.toml b/triagebot.toml index a72338d1950..bfb9ab2a792 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -583,11 +583,23 @@ message = "The list of allowed third-party dependencies may have been modified! cc = ["@davidtwco", "@wesleywiser"] [mentions."src/bootstrap/src/core/config"] -message = "This PR modifies `src/bootstrap/src/core/config`. If appropriate, please also update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/lib.rs` and `change-id` in `config.example.toml`." +message = """ +This PR modifies `src/bootstrap/src/core/config`. + +If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/utils/change_tracker.rs` and `change-id` in `config.example.toml`. +""" [mentions."src/bootstrap/defaults"] -message = "This PR modifies `src/bootstrap/defaults`. If appropriate, please also update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/lib.rs` and `change-id` in `config.example.toml`." +message = """ +This PR modifies `src/bootstrap/defaults`. + +If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/utils/change_tracker.rs` and `change-id` in `config.example.toml`. +""" [mentions."config.example.toml"] -message = "This PR changes `config.example.toml`. If appropriate, please also update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/lib.rs` and `change-id` in `config.example.toml`." +message = """ +This PR modifies `config.example.toml`. + +If appropriate, please update `CONFIG_CHANGE_HISTORY` in `src/bootstrap/src/utils/change_tracker.rs` and `change-id` in `config.example.toml`. +""" [mentions."src/bootstrap/defaults/config.compiler.toml"] message = "This PR changes src/bootstrap/defaults/config.compiler.toml. If appropriate, please also update `config.codegen.toml` so the defaults are in sync." From 5ad84ed2e6fea58faac621939521b7e62c27de03 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Fri, 24 Nov 2023 13:26:57 -0800 Subject: [PATCH 26/30] Break down `rustc_smir/mod.rs` file This file was getting too big and causing a lot of merge conflicts. All these changes shouldn't be visible to users since this module is private. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 2 +- compiler/rustc_smir/src/rustc_smir/context.rs | 375 ++++ .../rustc_smir/src/rustc_smir/convert/mir.rs | 743 ++++++ .../rustc_smir/src/rustc_smir/convert/mod.rs | 74 + .../rustc_smir/src/rustc_smir/convert/ty.rs | 814 +++++++ compiler/rustc_smir/src/rustc_smir/mod.rs | 1999 +---------------- 6 files changed, 2021 insertions(+), 1986 deletions(-) create mode 100644 compiler/rustc_smir/src/rustc_smir/context.rs create mode 100644 compiler/rustc_smir/src/rustc_smir/convert/mir.rs create mode 100644 compiler/rustc_smir/src/rustc_smir/convert/mod.rs create mode 100644 compiler/rustc_smir/src/rustc_smir/convert/ty.rs diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index fed21f16a4e..b13bf2e98c9 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -3,7 +3,7 @@ //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs //! until stable MIR is complete. -use crate::rustc_smir::{Stable, Tables, TablesWrapper}; +use crate::rustc_smir::{context::TablesWrapper, Stable, Tables}; use rustc_data_structures::fx; use rustc_data_structures::fx::FxIndexMap; use rustc_middle::mir::interpret::AllocId; diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs new file mode 100644 index 00000000000..d399b9b3e8f --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -0,0 +1,375 @@ +//! Implementation of `[stable_mir::compiler::Context]` trait. +//! +//! This trait is currently the main interface between the Rust compiler, +//! and the `stable_mir` crate. + +use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; +use rustc_middle::ty::{GenericPredicates, Instance, ParamEnv, ScalarInt, ValTree}; +use rustc_span::def_id::LOCAL_CRATE; +use stable_mir::mir::alloc::GlobalAlloc; +use stable_mir::mir::mono::{InstanceDef, StaticDef}; +use stable_mir::mir::Body; +use stable_mir::ty::{ + AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FnDef, GenericArgs, LineInfo, + RigidTy, Span, TyKind, +}; +use stable_mir::{self, Context, Crate, CrateItem, Error, Filename, ItemKind, Symbol}; +use std::cell::RefCell; + +use crate::rustc_internal::{internal, RustcInternal}; +use crate::rustc_smir::builder::BodyBuilder; +use crate::rustc_smir::{new_item_kind, smir_crate, Stable, Tables}; + +impl<'tcx> Context for TablesWrapper<'tcx> { + fn entry_fn(&self) -> Option { + let mut tables = self.0.borrow_mut(); + let tcx = tables.tcx; + Some(tables.crate_item(tcx.entry_fn(())?.0)) + } + + fn all_local_items(&self) -> stable_mir::CrateItems { + let mut tables = self.0.borrow_mut(); + tables.tcx.mir_keys(()).iter().map(|item| tables.crate_item(item.to_def_id())).collect() + } + + fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body { + let mut tables = self.0.borrow_mut(); + let def_id = tables[item]; + tables.tcx.instance_mir(rustc_middle::ty::InstanceDef::Item(def_id)).stable(&mut tables) + } + + fn all_trait_decls(&self) -> stable_mir::TraitDecls { + let mut tables = self.0.borrow_mut(); + tables + .tcx + .traits(LOCAL_CRATE) + .iter() + .map(|trait_def_id| tables.trait_def(*trait_def_id)) + .collect() + } + + fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl { + let mut tables = self.0.borrow_mut(); + let def_id = tables[trait_def.0]; + let trait_def = tables.tcx.trait_def(def_id); + trait_def.stable(&mut *tables) + } + + fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls { + let mut tables = self.0.borrow_mut(); + tables + .tcx + .trait_impls_in_crate(LOCAL_CRATE) + .iter() + .map(|impl_def_id| tables.impl_def(*impl_def_id)) + .collect() + } + + fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait { + let mut tables = self.0.borrow_mut(); + let def_id = tables[impl_def.0]; + let impl_trait = tables.tcx.impl_trait_ref(def_id).unwrap(); + impl_trait.stable(&mut *tables) + } + + fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics { + let mut tables = self.0.borrow_mut(); + let def_id = tables[def_id]; + let generics = tables.tcx.generics_of(def_id); + generics.stable(&mut *tables) + } + + fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates { + let mut tables = self.0.borrow_mut(); + let def_id = tables[def_id]; + let GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id); + stable_mir::ty::GenericPredicates { + parent: parent.map(|did| tables.trait_def(did)), + predicates: predicates + .iter() + .map(|(clause, span)| { + ( + clause.as_predicate().kind().skip_binder().stable(&mut *tables), + span.stable(&mut *tables), + ) + }) + .collect(), + } + } + + fn explicit_predicates_of( + &self, + def_id: stable_mir::DefId, + ) -> stable_mir::ty::GenericPredicates { + let mut tables = self.0.borrow_mut(); + let def_id = tables[def_id]; + let GenericPredicates { parent, predicates } = tables.tcx.explicit_predicates_of(def_id); + stable_mir::ty::GenericPredicates { + parent: parent.map(|did| tables.trait_def(did)), + predicates: predicates + .iter() + .map(|(clause, span)| { + ( + clause.as_predicate().kind().skip_binder().stable(&mut *tables), + span.stable(&mut *tables), + ) + }) + .collect(), + } + } + + fn local_crate(&self) -> stable_mir::Crate { + let tables = self.0.borrow(); + smir_crate(tables.tcx, LOCAL_CRATE) + } + + fn external_crates(&self) -> Vec { + let tables = self.0.borrow(); + tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect() + } + + fn find_crates(&self, name: &str) -> Vec { + let tables = self.0.borrow(); + let crates: Vec = [LOCAL_CRATE] + .iter() + .chain(tables.tcx.crates(()).iter()) + .map(|crate_num| { + let crate_name = tables.tcx.crate_name(*crate_num).to_string(); + (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num)) + }) + .into_iter() + .filter_map(|c| c) + .collect(); + crates + } + + fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol { + let tables = self.0.borrow(); + if trimmed { + with_forced_trimmed_paths!(tables.tcx.def_path_str(tables[def_id])) + } else { + with_no_trimmed_paths!(tables.tcx.def_path_str(tables[def_id])) + } + } + + fn span_to_string(&self, span: stable_mir::ty::Span) -> String { + let tables = self.0.borrow(); + tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span]) + } + + fn get_filename(&self, span: &Span) -> Filename { + let tables = self.0.borrow(); + tables + .tcx + .sess + .source_map() + .span_to_filename(tables[*span]) + .display(rustc_span::FileNameDisplayPreference::Local) + .to_string() + } + + fn get_lines(&self, span: &Span) -> LineInfo { + let tables = self.0.borrow(); + let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]); + LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 } + } + + fn item_kind(&self, item: CrateItem) -> ItemKind { + let tables = self.0.borrow(); + new_item_kind(tables.tcx.def_kind(tables[item.0])) + } + + fn is_foreign_item(&self, item: CrateItem) -> bool { + let tables = self.0.borrow(); + tables.tcx.is_foreign_item(tables[item.0]) + } + + fn adt_kind(&self, def: AdtDef) -> AdtKind { + let mut tables = self.0.borrow_mut(); + def.internal(&mut *tables).adt_kind().stable(&mut *tables) + } + + fn adt_is_box(&self, def: AdtDef) -> bool { + let mut tables = self.0.borrow_mut(); + def.internal(&mut *tables).is_box() + } + + fn eval_target_usize(&self, cnst: &Const) -> Result { + let mut tables = self.0.borrow_mut(); + let mir_const = cnst.internal(&mut *tables); + mir_const + .try_eval_target_usize(tables.tcx, ParamEnv::empty()) + .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) + } + + fn usize_to_const(&self, val: u64) -> Result { + let mut tables = self.0.borrow_mut(); + let ty = tables.tcx.types.usize; + let size = tables.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap().size; + + let scalar = ScalarInt::try_from_uint(val, size).ok_or_else(|| { + Error::new(format!("Value overflow: cannot convert `{val}` to usize.")) + })?; + Ok(rustc_middle::ty::Const::new_value(tables.tcx, ValTree::from_scalar_int(scalar), ty) + .stable(&mut *tables)) + } + + fn new_rigid_ty(&self, kind: RigidTy) -> stable_mir::ty::Ty { + let mut tables = self.0.borrow_mut(); + let internal_kind = kind.internal(&mut *tables); + tables.tcx.mk_ty_from_kind(internal_kind).stable(&mut *tables) + } + + fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty { + let mut tables = self.0.borrow_mut(); + tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables) + } + + fn const_literal(&self, cnst: &stable_mir::ty::Const) -> String { + internal(cnst).to_string() + } + + fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span { + let mut tables = self.0.borrow_mut(); + tables.tcx.def_span(tables[def_id]).stable(&mut *tables) + } + + fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind { + let mut tables = self.0.borrow_mut(); + tables.types[ty].kind().stable(&mut *tables) + } + + fn instance_body(&self, def: InstanceDef) -> Option { + let mut tables = self.0.borrow_mut(); + let instance = tables.instances[def]; + tables + .has_body(instance) + .then(|| BodyBuilder::new(tables.tcx, instance).build(&mut *tables)) + } + + fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty { + let mut tables = self.0.borrow_mut(); + let instance = tables.instances[def]; + instance.ty(tables.tcx, ParamEnv::empty()).stable(&mut *tables) + } + + fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId { + let mut tables = self.0.borrow_mut(); + let def_id = tables.instances[def].def_id(); + tables.create_def_id(def_id) + } + + fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol { + let tables = self.0.borrow_mut(); + let instance = tables.instances[instance]; + tables.tcx.symbol_name(instance).name.to_string() + } + + fn mono_instance(&self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance { + let mut tables = self.0.borrow_mut(); + let def_id = tables[item.0]; + Instance::mono(tables.tcx, def_id).stable(&mut *tables) + } + + fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool { + let tables = self.0.borrow(); + let def_id = tables[def_id]; + let generics = tables.tcx.generics_of(def_id); + let result = generics.requires_monomorphization(tables.tcx); + result + } + + fn resolve_instance( + &self, + def: stable_mir::ty::FnDef, + args: &stable_mir::ty::GenericArgs, + ) -> Option { + let mut tables = self.0.borrow_mut(); + let def_id = def.0.internal(&mut *tables); + let args_ref = args.internal(&mut *tables); + match Instance::resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) { + Ok(Some(instance)) => Some(instance.stable(&mut *tables)), + Ok(None) | Err(_) => None, + } + } + + fn resolve_drop_in_place(&self, ty: stable_mir::ty::Ty) -> stable_mir::mir::mono::Instance { + let mut tables = self.0.borrow_mut(); + let internal_ty = ty.internal(&mut *tables); + let instance = Instance::resolve_drop_in_place(tables.tcx, internal_ty); + instance.stable(&mut *tables) + } + + fn resolve_for_fn_ptr( + &self, + def: FnDef, + args: &GenericArgs, + ) -> Option { + let mut tables = self.0.borrow_mut(); + let def_id = def.0.internal(&mut *tables); + let args_ref = args.internal(&mut *tables); + Instance::resolve_for_fn_ptr(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) + .stable(&mut *tables) + } + + fn resolve_closure( + &self, + def: ClosureDef, + args: &GenericArgs, + kind: ClosureKind, + ) -> Option { + let mut tables = self.0.borrow_mut(); + let def_id = def.0.internal(&mut *tables); + let args_ref = args.internal(&mut *tables); + let closure_kind = kind.internal(&mut *tables); + Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind).stable(&mut *tables) + } + + fn eval_static_initializer(&self, def: StaticDef) -> Result { + let mut tables = self.0.borrow_mut(); + let def_id = def.0.internal(&mut *tables); + tables.tcx.eval_static_initializer(def_id).stable(&mut *tables) + } + + fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc { + let mut tables = self.0.borrow_mut(); + let alloc_id = alloc.internal(&mut *tables); + tables.tcx.global_alloc(alloc_id).stable(&mut *tables) + } + + fn vtable_allocation( + &self, + global_alloc: &GlobalAlloc, + ) -> Option { + let mut tables = self.0.borrow_mut(); + let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else { return None }; + let alloc_id = tables + .tcx + .vtable_allocation((ty.internal(&mut *tables), trait_ref.internal(&mut *tables))); + Some(alloc_id.stable(&mut *tables)) + } + + fn krate(&self, def_id: stable_mir::DefId) -> Crate { + let tables = self.0.borrow(); + smir_crate(tables.tcx, tables[def_id].krate) + } + + /// Retrieve the instance name for diagnostic messages. + /// + /// This will return the specialized name, e.g., `Vec::new`. + fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol { + let tables = self.0.borrow_mut(); + let instance = tables.instances[def]; + if trimmed { + with_forced_trimmed_paths!( + tables.tcx.def_path_str_with_args(instance.def_id(), instance.args) + ) + } else { + with_no_trimmed_paths!( + tables.tcx.def_path_str_with_args(instance.def_id(), instance.args) + ) + } + } +} + +pub struct TablesWrapper<'tcx>(pub RefCell>); diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs new file mode 100644 index 00000000000..91fadc16442 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -0,0 +1,743 @@ +//! Conversion of internal Rust compiler `mir` items to stable ones. +use crate::rustc_smir::{alloc, Stable, Tables}; +use rustc_middle::mir; +use rustc_middle::mir::interpret::alloc_range; +use rustc_middle::mir::mono::MonoItem; +use stable_mir::mir::alloc::GlobalAlloc; +use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment}; +use stable_mir::ty::{Allocation, Const, ConstantKind}; +use stable_mir::{opaque, Error}; + +impl<'tcx> Stable<'tcx> for mir::Body<'tcx> { + type T = stable_mir::mir::Body; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + stable_mir::mir::Body::new( + self.basic_blocks + .iter() + .map(|block| stable_mir::mir::BasicBlock { + terminator: block.terminator().stable(tables), + statements: block + .statements + .iter() + .map(|statement| statement.stable(tables)) + .collect(), + }) + .collect(), + self.local_decls + .iter() + .map(|decl| stable_mir::mir::LocalDecl { + ty: decl.ty.stable(tables), + span: decl.source_info.span.stable(tables), + mutability: decl.mutability.stable(tables), + }) + .collect(), + self.arg_count, + self.var_debug_info.iter().map(|info| info.stable(tables)).collect(), + ) + } +} + +impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> { + type T = stable_mir::mir::VarDebugInfo; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + stable_mir::mir::VarDebugInfo { + name: self.name.to_string(), + source_info: self.source_info.stable(tables), + composite: self.composite.as_ref().map(|composite| composite.stable(tables)), + value: self.value.stable(tables), + argument_index: self.argument_index, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { + type T = stable_mir::mir::Statement; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for mir::SourceInfo { + type T = stable_mir::mir::SourceInfo; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + stable_mir::mir::SourceInfo { span: self.span.stable(tables), scope: self.scope.into() } + } +} + +impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> { + type T = stable_mir::mir::VarDebugInfoFragment; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + VarDebugInfoFragment { + ty: self.ty.stable(tables), + projection: self.projection.iter().map(|e| e.stable(tables)).collect(), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> { + type T = stable_mir::mir::VarDebugInfoContents; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + mir::VarDebugInfoContents::Place(place) => { + stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables)) + } + mir::VarDebugInfoContents::Const(const_operand) => { + let op = ConstOperand { + span: const_operand.span.stable(tables), + user_ty: const_operand.user_ty.map(|index| index.as_usize()), + const_: const_operand.const_.stable(tables), + }; + stable_mir::mir::VarDebugInfoContents::Const(op) + } + } + } +} + +impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> { + type T = stable_mir::mir::StatementKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + mir::StatementKind::Assign(assign) => stable_mir::mir::StatementKind::Assign( + assign.0.stable(tables), + assign.1.stable(tables), + ), + mir::StatementKind::FakeRead(fake_read_place) => { + stable_mir::mir::StatementKind::FakeRead( + fake_read_place.0.stable(tables), + fake_read_place.1.stable(tables), + ) + } + mir::StatementKind::SetDiscriminant { place, variant_index } => { + stable_mir::mir::StatementKind::SetDiscriminant { + place: place.as_ref().stable(tables), + variant_index: variant_index.stable(tables), + } + } + mir::StatementKind::Deinit(place) => { + stable_mir::mir::StatementKind::Deinit(place.stable(tables)) + } + + mir::StatementKind::StorageLive(place) => { + stable_mir::mir::StatementKind::StorageLive(place.stable(tables)) + } + + mir::StatementKind::StorageDead(place) => { + stable_mir::mir::StatementKind::StorageDead(place.stable(tables)) + } + mir::StatementKind::Retag(retag, place) => { + stable_mir::mir::StatementKind::Retag(retag.stable(tables), place.stable(tables)) + } + mir::StatementKind::PlaceMention(place) => { + stable_mir::mir::StatementKind::PlaceMention(place.stable(tables)) + } + mir::StatementKind::AscribeUserType(place_projection, variance) => { + stable_mir::mir::StatementKind::AscribeUserType { + place: place_projection.as_ref().0.stable(tables), + projections: place_projection.as_ref().1.stable(tables), + variance: variance.stable(tables), + } + } + mir::StatementKind::Coverage(coverage) => { + stable_mir::mir::StatementKind::Coverage(opaque(coverage)) + } + mir::StatementKind::Intrinsic(intrinstic) => { + stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables)) + } + mir::StatementKind::ConstEvalCounter => { + stable_mir::mir::StatementKind::ConstEvalCounter + } + mir::StatementKind::Nop => stable_mir::mir::StatementKind::Nop, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { + type T = stable_mir::mir::Rvalue; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::Rvalue::*; + match self { + Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)), + Repeat(op, len) => { + let len = len.stable(tables); + stable_mir::mir::Rvalue::Repeat(op.stable(tables), len) + } + Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref( + region.stable(tables), + kind.stable(tables), + place.stable(tables), + ), + ThreadLocalRef(def_id) => { + stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id)) + } + AddressOf(mutability, place) => { + stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables)) + } + Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)), + Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast( + cast_kind.stable(tables), + op.stable(tables), + ty.stable(tables), + ), + BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp( + bin_op.stable(tables), + ops.0.stable(tables), + ops.1.stable(tables), + ), + CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp( + bin_op.stable(tables), + ops.0.stable(tables), + ops.1.stable(tables), + ), + NullaryOp(null_op, ty) => { + stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), ty.stable(tables)) + } + UnaryOp(un_op, op) => { + stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables)) + } + Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables)), + Aggregate(agg_kind, operands) => { + let operands = operands.iter().map(|op| op.stable(tables)).collect(); + stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands) + } + ShallowInitBox(op, ty) => { + stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables)) + } + CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::Mutability { + type T = stable_mir::mir::Mutability; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_hir::Mutability::*; + match *self { + Not => stable_mir::mir::Mutability::Not, + Mut => stable_mir::mir::Mutability::Mut, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::BorrowKind { + type T = stable_mir::mir::BorrowKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::BorrowKind::*; + match *self { + Shared => stable_mir::mir::BorrowKind::Shared, + Fake => stable_mir::mir::BorrowKind::Fake, + Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) }, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::MutBorrowKind { + type T = stable_mir::mir::MutBorrowKind; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::MutBorrowKind::*; + match *self { + Default => stable_mir::mir::MutBorrowKind::Default, + TwoPhaseBorrow => stable_mir::mir::MutBorrowKind::TwoPhaseBorrow, + ClosureCapture => stable_mir::mir::MutBorrowKind::ClosureCapture, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> { + type T = stable_mir::mir::NullOp; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::NullOp::*; + match self { + SizeOf => stable_mir::mir::NullOp::SizeOf, + AlignOf => stable_mir::mir::NullOp::AlignOf, + OffsetOf(indices) => stable_mir::mir::NullOp::OffsetOf( + indices.iter().map(|idx| idx.stable(tables)).collect(), + ), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::CastKind { + type T = stable_mir::mir::CastKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::CastKind::*; + match self { + PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress, + PointerFromExposedAddress => stable_mir::mir::CastKind::PointerFromExposedAddress, + PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), + DynStar => stable_mir::mir::CastKind::DynStar, + IntToInt => stable_mir::mir::CastKind::IntToInt, + FloatToInt => stable_mir::mir::CastKind::FloatToInt, + FloatToFloat => stable_mir::mir::CastKind::FloatToFloat, + IntToFloat => stable_mir::mir::CastKind::IntToFloat, + PtrToPtr => stable_mir::mir::CastKind::PtrToPtr, + FnPtrToPtr => stable_mir::mir::CastKind::FnPtrToPtr, + Transmute => stable_mir::mir::CastKind::Transmute, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::FakeReadCause { + type T = stable_mir::mir::FakeReadCause; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::FakeReadCause::*; + match self { + ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard, + ForMatchedPlace(local_def_id) => { + stable_mir::mir::FakeReadCause::ForMatchedPlace(opaque(local_def_id)) + } + ForGuardBinding => stable_mir::mir::FakeReadCause::ForGuardBinding, + ForLet(local_def_id) => stable_mir::mir::FakeReadCause::ForLet(opaque(local_def_id)), + ForIndex => stable_mir::mir::FakeReadCause::ForIndex, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> { + type T = stable_mir::mir::Operand; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::Operand::*; + match self { + Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables)), + Move(place) => stable_mir::mir::Operand::Move(place.stable(tables)), + Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables)), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> { + type T = stable_mir::mir::Constant; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + stable_mir::mir::Constant { + span: self.span.stable(tables), + user_ty: self.user_ty.map(|u| u.as_usize()).or(None), + literal: self.const_.stable(tables), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::Place<'tcx> { + type T = stable_mir::mir::Place; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + stable_mir::mir::Place { + local: self.local.as_usize(), + projection: self.projection.iter().map(|e| e.stable(tables)).collect(), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { + type T = stable_mir::mir::ProjectionElem; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::ProjectionElem::*; + match self { + Deref => stable_mir::mir::ProjectionElem::Deref, + Field(idx, ty) => { + stable_mir::mir::ProjectionElem::Field(idx.stable(tables), ty.stable(tables)) + } + Index(local) => stable_mir::mir::ProjectionElem::Index(local.stable(tables)), + ConstantIndex { offset, min_length, from_end } => { + stable_mir::mir::ProjectionElem::ConstantIndex { + offset: *offset, + min_length: *min_length, + from_end: *from_end, + } + } + Subslice { from, to, from_end } => stable_mir::mir::ProjectionElem::Subslice { + from: *from, + to: *to, + from_end: *from_end, + }, + // MIR includes an `Option` argument for `Downcast` that is the name of the + // variant, used for printing MIR. However this information should also be accessible + // via a lookup using the `VariantIdx`. The `Option` argument is therefore + // dropped when converting to Stable MIR. A brief justification for this decision can be + // found at https://github.com/rust-lang/rust/pull/117517#issuecomment-1811683486 + Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)), + OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)), + Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::UserTypeProjection { + type T = stable_mir::mir::UserTypeProjection; + + fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T { + UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) } + } +} + +impl<'tcx> Stable<'tcx> for mir::Local { + type T = stable_mir::mir::Local; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + self.as_usize() + } +} + +impl<'tcx> Stable<'tcx> for mir::RetagKind { + type T = stable_mir::mir::RetagKind; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::RetagKind; + match self { + RetagKind::FnEntry => stable_mir::mir::RetagKind::FnEntry, + RetagKind::TwoPhase => stable_mir::mir::RetagKind::TwoPhase, + RetagKind::Raw => stable_mir::mir::RetagKind::Raw, + RetagKind::Default => stable_mir::mir::RetagKind::Default, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::UnwindAction { + type T = stable_mir::mir::UnwindAction; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::UnwindAction; + match self { + UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, + UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable, + UnwindAction::Terminate(_) => stable_mir::mir::UnwindAction::Terminate, + UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> { + type T = stable_mir::mir::NonDivergingIntrinsic; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::NonDivergingIntrinsic; + use stable_mir::mir::CopyNonOverlapping; + match self { + NonDivergingIntrinsic::Assume(op) => { + stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables)) + } + NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => { + stable_mir::mir::NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { + src: copy_non_overlapping.src.stable(tables), + dst: copy_non_overlapping.dst.stable(tables), + count: copy_non_overlapping.count.stable(tables), + }) + } + } + } +} + +impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { + type T = stable_mir::mir::AssertMessage; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::AssertKind; + match self { + AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck { + len: len.stable(tables), + index: index.stable(tables), + }, + AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow( + bin_op.stable(tables), + op1.stable(tables), + op2.stable(tables), + ), + AssertKind::OverflowNeg(op) => { + stable_mir::mir::AssertMessage::OverflowNeg(op.stable(tables)) + } + AssertKind::DivisionByZero(op) => { + stable_mir::mir::AssertMessage::DivisionByZero(op.stable(tables)) + } + AssertKind::RemainderByZero(op) => { + stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables)) + } + AssertKind::ResumedAfterReturn(coroutine) => { + stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables)) + } + AssertKind::ResumedAfterPanic(coroutine) => { + stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables)) + } + AssertKind::MisalignedPointerDereference { required, found } => { + stable_mir::mir::AssertMessage::MisalignedPointerDereference { + required: required.stable(tables), + found: found.stable(tables), + } + } + } + } +} + +impl<'tcx> Stable<'tcx> for mir::BinOp { + type T = stable_mir::mir::BinOp; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::BinOp; + match self { + BinOp::Add => stable_mir::mir::BinOp::Add, + BinOp::AddUnchecked => stable_mir::mir::BinOp::AddUnchecked, + BinOp::Sub => stable_mir::mir::BinOp::Sub, + BinOp::SubUnchecked => stable_mir::mir::BinOp::SubUnchecked, + BinOp::Mul => stable_mir::mir::BinOp::Mul, + BinOp::MulUnchecked => stable_mir::mir::BinOp::MulUnchecked, + BinOp::Div => stable_mir::mir::BinOp::Div, + BinOp::Rem => stable_mir::mir::BinOp::Rem, + BinOp::BitXor => stable_mir::mir::BinOp::BitXor, + BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd, + BinOp::BitOr => stable_mir::mir::BinOp::BitOr, + BinOp::Shl => stable_mir::mir::BinOp::Shl, + BinOp::ShlUnchecked => stable_mir::mir::BinOp::ShlUnchecked, + BinOp::Shr => stable_mir::mir::BinOp::Shr, + BinOp::ShrUnchecked => stable_mir::mir::BinOp::ShrUnchecked, + BinOp::Eq => stable_mir::mir::BinOp::Eq, + BinOp::Lt => stable_mir::mir::BinOp::Lt, + BinOp::Le => stable_mir::mir::BinOp::Le, + BinOp::Ne => stable_mir::mir::BinOp::Ne, + BinOp::Ge => stable_mir::mir::BinOp::Ge, + BinOp::Gt => stable_mir::mir::BinOp::Gt, + BinOp::Offset => stable_mir::mir::BinOp::Offset, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::UnOp { + type T = stable_mir::mir::UnOp; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::UnOp; + match self { + UnOp::Not => stable_mir::mir::UnOp::Not, + UnOp::Neg => stable_mir::mir::UnOp::Neg, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { + type T = stable_mir::mir::AggregateKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + mir::AggregateKind::Array(ty) => { + stable_mir::mir::AggregateKind::Array(ty.stable(tables)) + } + mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple, + mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => { + stable_mir::mir::AggregateKind::Adt( + tables.adt_def(*def_id), + var_idx.index(), + generic_arg.stable(tables), + user_ty_index.map(|idx| idx.index()), + field_idx.map(|idx| idx.index()), + ) + } + mir::AggregateKind::Closure(def_id, generic_arg) => { + stable_mir::mir::AggregateKind::Closure( + tables.closure_def(*def_id), + generic_arg.stable(tables), + ) + } + mir::AggregateKind::Coroutine(def_id, generic_arg, movability) => { + stable_mir::mir::AggregateKind::Coroutine( + tables.coroutine_def(*def_id), + generic_arg.stable(tables), + movability.stable(tables), + ) + } + } + } +} + +impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> { + type T = stable_mir::mir::InlineAsmOperand; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::InlineAsmOperand; + + let (in_value, out_place) = match self { + InlineAsmOperand::In { value, .. } => (Some(value.stable(tables)), None), + InlineAsmOperand::Out { place, .. } => (None, place.map(|place| place.stable(tables))), + InlineAsmOperand::InOut { in_value, out_place, .. } => { + (Some(in_value.stable(tables)), out_place.map(|place| place.stable(tables))) + } + InlineAsmOperand::Const { .. } + | InlineAsmOperand::SymFn { .. } + | InlineAsmOperand::SymStatic { .. } => (None, None), + }; + + stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{self:?}") } + } +} + +impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> { + type T = stable_mir::mir::Terminator; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::mir::Terminator; + Terminator { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { + type T = stable_mir::mir::TerminatorKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::mir::TerminatorKind; + match self { + mir::TerminatorKind::Goto { target } => { + TerminatorKind::Goto { target: target.as_usize() } + } + mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt { + discr: discr.stable(tables), + targets: targets + .iter() + .map(|(value, target)| stable_mir::mir::SwitchTarget { + value, + target: target.as_usize(), + }) + .collect(), + otherwise: targets.otherwise().as_usize(), + }, + mir::TerminatorKind::UnwindResume => TerminatorKind::Resume, + mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort, + mir::TerminatorKind::Return => TerminatorKind::Return, + mir::TerminatorKind::Unreachable => TerminatorKind::Unreachable, + mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => { + TerminatorKind::Drop { + place: place.stable(tables), + target: target.as_usize(), + unwind: unwind.stable(tables), + } + } + mir::TerminatorKind::Call { + func, + args, + destination, + target, + unwind, + call_source: _, + fn_span: _, + } => TerminatorKind::Call { + func: func.stable(tables), + args: args.iter().map(|arg| arg.stable(tables)).collect(), + destination: destination.stable(tables), + target: target.map(|t| t.as_usize()), + unwind: unwind.stable(tables), + }, + mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => { + TerminatorKind::Assert { + cond: cond.stable(tables), + expected: *expected, + msg: msg.stable(tables), + target: target.as_usize(), + unwind: unwind.stable(tables), + } + } + mir::TerminatorKind::InlineAsm { + template, + operands, + options, + line_spans, + destination, + unwind, + } => TerminatorKind::InlineAsm { + template: format!("{template:?}"), + operands: operands.iter().map(|operand| operand.stable(tables)).collect(), + options: format!("{options:?}"), + line_spans: format!("{line_spans:?}"), + destination: destination.map(|d| d.as_usize()), + unwind: unwind.stable(tables), + }, + mir::TerminatorKind::Yield { .. } + | mir::TerminatorKind::CoroutineDrop + | mir::TerminatorKind::FalseEdge { .. } + | mir::TerminatorKind::FalseUnwind { .. } => unreachable!(), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> { + type T = Allocation; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + self.inner().stable(tables) + } +} + +impl<'tcx> Stable<'tcx> for mir::interpret::Allocation { + type T = stable_mir::ty::Allocation; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + alloc::allocation_filter( + self, + alloc_range(rustc_target::abi::Size::ZERO, self.size()), + tables, + ) + } +} + +impl<'tcx> Stable<'tcx> for mir::interpret::AllocId { + type T = stable_mir::mir::alloc::AllocId; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + tables.create_alloc_id(*self) + } +} + +impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> { + type T = GlobalAlloc; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + mir::interpret::GlobalAlloc::Function(instance) => { + GlobalAlloc::Function(instance.stable(tables)) + } + mir::interpret::GlobalAlloc::VTable(ty, trait_ref) => { + GlobalAlloc::VTable(ty.stable(tables), trait_ref.stable(tables)) + } + mir::interpret::GlobalAlloc::Static(def) => { + GlobalAlloc::Static(tables.static_def(*def)) + } + mir::interpret::GlobalAlloc::Memory(alloc) => GlobalAlloc::Memory(alloc.stable(tables)), + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { + type T = stable_mir::ty::Const; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match *self { + mir::Const::Ty(c) => c.stable(tables), + mir::Const::Unevaluated(unev_const, ty) => { + let kind = + stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { + def: tables.const_def(unev_const.def), + args: unev_const.args.stable(tables), + promoted: unev_const.promoted.map(|u| u.as_u32()), + }); + let ty = ty.stable(tables); + let id = tables.intern_const(*self); + Const::new(kind, ty, id) + } + mir::Const::Val(val, ty) if matches!(val, mir::ConstValue::ZeroSized) => { + let ty = ty.stable(tables); + let id = tables.intern_const(*self); + Const::new(ConstantKind::ZeroSized, ty, id) + } + mir::Const::Val(val, ty) => { + let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables)); + let ty = ty.stable(tables); + let id = tables.intern_const(*self); + Const::new(kind, ty, id) + } + } + } +} + +impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled { + type T = Error; + + fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T { + Error::new(format!("{self:?}")) + } +} + +impl<'tcx> Stable<'tcx> for MonoItem<'tcx> { + type T = stable_mir::mir::mono::MonoItem; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::mir::mono::MonoItem as StableMonoItem; + match self { + MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables)), + MonoItem::Static(def_id) => StableMonoItem::Static(tables.static_def(*def_id)), + MonoItem::GlobalAsm(item_id) => StableMonoItem::GlobalAsm(opaque(item_id)), + } + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs new file mode 100644 index 00000000000..9bccb57f9b8 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs @@ -0,0 +1,74 @@ +//! Conversion of internal Rust compiler items to stable ones. +use crate::rustc_smir::{Stable, Tables}; +use rustc_target::abi::FieldIdx; +use stable_mir::mir::VariantIdx; + +mod mir; +mod ty; + +impl<'tcx> Stable<'tcx> for rustc_hir::Unsafety { + type T = stable_mir::mir::Safety; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + match self { + rustc_hir::Unsafety::Unsafe => stable_mir::mir::Safety::Unsafe, + rustc_hir::Unsafety::Normal => stable_mir::mir::Safety::Normal, + } + } +} + +impl<'tcx> Stable<'tcx> for FieldIdx { + type T = usize; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + self.as_usize() + } +} + +impl<'tcx> Stable<'tcx> for (rustc_target::abi::VariantIdx, FieldIdx) { + type T = (usize, usize); + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + (self.0.as_usize(), self.1.as_usize()) + } +} + +impl<'tcx> Stable<'tcx> for rustc_target::abi::VariantIdx { + type T = VariantIdx; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + self.as_usize() + } +} + +impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource { + type T = stable_mir::mir::CoroutineSource; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_hir::CoroutineSource; + match self { + CoroutineSource::Block => stable_mir::mir::CoroutineSource::Block, + CoroutineSource::Closure => stable_mir::mir::CoroutineSource::Closure, + CoroutineSource::Fn => stable_mir::mir::CoroutineSource::Fn, + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind { + type T = stable_mir::mir::CoroutineKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_hir::CoroutineKind; + match self { + CoroutineKind::Async(source) => { + stable_mir::mir::CoroutineKind::Async(source.stable(tables)) + } + CoroutineKind::Gen(source) => { + stable_mir::mir::CoroutineKind::Gen(source.stable(tables)) + } + CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine, + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_span::Span { + type T = stable_mir::ty::Span; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + tables.create_span(*self) + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs new file mode 100644 index 00000000000..cca7e0ce0b6 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -0,0 +1,814 @@ +//! Conversion of internal Rust compiler `ty` items to stable ones. + +use crate::rustc_smir::{alloc, Stable, Tables}; +use rustc_middle::ty::Ty; +use rustc_middle::{mir, ty}; +use stable_mir::ty::{ + AdtKind, Const, ConstantKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, + TyKind, UintTy, +}; + +impl<'tcx> Stable<'tcx> for ty::AliasKind { + type T = stable_mir::ty::AliasKind; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::ty::AliasKind::*; + match self { + Projection => stable_mir::ty::AliasKind::Projection, + Inherent => stable_mir::ty::AliasKind::Inherent, + Opaque => stable_mir::ty::AliasKind::Opaque, + Weak => stable_mir::ty::AliasKind::Weak, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> { + type T = stable_mir::ty::AliasTy; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::AliasTy { args, def_id, .. } = self; + stable_mir::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for ty::DynKind { + type T = stable_mir::ty::DynKind; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::ty::DynKind; + match self { + DynKind::Dyn => stable_mir::ty::DynKind::Dyn, + DynKind::DynStar => stable_mir::ty::DynKind::DynStar, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> { + type T = stable_mir::ty::ExistentialPredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::ExistentialPredicate::*; + match self { + ty::ExistentialPredicate::Trait(existential_trait_ref) => { + Trait(existential_trait_ref.stable(tables)) + } + ty::ExistentialPredicate::Projection(existential_projection) => { + Projection(existential_projection.stable(tables)) + } + ty::ExistentialPredicate::AutoTrait(def_id) => AutoTrait(tables.trait_def(*def_id)), + } + } +} + +impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> { + type T = stable_mir::ty::ExistentialTraitRef; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::ExistentialTraitRef { def_id, args } = self; + stable_mir::ty::ExistentialTraitRef { + def_id: tables.trait_def(*def_id), + generic_args: args.stable(tables), + } + } +} + +impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> { + type T = stable_mir::ty::TermKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::TermKind; + match self { + ty::TermKind::Ty(ty) => TermKind::Type(ty.stable(tables)), + ty::TermKind::Const(cnst) => { + let cnst = cnst.stable(tables); + TermKind::Const(cnst) + } + } + } +} + +impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> { + type T = stable_mir::ty::ExistentialProjection; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::ExistentialProjection { def_id, args, term } = self; + stable_mir::ty::ExistentialProjection { + def_id: tables.trait_def(*def_id), + generic_args: args.stable(tables), + term: term.unpack().stable(tables), + } + } +} + +impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion { + type T = stable_mir::mir::PointerCoercion; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::ty::adjustment::PointerCoercion; + match self { + PointerCoercion::ReifyFnPointer => stable_mir::mir::PointerCoercion::ReifyFnPointer, + PointerCoercion::UnsafeFnPointer => stable_mir::mir::PointerCoercion::UnsafeFnPointer, + PointerCoercion::ClosureFnPointer(unsafety) => { + stable_mir::mir::PointerCoercion::ClosureFnPointer(unsafety.stable(tables)) + } + PointerCoercion::MutToConstPointer => { + stable_mir::mir::PointerCoercion::MutToConstPointer + } + PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer, + PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex { + type T = usize; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + self.as_usize() + } +} + +impl<'tcx> Stable<'tcx> for ty::AdtKind { + type T = AdtKind; + + fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T { + match self { + ty::AdtKind::Struct => AdtKind::Struct, + ty::AdtKind::Union => AdtKind::Union, + ty::AdtKind::Enum => AdtKind::Enum, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> { + type T = stable_mir::ty::GenericArgs; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + GenericArgs(self.iter().map(|arg| arg.unpack().stable(tables)).collect()) + } +} + +impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> { + type T = stable_mir::ty::GenericArgKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::GenericArgKind; + match self { + ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)), + ty::GenericArgKind::Type(ty) => GenericArgKind::Type(ty.stable(tables)), + ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)), + } + } +} + +impl<'tcx, S, V> Stable<'tcx> for ty::Binder<'tcx, S> +where + S: Stable<'tcx, T = V>, +{ + type T = stable_mir::ty::Binder; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::Binder; + + Binder { + value: self.as_ref().skip_binder().stable(tables), + bound_vars: self + .bound_vars() + .iter() + .map(|bound_var| bound_var.stable(tables)) + .collect(), + } + } +} + +impl<'tcx, S, V> Stable<'tcx> for ty::EarlyBinder +where + S: Stable<'tcx, T = V>, +{ + type T = stable_mir::ty::EarlyBinder; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::EarlyBinder; + + EarlyBinder { value: self.as_ref().skip_binder().stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { + type T = stable_mir::ty::FnSig; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_target::spec::abi; + use stable_mir::ty::{Abi, FnSig}; + + FnSig { + inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(), + c_variadic: self.c_variadic, + unsafety: self.unsafety.stable(tables), + abi: match self.abi { + abi::Abi::Rust => Abi::Rust, + abi::Abi::C { unwind } => Abi::C { unwind }, + abi::Abi::Cdecl { unwind } => Abi::Cdecl { unwind }, + abi::Abi::Stdcall { unwind } => Abi::Stdcall { unwind }, + abi::Abi::Fastcall { unwind } => Abi::Fastcall { unwind }, + abi::Abi::Vectorcall { unwind } => Abi::Vectorcall { unwind }, + abi::Abi::Thiscall { unwind } => Abi::Thiscall { unwind }, + abi::Abi::Aapcs { unwind } => Abi::Aapcs { unwind }, + abi::Abi::Win64 { unwind } => Abi::Win64 { unwind }, + abi::Abi::SysV64 { unwind } => Abi::SysV64 { unwind }, + abi::Abi::PtxKernel => Abi::PtxKernel, + abi::Abi::Msp430Interrupt => Abi::Msp430Interrupt, + abi::Abi::X86Interrupt => Abi::X86Interrupt, + abi::Abi::AmdGpuKernel => Abi::AmdGpuKernel, + abi::Abi::EfiApi => Abi::EfiApi, + abi::Abi::AvrInterrupt => Abi::AvrInterrupt, + abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt, + abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall, + abi::Abi::Wasm => Abi::Wasm, + abi::Abi::System { unwind } => Abi::System { unwind }, + abi::Abi::RustIntrinsic => Abi::RustIntrinsic, + abi::Abi::RustCall => Abi::RustCall, + abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic, + abi::Abi::Unadjusted => Abi::Unadjusted, + abi::Abi::RustCold => Abi::RustCold, + abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM, + abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS, + }, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::BoundTyKind { + type T = stable_mir::ty::BoundTyKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::BoundTyKind; + + match self { + ty::BoundTyKind::Anon => BoundTyKind::Anon, + ty::BoundTyKind::Param(def_id, symbol) => { + BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string()) + } + } + } +} + +impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { + type T = stable_mir::ty::BoundRegionKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::BoundRegionKind; + + match self { + ty::BoundRegionKind::BrAnon => BoundRegionKind::BrAnon, + ty::BoundRegionKind::BrNamed(def_id, symbol) => { + BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string()) + } + ty::BoundRegionKind::BrEnv => BoundRegionKind::BrEnv, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::BoundVariableKind { + type T = stable_mir::ty::BoundVariableKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::BoundVariableKind; + + match self { + ty::BoundVariableKind::Ty(bound_ty_kind) => { + BoundVariableKind::Ty(bound_ty_kind.stable(tables)) + } + ty::BoundVariableKind::Region(bound_region_kind) => { + BoundVariableKind::Region(bound_region_kind.stable(tables)) + } + ty::BoundVariableKind::Const => BoundVariableKind::Const, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::IntTy { + type T = IntTy; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + match self { + ty::IntTy::Isize => IntTy::Isize, + ty::IntTy::I8 => IntTy::I8, + ty::IntTy::I16 => IntTy::I16, + ty::IntTy::I32 => IntTy::I32, + ty::IntTy::I64 => IntTy::I64, + ty::IntTy::I128 => IntTy::I128, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::UintTy { + type T = UintTy; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + match self { + ty::UintTy::Usize => UintTy::Usize, + ty::UintTy::U8 => UintTy::U8, + ty::UintTy::U16 => UintTy::U16, + ty::UintTy::U32 => UintTy::U32, + ty::UintTy::U64 => UintTy::U64, + ty::UintTy::U128 => UintTy::U128, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::FloatTy { + type T = FloatTy; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + match self { + ty::FloatTy::F32 => FloatTy::F32, + ty::FloatTy::F64 => FloatTy::F64, + } + } +} + +impl<'tcx> Stable<'tcx> for Ty<'tcx> { + type T = stable_mir::ty::Ty; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + tables.intern_ty(*self) + } +} + +impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { + type T = stable_mir::ty::TyKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + ty::Bool => TyKind::RigidTy(RigidTy::Bool), + ty::Char => TyKind::RigidTy(RigidTy::Char), + ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables))), + ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))), + ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))), + ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt( + tables.adt_def(adt_def.did()), + generic_args.stable(tables), + )), + ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))), + ty::Str => TyKind::RigidTy(RigidTy::Str), + ty::Array(ty, constant) => { + TyKind::RigidTy(RigidTy::Array(ty.stable(tables), constant.stable(tables))) + } + ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(ty.stable(tables))), + ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => { + TyKind::RigidTy(RigidTy::RawPtr(ty.stable(tables), mutbl.stable(tables))) + } + ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref( + region.stable(tables), + ty.stable(tables), + mutbl.stable(tables), + )), + ty::FnDef(def_id, generic_args) => { + TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables))) + } + ty::FnPtr(poly_fn_sig) => TyKind::RigidTy(RigidTy::FnPtr(poly_fn_sig.stable(tables))), + ty::Dynamic(existential_predicates, region, dyn_kind) => { + TyKind::RigidTy(RigidTy::Dynamic( + existential_predicates + .iter() + .map(|existential_predicate| existential_predicate.stable(tables)) + .collect(), + region.stable(tables), + dyn_kind.stable(tables), + )) + } + ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure( + tables.closure_def(*def_id), + generic_args.stable(tables), + )), + ty::Coroutine(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Coroutine( + tables.coroutine_def(*def_id), + generic_args.stable(tables), + movability.stable(tables), + )), + ty::Never => TyKind::RigidTy(RigidTy::Never), + ty::Tuple(fields) => { + TyKind::RigidTy(RigidTy::Tuple(fields.iter().map(|ty| ty.stable(tables)).collect())) + } + ty::Alias(alias_kind, alias_ty) => { + TyKind::Alias(alias_kind.stable(tables), alias_ty.stable(tables)) + } + ty::Param(param_ty) => TyKind::Param(param_ty.stable(tables)), + ty::Bound(debruijn_idx, bound_ty) => { + TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables)) + } + ty::CoroutineWitness(def_id, args) => TyKind::RigidTy(RigidTy::CoroutineWitness( + tables.coroutine_witness_def(*def_id), + args.stable(tables), + )), + ty::Placeholder(..) | ty::Infer(_) | ty::Error(_) => { + unreachable!(); + } + } + } +} + +impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { + type T = stable_mir::ty::Const; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let kind = match self.kind() { + ty::Value(val) => { + let const_val = tables.tcx.valtree_to_const_val((self.ty(), val)); + if matches!(const_val, mir::ConstValue::ZeroSized) { + ConstantKind::ZeroSized + } else { + stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( + self.ty(), + const_val, + tables, + )) + } + } + ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)), + ty::ErrorCt(_) => unreachable!(), + ty::InferCt(_) => unreachable!(), + ty::BoundCt(_, _) => unimplemented!(), + ty::PlaceholderCt(_) => unimplemented!(), + ty::Unevaluated(uv) => { + stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { + def: tables.const_def(uv.def), + args: uv.args.stable(tables), + promoted: None, + }) + } + ty::ExprCt(_) => unimplemented!(), + }; + let ty = self.ty().stable(tables); + let id = tables.intern_const(mir::Const::Ty(*self)); + Const::new(kind, ty, id) + } +} + +impl<'tcx> Stable<'tcx> for ty::ParamConst { + type T = stable_mir::ty::ParamConst; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::ParamConst; + ParamConst { index: self.index, name: self.name.to_string() } + } +} + +impl<'tcx> Stable<'tcx> for ty::ParamTy { + type T = stable_mir::ty::ParamTy; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::ParamTy; + ParamTy { index: self.index, name: self.name.to_string() } + } +} + +impl<'tcx> Stable<'tcx> for ty::BoundTy { + type T = stable_mir::ty::BoundTy; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::BoundTy; + BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind { + type T = stable_mir::ty::TraitSpecializationKind; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::TraitSpecializationKind; + + match self { + ty::trait_def::TraitSpecializationKind::None => TraitSpecializationKind::None, + ty::trait_def::TraitSpecializationKind::Marker => TraitSpecializationKind::Marker, + ty::trait_def::TraitSpecializationKind::AlwaysApplicable => { + TraitSpecializationKind::AlwaysApplicable + } + } + } +} + +impl<'tcx> Stable<'tcx> for ty::TraitDef { + type T = stable_mir::ty::TraitDecl; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::opaque; + use stable_mir::ty::TraitDecl; + + TraitDecl { + def_id: tables.trait_def(self.def_id), + unsafety: self.unsafety.stable(tables), + paren_sugar: self.paren_sugar, + has_auto_impl: self.has_auto_impl, + is_marker: self.is_marker, + is_coinductive: self.is_coinductive, + skip_array_during_method_dispatch: self.skip_array_during_method_dispatch, + specialization_kind: self.specialization_kind.stable(tables), + must_implement_one_of: self + .must_implement_one_of + .as_ref() + .map(|idents| idents.iter().map(|ident| opaque(ident)).collect()), + implement_via_object: self.implement_via_object, + deny_explicit_impl: self.deny_explicit_impl, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> { + type T = stable_mir::ty::TraitRef; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::TraitRef; + + TraitRef::try_new(tables.trait_def(self.def_id), self.args.stable(tables)).unwrap() + } +} + +impl<'tcx> Stable<'tcx> for ty::Generics { + type T = stable_mir::ty::Generics; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::Generics; + + let params: Vec<_> = self.params.iter().map(|param| param.stable(tables)).collect(); + let param_def_id_to_index = + params.iter().map(|param| (param.def_id, param.index)).collect(); + + Generics { + parent: self.parent.map(|did| tables.generic_def(did)), + parent_count: self.parent_count, + params, + param_def_id_to_index, + has_self: self.has_self, + has_late_bound_regions: self + .has_late_bound_regions + .as_ref() + .map(|late_bound_regions| late_bound_regions.stable(tables)), + host_effect_index: self.host_effect_index, + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { + type T = stable_mir::ty::GenericParamDefKind; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::GenericParamDefKind; + match self { + ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime, + ty::GenericParamDefKind::Type { has_default, synthetic } => { + GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic } + } + ty::GenericParamDefKind::Const { has_default, is_host_effect: _ } => { + GenericParamDefKind::Const { has_default: *has_default } + } + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef { + type T = stable_mir::ty::GenericParamDef; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + GenericParamDef { + name: self.name.to_string(), + def_id: tables.generic_def(self.def_id), + index: self.index, + pure_wrt_drop: self.pure_wrt_drop, + kind: self.kind.stable(tables), + } + } +} + +impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> { + type T = stable_mir::ty::PredicateKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::ty::PredicateKind; + match self { + PredicateKind::Clause(clause_kind) => { + stable_mir::ty::PredicateKind::Clause(clause_kind.stable(tables)) + } + PredicateKind::ObjectSafe(did) => { + stable_mir::ty::PredicateKind::ObjectSafe(tables.trait_def(*did)) + } + PredicateKind::Subtype(subtype_predicate) => { + stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables)) + } + PredicateKind::Coerce(coerce_predicate) => { + stable_mir::ty::PredicateKind::Coerce(coerce_predicate.stable(tables)) + } + PredicateKind::ConstEquate(a, b) => { + stable_mir::ty::PredicateKind::ConstEquate(a.stable(tables), b.stable(tables)) + } + PredicateKind::Ambiguous => stable_mir::ty::PredicateKind::Ambiguous, + PredicateKind::AliasRelate(a, b, alias_relation_direction) => { + stable_mir::ty::PredicateKind::AliasRelate( + a.unpack().stable(tables), + b.unpack().stable(tables), + alias_relation_direction.stable(tables), + ) + } + } + } +} + +impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { + type T = stable_mir::ty::ClauseKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::ty::ClauseKind; + match *self { + ClauseKind::Trait(trait_object) => { + stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables)) + } + ClauseKind::RegionOutlives(region_outlives) => { + stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables)) + } + ClauseKind::TypeOutlives(type_outlives) => { + let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives; + stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate( + a.stable(tables), + b.stable(tables), + )) + } + ClauseKind::Projection(projection_predicate) => { + stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables)) + } + ClauseKind::ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType( + const_.stable(tables), + ty.stable(tables), + ), + ClauseKind::WellFormed(generic_arg) => { + stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables)) + } + ClauseKind::ConstEvaluatable(const_) => { + stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables)) + } + } + } +} + +impl<'tcx> Stable<'tcx> for ty::ClosureKind { + type T = stable_mir::ty::ClosureKind; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::ty::ClosureKind::*; + match self { + Fn => stable_mir::ty::ClosureKind::Fn, + FnMut => stable_mir::ty::ClosureKind::FnMut, + FnOnce => stable_mir::ty::ClosureKind::FnOnce, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> { + type T = stable_mir::ty::SubtypePredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::SubtypePredicate { a, b, a_is_expected: _ } = self; + stable_mir::ty::SubtypePredicate { a: a.stable(tables), b: b.stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> { + type T = stable_mir::ty::CoercePredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::CoercePredicate { a, b } = self; + stable_mir::ty::CoercePredicate { a: a.stable(tables), b: b.stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection { + type T = stable_mir::ty::AliasRelationDirection; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::ty::AliasRelationDirection::*; + match self { + Equate => stable_mir::ty::AliasRelationDirection::Equate, + Subtype => stable_mir::ty::AliasRelationDirection::Subtype, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> { + type T = stable_mir::ty::TraitPredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::TraitPredicate { trait_ref, polarity } = self; + stable_mir::ty::TraitPredicate { + trait_ref: trait_ref.stable(tables), + polarity: polarity.stable(tables), + } + } +} + +impl<'tcx, A, B, U, V> Stable<'tcx> for ty::OutlivesPredicate +where + A: Stable<'tcx, T = U>, + B: Stable<'tcx, T = V>, +{ + type T = stable_mir::ty::OutlivesPredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::OutlivesPredicate(a, b) = self; + stable_mir::ty::OutlivesPredicate(a.stable(tables), b.stable(tables)) + } +} + +impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { + type T = stable_mir::ty::ProjectionPredicate; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let ty::ProjectionPredicate { projection_ty, term } = self; + stable_mir::ty::ProjectionPredicate { + projection_ty: projection_ty.stable(tables), + term: term.unpack().stable(tables), + } + } +} + +impl<'tcx> Stable<'tcx> for ty::ImplPolarity { + type T = stable_mir::ty::ImplPolarity; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::ty::ImplPolarity::*; + match self { + Positive => stable_mir::ty::ImplPolarity::Positive, + Negative => stable_mir::ty::ImplPolarity::Negative, + Reservation => stable_mir::ty::ImplPolarity::Reservation, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { + type T = stable_mir::ty::Region; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + Region { kind: self.kind().stable(tables) } + } +} + +impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { + type T = stable_mir::ty::RegionKind; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind}; + match self { + ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion { + def_id: tables.region_def(early_reg.def_id), + index: early_reg.index, + name: early_reg.name.to_string(), + }), + ty::ReBound(db_index, bound_reg) => RegionKind::ReBound( + db_index.as_u32(), + BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) }, + ), + ty::ReStatic => RegionKind::ReStatic, + ty::RePlaceholder(place_holder) => { + RegionKind::RePlaceholder(stable_mir::ty::Placeholder { + universe: place_holder.universe.as_u32(), + bound: BoundRegion { + var: place_holder.bound.var.as_u32(), + kind: place_holder.bound.kind.stable(tables), + }, + }) + } + ty::ReErased => RegionKind::ReErased, + _ => unreachable!("{self:?}"), + } + } +} + +impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { + type T = stable_mir::mir::mono::Instance; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + let def = tables.instance_def(*self); + let kind = match self.def { + ty::InstanceDef::Item(..) => stable_mir::mir::mono::InstanceKind::Item, + ty::InstanceDef::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic, + ty::InstanceDef::Virtual(..) => stable_mir::mir::mono::InstanceKind::Virtual, + ty::InstanceDef::VTableShim(..) + | ty::InstanceDef::ReifyShim(..) + | ty::InstanceDef::FnPtrAddrShim(..) + | ty::InstanceDef::ClosureOnceShim { .. } + | ty::InstanceDef::ThreadLocalShim(..) + | ty::InstanceDef::DropGlue(..) + | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::FnPtrShim(..) => stable_mir::mir::mono::InstanceKind::Shim, + }; + stable_mir::mir::mono::Instance { def, kind } + } +} + +impl<'tcx> Stable<'tcx> for ty::Variance { + type T = stable_mir::mir::Variance; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + match self { + ty::Variance::Bivariant => stable_mir::mir::Variance::Bivariant, + ty::Variance::Contravariant => stable_mir::mir::Variance::Contravariant, + ty::Variance::Covariant => stable_mir::mir::Variance::Covariant, + ty::Variance::Invariant => stable_mir::mir::Variance::Invariant, + } + } +} + +impl<'tcx> Stable<'tcx> for ty::Movability { + type T = stable_mir::ty::Movability; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + match self { + ty::Movability::Static => stable_mir::ty::Movability::Static, + ty::Movability::Movable => stable_mir::ty::Movability::Movable, + } + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 9921a89eb23..5d903e69c6c 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,389 +7,22 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use crate::rustc_internal::{internal, IndexMap, RustcInternal}; -use crate::rustc_smir::stable_mir::ty::{BoundRegion, Region}; -use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_middle::mir; -use rustc_middle::mir::interpret::{alloc_range, AllocId}; -use rustc_middle::mir::mono::MonoItem; -use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; -use rustc_middle::ty::{self, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, Variance}; +use rustc_middle::mir::interpret::AllocId; +use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use rustc_target::abi::FieldIdx; -use stable_mir::mir::alloc::GlobalAlloc; -use stable_mir::mir::mono::{InstanceDef, StaticDef}; -use stable_mir::mir::{ - Body, ConstOperand, CopyNonOverlapping, Statement, UserTypeProjection, VarDebugInfoFragment, - VariantIdx, -}; -use stable_mir::ty::{ - AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, - EarlyParamRegion, FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, - RigidTy, Span, TyKind, UintTy, -}; -use stable_mir::{self, opaque, Context, Crate, CrateItem, Error, Filename, ItemKind, Symbol}; -use std::cell::RefCell; +use stable_mir::mir::mono::InstanceDef; +use stable_mir::ty::{ConstId, Span}; +use stable_mir::{self, ItemKind}; use tracing::debug; +use crate::rustc_internal::IndexMap; + mod alloc; mod builder; - -impl<'tcx> Context for TablesWrapper<'tcx> { - fn local_crate(&self) -> stable_mir::Crate { - let tables = self.0.borrow(); - smir_crate(tables.tcx, LOCAL_CRATE) - } - - fn external_crates(&self) -> Vec { - let tables = self.0.borrow(); - tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect() - } - - fn find_crates(&self, name: &str) -> Vec { - let tables = self.0.borrow(); - let crates: Vec = [LOCAL_CRATE] - .iter() - .chain(tables.tcx.crates(()).iter()) - .map(|crate_num| { - let crate_name = tables.tcx.crate_name(*crate_num).to_string(); - (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num)) - }) - .into_iter() - .filter_map(|c| c) - .collect(); - crates - } - - fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol { - let tables = self.0.borrow(); - if trimmed { - with_forced_trimmed_paths!(tables.tcx.def_path_str(tables[def_id])) - } else { - with_no_trimmed_paths!(tables.tcx.def_path_str(tables[def_id])) - } - } - - fn krate(&self, def_id: stable_mir::DefId) -> Crate { - let tables = self.0.borrow(); - smir_crate(tables.tcx, tables[def_id].krate) - } - - fn span_to_string(&self, span: stable_mir::ty::Span) -> String { - let tables = self.0.borrow(); - tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span]) - } - - fn get_filename(&self, span: &Span) -> Filename { - let tables = self.0.borrow(); - tables - .tcx - .sess - .source_map() - .span_to_filename(tables[*span]) - .display(rustc_span::FileNameDisplayPreference::Local) - .to_string() - } - - fn get_lines(&self, span: &Span) -> LineInfo { - let tables = self.0.borrow(); - let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]); - LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 } - } - - fn item_kind(&self, item: CrateItem) -> ItemKind { - let tables = self.0.borrow(); - new_item_kind(tables.tcx.def_kind(tables[item.0])) - } - - fn is_foreign_item(&self, item: CrateItem) -> bool { - let tables = self.0.borrow(); - tables.tcx.is_foreign_item(tables[item.0]) - } - - fn adt_kind(&self, def: AdtDef) -> AdtKind { - let mut tables = self.0.borrow_mut(); - def.internal(&mut *tables).adt_kind().stable(&mut *tables) - } - - fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty { - let mut tables = self.0.borrow_mut(); - tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables) - } - - fn const_literal(&self, cnst: &stable_mir::ty::Const) -> String { - internal(cnst).to_string() - } - - fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span { - let mut tables = self.0.borrow_mut(); - tables.tcx.def_span(tables[def_id]).stable(&mut *tables) - } - - fn all_local_items(&self) -> stable_mir::CrateItems { - let mut tables = self.0.borrow_mut(); - tables.tcx.mir_keys(()).iter().map(|item| tables.crate_item(item.to_def_id())).collect() - } - - fn entry_fn(&self) -> Option { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - Some(tables.crate_item(tcx.entry_fn(())?.0)) - } - - fn all_trait_decls(&self) -> stable_mir::TraitDecls { - let mut tables = self.0.borrow_mut(); - tables - .tcx - .traits(LOCAL_CRATE) - .iter() - .map(|trait_def_id| tables.trait_def(*trait_def_id)) - .collect() - } - - fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl { - let mut tables = self.0.borrow_mut(); - let def_id = tables[trait_def.0]; - let trait_def = tables.tcx.trait_def(def_id); - trait_def.stable(&mut *tables) - } - - fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls { - let mut tables = self.0.borrow_mut(); - tables - .tcx - .trait_impls_in_crate(LOCAL_CRATE) - .iter() - .map(|impl_def_id| tables.impl_def(*impl_def_id)) - .collect() - } - - fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait { - let mut tables = self.0.borrow_mut(); - let def_id = tables[impl_def.0]; - let impl_trait = tables.tcx.impl_trait_ref(def_id).unwrap(); - impl_trait.stable(&mut *tables) - } - - fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body { - let mut tables = self.0.borrow_mut(); - let def_id = tables[item]; - tables.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(&mut tables) - } - - fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind { - let mut tables = self.0.borrow_mut(); - tables.types[ty].kind().stable(&mut *tables) - } - - fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics { - let mut tables = self.0.borrow_mut(); - let def_id = tables[def_id]; - let generics = tables.tcx.generics_of(def_id); - generics.stable(&mut *tables) - } - - fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates { - let mut tables = self.0.borrow_mut(); - let def_id = tables[def_id]; - let ty::GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id); - stable_mir::ty::GenericPredicates { - parent: parent.map(|did| tables.trait_def(did)), - predicates: predicates - .iter() - .map(|(clause, span)| { - ( - clause.as_predicate().kind().skip_binder().stable(&mut *tables), - span.stable(&mut *tables), - ) - }) - .collect(), - } - } - - fn explicit_predicates_of( - &self, - def_id: stable_mir::DefId, - ) -> stable_mir::ty::GenericPredicates { - let mut tables = self.0.borrow_mut(); - let def_id = tables[def_id]; - let ty::GenericPredicates { parent, predicates } = - tables.tcx.explicit_predicates_of(def_id); - stable_mir::ty::GenericPredicates { - parent: parent.map(|did| tables.trait_def(did)), - predicates: predicates - .iter() - .map(|(clause, span)| { - ( - clause.as_predicate().kind().skip_binder().stable(&mut *tables), - span.stable(&mut *tables), - ) - }) - .collect(), - } - } - - fn instance_body(&self, def: InstanceDef) -> Option { - let mut tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - tables - .has_body(instance) - .then(|| builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables)) - } - - fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty { - let mut tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - instance.ty(tables.tcx, ParamEnv::empty()).stable(&mut *tables) - } - - fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId { - let mut tables = self.0.borrow_mut(); - let def_id = tables.instances[def].def_id(); - tables.create_def_id(def_id) - } - - fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol { - let tables = self.0.borrow_mut(); - let instance = tables.instances[instance]; - tables.tcx.symbol_name(instance).name.to_string() - } - - /// Retrieve the instance name for diagnostic messages. - /// - /// This will return the specialized name, e.g., `Vec::new`. - fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol { - let tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - if trimmed { - with_forced_trimmed_paths!( - tables.tcx.def_path_str_with_args(instance.def_id(), instance.args) - ) - } else { - with_no_trimmed_paths!( - tables.tcx.def_path_str_with_args(instance.def_id(), instance.args) - ) - } - } - - fn mono_instance(&self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance { - let mut tables = self.0.borrow_mut(); - let def_id = tables[item.0]; - Instance::mono(tables.tcx, def_id).stable(&mut *tables) - } - - fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool { - let tables = self.0.borrow(); - let def_id = tables[def_id]; - let generics = tables.tcx.generics_of(def_id); - let result = generics.requires_monomorphization(tables.tcx); - result - } - - fn resolve_instance( - &self, - def: stable_mir::ty::FnDef, - args: &stable_mir::ty::GenericArgs, - ) -> Option { - let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); - let args_ref = args.internal(&mut *tables); - match Instance::resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) { - Ok(Some(instance)) => Some(instance.stable(&mut *tables)), - Ok(None) | Err(_) => None, - } - } - - fn resolve_drop_in_place(&self, ty: stable_mir::ty::Ty) -> stable_mir::mir::mono::Instance { - let mut tables = self.0.borrow_mut(); - let internal_ty = ty.internal(&mut *tables); - let instance = Instance::resolve_drop_in_place(tables.tcx, internal_ty); - instance.stable(&mut *tables) - } - - fn resolve_for_fn_ptr( - &self, - def: FnDef, - args: &GenericArgs, - ) -> Option { - let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); - let args_ref = args.internal(&mut *tables); - Instance::resolve_for_fn_ptr(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) - .stable(&mut *tables) - } - - fn resolve_closure( - &self, - def: ClosureDef, - args: &GenericArgs, - kind: ClosureKind, - ) -> Option { - let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); - let args_ref = args.internal(&mut *tables); - let closure_kind = kind.internal(&mut *tables); - Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind).stable(&mut *tables) - } - - fn adt_is_box(&self, def: AdtDef) -> bool { - let mut tables = self.0.borrow_mut(); - def.internal(&mut *tables).is_box() - } - - fn eval_target_usize(&self, cnst: &Const) -> Result { - let mut tables = self.0.borrow_mut(); - let mir_const = cnst.internal(&mut *tables); - mir_const - .try_eval_target_usize(tables.tcx, ParamEnv::empty()) - .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) - } - - fn eval_static_initializer(&self, def: StaticDef) -> Result { - let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); - tables.tcx.eval_static_initializer(def_id).stable(&mut *tables) - } - - fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc { - let mut tables = self.0.borrow_mut(); - let alloc_id = alloc.internal(&mut *tables); - tables.tcx.global_alloc(alloc_id).stable(&mut *tables) - } - - fn vtable_allocation( - &self, - global_alloc: &GlobalAlloc, - ) -> Option { - let mut tables = self.0.borrow_mut(); - let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else { return None }; - let alloc_id = tables - .tcx - .vtable_allocation((ty.internal(&mut *tables), trait_ref.internal(&mut *tables))); - Some(alloc_id.stable(&mut *tables)) - } - - fn usize_to_const(&self, val: u64) -> Result { - let mut tables = self.0.borrow_mut(); - let ty = tables.tcx.types.usize; - let size = tables.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap().size; - - let scalar = ScalarInt::try_from_uint(val, size).ok_or_else(|| { - Error::new(format!("Value overflow: cannot convert `{val}` to usize.")) - })?; - Ok(ty::Const::new_value(tables.tcx, ty::ValTree::from_scalar_int(scalar), ty) - .stable(&mut *tables)) - } - - fn new_rigid_ty(&self, kind: RigidTy) -> stable_mir::ty::Ty { - let mut tables = self.0.borrow_mut(); - let internal_kind = kind.internal(&mut *tables); - tables.tcx.mk_ty_from_kind(internal_kind).stable(&mut *tables) - } -} - -pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell>); +pub(crate) mod context; +mod convert; pub struct Tables<'tcx> { pub(crate) tcx: TyCtxt<'tcx>, @@ -402,15 +35,15 @@ pub struct Tables<'tcx> { } impl<'tcx> Tables<'tcx> { - fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty { + pub(crate) fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty { self.types.create_or_fetch(ty) } - fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId { + pub(crate) fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId { self.constants.create_or_fetch(constant) } - fn has_body(&self, instance: Instance<'tcx>) -> bool { + pub(crate) fn has_body(&self, instance: Instance<'tcx>) -> bool { let def_id = instance.def_id(); self.tcx.is_mir_available(def_id) || !matches!( @@ -423,14 +56,14 @@ impl<'tcx> Tables<'tcx> { } /// Build a stable mir crate from a given crate number. -fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { +pub(crate) fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { let crate_name = tcx.crate_name(crate_num).to_string(); let is_local = crate_num == LOCAL_CRATE; debug!(?crate_name, ?crate_num, "smir_crate"); stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local } } -fn new_item_kind(kind: DefKind) -> ItemKind { +pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { match kind { DefKind::Mod | DefKind::Struct @@ -472,1610 +105,6 @@ pub trait Stable<'tcx> { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T; } -impl<'tcx> Stable<'tcx> for mir::Body<'tcx> { - type T = stable_mir::mir::Body; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - stable_mir::mir::Body::new( - self.basic_blocks - .iter() - .map(|block| stable_mir::mir::BasicBlock { - terminator: block.terminator().stable(tables), - statements: block - .statements - .iter() - .map(|statement| statement.stable(tables)) - .collect(), - }) - .collect(), - self.local_decls - .iter() - .map(|decl| stable_mir::mir::LocalDecl { - ty: decl.ty.stable(tables), - span: decl.source_info.span.stable(tables), - mutability: decl.mutability.stable(tables), - }) - .collect(), - self.arg_count, - self.var_debug_info.iter().map(|info| info.stable(tables)).collect(), - ) - } -} - -impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> { - type T = stable_mir::mir::VarDebugInfo; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - stable_mir::mir::VarDebugInfo { - name: self.name.to_string(), - source_info: self.source_info.stable(tables), - composite: self.composite.as_ref().map(|composite| composite.stable(tables)), - value: self.value.stable(tables), - argument_index: self.argument_index, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { - type T = stable_mir::mir::Statement; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) } - } -} - -impl<'tcx> Stable<'tcx> for mir::SourceInfo { - type T = stable_mir::mir::SourceInfo; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - stable_mir::mir::SourceInfo { span: self.span.stable(tables), scope: self.scope.into() } - } -} - -impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> { - type T = stable_mir::mir::VarDebugInfoFragment; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - VarDebugInfoFragment { - ty: self.ty.stable(tables), - projection: self.projection.iter().map(|e| e.stable(tables)).collect(), - } - } -} - -impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> { - type T = stable_mir::mir::VarDebugInfoContents; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - match self { - mir::VarDebugInfoContents::Place(place) => { - stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables)) - } - mir::VarDebugInfoContents::Const(const_operand) => { - let op = ConstOperand { - span: const_operand.span.stable(tables), - user_ty: const_operand.user_ty.map(|index| index.as_usize()), - const_: const_operand.const_.stable(tables), - }; - stable_mir::mir::VarDebugInfoContents::Const(op) - } - } - } -} - -impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> { - type T = stable_mir::mir::StatementKind; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - match self { - mir::StatementKind::Assign(assign) => stable_mir::mir::StatementKind::Assign( - assign.0.stable(tables), - assign.1.stable(tables), - ), - mir::StatementKind::FakeRead(fake_read_place) => { - stable_mir::mir::StatementKind::FakeRead( - fake_read_place.0.stable(tables), - fake_read_place.1.stable(tables), - ) - } - mir::StatementKind::SetDiscriminant { place, variant_index } => { - stable_mir::mir::StatementKind::SetDiscriminant { - place: place.as_ref().stable(tables), - variant_index: variant_index.stable(tables), - } - } - mir::StatementKind::Deinit(place) => { - stable_mir::mir::StatementKind::Deinit(place.stable(tables)) - } - - mir::StatementKind::StorageLive(place) => { - stable_mir::mir::StatementKind::StorageLive(place.stable(tables)) - } - - mir::StatementKind::StorageDead(place) => { - stable_mir::mir::StatementKind::StorageDead(place.stable(tables)) - } - mir::StatementKind::Retag(retag, place) => { - stable_mir::mir::StatementKind::Retag(retag.stable(tables), place.stable(tables)) - } - mir::StatementKind::PlaceMention(place) => { - stable_mir::mir::StatementKind::PlaceMention(place.stable(tables)) - } - mir::StatementKind::AscribeUserType(place_projection, variance) => { - stable_mir::mir::StatementKind::AscribeUserType { - place: place_projection.as_ref().0.stable(tables), - projections: place_projection.as_ref().1.stable(tables), - variance: variance.stable(tables), - } - } - mir::StatementKind::Coverage(coverage) => { - stable_mir::mir::StatementKind::Coverage(opaque(coverage)) - } - mir::StatementKind::Intrinsic(intrinstic) => { - stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables)) - } - mir::StatementKind::ConstEvalCounter => { - stable_mir::mir::StatementKind::ConstEvalCounter - } - mir::StatementKind::Nop => stable_mir::mir::StatementKind::Nop, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { - type T = stable_mir::mir::Rvalue; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use mir::Rvalue::*; - match self { - Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)), - Repeat(op, len) => { - let len = len.stable(tables); - stable_mir::mir::Rvalue::Repeat(op.stable(tables), len) - } - Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref( - region.stable(tables), - kind.stable(tables), - place.stable(tables), - ), - ThreadLocalRef(def_id) => { - stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id)) - } - AddressOf(mutability, place) => { - stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables)) - } - Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)), - Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast( - cast_kind.stable(tables), - op.stable(tables), - ty.stable(tables), - ), - BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp( - bin_op.stable(tables), - ops.0.stable(tables), - ops.1.stable(tables), - ), - CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp( - bin_op.stable(tables), - ops.0.stable(tables), - ops.1.stable(tables), - ), - NullaryOp(null_op, ty) => { - stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), ty.stable(tables)) - } - UnaryOp(un_op, op) => { - stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables)) - } - Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables)), - Aggregate(agg_kind, operands) => { - let operands = operands.iter().map(|op| op.stable(tables)).collect(); - stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands) - } - ShallowInitBox(op, ty) => { - stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables)) - } - CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)), - } - } -} - -impl<'tcx> Stable<'tcx> for mir::Mutability { - type T = stable_mir::mir::Mutability; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use mir::Mutability::*; - match *self { - Not => stable_mir::mir::Mutability::Not, - Mut => stable_mir::mir::Mutability::Mut, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::BorrowKind { - type T = stable_mir::mir::BorrowKind; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use mir::BorrowKind::*; - match *self { - Shared => stable_mir::mir::BorrowKind::Shared, - Fake => stable_mir::mir::BorrowKind::Fake, - Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) }, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::MutBorrowKind { - type T = stable_mir::mir::MutBorrowKind; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use mir::MutBorrowKind::*; - match *self { - Default => stable_mir::mir::MutBorrowKind::Default, - TwoPhaseBorrow => stable_mir::mir::MutBorrowKind::TwoPhaseBorrow, - ClosureCapture => stable_mir::mir::MutBorrowKind::ClosureCapture, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> { - type T = stable_mir::mir::NullOp; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use mir::NullOp::*; - match self { - SizeOf => stable_mir::mir::NullOp::SizeOf, - AlignOf => stable_mir::mir::NullOp::AlignOf, - OffsetOf(indices) => stable_mir::mir::NullOp::OffsetOf( - indices.iter().map(|idx| idx.stable(tables)).collect(), - ), - } - } -} - -impl<'tcx> Stable<'tcx> for mir::CastKind { - type T = stable_mir::mir::CastKind; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use mir::CastKind::*; - match self { - PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress, - PointerFromExposedAddress => stable_mir::mir::CastKind::PointerFromExposedAddress, - PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), - DynStar => stable_mir::mir::CastKind::DynStar, - IntToInt => stable_mir::mir::CastKind::IntToInt, - FloatToInt => stable_mir::mir::CastKind::FloatToInt, - FloatToFloat => stable_mir::mir::CastKind::FloatToFloat, - IntToFloat => stable_mir::mir::CastKind::IntToFloat, - PtrToPtr => stable_mir::mir::CastKind::PtrToPtr, - FnPtrToPtr => stable_mir::mir::CastKind::FnPtrToPtr, - Transmute => stable_mir::mir::CastKind::Transmute, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::AliasKind { - type T = stable_mir::ty::AliasKind; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use ty::AliasKind::*; - match self { - Projection => stable_mir::ty::AliasKind::Projection, - Inherent => stable_mir::ty::AliasKind::Inherent, - Opaque => stable_mir::ty::AliasKind::Opaque, - Weak => stable_mir::ty::AliasKind::Weak, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> { - type T = stable_mir::ty::AliasTy; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let ty::AliasTy { args, def_id, .. } = self; - stable_mir::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables) } - } -} - -impl<'tcx> Stable<'tcx> for ty::DynKind { - type T = stable_mir::ty::DynKind; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use ty::DynKind; - match self { - DynKind::Dyn => stable_mir::ty::DynKind::Dyn, - DynKind::DynStar => stable_mir::ty::DynKind::DynStar, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> { - type T = stable_mir::ty::ExistentialPredicate; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::ExistentialPredicate::*; - match self { - ty::ExistentialPredicate::Trait(existential_trait_ref) => { - Trait(existential_trait_ref.stable(tables)) - } - ty::ExistentialPredicate::Projection(existential_projection) => { - Projection(existential_projection.stable(tables)) - } - ty::ExistentialPredicate::AutoTrait(def_id) => AutoTrait(tables.trait_def(*def_id)), - } - } -} - -impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> { - type T = stable_mir::ty::ExistentialTraitRef; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let ty::ExistentialTraitRef { def_id, args } = self; - stable_mir::ty::ExistentialTraitRef { - def_id: tables.trait_def(*def_id), - generic_args: args.stable(tables), - } - } -} - -impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> { - type T = stable_mir::ty::TermKind; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::TermKind; - match self { - ty::TermKind::Ty(ty) => TermKind::Type(ty.stable(tables)), - ty::TermKind::Const(cnst) => { - let cnst = cnst.stable(tables); - TermKind::Const(cnst) - } - } - } -} - -impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> { - type T = stable_mir::ty::ExistentialProjection; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let ty::ExistentialProjection { def_id, args, term } = self; - stable_mir::ty::ExistentialProjection { - def_id: tables.trait_def(*def_id), - generic_args: args.stable(tables), - term: term.unpack().stable(tables), - } - } -} - -impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion { - type T = stable_mir::mir::PointerCoercion; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use ty::adjustment::PointerCoercion; - match self { - PointerCoercion::ReifyFnPointer => stable_mir::mir::PointerCoercion::ReifyFnPointer, - PointerCoercion::UnsafeFnPointer => stable_mir::mir::PointerCoercion::UnsafeFnPointer, - PointerCoercion::ClosureFnPointer(unsafety) => { - stable_mir::mir::PointerCoercion::ClosureFnPointer(unsafety.stable(tables)) - } - PointerCoercion::MutToConstPointer => { - stable_mir::mir::PointerCoercion::MutToConstPointer - } - PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer, - PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize, - } - } -} - -impl<'tcx> Stable<'tcx> for rustc_hir::Unsafety { - type T = stable_mir::mir::Safety; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - match self { - rustc_hir::Unsafety::Unsafe => stable_mir::mir::Safety::Unsafe, - rustc_hir::Unsafety::Normal => stable_mir::mir::Safety::Normal, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::FakeReadCause { - type T = stable_mir::mir::FakeReadCause; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use mir::FakeReadCause::*; - match self { - ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard, - ForMatchedPlace(local_def_id) => { - stable_mir::mir::FakeReadCause::ForMatchedPlace(opaque(local_def_id)) - } - ForGuardBinding => stable_mir::mir::FakeReadCause::ForGuardBinding, - ForLet(local_def_id) => stable_mir::mir::FakeReadCause::ForLet(opaque(local_def_id)), - ForIndex => stable_mir::mir::FakeReadCause::ForIndex, - } - } -} - -impl<'tcx> Stable<'tcx> for FieldIdx { - type T = usize; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - self.as_usize() - } -} - -impl<'tcx> Stable<'tcx> for (rustc_target::abi::VariantIdx, FieldIdx) { - type T = (usize, usize); - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - (self.0.as_usize(), self.1.as_usize()) - } -} - -impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> { - type T = stable_mir::mir::Operand; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use mir::Operand::*; - match self { - Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables)), - Move(place) => stable_mir::mir::Operand::Move(place.stable(tables)), - Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables)), - } - } -} - -impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> { - type T = stable_mir::mir::Constant; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - stable_mir::mir::Constant { - span: self.span.stable(tables), - user_ty: self.user_ty.map(|u| u.as_usize()).or(None), - literal: self.const_.stable(tables), - } - } -} - -impl<'tcx> Stable<'tcx> for mir::Place<'tcx> { - type T = stable_mir::mir::Place; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - stable_mir::mir::Place { - local: self.local.as_usize(), - projection: self.projection.iter().map(|e| e.stable(tables)).collect(), - } - } -} - -impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { - type T = stable_mir::mir::ProjectionElem; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use mir::ProjectionElem::*; - match self { - Deref => stable_mir::mir::ProjectionElem::Deref, - Field(idx, ty) => { - stable_mir::mir::ProjectionElem::Field(idx.stable(tables), ty.stable(tables)) - } - Index(local) => stable_mir::mir::ProjectionElem::Index(local.stable(tables)), - ConstantIndex { offset, min_length, from_end } => { - stable_mir::mir::ProjectionElem::ConstantIndex { - offset: *offset, - min_length: *min_length, - from_end: *from_end, - } - } - Subslice { from, to, from_end } => stable_mir::mir::ProjectionElem::Subslice { - from: *from, - to: *to, - from_end: *from_end, - }, - // MIR includes an `Option` argument for `Downcast` that is the name of the - // variant, used for printing MIR. However this information should also be accessible - // via a lookup using the `VariantIdx`. The `Option` argument is therefore - // dropped when converting to Stable MIR. A brief justification for this decision can be - // found at https://github.com/rust-lang/rust/pull/117517#issuecomment-1811683486 - Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)), - OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)), - Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)), - } - } -} - -impl<'tcx> Stable<'tcx> for mir::UserTypeProjection { - type T = stable_mir::mir::UserTypeProjection; - - fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T { - UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) } - } -} - -impl<'tcx> Stable<'tcx> for mir::Local { - type T = stable_mir::mir::Local; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - self.as_usize() - } -} - -impl<'tcx> Stable<'tcx> for rustc_target::abi::VariantIdx { - type T = VariantIdx; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - self.as_usize() - } -} - -impl<'tcx> Stable<'tcx> for Variance { - type T = stable_mir::mir::Variance; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - match self { - Variance::Bivariant => stable_mir::mir::Variance::Bivariant, - Variance::Contravariant => stable_mir::mir::Variance::Contravariant, - Variance::Covariant => stable_mir::mir::Variance::Covariant, - Variance::Invariant => stable_mir::mir::Variance::Invariant, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::RetagKind { - type T = stable_mir::mir::RetagKind; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use rustc_middle::mir::RetagKind; - match self { - RetagKind::FnEntry => stable_mir::mir::RetagKind::FnEntry, - RetagKind::TwoPhase => stable_mir::mir::RetagKind::TwoPhase, - RetagKind::Raw => stable_mir::mir::RetagKind::Raw, - RetagKind::Default => stable_mir::mir::RetagKind::Default, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex { - type T = usize; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - self.as_usize() - } -} - -impl<'tcx> Stable<'tcx> for mir::UnwindAction { - type T = stable_mir::mir::UnwindAction; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use rustc_middle::mir::UnwindAction; - match self { - UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, - UnwindAction::Unreachable => stable_mir::mir::UnwindAction::Unreachable, - UnwindAction::Terminate(_) => stable_mir::mir::UnwindAction::Terminate, - UnwindAction::Cleanup(bb) => stable_mir::mir::UnwindAction::Cleanup(bb.as_usize()), - } - } -} - -impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> { - type T = stable_mir::mir::NonDivergingIntrinsic; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use rustc_middle::mir::NonDivergingIntrinsic; - match self { - NonDivergingIntrinsic::Assume(op) => { - stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables)) - } - NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => { - stable_mir::mir::NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { - src: copy_non_overlapping.src.stable(tables), - dst: copy_non_overlapping.dst.stable(tables), - count: copy_non_overlapping.count.stable(tables), - }) - } - } - } -} - -impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { - type T = stable_mir::mir::AssertMessage; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use rustc_middle::mir::AssertKind; - match self { - AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck { - len: len.stable(tables), - index: index.stable(tables), - }, - AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow( - bin_op.stable(tables), - op1.stable(tables), - op2.stable(tables), - ), - AssertKind::OverflowNeg(op) => { - stable_mir::mir::AssertMessage::OverflowNeg(op.stable(tables)) - } - AssertKind::DivisionByZero(op) => { - stable_mir::mir::AssertMessage::DivisionByZero(op.stable(tables)) - } - AssertKind::RemainderByZero(op) => { - stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables)) - } - AssertKind::ResumedAfterReturn(coroutine) => { - stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables)) - } - AssertKind::ResumedAfterPanic(coroutine) => { - stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables)) - } - AssertKind::MisalignedPointerDereference { required, found } => { - stable_mir::mir::AssertMessage::MisalignedPointerDereference { - required: required.stable(tables), - found: found.stable(tables), - } - } - } - } -} - -impl<'tcx> Stable<'tcx> for mir::BinOp { - type T = stable_mir::mir::BinOp; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use mir::BinOp; - match self { - BinOp::Add => stable_mir::mir::BinOp::Add, - BinOp::AddUnchecked => stable_mir::mir::BinOp::AddUnchecked, - BinOp::Sub => stable_mir::mir::BinOp::Sub, - BinOp::SubUnchecked => stable_mir::mir::BinOp::SubUnchecked, - BinOp::Mul => stable_mir::mir::BinOp::Mul, - BinOp::MulUnchecked => stable_mir::mir::BinOp::MulUnchecked, - BinOp::Div => stable_mir::mir::BinOp::Div, - BinOp::Rem => stable_mir::mir::BinOp::Rem, - BinOp::BitXor => stable_mir::mir::BinOp::BitXor, - BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd, - BinOp::BitOr => stable_mir::mir::BinOp::BitOr, - BinOp::Shl => stable_mir::mir::BinOp::Shl, - BinOp::ShlUnchecked => stable_mir::mir::BinOp::ShlUnchecked, - BinOp::Shr => stable_mir::mir::BinOp::Shr, - BinOp::ShrUnchecked => stable_mir::mir::BinOp::ShrUnchecked, - BinOp::Eq => stable_mir::mir::BinOp::Eq, - BinOp::Lt => stable_mir::mir::BinOp::Lt, - BinOp::Le => stable_mir::mir::BinOp::Le, - BinOp::Ne => stable_mir::mir::BinOp::Ne, - BinOp::Ge => stable_mir::mir::BinOp::Ge, - BinOp::Gt => stable_mir::mir::BinOp::Gt, - BinOp::Offset => stable_mir::mir::BinOp::Offset, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::UnOp { - type T = stable_mir::mir::UnOp; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use mir::UnOp; - match self { - UnOp::Not => stable_mir::mir::UnOp::Not, - UnOp::Neg => stable_mir::mir::UnOp::Neg, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { - type T = stable_mir::mir::AggregateKind; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - match self { - mir::AggregateKind::Array(ty) => { - stable_mir::mir::AggregateKind::Array(ty.stable(tables)) - } - mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple, - mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => { - stable_mir::mir::AggregateKind::Adt( - tables.adt_def(*def_id), - var_idx.index(), - generic_arg.stable(tables), - user_ty_index.map(|idx| idx.index()), - field_idx.map(|idx| idx.index()), - ) - } - mir::AggregateKind::Closure(def_id, generic_arg) => { - stable_mir::mir::AggregateKind::Closure( - tables.closure_def(*def_id), - generic_arg.stable(tables), - ) - } - mir::AggregateKind::Coroutine(def_id, generic_arg, movability) => { - stable_mir::mir::AggregateKind::Coroutine( - tables.coroutine_def(*def_id), - generic_arg.stable(tables), - movability.stable(tables), - ) - } - } - } -} - -impl<'tcx> Stable<'tcx> for ty::AdtKind { - type T = AdtKind; - - fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T { - match self { - ty::AdtKind::Struct => AdtKind::Struct, - ty::AdtKind::Union => AdtKind::Union, - ty::AdtKind::Enum => AdtKind::Enum, - } - } -} - -impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource { - type T = stable_mir::mir::CoroutineSource; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use rustc_hir::CoroutineSource; - match self { - CoroutineSource::Block => stable_mir::mir::CoroutineSource::Block, - CoroutineSource::Closure => stable_mir::mir::CoroutineSource::Closure, - CoroutineSource::Fn => stable_mir::mir::CoroutineSource::Fn, - } - } -} - -impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind { - type T = stable_mir::mir::CoroutineKind; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use rustc_hir::CoroutineKind; - match self { - CoroutineKind::Async(source) => { - stable_mir::mir::CoroutineKind::Async(source.stable(tables)) - } - CoroutineKind::Gen(source) => { - stable_mir::mir::CoroutineKind::Gen(source.stable(tables)) - } - CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine, - } - } -} - -impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> { - type T = stable_mir::mir::InlineAsmOperand; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use rustc_middle::mir::InlineAsmOperand; - - let (in_value, out_place) = match self { - InlineAsmOperand::In { value, .. } => (Some(value.stable(tables)), None), - InlineAsmOperand::Out { place, .. } => (None, place.map(|place| place.stable(tables))), - InlineAsmOperand::InOut { in_value, out_place, .. } => { - (Some(in_value.stable(tables)), out_place.map(|place| place.stable(tables))) - } - InlineAsmOperand::Const { .. } - | InlineAsmOperand::SymFn { .. } - | InlineAsmOperand::SymStatic { .. } => (None, None), - }; - - stable_mir::mir::InlineAsmOperand { in_value, out_place, raw_rpr: format!("{self:?}") } - } -} - -impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> { - type T = stable_mir::mir::Terminator; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::mir::Terminator; - Terminator { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) } - } -} - -impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { - type T = stable_mir::mir::TerminatorKind; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::mir::TerminatorKind; - match self { - mir::TerminatorKind::Goto { target } => { - TerminatorKind::Goto { target: target.as_usize() } - } - mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt { - discr: discr.stable(tables), - targets: targets - .iter() - .map(|(value, target)| stable_mir::mir::SwitchTarget { - value, - target: target.as_usize(), - }) - .collect(), - otherwise: targets.otherwise().as_usize(), - }, - mir::TerminatorKind::UnwindResume => TerminatorKind::Resume, - mir::TerminatorKind::UnwindTerminate(_) => TerminatorKind::Abort, - mir::TerminatorKind::Return => TerminatorKind::Return, - mir::TerminatorKind::Unreachable => TerminatorKind::Unreachable, - mir::TerminatorKind::Drop { place, target, unwind, replace: _ } => { - TerminatorKind::Drop { - place: place.stable(tables), - target: target.as_usize(), - unwind: unwind.stable(tables), - } - } - mir::TerminatorKind::Call { - func, - args, - destination, - target, - unwind, - call_source: _, - fn_span: _, - } => TerminatorKind::Call { - func: func.stable(tables), - args: args.iter().map(|arg| arg.stable(tables)).collect(), - destination: destination.stable(tables), - target: target.map(|t| t.as_usize()), - unwind: unwind.stable(tables), - }, - mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => { - TerminatorKind::Assert { - cond: cond.stable(tables), - expected: *expected, - msg: msg.stable(tables), - target: target.as_usize(), - unwind: unwind.stable(tables), - } - } - mir::TerminatorKind::InlineAsm { - template, - operands, - options, - line_spans, - destination, - unwind, - } => TerminatorKind::InlineAsm { - template: format!("{template:?}"), - operands: operands.iter().map(|operand| operand.stable(tables)).collect(), - options: format!("{options:?}"), - line_spans: format!("{line_spans:?}"), - destination: destination.map(|d| d.as_usize()), - unwind: unwind.stable(tables), - }, - mir::TerminatorKind::Yield { .. } - | mir::TerminatorKind::CoroutineDrop - | mir::TerminatorKind::FalseEdge { .. } - | mir::TerminatorKind::FalseUnwind { .. } => unreachable!(), - } - } -} - -impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> { - type T = stable_mir::ty::GenericArgs; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - GenericArgs(self.iter().map(|arg| arg.unpack().stable(tables)).collect()) - } -} - -impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> { - type T = stable_mir::ty::GenericArgKind; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::GenericArgKind; - match self { - ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)), - ty::GenericArgKind::Type(ty) => GenericArgKind::Type(ty.stable(tables)), - ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)), - } - } -} - -impl<'tcx, S, V> Stable<'tcx> for ty::Binder<'tcx, S> -where - S: Stable<'tcx, T = V>, -{ - type T = stable_mir::ty::Binder; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::Binder; - - Binder { - value: self.as_ref().skip_binder().stable(tables), - bound_vars: self - .bound_vars() - .iter() - .map(|bound_var| bound_var.stable(tables)) - .collect(), - } - } -} - -impl<'tcx, S, V> Stable<'tcx> for ty::EarlyBinder -where - S: Stable<'tcx, T = V>, -{ - type T = stable_mir::ty::EarlyBinder; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::EarlyBinder; - - EarlyBinder { value: self.as_ref().skip_binder().stable(tables) } - } -} - -impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { - type T = stable_mir::ty::FnSig; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use rustc_target::spec::abi; - use stable_mir::ty::{Abi, FnSig}; - - FnSig { - inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(), - c_variadic: self.c_variadic, - unsafety: self.unsafety.stable(tables), - abi: match self.abi { - abi::Abi::Rust => Abi::Rust, - abi::Abi::C { unwind } => Abi::C { unwind }, - abi::Abi::Cdecl { unwind } => Abi::Cdecl { unwind }, - abi::Abi::Stdcall { unwind } => Abi::Stdcall { unwind }, - abi::Abi::Fastcall { unwind } => Abi::Fastcall { unwind }, - abi::Abi::Vectorcall { unwind } => Abi::Vectorcall { unwind }, - abi::Abi::Thiscall { unwind } => Abi::Thiscall { unwind }, - abi::Abi::Aapcs { unwind } => Abi::Aapcs { unwind }, - abi::Abi::Win64 { unwind } => Abi::Win64 { unwind }, - abi::Abi::SysV64 { unwind } => Abi::SysV64 { unwind }, - abi::Abi::PtxKernel => Abi::PtxKernel, - abi::Abi::Msp430Interrupt => Abi::Msp430Interrupt, - abi::Abi::X86Interrupt => Abi::X86Interrupt, - abi::Abi::AmdGpuKernel => Abi::AmdGpuKernel, - abi::Abi::EfiApi => Abi::EfiApi, - abi::Abi::AvrInterrupt => Abi::AvrInterrupt, - abi::Abi::AvrNonBlockingInterrupt => Abi::AvrNonBlockingInterrupt, - abi::Abi::CCmseNonSecureCall => Abi::CCmseNonSecureCall, - abi::Abi::Wasm => Abi::Wasm, - abi::Abi::System { unwind } => Abi::System { unwind }, - abi::Abi::RustIntrinsic => Abi::RustIntrinsic, - abi::Abi::RustCall => Abi::RustCall, - abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic, - abi::Abi::Unadjusted => Abi::Unadjusted, - abi::Abi::RustCold => Abi::RustCold, - abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM, - abi::Abi::RiscvInterruptS => Abi::RiscvInterruptS, - }, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::BoundTyKind { - type T = stable_mir::ty::BoundTyKind; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::BoundTyKind; - - match self { - ty::BoundTyKind::Anon => BoundTyKind::Anon, - ty::BoundTyKind::Param(def_id, symbol) => { - BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string()) - } - } - } -} - -impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { - type T = stable_mir::ty::BoundRegionKind; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::BoundRegionKind; - - match self { - ty::BoundRegionKind::BrAnon => BoundRegionKind::BrAnon, - ty::BoundRegionKind::BrNamed(def_id, symbol) => { - BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string()) - } - ty::BoundRegionKind::BrEnv => BoundRegionKind::BrEnv, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::BoundVariableKind { - type T = stable_mir::ty::BoundVariableKind; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::BoundVariableKind; - - match self { - ty::BoundVariableKind::Ty(bound_ty_kind) => { - BoundVariableKind::Ty(bound_ty_kind.stable(tables)) - } - ty::BoundVariableKind::Region(bound_region_kind) => { - BoundVariableKind::Region(bound_region_kind.stable(tables)) - } - ty::BoundVariableKind::Const => BoundVariableKind::Const, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::IntTy { - type T = IntTy; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - match self { - ty::IntTy::Isize => IntTy::Isize, - ty::IntTy::I8 => IntTy::I8, - ty::IntTy::I16 => IntTy::I16, - ty::IntTy::I32 => IntTy::I32, - ty::IntTy::I64 => IntTy::I64, - ty::IntTy::I128 => IntTy::I128, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::UintTy { - type T = UintTy; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - match self { - ty::UintTy::Usize => UintTy::Usize, - ty::UintTy::U8 => UintTy::U8, - ty::UintTy::U16 => UintTy::U16, - ty::UintTy::U32 => UintTy::U32, - ty::UintTy::U64 => UintTy::U64, - ty::UintTy::U128 => UintTy::U128, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::FloatTy { - type T = FloatTy; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - match self { - ty::FloatTy::F32 => FloatTy::F32, - ty::FloatTy::F64 => FloatTy::F64, - } - } -} - -impl<'tcx> Stable<'tcx> for hir::Movability { - type T = Movability; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - match self { - hir::Movability::Static => Movability::Static, - hir::Movability::Movable => Movability::Movable, - } - } -} - -impl<'tcx> Stable<'tcx> for Ty<'tcx> { - type T = stable_mir::ty::Ty; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - tables.intern_ty(*self) - } -} - -impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { - type T = stable_mir::ty::TyKind; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - match self { - ty::Bool => TyKind::RigidTy(RigidTy::Bool), - ty::Char => TyKind::RigidTy(RigidTy::Char), - ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables))), - ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))), - ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))), - ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt( - tables.adt_def(adt_def.did()), - generic_args.stable(tables), - )), - ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))), - ty::Str => TyKind::RigidTy(RigidTy::Str), - ty::Array(ty, constant) => { - TyKind::RigidTy(RigidTy::Array(ty.stable(tables), constant.stable(tables))) - } - ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(ty.stable(tables))), - ty::RawPtr(ty::TypeAndMut { ty, mutbl }) => { - TyKind::RigidTy(RigidTy::RawPtr(ty.stable(tables), mutbl.stable(tables))) - } - ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref( - region.stable(tables), - ty.stable(tables), - mutbl.stable(tables), - )), - ty::FnDef(def_id, generic_args) => { - TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables))) - } - ty::FnPtr(poly_fn_sig) => TyKind::RigidTy(RigidTy::FnPtr(poly_fn_sig.stable(tables))), - ty::Dynamic(existential_predicates, region, dyn_kind) => { - TyKind::RigidTy(RigidTy::Dynamic( - existential_predicates - .iter() - .map(|existential_predicate| existential_predicate.stable(tables)) - .collect(), - region.stable(tables), - dyn_kind.stable(tables), - )) - } - ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure( - tables.closure_def(*def_id), - generic_args.stable(tables), - )), - ty::Coroutine(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Coroutine( - tables.coroutine_def(*def_id), - generic_args.stable(tables), - movability.stable(tables), - )), - ty::Never => TyKind::RigidTy(RigidTy::Never), - ty::Tuple(fields) => { - TyKind::RigidTy(RigidTy::Tuple(fields.iter().map(|ty| ty.stable(tables)).collect())) - } - ty::Alias(alias_kind, alias_ty) => { - TyKind::Alias(alias_kind.stable(tables), alias_ty.stable(tables)) - } - ty::Param(param_ty) => TyKind::Param(param_ty.stable(tables)), - ty::Bound(debruijn_idx, bound_ty) => { - TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables)) - } - ty::CoroutineWitness(def_id, args) => TyKind::RigidTy(RigidTy::CoroutineWitness( - tables.coroutine_witness_def(*def_id), - args.stable(tables), - )), - ty::Placeholder(..) | ty::Infer(_) | ty::Error(_) => { - unreachable!(); - } - } - } -} - -impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { - type T = stable_mir::ty::Const; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let kind = match self.kind() { - ty::Value(val) => { - let const_val = tables.tcx.valtree_to_const_val((self.ty(), val)); - if matches!(const_val, mir::ConstValue::ZeroSized) { - ConstantKind::ZeroSized - } else { - stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( - self.ty(), - const_val, - tables, - )) - } - } - ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)), - ty::ErrorCt(_) => unreachable!(), - ty::InferCt(_) => unreachable!(), - ty::BoundCt(_, _) => unimplemented!(), - ty::PlaceholderCt(_) => unimplemented!(), - ty::Unevaluated(uv) => { - stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { - def: tables.const_def(uv.def), - args: uv.args.stable(tables), - promoted: None, - }) - } - ty::ExprCt(_) => unimplemented!(), - }; - let ty = self.ty().stable(tables); - let id = tables.intern_const(mir::Const::Ty(*self)); - Const::new(kind, ty, id) - } -} - -impl<'tcx> Stable<'tcx> for ty::ParamConst { - type T = stable_mir::ty::ParamConst; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::ParamConst; - ParamConst { index: self.index, name: self.name.to_string() } - } -} - -impl<'tcx> Stable<'tcx> for ty::ParamTy { - type T = stable_mir::ty::ParamTy; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::ParamTy; - ParamTy { index: self.index, name: self.name.to_string() } - } -} - -impl<'tcx> Stable<'tcx> for ty::BoundTy { - type T = stable_mir::ty::BoundTy; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::BoundTy; - BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables) } - } -} - -impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> { - type T = Allocation; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - self.inner().stable(tables) - } -} - -impl<'tcx> Stable<'tcx> for mir::interpret::Allocation { - type T = stable_mir::ty::Allocation; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - alloc::allocation_filter( - self, - alloc_range(rustc_target::abi::Size::ZERO, self.size()), - tables, - ) - } -} - -impl<'tcx> Stable<'tcx> for mir::interpret::AllocId { - type T = stable_mir::mir::alloc::AllocId; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - tables.create_alloc_id(*self) - } -} - -impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> { - type T = GlobalAlloc; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - match self { - mir::interpret::GlobalAlloc::Function(instance) => { - GlobalAlloc::Function(instance.stable(tables)) - } - mir::interpret::GlobalAlloc::VTable(ty, trait_ref) => { - GlobalAlloc::VTable(ty.stable(tables), trait_ref.stable(tables)) - } - mir::interpret::GlobalAlloc::Static(def) => { - GlobalAlloc::Static(tables.static_def(*def)) - } - mir::interpret::GlobalAlloc::Memory(alloc) => GlobalAlloc::Memory(alloc.stable(tables)), - } - } -} - -impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind { - type T = stable_mir::ty::TraitSpecializationKind; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::TraitSpecializationKind; - - match self { - ty::trait_def::TraitSpecializationKind::None => TraitSpecializationKind::None, - ty::trait_def::TraitSpecializationKind::Marker => TraitSpecializationKind::Marker, - ty::trait_def::TraitSpecializationKind::AlwaysApplicable => { - TraitSpecializationKind::AlwaysApplicable - } - } - } -} - -impl<'tcx> Stable<'tcx> for ty::TraitDef { - type T = stable_mir::ty::TraitDecl; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::TraitDecl; - - TraitDecl { - def_id: tables.trait_def(self.def_id), - unsafety: self.unsafety.stable(tables), - paren_sugar: self.paren_sugar, - has_auto_impl: self.has_auto_impl, - is_marker: self.is_marker, - is_coinductive: self.is_coinductive, - skip_array_during_method_dispatch: self.skip_array_during_method_dispatch, - specialization_kind: self.specialization_kind.stable(tables), - must_implement_one_of: self - .must_implement_one_of - .as_ref() - .map(|idents| idents.iter().map(|ident| opaque(ident)).collect()), - implement_via_object: self.implement_via_object, - deny_explicit_impl: self.deny_explicit_impl, - } - } -} - -impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { - type T = stable_mir::ty::Const; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - match *self { - mir::Const::Ty(c) => c.stable(tables), - mir::Const::Unevaluated(unev_const, ty) => { - let kind = - stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { - def: tables.const_def(unev_const.def), - args: unev_const.args.stable(tables), - promoted: unev_const.promoted.map(|u| u.as_u32()), - }); - let ty = ty.stable(tables); - let id = tables.intern_const(*self); - Const::new(kind, ty, id) - } - mir::Const::Val(val, ty) if matches!(val, mir::ConstValue::ZeroSized) => { - let ty = ty.stable(tables); - let id = tables.intern_const(*self); - Const::new(ConstantKind::ZeroSized, ty, id) - } - mir::Const::Val(val, ty) => { - let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables)); - let ty = ty.stable(tables); - let id = tables.intern_const(*self); - Const::new(kind, ty, id) - } - } - } -} - -impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> { - type T = stable_mir::ty::TraitRef; - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::TraitRef; - - TraitRef::try_new(tables.trait_def(self.def_id), self.args.stable(tables)).unwrap() - } -} - -impl<'tcx> Stable<'tcx> for ty::Generics { - type T = stable_mir::ty::Generics; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::Generics; - - let params: Vec<_> = self.params.iter().map(|param| param.stable(tables)).collect(); - let param_def_id_to_index = - params.iter().map(|param| (param.def_id, param.index)).collect(); - - Generics { - parent: self.parent.map(|did| tables.generic_def(did)), - parent_count: self.parent_count, - params, - param_def_id_to_index, - has_self: self.has_self, - has_late_bound_regions: self - .has_late_bound_regions - .as_ref() - .map(|late_bound_regions| late_bound_regions.stable(tables)), - host_effect_index: self.host_effect_index, - } - } -} - -impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { - type T = stable_mir::ty::GenericParamDefKind; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::GenericParamDefKind; - match self { - ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime, - ty::GenericParamDefKind::Type { has_default, synthetic } => { - GenericParamDefKind::Type { has_default: *has_default, synthetic: *synthetic } - } - ty::GenericParamDefKind::Const { has_default, is_host_effect: _ } => { - GenericParamDefKind::Const { has_default: *has_default } - } - } - } -} - -impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef { - type T = stable_mir::ty::GenericParamDef; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - GenericParamDef { - name: self.name.to_string(), - def_id: tables.generic_def(self.def_id), - index: self.index, - pure_wrt_drop: self.pure_wrt_drop, - kind: self.kind.stable(tables), - } - } -} - -impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> { - type T = stable_mir::ty::PredicateKind; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use ty::PredicateKind; - match self { - PredicateKind::Clause(clause_kind) => { - stable_mir::ty::PredicateKind::Clause(clause_kind.stable(tables)) - } - PredicateKind::ObjectSafe(did) => { - stable_mir::ty::PredicateKind::ObjectSafe(tables.trait_def(*did)) - } - PredicateKind::Subtype(subtype_predicate) => { - stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables)) - } - PredicateKind::Coerce(coerce_predicate) => { - stable_mir::ty::PredicateKind::Coerce(coerce_predicate.stable(tables)) - } - PredicateKind::ConstEquate(a, b) => { - stable_mir::ty::PredicateKind::ConstEquate(a.stable(tables), b.stable(tables)) - } - PredicateKind::Ambiguous => stable_mir::ty::PredicateKind::Ambiguous, - PredicateKind::AliasRelate(a, b, alias_relation_direction) => { - stable_mir::ty::PredicateKind::AliasRelate( - a.unpack().stable(tables), - b.unpack().stable(tables), - alias_relation_direction.stable(tables), - ) - } - } - } -} - -impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { - type T = stable_mir::ty::ClauseKind; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use ty::ClauseKind; - match *self { - ClauseKind::Trait(trait_object) => { - stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables)) - } - ClauseKind::RegionOutlives(region_outlives) => { - stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables)) - } - ClauseKind::TypeOutlives(type_outlives) => { - let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives; - stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate( - a.stable(tables), - b.stable(tables), - )) - } - ClauseKind::Projection(projection_predicate) => { - stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables)) - } - ClauseKind::ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType( - const_.stable(tables), - ty.stable(tables), - ), - ClauseKind::WellFormed(generic_arg) => { - stable_mir::ty::ClauseKind::WellFormed(generic_arg.unpack().stable(tables)) - } - ClauseKind::ConstEvaluatable(const_) => { - stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables)) - } - } - } -} - -impl<'tcx> Stable<'tcx> for ty::ClosureKind { - type T = stable_mir::ty::ClosureKind; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use ty::ClosureKind::*; - match self { - Fn => stable_mir::ty::ClosureKind::Fn, - FnMut => stable_mir::ty::ClosureKind::FnMut, - FnOnce => stable_mir::ty::ClosureKind::FnOnce, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> { - type T = stable_mir::ty::SubtypePredicate; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let ty::SubtypePredicate { a, b, a_is_expected: _ } = self; - stable_mir::ty::SubtypePredicate { a: a.stable(tables), b: b.stable(tables) } - } -} - -impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> { - type T = stable_mir::ty::CoercePredicate; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let ty::CoercePredicate { a, b } = self; - stable_mir::ty::CoercePredicate { a: a.stable(tables), b: b.stable(tables) } - } -} - -impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection { - type T = stable_mir::ty::AliasRelationDirection; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use ty::AliasRelationDirection::*; - match self { - Equate => stable_mir::ty::AliasRelationDirection::Equate, - Subtype => stable_mir::ty::AliasRelationDirection::Subtype, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> { - type T = stable_mir::ty::TraitPredicate; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let ty::TraitPredicate { trait_ref, polarity } = self; - stable_mir::ty::TraitPredicate { - trait_ref: trait_ref.stable(tables), - polarity: polarity.stable(tables), - } - } -} - -impl<'tcx, A, B, U, V> Stable<'tcx> for ty::OutlivesPredicate -where - A: Stable<'tcx, T = U>, - B: Stable<'tcx, T = V>, -{ - type T = stable_mir::ty::OutlivesPredicate; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let ty::OutlivesPredicate(a, b) = self; - stable_mir::ty::OutlivesPredicate(a.stable(tables), b.stable(tables)) - } -} - -impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { - type T = stable_mir::ty::ProjectionPredicate; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let ty::ProjectionPredicate { projection_ty, term } = self; - stable_mir::ty::ProjectionPredicate { - projection_ty: projection_ty.stable(tables), - term: term.unpack().stable(tables), - } - } -} - -impl<'tcx> Stable<'tcx> for ty::ImplPolarity { - type T = stable_mir::ty::ImplPolarity; - - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - use ty::ImplPolarity::*; - match self { - Positive => stable_mir::ty::ImplPolarity::Positive, - Negative => stable_mir::ty::ImplPolarity::Negative, - Reservation => stable_mir::ty::ImplPolarity::Reservation, - } - } -} - -impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { - type T = stable_mir::ty::Region; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - Region { kind: self.kind().stable(tables) } - } -} - -impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { - type T = stable_mir::ty::RegionKind; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::ty::RegionKind; - match self { - ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion { - def_id: tables.region_def(early_reg.def_id), - index: early_reg.index, - name: early_reg.name.to_string(), - }), - ty::ReBound(db_index, bound_reg) => RegionKind::ReBound( - db_index.as_u32(), - BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) }, - ), - ty::ReStatic => RegionKind::ReStatic, - ty::RePlaceholder(place_holder) => { - RegionKind::RePlaceholder(stable_mir::ty::Placeholder { - universe: place_holder.universe.as_u32(), - bound: BoundRegion { - var: place_holder.bound.var.as_u32(), - kind: place_holder.bound.kind.stable(tables), - }, - }) - } - ty::ReErased => RegionKind::ReErased, - _ => unreachable!("{self:?}"), - } - } -} - -impl<'tcx> Stable<'tcx> for rustc_span::Span { - type T = stable_mir::ty::Span; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - tables.create_span(*self) - } -} - -impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { - type T = stable_mir::mir::mono::Instance; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - let def = tables.instance_def(*self); - let kind = match self.def { - ty::InstanceDef::Item(..) => stable_mir::mir::mono::InstanceKind::Item, - ty::InstanceDef::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic, - ty::InstanceDef::Virtual(..) => stable_mir::mir::mono::InstanceKind::Virtual, - ty::InstanceDef::VTableShim(..) - | ty::InstanceDef::ReifyShim(..) - | ty::InstanceDef::FnPtrAddrShim(..) - | ty::InstanceDef::ClosureOnceShim { .. } - | ty::InstanceDef::ThreadLocalShim(..) - | ty::InstanceDef::DropGlue(..) - | ty::InstanceDef::CloneShim(..) - | ty::InstanceDef::FnPtrShim(..) => stable_mir::mir::mono::InstanceKind::Shim, - }; - stable_mir::mir::mono::Instance { def, kind } - } -} - -impl<'tcx> Stable<'tcx> for MonoItem<'tcx> { - type T = stable_mir::mir::mono::MonoItem; - - fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { - use stable_mir::mir::mono::MonoItem as StableMonoItem; - match self { - MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables)), - MonoItem::Static(def_id) => StableMonoItem::Static(tables.static_def(*def_id)), - MonoItem::GlobalAsm(item_id) => StableMonoItem::GlobalAsm(opaque(item_id)), - } - } -} - -impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled { - type T = Error; - - fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T { - Error::new(format!("{self:?}")) - } -} - impl<'tcx, T> Stable<'tcx> for &T where T: Stable<'tcx>, From d7c723684545c79dc83aec2d44afeb6e7f2b3aad Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Fri, 24 Nov 2023 13:41:45 -0800 Subject: [PATCH 27/30] Move the compiler interface defs to its own module Separate items that are exposed in the `stable_mir` crate to be used by the compiler from items that we expect to be used by tool developers. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 2 +- compiler/rustc_smir/src/rustc_smir/context.rs | 5 +- compiler/stable_mir/src/compiler_interface.rs | 163 +++++++++++++++++ compiler/stable_mir/src/lib.rs | 169 +----------------- 4 files changed, 176 insertions(+), 163 deletions(-) create mode 100644 compiler/stable_mir/src/compiler_interface.rs diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index b13bf2e98c9..c3db9b358e8 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -181,7 +181,7 @@ where instances: IndexMap::default(), constants: IndexMap::default(), })); - stable_mir::run(&tables, || init(&tables, f)) + stable_mir::compiler_interface::run(&tables, || init(&tables, f)) } #[macro_export] diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index d399b9b3e8f..3449176f729 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -1,4 +1,4 @@ -//! Implementation of `[stable_mir::compiler::Context]` trait. +//! Implementation of `[stable_mir::compiler_interface::Context]` trait. //! //! This trait is currently the main interface between the Rust compiler, //! and the `stable_mir` crate. @@ -6,6 +6,7 @@ use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; use rustc_middle::ty::{GenericPredicates, Instance, ParamEnv, ScalarInt, ValTree}; use rustc_span::def_id::LOCAL_CRATE; +use stable_mir::compiler_interface::Context; use stable_mir::mir::alloc::GlobalAlloc; use stable_mir::mir::mono::{InstanceDef, StaticDef}; use stable_mir::mir::Body; @@ -13,7 +14,7 @@ use stable_mir::ty::{ AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FnDef, GenericArgs, LineInfo, RigidTy, Span, TyKind, }; -use stable_mir::{self, Context, Crate, CrateItem, Error, Filename, ItemKind, Symbol}; +use stable_mir::{self, Crate, CrateItem, Error, Filename, ItemKind, Symbol}; use std::cell::RefCell; use crate::rustc_internal::{internal, RustcInternal}; diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs new file mode 100644 index 00000000000..9f4512b167e --- /dev/null +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -0,0 +1,163 @@ +//! Define the interface with the Rust compiler. +//! +//! StableMIR users should not use any of the items in this module directly. +//! These APIs have no stability guarantee. + +use crate::mir::alloc::{AllocId, GlobalAlloc}; +use crate::mir::mono::{Instance, InstanceDef, StaticDef}; +use crate::mir::Body; +use crate::ty::{ + AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FnDef, GenericArgs, + GenericPredicates, Generics, ImplDef, ImplTrait, LineInfo, RigidTy, Span, TraitDecl, TraitDef, + Ty, TyKind, +}; +use crate::{ + mir, Crate, CrateItem, CrateItems, DefId, Error, Filename, ImplTraitDecls, ItemKind, Symbol, + TraitDecls, +}; +use std::cell::Cell; + +/// This trait defines the interface between stable_mir and the Rust compiler. +/// Do not use this directly. +pub trait Context { + fn entry_fn(&self) -> Option; + /// Retrieve all items of the local crate that have a MIR associated with them. + fn all_local_items(&self) -> CrateItems; + fn mir_body(&self, item: DefId) -> mir::Body; + fn all_trait_decls(&self) -> TraitDecls; + fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl; + fn all_trait_impls(&self) -> ImplTraitDecls; + fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait; + fn generics_of(&self, def_id: DefId) -> Generics; + fn predicates_of(&self, def_id: DefId) -> GenericPredicates; + fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates; + /// Get information about the local crate. + fn local_crate(&self) -> Crate; + /// Retrieve a list of all external crates. + fn external_crates(&self) -> Vec; + + /// Find a crate with the given name. + fn find_crates(&self, name: &str) -> Vec; + + /// Returns the name of given `DefId` + fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol; + + /// Returns printable, human readable form of `Span` + fn span_to_string(&self, span: Span) -> String; + + /// Return filename from given `Span`, for diagnostic purposes + fn get_filename(&self, span: &Span) -> Filename; + + /// Return lines corresponding to this `Span` + fn get_lines(&self, span: &Span) -> LineInfo; + + /// Returns the `kind` of given `DefId` + fn item_kind(&self, item: CrateItem) -> ItemKind; + + /// Returns whether this is a foreign item. + fn is_foreign_item(&self, item: CrateItem) -> bool; + + /// Returns the kind of a given algebraic data type + fn adt_kind(&self, def: AdtDef) -> AdtKind; + + /// Returns if the ADT is a box. + fn adt_is_box(&self, def: AdtDef) -> bool; + + /// Evaluate constant as a target usize. + fn eval_target_usize(&self, cnst: &Const) -> Result; + + /// Create a target usize constant for the given value. + fn usize_to_const(&self, val: u64) -> Result; + + /// Create a new type from the given kind. + fn new_rigid_ty(&self, kind: RigidTy) -> Ty; + + /// Returns the type of given crate item. + fn def_ty(&self, item: DefId) -> Ty; + + /// Returns literal value of a const as a string. + fn const_literal(&self, cnst: &Const) -> String; + + /// `Span` of an item + fn span_of_an_item(&self, def_id: DefId) -> Span; + + /// Obtain the representation of a type. + fn ty_kind(&self, ty: Ty) -> TyKind; + + /// Get the body of an Instance. + /// FIXME: Monomorphize the body. + fn instance_body(&self, instance: InstanceDef) -> Option; + + /// Get the instance type with generic substitutions applied and lifetimes erased. + fn instance_ty(&self, instance: InstanceDef) -> Ty; + + /// Get the instance. + fn instance_def_id(&self, instance: InstanceDef) -> DefId; + + /// Get the instance mangled name. + fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol; + + /// Convert a non-generic crate item into an instance. + /// This function will panic if the item is generic. + fn mono_instance(&self, item: CrateItem) -> Instance; + + /// Item requires monomorphization. + fn requires_monomorphization(&self, def_id: DefId) -> bool; + + /// Resolve an instance from the given function definition and generic arguments. + fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option; + + /// Resolve an instance for drop_in_place for the given type. + fn resolve_drop_in_place(&self, ty: Ty) -> Instance; + + /// Resolve instance for a function pointer. + fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option; + + /// Resolve instance for a closure with the requested type. + fn resolve_closure( + &self, + def: ClosureDef, + args: &GenericArgs, + kind: ClosureKind, + ) -> Option; + + /// Evaluate a static's initializer. + fn eval_static_initializer(&self, def: StaticDef) -> Result; + + /// Retrieve global allocation for the given allocation ID. + fn global_alloc(&self, id: AllocId) -> GlobalAlloc; + + /// Retrieve the id for the virtual table. + fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option; + fn krate(&self, def_id: DefId) -> Crate; + fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol; +} + +// A thread local variable that stores a pointer to the tables mapping between TyCtxt +// datastructures and stable MIR datastructures +scoped_thread_local! (static TLV: Cell<*const ()>); + +pub fn run(context: &dyn Context, f: F) -> Result +where + F: FnOnce() -> T, +{ + if TLV.is_set() { + Err(Error::from("StableMIR already running")) + } else { + let ptr: *const () = &context as *const &_ as _; + TLV.set(&Cell::new(ptr), || Ok(f())) + } +} + +/// Execute the given function with access the compiler [Context]. +/// +/// I.e., This function will load the current context and calls a function with it. +/// Do not nest these, as that will ICE. +pub(crate) fn with(f: impl FnOnce(&dyn Context) -> R) -> R { + assert!(TLV.is_set()); + TLV.with(|tlv| { + let ptr = tlv.get(); + assert!(!ptr.is_null()); + f(unsafe { *(ptr as *const &dyn Context) }) + }) +} diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 1b1faea4953..18c2b942170 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -17,38 +17,30 @@ //! The goal is to eventually be published on //! [crates.io](https://crates.io). -use crate::mir::mono::{InstanceDef, StaticDef}; +use self::ty::{ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty}; +pub(crate) use crate::compiler_interface::with; +pub use crate::crate_def::CrateDef; +pub use crate::crate_def::DefId; +use crate::mir::pretty::function_name; use crate::mir::Body; +use crate::mir::Mutability; +pub use error::*; use std::fmt; use std::fmt::Debug; -use std::{cell::Cell, io}; - -use self::ty::{ - GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, LineInfo, Span, TraitDecl, - TraitDef, Ty, TyKind, -}; +use std::io; #[macro_use] extern crate scoped_tls; #[macro_use] pub mod crate_def; +pub mod compiler_interface; #[macro_use] pub mod error; pub mod mir; pub mod ty; pub mod visitor; -pub use crate::crate_def::CrateDef; -pub use crate::crate_def::DefId; -use crate::mir::alloc::{AllocId, GlobalAlloc}; -use crate::mir::pretty::function_name; -use crate::mir::Mutability; -use crate::ty::{AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, RigidTy}; -pub use error::*; -use mir::mono::Instance; -use ty::{FnDef, GenericArgs}; - /// Use String for now but we should replace it. pub type Symbol = String; @@ -179,149 +171,6 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait { with(|cx| cx.trait_impl(trait_impl)) } -/// This trait defines the interface between stable_mir and the Rust compiler. -/// Do not use this directly. -pub trait Context { - fn entry_fn(&self) -> Option; - /// Retrieve all items of the local crate that have a MIR associated with them. - fn all_local_items(&self) -> CrateItems; - fn mir_body(&self, item: DefId) -> mir::Body; - fn all_trait_decls(&self) -> TraitDecls; - fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl; - fn all_trait_impls(&self) -> ImplTraitDecls; - fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait; - fn generics_of(&self, def_id: DefId) -> Generics; - fn predicates_of(&self, def_id: DefId) -> GenericPredicates; - fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates; - /// Get information about the local crate. - fn local_crate(&self) -> Crate; - /// Retrieve a list of all external crates. - fn external_crates(&self) -> Vec; - - /// Find a crate with the given name. - fn find_crates(&self, name: &str) -> Vec; - - /// Returns the name of given `DefId` - fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol; - - /// Returns printable, human readable form of `Span` - fn span_to_string(&self, span: Span) -> String; - - /// Return filename from given `Span`, for diagnostic purposes - fn get_filename(&self, span: &Span) -> Filename; - - /// Return lines corresponding to this `Span` - fn get_lines(&self, span: &Span) -> LineInfo; - - /// Returns the `kind` of given `DefId` - fn item_kind(&self, item: CrateItem) -> ItemKind; - - /// Returns whether this is a foreign item. - fn is_foreign_item(&self, item: CrateItem) -> bool; - - /// Returns the kind of a given algebraic data type - fn adt_kind(&self, def: AdtDef) -> AdtKind; - - /// Returns if the ADT is a box. - fn adt_is_box(&self, def: AdtDef) -> bool; - - /// Evaluate constant as a target usize. - fn eval_target_usize(&self, cnst: &Const) -> Result; - - /// Create a target usize constant for the given value. - fn usize_to_const(&self, val: u64) -> Result; - - /// Create a new type from the given kind. - fn new_rigid_ty(&self, kind: RigidTy) -> Ty; - - /// Returns the type of given crate item. - fn def_ty(&self, item: DefId) -> Ty; - - /// Returns literal value of a const as a string. - fn const_literal(&self, cnst: &Const) -> String; - - /// `Span` of an item - fn span_of_an_item(&self, def_id: DefId) -> Span; - - /// Obtain the representation of a type. - fn ty_kind(&self, ty: Ty) -> TyKind; - - /// Get the body of an Instance. - /// FIXME: Monomorphize the body. - fn instance_body(&self, instance: InstanceDef) -> Option; - - /// Get the instance type with generic substitutions applied and lifetimes erased. - fn instance_ty(&self, instance: InstanceDef) -> Ty; - - /// Get the instance. - fn instance_def_id(&self, instance: InstanceDef) -> DefId; - - /// Get the instance mangled name. - fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol; - - /// Convert a non-generic crate item into an instance. - /// This function will panic if the item is generic. - fn mono_instance(&self, item: CrateItem) -> Instance; - - /// Item requires monomorphization. - fn requires_monomorphization(&self, def_id: DefId) -> bool; - - /// Resolve an instance from the given function definition and generic arguments. - fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option; - - /// Resolve an instance for drop_in_place for the given type. - fn resolve_drop_in_place(&self, ty: Ty) -> Instance; - - /// Resolve instance for a function pointer. - fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option; - - /// Resolve instance for a closure with the requested type. - fn resolve_closure( - &self, - def: ClosureDef, - args: &GenericArgs, - kind: ClosureKind, - ) -> Option; - - /// Evaluate a static's initializer. - fn eval_static_initializer(&self, def: StaticDef) -> Result; - - /// Retrieve global allocation for the given allocation ID. - fn global_alloc(&self, id: AllocId) -> GlobalAlloc; - - /// Retrieve the id for the virtual table. - fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option; - fn krate(&self, def_id: DefId) -> Crate; - fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol; -} - -// A thread local variable that stores a pointer to the tables mapping between TyCtxt -// datastructures and stable MIR datastructures -scoped_thread_local! (static TLV: Cell<*const ()>); - -pub fn run(context: &dyn Context, f: F) -> Result -where - F: FnOnce() -> T, -{ - if TLV.is_set() { - Err(Error::from("StableMIR already running")) - } else { - let ptr: *const () = &context as *const &_ as _; - TLV.set(&Cell::new(ptr), || Ok(f())) - } -} - -/// Loads the current context and calls a function with it. -/// Do not nest these, as that will ICE. -pub fn with(f: impl FnOnce(&dyn Context) -> R) -> R { - assert!(TLV.is_set()); - TLV.with(|tlv| { - let ptr = tlv.get(); - assert!(!ptr.is_null()); - f(unsafe { *(ptr as *const &dyn Context) }) - }) -} - /// A type that provides internal information but that can still be used for debug purpose. #[derive(Clone, PartialEq, Eq, Hash)] pub struct Opaque(String); From f8c2478b6b2459dffa03502fff8a10b7b8ec834d Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Fri, 24 Nov 2023 15:09:26 -0800 Subject: [PATCH 28/30] Reorder imports and remove re-export --- .../rustc_smir/src/rustc_smir/convert/mir.rs | 4 +++- .../rustc_smir/src/rustc_smir/convert/mod.rs | 4 +++- .../rustc_smir/src/rustc_smir/convert/ty.rs | 3 ++- compiler/stable_mir/src/compiler_interface.rs | 3 ++- compiler/stable_mir/src/lib.rs | 21 ++++++++++--------- 5 files changed, 21 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index 91fadc16442..62a26bc089a 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -1,5 +1,5 @@ //! Conversion of internal Rust compiler `mir` items to stable ones. -use crate::rustc_smir::{alloc, Stable, Tables}; + use rustc_middle::mir; use rustc_middle::mir::interpret::alloc_range; use rustc_middle::mir::mono::MonoItem; @@ -8,6 +8,8 @@ use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoF use stable_mir::ty::{Allocation, Const, ConstantKind}; use stable_mir::{opaque, Error}; +use crate::rustc_smir::{alloc, Stable, Tables}; + impl<'tcx> Stable<'tcx> for mir::Body<'tcx> { type T = stable_mir::mir::Body; diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs index 9bccb57f9b8..edb32df305c 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs @@ -1,8 +1,10 @@ //! Conversion of internal Rust compiler items to stable ones. -use crate::rustc_smir::{Stable, Tables}; + use rustc_target::abi::FieldIdx; use stable_mir::mir::VariantIdx; +use crate::rustc_smir::{Stable, Tables}; + mod mir; mod ty; diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index cca7e0ce0b6..32ee928ddd4 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -1,6 +1,5 @@ //! Conversion of internal Rust compiler `ty` items to stable ones. -use crate::rustc_smir::{alloc, Stable, Tables}; use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; use stable_mir::ty::{ @@ -8,6 +7,8 @@ use stable_mir::ty::{ TyKind, UintTy, }; +use crate::rustc_smir::{alloc, Stable, Tables}; + impl<'tcx> Stable<'tcx> for ty::AliasKind { type T = stable_mir::ty::AliasKind; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index 9f4512b167e..827418a6432 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -3,6 +3,8 @@ //! StableMIR users should not use any of the items in this module directly. //! These APIs have no stability guarantee. +use std::cell::Cell; + use crate::mir::alloc::{AllocId, GlobalAlloc}; use crate::mir::mono::{Instance, InstanceDef, StaticDef}; use crate::mir::Body; @@ -15,7 +17,6 @@ use crate::{ mir, Crate, CrateItem, CrateItems, DefId, Error, Filename, ImplTraitDecls, ItemKind, Symbol, TraitDecls, }; -use std::cell::Cell; /// This trait defines the interface between stable_mir and the Rust compiler. /// Do not use this directly. diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 18c2b942170..1f75dfb69cf 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -17,20 +17,21 @@ //! The goal is to eventually be published on //! [crates.io](https://crates.io). -use self::ty::{ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty}; -pub(crate) use crate::compiler_interface::with; -pub use crate::crate_def::CrateDef; -pub use crate::crate_def::DefId; -use crate::mir::pretty::function_name; -use crate::mir::Body; -use crate::mir::Mutability; -pub use error::*; +#[macro_use] +extern crate scoped_tls; + use std::fmt; use std::fmt::Debug; use std::io; -#[macro_use] -extern crate scoped_tls; +use crate::compiler_interface::with; +pub use crate::crate_def::CrateDef; +pub use crate::crate_def::DefId; +pub use crate::error::*; +use crate::mir::pretty::function_name; +use crate::mir::Body; +use crate::mir::Mutability; +use crate::ty::{ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty}; #[macro_use] pub mod crate_def; From b601b40b402028639cac8d6b87e6a9cabd11b457 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 24 Nov 2023 23:35:05 +0000 Subject: [PATCH 29/30] Separate Nan/Inf floats with _ --- compiler/rustc_middle/src/ty/print/pretty.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 25a151443d5..2bde339ec77 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -8,6 +8,7 @@ use crate::ty::{ }; use crate::ty::{GenericArg, GenericArgKind}; use rustc_apfloat::ieee::{Double, Single}; +use rustc_apfloat::Float; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::sso::SsoHashSet; use rustc_hir as hir; @@ -1477,10 +1478,12 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { ty::Bool if int == ScalarInt::TRUE => p!("true"), // Float ty::Float(ty::FloatTy::F32) => { - p!(write("{}f32", Single::try_from(int).unwrap())) + let val = Single::try_from(int).unwrap(); + p!(write("{}{}f32", val, if val.is_finite() { "" } else { "_" })) } ty::Float(ty::FloatTy::F64) => { - p!(write("{}f64", Double::try_from(int).unwrap())) + let val = Double::try_from(int).unwrap(); + p!(write("{}{}f64", val, if val.is_finite() { "" } else { "_" })) } // Int ty::Uint(_) | ty::Int(_) => { From 60817e6863939a82eeb0f071018e4a40e097bb5a Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Fri, 24 Nov 2023 18:42:39 -0800 Subject: [PATCH 30/30] Fix smir's `Ty::Ref` pretty printing --- compiler/stable_mir/src/mir/pretty.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index c16d7ddf335..e7bca295b5a 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -171,7 +171,6 @@ pub fn pretty_rvalue(rval: &Rvalue) -> String { pub fn pretty_ty(ty: TyKind) -> String { let mut pretty = String::new(); - pretty.push_str(""); match ty { TyKind::RigidTy(rigid_ty) => match rigid_ty { RigidTy::Bool => "bool".to_string(), @@ -215,7 +214,10 @@ pub fn pretty_ty(ty: TyKind) -> String { pretty.push_str(&pretty_ty(ty.kind())); pretty } - RigidTy::Ref(_, ty, _) => pretty_ty(ty.kind()), + RigidTy::Ref(_, ty, mutability) => match mutability { + Mutability::Not => format!("&{}", pretty_ty(ty.kind())), + Mutability::Mut => format!("&mut {}", pretty_ty(ty.kind())), + }, RigidTy::FnDef(_, _) => format!("{:#?}", rigid_ty), RigidTy::FnPtr(_) => format!("{:#?}", rigid_ty), RigidTy::Closure(_, _) => format!("{:#?}", rigid_ty),