diff options
Diffstat (limited to 'compiler/stable_mir/src/lib.rs')
-rw-r--r-- | compiler/stable_mir/src/lib.rs | 150 |
1 files changed, 94 insertions, 56 deletions
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 104985493..f316671b2 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -17,22 +17,29 @@ //! The goal is to eventually be published on //! [crates.io](https://crates.io). +use crate::mir::mono::InstanceDef; +use crate::mir::Body; use std::cell::Cell; use std::fmt; use std::fmt::Debug; use self::ty::{ - GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind, + GenericPredicates, Generics, ImplDef, ImplTrait, IndexedVal, LineInfo, Span, TraitDecl, + TraitDef, Ty, TyKind, }; #[macro_use] extern crate scoped_tls; -pub mod fold; +pub mod error; pub mod mir; pub mod ty; pub mod visitor; +pub use error::*; +use mir::mono::Instance; +use ty::{FnDef, GenericArgs}; + /// Use String for now but we should replace it. pub type Symbol = String; @@ -41,7 +48,7 @@ pub type CrateNum = usize; /// A unique identification number for each item accessible for the current compilation unit. #[derive(Clone, Copy, PartialEq, Eq)] -pub struct DefId(pub usize); +pub struct DefId(usize); impl Debug for DefId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -52,9 +59,28 @@ impl Debug for DefId { } } +impl IndexedVal for DefId { + fn to_val(index: usize) -> Self { + DefId(index) + } + + fn to_index(&self) -> usize { + self.0 + } +} + /// A unique identification number for each provenance #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct AllocId(pub usize); +pub struct AllocId(usize); + +impl IndexedVal for AllocId { + fn to_val(index: usize) -> Self { + AllocId(index) + } + fn to_index(&self) -> usize { + self.0 + } +} /// A list of crate items. pub type CrateItems = Vec<CrateItem>; @@ -65,20 +91,6 @@ pub type TraitDecls = Vec<TraitDef>; /// A list of impl trait decls. pub type ImplTraitDecls = Vec<ImplDef>; -/// An error type used to represent an error that has already been reported by the compiler. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum CompilerError<T> { - /// Internal compiler error (I.e.: Compiler crashed). - ICE, - /// Compilation failed. - CompilationFailed, - /// Compilation was interrupted. - Interrupted(T), - /// Compilation skipped. This happens when users invoke rustc to retrieve information such as - /// --version. - Skipped, -} - /// Holds information about a crate. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Crate { @@ -88,11 +100,10 @@ pub struct Crate { } pub type DefKind = Opaque; +pub type Filename = Opaque; /// Holds information about an item in the crate. -/// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to -/// use this item. -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct CrateItem(pub DefId); impl CrateItem { @@ -111,6 +122,10 @@ impl CrateItem { pub fn kind(&self) -> DefKind { with(|cx| cx.def_kind(self.0)) } + + pub fn requires_monomorphization(&self) -> bool { + with(|cx| cx.requires_monomorphization(self.0)) + } } /// Return the function where execution starts if the current @@ -125,9 +140,9 @@ pub fn local_crate() -> Crate { with(|cx| cx.local_crate()) } -/// Try to find a crate with the given name. -pub fn find_crate(name: &str) -> Option<Crate> { - with(|cx| cx.find_crate(name)) +/// Try to find a crate or crates if multiple crates exist from given name. +pub fn find_crates(name: &str) -> Vec<Crate> { + with(|cx| cx.find_crates(name)) } /// Try to find a crate with the given name. @@ -157,72 +172,95 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait { } pub trait Context { - fn entry_fn(&mut self) -> Option<CrateItem>; + fn entry_fn(&self) -> Option<CrateItem>; /// Retrieve all items of the local crate that have a MIR associated with them. - fn all_local_items(&mut self) -> CrateItems; - fn mir_body(&mut self, item: DefId) -> mir::Body; - fn all_trait_decls(&mut self) -> TraitDecls; - fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl; - fn all_trait_impls(&mut self) -> ImplTraitDecls; - fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait; - fn generics_of(&mut self, def_id: DefId) -> Generics; - fn predicates_of(&mut self, def_id: DefId) -> GenericPredicates; - fn explicit_predicates_of(&mut self, def_id: DefId) -> GenericPredicates; + 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<Crate>; /// Find a crate with the given name. - fn find_crate(&self, name: &str) -> Option<Crate>; + fn find_crates(&self, name: &str) -> Vec<Crate>; - /// Prints the name of given `DefId` + /// Returns the name of given `DefId` fn name_of_def_id(&self, def_id: DefId) -> String; - /// Prints a human readable form of `Span` - fn print_span(&self, span: Span) -> String; + /// Returns printable, human readable form of `Span` + fn span_to_string(&self, span: Span) -> String; - /// Prints the kind of given `DefId` - fn def_kind(&mut self, def_id: DefId) -> DefKind; + /// 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 def_kind(&self, def_id: DefId) -> DefKind; /// `Span` of an item - fn span_of_an_item(&mut self, def_id: DefId) -> Span; + fn span_of_an_item(&self, def_id: DefId) -> Span; /// Obtain the representation of a type. - fn ty_kind(&mut self, ty: Ty) -> TyKind; + fn ty_kind(&self, ty: Ty) -> TyKind; + + /// Get the body of an Instance. + /// FIXME: Monomorphize the body. + fn instance_body(&self, instance: InstanceDef) -> Body; - /// Create a new `Ty` from scratch without information from rustc. - fn mk_ty(&mut self, kind: TyKind) -> Ty; + /// 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) -> String; + + /// 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<Instance>; } // 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<*mut ()>); +scoped_thread_local! (static TLV: Cell<*const ()>); -pub fn run(mut context: impl Context, f: impl FnOnce()) { +pub fn run(context: &dyn Context, f: impl FnOnce()) { assert!(!TLV.is_set()); - fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) { - let ptr: *mut () = &mut context as *mut &mut _ as _; - TLV.set(&Cell::new(ptr), || { - f(); - }); - } - g(&mut context, f); + let ptr: *const () = &context as *const &_ as _; + TLV.set(&Cell::new(ptr), || { + f(); + }); } /// Loads the current context and calls a function with it. /// Do not nest these, as that will ICE. -pub fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R { +pub fn with<R>(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 *mut &mut dyn Context) }) + f(unsafe { *(ptr as *const &dyn Context) }) }) } /// A type that provides internal information but that can still be used for debug purpose. -#[derive(Clone)] +#[derive(Clone, Eq, PartialEq)] pub struct Opaque(String); impl std::fmt::Display for Opaque { |