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