1 use rustc_hir::def_id::CrateNum;
2 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
3 use rustc_middle::mir::interpret::Allocation;
4 use rustc_middle::ty::{
6 print::{PrettyPrinter, Print, Printer},
7 subst::{GenericArg, GenericArgKind},
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.
50 | ty::Dynamic(_, _) => self.pretty_print_type(ty),
52 // Placeholders (all printed as `_` to uniformize them).
53 ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error => {
58 // Types with identity (print the module path).
59 ty::Adt(&ty::AdtDef { did: def_id, .. }, substs)
60 | ty::FnDef(def_id, substs)
61 | ty::Opaque(def_id, substs)
62 | ty::Projection(ty::ProjectionTy { item_def_id: def_id, substs })
63 | ty::Closure(def_id, substs)
64 | ty::Generator(def_id, substs, _) => self.print_def_path(def_id, substs),
65 ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
67 ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
71 fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
72 self.pretty_print_const(ct, false)
75 fn print_dyn_existential(
77 predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
78 ) -> Result<Self::DynExistential, Self::Error> {
85 self = p.print(self)?;
90 fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
91 self.path.push_str(&self.tcx.original_crate_name(cnum).as_str());
98 trait_ref: Option<ty::TraitRef<'tcx>>,
99 ) -> Result<Self::Path, Self::Error> {
100 self.pretty_path_qualified(self_ty, trait_ref)
105 print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
106 _disambiguated_data: &DisambiguatedDefPathData,
108 trait_ref: Option<ty::TraitRef<'tcx>>,
109 ) -> Result<Self::Path, Self::Error> {
110 self.pretty_path_append_impl(
112 cx = print_prefix(cx)?;
114 cx.path.push_str("::");
125 print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
126 disambiguated_data: &DisambiguatedDefPathData,
127 ) -> Result<Self::Path, Self::Error> {
128 self = print_prefix(self)?;
130 // Skip `::{{constructor}}` on tuple/unit structs.
131 if disambiguated_data.data == DefPathData::Ctor {
135 self.path.push_str("::");
137 self.path.push_str(&disambiguated_data.data.as_symbol().as_str());
141 fn path_generic_args(
143 print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
144 args: &[GenericArg<'tcx>],
145 ) -> Result<Self::Path, Self::Error> {
146 self = print_prefix(self)?;
147 let args = args.iter().cloned().filter(|arg| match arg.unpack() {
148 GenericArgKind::Lifetime(_) => false,
151 if args.clone().next().is_some() {
152 self.generic_delimiters(|cx| cx.comma_sep(args))
159 impl PrettyPrinter<'tcx> for AbsolutePathPrinter<'tcx> {
160 fn region_should_not_be_omitted(&self, _region: ty::Region<'_>) -> bool {
163 fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error>
165 T: Print<'tcx, Self, Output = Self, Error = Self::Error>,
167 if let Some(first) = elems.next() {
168 self = first.print(self)?;
170 self.path.push_str(", ");
171 self = elem.print(self)?;
177 fn generic_delimiters(
179 f: impl FnOnce(Self) -> Result<Self, Self::Error>,
180 ) -> Result<Self, Self::Error> {
191 impl Write for AbsolutePathPrinter<'_> {
192 fn write_str(&mut self, s: &str) -> std::fmt::Result {
193 self.path.push_str(s);
198 /// Directly returns an `Allocation` containing an absolute path representation of the given type.
199 crate fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation {
200 let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
201 let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes());
202 tcx.intern_const_alloc(alloc)