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