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