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