diff --git a/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs b/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs index 33d51bdddeaf9..550f20515536e 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 10582cc7bb320..f7d1bdbc4c6ff 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 9f52669e1880f..b4724b0e9d060 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_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 102c83751aad7..ff92d4c4a3eeb 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; } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 78e755378f5f8..773f184472bd9 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 7252a812466c7..b26ce464486a5 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_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 18a9cb6b44b78..ece30bbba12ac 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_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index b218cc5789df1..f0e415492ae96 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/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 25a151443d523..2bde339ec77d2 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(_) => { diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index fed21f16a4e58..c3db9b358e8b5 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; @@ -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 new file mode 100644 index 0000000000000..3449176f72937 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -0,0 +1,376 @@ +//! Implementation of `[stable_mir::compiler_interface::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::compiler_interface::Context; +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, 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 0000000000000..62a26bc089ad8 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -0,0 +1,745 @@ +//! Conversion of internal Rust compiler `mir` items to stable ones. + +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}; + +use crate::rustc_smir::{alloc, Stable, Tables}; + +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 0000000000000..edb32df305c8e --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs @@ -0,0 +1,76 @@ +//! Conversion of internal Rust compiler items to stable ones. + +use rustc_target::abi::FieldIdx; +use stable_mir::mir::VariantIdx; + +use crate::rustc_smir::{Stable, Tables}; + +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 0000000000000..32ee928ddd406 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -0,0 +1,815 @@ +//! Conversion of internal Rust compiler `ty` items to stable ones. + +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, +}; + +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 { + 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 9921a89eb23da..5d903e69c6cdd 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>, 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 ae7f6ca2f7a01..da2f16e97608a 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 }, diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs new file mode 100644 index 0000000000000..827418a643259 --- /dev/null +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -0,0 +1,164 @@ +//! 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 std::cell::Cell; + +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, +}; + +/// 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 1b1faea49539f..1f75dfb69cfd9 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -17,38 +17,31 @@ //! The goal is to eventually be published on //! [crates.io](https://crates.io). -use crate::mir::mono::{InstanceDef, StaticDef}; -use crate::mir::Body; +#[macro_use] +extern crate scoped_tls; + use std::fmt; use std::fmt::Debug; -use std::{cell::Cell, io}; +use std::io; -use self::ty::{ - GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, LineInfo, Span, TraitDecl, - TraitDef, Ty, TyKind, -}; - -#[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; +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 +172,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); diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index c16d7ddf335b3..e7bca295b5a04 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), diff --git a/config.example.toml b/config.example.toml index 5f9ae039b252a..c91222169d982 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/README.md b/src/bootstrap/README.md index e7998a40a6520..d0a069f45e138 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/bin/main.rs b/src/bootstrap/src/bin/main.rs index 7e6fdb7092dee..952ef40ed424d 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 { diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index bbbdb4c3186d6..49373177abeac 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 736a9b312f059..480dd75791517 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,62 +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.", - }, -]; - /// Extra --check-cfg to add when building /// (Mode restriction, config name, config values (if any)) const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ @@ -1895,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 0000000000000..887b596b7868a --- /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 8ca22d00865b6..cb535f0e1632a 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/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index ce9e1bcf4883a..14387e0d45dfe 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/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 4822690fd04b6..0bb56cd971013 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/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index d6516cff63fb4..f85f9e674ab12 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(); diff --git a/tests/rustdoc-js/assoc-type-loop.js b/tests/rustdoc-js/assoc-type-loop.js new file mode 100644 index 0000000000000..f0192371ab41a --- /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 0000000000000..f123c83f50fdf --- /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; +} diff --git a/triagebot.toml b/triagebot.toml index a72338d19505a..c1482769852bf 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"] @@ -583,11 +589,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."