Skip to content

Add common trait for crate definitions #118215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions compiler/rustc_smir/src/rustc_internal/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use stable_mir::mir::alloc::AllocId;
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
use stable_mir::ty::{
AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const,
ExistentialTraitRef, FloatTy, GenericArgKind, GenericArgs, IntTy, Region, RigidTy, TraitRef,
Ty, UintTy,
ExistentialTraitRef, FloatTy, GenericArgKind, GenericArgs, IntTy, Region, RigidTy, Span,
TraitRef, Ty, UintTy,
};
use stable_mir::{CrateItem, DefId};

Expand Down Expand Up @@ -279,6 +279,14 @@ impl<'tcx> RustcInternal<'tcx> for AdtDef {
}
}

impl<'tcx> RustcInternal<'tcx> for Span {
type T = rustc_span::Span;

fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
tables[*self]
}
}

impl<'tcx, T> RustcInternal<'tcx> for &T
where
T: RustcInternal<'tcx>,
Expand Down
37 changes: 32 additions & 5 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ 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_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_target::abi::FieldIdx;
Expand All @@ -28,7 +29,7 @@ use stable_mir::ty::{
EarlyParamRegion, FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability,
RigidTy, Span, TyKind, UintTy,
};
use stable_mir::{self, opaque, Context, CrateItem, Error, Filename, ItemKind};
use stable_mir::{self, opaque, Context, Crate, CrateItem, Error, Filename, ItemKind, Symbol};
use std::cell::RefCell;
use tracing::debug;

Expand Down Expand Up @@ -61,9 +62,18 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
crates
}

fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String {
fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol {
let tables = self.0.borrow();
tables.tcx.def_path_str(tables[def_id])
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 {
Expand Down Expand Up @@ -240,12 +250,29 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
tables.create_def_id(def_id)
}

fn instance_mangled_name(&self, def: InstanceDef) -> String {
fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol {
let tables = self.0.borrow_mut();
let instance = tables.instances[def];
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<char>::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];
Expand Down
69 changes: 69 additions & 0 deletions compiler/stable_mir/src/crate_def.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//! Module that define a common trait for things that represent a crate definition,
//! such as, a function, a trait, an enum, and any other definitions.

use crate::ty::Span;
use crate::{with, Crate, Symbol};

/// A unique identification number for each item accessible for the current compilation unit.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct DefId(pub(crate) usize);

/// A trait for retrieving information about a particular definition.
///
/// Implementors must provide the implementation of `def_id` which will be used to retrieve
/// information about a crate's definition.
pub trait CrateDef {
/// Retrieve the unique identifier for the current definition.
fn def_id(&self) -> DefId;

/// Return the fully qualified name of the current definition.
fn name(&self) -> Symbol {
let def_id = self.def_id();
with(|cx| cx.def_name(def_id, false))
}

/// Return a trimmed name of this definition.
///
/// This can be used to print more user friendly diagnostic messages.
///
/// If a symbol name can only be imported from one place for a type, and as
/// long as it was not glob-imported anywhere in the current crate, we trim its
/// path and print only the name.
///
/// For example, this function may shorten `std::vec::Vec` to just `Vec`,
/// as long as there is no other `Vec` importable anywhere.
fn trimmed_name(&self) -> Symbol {
let def_id = self.def_id();
with(|cx| cx.def_name(def_id, true))
}

/// Return information about the crate where this definition is declared.
///
/// This will return the crate number and its name.
fn krate(&self) -> Crate {
let def_id = self.def_id();
with(|cx| cx.krate(def_id))
}

/// Return the span of this definition.
fn span(&self) -> Span {
let def_id = self.def_id();
with(|cx| cx.span_of_an_item(def_id))
}
}

macro_rules! crate_def {
( $(#[$attr:meta])*
$vis:vis $name:ident $(;)?
) => {
$(#[$attr])*
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
$vis struct $name(pub DefId);

impl CrateDef for $name {
fn def_id(&self) -> DefId {
self.0
}
}
};
}
27 changes: 13 additions & 14 deletions compiler/stable_mir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,16 @@ use self::ty::{
#[macro_use]
extern crate scoped_tls;

#[macro_use]
pub mod crate_def;
#[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;
Expand All @@ -51,15 +55,11 @@ pub type Symbol = String;
/// The number that identifies a crate.
pub type CrateNum = usize;

/// A unique identification number for each item accessible for the current compilation unit.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct DefId(usize);

impl Debug for DefId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DefId")
.field("id", &self.0)
.field("name", &with(|cx| cx.name_of_def_id(*self)))
.field("name", &with(|cx| cx.def_name(*self, false)))
.finish()
}
}
Expand Down Expand Up @@ -100,9 +100,10 @@ pub enum ItemKind {

pub type Filename = String;

/// Holds information about an item in the crate.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct CrateItem(pub DefId);
crate_def! {
/// Holds information about an item in a crate.
pub CrateItem;
}

impl CrateItem {
pub fn body(&self) -> mir::Body {
Expand All @@ -113,10 +114,6 @@ impl CrateItem {
with(|cx| cx.span_of_an_item(self.0))
}

pub fn name(&self) -> String {
with(|cx| cx.name_of_def_id(self.0))
}

pub fn kind(&self) -> ItemKind {
with(|cx| cx.item_kind(*self))
}
Expand Down Expand Up @@ -205,7 +202,7 @@ pub trait Context {
fn find_crates(&self, name: &str) -> Vec<Crate>;

/// Returns the name of given `DefId`
fn name_of_def_id(&self, def_id: DefId) -> String;
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;
Expand Down Expand Up @@ -260,7 +257,7 @@ pub trait Context {
fn instance_def_id(&self, instance: InstanceDef) -> DefId;

/// Get the instance mangled name.
fn instance_mangled_name(&self, instance: InstanceDef) -> String;
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.
Expand Down Expand Up @@ -294,6 +291,8 @@ pub trait Context {

/// Retrieve the id for the virtual table.
fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option<AllocId>;
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
Expand Down
32 changes: 28 additions & 4 deletions compiler/stable_mir/src/mir/mono.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::crate_def::CrateDef;
use crate::mir::Body;
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque};
use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol};
use std::fmt::{Debug, Formatter};

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -47,10 +48,29 @@ impl Instance {
with(|context| context.instance_ty(self.def))
}

pub fn mangled_name(&self) -> String {
/// Retrieve the instance's mangled name used for calling the given instance.
///
/// This will also look up the correct name of instances from upstream crates.
pub fn mangled_name(&self) -> Symbol {
with(|context| context.instance_mangled_name(self.def))
}

/// Retrieve the instance name for diagnostic messages.
///
/// This will return the specialized name, e.g., `std::vec::Vec<u8>::new`.
pub fn name(&self) -> Symbol {
with(|context| context.instance_name(self.def, false))
}

/// Return a trimmed name of the given instance including its args.
///
/// If a symbol name can only be imported from one place for a type, and as
/// long as it was not glob-imported anywhere in the current crate, we trim its
/// path and print only the name.
pub fn trimmed_name(&self) -> Symbol {
with(|context| context.instance_name(self.def, true))
}

/// Resolve an instance starting from a function definition and generic arguments.
pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> {
with(|context| {
Expand Down Expand Up @@ -104,6 +124,8 @@ impl TryFrom<CrateItem> for Instance {

fn try_from(item: CrateItem) -> Result<Self, Self::Error> {
with(|context| {
// FIXME(celinval):
// - Return `Err` if instance does not have a body.
if !context.requires_monomorphization(item.0) {
Ok(context.mono_instance(item))
} else {
Expand Down Expand Up @@ -148,8 +170,10 @@ impl From<StaticDef> for CrateItem {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct InstanceDef(usize);

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub struct StaticDef(pub DefId);
crate_def! {
/// Holds information about a static variable definition.
pub StaticDef;
}

impl TryFrom<CrateItem> for StaticDef {
type Error = crate::Error;
Expand Down
1 change: 1 addition & 0 deletions compiler/stable_mir/src/mir/pretty.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::crate_def::CrateDef;
use crate::mir::{Operand, Rvalue, StatementKind};
use crate::ty::{DynKind, FloatTy, IntTy, RigidTy, TyKind, UintTy};
use crate::{with, Body, CrateItem, Mutability};
Expand Down
Loading