stable_mir/
crate_def.rs

1//! Module that define a common trait for things that represent a crate definition,
2//! such as, a function, a trait, an enum, and any other definitions.
3
4use serde::Serialize;
5
6use crate::ty::{GenericArgs, Span, Ty};
7use crate::{Crate, Symbol, with};
8
9/// A unique identification number for each item accessible for the current compilation unit.
10#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
11pub struct DefId(pub(crate) usize);
12
13/// A trait for retrieving information about a particular definition.
14///
15/// Implementors must provide the implementation of `def_id` which will be used to retrieve
16/// information about a crate's definition.
17pub trait CrateDef {
18    /// Retrieve the unique identifier for the current definition.
19    fn def_id(&self) -> DefId;
20
21    /// Return the fully qualified name of the current definition.
22    fn name(&self) -> Symbol {
23        let def_id = self.def_id();
24        with(|cx| cx.def_name(def_id, false))
25    }
26
27    /// Return a trimmed name of this definition.
28    ///
29    /// This can be used to print more user friendly diagnostic messages.
30    ///
31    /// If a symbol name can only be imported from one place for a type, and as
32    /// long as it was not glob-imported anywhere in the current crate, we trim its
33    /// path and print only the name.
34    ///
35    /// For example, this function may shorten `std::vec::Vec` to just `Vec`,
36    /// as long as there is no other `Vec` importable anywhere.
37    fn trimmed_name(&self) -> Symbol {
38        let def_id = self.def_id();
39        with(|cx| cx.def_name(def_id, true))
40    }
41
42    /// Return information about the crate where this definition is declared.
43    ///
44    /// This will return the crate number and its name.
45    fn krate(&self) -> Crate {
46        let def_id = self.def_id();
47        with(|cx| cx.krate(def_id))
48    }
49
50    /// Return the span of this definition.
51    fn span(&self) -> Span {
52        let def_id = self.def_id();
53        with(|cx| cx.span_of_an_item(def_id))
54    }
55
56    /// Return attributes with the given attribute name.
57    ///
58    /// Single segmented name like `#[inline]` is specified as `&["inline".to_string()]`.
59    /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`.
60    fn attrs_by_path(&self, attr: &[Symbol]) -> Vec<Attribute> {
61        let def_id = self.def_id();
62        with(|cx| cx.get_attrs_by_path(def_id, attr))
63    }
64
65    /// Return all attributes of this definition.
66    fn all_attrs(&self) -> Vec<Attribute> {
67        let def_id = self.def_id();
68        with(|cx| cx.get_all_attrs(def_id))
69    }
70}
71
72/// A trait that can be used to retrieve a definition's type.
73///
74/// Note that not every CrateDef has a type `Ty`. They should not implement this trait.
75pub trait CrateDefType: CrateDef {
76    /// Returns the type of this crate item.
77    fn ty(&self) -> Ty {
78        with(|cx| cx.def_ty(self.def_id()))
79    }
80
81    /// Retrieve the type of this definition by instantiating and normalizing it with `args`.
82    ///
83    /// This will panic if instantiation fails.
84    fn ty_with_args(&self, args: &GenericArgs) -> Ty {
85        with(|cx| cx.def_ty_with_args(self.def_id(), args))
86    }
87}
88
89#[derive(Clone, Debug, PartialEq, Eq)]
90pub struct Attribute {
91    value: String,
92    span: Span,
93}
94
95impl Attribute {
96    pub fn new(value: String, span: Span) -> Attribute {
97        Attribute { value, span }
98    }
99
100    /// Get the span of this attribute.
101    pub fn span(&self) -> Span {
102        self.span
103    }
104
105    /// Get the string representation of this attribute.
106    pub fn as_str(&self) -> &str {
107        &self.value
108    }
109}
110
111macro_rules! crate_def {
112    ( $(#[$attr:meta])*
113      $vis:vis $name:ident $(;)?
114    ) => {
115        $(#[$attr])*
116        #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
117        $vis struct $name(pub DefId);
118
119        impl CrateDef for $name {
120            fn def_id(&self) -> DefId {
121                self.0
122            }
123        }
124    };
125}
126
127macro_rules! crate_def_with_ty {
128    ( $(#[$attr:meta])*
129      $vis:vis $name:ident $(;)?
130    ) => {
131        $(#[$attr])*
132        #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
133        $vis struct $name(pub DefId);
134
135        impl CrateDef for $name {
136            fn def_id(&self) -> DefId {
137                self.0
138            }
139        }
140
141        impl CrateDefType for $name {}
142    };
143}