diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 5d465bca4eef1..bdc2353b62587 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -20,7 +20,6 @@ pub mod rustc_internal; -// Make this module private for now since external users should not call these directly. -mod rustc_smir; +pub mod rustc_smir; pub mod stable_mir; diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index a546a44c87004..69582bd054f62 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -18,9 +18,10 @@ use rustc_span::def_id::{CrateNum, DefId}; use scoped_tls::scoped_thread_local; use stable_mir::Error; use stable_mir::abi::Layout; +use stable_mir::compiler_interface::SmirInterface; use stable_mir::ty::IndexedVal; -use crate::rustc_smir::context::TablesWrapper; +use crate::rustc_smir::context::SmirCtxt; use crate::rustc_smir::{Stable, Tables}; use crate::stable_mir; @@ -196,12 +197,12 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { // datastructures and stable MIR datastructures scoped_thread_local! (static TLV: Cell<*const ()>); -pub(crate) fn init<'tcx, F, T>(tables: &TablesWrapper<'tcx>, f: F) -> T +pub(crate) fn init<'tcx, F, T>(cx: &SmirCtxt<'tcx>, f: F) -> T where F: FnOnce() -> T, { assert!(!TLV.is_set()); - let ptr = tables as *const _ as *const (); + let ptr = cx as *const _ as *const (); TLV.set(&Cell::new(ptr), || f()) } @@ -212,8 +213,8 @@ pub(crate) fn with_tables(f: impl for<'tcx> FnOnce(&mut Tables<'tcx>) -> R) - TLV.with(|tlv| { let ptr = tlv.get(); assert!(!ptr.is_null()); - let wrapper = ptr as *const TablesWrapper<'_>; - let mut tables = unsafe { (*wrapper).0.borrow_mut() }; + let context = ptr as *const SmirCtxt<'_>; + let mut tables = unsafe { (*context).0.borrow_mut() }; f(&mut *tables) }) } @@ -222,7 +223,7 @@ pub fn run(tcx: TyCtxt<'_>, f: F) -> Result where F: FnOnce() -> T, { - let tables = TablesWrapper(RefCell::new(Tables { + let tables = SmirCtxt(RefCell::new(Tables { tcx, def_ids: IndexMap::default(), alloc_ids: IndexMap::default(), @@ -233,7 +234,12 @@ where mir_consts: IndexMap::default(), layouts: IndexMap::default(), })); - stable_mir::compiler_interface::run(&tables, || init(&tables, f)) + + let interface = SmirInterface { cx: tables }; + + // Pass the `SmirInterface` to compiler_interface::run + // and initialize the rustc-specific TLS with tables. + stable_mir::compiler_interface::run(&interface, || init(&interface.cx, f)) } /// Instantiate and run the compiler with the provided arguments and callback. diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 240f6f7fe45a1..9a4cac243bd39 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -1,7 +1,4 @@ -//! Implementation of `[stable_mir::compiler_interface::Context]` trait. -//! -//! This trait is currently the main interface between the Rust compiler, -//! and the `stable_mir` crate. +//! Implementation of StableMIR Context. #![allow(rustc::usage_of_qualified_ty)] @@ -20,7 +17,6 @@ use rustc_middle::ty::{ use rustc_middle::{mir, ty}; use rustc_span::def_id::LOCAL_CRATE; use stable_mir::abi::{FnAbi, Layout, LayoutShape}; -use stable_mir::compiler_interface::Context; use stable_mir::mir::alloc::GlobalAlloc; use stable_mir::mir::mono::{InstanceDef, StaticDef}; use stable_mir::mir::{BinOp, Body, Place, UnOp}; @@ -37,8 +33,14 @@ use crate::rustc_smir::builder::BodyBuilder; use crate::rustc_smir::{Stable, Tables, alloc, filter_def_ids, new_item_kind, smir_crate}; use crate::stable_mir; -impl<'tcx> Context for TablesWrapper<'tcx> { - fn target_info(&self) -> MachineInfo { +/// Provides direct access to rustc's internal queries. +/// +/// The [`crate::stable_mir::compiler_interface::SmirInterface`] must go through +/// this context to obtain rustc-level information. +pub struct SmirCtxt<'tcx>(pub RefCell>); + +impl<'tcx> SmirCtxt<'tcx> { + pub fn target_info(&self) -> MachineInfo { let mut tables = self.0.borrow_mut(); MachineInfo { endian: tables.tcx.data_layout.endian.stable(&mut *tables), @@ -48,31 +50,35 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } } - fn entry_fn(&self) -> Option { + pub 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 { + /// Retrieve all items of the local crate that have a MIR associated with them. + pub 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 { + /// Retrieve the body of a function. + /// This function will panic if the body is not available. + pub 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::InstanceKind::Item(def_id)).stable(&mut tables) } - fn has_body(&self, def: DefId) -> bool { + /// Check whether the body of a function is available. + pub fn has_body(&self, def: DefId) -> bool { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let def_id = def.internal(&mut *tables, tcx); tables.item_has_body(def_id) } - fn foreign_modules(&self, crate_num: CrateNum) -> Vec { + pub fn foreign_modules(&self, crate_num: CrateNum) -> Vec { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; tcx.foreign_modules(crate_num.internal(&mut *tables, tcx)) @@ -81,21 +87,23 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .collect() } - fn crate_functions(&self, crate_num: CrateNum) -> Vec { + /// Retrieve all functions defined in this crate. + pub fn crate_functions(&self, crate_num: CrateNum) -> Vec { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let krate = crate_num.internal(&mut *tables, tcx); filter_def_ids(tcx, krate, |def_id| tables.to_fn_def(def_id)) } - fn crate_statics(&self, crate_num: CrateNum) -> Vec { + /// Retrieve all static items defined in this crate. + pub fn crate_statics(&self, crate_num: CrateNum) -> Vec { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let krate = crate_num.internal(&mut *tables, tcx); filter_def_ids(tcx, krate, |def_id| tables.to_static(def_id)) } - fn foreign_module( + pub fn foreign_module( &self, mod_def: stable_mir::ty::ForeignModuleDef, ) -> stable_mir::ty::ForeignModule { @@ -105,7 +113,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { mod_def.stable(&mut *tables) } - fn foreign_items(&self, mod_def: stable_mir::ty::ForeignModuleDef) -> Vec { + pub fn foreign_items(&self, mod_def: stable_mir::ty::ForeignModuleDef) -> Vec { let mut tables = self.0.borrow_mut(); let def_id = tables[mod_def.def_id()]; tables @@ -119,12 +127,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .collect() } - fn all_trait_decls(&self) -> stable_mir::TraitDecls { + pub fn all_trait_decls(&self) -> stable_mir::TraitDecls { let mut tables = self.0.borrow_mut(); tables.tcx.all_traits().map(|trait_def_id| tables.trait_def(trait_def_id)).collect() } - fn trait_decls(&self, crate_num: CrateNum) -> stable_mir::TraitDecls { + pub fn trait_decls(&self, crate_num: CrateNum) -> stable_mir::TraitDecls { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; tcx.traits(crate_num.internal(&mut *tables, tcx)) @@ -133,14 +141,14 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .collect() } - fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl { + pub 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 { + pub fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; iter::once(LOCAL_CRATE) @@ -150,7 +158,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .collect() } - fn trait_impls(&self, crate_num: CrateNum) -> stable_mir::ImplTraitDecls { + pub fn trait_impls(&self, crate_num: CrateNum) -> stable_mir::ImplTraitDecls { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; tcx.trait_impls_in_crate(crate_num.internal(&mut *tables, tcx)) @@ -159,21 +167,21 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .collect() } - fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait { + pub 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 { + pub 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 { + pub 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); @@ -191,7 +199,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } } - fn explicit_predicates_of( + pub fn explicit_predicates_of( &self, def_id: stable_mir::DefId, ) -> stable_mir::ty::GenericPredicates { @@ -212,17 +220,20 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } } - fn local_crate(&self) -> stable_mir::Crate { + /// Get information about the local crate. + pub fn local_crate(&self) -> stable_mir::Crate { let tables = self.0.borrow(); smir_crate(tables.tcx, LOCAL_CRATE) } - fn external_crates(&self) -> Vec { + /// Retrieve a list of all external crates. + pub 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 { + /// Find a crate with the given name. + pub fn find_crates(&self, name: &str) -> Vec { let tables = self.0.borrow(); let crates: Vec = [LOCAL_CRATE] .iter() @@ -235,7 +246,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { crates } - fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol { + /// Returns the name of given `DefId`. + pub 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])) @@ -244,7 +256,14 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } } - fn tool_attrs( + /// Return registered tool attributes with the given attribute name. + /// + /// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool + /// attributes will simply return an empty list. + /// + /// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`. + /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`. + pub fn tool_attrs( &self, def_id: stable_mir::DefId, attr: &[stable_mir::Symbol], @@ -268,7 +287,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .collect() } - fn all_tool_attrs(&self, def_id: stable_mir::DefId) -> Vec { + /// Get all tool attributes of a definition. + pub fn all_tool_attrs( + &self, + def_id: stable_mir::DefId, + ) -> Vec { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let did = tables[def_id]; @@ -292,12 +315,14 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .collect() } - fn span_to_string(&self, span: stable_mir::ty::Span) -> String { + /// Returns printable, human readable form of `Span`. + pub 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 { + /// Return filename from given `Span`, for diagnostic purposes. + pub fn get_filename(&self, span: &Span) -> Filename { let tables = self.0.borrow(); tables .tcx @@ -308,23 +333,27 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .to_string() } - fn get_lines(&self, span: &Span) -> LineInfo { + /// Return lines corresponding to this `Span`. + pub 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 { + /// Returns the `kind` of given `DefId`. + pub 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: DefId) -> bool { + /// Returns whether this is a foreign item. + pub fn is_foreign_item(&self, item: DefId) -> bool { let tables = self.0.borrow(); tables.tcx.is_foreign_item(tables[item]) } - fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind { + /// Returns the kind of a given foreign item. + pub fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind { let mut tables = self.0.borrow_mut(); let def_id = tables[def.def_id()]; let tcx = tables.tcx; @@ -339,32 +368,37 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } } - fn adt_kind(&self, def: AdtDef) -> AdtKind { + /// Returns the kind of a given algebraic data type. + pub fn adt_kind(&self, def: AdtDef) -> AdtKind { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; def.internal(&mut *tables, tcx).adt_kind().stable(&mut *tables) } - fn adt_is_box(&self, def: AdtDef) -> bool { + /// Returns if the ADT is a box. + pub fn adt_is_box(&self, def: AdtDef) -> bool { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; def.internal(&mut *tables, tcx).is_box() } - fn adt_is_simd(&self, def: AdtDef) -> bool { + /// Returns whether this ADT is simd. + pub fn adt_is_simd(&self, def: AdtDef) -> bool { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; def.internal(&mut *tables, tcx).repr().simd() } - fn adt_is_cstr(&self, def: AdtDef) -> bool { + /// Returns whether this definition is a C string. + pub fn adt_is_cstr(&self, def: AdtDef) -> bool { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let def_id = def.0.internal(&mut *tables, tcx); tables.tcx.is_lang_item(def_id, LangItem::CStr) } - fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { + /// Retrieve the function signature for the given generic arguments. + pub fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let def_id = def.0.internal(&mut *tables, tcx); @@ -373,7 +407,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { sig.stable(&mut *tables) } - fn intrinsic(&self, def: DefId) -> Option { + /// Retrieve the intrinsic definition if the item corresponds one. + pub fn intrinsic(&self, def: DefId) -> Option { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let def_id = def.internal(&mut *tables, tcx); @@ -381,14 +416,16 @@ impl<'tcx> Context for TablesWrapper<'tcx> { intrinsic.map(|_| IntrinsicDef(def)) } - fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol { + /// Retrieve the plain function name of an intrinsic. + pub fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let def_id = def.0.internal(&mut *tables, tcx); tcx.intrinsic(def_id).unwrap().name.to_string() } - fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig { + /// Retrieve the closure signature for the given generic arguments. + pub fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let args_ref = args.internal(&mut *tables, tcx); @@ -396,25 +433,28 @@ impl<'tcx> Context for TablesWrapper<'tcx> { sig.stable(&mut *tables) } - fn adt_variants_len(&self, def: AdtDef) -> usize { + /// The number of variants in this ADT. + pub fn adt_variants_len(&self, def: AdtDef) -> usize { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; def.internal(&mut *tables, tcx).variants().len() } - fn variant_name(&self, def: VariantDef) -> Symbol { + /// The name of a variant. + pub fn variant_name(&self, def: VariantDef) -> Symbol { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; def.internal(&mut *tables, tcx).name.to_string() } - fn variant_fields(&self, def: VariantDef) -> Vec { + pub fn variant_fields(&self, def: VariantDef) -> Vec { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; def.internal(&mut *tables, tcx).fields.iter().map(|f| f.stable(&mut *tables)).collect() } - fn eval_target_usize(&self, cnst: &MirConst) -> Result { + /// Evaluate constant as a target usize. + pub fn eval_target_usize(&self, cnst: &MirConst) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let mir_const = cnst.internal(&mut *tables, tcx); @@ -422,7 +462,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .try_eval_target_usize(tables.tcx, ty::TypingEnv::fully_monomorphized()) .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) } - fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result { + pub fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let mir_const = cnst.internal(&mut *tables, tcx); @@ -431,7 +471,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) } - fn try_new_const_zst(&self, ty: Ty) -> Result { + /// Create a new zero-sized constant. + pub fn try_new_const_zst(&self, ty: Ty) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty_internal = ty.internal(&mut *tables, tcx); @@ -456,7 +497,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .stable(&mut *tables)) } - fn new_const_str(&self, value: &str) -> MirConst { + /// Create a new constant that represents the given string value. + pub fn new_const_str(&self, value: &str) -> MirConst { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty = ty::Ty::new_static_str(tcx); @@ -467,12 +509,14 @@ impl<'tcx> Context for TablesWrapper<'tcx> { mir::Const::from_value(val, ty).stable(&mut tables) } - fn new_const_bool(&self, value: bool) -> MirConst { + /// Create a new constant that represents the given boolean value. + pub fn new_const_bool(&self, value: bool) -> MirConst { let mut tables = self.0.borrow_mut(); mir::Const::from_bool(tables.tcx, value).stable(&mut tables) } - fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { + /// Create a new constant that represents the given value. + pub fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); @@ -487,7 +531,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { Ok(mir::Const::from_scalar(tcx, mir::interpret::Scalar::Int(scalar), ty) .stable(&mut tables)) } - fn try_new_ty_const_uint( + pub fn try_new_ty_const_uint( &self, value: u128, uint_ty: UintTy, @@ -509,27 +553,35 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .stable(&mut *tables)) } - fn new_rigid_ty(&self, kind: RigidTy) -> stable_mir::ty::Ty { + /// Create a new type from the given kind. + pub fn new_rigid_ty(&self, kind: RigidTy) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let internal_kind = kind.internal(&mut *tables, tcx); tables.tcx.mk_ty_from_kind(internal_kind).stable(&mut *tables) } - fn new_box_ty(&self, ty: stable_mir::ty::Ty) -> stable_mir::ty::Ty { + /// Create a new box type, `Box`, for the given inner type `T`. + pub fn new_box_ty(&self, ty: stable_mir::ty::Ty) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let inner = ty.internal(&mut *tables, tcx); ty::Ty::new_box(tables.tcx, inner).stable(&mut *tables) } - fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty { + /// Returns the type of given crate item. + pub fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; tcx.type_of(item.internal(&mut *tables, tcx)).instantiate_identity().stable(&mut *tables) } - fn def_ty_with_args(&self, item: stable_mir::DefId, args: &GenericArgs) -> stable_mir::ty::Ty { + /// Returns the type of given definition instantiated with the given arguments. + pub fn def_ty_with_args( + &self, + item: stable_mir::DefId, + args: &GenericArgs, + ) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let args = args.internal(&mut *tables, tcx); @@ -544,33 +596,38 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .stable(&mut *tables) } - fn mir_const_pretty(&self, cnst: &stable_mir::ty::MirConst) -> String { + /// Returns literal value of a const as a string. + pub fn mir_const_pretty(&self, cnst: &stable_mir::ty::MirConst) -> String { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; cnst.internal(&mut *tables, tcx).to_string() } - fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span { + /// `Span` of an item. + pub 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_pretty(&self, ty: stable_mir::ty::Ty) -> String { + /// Obtain the representation of a type. + pub fn ty_pretty(&self, ty: stable_mir::ty::Ty) -> String { let tables = self.0.borrow_mut(); tables.types[ty].to_string() } - fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind { + /// Obtain the representation of a type. + pub 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 ty_const_pretty(&self, ct: stable_mir::ty::TyConstId) -> String { + pub fn ty_const_pretty(&self, ct: stable_mir::ty::TyConstId) -> String { let tables = self.0.borrow_mut(); tables.ty_consts[ct].to_string() } - fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty { + /// Get the discriminant Ty for this Ty if there's one. + pub fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let internal_kind = ty.internal(&mut *tables, tcx); @@ -578,7 +635,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { internal_ty.discriminant_ty(tables.tcx).stable(&mut *tables) } - fn instance_body(&self, def: InstanceDef) -> Option { + /// Get the body of an Instance which is already monomorphized. + pub fn instance_body(&self, def: InstanceDef) -> Option { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; tables @@ -586,63 +644,74 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .then(|| BodyBuilder::new(tables.tcx, instance).build(&mut *tables)) } - fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty { + /// Get the instance type with generic instantiations applied and lifetimes erased. + pub fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation"); instance.ty(tables.tcx, ty::TypingEnv::fully_monomorphized()).stable(&mut *tables) } - fn instance_args(&self, def: InstanceDef) -> GenericArgs { + /// Get the instantiation types. + pub fn instance_args(&self, def: InstanceDef) -> GenericArgs { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; instance.args.stable(&mut *tables) } - fn instance_abi(&self, def: InstanceDef) -> Result { + /// Get an instance ABI. + pub fn instance_abi(&self, def: InstanceDef) -> Result { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables)) } - fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result { + /// Get the ABI of a function pointer. + pub fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let sig = fn_ptr.internal(&mut *tables, tcx); Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?.stable(&mut *tables)) } - fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId { + /// Get the instance. + pub 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 { + /// Get the instance mangled name. + pub 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 is_empty_drop_shim(&self, def: InstanceDef) -> bool { + /// Check if this is an empty DropGlue shim. + pub fn is_empty_drop_shim(&self, def: InstanceDef) -> bool { let tables = self.0.borrow_mut(); let instance = tables.instances[def]; matches!(instance.def, ty::InstanceKind::DropGlue(_, None)) } - fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool { + /// Check if this is an empty AsyncDropGlueCtor shim. + pub fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool { let tables = self.0.borrow_mut(); let instance = tables.instances[def]; matches!(instance.def, ty::InstanceKind::AsyncDropGlueCtorShim(_, None)) } - fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance { + /// Convert a non-generic crate item into an instance. + /// This function will panic if the item is generic. + pub fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance { let mut tables = self.0.borrow_mut(); let def_id = tables[def_id]; Instance::mono(tables.tcx, def_id).stable(&mut *tables) } - fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool { + /// Item requires monomorphization. + pub 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); @@ -650,7 +719,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { result } - fn resolve_instance( + /// Resolve an instance from the given function definition and generic arguments. + pub fn resolve_instance( &self, def: stable_mir::ty::FnDef, args: &stable_mir::ty::GenericArgs, @@ -670,7 +740,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } } - fn resolve_drop_in_place(&self, ty: stable_mir::ty::Ty) -> stable_mir::mir::mono::Instance { + /// Resolve an instance for drop_in_place for the given type. + pub fn resolve_drop_in_place(&self, ty: stable_mir::ty::Ty) -> stable_mir::mir::mono::Instance { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let internal_ty = ty.internal(&mut *tables, tcx); @@ -678,7 +749,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { instance.stable(&mut *tables) } - fn resolve_for_fn_ptr( + /// Resolve instance for a function pointer. + pub fn resolve_for_fn_ptr( &self, def: FnDef, args: &GenericArgs, @@ -696,7 +768,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .stable(&mut *tables) } - fn resolve_closure( + /// Resolve instance for a closure with the requested type. + pub fn resolve_closure( &self, def: ClosureDef, args: &GenericArgs, @@ -713,7 +786,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ) } - fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result { + /// Try to evaluate an instance into a constant. + pub fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; let tcx = tables.tcx; @@ -733,21 +807,24 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .map_err(|e| e.stable(&mut *tables))? } - fn eval_static_initializer(&self, def: StaticDef) -> Result { + /// Evaluate a static's initializer. + pub fn eval_static_initializer(&self, def: StaticDef) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let def_id = def.0.internal(&mut *tables, tcx); tables.tcx.eval_static_initializer(def_id).stable(&mut *tables) } - fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc { + /// Retrieve global allocation for the given allocation ID. + pub fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let alloc_id = alloc.internal(&mut *tables, tcx); tables.tcx.global_alloc(alloc_id).stable(&mut *tables) } - fn vtable_allocation( + /// Retrieve the id for the virtual table. + pub fn vtable_allocation( &self, global_alloc: &GlobalAlloc, ) -> Option { @@ -765,7 +842,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { Some(alloc_id.stable(&mut *tables)) } - fn krate(&self, def_id: stable_mir::DefId) -> Crate { + pub fn krate(&self, def_id: stable_mir::DefId) -> Crate { let tables = self.0.borrow(); smir_crate(tables.tcx, tables[def_id].krate) } @@ -773,7 +850,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { /// 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 { + pub fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol { let tables = self.0.borrow_mut(); let instance = tables.instances[def]; if trimmed { @@ -787,7 +864,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } } - fn ty_layout(&self, ty: Ty) -> Result { + /// Get the layout of a type. + pub fn ty_layout(&self, ty: Ty) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty = ty.internal(&mut *tables, tcx); @@ -795,19 +873,22 @@ impl<'tcx> Context for TablesWrapper<'tcx> { Ok(layout.stable(&mut *tables)) } - fn layout_shape(&self, id: Layout) -> LayoutShape { + /// Get the layout shape. + pub fn layout_shape(&self, id: Layout) -> LayoutShape { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; id.internal(&mut *tables, tcx).0.stable(&mut *tables) } - fn place_pretty(&self, place: &Place) -> String { + /// Get a debug string representation of a place. + pub fn place_pretty(&self, place: &Place) -> String { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; format!("{:?}", place.internal(&mut *tables, tcx)) } - fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty { + /// Get the resulting type of binary operation. + pub fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let rhs_internal = rhs.internal(&mut *tables, tcx); @@ -816,7 +897,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ty.stable(&mut *tables) } - fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty { + /// Get the resulting type of unary operation. + pub fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let arg_internal = arg.internal(&mut *tables, tcx); @@ -824,7 +906,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ty.stable(&mut *tables) } - fn associated_items(&self, def_id: stable_mir::DefId) -> stable_mir::AssocItems { + /// Get all associated items of a definition. + pub fn associated_items(&self, def_id: stable_mir::DefId) -> stable_mir::AssocItems { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let def_id = tables[def_id]; @@ -840,8 +923,6 @@ impl<'tcx> Context for TablesWrapper<'tcx> { } } -pub(crate) struct TablesWrapper<'tcx>(pub RefCell>); - /// Implement error handling for extracting function ABI information. impl<'tcx> FnAbiOfHelpers<'tcx> for Tables<'tcx> { type FnAbiOfResult = Result<&'tcx rustc_target::callconv::FnAbi<'tcx, ty::Ty<'tcx>>, Error>; diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index dea8f54a67097..b5003baaf633c 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -25,7 +25,7 @@ use crate::stable_mir; mod alloc; mod builder; -pub(crate) mod context; +pub mod context; mod convert; pub struct Tables<'tcx> { diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index 33d950bb951cd..cd61907dc6baa 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -5,6 +5,7 @@ use std::cell::Cell; +use rustc_smir::context::SmirCtxt; use stable_mir::abi::{FnAbi, Layout, LayoutShape}; use stable_mir::crate_def::Attribute; use stable_mir::mir::alloc::{AllocId, GlobalAlloc}; @@ -22,47 +23,116 @@ use stable_mir::{ ItemKind, Symbol, TraitDecls, mir, }; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; + +/// Stable public API for querying compiler information. +/// +/// All queries are delegated to an internal [`SmirCtxt`] that provides +/// similar APIs but based on internal rustc constructs. +/// +/// Do not use this directly. This is currently used in the macro expansion. +pub(crate) struct SmirInterface<'tcx> { + pub(crate) cx: SmirCtxt<'tcx>, +} + +impl<'tcx> SmirInterface<'tcx> { + pub(crate) fn entry_fn(&self) -> Option { + self.cx.entry_fn() + } -/// 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; + pub(crate) fn all_local_items(&self) -> CrateItems { + self.cx.all_local_items() + } + /// Retrieve the body of a function. /// This function will panic if the body is not available. - fn mir_body(&self, item: DefId) -> mir::Body; + pub(crate) fn mir_body(&self, item: DefId) -> mir::Body { + self.cx.mir_body(item) + } + /// Check whether the body of a function is available. - fn has_body(&self, item: DefId) -> bool; - fn foreign_modules(&self, crate_num: CrateNum) -> Vec; + pub(crate) fn has_body(&self, item: DefId) -> bool { + self.cx.has_body(item) + } + + pub(crate) fn foreign_modules(&self, crate_num: CrateNum) -> Vec { + self.cx.foreign_modules(crate_num) + } /// Retrieve all functions defined in this crate. - fn crate_functions(&self, crate_num: CrateNum) -> Vec; + pub(crate) fn crate_functions(&self, crate_num: CrateNum) -> Vec { + self.cx.crate_functions(crate_num) + } /// Retrieve all static items defined in this crate. - fn crate_statics(&self, crate_num: CrateNum) -> Vec; - fn foreign_module(&self, mod_def: ForeignModuleDef) -> ForeignModule; - fn foreign_items(&self, mod_def: ForeignModuleDef) -> Vec; - fn all_trait_decls(&self) -> TraitDecls; - fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls; - fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl; - fn all_trait_impls(&self) -> ImplTraitDecls; - fn trait_impls(&self, crate_num: CrateNum) -> 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; + pub(crate) fn crate_statics(&self, crate_num: CrateNum) -> Vec { + self.cx.crate_statics(crate_num) + } + + pub(crate) fn foreign_module(&self, mod_def: ForeignModuleDef) -> ForeignModule { + self.cx.foreign_module(mod_def) + } + + pub(crate) fn foreign_items(&self, mod_def: ForeignModuleDef) -> Vec { + self.cx.foreign_items(mod_def) + } + + pub(crate) fn all_trait_decls(&self) -> TraitDecls { + self.cx.all_trait_decls() + } + + pub(crate) fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls { + self.cx.trait_decls(crate_num) + } + + pub(crate) fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl { + self.cx.trait_decl(trait_def) + } + + pub(crate) fn all_trait_impls(&self) -> ImplTraitDecls { + self.cx.all_trait_impls() + } + + pub(crate) fn trait_impls(&self, crate_num: CrateNum) -> ImplTraitDecls { + self.cx.trait_impls(crate_num) + } + + pub(crate) fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait { + self.cx.trait_impl(trait_impl) + } + + pub(crate) fn generics_of(&self, def_id: DefId) -> Generics { + self.cx.generics_of(def_id) + } + + pub(crate) fn predicates_of(&self, def_id: DefId) -> GenericPredicates { + self.cx.predicates_of(def_id) + } + + pub(crate) fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates { + self.cx.explicit_predicates_of(def_id) + } + /// Get information about the local crate. - fn local_crate(&self) -> Crate; + pub(crate) fn local_crate(&self) -> Crate { + self.cx.local_crate() + } + /// Retrieve a list of all external crates. - fn external_crates(&self) -> Vec; + pub(crate) fn external_crates(&self) -> Vec { + self.cx.external_crates() + } /// Find a crate with the given name. - fn find_crates(&self, name: &str) -> Vec; + pub(crate) fn find_crates(&self, name: &str) -> Vec { + self.cx.find_crates(name) + } - /// Returns the name of given `DefId` - fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol; + /// Returns the name of given `DefId`. + pub(crate) fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol { + self.cx.def_name(def_id, trimmed) + } /// Return registered tool attributes with the given attribute name. /// @@ -71,218 +141,362 @@ pub trait Context { /// /// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`. /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`. - fn tool_attrs(&self, def_id: DefId, attr: &[Symbol]) -> Vec; + pub(crate) fn tool_attrs(&self, def_id: DefId, attr: &[Symbol]) -> Vec { + self.cx.tool_attrs(def_id, attr) + } /// Get all tool attributes of a definition. - fn all_tool_attrs(&self, def_id: DefId) -> Vec; + pub(crate) fn all_tool_attrs(&self, def_id: DefId) -> Vec { + self.cx.all_tool_attrs(def_id) + } - /// Returns printable, human readable form of `Span` - fn span_to_string(&self, span: Span) -> String; + /// Returns printable, human readable form of `Span`. + pub(crate) fn span_to_string(&self, span: Span) -> String { + self.cx.span_to_string(span) + } - /// Return filename from given `Span`, for diagnostic purposes - fn get_filename(&self, span: &Span) -> Filename; + /// Return filename from given `Span`, for diagnostic purposes. + pub(crate) fn get_filename(&self, span: &Span) -> Filename { + self.cx.get_filename(span) + } - /// Return lines corresponding to this `Span` - fn get_lines(&self, span: &Span) -> LineInfo; + /// Return lines corresponding to this `Span`. + pub(crate) fn get_lines(&self, span: &Span) -> LineInfo { + self.cx.get_lines(span) + } - /// Returns the `kind` of given `DefId` - fn item_kind(&self, item: CrateItem) -> ItemKind; + /// Returns the `kind` of given `DefId`. + pub(crate) fn item_kind(&self, item: CrateItem) -> ItemKind { + self.cx.item_kind(item) + } /// Returns whether this is a foreign item. - fn is_foreign_item(&self, item: DefId) -> bool; + pub(crate) fn is_foreign_item(&self, item: DefId) -> bool { + self.cx.is_foreign_item(item) + } /// Returns the kind of a given foreign item. - fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind; + pub(crate) fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind { + self.cx.foreign_item_kind(def) + } - /// Returns the kind of a given algebraic data type - fn adt_kind(&self, def: AdtDef) -> AdtKind; + /// Returns the kind of a given algebraic data type. + pub(crate) fn adt_kind(&self, def: AdtDef) -> AdtKind { + self.cx.adt_kind(def) + } /// Returns if the ADT is a box. - fn adt_is_box(&self, def: AdtDef) -> bool; + pub(crate) fn adt_is_box(&self, def: AdtDef) -> bool { + self.cx.adt_is_box(def) + } /// Returns whether this ADT is simd. - fn adt_is_simd(&self, def: AdtDef) -> bool; + pub(crate) fn adt_is_simd(&self, def: AdtDef) -> bool { + self.cx.adt_is_simd(def) + } /// Returns whether this definition is a C string. - fn adt_is_cstr(&self, def: AdtDef) -> bool; + pub(crate) fn adt_is_cstr(&self, def: AdtDef) -> bool { + self.cx.adt_is_cstr(def) + } /// Retrieve the function signature for the given generic arguments. - fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig; + pub(crate) fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { + self.cx.fn_sig(def, args) + } /// Retrieve the intrinsic definition if the item corresponds one. - fn intrinsic(&self, item: DefId) -> Option; + pub(crate) fn intrinsic(&self, item: DefId) -> Option { + self.cx.intrinsic(item) + } /// Retrieve the plain function name of an intrinsic. - fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol; + pub(crate) fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol { + self.cx.intrinsic_name(def) + } /// Retrieve the closure signature for the given generic arguments. - fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig; + pub(crate) fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig { + self.cx.closure_sig(args) + } /// The number of variants in this ADT. - fn adt_variants_len(&self, def: AdtDef) -> usize; + pub(crate) fn adt_variants_len(&self, def: AdtDef) -> usize { + self.cx.adt_variants_len(def) + } /// The name of a variant. - fn variant_name(&self, def: VariantDef) -> Symbol; - fn variant_fields(&self, def: VariantDef) -> Vec; + pub(crate) fn variant_name(&self, def: VariantDef) -> Symbol { + self.cx.variant_name(def) + } + + pub(crate) fn variant_fields(&self, def: VariantDef) -> Vec { + self.cx.variant_fields(def) + } /// Evaluate constant as a target usize. - fn eval_target_usize(&self, cnst: &MirConst) -> Result; - fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result; + pub(crate) fn eval_target_usize(&self, cnst: &MirConst) -> Result { + self.cx.eval_target_usize(cnst) + } + + pub(crate) fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result { + self.cx.eval_target_usize_ty(cnst) + } /// Create a new zero-sized constant. - fn try_new_const_zst(&self, ty: Ty) -> Result; + pub(crate) fn try_new_const_zst(&self, ty: Ty) -> Result { + self.cx.try_new_const_zst(ty) + } /// Create a new constant that represents the given string value. - fn new_const_str(&self, value: &str) -> MirConst; + pub(crate) fn new_const_str(&self, value: &str) -> MirConst { + self.cx.new_const_str(value) + } /// Create a new constant that represents the given boolean value. - fn new_const_bool(&self, value: bool) -> MirConst; + pub(crate) fn new_const_bool(&self, value: bool) -> MirConst { + self.cx.new_const_bool(value) + } /// Create a new constant that represents the given value. - fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; - fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; + pub(crate) fn try_new_const_uint( + &self, + value: u128, + uint_ty: UintTy, + ) -> Result { + self.cx.try_new_const_uint(value, uint_ty) + } + + pub(crate) fn try_new_ty_const_uint( + &self, + value: u128, + uint_ty: UintTy, + ) -> Result { + self.cx.try_new_ty_const_uint(value, uint_ty) + } /// Create a new type from the given kind. - fn new_rigid_ty(&self, kind: RigidTy) -> Ty; + pub(crate) fn new_rigid_ty(&self, kind: RigidTy) -> Ty { + self.cx.new_rigid_ty(kind) + } /// Create a new box type, `Box`, for the given inner type `T`. - fn new_box_ty(&self, ty: Ty) -> Ty; + pub(crate) fn new_box_ty(&self, ty: Ty) -> Ty { + self.cx.new_box_ty(ty) + } /// Returns the type of given crate item. - fn def_ty(&self, item: DefId) -> Ty; + pub(crate) fn def_ty(&self, item: DefId) -> Ty { + self.cx.def_ty(item) + } /// Returns the type of given definition instantiated with the given arguments. - fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty; + pub(crate) fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty { + self.cx.def_ty_with_args(item, args) + } /// Returns literal value of a const as a string. - fn mir_const_pretty(&self, cnst: &MirConst) -> String; + pub(crate) fn mir_const_pretty(&self, cnst: &MirConst) -> String { + self.cx.mir_const_pretty(cnst) + } - /// `Span` of an item - fn span_of_an_item(&self, def_id: DefId) -> Span; + /// `Span` of an item. + pub(crate) fn span_of_an_item(&self, def_id: DefId) -> Span { + self.cx.span_of_an_item(def_id) + } - fn ty_const_pretty(&self, ct: TyConstId) -> String; + pub(crate) fn ty_const_pretty(&self, ct: TyConstId) -> String { + self.cx.ty_const_pretty(ct) + } /// Obtain the representation of a type. - fn ty_pretty(&self, ty: Ty) -> String; + pub(crate) fn ty_pretty(&self, ty: Ty) -> String { + self.cx.ty_pretty(ty) + } /// Obtain the representation of a type. - fn ty_kind(&self, ty: Ty) -> TyKind; + pub(crate) fn ty_kind(&self, ty: Ty) -> TyKind { + self.cx.ty_kind(ty) + } - // Get the discriminant Ty for this Ty if there's one. - fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> Ty; + /// Get the discriminant Ty for this Ty if there's one. + pub(crate) fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> Ty { + self.cx.rigid_ty_discriminant_ty(ty) + } /// Get the body of an Instance which is already monomorphized. - fn instance_body(&self, instance: InstanceDef) -> Option; + pub(crate) fn instance_body(&self, instance: InstanceDef) -> Option { + self.cx.instance_body(instance) + } /// Get the instance type with generic instantiations applied and lifetimes erased. - fn instance_ty(&self, instance: InstanceDef) -> Ty; + pub(crate) fn instance_ty(&self, instance: InstanceDef) -> Ty { + self.cx.instance_ty(instance) + } /// Get the instantiation types. - fn instance_args(&self, def: InstanceDef) -> GenericArgs; + pub(crate) fn instance_args(&self, def: InstanceDef) -> GenericArgs { + self.cx.instance_args(def) + } /// Get the instance. - fn instance_def_id(&self, instance: InstanceDef) -> DefId; + pub(crate) fn instance_def_id(&self, instance: InstanceDef) -> DefId { + self.cx.instance_def_id(instance) + } /// Get the instance mangled name. - fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol; + pub(crate) fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol { + self.cx.instance_mangled_name(instance) + } /// Check if this is an empty DropGlue shim. - fn is_empty_drop_shim(&self, def: InstanceDef) -> bool; + pub(crate) fn is_empty_drop_shim(&self, def: InstanceDef) -> bool { + self.cx.is_empty_drop_shim(def) + } /// Check if this is an empty AsyncDropGlueCtor shim. - fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool; + pub(crate) fn is_empty_async_drop_ctor_shim(&self, def: InstanceDef) -> bool { + self.cx.is_empty_async_drop_ctor_shim(def) + } /// Convert a non-generic crate item into an instance. /// This function will panic if the item is generic. - fn mono_instance(&self, def_id: DefId) -> Instance; + pub(crate) fn mono_instance(&self, def_id: DefId) -> Instance { + self.cx.mono_instance(def_id) + } /// Item requires monomorphization. - fn requires_monomorphization(&self, def_id: DefId) -> bool; + pub(crate) fn requires_monomorphization(&self, def_id: DefId) -> bool { + self.cx.requires_monomorphization(def_id) + } /// Resolve an instance from the given function definition and generic arguments. - fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option; + pub(crate) fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option { + self.cx.resolve_instance(def, args) + } /// Resolve an instance for drop_in_place for the given type. - fn resolve_drop_in_place(&self, ty: Ty) -> Instance; + pub(crate) fn resolve_drop_in_place(&self, ty: Ty) -> Instance { + self.cx.resolve_drop_in_place(ty) + } /// Resolve instance for a function pointer. - fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option; + pub(crate) fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option { + self.cx.resolve_for_fn_ptr(def, args) + } /// Resolve instance for a closure with the requested type. - fn resolve_closure( + pub(crate) fn resolve_closure( &self, def: ClosureDef, args: &GenericArgs, kind: ClosureKind, - ) -> Option; + ) -> Option { + self.cx.resolve_closure(def, args, kind) + } /// Evaluate a static's initializer. - fn eval_static_initializer(&self, def: StaticDef) -> Result; + pub(crate) fn eval_static_initializer(&self, def: StaticDef) -> Result { + self.cx.eval_static_initializer(def) + } /// Try to evaluate an instance into a constant. - fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result; + pub(crate) fn eval_instance( + &self, + def: InstanceDef, + const_ty: Ty, + ) -> Result { + self.cx.eval_instance(def, const_ty) + } /// Retrieve global allocation for the given allocation ID. - fn global_alloc(&self, id: AllocId) -> GlobalAlloc; + pub(crate) fn global_alloc(&self, id: AllocId) -> GlobalAlloc { + self.cx.global_alloc(id) + } /// 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; + pub(crate) fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option { + self.cx.vtable_allocation(global_alloc) + } + + pub(crate) fn krate(&self, def_id: DefId) -> Crate { + self.cx.krate(def_id) + } + + pub(crate) fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol { + self.cx.instance_name(def, trimmed) + } /// Return information about the target machine. - fn target_info(&self) -> MachineInfo; + pub(crate) fn target_info(&self) -> MachineInfo { + self.cx.target_info() + } /// Get an instance ABI. - fn instance_abi(&self, def: InstanceDef) -> Result; + pub(crate) fn instance_abi(&self, def: InstanceDef) -> Result { + self.cx.instance_abi(def) + } /// Get the ABI of a function pointer. - fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result; + pub(crate) fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result { + self.cx.fn_ptr_abi(fn_ptr) + } /// Get the layout of a type. - fn ty_layout(&self, ty: Ty) -> Result; + pub(crate) fn ty_layout(&self, ty: Ty) -> Result { + self.cx.ty_layout(ty) + } /// Get the layout shape. - fn layout_shape(&self, id: Layout) -> LayoutShape; + pub(crate) fn layout_shape(&self, id: Layout) -> LayoutShape { + self.cx.layout_shape(id) + } /// Get a debug string representation of a place. - fn place_pretty(&self, place: &Place) -> String; + pub(crate) fn place_pretty(&self, place: &Place) -> String { + self.cx.place_pretty(place) + } /// Get the resulting type of binary operation. - fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty; + pub(crate) fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty { + self.cx.binop_ty(bin_op, rhs, lhs) + } /// Get the resulting type of unary operation. - fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty; + pub(crate) fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty { + self.cx.unop_ty(un_op, arg) + } /// Get all associated items of a definition. - fn associated_items(&self, def_id: DefId) -> AssocItems; + pub(crate) fn associated_items(&self, def_id: DefId) -> AssocItems { + self.cx.associated_items(def_id) + } } -// A thread local variable that stores a pointer to the tables mapping between TyCtxt -// datastructures and stable MIR datastructures +// A thread local variable that stores a pointer to [`SmirInterface`]. scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>); -pub fn run(context: &dyn Context, f: F) -> Result +pub(crate) fn run<'tcx, T, F>(interface: &SmirInterface<'tcx>, f: F) -> Result where F: FnOnce() -> T, { if TLV.is_set() { Err(Error::from("StableMIR already running")) } else { - let ptr: *const () = (&raw const context) as _; + let ptr: *const () = (interface as *const SmirInterface<'tcx>) as *const (); TLV.set(&Cell::new(ptr), || Ok(f())) } } -/// Execute the given function with access the compiler [Context]. +/// Execute the given function with access the [`SmirInterface`]. /// -/// I.e., This function will load the current context and calls a function with it. +/// I.e., This function will load the current interface 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 { +pub(crate) fn with(f: impl FnOnce(&SmirInterface<'_>) -> R) -> R { assert!(TLV.is_set()); TLV.with(|tlv| { let ptr = tlv.get(); assert!(!ptr.is_null()); - f(unsafe { *(ptr as *const &dyn Context) }) + f(unsafe { &*(ptr as *const SmirInterface<'_>) }) }) }