]>
Commit | Line | Data |
---|---|---|
5e7ed085 | 1 | use rustc_data_structures::intern::Interned; |
ba9703b0 | 2 | use rustc_hir::def_id::CrateNum; |
17df50a5 | 3 | use rustc_hir::definitions::DisambiguatedDefPathData; |
ba9703b0 | 4 | use rustc_middle::ty::{ |
dc9dc135 | 5 | self, |
487cf647 | 6 | print::{PrettyPrinter, Print, Printer}, |
dfeec247 XL |
7 | subst::{GenericArg, GenericArgKind}, |
8 | Ty, TyCtxt, | |
dc9dc135 | 9 | }; |
dc9dc135 | 10 | use std::fmt::Write; |
dc9dc135 XL |
11 | |
12 | struct AbsolutePathPrinter<'tcx> { | |
13 | tcx: TyCtxt<'tcx>, | |
14 | path: String, | |
15 | } | |
16 | ||
17 | impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { | |
18 | type Error = std::fmt::Error; | |
19 | ||
20 | type Path = Self; | |
21 | type Region = Self; | |
22 | type Type = Self; | |
23 | type DynExistential = Self; | |
24 | type Const = Self; | |
25 | ||
26 | fn tcx(&self) -> TyCtxt<'tcx> { | |
27 | self.tcx | |
28 | } | |
29 | ||
30 | fn print_region(self, _region: ty::Region<'_>) -> Result<Self::Region, Self::Error> { | |
31 | Ok(self) | |
32 | } | |
33 | ||
34 | fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { | |
1b1a35ee | 35 | match *ty.kind() { |
dc9dc135 | 36 | // Types without identity. |
dfeec247 | 37 | ty::Bool |
dc9dc135 XL |
38 | | ty::Char |
39 | | ty::Int(_) | |
40 | | ty::Uint(_) | |
41 | | ty::Float(_) | |
42 | | ty::Str | |
43 | | ty::Array(_, _) | |
44 | | ty::Slice(_) | |
45 | | ty::RawPtr(_) | |
46 | | ty::Ref(_, _, _) | |
47 | | ty::FnPtr(_) | |
48 | | ty::Never | |
49 | | ty::Tuple(_) | |
f2b60f7d | 50 | | ty::Dynamic(_, _, _) => self.pretty_print_type(ty), |
dc9dc135 XL |
51 | |
52 | // Placeholders (all printed as `_` to uniformize them). | |
f035d41b | 53 | ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => { |
dc9dc135 XL |
54 | write!(self, "_")?; |
55 | Ok(self) | |
56 | } | |
57 | ||
58 | // Types with identity (print the module path). | |
5e7ed085 | 59 | ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), substs) |
dc9dc135 | 60 | | ty::FnDef(def_id, substs) |
9c376795 | 61 | | ty::Alias(_, ty::AliasTy { def_id, substs, .. }) |
e74abb32 XL |
62 | | ty::Closure(def_id, substs) |
63 | | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs), | |
dc9dc135 XL |
64 | ty::Foreign(def_id) => self.print_def_path(def_id, &[]), |
65 | ||
dfeec247 | 66 | ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"), |
9ffffee4 | 67 | ty::GeneratorWitnessMIR(..) => bug!("type_name: unexpected `GeneratorWitnessMIR`"), |
dc9dc135 XL |
68 | } |
69 | } | |
70 | ||
5099ac24 | 71 | fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> { |
dfeec247 | 72 | self.pretty_print_const(ct, false) |
dc9dc135 XL |
73 | } |
74 | ||
75 | fn print_dyn_existential( | |
487cf647 FG |
76 | self, |
77 | predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, | |
dc9dc135 | 78 | ) -> Result<Self::DynExistential, Self::Error> { |
487cf647 | 79 | self.pretty_print_dyn_existential(predicates) |
dc9dc135 XL |
80 | } |
81 | ||
82 | fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> { | |
a2a8927a | 83 | self.path.push_str(self.tcx.crate_name(cnum).as_str()); |
dc9dc135 XL |
84 | Ok(self) |
85 | } | |
86 | ||
87 | fn path_qualified( | |
88 | self, | |
89 | self_ty: Ty<'tcx>, | |
90 | trait_ref: Option<ty::TraitRef<'tcx>>, | |
91 | ) -> Result<Self::Path, Self::Error> { | |
92 | self.pretty_path_qualified(self_ty, trait_ref) | |
93 | } | |
94 | ||
95 | fn path_append_impl( | |
96 | self, | |
97 | print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, | |
98 | _disambiguated_data: &DisambiguatedDefPathData, | |
99 | self_ty: Ty<'tcx>, | |
100 | trait_ref: Option<ty::TraitRef<'tcx>>, | |
101 | ) -> Result<Self::Path, Self::Error> { | |
102 | self.pretty_path_append_impl( | |
103 | |mut cx| { | |
104 | cx = print_prefix(cx)?; | |
105 | ||
106 | cx.path.push_str("::"); | |
107 | ||
108 | Ok(cx) | |
109 | }, | |
110 | self_ty, | |
111 | trait_ref, | |
112 | ) | |
113 | } | |
114 | ||
115 | fn path_append( | |
116 | mut self, | |
117 | print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, | |
118 | disambiguated_data: &DisambiguatedDefPathData, | |
119 | ) -> Result<Self::Path, Self::Error> { | |
120 | self = print_prefix(self)?; | |
121 | ||
1b1a35ee | 122 | write!(self.path, "::{}", disambiguated_data.data).unwrap(); |
dc9dc135 | 123 | |
dc9dc135 XL |
124 | Ok(self) |
125 | } | |
126 | ||
127 | fn path_generic_args( | |
128 | mut self, | |
129 | print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>, | |
e74abb32 | 130 | args: &[GenericArg<'tcx>], |
dc9dc135 XL |
131 | ) -> Result<Self::Path, Self::Error> { |
132 | self = print_prefix(self)?; | |
3c0e092e XL |
133 | let args = |
134 | args.iter().cloned().filter(|arg| !matches!(arg.unpack(), GenericArgKind::Lifetime(_))); | |
dc9dc135 XL |
135 | if args.clone().next().is_some() { |
136 | self.generic_delimiters(|cx| cx.comma_sep(args)) | |
137 | } else { | |
138 | Ok(self) | |
139 | } | |
140 | } | |
141 | } | |
ba9703b0 | 142 | |
a2a8927a | 143 | impl<'tcx> PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> { |
5e7ed085 | 144 | fn should_print_region(&self, _region: ty::Region<'_>) -> bool { |
dc9dc135 XL |
145 | false |
146 | } | |
147 | fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error> | |
148 | where | |
149 | T: Print<'tcx, Self, Output = Self, Error = Self::Error>, | |
150 | { | |
151 | if let Some(first) = elems.next() { | |
152 | self = first.print(self)?; | |
153 | for elem in elems { | |
154 | self.path.push_str(", "); | |
155 | self = elem.print(self)?; | |
156 | } | |
157 | } | |
158 | Ok(self) | |
159 | } | |
160 | ||
161 | fn generic_delimiters( | |
162 | mut self, | |
163 | f: impl FnOnce(Self) -> Result<Self, Self::Error>, | |
164 | ) -> Result<Self, Self::Error> { | |
165 | write!(self, "<")?; | |
166 | ||
167 | self = f(self)?; | |
168 | ||
169 | write!(self, ">")?; | |
170 | ||
171 | Ok(self) | |
172 | } | |
487cf647 FG |
173 | |
174 | fn should_print_verbose(&self) -> bool { | |
175 | // `std::any::type_name` should never print verbose type names | |
176 | false | |
177 | } | |
dc9dc135 XL |
178 | } |
179 | ||
180 | impl Write for AbsolutePathPrinter<'_> { | |
181 | fn write_str(&mut self, s: &str) -> std::fmt::Result { | |
ba9703b0 XL |
182 | self.path.push_str(s); |
183 | Ok(()) | |
dc9dc135 XL |
184 | } |
185 | } | |
186 | ||
487cf647 FG |
187 | pub fn type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> String { |
188 | AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path | |
dc9dc135 | 189 | } |