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
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#[derive(Clone, Debug, PartialEq, Eq)]
107pub struct Attribute {
108 value: String,
109 span: Span,
110}
111
112impl Attribute {
113 pub fn new(value: String, span: Span) -> Attribute {
114 Attribute { value, span }
115 }
116
117 /// Get the span of this attribute.
118 pub fn span(&self) -> Span {
119 self.span
120 }
121
122 /// Get the string representation of this attribute.
123 pub fn as_str(&self) -> &str {
124 &self.value
125 }
126}
127
128macro_rules! crate_def {
129 ( $(#[$attr:meta])*
130 $vis:vis $name:ident $(;)?
131 ) => {
132 $(#[$attr])*
133 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
134 $vis struct $name(pub DefId);
135
136 impl CrateDef for $name {
137 fn def_id(&self) -> DefId {
138 self.0
139 }
140 }
141 };
142}
143
144macro_rules! crate_def_with_ty {
145 ( $(#[$attr:meta])*
146 $vis:vis $name:ident $(;)?
147 ) => {
148 $(#[$attr])*
149 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
150 $vis struct $name(pub DefId);
151
152 impl CrateDef for $name {
153 fn def_id(&self) -> DefId {
154 self.0
155 }
156 }
157
158 impl CrateDefType for $name {}
159 };
160}