]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/print/pretty.rs
893df1a009cfc26efc48ba94f22f8b1ffb6d9b67
[rust.git] / compiler / rustc_middle / src / ty / print / pretty.rs
1 use crate::mir::interpret::{AllocRange, ConstValue, GlobalAlloc, Pointer, Provenance, Scalar};
2 use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
3 use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable};
4 use rustc_apfloat::ieee::{Double, Single};
5 use rustc_data_structures::fx::FxHashMap;
6 use rustc_data_structures::intern::Interned;
7 use rustc_data_structures::sso::SsoHashSet;
8 use rustc_hir as hir;
9 use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
10 use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE};
11 use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
12 use rustc_hir::ItemKind;
13 use rustc_session::config::TrimmedDefPaths;
14 use rustc_session::cstore::{ExternCrate, ExternCrateSource};
15 use rustc_span::symbol::{kw, Ident, Symbol};
16 use rustc_target::abi::Size;
17 use rustc_target::spec::abi::Abi;
18
19 use std::cell::Cell;
20 use std::char;
21 use std::collections::BTreeMap;
22 use std::convert::TryFrom;
23 use std::fmt::{self, Write as _};
24 use std::iter;
25 use std::ops::{ControlFlow, Deref, DerefMut};
26
27 // `pretty` is a separate module only for organization.
28 use super::*;
29
30 macro_rules! p {
31     (@$lit:literal) => {
32         write!(scoped_cx!(), $lit)?
33     };
34     (@write($($data:expr),+)) => {
35         write!(scoped_cx!(), $($data),+)?
36     };
37     (@print($x:expr)) => {
38         scoped_cx!() = $x.print(scoped_cx!())?
39     };
40     (@$method:ident($($arg:expr),*)) => {
41         scoped_cx!() = scoped_cx!().$method($($arg),*)?
42     };
43     ($($elem:tt $(($($args:tt)*))?),+) => {{
44         $(p!(@ $elem $(($($args)*))?);)+
45     }};
46 }
47 macro_rules! define_scoped_cx {
48     ($cx:ident) => {
49         #[allow(unused_macros)]
50         macro_rules! scoped_cx {
51             () => {
52                 $cx
53             };
54         }
55     };
56 }
57
58 thread_local! {
59     static FORCE_IMPL_FILENAME_LINE: Cell<bool> = const { Cell::new(false) };
60     static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = const { Cell::new(false) };
61     static NO_TRIMMED_PATH: Cell<bool> = const { Cell::new(false) };
62     static NO_QUERIES: Cell<bool> = const { Cell::new(false) };
63     static NO_VISIBLE_PATH: Cell<bool> = const { Cell::new(false) };
64 }
65
66 /// Avoids running any queries during any prints that occur
67 /// during the closure. This may alter the appearance of some
68 /// types (e.g. forcing verbose printing for opaque types).
69 /// This method is used during some queries (e.g. `explicit_item_bounds`
70 /// for opaque types), to ensure that any debug printing that
71 /// occurs during the query computation does not end up recursively
72 /// calling the same query.
73 pub fn with_no_queries<F: FnOnce() -> R, R>(f: F) -> R {
74     NO_QUERIES.with(|no_queries| {
75         let old = no_queries.replace(true);
76         let result = f();
77         no_queries.set(old);
78         result
79     })
80 }
81
82 /// Force us to name impls with just the filename/line number. We
83 /// normally try to use types. But at some points, notably while printing
84 /// cycle errors, this can result in extra or suboptimal error output,
85 /// so this variable disables that check.
86 pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
87     FORCE_IMPL_FILENAME_LINE.with(|force| {
88         let old = force.replace(true);
89         let result = f();
90         force.set(old);
91         result
92     })
93 }
94
95 /// Adds the `crate::` prefix to paths where appropriate.
96 pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
97     SHOULD_PREFIX_WITH_CRATE.with(|flag| {
98         let old = flag.replace(true);
99         let result = f();
100         flag.set(old);
101         result
102     })
103 }
104
105 /// Prevent path trimming if it is turned on. Path trimming affects `Display` impl
106 /// of various rustc types, for example `std::vec::Vec` would be trimmed to `Vec`,
107 /// if no other `Vec` is found.
108 pub fn with_no_trimmed_paths<F: FnOnce() -> R, R>(f: F) -> R {
109     NO_TRIMMED_PATH.with(|flag| {
110         let old = flag.replace(true);
111         let result = f();
112         flag.set(old);
113         result
114     })
115 }
116
117 /// Prevent selection of visible paths. `Display` impl of DefId will prefer visible (public) reexports of types as paths.
118 pub fn with_no_visible_paths<F: FnOnce() -> R, R>(f: F) -> R {
119     NO_VISIBLE_PATH.with(|flag| {
120         let old = flag.replace(true);
121         let result = f();
122         flag.set(old);
123         result
124     })
125 }
126
127 /// The "region highlights" are used to control region printing during
128 /// specific error messages. When a "region highlight" is enabled, it
129 /// gives an alternate way to print specific regions. For now, we
130 /// always print those regions using a number, so something like "`'0`".
131 ///
132 /// Regions not selected by the region highlight mode are presently
133 /// unaffected.
134 #[derive(Copy, Clone)]
135 pub struct RegionHighlightMode<'tcx> {
136     tcx: TyCtxt<'tcx>,
137
138     /// If enabled, when we see the selected region, use "`'N`"
139     /// instead of the ordinary behavior.
140     highlight_regions: [Option<(ty::Region<'tcx>, usize)>; 3],
141
142     /// If enabled, when printing a "free region" that originated from
143     /// the given `ty::BoundRegionKind`, print it as "`'1`". Free regions that would ordinarily
144     /// have names print as normal.
145     ///
146     /// This is used when you have a signature like `fn foo(x: &u32,
147     /// y: &'a u32)` and we want to give a name to the region of the
148     /// reference `x`.
149     highlight_bound_region: Option<(ty::BoundRegionKind, usize)>,
150 }
151
152 impl<'tcx> RegionHighlightMode<'tcx> {
153     pub fn new(tcx: TyCtxt<'tcx>) -> Self {
154         Self {
155             tcx,
156             highlight_regions: Default::default(),
157             highlight_bound_region: Default::default(),
158         }
159     }
160
161     /// If `region` and `number` are both `Some`, invokes
162     /// `highlighting_region`.
163     pub fn maybe_highlighting_region(
164         &mut self,
165         region: Option<ty::Region<'tcx>>,
166         number: Option<usize>,
167     ) {
168         if let Some(k) = region {
169             if let Some(n) = number {
170                 self.highlighting_region(k, n);
171             }
172         }
173     }
174
175     /// Highlights the region inference variable `vid` as `'N`.
176     pub fn highlighting_region(&mut self, region: ty::Region<'tcx>, number: usize) {
177         let num_slots = self.highlight_regions.len();
178         let first_avail_slot =
179             self.highlight_regions.iter_mut().find(|s| s.is_none()).unwrap_or_else(|| {
180                 bug!("can only highlight {} placeholders at a time", num_slots,)
181             });
182         *first_avail_slot = Some((region, number));
183     }
184
185     /// Convenience wrapper for `highlighting_region`.
186     pub fn highlighting_region_vid(&mut self, vid: ty::RegionVid, number: usize) {
187         self.highlighting_region(self.tcx.mk_region(ty::ReVar(vid)), number)
188     }
189
190     /// Returns `Some(n)` with the number to use for the given region, if any.
191     fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
192         self.highlight_regions.iter().find_map(|h| match h {
193             Some((r, n)) if *r == region => Some(*n),
194             _ => None,
195         })
196     }
197
198     /// Highlight the given bound region.
199     /// We can only highlight one bound region at a time. See
200     /// the field `highlight_bound_region` for more detailed notes.
201     pub fn highlighting_bound_region(&mut self, br: ty::BoundRegionKind, number: usize) {
202         assert!(self.highlight_bound_region.is_none());
203         self.highlight_bound_region = Some((br, number));
204     }
205 }
206
207 /// Trait for printers that pretty-print using `fmt::Write` to the printer.
208 pub trait PrettyPrinter<'tcx>:
209     Printer<
210         'tcx,
211         Error = fmt::Error,
212         Path = Self,
213         Region = Self,
214         Type = Self,
215         DynExistential = Self,
216         Const = Self,
217     > + fmt::Write
218 {
219     /// Like `print_def_path` but for value paths.
220     fn print_value_path(
221         self,
222         def_id: DefId,
223         substs: &'tcx [GenericArg<'tcx>],
224     ) -> Result<Self::Path, Self::Error> {
225         self.print_def_path(def_id, substs)
226     }
227
228     fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error>
229     where
230         T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
231     {
232         value.as_ref().skip_binder().print(self)
233     }
234
235     fn wrap_binder<T, F: Fn(&T, Self) -> Result<Self, fmt::Error>>(
236         self,
237         value: &ty::Binder<'tcx, T>,
238         f: F,
239     ) -> Result<Self, Self::Error>
240     where
241         T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
242     {
243         f(value.as_ref().skip_binder(), self)
244     }
245
246     /// Prints comma-separated elements.
247     fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error>
248     where
249         T: Print<'tcx, Self, Output = Self, Error = Self::Error>,
250     {
251         if let Some(first) = elems.next() {
252             self = first.print(self)?;
253             for elem in elems {
254                 self.write_str(", ")?;
255                 self = elem.print(self)?;
256             }
257         }
258         Ok(self)
259     }
260
261     /// Prints `{f: t}` or `{f as t}` depending on the `cast` argument
262     fn typed_value(
263         mut self,
264         f: impl FnOnce(Self) -> Result<Self, Self::Error>,
265         t: impl FnOnce(Self) -> Result<Self, Self::Error>,
266         conversion: &str,
267     ) -> Result<Self::Const, Self::Error> {
268         self.write_str("{")?;
269         self = f(self)?;
270         self.write_str(conversion)?;
271         self = t(self)?;
272         self.write_str("}")?;
273         Ok(self)
274     }
275
276     /// Prints `<...>` around what `f` prints.
277     fn generic_delimiters(
278         self,
279         f: impl FnOnce(Self) -> Result<Self, Self::Error>,
280     ) -> Result<Self, Self::Error>;
281
282     /// Returns `true` if the region should be printed in
283     /// optional positions, e.g., `&'a T` or `dyn Tr + 'b`.
284     /// This is typically the case for all non-`'_` regions.
285     fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool;
286
287     // Defaults (should not be overridden):
288
289     /// If possible, this returns a global path resolving to `def_id` that is visible
290     /// from at least one local module, and returns `true`. If the crate defining `def_id` is
291     /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
292     fn try_print_visible_def_path(self, def_id: DefId) -> Result<(Self, bool), Self::Error> {
293         if NO_VISIBLE_PATH.with(|flag| flag.get()) {
294             return Ok((self, false));
295         }
296
297         let mut callers = Vec::new();
298         self.try_print_visible_def_path_recur(def_id, &mut callers)
299     }
300
301     /// Try to see if this path can be trimmed to a unique symbol name.
302     fn try_print_trimmed_def_path(
303         mut self,
304         def_id: DefId,
305     ) -> Result<(Self::Path, bool), Self::Error> {
306         if !self.tcx().sess.opts.debugging_opts.trim_diagnostic_paths
307             || matches!(self.tcx().sess.opts.trimmed_def_paths, TrimmedDefPaths::Never)
308             || NO_TRIMMED_PATH.with(|flag| flag.get())
309             || SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get())
310         {
311             return Ok((self, false));
312         }
313
314         match self.tcx().trimmed_def_paths(()).get(&def_id) {
315             None => Ok((self, false)),
316             Some(symbol) => {
317                 self.write_str(symbol.as_str())?;
318                 Ok((self, true))
319             }
320         }
321     }
322
323     /// Does the work of `try_print_visible_def_path`, building the
324     /// full definition path recursively before attempting to
325     /// post-process it into the valid and visible version that
326     /// accounts for re-exports.
327     ///
328     /// This method should only be called by itself or
329     /// `try_print_visible_def_path`.
330     ///
331     /// `callers` is a chain of visible_parent's leading to `def_id`,
332     /// to support cycle detection during recursion.
333     ///
334     /// This method returns false if we can't print the visible path, so
335     /// `print_def_path` can fall back on the item's real definition path.
336     fn try_print_visible_def_path_recur(
337         mut self,
338         def_id: DefId,
339         callers: &mut Vec<DefId>,
340     ) -> Result<(Self, bool), Self::Error> {
341         define_scoped_cx!(self);
342
343         debug!("try_print_visible_def_path: def_id={:?}", def_id);
344
345         // If `def_id` is a direct or injected extern crate, return the
346         // path to the crate followed by the path to the item within the crate.
347         if def_id.index == CRATE_DEF_INDEX {
348             let cnum = def_id.krate;
349
350             if cnum == LOCAL_CRATE {
351                 return Ok((self.path_crate(cnum)?, true));
352             }
353
354             // In local mode, when we encounter a crate other than
355             // LOCAL_CRATE, execution proceeds in one of two ways:
356             //
357             // 1. For a direct dependency, where user added an
358             //    `extern crate` manually, we put the `extern
359             //    crate` as the parent. So you wind up with
360             //    something relative to the current crate.
361             // 2. For an extern inferred from a path or an indirect crate,
362             //    where there is no explicit `extern crate`, we just prepend
363             //    the crate name.
364             match self.tcx().extern_crate(def_id) {
365                 Some(&ExternCrate { src, dependency_of, span, .. }) => match (src, dependency_of) {
366                     (ExternCrateSource::Extern(def_id), LOCAL_CRATE) => {
367                         // NOTE(eddyb) the only reason `span` might be dummy,
368                         // that we're aware of, is that it's the `std`/`core`
369                         // `extern crate` injected by default.
370                         // FIXME(eddyb) find something better to key this on,
371                         // or avoid ending up with `ExternCrateSource::Extern`,
372                         // for the injected `std`/`core`.
373                         if span.is_dummy() {
374                             return Ok((self.path_crate(cnum)?, true));
375                         }
376
377                         // Disable `try_print_trimmed_def_path` behavior within
378                         // the `print_def_path` call, to avoid infinite recursion
379                         // in cases where the `extern crate foo` has non-trivial
380                         // parents, e.g. it's nested in `impl foo::Trait for Bar`
381                         // (see also issues #55779 and #87932).
382                         self = with_no_visible_paths(|| self.print_def_path(def_id, &[]))?;
383
384                         return Ok((self, true));
385                     }
386                     (ExternCrateSource::Path, LOCAL_CRATE) => {
387                         return Ok((self.path_crate(cnum)?, true));
388                     }
389                     _ => {}
390                 },
391                 None => {
392                     return Ok((self.path_crate(cnum)?, true));
393                 }
394             }
395         }
396
397         if def_id.is_local() {
398             return Ok((self, false));
399         }
400
401         let visible_parent_map = self.tcx().visible_parent_map(());
402
403         let mut cur_def_key = self.tcx().def_key(def_id);
404         debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key);
405
406         // For a constructor, we want the name of its parent rather than <unnamed>.
407         if let DefPathData::Ctor = cur_def_key.disambiguated_data.data {
408             let parent = DefId {
409                 krate: def_id.krate,
410                 index: cur_def_key
411                     .parent
412                     .expect("`DefPathData::Ctor` / `VariantData` missing a parent"),
413             };
414
415             cur_def_key = self.tcx().def_key(parent);
416         }
417
418         let visible_parent = match visible_parent_map.get(&def_id).cloned() {
419             Some(parent) => parent,
420             None => return Ok((self, false)),
421         };
422
423         let actual_parent = self.tcx().parent(def_id);
424         debug!(
425             "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
426             visible_parent, actual_parent,
427         );
428
429         let mut data = cur_def_key.disambiguated_data.data;
430         debug!(
431             "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}",
432             data, visible_parent, actual_parent,
433         );
434
435         match data {
436             // In order to output a path that could actually be imported (valid and visible),
437             // we need to handle re-exports correctly.
438             //
439             // For example, take `std::os::unix::process::CommandExt`, this trait is actually
440             // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing).
441             //
442             // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is
443             // private so the "true" path to `CommandExt` isn't accessible.
444             //
445             // In this case, the `visible_parent_map` will look something like this:
446             //
447             // (child) -> (parent)
448             // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process`
449             // `std::sys::unix::ext::process` -> `std::sys::unix::ext`
450             // `std::sys::unix::ext` -> `std::os`
451             //
452             // This is correct, as the visible parent of `std::sys::unix::ext` is in fact
453             // `std::os`.
454             //
455             // When printing the path to `CommandExt` and looking at the `cur_def_key` that
456             // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go
457             // to the parent - resulting in a mangled path like
458             // `std::os::ext::process::CommandExt`.
459             //
460             // Instead, we must detect that there was a re-export and instead print `unix`
461             // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To
462             // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with
463             // the visible parent (`std::os`). If these do not match, then we iterate over
464             // the children of the visible parent (as was done when computing
465             // `visible_parent_map`), looking for the specific child we currently have and then
466             // have access to the re-exported name.
467             DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => {
468                 // Item might be re-exported several times, but filter for the one
469                 // that's public and whose identifier isn't `_`.
470                 let reexport = self
471                     .tcx()
472                     .module_children(visible_parent)
473                     .iter()
474                     .filter(|child| child.res.opt_def_id() == Some(def_id))
475                     .find(|child| child.vis.is_public() && child.ident.name != kw::Underscore)
476                     .map(|child| child.ident.name);
477
478                 if let Some(new_name) = reexport {
479                     *name = new_name;
480                 } else {
481                     // There is no name that is public and isn't `_`, so bail.
482                     return Ok((self, false));
483                 }
484             }
485             // Re-exported `extern crate` (#43189).
486             DefPathData::CrateRoot => {
487                 data = DefPathData::TypeNs(self.tcx().crate_name(def_id.krate));
488             }
489             _ => {}
490         }
491         debug!("try_print_visible_def_path: data={:?}", data);
492
493         if callers.contains(&visible_parent) {
494             return Ok((self, false));
495         }
496         callers.push(visible_parent);
497         // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid
498         // knowing ahead of time whether the entire path will succeed or not.
499         // To support printers that do not implement `PrettyPrinter`, a `Vec` or
500         // linked list on the stack would need to be built, before any printing.
501         match self.try_print_visible_def_path_recur(visible_parent, callers)? {
502             (cx, false) => return Ok((cx, false)),
503             (cx, true) => self = cx,
504         }
505         callers.pop();
506
507         Ok((self.path_append(Ok, &DisambiguatedDefPathData { data, disambiguator: 0 })?, true))
508     }
509
510     fn pretty_path_qualified(
511         self,
512         self_ty: Ty<'tcx>,
513         trait_ref: Option<ty::TraitRef<'tcx>>,
514     ) -> Result<Self::Path, Self::Error> {
515         if trait_ref.is_none() {
516             // Inherent impls. Try to print `Foo::bar` for an inherent
517             // impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
518             // anything other than a simple path.
519             match self_ty.kind() {
520                 ty::Adt(..)
521                 | ty::Foreign(_)
522                 | ty::Bool
523                 | ty::Char
524                 | ty::Str
525                 | ty::Int(_)
526                 | ty::Uint(_)
527                 | ty::Float(_) => {
528                     return self_ty.print(self);
529                 }
530
531                 _ => {}
532             }
533         }
534
535         self.generic_delimiters(|mut cx| {
536             define_scoped_cx!(cx);
537
538             p!(print(self_ty));
539             if let Some(trait_ref) = trait_ref {
540                 p!(" as ", print(trait_ref.print_only_trait_path()));
541             }
542             Ok(cx)
543         })
544     }
545
546     fn pretty_path_append_impl(
547         mut self,
548         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
549         self_ty: Ty<'tcx>,
550         trait_ref: Option<ty::TraitRef<'tcx>>,
551     ) -> Result<Self::Path, Self::Error> {
552         self = print_prefix(self)?;
553
554         self.generic_delimiters(|mut cx| {
555             define_scoped_cx!(cx);
556
557             p!("impl ");
558             if let Some(trait_ref) = trait_ref {
559                 p!(print(trait_ref.print_only_trait_path()), " for ");
560             }
561             p!(print(self_ty));
562
563             Ok(cx)
564         })
565     }
566
567     fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
568         define_scoped_cx!(self);
569
570         match *ty.kind() {
571             ty::Bool => p!("bool"),
572             ty::Char => p!("char"),
573             ty::Int(t) => p!(write("{}", t.name_str())),
574             ty::Uint(t) => p!(write("{}", t.name_str())),
575             ty::Float(t) => p!(write("{}", t.name_str())),
576             ty::RawPtr(ref tm) => {
577                 p!(write(
578                     "*{} ",
579                     match tm.mutbl {
580                         hir::Mutability::Mut => "mut",
581                         hir::Mutability::Not => "const",
582                     }
583                 ));
584                 p!(print(tm.ty))
585             }
586             ty::Ref(r, ty, mutbl) => {
587                 p!("&");
588                 if self.region_should_not_be_omitted(r) {
589                     p!(print(r), " ");
590                 }
591                 p!(print(ty::TypeAndMut { ty, mutbl }))
592             }
593             ty::Never => p!("!"),
594             ty::Tuple(ref tys) => {
595                 p!("(", comma_sep(tys.iter()));
596                 if tys.len() == 1 {
597                     p!(",");
598                 }
599                 p!(")")
600             }
601             ty::FnDef(def_id, substs) => {
602                 let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs);
603                 p!(print(sig), " {{", print_value_path(def_id, substs), "}}");
604             }
605             ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
606             ty::Infer(infer_ty) => {
607                 let verbose = self.tcx().sess.verbose();
608                 if let ty::TyVar(ty_vid) = infer_ty {
609                     if let Some(name) = self.infer_ty_name(ty_vid) {
610                         p!(write("{}", name))
611                     } else {
612                         if verbose {
613                             p!(write("{:?}", infer_ty))
614                         } else {
615                             p!(write("{}", infer_ty))
616                         }
617                     }
618                 } else {
619                     if verbose { p!(write("{:?}", infer_ty)) } else { p!(write("{}", infer_ty)) }
620                 }
621             }
622             ty::Error(_) => p!("[type error]"),
623             ty::Param(ref param_ty) => p!(write("{}", param_ty)),
624             ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
625                 ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?,
626                 ty::BoundTyKind::Param(p) => p!(write("{}", p)),
627             },
628             ty::Adt(def, substs) => {
629                 p!(print_def_path(def.did, substs));
630             }
631             ty::Dynamic(data, r) => {
632                 let print_r = self.region_should_not_be_omitted(r);
633                 if print_r {
634                     p!("(");
635                 }
636                 p!("dyn ", print(data));
637                 if print_r {
638                     p!(" + ", print(r), ")");
639                 }
640             }
641             ty::Foreign(def_id) => {
642                 p!(print_def_path(def_id, &[]));
643             }
644             ty::Projection(ref data) => p!(print(data)),
645             ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
646             ty::Opaque(def_id, substs) => {
647                 // FIXME(eddyb) print this with `print_def_path`.
648                 // We use verbose printing in 'NO_QUERIES' mode, to
649                 // avoid needing to call `predicates_of`. This should
650                 // only affect certain debug messages (e.g. messages printed
651                 // from `rustc_middle::ty` during the computation of `tcx.predicates_of`),
652                 // and should have no effect on any compiler output.
653                 if self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()) {
654                     p!(write("Opaque({:?}, {:?})", def_id, substs));
655                     return Ok(self);
656                 }
657
658                 return with_no_queries(|| {
659                     let def_key = self.tcx().def_key(def_id);
660                     if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
661                         p!(write("{}", name));
662                         // FIXME(eddyb) print this with `print_def_path`.
663                         if !substs.is_empty() {
664                             p!("::");
665                             p!(generic_delimiters(|cx| cx.comma_sep(substs.iter())));
666                         }
667                         return Ok(self);
668                     }
669
670                     self.pretty_print_opaque_impl_type(def_id, substs)
671                 });
672             }
673             ty::Str => p!("str"),
674             ty::Generator(did, substs, movability) => {
675                 p!(write("["));
676                 match movability {
677                     hir::Movability::Movable => {}
678                     hir::Movability::Static => p!("static "),
679                 }
680
681                 if !self.tcx().sess.verbose() {
682                     p!("generator");
683                     // FIXME(eddyb) should use `def_span`.
684                     if let Some(did) = did.as_local() {
685                         let span = self.tcx().def_span(did);
686                         p!(write(
687                             "@{}",
688                             // This may end up in stderr diagnostics but it may also be emitted
689                             // into MIR. Hence we use the remapped path if available
690                             self.tcx().sess.source_map().span_to_embeddable_string(span)
691                         ));
692                     } else {
693                         p!(write("@"), print_def_path(did, substs));
694                     }
695                 } else {
696                     p!(print_def_path(did, substs));
697                     p!(" upvar_tys=(");
698                     if !substs.as_generator().is_valid() {
699                         p!("unavailable");
700                     } else {
701                         self = self.comma_sep(substs.as_generator().upvar_tys())?;
702                     }
703                     p!(")");
704
705                     if substs.as_generator().is_valid() {
706                         p!(" ", print(substs.as_generator().witness()));
707                     }
708                 }
709
710                 p!("]")
711             }
712             ty::GeneratorWitness(types) => {
713                 p!(in_binder(&types));
714             }
715             ty::Closure(did, substs) => {
716                 p!(write("["));
717                 if !self.tcx().sess.verbose() {
718                     p!(write("closure"));
719                     // FIXME(eddyb) should use `def_span`.
720                     if let Some(did) = did.as_local() {
721                         if self.tcx().sess.opts.debugging_opts.span_free_formats {
722                             p!("@", print_def_path(did.to_def_id(), substs));
723                         } else {
724                             let span = self.tcx().def_span(did);
725                             p!(write(
726                                 "@{}",
727                                 // This may end up in stderr diagnostics but it may also be emitted
728                                 // into MIR. Hence we use the remapped path if available
729                                 self.tcx().sess.source_map().span_to_embeddable_string(span)
730                             ));
731                         }
732                     } else {
733                         p!(write("@"), print_def_path(did, substs));
734                     }
735                 } else {
736                     p!(print_def_path(did, substs));
737                     if !substs.as_closure().is_valid() {
738                         p!(" closure_substs=(unavailable)");
739                         p!(write(" substs={:?}", substs));
740                     } else {
741                         p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
742                         p!(
743                             " closure_sig_as_fn_ptr_ty=",
744                             print(substs.as_closure().sig_as_fn_ptr_ty())
745                         );
746                         p!(" upvar_tys=(");
747                         self = self.comma_sep(substs.as_closure().upvar_tys())?;
748                         p!(")");
749                     }
750                 }
751                 p!("]");
752             }
753             ty::Array(ty, sz) => {
754                 p!("[", print(ty), "; ");
755                 if self.tcx().sess.verbose() {
756                     p!(write("{:?}", sz));
757                 } else if let ty::ConstKind::Unevaluated(..) = sz.val() {
758                     // Do not try to evaluate unevaluated constants. If we are const evaluating an
759                     // array length anon const, rustc will (with debug assertions) print the
760                     // constant's path. Which will end up here again.
761                     p!("_");
762                 } else if let Some(n) = sz.val().try_to_bits(self.tcx().data_layout.pointer_size) {
763                     p!(write("{}", n));
764                 } else if let ty::ConstKind::Param(param) = sz.val() {
765                     p!(write("{}", param));
766                 } else {
767                     p!("_");
768                 }
769                 p!("]")
770             }
771             ty::Slice(ty) => p!("[", print(ty), "]"),
772         }
773
774         Ok(self)
775     }
776
777     fn pretty_print_opaque_impl_type(
778         mut self,
779         def_id: DefId,
780         substs: &'tcx ty::List<ty::GenericArg<'tcx>>,
781     ) -> Result<Self::Type, Self::Error> {
782         define_scoped_cx!(self);
783
784         // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
785         // by looking up the projections associated with the def_id.
786         let bounds = self.tcx().explicit_item_bounds(def_id);
787
788         let mut traits = BTreeMap::new();
789         let mut fn_traits = BTreeMap::new();
790         let mut is_sized = false;
791
792         for (predicate, _) in bounds {
793             let predicate = predicate.subst(self.tcx(), substs);
794             let bound_predicate = predicate.kind();
795
796             match bound_predicate.skip_binder() {
797                 ty::PredicateKind::Trait(pred) => {
798                     let trait_ref = bound_predicate.rebind(pred.trait_ref);
799
800                     // Don't print + Sized, but rather + ?Sized if absent.
801                     if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
802                         is_sized = true;
803                         continue;
804                     }
805
806                     self.insert_trait_and_projection(trait_ref, None, &mut traits, &mut fn_traits);
807                 }
808                 ty::PredicateKind::Projection(pred) => {
809                     let proj_ref = bound_predicate.rebind(pred);
810                     let trait_ref = proj_ref.required_poly_trait_ref(self.tcx());
811
812                     // Projection type entry -- the def-id for naming, and the ty.
813                     let proj_ty = (proj_ref.projection_def_id(), proj_ref.term());
814
815                     self.insert_trait_and_projection(
816                         trait_ref,
817                         Some(proj_ty),
818                         &mut traits,
819                         &mut fn_traits,
820                     );
821                 }
822                 _ => {}
823             }
824         }
825
826         let mut first = true;
827         // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
828         let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !is_sized;
829
830         p!("impl");
831
832         for (fn_once_trait_ref, entry) in fn_traits {
833             // Get the (single) generic ty (the args) of this FnOnce trait ref.
834             let generics = self.generic_args_to_print(
835                 self.tcx().generics_of(fn_once_trait_ref.def_id()),
836                 fn_once_trait_ref.skip_binder().substs,
837             );
838
839             match (entry.return_ty, generics[0].expect_ty()) {
840                 // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
841                 // a return type.
842                 (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
843                     let name = if entry.fn_trait_ref.is_some() {
844                         "Fn"
845                     } else if entry.fn_mut_trait_ref.is_some() {
846                         "FnMut"
847                     } else {
848                         "FnOnce"
849                     };
850
851                     p!(
852                         write("{}", if first { " " } else { " + " }),
853                         write("{}{}(", if paren_needed { "(" } else { "" }, name)
854                     );
855
856                     for (idx, ty) in arg_tys.tuple_fields().enumerate() {
857                         if idx > 0 {
858                             p!(", ");
859                         }
860                         p!(print(ty));
861                     }
862
863                     p!(")");
864                     if let Term::Ty(ty) = return_ty.skip_binder() {
865                         if !ty.is_unit() {
866                             p!("-> ", print(return_ty));
867                         }
868                     }
869                     p!(write("{}", if paren_needed { ")" } else { "" }));
870
871                     first = false;
872                 }
873                 // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
874                 // trait_refs we collected in the OpaqueFnEntry as normal trait refs.
875                 _ => {
876                     if entry.has_fn_once {
877                         traits.entry(fn_once_trait_ref).or_default().extend(
878                             // Group the return ty with its def id, if we had one.
879                             entry
880                                 .return_ty
881                                 .map(|ty| (self.tcx().lang_items().fn_once_output().unwrap(), ty)),
882                         );
883                     }
884                     if let Some(trait_ref) = entry.fn_mut_trait_ref {
885                         traits.entry(trait_ref).or_default();
886                     }
887                     if let Some(trait_ref) = entry.fn_trait_ref {
888                         traits.entry(trait_ref).or_default();
889                     }
890                 }
891             }
892         }
893
894         // Print the rest of the trait types (that aren't Fn* family of traits)
895         for (trait_ref, assoc_items) in traits {
896             p!(
897                 write("{}", if first { " " } else { " + " }),
898                 print(trait_ref.skip_binder().print_only_trait_name())
899             );
900
901             let generics = self.generic_args_to_print(
902                 self.tcx().generics_of(trait_ref.def_id()),
903                 trait_ref.skip_binder().substs,
904             );
905
906             if !generics.is_empty() || !assoc_items.is_empty() {
907                 p!("<");
908                 let mut first = true;
909
910                 for ty in generics {
911                     if !first {
912                         p!(", ");
913                     }
914                     p!(print(trait_ref.rebind(*ty)));
915                     first = false;
916                 }
917
918                 for (assoc_item_def_id, term) in assoc_items {
919                     if !first {
920                         p!(", ");
921                     }
922                     p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).name));
923
924                     match term.skip_binder() {
925                         Term::Ty(ty) => {
926                             // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
927                             if matches!(
928                               ty.kind(), ty::Projection(ty::ProjectionTy { item_def_id, .. })
929                               if Some(*item_def_id) == self.tcx().lang_items().generator_return()
930                             ) {
931                                 p!("[async output]")
932                             } else {
933                                 p!(print(ty))
934                             }
935                         }
936                         Term::Const(c) => {
937                             p!(print(c));
938                         }
939                     };
940
941                     first = false;
942                 }
943
944                 p!(">");
945             }
946
947             first = false;
948         }
949
950         if !is_sized {
951             p!(write("{}?Sized", if first { " " } else { " + " }));
952         } else if first {
953             p!(" Sized");
954         }
955
956         Ok(self)
957     }
958
959     /// Insert the trait ref and optionally a projection type associated with it into either the
960     /// traits map or fn_traits map, depending on if the trait is in the Fn* family of traits.
961     fn insert_trait_and_projection(
962         &mut self,
963         trait_ref: ty::PolyTraitRef<'tcx>,
964         proj_ty: Option<(DefId, ty::Binder<'tcx, Term<'tcx>>)>,
965         traits: &mut BTreeMap<
966             ty::PolyTraitRef<'tcx>,
967             BTreeMap<DefId, ty::Binder<'tcx, Term<'tcx>>>,
968         >,
969         fn_traits: &mut BTreeMap<ty::PolyTraitRef<'tcx>, OpaqueFnEntry<'tcx>>,
970     ) {
971         let trait_def_id = trait_ref.def_id();
972
973         // If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce
974         // super-trait ref and record it there.
975         if let Some(fn_once_trait) = self.tcx().lang_items().fn_once_trait() {
976             // If we have a FnOnce, then insert it into
977             if trait_def_id == fn_once_trait {
978                 let entry = fn_traits.entry(trait_ref).or_default();
979                 // Optionally insert the return_ty as well.
980                 if let Some((_, ty)) = proj_ty {
981                     entry.return_ty = Some(ty);
982                 }
983                 entry.has_fn_once = true;
984                 return;
985             } else if Some(trait_def_id) == self.tcx().lang_items().fn_mut_trait() {
986                 let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref)
987                     .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
988                     .unwrap();
989
990                 fn_traits.entry(super_trait_ref).or_default().fn_mut_trait_ref = Some(trait_ref);
991                 return;
992             } else if Some(trait_def_id) == self.tcx().lang_items().fn_trait() {
993                 let super_trait_ref = crate::traits::util::supertraits(self.tcx(), trait_ref)
994                     .find(|super_trait_ref| super_trait_ref.def_id() == fn_once_trait)
995                     .unwrap();
996
997                 fn_traits.entry(super_trait_ref).or_default().fn_trait_ref = Some(trait_ref);
998                 return;
999             }
1000         }
1001
1002         // Otherwise, just group our traits and projection types.
1003         traits.entry(trait_ref).or_default().extend(proj_ty);
1004     }
1005
1006     fn pretty_print_bound_var(
1007         &mut self,
1008         debruijn: ty::DebruijnIndex,
1009         var: ty::BoundVar,
1010     ) -> Result<(), Self::Error> {
1011         if debruijn == ty::INNERMOST {
1012             write!(self, "^{}", var.index())
1013         } else {
1014             write!(self, "^{}_{}", debruijn.index(), var.index())
1015         }
1016     }
1017
1018     fn infer_ty_name(&self, _: ty::TyVid) -> Option<String> {
1019         None
1020     }
1021
1022     fn pretty_print_dyn_existential(
1023         mut self,
1024         predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
1025     ) -> Result<Self::DynExistential, Self::Error> {
1026         // Generate the main trait ref, including associated types.
1027         let mut first = true;
1028
1029         if let Some(principal) = predicates.principal() {
1030             self = self.wrap_binder(&principal, |principal, mut cx| {
1031                 define_scoped_cx!(cx);
1032                 p!(print_def_path(principal.def_id, &[]));
1033
1034                 let mut resugared = false;
1035
1036                 // Special-case `Fn(...) -> ...` and resugar it.
1037                 let fn_trait_kind = cx.tcx().fn_trait_kind_from_lang_item(principal.def_id);
1038                 if !cx.tcx().sess.verbose() && fn_trait_kind.is_some() {
1039                     if let ty::Tuple(ref args) = principal.substs.type_at(0).kind() {
1040                         let mut projections = predicates.projection_bounds();
1041                         if let (Some(proj), None) = (projections.next(), projections.next()) {
1042                             let tys: Vec<_> = args.iter().map(|k| k.expect_ty()).collect();
1043                             p!(pretty_fn_sig(
1044                                 &tys,
1045                                 false,
1046                                 proj.skip_binder().term.ty().expect("Return type was a const")
1047                             ));
1048                             resugared = true;
1049                         }
1050                     }
1051                 }
1052
1053                 // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`,
1054                 // in order to place the projections inside the `<...>`.
1055                 if !resugared {
1056                     // Use a type that can't appear in defaults of type parameters.
1057                     let dummy_cx = cx.tcx().mk_ty_infer(ty::FreshTy(0));
1058                     let principal = principal.with_self_ty(cx.tcx(), dummy_cx);
1059
1060                     let args = cx.generic_args_to_print(
1061                         cx.tcx().generics_of(principal.def_id),
1062                         principal.substs,
1063                     );
1064
1065                     // Don't print `'_` if there's no unerased regions.
1066                     let print_regions = args.iter().any(|arg| match arg.unpack() {
1067                         GenericArgKind::Lifetime(r) => !r.is_erased(),
1068                         _ => false,
1069                     });
1070                     let mut args = args.iter().cloned().filter(|arg| match arg.unpack() {
1071                         GenericArgKind::Lifetime(_) => print_regions,
1072                         _ => true,
1073                     });
1074                     let mut projections = predicates.projection_bounds();
1075
1076                     let arg0 = args.next();
1077                     let projection0 = projections.next();
1078                     if arg0.is_some() || projection0.is_some() {
1079                         let args = arg0.into_iter().chain(args);
1080                         let projections = projection0.into_iter().chain(projections);
1081
1082                         p!(generic_delimiters(|mut cx| {
1083                             cx = cx.comma_sep(args)?;
1084                             if arg0.is_some() && projection0.is_some() {
1085                                 write!(cx, ", ")?;
1086                             }
1087                             cx.comma_sep(projections)
1088                         }));
1089                     }
1090                 }
1091                 Ok(cx)
1092             })?;
1093
1094             first = false;
1095         }
1096
1097         define_scoped_cx!(self);
1098
1099         // Builtin bounds.
1100         // FIXME(eddyb) avoid printing twice (needed to ensure
1101         // that the auto traits are sorted *and* printed via cx).
1102         let mut auto_traits: Vec<_> =
1103             predicates.auto_traits().map(|did| (self.tcx().def_path_str(did), did)).collect();
1104
1105         // The auto traits come ordered by `DefPathHash`. While
1106         // `DefPathHash` is *stable* in the sense that it depends on
1107         // neither the host nor the phase of the moon, it depends
1108         // "pseudorandomly" on the compiler version and the target.
1109         //
1110         // To avoid that causing instabilities in compiletest
1111         // output, sort the auto-traits alphabetically.
1112         auto_traits.sort();
1113
1114         for (_, def_id) in auto_traits {
1115             if !first {
1116                 p!(" + ");
1117             }
1118             first = false;
1119
1120             p!(print_def_path(def_id, &[]));
1121         }
1122
1123         Ok(self)
1124     }
1125
1126     fn pretty_fn_sig(
1127         mut self,
1128         inputs: &[Ty<'tcx>],
1129         c_variadic: bool,
1130         output: Ty<'tcx>,
1131     ) -> Result<Self, Self::Error> {
1132         define_scoped_cx!(self);
1133
1134         p!("(", comma_sep(inputs.iter().copied()));
1135         if c_variadic {
1136             if !inputs.is_empty() {
1137                 p!(", ");
1138             }
1139             p!("...");
1140         }
1141         p!(")");
1142         if !output.is_unit() {
1143             p!(" -> ", print(output));
1144         }
1145
1146         Ok(self)
1147     }
1148
1149     fn pretty_print_const(
1150         mut self,
1151         ct: ty::Const<'tcx>,
1152         print_ty: bool,
1153     ) -> Result<Self::Const, Self::Error> {
1154         define_scoped_cx!(self);
1155
1156         if self.tcx().sess.verbose() {
1157             p!(write("Const({:?}: {:?})", ct.val(), ct.ty()));
1158             return Ok(self);
1159         }
1160
1161         macro_rules! print_underscore {
1162             () => {{
1163                 if print_ty {
1164                     self = self.typed_value(
1165                         |mut this| {
1166                             write!(this, "_")?;
1167                             Ok(this)
1168                         },
1169                         |this| this.print_type(ct.ty()),
1170                         ": ",
1171                     )?;
1172                 } else {
1173                     write!(self, "_")?;
1174                 }
1175             }};
1176         }
1177
1178         match ct.val() {
1179             ty::ConstKind::Unevaluated(ty::Unevaluated {
1180                 def,
1181                 substs,
1182                 promoted: Some(promoted),
1183             }) => {
1184                 p!(print_value_path(def.did, substs));
1185                 p!(write("::{:?}", promoted));
1186             }
1187             ty::ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted: None }) => {
1188                 match self.tcx().def_kind(def.did) {
1189                     DefKind::Static | DefKind::Const | DefKind::AssocConst => {
1190                         p!(print_value_path(def.did, substs))
1191                     }
1192                     _ => {
1193                         if def.is_local() {
1194                             let span = self.tcx().def_span(def.did);
1195                             if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) {
1196                                 p!(write("{}", snip))
1197                             } else {
1198                                 print_underscore!()
1199                             }
1200                         } else {
1201                             print_underscore!()
1202                         }
1203                     }
1204                 }
1205             }
1206             ty::ConstKind::Infer(..) => print_underscore!(),
1207             ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
1208             ty::ConstKind::Value(value) => {
1209                 return self.pretty_print_const_value(value, ct.ty(), print_ty);
1210             }
1211
1212             ty::ConstKind::Bound(debruijn, bound_var) => {
1213                 self.pretty_print_bound_var(debruijn, bound_var)?
1214             }
1215             ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
1216             ty::ConstKind::Error(_) => p!("[const error]"),
1217         };
1218         Ok(self)
1219     }
1220
1221     fn pretty_print_const_scalar(
1222         self,
1223         scalar: Scalar,
1224         ty: Ty<'tcx>,
1225         print_ty: bool,
1226     ) -> Result<Self::Const, Self::Error> {
1227         match scalar {
1228             Scalar::Ptr(ptr, _size) => self.pretty_print_const_scalar_ptr(ptr, ty, print_ty),
1229             Scalar::Int(int) => self.pretty_print_const_scalar_int(int, ty, print_ty),
1230         }
1231     }
1232
1233     fn pretty_print_const_scalar_ptr(
1234         mut self,
1235         ptr: Pointer,
1236         ty: Ty<'tcx>,
1237         print_ty: bool,
1238     ) -> Result<Self::Const, Self::Error> {
1239         define_scoped_cx!(self);
1240
1241         let (alloc_id, offset) = ptr.into_parts();
1242         match ty.kind() {
1243             // Byte strings (&[u8; N])
1244             ty::Ref(
1245                 _,
1246                 Ty(Interned(
1247                     ty::TyS {
1248                         kind:
1249                             ty::Array(
1250                                 Ty(Interned(ty::TyS { kind: ty::Uint(ty::UintTy::U8), .. }, _)),
1251                                 ty::Const(Interned(
1252                                     ty::ConstS {
1253                                         val: ty::ConstKind::Value(ConstValue::Scalar(int)),
1254                                         ..
1255                                     },
1256                                     _,
1257                                 )),
1258                             ),
1259                         ..
1260                     },
1261                     _,
1262                 )),
1263                 _,
1264             ) => match self.tcx().get_global_alloc(alloc_id) {
1265                 Some(GlobalAlloc::Memory(alloc)) => {
1266                     let len = int.assert_bits(self.tcx().data_layout.pointer_size);
1267                     let range = AllocRange { start: offset, size: Size::from_bytes(len) };
1268                     if let Ok(byte_str) = alloc.get_bytes(&self.tcx(), range) {
1269                         p!(pretty_print_byte_str(byte_str))
1270                     } else {
1271                         p!("<too short allocation>")
1272                     }
1273                 }
1274                 // FIXME: for statics and functions, we could in principle print more detail.
1275                 Some(GlobalAlloc::Static(def_id)) => p!(write("<static({:?})>", def_id)),
1276                 Some(GlobalAlloc::Function(_)) => p!("<function>"),
1277                 None => p!("<dangling pointer>"),
1278             },
1279             ty::FnPtr(_) => {
1280                 // FIXME: We should probably have a helper method to share code with the "Byte strings"
1281                 // printing above (which also has to handle pointers to all sorts of things).
1282                 match self.tcx().get_global_alloc(alloc_id) {
1283                     Some(GlobalAlloc::Function(instance)) => {
1284                         self = self.typed_value(
1285                             |this| this.print_value_path(instance.def_id(), instance.substs),
1286                             |this| this.print_type(ty),
1287                             " as ",
1288                         )?;
1289                     }
1290                     _ => self = self.pretty_print_const_pointer(ptr, ty, print_ty)?,
1291                 }
1292             }
1293             // Any pointer values not covered by a branch above
1294             _ => {
1295                 self = self.pretty_print_const_pointer(ptr, ty, print_ty)?;
1296             }
1297         }
1298         Ok(self)
1299     }
1300
1301     fn pretty_print_const_scalar_int(
1302         mut self,
1303         int: ScalarInt,
1304         ty: Ty<'tcx>,
1305         print_ty: bool,
1306     ) -> Result<Self::Const, Self::Error> {
1307         define_scoped_cx!(self);
1308
1309         match ty.kind() {
1310             // Bool
1311             ty::Bool if int == ScalarInt::FALSE => p!("false"),
1312             ty::Bool if int == ScalarInt::TRUE => p!("true"),
1313             // Float
1314             ty::Float(ty::FloatTy::F32) => {
1315                 p!(write("{}f32", Single::try_from(int).unwrap()))
1316             }
1317             ty::Float(ty::FloatTy::F64) => {
1318                 p!(write("{}f64", Double::try_from(int).unwrap()))
1319             }
1320             // Int
1321             ty::Uint(_) | ty::Int(_) => {
1322                 let int =
1323                     ConstInt::new(int, matches!(ty.kind(), ty::Int(_)), ty.is_ptr_sized_integral());
1324                 if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) }
1325             }
1326             // Char
1327             ty::Char if char::try_from(int).is_ok() => {
1328                 p!(write("{:?}", char::try_from(int).unwrap()))
1329             }
1330             // Pointer types
1331             ty::Ref(..) | ty::RawPtr(_) | ty::FnPtr(_) => {
1332                 let data = int.assert_bits(self.tcx().data_layout.pointer_size);
1333                 self = self.typed_value(
1334                     |mut this| {
1335                         write!(this, "0x{:x}", data)?;
1336                         Ok(this)
1337                     },
1338                     |this| this.print_type(ty),
1339                     " as ",
1340                 )?;
1341             }
1342             // For function type zsts just printing the path is enough
1343             ty::FnDef(d, s) if int == ScalarInt::ZST => {
1344                 p!(print_value_path(*d, s))
1345             }
1346             // Nontrivial types with scalar bit representation
1347             _ => {
1348                 let print = |mut this: Self| {
1349                     if int.size() == Size::ZERO {
1350                         write!(this, "transmute(())")?;
1351                     } else {
1352                         write!(this, "transmute(0x{:x})", int)?;
1353                     }
1354                     Ok(this)
1355                 };
1356                 self = if print_ty {
1357                     self.typed_value(print, |this| this.print_type(ty), ": ")?
1358                 } else {
1359                     print(self)?
1360                 };
1361             }
1362         }
1363         Ok(self)
1364     }
1365
1366     /// This is overridden for MIR printing because we only want to hide alloc ids from users, not
1367     /// from MIR where it is actually useful.
1368     fn pretty_print_const_pointer<Tag: Provenance>(
1369         mut self,
1370         _: Pointer<Tag>,
1371         ty: Ty<'tcx>,
1372         print_ty: bool,
1373     ) -> Result<Self::Const, Self::Error> {
1374         if print_ty {
1375             self.typed_value(
1376                 |mut this| {
1377                     this.write_str("&_")?;
1378                     Ok(this)
1379                 },
1380                 |this| this.print_type(ty),
1381                 ": ",
1382             )
1383         } else {
1384             self.write_str("&_")?;
1385             Ok(self)
1386         }
1387     }
1388
1389     fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result<Self::Const, Self::Error> {
1390         define_scoped_cx!(self);
1391         p!("b\"");
1392         for &c in byte_str {
1393             for e in std::ascii::escape_default(c) {
1394                 self.write_char(e as char)?;
1395             }
1396         }
1397         p!("\"");
1398         Ok(self)
1399     }
1400
1401     fn pretty_print_const_value(
1402         mut self,
1403         ct: ConstValue<'tcx>,
1404         ty: Ty<'tcx>,
1405         print_ty: bool,
1406     ) -> Result<Self::Const, Self::Error> {
1407         define_scoped_cx!(self);
1408
1409         if self.tcx().sess.verbose() {
1410             p!(write("ConstValue({:?}: ", ct), print(ty), ")");
1411             return Ok(self);
1412         }
1413
1414         let u8_type = self.tcx().types.u8;
1415
1416         match (ct, ty.kind()) {
1417             // Byte/string slices, printed as (byte) string literals.
1418             (
1419                 ConstValue::Slice { data, start, end },
1420                 ty::Ref(_, Ty(Interned(ty::TyS { kind: ty::Slice(t), .. }, _)), _),
1421             ) if *t == u8_type => {
1422                 // The `inspect` here is okay since we checked the bounds, and there are
1423                 // no relocations (we have an active slice reference here). We don't use
1424                 // this result to affect interpreter execution.
1425                 let byte_str = data.inspect_with_uninit_and_ptr_outside_interpreter(start..end);
1426                 self.pretty_print_byte_str(byte_str)
1427             }
1428             (
1429                 ConstValue::Slice { data, start, end },
1430                 ty::Ref(_, Ty(Interned(ty::TyS { kind: ty::Str, .. }, _)), _),
1431             ) => {
1432                 // The `inspect` here is okay since we checked the bounds, and there are no
1433                 // relocations (we have an active `str` reference here). We don't use this
1434                 // result to affect interpreter execution.
1435                 let slice = data.inspect_with_uninit_and_ptr_outside_interpreter(start..end);
1436                 let s = std::str::from_utf8(slice).expect("non utf8 str from miri");
1437                 p!(write("{:?}", s));
1438                 Ok(self)
1439             }
1440             (ConstValue::ByRef { alloc, offset }, ty::Array(t, n)) if *t == u8_type => {
1441                 let n = n.val().try_to_bits(self.tcx().data_layout.pointer_size).unwrap();
1442                 // cast is ok because we already checked for pointer size (32 or 64 bit) above
1443                 let range = AllocRange { start: offset, size: Size::from_bytes(n) };
1444
1445                 let byte_str = alloc.get_bytes(&self.tcx(), range).unwrap();
1446                 p!("*");
1447                 p!(pretty_print_byte_str(byte_str));
1448                 Ok(self)
1449             }
1450
1451             // Aggregates, printed as array/tuple/struct/variant construction syntax.
1452             //
1453             // NB: the `has_param_types_or_consts` check ensures that we can use
1454             // the `destructure_const` query with an empty `ty::ParamEnv` without
1455             // introducing ICEs (e.g. via `layout_of`) from missing bounds.
1456             // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
1457             // to be able to destructure the tuple into `(0u8, *mut T)
1458             //
1459             // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
1460             // correct `ty::ParamEnv` to allow printing *all* constant values.
1461             (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
1462                 let contents =
1463                     self.tcx().destructure_const(ty::ParamEnv::reveal_all().and(
1464                         self.tcx().mk_const(ty::ConstS { val: ty::ConstKind::Value(ct), ty }),
1465                     ));
1466                 let fields = contents.fields.iter().copied();
1467
1468                 match *ty.kind() {
1469                     ty::Array(..) => {
1470                         p!("[", comma_sep(fields), "]");
1471                     }
1472                     ty::Tuple(..) => {
1473                         p!("(", comma_sep(fields));
1474                         if contents.fields.len() == 1 {
1475                             p!(",");
1476                         }
1477                         p!(")");
1478                     }
1479                     ty::Adt(def, _) if def.variants.is_empty() => {
1480                         self = self.typed_value(
1481                             |mut this| {
1482                                 write!(this, "unreachable()")?;
1483                                 Ok(this)
1484                             },
1485                             |this| this.print_type(ty),
1486                             ": ",
1487                         )?;
1488                     }
1489                     ty::Adt(def, substs) => {
1490                         let variant_idx =
1491                             contents.variant.expect("destructed const of adt without variant idx");
1492                         let variant_def = &def.variants[variant_idx];
1493                         p!(print_value_path(variant_def.def_id, substs));
1494
1495                         match variant_def.ctor_kind {
1496                             CtorKind::Const => {}
1497                             CtorKind::Fn => {
1498                                 p!("(", comma_sep(fields), ")");
1499                             }
1500                             CtorKind::Fictive => {
1501                                 p!(" {{ ");
1502                                 let mut first = true;
1503                                 for (field_def, field) in iter::zip(&variant_def.fields, fields) {
1504                                     if !first {
1505                                         p!(", ");
1506                                     }
1507                                     p!(write("{}: ", field_def.name), print(field));
1508                                     first = false;
1509                                 }
1510                                 p!(" }}");
1511                             }
1512                         }
1513                     }
1514                     _ => unreachable!(),
1515                 }
1516
1517                 Ok(self)
1518             }
1519
1520             (ConstValue::Scalar(scalar), _) => self.pretty_print_const_scalar(scalar, ty, print_ty),
1521
1522             // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
1523             // their fields instead of just dumping the memory.
1524             _ => {
1525                 // fallback
1526                 p!(write("{:?}", ct));
1527                 if print_ty {
1528                     p!(": ", print(ty));
1529                 }
1530                 Ok(self)
1531             }
1532         }
1533     }
1534 }
1535
1536 // HACK(eddyb) boxed to avoid moving around a large struct by-value.
1537 pub struct FmtPrinter<'a, 'tcx, F>(Box<FmtPrinterData<'a, 'tcx, F>>);
1538
1539 pub struct FmtPrinterData<'a, 'tcx, F> {
1540     tcx: TyCtxt<'tcx>,
1541     fmt: F,
1542
1543     empty_path: bool,
1544     in_value: bool,
1545     pub print_alloc_ids: bool,
1546
1547     used_region_names: FxHashSet<Symbol>,
1548     region_index: usize,
1549     binder_depth: usize,
1550     printed_type_count: usize,
1551
1552     pub region_highlight_mode: RegionHighlightMode<'tcx>,
1553
1554     pub name_resolver: Option<Box<&'a dyn Fn(ty::TyVid) -> Option<String>>>,
1555 }
1556
1557 impl<'a, 'tcx, F> Deref for FmtPrinter<'a, 'tcx, F> {
1558     type Target = FmtPrinterData<'a, 'tcx, F>;
1559     fn deref(&self) -> &Self::Target {
1560         &self.0
1561     }
1562 }
1563
1564 impl<F> DerefMut for FmtPrinter<'_, '_, F> {
1565     fn deref_mut(&mut self) -> &mut Self::Target {
1566         &mut self.0
1567     }
1568 }
1569
1570 impl<'a, 'tcx, F> FmtPrinter<'a, 'tcx, F> {
1571     pub fn new(tcx: TyCtxt<'tcx>, fmt: F, ns: Namespace) -> Self {
1572         FmtPrinter(Box::new(FmtPrinterData {
1573             tcx,
1574             fmt,
1575             empty_path: false,
1576             in_value: ns == Namespace::ValueNS,
1577             print_alloc_ids: false,
1578             used_region_names: Default::default(),
1579             region_index: 0,
1580             binder_depth: 0,
1581             printed_type_count: 0,
1582             region_highlight_mode: RegionHighlightMode::new(tcx),
1583             name_resolver: None,
1584         }))
1585     }
1586 }
1587
1588 // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
1589 // (but also some things just print a `DefId` generally so maybe we need this?)
1590 fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace {
1591     match tcx.def_key(def_id).disambiguated_data.data {
1592         DefPathData::TypeNs(..) | DefPathData::CrateRoot | DefPathData::ImplTrait => {
1593             Namespace::TypeNS
1594         }
1595
1596         DefPathData::ValueNs(..)
1597         | DefPathData::AnonConst
1598         | DefPathData::ClosureExpr
1599         | DefPathData::Ctor => Namespace::ValueNS,
1600
1601         DefPathData::MacroNs(..) => Namespace::MacroNS,
1602
1603         _ => Namespace::TypeNS,
1604     }
1605 }
1606
1607 impl<'t> TyCtxt<'t> {
1608     /// Returns a string identifying this `DefId`. This string is
1609     /// suitable for user output.
1610     pub fn def_path_str(self, def_id: DefId) -> String {
1611         self.def_path_str_with_substs(def_id, &[])
1612     }
1613
1614     pub fn def_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String {
1615         let ns = guess_def_namespace(self, def_id);
1616         debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns);
1617         let mut s = String::new();
1618         let _ = FmtPrinter::new(self, &mut s, ns).print_def_path(def_id, substs);
1619         s
1620     }
1621 }
1622
1623 impl<F: fmt::Write> fmt::Write for FmtPrinter<'_, '_, F> {
1624     fn write_str(&mut self, s: &str) -> fmt::Result {
1625         self.fmt.write_str(s)
1626     }
1627 }
1628
1629 impl<'tcx, F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
1630     type Error = fmt::Error;
1631
1632     type Path = Self;
1633     type Region = Self;
1634     type Type = Self;
1635     type DynExistential = Self;
1636     type Const = Self;
1637
1638     fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
1639         self.tcx
1640     }
1641
1642     fn print_def_path(
1643         mut self,
1644         def_id: DefId,
1645         substs: &'tcx [GenericArg<'tcx>],
1646     ) -> Result<Self::Path, Self::Error> {
1647         define_scoped_cx!(self);
1648
1649         if substs.is_empty() {
1650             match self.try_print_trimmed_def_path(def_id)? {
1651                 (cx, true) => return Ok(cx),
1652                 (cx, false) => self = cx,
1653             }
1654
1655             match self.try_print_visible_def_path(def_id)? {
1656                 (cx, true) => return Ok(cx),
1657                 (cx, false) => self = cx,
1658             }
1659         }
1660
1661         let key = self.tcx.def_key(def_id);
1662         if let DefPathData::Impl = key.disambiguated_data.data {
1663             // Always use types for non-local impls, where types are always
1664             // available, and filename/line-number is mostly uninteresting.
1665             let use_types = !def_id.is_local() || {
1666                 // Otherwise, use filename/line-number if forced.
1667                 let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
1668                 !force_no_types
1669             };
1670
1671             if !use_types {
1672                 // If no type info is available, fall back to
1673                 // pretty printing some span information. This should
1674                 // only occur very early in the compiler pipeline.
1675                 let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
1676                 let span = self.tcx.def_span(def_id);
1677
1678                 self = self.print_def_path(parent_def_id, &[])?;
1679
1680                 // HACK(eddyb) copy of `path_append` to avoid
1681                 // constructing a `DisambiguatedDefPathData`.
1682                 if !self.empty_path {
1683                     write!(self, "::")?;
1684                 }
1685                 write!(
1686                     self,
1687                     "<impl at {}>",
1688                     // This may end up in stderr diagnostics but it may also be emitted
1689                     // into MIR. Hence we use the remapped path if available
1690                     self.tcx.sess.source_map().span_to_embeddable_string(span)
1691                 )?;
1692                 self.empty_path = false;
1693
1694                 return Ok(self);
1695             }
1696         }
1697
1698         self.default_print_def_path(def_id, substs)
1699     }
1700
1701     fn print_region(self, region: ty::Region<'_>) -> Result<Self::Region, Self::Error> {
1702         self.pretty_print_region(region)
1703     }
1704
1705     fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
1706         let type_length_limit = self.tcx.type_length_limit();
1707         if type_length_limit.value_within_limit(self.printed_type_count) {
1708             self.printed_type_count += 1;
1709             self.pretty_print_type(ty)
1710         } else {
1711             write!(self, "...")?;
1712             Ok(self)
1713         }
1714     }
1715
1716     fn print_dyn_existential(
1717         self,
1718         predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
1719     ) -> Result<Self::DynExistential, Self::Error> {
1720         self.pretty_print_dyn_existential(predicates)
1721     }
1722
1723     fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
1724         self.pretty_print_const(ct, true)
1725     }
1726
1727     fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
1728         self.empty_path = true;
1729         if cnum == LOCAL_CRATE {
1730             if self.tcx.sess.rust_2018() {
1731                 // We add the `crate::` keyword on Rust 2018, only when desired.
1732                 if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
1733                     write!(self, "{}", kw::Crate)?;
1734                     self.empty_path = false;
1735                 }
1736             }
1737         } else {
1738             write!(self, "{}", self.tcx.crate_name(cnum))?;
1739             self.empty_path = false;
1740         }
1741         Ok(self)
1742     }
1743
1744     fn path_qualified(
1745         mut self,
1746         self_ty: Ty<'tcx>,
1747         trait_ref: Option<ty::TraitRef<'tcx>>,
1748     ) -> Result<Self::Path, Self::Error> {
1749         self = self.pretty_path_qualified(self_ty, trait_ref)?;
1750         self.empty_path = false;
1751         Ok(self)
1752     }
1753
1754     fn path_append_impl(
1755         mut self,
1756         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
1757         _disambiguated_data: &DisambiguatedDefPathData,
1758         self_ty: Ty<'tcx>,
1759         trait_ref: Option<ty::TraitRef<'tcx>>,
1760     ) -> Result<Self::Path, Self::Error> {
1761         self = self.pretty_path_append_impl(
1762             |mut cx| {
1763                 cx = print_prefix(cx)?;
1764                 if !cx.empty_path {
1765                     write!(cx, "::")?;
1766                 }
1767
1768                 Ok(cx)
1769             },
1770             self_ty,
1771             trait_ref,
1772         )?;
1773         self.empty_path = false;
1774         Ok(self)
1775     }
1776
1777     fn path_append(
1778         mut self,
1779         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
1780         disambiguated_data: &DisambiguatedDefPathData,
1781     ) -> Result<Self::Path, Self::Error> {
1782         self = print_prefix(self)?;
1783
1784         // Skip `::{{extern}}` blocks and `::{{constructor}}` on tuple/unit structs.
1785         if let DefPathData::ForeignMod | DefPathData::Ctor = disambiguated_data.data {
1786             return Ok(self);
1787         }
1788
1789         let name = disambiguated_data.data.name();
1790         if !self.empty_path {
1791             write!(self, "::")?;
1792         }
1793
1794         if let DefPathDataName::Named(name) = name {
1795             if Ident::with_dummy_span(name).is_raw_guess() {
1796                 write!(self, "r#")?;
1797             }
1798         }
1799
1800         let verbose = self.tcx.sess.verbose();
1801         disambiguated_data.fmt_maybe_verbose(&mut self, verbose)?;
1802
1803         self.empty_path = false;
1804
1805         Ok(self)
1806     }
1807
1808     fn path_generic_args(
1809         mut self,
1810         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
1811         args: &[GenericArg<'tcx>],
1812     ) -> Result<Self::Path, Self::Error> {
1813         self = print_prefix(self)?;
1814
1815         // Don't print `'_` if there's no unerased regions.
1816         let print_regions = self.tcx.sess.verbose()
1817             || args.iter().any(|arg| match arg.unpack() {
1818                 GenericArgKind::Lifetime(r) => !r.is_erased(),
1819                 _ => false,
1820             });
1821         let args = args.iter().cloned().filter(|arg| match arg.unpack() {
1822             GenericArgKind::Lifetime(_) => print_regions,
1823             _ => true,
1824         });
1825
1826         if args.clone().next().is_some() {
1827             if self.in_value {
1828                 write!(self, "::")?;
1829             }
1830             self.generic_delimiters(|cx| cx.comma_sep(args))
1831         } else {
1832             Ok(self)
1833         }
1834     }
1835 }
1836
1837 impl<'tcx, F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
1838     fn infer_ty_name(&self, id: ty::TyVid) -> Option<String> {
1839         self.0.name_resolver.as_ref().and_then(|func| func(id))
1840     }
1841
1842     fn print_value_path(
1843         mut self,
1844         def_id: DefId,
1845         substs: &'tcx [GenericArg<'tcx>],
1846     ) -> Result<Self::Path, Self::Error> {
1847         let was_in_value = std::mem::replace(&mut self.in_value, true);
1848         self = self.print_def_path(def_id, substs)?;
1849         self.in_value = was_in_value;
1850
1851         Ok(self)
1852     }
1853
1854     fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error>
1855     where
1856         T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
1857     {
1858         self.pretty_in_binder(value)
1859     }
1860
1861     fn wrap_binder<T, C: Fn(&T, Self) -> Result<Self, Self::Error>>(
1862         self,
1863         value: &ty::Binder<'tcx, T>,
1864         f: C,
1865     ) -> Result<Self, Self::Error>
1866     where
1867         T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
1868     {
1869         self.pretty_wrap_binder(value, f)
1870     }
1871
1872     fn typed_value(
1873         mut self,
1874         f: impl FnOnce(Self) -> Result<Self, Self::Error>,
1875         t: impl FnOnce(Self) -> Result<Self, Self::Error>,
1876         conversion: &str,
1877     ) -> Result<Self::Const, Self::Error> {
1878         self.write_str("{")?;
1879         self = f(self)?;
1880         self.write_str(conversion)?;
1881         let was_in_value = std::mem::replace(&mut self.in_value, false);
1882         self = t(self)?;
1883         self.in_value = was_in_value;
1884         self.write_str("}")?;
1885         Ok(self)
1886     }
1887
1888     fn generic_delimiters(
1889         mut self,
1890         f: impl FnOnce(Self) -> Result<Self, Self::Error>,
1891     ) -> Result<Self, Self::Error> {
1892         write!(self, "<")?;
1893
1894         let was_in_value = std::mem::replace(&mut self.in_value, false);
1895         let mut inner = f(self)?;
1896         inner.in_value = was_in_value;
1897
1898         write!(inner, ">")?;
1899         Ok(inner)
1900     }
1901
1902     fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool {
1903         let highlight = self.region_highlight_mode;
1904         if highlight.region_highlighted(region).is_some() {
1905             return true;
1906         }
1907
1908         if self.tcx.sess.verbose() {
1909             return true;
1910         }
1911
1912         let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;
1913
1914         match *region {
1915             ty::ReEarlyBound(ref data) => {
1916                 data.name != kw::Empty && data.name != kw::UnderscoreLifetime
1917             }
1918
1919             ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
1920             | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
1921             | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
1922                 if let ty::BrNamed(_, name) = br {
1923                     if name != kw::Empty && name != kw::UnderscoreLifetime {
1924                         return true;
1925                     }
1926                 }
1927
1928                 if let Some((region, _)) = highlight.highlight_bound_region {
1929                     if br == region {
1930                         return true;
1931                     }
1932                 }
1933
1934                 false
1935             }
1936
1937             ty::ReVar(_) if identify_regions => true,
1938
1939             ty::ReVar(_) | ty::ReErased => false,
1940
1941             ty::ReStatic | ty::ReEmpty(_) => true,
1942         }
1943     }
1944
1945     fn pretty_print_const_pointer<Tag: Provenance>(
1946         self,
1947         p: Pointer<Tag>,
1948         ty: Ty<'tcx>,
1949         print_ty: bool,
1950     ) -> Result<Self::Const, Self::Error> {
1951         let print = |mut this: Self| {
1952             define_scoped_cx!(this);
1953             if this.print_alloc_ids {
1954                 p!(write("{:?}", p));
1955             } else {
1956                 p!("&_");
1957             }
1958             Ok(this)
1959         };
1960         if print_ty {
1961             self.typed_value(print, |this| this.print_type(ty), ": ")
1962         } else {
1963             print(self)
1964         }
1965     }
1966 }
1967
1968 // HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
1969 impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
1970     pub fn pretty_print_region(mut self, region: ty::Region<'_>) -> Result<Self, fmt::Error> {
1971         define_scoped_cx!(self);
1972
1973         // Watch out for region highlights.
1974         let highlight = self.region_highlight_mode;
1975         if let Some(n) = highlight.region_highlighted(region) {
1976             p!(write("'{}", n));
1977             return Ok(self);
1978         }
1979
1980         if self.tcx.sess.verbose() {
1981             p!(write("{:?}", region));
1982             return Ok(self);
1983         }
1984
1985         let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;
1986
1987         // These printouts are concise.  They do not contain all the information
1988         // the user might want to diagnose an error, but there is basically no way
1989         // to fit that into a short string.  Hence the recommendation to use
1990         // `explain_region()` or `note_and_explain_region()`.
1991         match *region {
1992             ty::ReEarlyBound(ref data) => {
1993                 if data.name != kw::Empty {
1994                     p!(write("{}", data.name));
1995                     return Ok(self);
1996                 }
1997             }
1998             ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
1999             | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
2000             | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
2001                 if let ty::BrNamed(_, name) = br {
2002                     if name != kw::Empty && name != kw::UnderscoreLifetime {
2003                         p!(write("{}", name));
2004                         return Ok(self);
2005                     }
2006                 }
2007
2008                 if let Some((region, counter)) = highlight.highlight_bound_region {
2009                     if br == region {
2010                         p!(write("'{}", counter));
2011                         return Ok(self);
2012                     }
2013                 }
2014             }
2015             ty::ReVar(region_vid) if identify_regions => {
2016                 p!(write("{:?}", region_vid));
2017                 return Ok(self);
2018             }
2019             ty::ReVar(_) => {}
2020             ty::ReErased => {}
2021             ty::ReStatic => {
2022                 p!("'static");
2023                 return Ok(self);
2024             }
2025             ty::ReEmpty(ty::UniverseIndex::ROOT) => {
2026                 p!("'<empty>");
2027                 return Ok(self);
2028             }
2029             ty::ReEmpty(ui) => {
2030                 p!(write("'<empty:{:?}>", ui));
2031                 return Ok(self);
2032             }
2033         }
2034
2035         p!("'_");
2036
2037         Ok(self)
2038     }
2039 }
2040
2041 /// Folds through bound vars and placeholders, naming them
2042 struct RegionFolder<'a, 'tcx> {
2043     tcx: TyCtxt<'tcx>,
2044     current_index: ty::DebruijnIndex,
2045     region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
2046     name: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
2047 }
2048
2049 impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
2050     fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
2051         self.tcx
2052     }
2053
2054     fn fold_binder<T: TypeFoldable<'tcx>>(
2055         &mut self,
2056         t: ty::Binder<'tcx, T>,
2057     ) -> ty::Binder<'tcx, T> {
2058         self.current_index.shift_in(1);
2059         let t = t.super_fold_with(self);
2060         self.current_index.shift_out(1);
2061         t
2062     }
2063
2064     fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
2065         match *t.kind() {
2066             _ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => {
2067                 return t.super_fold_with(self);
2068             }
2069             _ => {}
2070         }
2071         t
2072     }
2073
2074     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
2075         let name = &mut self.name;
2076         let region = match *r {
2077             ty::ReLateBound(_, br) => *self.region_map.entry(br).or_insert_with(|| name(br)),
2078             ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
2079                 // If this is an anonymous placeholder, don't rename. Otherwise, in some
2080                 // async fns, we get a `for<'r> Send` bound
2081                 match kind {
2082                     ty::BrAnon(_) | ty::BrEnv => r,
2083                     _ => {
2084                         // Index doesn't matter, since this is just for naming and these never get bound
2085                         let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
2086                         *self.region_map.entry(br).or_insert_with(|| name(br))
2087                     }
2088                 }
2089             }
2090             _ => return r,
2091         };
2092         if let ty::ReLateBound(debruijn1, br) = *region {
2093             assert_eq!(debruijn1, ty::INNERMOST);
2094             self.tcx.mk_region(ty::ReLateBound(self.current_index, br))
2095         } else {
2096             region
2097         }
2098     }
2099 }
2100
2101 // HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
2102 // `region_index` and `used_region_names`.
2103 impl<'tcx, F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
2104     pub fn name_all_regions<T>(
2105         mut self,
2106         value: &ty::Binder<'tcx, T>,
2107     ) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
2108     where
2109         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
2110     {
2111         fn name_by_region_index(index: usize) -> Symbol {
2112             match index {
2113                 0 => Symbol::intern("'r"),
2114                 1 => Symbol::intern("'s"),
2115                 i => Symbol::intern(&format!("'t{}", i - 2)),
2116             }
2117         }
2118
2119         // Replace any anonymous late-bound regions with named
2120         // variants, using new unique identifiers, so that we can
2121         // clearly differentiate between named and unnamed regions in
2122         // the output. We'll probably want to tweak this over time to
2123         // decide just how much information to give.
2124         if self.binder_depth == 0 {
2125             self.prepare_late_bound_region_info(value);
2126         }
2127
2128         let mut empty = true;
2129         let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
2130             let w = if empty {
2131                 empty = false;
2132                 start
2133             } else {
2134                 cont
2135             };
2136             let _ = write!(cx, "{}", w);
2137         };
2138         let do_continue = |cx: &mut Self, cont: Symbol| {
2139             let _ = write!(cx, "{}", cont);
2140         };
2141
2142         define_scoped_cx!(self);
2143
2144         let mut region_index = self.region_index;
2145         // If we want to print verbosly, then print *all* binders, even if they
2146         // aren't named. Eventually, we might just want this as the default, but
2147         // this is not *quite* right and changes the ordering of some output
2148         // anyways.
2149         let (new_value, map) = if self.tcx().sess.verbose() {
2150             // anon index + 1 (BrEnv takes 0) -> name
2151             let mut region_map: BTreeMap<u32, Symbol> = BTreeMap::default();
2152             let bound_vars = value.bound_vars();
2153             for var in bound_vars {
2154                 match var {
2155                     ty::BoundVariableKind::Region(ty::BrNamed(_, name)) => {
2156                         start_or_continue(&mut self, "for<", ", ");
2157                         do_continue(&mut self, name);
2158                     }
2159                     ty::BoundVariableKind::Region(ty::BrAnon(i)) => {
2160                         start_or_continue(&mut self, "for<", ", ");
2161                         let name = loop {
2162                             let name = name_by_region_index(region_index);
2163                             region_index += 1;
2164                             if !self.used_region_names.contains(&name) {
2165                                 break name;
2166                             }
2167                         };
2168                         do_continue(&mut self, name);
2169                         region_map.insert(i + 1, name);
2170                     }
2171                     ty::BoundVariableKind::Region(ty::BrEnv) => {
2172                         start_or_continue(&mut self, "for<", ", ");
2173                         let name = loop {
2174                             let name = name_by_region_index(region_index);
2175                             region_index += 1;
2176                             if !self.used_region_names.contains(&name) {
2177                                 break name;
2178                             }
2179                         };
2180                         do_continue(&mut self, name);
2181                         region_map.insert(0, name);
2182                     }
2183                     _ => continue,
2184                 }
2185             }
2186             start_or_continue(&mut self, "", "> ");
2187
2188             self.tcx.replace_late_bound_regions(value.clone(), |br| {
2189                 let kind = match br.kind {
2190                     ty::BrNamed(_, _) => br.kind,
2191                     ty::BrAnon(i) => {
2192                         let name = region_map[&(i + 1)];
2193                         ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
2194                     }
2195                     ty::BrEnv => {
2196                         let name = region_map[&0];
2197                         ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
2198                     }
2199                 };
2200                 self.tcx.mk_region(ty::ReLateBound(
2201                     ty::INNERMOST,
2202                     ty::BoundRegion { var: br.var, kind },
2203                 ))
2204             })
2205         } else {
2206             let tcx = self.tcx;
2207             let mut name = |br: ty::BoundRegion| {
2208                 start_or_continue(&mut self, "for<", ", ");
2209                 let kind = match br.kind {
2210                     ty::BrNamed(_, name) => {
2211                         do_continue(&mut self, name);
2212                         br.kind
2213                     }
2214                     ty::BrAnon(_) | ty::BrEnv => {
2215                         let name = loop {
2216                             let name = name_by_region_index(region_index);
2217                             region_index += 1;
2218                             if !self.used_region_names.contains(&name) {
2219                                 break name;
2220                             }
2221                         };
2222                         do_continue(&mut self, name);
2223                         ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
2224                     }
2225                 };
2226                 tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
2227             };
2228             let mut folder = RegionFolder {
2229                 tcx,
2230                 current_index: ty::INNERMOST,
2231                 name: &mut name,
2232                 region_map: BTreeMap::new(),
2233             };
2234             let new_value = value.clone().skip_binder().fold_with(&mut folder);
2235             let region_map = folder.region_map;
2236             start_or_continue(&mut self, "", "> ");
2237             (new_value, region_map)
2238         };
2239
2240         self.binder_depth += 1;
2241         self.region_index = region_index;
2242         Ok((self, new_value, map))
2243     }
2244
2245     pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error>
2246     where
2247         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
2248     {
2249         let old_region_index = self.region_index;
2250         let (new, new_value, _) = self.name_all_regions(value)?;
2251         let mut inner = new_value.print(new)?;
2252         inner.region_index = old_region_index;
2253         inner.binder_depth -= 1;
2254         Ok(inner)
2255     }
2256
2257     pub fn pretty_wrap_binder<T, C: Fn(&T, Self) -> Result<Self, fmt::Error>>(
2258         self,
2259         value: &ty::Binder<'tcx, T>,
2260         f: C,
2261     ) -> Result<Self, fmt::Error>
2262     where
2263         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
2264     {
2265         let old_region_index = self.region_index;
2266         let (new, new_value, _) = self.name_all_regions(value)?;
2267         let mut inner = f(&new_value, new)?;
2268         inner.region_index = old_region_index;
2269         inner.binder_depth -= 1;
2270         Ok(inner)
2271     }
2272
2273     #[instrument(skip(self), level = "debug")]
2274     fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>)
2275     where
2276         T: TypeFoldable<'tcx>,
2277     {
2278         struct LateBoundRegionNameCollector<'a, 'tcx> {
2279             used_region_names: &'a mut FxHashSet<Symbol>,
2280             type_collector: SsoHashSet<Ty<'tcx>>,
2281         }
2282
2283         impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_, 'tcx> {
2284             type BreakTy = ();
2285
2286             #[instrument(skip(self), level = "trace")]
2287             fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
2288                 trace!("address: {:p}", r.0.0);
2289                 if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
2290                     self.used_region_names.insert(name);
2291                 } else if let ty::RePlaceholder(ty::PlaceholderRegion {
2292                     name: ty::BrNamed(_, name),
2293                     ..
2294                 }) = *r
2295                 {
2296                     self.used_region_names.insert(name);
2297                 }
2298                 r.super_visit_with(self)
2299             }
2300
2301             // We collect types in order to prevent really large types from compiling for
2302             // a really long time. See issue #83150 for why this is necessary.
2303             #[instrument(skip(self), level = "trace")]
2304             fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
2305                 let not_previously_inserted = self.type_collector.insert(ty);
2306                 if not_previously_inserted {
2307                     ty.super_visit_with(self)
2308                 } else {
2309                     ControlFlow::CONTINUE
2310                 }
2311             }
2312         }
2313
2314         self.used_region_names.clear();
2315         let mut collector = LateBoundRegionNameCollector {
2316             used_region_names: &mut self.used_region_names,
2317             type_collector: SsoHashSet::new(),
2318         };
2319         value.visit_with(&mut collector);
2320         self.region_index = 0;
2321     }
2322 }
2323
2324 impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T>
2325 where
2326     T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>,
2327 {
2328     type Output = P;
2329     type Error = P::Error;
2330     fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
2331         cx.in_binder(self)
2332     }
2333 }
2334
2335 impl<'tcx, T, U, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<T, U>
2336 where
2337     T: Print<'tcx, P, Output = P, Error = P::Error>,
2338     U: Print<'tcx, P, Output = P, Error = P::Error>,
2339 {
2340     type Output = P;
2341     type Error = P::Error;
2342     fn print(&self, mut cx: P) -> Result<Self::Output, Self::Error> {
2343         define_scoped_cx!(cx);
2344         p!(print(self.0), ": ", print(self.1));
2345         Ok(cx)
2346     }
2347 }
2348
2349 macro_rules! forward_display_to_print {
2350     ($($ty:ty),+) => {
2351         // Some of the $ty arguments may not actually use 'tcx
2352         $(#[allow(unused_lifetimes)] impl<'tcx> fmt::Display for $ty {
2353             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2354                 ty::tls::with(|tcx| {
2355                     tcx.lift(*self)
2356                         .expect("could not lift for printing")
2357                         .print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
2358                     Ok(())
2359                 })
2360             }
2361         })+
2362     };
2363 }
2364
2365 macro_rules! define_print_and_forward_display {
2366     (($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
2367         $(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty {
2368             type Output = P;
2369             type Error = fmt::Error;
2370             fn print(&$self, $cx: P) -> Result<Self::Output, Self::Error> {
2371                 #[allow(unused_mut)]
2372                 let mut $cx = $cx;
2373                 define_scoped_cx!($cx);
2374                 let _: () = $print;
2375                 #[allow(unreachable_code)]
2376                 Ok($cx)
2377             }
2378         })+
2379
2380         forward_display_to_print!($($ty),+);
2381     };
2382 }
2383
2384 // HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
2385 impl<'tcx> fmt::Display for ty::Region<'tcx> {
2386     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2387         ty::tls::with(|tcx| {
2388             self.print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
2389             Ok(())
2390         })
2391     }
2392 }
2393
2394 /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
2395 /// the trait path. That is, it will print `Trait<U>` instead of
2396 /// `<T as Trait<U>>`.
2397 #[derive(Copy, Clone, TypeFoldable, Lift)]
2398 pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
2399
2400 impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
2401     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2402         fmt::Display::fmt(self, f)
2403     }
2404 }
2405
2406 /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
2407 /// the trait name. That is, it will print `Trait` instead of
2408 /// `<T as Trait<U>>`.
2409 #[derive(Copy, Clone, TypeFoldable, Lift)]
2410 pub struct TraitRefPrintOnlyTraitName<'tcx>(ty::TraitRef<'tcx>);
2411
2412 impl<'tcx> fmt::Debug for TraitRefPrintOnlyTraitName<'tcx> {
2413     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2414         fmt::Display::fmt(self, f)
2415     }
2416 }
2417
2418 impl<'tcx> ty::TraitRef<'tcx> {
2419     pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
2420         TraitRefPrintOnlyTraitPath(self)
2421     }
2422
2423     pub fn print_only_trait_name(self) -> TraitRefPrintOnlyTraitName<'tcx> {
2424         TraitRefPrintOnlyTraitName(self)
2425     }
2426 }
2427
2428 impl<'tcx> ty::Binder<'tcx, ty::TraitRef<'tcx>> {
2429     pub fn print_only_trait_path(self) -> ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>> {
2430         self.map_bound(|tr| tr.print_only_trait_path())
2431     }
2432 }
2433
2434 #[derive(Copy, Clone, TypeFoldable, Lift)]
2435 pub struct TraitPredPrintModifiersAndPath<'tcx>(ty::TraitPredicate<'tcx>);
2436
2437 impl<'tcx> fmt::Debug for TraitPredPrintModifiersAndPath<'tcx> {
2438     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2439         fmt::Display::fmt(self, f)
2440     }
2441 }
2442
2443 impl<'tcx> ty::TraitPredicate<'tcx> {
2444     pub fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> {
2445         TraitPredPrintModifiersAndPath(self)
2446     }
2447 }
2448
2449 impl<'tcx> ty::PolyTraitPredicate<'tcx> {
2450     pub fn print_modifiers_and_trait_path(
2451         self,
2452     ) -> ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>> {
2453         self.map_bound(TraitPredPrintModifiersAndPath)
2454     }
2455 }
2456
2457 forward_display_to_print! {
2458     Ty<'tcx>,
2459     &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
2460     ty::Const<'tcx>,
2461
2462     // HACK(eddyb) these are exhaustive instead of generic,
2463     // because `for<'tcx>` isn't possible yet.
2464     ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>,
2465     ty::Binder<'tcx, ty::TraitRef<'tcx>>,
2466     ty::Binder<'tcx, ty::ExistentialTraitRef<'tcx>>,
2467     ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>,
2468     ty::Binder<'tcx, TraitRefPrintOnlyTraitName<'tcx>>,
2469     ty::Binder<'tcx, ty::FnSig<'tcx>>,
2470     ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
2471     ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>>,
2472     ty::Binder<'tcx, ty::SubtypePredicate<'tcx>>,
2473     ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>,
2474     ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
2475     ty::Binder<'tcx, ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>,
2476
2477     ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
2478     ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
2479 }
2480
2481 define_print_and_forward_display! {
2482     (self, cx):
2483
2484     &'tcx ty::List<Ty<'tcx>> {
2485         p!("{{", comma_sep(self.iter()), "}}")
2486     }
2487
2488     ty::TypeAndMut<'tcx> {
2489         p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
2490     }
2491
2492     ty::ExistentialTraitRef<'tcx> {
2493         // Use a type that can't appear in defaults of type parameters.
2494         let dummy_self = cx.tcx().mk_ty_infer(ty::FreshTy(0));
2495         let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
2496         p!(print(trait_ref.print_only_trait_path()))
2497     }
2498
2499     ty::ExistentialProjection<'tcx> {
2500         let name = cx.tcx().associated_item(self.item_def_id).name;
2501         p!(write("{} = ", name), print(self.term))
2502     }
2503
2504     ty::ExistentialPredicate<'tcx> {
2505         match *self {
2506             ty::ExistentialPredicate::Trait(x) => p!(print(x)),
2507             ty::ExistentialPredicate::Projection(x) => p!(print(x)),
2508             ty::ExistentialPredicate::AutoTrait(def_id) => {
2509                 p!(print_def_path(def_id, &[]));
2510             }
2511         }
2512     }
2513
2514     ty::FnSig<'tcx> {
2515         p!(write("{}", self.unsafety.prefix_str()));
2516
2517         if self.abi != Abi::Rust {
2518             p!(write("extern {} ", self.abi));
2519         }
2520
2521         p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
2522     }
2523
2524     ty::TraitRef<'tcx> {
2525         p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
2526     }
2527
2528     TraitRefPrintOnlyTraitPath<'tcx> {
2529         p!(print_def_path(self.0.def_id, self.0.substs));
2530     }
2531
2532     TraitRefPrintOnlyTraitName<'tcx> {
2533         p!(print_def_path(self.0.def_id, &[]));
2534     }
2535
2536     TraitPredPrintModifiersAndPath<'tcx> {
2537         if let ty::BoundConstness::ConstIfConst = self.0.constness {
2538             p!("~const ")
2539         }
2540
2541         if let ty::ImplPolarity::Negative = self.0.polarity {
2542             p!("!")
2543         }
2544
2545         p!(print(self.0.trait_ref.print_only_trait_path()));
2546     }
2547
2548     ty::ParamTy {
2549         p!(write("{}", self.name))
2550     }
2551
2552     ty::ParamConst {
2553         p!(write("{}", self.name))
2554     }
2555
2556     ty::SubtypePredicate<'tcx> {
2557         p!(print(self.a), " <: ", print(self.b))
2558     }
2559
2560     ty::CoercePredicate<'tcx> {
2561         p!(print(self.a), " -> ", print(self.b))
2562     }
2563
2564     ty::TraitPredicate<'tcx> {
2565         p!(print(self.trait_ref.self_ty()), ": ");
2566         if let ty::BoundConstness::ConstIfConst = self.constness {
2567             p!("~const ");
2568         }
2569         p!(print(self.trait_ref.print_only_trait_path()))
2570     }
2571
2572     ty::ProjectionPredicate<'tcx> {
2573         p!(print(self.projection_ty), " == ", print(self.term))
2574     }
2575
2576     ty::Term<'tcx> {
2577       match self {
2578         ty::Term::Ty(ty) => p!(print(ty)),
2579         ty::Term::Const(c) => p!(print(c)),
2580       }
2581     }
2582
2583     ty::ProjectionTy<'tcx> {
2584         p!(print_def_path(self.item_def_id, self.substs));
2585     }
2586
2587     ty::ClosureKind {
2588         match *self {
2589             ty::ClosureKind::Fn => p!("Fn"),
2590             ty::ClosureKind::FnMut => p!("FnMut"),
2591             ty::ClosureKind::FnOnce => p!("FnOnce"),
2592         }
2593     }
2594
2595     ty::Predicate<'tcx> {
2596         let binder = self.kind();
2597         p!(print(binder))
2598     }
2599
2600     ty::PredicateKind<'tcx> {
2601         match *self {
2602             ty::PredicateKind::Trait(ref data) => {
2603                 p!(print(data))
2604             }
2605             ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
2606             ty::PredicateKind::Coerce(predicate) => p!(print(predicate)),
2607             ty::PredicateKind::RegionOutlives(predicate) => p!(print(predicate)),
2608             ty::PredicateKind::TypeOutlives(predicate) => p!(print(predicate)),
2609             ty::PredicateKind::Projection(predicate) => p!(print(predicate)),
2610             ty::PredicateKind::WellFormed(arg) => p!(print(arg), " well-formed"),
2611             ty::PredicateKind::ObjectSafe(trait_def_id) => {
2612                 p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
2613             }
2614             ty::PredicateKind::ClosureKind(closure_def_id, _closure_substs, kind) => {
2615                 p!("the closure `",
2616                 print_value_path(closure_def_id, &[]),
2617                 write("` implements the trait `{}`", kind))
2618             }
2619             ty::PredicateKind::ConstEvaluatable(uv) => {
2620                 p!("the constant `", print_value_path(uv.def.did, uv.substs), "` can be evaluated")
2621             }
2622             ty::PredicateKind::ConstEquate(c1, c2) => {
2623                 p!("the constant `", print(c1), "` equals `", print(c2), "`")
2624             }
2625             ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
2626                 p!("the type `", print(ty), "` is found in the environment")
2627             }
2628         }
2629     }
2630
2631     GenericArg<'tcx> {
2632         match self.unpack() {
2633             GenericArgKind::Lifetime(lt) => p!(print(lt)),
2634             GenericArgKind::Type(ty) => p!(print(ty)),
2635             GenericArgKind::Const(ct) => p!(print(ct)),
2636         }
2637     }
2638 }
2639
2640 fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) {
2641     // Iterate all local crate items no matter where they are defined.
2642     let hir = tcx.hir();
2643     for item in hir.items() {
2644         if item.ident.name.as_str().is_empty() || matches!(item.kind, ItemKind::Use(_, _)) {
2645             continue;
2646         }
2647
2648         let def_id = item.def_id.to_def_id();
2649         let ns = tcx.def_kind(def_id).ns().unwrap_or(Namespace::TypeNS);
2650         collect_fn(&item.ident, ns, def_id);
2651     }
2652
2653     // Now take care of extern crate items.
2654     let queue = &mut Vec::new();
2655     let mut seen_defs: DefIdSet = Default::default();
2656
2657     for &cnum in tcx.crates(()).iter() {
2658         let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
2659
2660         // Ignore crates that are not direct dependencies.
2661         match tcx.extern_crate(def_id) {
2662             None => continue,
2663             Some(extern_crate) => {
2664                 if !extern_crate.is_direct() {
2665                     continue;
2666                 }
2667             }
2668         }
2669
2670         queue.push(def_id);
2671     }
2672
2673     // Iterate external crate defs but be mindful about visibility
2674     while let Some(def) = queue.pop() {
2675         for child in tcx.module_children(def).iter() {
2676             if !child.vis.is_public() {
2677                 continue;
2678             }
2679
2680             match child.res {
2681                 def::Res::Def(DefKind::AssocTy, _) => {}
2682                 def::Res::Def(DefKind::TyAlias, _) => {}
2683                 def::Res::Def(defkind, def_id) => {
2684                     if let Some(ns) = defkind.ns() {
2685                         collect_fn(&child.ident, ns, def_id);
2686                     }
2687
2688                     if matches!(defkind, DefKind::Mod | DefKind::Enum | DefKind::Trait)
2689                         && seen_defs.insert(def_id)
2690                     {
2691                         queue.push(def_id);
2692                     }
2693                 }
2694                 _ => {}
2695             }
2696         }
2697     }
2698 }
2699
2700 /// The purpose of this function is to collect public symbols names that are unique across all
2701 /// crates in the build. Later, when printing about types we can use those names instead of the
2702 /// full exported path to them.
2703 ///
2704 /// So essentially, if a symbol name can only be imported from one place for a type, and as
2705 /// long as it was not glob-imported anywhere in the current crate, we can trim its printed
2706 /// path and print only the name.
2707 ///
2708 /// This has wide implications on error messages with types, for example, shortening
2709 /// `std::vec::Vec` to just `Vec`, as long as there is no other `Vec` importable anywhere.
2710 ///
2711 /// The implementation uses similar import discovery logic to that of 'use' suggestions.
2712 fn trimmed_def_paths(tcx: TyCtxt<'_>, (): ()) -> FxHashMap<DefId, Symbol> {
2713     let mut map: FxHashMap<DefId, Symbol> = FxHashMap::default();
2714
2715     if let TrimmedDefPaths::GoodPath = tcx.sess.opts.trimmed_def_paths {
2716         // For good paths causing this bug, the `rustc_middle::ty::print::with_no_trimmed_paths`
2717         // wrapper can be used to suppress this query, in exchange for full paths being formatted.
2718         tcx.sess.delay_good_path_bug("trimmed_def_paths constructed");
2719     }
2720
2721     let unique_symbols_rev: &mut FxHashMap<(Namespace, Symbol), Option<DefId>> =
2722         &mut FxHashMap::default();
2723
2724     for symbol_set in tcx.resolutions(()).glob_map.values() {
2725         for symbol in symbol_set {
2726             unique_symbols_rev.insert((Namespace::TypeNS, *symbol), None);
2727             unique_symbols_rev.insert((Namespace::ValueNS, *symbol), None);
2728             unique_symbols_rev.insert((Namespace::MacroNS, *symbol), None);
2729         }
2730     }
2731
2732     for_each_def(tcx, |ident, ns, def_id| {
2733         use std::collections::hash_map::Entry::{Occupied, Vacant};
2734
2735         match unique_symbols_rev.entry((ns, ident.name)) {
2736             Occupied(mut v) => match v.get() {
2737                 None => {}
2738                 Some(existing) => {
2739                     if *existing != def_id {
2740                         v.insert(None);
2741                     }
2742                 }
2743             },
2744             Vacant(v) => {
2745                 v.insert(Some(def_id));
2746             }
2747         }
2748     });
2749
2750     for ((_, symbol), opt_def_id) in unique_symbols_rev.drain() {
2751         use std::collections::hash_map::Entry::{Occupied, Vacant};
2752
2753         if let Some(def_id) = opt_def_id {
2754             match map.entry(def_id) {
2755                 Occupied(mut v) => {
2756                     // A single DefId can be known under multiple names (e.g.,
2757                     // with a `pub use ... as ...;`). We need to ensure that the
2758                     // name placed in this map is chosen deterministically, so
2759                     // if we find multiple names (`symbol`) resolving to the
2760                     // same `def_id`, we prefer the lexicographically smallest
2761                     // name.
2762                     //
2763                     // Any stable ordering would be fine here though.
2764                     if *v.get() != symbol {
2765                         if v.get().as_str() > symbol.as_str() {
2766                             v.insert(symbol);
2767                         }
2768                     }
2769                 }
2770                 Vacant(v) => {
2771                     v.insert(symbol);
2772                 }
2773             }
2774         }
2775     }
2776
2777     map
2778 }
2779
2780 pub fn provide(providers: &mut ty::query::Providers) {
2781     *providers = ty::query::Providers { trimmed_def_paths, ..*providers };
2782 }
2783
2784 #[derive(Default)]
2785 pub struct OpaqueFnEntry<'tcx> {
2786     // The trait ref is already stored as a key, so just track if we have it as a real predicate
2787     has_fn_once: bool,
2788     fn_mut_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
2789     fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
2790     return_ty: Option<ty::Binder<'tcx, Term<'tcx>>>,
2791 }