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