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