3 subst::{UnpackedKind, Kind},
4 print::{Printer, PrettyPrinter, Print},
7 use rustc::hir::map::{DefPathData, DisambiguatedDefPathData};
8 use rustc::hir::def_id::CrateNum;
10 use rustc::mir::interpret::Allocation;
12 struct AbsolutePathPrinter<'tcx> {
17 impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
18 type Error = std::fmt::Error;
23 type DynExistential = Self;
26 fn tcx(&self) -> TyCtxt<'tcx> {
30 fn print_region(self, _region: ty::Region<'_>) -> Result<Self::Region, Self::Error> {
34 fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
36 // Types without identity.
51 => self.pretty_print_type(ty),
53 // Placeholders (all printed as `_` to uniformize them).
64 // Types with identity (print the module path).
65 | ty::Adt(&ty::AdtDef { did: def_id, .. }, substs)
66 | ty::FnDef(def_id, substs)
67 | ty::Opaque(def_id, substs)
68 | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
69 | ty::UnnormalizedProjection(ty::ProjectionTy { item_def_id: def_id, substs })
70 | ty::Closure(def_id, ty::ClosureSubsts { substs })
71 | ty::Generator(def_id, ty::GeneratorSubsts { substs }, _)
72 => self.print_def_path(def_id, substs),
73 ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
75 ty::GeneratorWitness(_) => {
76 bug!("type_name: unexpected `GeneratorWitness`")
83 _: &'tcx ty::Const<'tcx>,
84 ) -> Result<Self::Const, Self::Error> {
85 // don't print constants to the user
89 fn print_dyn_existential(
91 predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
92 ) -> Result<Self::DynExistential, Self::Error> {
99 self = p.print(self)?;
104 fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
105 self.path.push_str(&self.tcx.original_crate_name(cnum).as_str());
112 trait_ref: Option<ty::TraitRef<'tcx>>,
113 ) -> Result<Self::Path, Self::Error> {
114 self.pretty_path_qualified(self_ty, trait_ref)
119 print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
120 _disambiguated_data: &DisambiguatedDefPathData,
122 trait_ref: Option<ty::TraitRef<'tcx>>,
123 ) -> Result<Self::Path, Self::Error> {
124 self.pretty_path_append_impl(
126 cx = print_prefix(cx)?;
128 cx.path.push_str("::");
139 print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
140 disambiguated_data: &DisambiguatedDefPathData,
141 ) -> Result<Self::Path, Self::Error> {
142 self = print_prefix(self)?;
144 // Skip `::{{constructor}}` on tuple/unit structs.
145 match disambiguated_data.data {
146 DefPathData::Ctor => return Ok(self),
150 self.path.push_str("::");
152 self.path.push_str(&disambiguated_data.data.as_interned_str().as_str());
156 fn path_generic_args(
158 print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
160 ) -> Result<Self::Path, Self::Error> {
161 self = print_prefix(self)?;
162 let args = args.iter().cloned().filter(|arg| {
164 UnpackedKind::Lifetime(_) => false,
168 if args.clone().next().is_some() {
169 self.generic_delimiters(|cx| cx.comma_sep(args))
175 impl PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> {
176 fn region_should_not_be_omitted(
178 _region: ty::Region<'_>,
182 fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error>
184 T: Print<'tcx, Self, Output = Self, Error = Self::Error>,
186 if let Some(first) = elems.next() {
187 self = first.print(self)?;
189 self.path.push_str(", ");
190 self = elem.print(self)?;
196 fn generic_delimiters(
198 f: impl FnOnce(Self) -> Result<Self, Self::Error>,
199 ) -> Result<Self, Self::Error> {
210 impl Write for AbsolutePathPrinter<'_> {
211 fn write_str(&mut self, s: &str) -> std::fmt::Result {
212 Ok(self.path.push_str(s))
216 /// Directly returns an `Allocation` containing an absolute path representation of the given type.
217 crate fn alloc_type_name<'tcx>(
220 ) -> &'tcx Allocation {
221 let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
222 let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes());
223 tcx.intern_const_alloc(alloc)