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