]> git.lizzy.rs Git - rust.git/blob - src/librustc_middle/ty/print/pretty.rs
Auto merge of #71331 - Dylan-DPC:rollup-5rn1isc, r=Dylan-DPC
[rust.git] / src / librustc_middle / ty / print / pretty.rs
1 use crate::middle::cstore::{ExternCrate, ExternCrateSource};
2 use crate::middle::region;
3 use crate::mir::interpret::{sign_extend, truncate, AllocId, ConstValue, Pointer, Scalar};
4 use crate::ty::layout::IntegerExt;
5 use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
6 use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
7 use rustc_apfloat::ieee::{Double, Single};
8 use rustc_apfloat::Float;
9 use rustc_ast::ast;
10 use rustc_attr::{SignedInt, UnsignedInt};
11 use rustc_hir as hir;
12 use rustc_hir::def::{DefKind, Namespace};
13 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
14 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
15 use rustc_span::symbol::{kw, Symbol};
16 use rustc_target::abi::{Integer, 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::fmt::{self, Write as _};
23 use std::ops::{Deref, DerefMut};
24
25 // `pretty` is a separate module only for organization.
26 use super::*;
27
28 macro_rules! p {
29     (@write($($data:expr),+)) => {
30         write!(scoped_cx!(), $($data),+)?
31     };
32     (@print($x:expr)) => {
33         scoped_cx!() = $x.print(scoped_cx!())?
34     };
35     (@$method:ident($($arg:expr),*)) => {
36         scoped_cx!() = scoped_cx!().$method($($arg),*)?
37     };
38     ($($kind:ident $data:tt),+) => {{
39         $(p!(@$kind $data);)+
40     }};
41 }
42 macro_rules! define_scoped_cx {
43     ($cx:ident) => {
44         #[allow(unused_macros)]
45         macro_rules! scoped_cx {
46             () => {
47                 $cx
48             };
49         }
50     };
51 }
52
53 thread_local! {
54     static FORCE_IMPL_FILENAME_LINE: Cell<bool> = Cell::new(false);
55     static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = Cell::new(false);
56     static NO_QUERIES: Cell<bool> = Cell::new(false);
57 }
58
59 /// Avoids running any queries during any prints that occur
60 /// during the closure. This may alter the appearance of some
61 /// types (e.g. forcing verbose printing for opaque types).
62 /// This method is used during some queries (e.g. `predicates_of`
63 /// for opaque types), to ensure that any debug printing that
64 /// occurs during the query computation does not end up recursively
65 /// calling the same query.
66 pub fn with_no_queries<F: FnOnce() -> R, R>(f: F) -> R {
67     NO_QUERIES.with(|no_queries| {
68         let old = no_queries.replace(true);
69         let result = f();
70         no_queries.set(old);
71         result
72     })
73 }
74
75 /// Force us to name impls with just the filename/line number. We
76 /// normally try to use types. But at some points, notably while printing
77 /// cycle errors, this can result in extra or suboptimal error output,
78 /// so this variable disables that check.
79 pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
80     FORCE_IMPL_FILENAME_LINE.with(|force| {
81         let old = force.replace(true);
82         let result = f();
83         force.set(old);
84         result
85     })
86 }
87
88 /// Adds the `crate::` prefix to paths where appropriate.
89 pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
90     SHOULD_PREFIX_WITH_CRATE.with(|flag| {
91         let old = flag.replace(true);
92         let result = f();
93         flag.set(old);
94         result
95     })
96 }
97
98 /// The "region highlights" are used to control region printing during
99 /// specific error messages. When a "region highlight" is enabled, it
100 /// gives an alternate way to print specific regions. For now, we
101 /// always print those regions using a number, so something like "`'0`".
102 ///
103 /// Regions not selected by the region highlight mode are presently
104 /// unaffected.
105 #[derive(Copy, Clone, Default)]
106 pub struct RegionHighlightMode {
107     /// If enabled, when we see the selected region, use "`'N`"
108     /// instead of the ordinary behavior.
109     highlight_regions: [Option<(ty::RegionKind, usize)>; 3],
110
111     /// If enabled, when printing a "free region" that originated from
112     /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily
113     /// have names print as normal.
114     ///
115     /// This is used when you have a signature like `fn foo(x: &u32,
116     /// y: &'a u32)` and we want to give a name to the region of the
117     /// reference `x`.
118     highlight_bound_region: Option<(ty::BoundRegion, usize)>,
119 }
120
121 impl RegionHighlightMode {
122     /// If `region` and `number` are both `Some`, invokes
123     /// `highlighting_region`.
124     pub fn maybe_highlighting_region(
125         &mut self,
126         region: Option<ty::Region<'_>>,
127         number: Option<usize>,
128     ) {
129         if let Some(k) = region {
130             if let Some(n) = number {
131                 self.highlighting_region(k, n);
132             }
133         }
134     }
135
136     /// Highlights the region inference variable `vid` as `'N`.
137     pub fn highlighting_region(&mut self, region: ty::Region<'_>, number: usize) {
138         let num_slots = self.highlight_regions.len();
139         let first_avail_slot =
140             self.highlight_regions.iter_mut().find(|s| s.is_none()).unwrap_or_else(|| {
141                 bug!("can only highlight {} placeholders at a time", num_slots,)
142             });
143         *first_avail_slot = Some((*region, number));
144     }
145
146     /// Convenience wrapper for `highlighting_region`.
147     pub fn highlighting_region_vid(&mut self, vid: ty::RegionVid, number: usize) {
148         self.highlighting_region(&ty::ReVar(vid), number)
149     }
150
151     /// Returns `Some(n)` with the number to use for the given region, if any.
152     fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
153         self.highlight_regions
154             .iter()
155             .filter_map(|h| match h {
156                 Some((r, n)) if r == region => Some(*n),
157                 _ => None,
158             })
159             .next()
160     }
161
162     /// Highlight the given bound region.
163     /// We can only highlight one bound region at a time. See
164     /// the field `highlight_bound_region` for more detailed notes.
165     pub fn highlighting_bound_region(&mut self, br: ty::BoundRegion, number: usize) {
166         assert!(self.highlight_bound_region.is_none());
167         self.highlight_bound_region = Some((br, number));
168     }
169 }
170
171 /// Trait for printers that pretty-print using `fmt::Write` to the printer.
172 pub trait PrettyPrinter<'tcx>:
173     Printer<
174         'tcx,
175         Error = fmt::Error,
176         Path = Self,
177         Region = Self,
178         Type = Self,
179         DynExistential = Self,
180         Const = Self,
181     > + fmt::Write
182 {
183     /// Like `print_def_path` but for value paths.
184     fn print_value_path(
185         self,
186         def_id: DefId,
187         substs: &'tcx [GenericArg<'tcx>],
188     ) -> Result<Self::Path, Self::Error> {
189         self.print_def_path(def_id, substs)
190     }
191
192     fn in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, Self::Error>
193     where
194         T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
195     {
196         value.skip_binder().print(self)
197     }
198
199     /// Prints comma-separated elements.
200     fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error>
201     where
202         T: Print<'tcx, Self, Output = Self, Error = Self::Error>,
203     {
204         if let Some(first) = elems.next() {
205             self = first.print(self)?;
206             for elem in elems {
207                 self.write_str(", ")?;
208                 self = elem.print(self)?;
209             }
210         }
211         Ok(self)
212     }
213
214     /// Prints `{f: t}` or `{f as t}` depending on the `cast` argument
215     fn typed_value(
216         mut self,
217         f: impl FnOnce(Self) -> Result<Self, Self::Error>,
218         t: impl FnOnce(Self) -> Result<Self, Self::Error>,
219         conversion: &str,
220     ) -> Result<Self::Const, Self::Error> {
221         self.write_str("{")?;
222         self = f(self)?;
223         self.write_str(conversion)?;
224         self = t(self)?;
225         self.write_str("}")?;
226         Ok(self)
227     }
228
229     /// Prints `<...>` around what `f` prints.
230     fn generic_delimiters(
231         self,
232         f: impl FnOnce(Self) -> Result<Self, Self::Error>,
233     ) -> Result<Self, Self::Error>;
234
235     /// Returns `true` if the region should be printed in
236     /// optional positions, e.g., `&'a T` or `dyn Tr + 'b`.
237     /// This is typically the case for all non-`'_` regions.
238     fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool;
239
240     // Defaults (should not be overridden):
241
242     /// If possible, this returns a global path resolving to `def_id` that is visible
243     /// from at least one local module, and returns `true`. If the crate defining `def_id` is
244     /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
245     fn try_print_visible_def_path(self, def_id: DefId) -> Result<(Self, bool), Self::Error> {
246         let mut callers = Vec::new();
247         self.try_print_visible_def_path_recur(def_id, &mut callers)
248     }
249
250     /// Does the work of `try_print_visible_def_path`, building the
251     /// full definition path recursively before attempting to
252     /// post-process it into the valid and visible version that
253     /// accounts for re-exports.
254     ///
255     /// This method should only be called by itself or
256     /// `try_print_visible_def_path`.
257     ///
258     /// `callers` is a chain of visible_parent's leading to `def_id`,
259     /// to support cycle detection during recursion.
260     fn try_print_visible_def_path_recur(
261         mut self,
262         def_id: DefId,
263         callers: &mut Vec<DefId>,
264     ) -> Result<(Self, bool), Self::Error> {
265         define_scoped_cx!(self);
266
267         debug!("try_print_visible_def_path: def_id={:?}", def_id);
268
269         // If `def_id` is a direct or injected extern crate, return the
270         // path to the crate followed by the path to the item within the crate.
271         if def_id.index == CRATE_DEF_INDEX {
272             let cnum = def_id.krate;
273
274             if cnum == LOCAL_CRATE {
275                 return Ok((self.path_crate(cnum)?, true));
276             }
277
278             // In local mode, when we encounter a crate other than
279             // LOCAL_CRATE, execution proceeds in one of two ways:
280             //
281             // 1. For a direct dependency, where user added an
282             //    `extern crate` manually, we put the `extern
283             //    crate` as the parent. So you wind up with
284             //    something relative to the current crate.
285             // 2. For an extern inferred from a path or an indirect crate,
286             //    where there is no explicit `extern crate`, we just prepend
287             //    the crate name.
288             match self.tcx().extern_crate(def_id) {
289                 Some(&ExternCrate {
290                     src: ExternCrateSource::Extern(def_id),
291                     dependency_of: LOCAL_CRATE,
292                     span,
293                     ..
294                 }) => {
295                     debug!("try_print_visible_def_path: def_id={:?}", def_id);
296                     return Ok((
297                         if !span.is_dummy() {
298                             self.print_def_path(def_id, &[])?
299                         } else {
300                             self.path_crate(cnum)?
301                         },
302                         true,
303                     ));
304                 }
305                 None => {
306                     return Ok((self.path_crate(cnum)?, true));
307                 }
308                 _ => {}
309             }
310         }
311
312         if def_id.is_local() {
313             return Ok((self, false));
314         }
315
316         let visible_parent_map = self.tcx().visible_parent_map(LOCAL_CRATE);
317
318         let mut cur_def_key = self.tcx().def_key(def_id);
319         debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key);
320
321         // For a constructor, we want the name of its parent rather than <unnamed>.
322         if let DefPathData::Ctor = cur_def_key.disambiguated_data.data {
323             let parent = DefId {
324                 krate: def_id.krate,
325                 index: cur_def_key
326                     .parent
327                     .expect("`DefPathData::Ctor` / `VariantData` missing a parent"),
328             };
329
330             cur_def_key = self.tcx().def_key(parent);
331         }
332
333         let visible_parent = match visible_parent_map.get(&def_id).cloned() {
334             Some(parent) => parent,
335             None => return Ok((self, false)),
336         };
337         if callers.contains(&visible_parent) {
338             return Ok((self, false));
339         }
340         callers.push(visible_parent);
341         // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid
342         // knowing ahead of time whether the entire path will succeed or not.
343         // To support printers that do not implement `PrettyPrinter`, a `Vec` or
344         // linked list on the stack would need to be built, before any printing.
345         match self.try_print_visible_def_path_recur(visible_parent, callers)? {
346             (cx, false) => return Ok((cx, false)),
347             (cx, true) => self = cx,
348         }
349         callers.pop();
350         let actual_parent = self.tcx().parent(def_id);
351         debug!(
352             "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
353             visible_parent, actual_parent,
354         );
355
356         let mut data = cur_def_key.disambiguated_data.data;
357         debug!(
358             "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}",
359             data, visible_parent, actual_parent,
360         );
361
362         match data {
363             // In order to output a path that could actually be imported (valid and visible),
364             // we need to handle re-exports correctly.
365             //
366             // For example, take `std::os::unix::process::CommandExt`, this trait is actually
367             // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing).
368             //
369             // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is
370             // private so the "true" path to `CommandExt` isn't accessible.
371             //
372             // In this case, the `visible_parent_map` will look something like this:
373             //
374             // (child) -> (parent)
375             // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process`
376             // `std::sys::unix::ext::process` -> `std::sys::unix::ext`
377             // `std::sys::unix::ext` -> `std::os`
378             //
379             // This is correct, as the visible parent of `std::sys::unix::ext` is in fact
380             // `std::os`.
381             //
382             // When printing the path to `CommandExt` and looking at the `cur_def_key` that
383             // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go
384             // to the parent - resulting in a mangled path like
385             // `std::os::ext::process::CommandExt`.
386             //
387             // Instead, we must detect that there was a re-export and instead print `unix`
388             // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To
389             // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with
390             // the visible parent (`std::os`). If these do not match, then we iterate over
391             // the children of the visible parent (as was done when computing
392             // `visible_parent_map`), looking for the specific child we currently have and then
393             // have access to the re-exported name.
394             DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => {
395                 let reexport = self
396                     .tcx()
397                     .item_children(visible_parent)
398                     .iter()
399                     .find(|child| child.res.def_id() == def_id)
400                     .map(|child| child.ident.name);
401                 if let Some(reexport) = reexport {
402                     *name = reexport;
403                 }
404             }
405             // Re-exported `extern crate` (#43189).
406             DefPathData::CrateRoot => {
407                 data = DefPathData::TypeNs(self.tcx().original_crate_name(def_id.krate));
408             }
409             _ => {}
410         }
411         debug!("try_print_visible_def_path: data={:?}", data);
412
413         Ok((self.path_append(Ok, &DisambiguatedDefPathData { data, disambiguator: 0 })?, true))
414     }
415
416     fn pretty_path_qualified(
417         self,
418         self_ty: Ty<'tcx>,
419         trait_ref: Option<ty::TraitRef<'tcx>>,
420     ) -> Result<Self::Path, Self::Error> {
421         if trait_ref.is_none() {
422             // Inherent impls. Try to print `Foo::bar` for an inherent
423             // impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
424             // anything other than a simple path.
425             match self_ty.kind {
426                 ty::Adt(..)
427                 | ty::Foreign(_)
428                 | ty::Bool
429                 | ty::Char
430                 | ty::Str
431                 | ty::Int(_)
432                 | ty::Uint(_)
433                 | ty::Float(_) => {
434                     return self_ty.print(self);
435                 }
436
437                 _ => {}
438             }
439         }
440
441         self.generic_delimiters(|mut cx| {
442             define_scoped_cx!(cx);
443
444             p!(print(self_ty));
445             if let Some(trait_ref) = trait_ref {
446                 p!(write(" as "), print(trait_ref.print_only_trait_path()));
447             }
448             Ok(cx)
449         })
450     }
451
452     fn pretty_path_append_impl(
453         mut self,
454         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
455         self_ty: Ty<'tcx>,
456         trait_ref: Option<ty::TraitRef<'tcx>>,
457     ) -> Result<Self::Path, Self::Error> {
458         self = print_prefix(self)?;
459
460         self.generic_delimiters(|mut cx| {
461             define_scoped_cx!(cx);
462
463             p!(write("impl "));
464             if let Some(trait_ref) = trait_ref {
465                 p!(print(trait_ref.print_only_trait_path()), write(" for "));
466             }
467             p!(print(self_ty));
468
469             Ok(cx)
470         })
471     }
472
473     fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
474         define_scoped_cx!(self);
475
476         match ty.kind {
477             ty::Bool => p!(write("bool")),
478             ty::Char => p!(write("char")),
479             ty::Int(t) => p!(write("{}", t.name_str())),
480             ty::Uint(t) => p!(write("{}", t.name_str())),
481             ty::Float(t) => p!(write("{}", t.name_str())),
482             ty::RawPtr(ref tm) => {
483                 p!(write(
484                     "*{} ",
485                     match tm.mutbl {
486                         hir::Mutability::Mut => "mut",
487                         hir::Mutability::Not => "const",
488                     }
489                 ));
490                 p!(print(tm.ty))
491             }
492             ty::Ref(r, ty, mutbl) => {
493                 p!(write("&"));
494                 if self.region_should_not_be_omitted(r) {
495                     p!(print(r), write(" "));
496                 }
497                 p!(print(ty::TypeAndMut { ty, mutbl }))
498             }
499             ty::Never => p!(write("!")),
500             ty::Tuple(ref tys) => {
501                 p!(write("("));
502                 let mut tys = tys.iter();
503                 if let Some(&ty) = tys.next() {
504                     p!(print(ty), write(","));
505                     if let Some(&ty) = tys.next() {
506                         p!(write(" "), print(ty));
507                         for &ty in tys {
508                             p!(write(", "), print(ty));
509                         }
510                     }
511                 }
512                 p!(write(")"))
513             }
514             ty::FnDef(def_id, substs) => {
515                 let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs);
516                 p!(print(sig), write(" {{"), print_value_path(def_id, substs), write("}}"));
517             }
518             ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
519             ty::Infer(infer_ty) => {
520                 if let ty::TyVar(ty_vid) = infer_ty {
521                     if let Some(name) = self.infer_ty_name(ty_vid) {
522                         p!(write("{}", name))
523                     } else {
524                         p!(write("{}", infer_ty))
525                     }
526                 } else {
527                     p!(write("{}", infer_ty))
528                 }
529             }
530             ty::Error => p!(write("[type error]")),
531             ty::Param(ref param_ty) => p!(write("{}", param_ty)),
532             ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
533                 ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?,
534                 ty::BoundTyKind::Param(p) => p!(write("{}", p)),
535             },
536             ty::Adt(def, substs) => {
537                 p!(print_def_path(def.did, substs));
538             }
539             ty::Dynamic(data, r) => {
540                 let print_r = self.region_should_not_be_omitted(r);
541                 if print_r {
542                     p!(write("("));
543                 }
544                 p!(write("dyn "), print(data));
545                 if print_r {
546                     p!(write(" + "), print(r), write(")"));
547                 }
548             }
549             ty::Foreign(def_id) => {
550                 p!(print_def_path(def_id, &[]));
551             }
552             ty::Projection(ref data) => p!(print(data)),
553             ty::UnnormalizedProjection(ref data) => {
554                 p!(write("Unnormalized("), print(data), write(")"))
555             }
556             ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
557             ty::Opaque(def_id, substs) => {
558                 // FIXME(eddyb) print this with `print_def_path`.
559                 // We use verbose printing in 'NO_QUERIES' mode, to
560                 // avoid needing to call `predicates_of`. This should
561                 // only affect certain debug messages (e.g. messages printed
562                 // from `rustc_middle::ty` during the computation of `tcx.predicates_of`),
563                 // and should have no effect on any compiler output.
564                 if self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()) {
565                     p!(write("Opaque({:?}, {:?})", def_id, substs));
566                     return Ok(self);
567                 }
568
569                 return Ok(with_no_queries(|| {
570                     let def_key = self.tcx().def_key(def_id);
571                     if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
572                         p!(write("{}", name));
573                         let mut substs = substs.iter();
574                         // FIXME(eddyb) print this with `print_def_path`.
575                         if let Some(first) = substs.next() {
576                             p!(write("::<"));
577                             p!(print(first));
578                             for subst in substs {
579                                 p!(write(", "), print(subst));
580                             }
581                             p!(write(">"));
582                         }
583                         return Ok(self);
584                     }
585                     // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
586                     // by looking up the projections associated with the def_id.
587                     let bounds = self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs);
588
589                     let mut first = true;
590                     let mut is_sized = false;
591                     p!(write("impl"));
592                     for predicate in bounds.predicates {
593                         if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
594                             // Don't print +Sized, but rather +?Sized if absent.
595                             if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
596                                 is_sized = true;
597                                 continue;
598                             }
599
600                             p!(
601                                 write("{}", if first { " " } else { "+" }),
602                                 print(trait_ref.print_only_trait_path())
603                             );
604                             first = false;
605                         }
606                     }
607                     if !is_sized {
608                         p!(write("{}?Sized", if first { " " } else { "+" }));
609                     } else if first {
610                         p!(write(" Sized"));
611                     }
612                     Ok(self)
613                 })?);
614             }
615             ty::Str => p!(write("str")),
616             ty::Generator(did, substs, movability) => {
617                 match movability {
618                     hir::Movability::Movable => p!(write("[generator")),
619                     hir::Movability::Static => p!(write("[static generator")),
620                 }
621
622                 // FIXME(eddyb) should use `def_span`.
623                 if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
624                     p!(write("@{:?}", self.tcx().hir().span(hir_id)));
625
626                     if substs.as_generator().is_valid() {
627                         let upvar_tys = substs.as_generator().upvar_tys();
628                         let mut sep = " ";
629                         for (&var_id, upvar_ty) in self
630                             .tcx()
631                             .upvars(did)
632                             .as_ref()
633                             .iter()
634                             .flat_map(|v| v.keys())
635                             .zip(upvar_tys)
636                         {
637                             p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
638                             sep = ", ";
639                         }
640                     }
641                 } else {
642                     p!(write("@{}", self.tcx().def_path_str(did)));
643
644                     if substs.as_generator().is_valid() {
645                         let upvar_tys = substs.as_generator().upvar_tys();
646                         let mut sep = " ";
647                         for (index, upvar_ty) in upvar_tys.enumerate() {
648                             p!(write("{}{}:", sep, index), print(upvar_ty));
649                             sep = ", ";
650                         }
651                     }
652                 }
653
654                 if substs.as_generator().is_valid() {
655                     p!(write(" "), print(substs.as_generator().witness()));
656                 }
657
658                 p!(write("]"))
659             }
660             ty::GeneratorWitness(types) => {
661                 p!(in_binder(&types));
662             }
663             ty::Closure(did, substs) => {
664                 p!(write("[closure"));
665
666                 // FIXME(eddyb) should use `def_span`.
667                 if let Some(hir_id) = self.tcx().hir().as_local_hir_id(did) {
668                     if self.tcx().sess.opts.debugging_opts.span_free_formats {
669                         p!(write("@"), print_def_path(did, substs));
670                     } else {
671                         p!(write("@{:?}", self.tcx().hir().span(hir_id)));
672                     }
673
674                     if substs.as_closure().is_valid() {
675                         let upvar_tys = substs.as_closure().upvar_tys();
676                         let mut sep = " ";
677                         for (&var_id, upvar_ty) in self
678                             .tcx()
679                             .upvars(did)
680                             .as_ref()
681                             .iter()
682                             .flat_map(|v| v.keys())
683                             .zip(upvar_tys)
684                         {
685                             p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
686                             sep = ", ";
687                         }
688                     }
689                 } else {
690                     p!(write("@{}", self.tcx().def_path_str(did)));
691
692                     if substs.as_closure().is_valid() {
693                         let upvar_tys = substs.as_closure().upvar_tys();
694                         let mut sep = " ";
695                         for (index, upvar_ty) in upvar_tys.enumerate() {
696                             p!(write("{}{}:", sep, index), print(upvar_ty));
697                             sep = ", ";
698                         }
699                     }
700                 }
701
702                 if self.tcx().sess.verbose() && substs.as_closure().is_valid() {
703                     p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
704                     p!(
705                         write(" closure_sig_as_fn_ptr_ty="),
706                         print(substs.as_closure().sig_as_fn_ptr_ty())
707                     );
708                 }
709
710                 p!(write("]"))
711             }
712             ty::Array(ty, sz) => {
713                 p!(write("["), print(ty), write("; "));
714                 if self.tcx().sess.verbose() {
715                     p!(write("{:?}", sz));
716                 } else if let ty::ConstKind::Unevaluated(..) = sz.val {
717                     // do not try to evaluate unevaluated constants. If we are const evaluating an
718                     // array length anon const, rustc will (with debug assertions) print the
719                     // constant's path. Which will end up here again.
720                     p!(write("_"));
721                 } else if let Some(n) = sz.val.try_to_bits(self.tcx().data_layout.pointer_size) {
722                     p!(write("{}", n));
723                 } else {
724                     p!(write("_"));
725                 }
726                 p!(write("]"))
727             }
728             ty::Slice(ty) => p!(write("["), print(ty), write("]")),
729         }
730
731         Ok(self)
732     }
733
734     fn pretty_print_bound_var(
735         &mut self,
736         debruijn: ty::DebruijnIndex,
737         var: ty::BoundVar,
738     ) -> Result<(), Self::Error> {
739         if debruijn == ty::INNERMOST {
740             write!(self, "^{}", var.index())
741         } else {
742             write!(self, "^{}_{}", debruijn.index(), var.index())
743         }
744     }
745
746     fn infer_ty_name(&self, _: ty::TyVid) -> Option<String> {
747         None
748     }
749
750     fn pretty_print_dyn_existential(
751         mut self,
752         predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
753     ) -> Result<Self::DynExistential, Self::Error> {
754         define_scoped_cx!(self);
755
756         // Generate the main trait ref, including associated types.
757         let mut first = true;
758
759         if let Some(principal) = predicates.principal() {
760             p!(print_def_path(principal.def_id, &[]));
761
762             let mut resugared = false;
763
764             // Special-case `Fn(...) -> ...` and resugar it.
765             let fn_trait_kind = self.tcx().fn_trait_kind_from_lang_item(principal.def_id);
766             if !self.tcx().sess.verbose() && fn_trait_kind.is_some() {
767                 if let ty::Tuple(ref args) = principal.substs.type_at(0).kind {
768                     let mut projections = predicates.projection_bounds();
769                     if let (Some(proj), None) = (projections.next(), projections.next()) {
770                         let tys: Vec<_> = args.iter().map(|k| k.expect_ty()).collect();
771                         p!(pretty_fn_sig(&tys, false, proj.ty));
772                         resugared = true;
773                     }
774                 }
775             }
776
777             // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`,
778             // in order to place the projections inside the `<...>`.
779             if !resugared {
780                 // Use a type that can't appear in defaults of type parameters.
781                 let dummy_self = self.tcx().mk_ty_infer(ty::FreshTy(0));
782                 let principal = principal.with_self_ty(self.tcx(), dummy_self);
783
784                 let args = self.generic_args_to_print(
785                     self.tcx().generics_of(principal.def_id),
786                     principal.substs,
787                 );
788
789                 // Don't print `'_` if there's no unerased regions.
790                 let print_regions = args.iter().any(|arg| match arg.unpack() {
791                     GenericArgKind::Lifetime(r) => *r != ty::ReErased,
792                     _ => false,
793                 });
794                 let mut args = args.iter().cloned().filter(|arg| match arg.unpack() {
795                     GenericArgKind::Lifetime(_) => print_regions,
796                     _ => true,
797                 });
798                 let mut projections = predicates.projection_bounds();
799
800                 let arg0 = args.next();
801                 let projection0 = projections.next();
802                 if arg0.is_some() || projection0.is_some() {
803                     let args = arg0.into_iter().chain(args);
804                     let projections = projection0.into_iter().chain(projections);
805
806                     p!(generic_delimiters(|mut cx| {
807                         cx = cx.comma_sep(args)?;
808                         if arg0.is_some() && projection0.is_some() {
809                             write!(cx, ", ")?;
810                         }
811                         cx.comma_sep(projections)
812                     }));
813                 }
814             }
815             first = false;
816         }
817
818         // Builtin bounds.
819         // FIXME(eddyb) avoid printing twice (needed to ensure
820         // that the auto traits are sorted *and* printed via cx).
821         let mut auto_traits: Vec<_> =
822             predicates.auto_traits().map(|did| (self.tcx().def_path_str(did), did)).collect();
823
824         // The auto traits come ordered by `DefPathHash`. While
825         // `DefPathHash` is *stable* in the sense that it depends on
826         // neither the host nor the phase of the moon, it depends
827         // "pseudorandomly" on the compiler version and the target.
828         //
829         // To avoid that causing instabilities in compiletest
830         // output, sort the auto-traits alphabetically.
831         auto_traits.sort();
832
833         for (_, def_id) in auto_traits {
834             if !first {
835                 p!(write(" + "));
836             }
837             first = false;
838
839             p!(print_def_path(def_id, &[]));
840         }
841
842         Ok(self)
843     }
844
845     fn pretty_fn_sig(
846         mut self,
847         inputs: &[Ty<'tcx>],
848         c_variadic: bool,
849         output: Ty<'tcx>,
850     ) -> Result<Self, Self::Error> {
851         define_scoped_cx!(self);
852
853         p!(write("("));
854         let mut inputs = inputs.iter();
855         if let Some(&ty) = inputs.next() {
856             p!(print(ty));
857             for &ty in inputs {
858                 p!(write(", "), print(ty));
859             }
860             if c_variadic {
861                 p!(write(", ..."));
862             }
863         }
864         p!(write(")"));
865         if !output.is_unit() {
866             p!(write(" -> "), print(output));
867         }
868
869         Ok(self)
870     }
871
872     fn pretty_print_const(
873         mut self,
874         ct: &'tcx ty::Const<'tcx>,
875         print_ty: bool,
876     ) -> Result<Self::Const, Self::Error> {
877         define_scoped_cx!(self);
878
879         if self.tcx().sess.verbose() {
880             p!(write("Const({:?}: {:?})", ct.val, ct.ty));
881             return Ok(self);
882         }
883
884         macro_rules! print_underscore {
885             () => {{
886                 if print_ty {
887                     self = self.typed_value(
888                         |mut this| {
889                             write!(this, "_")?;
890                             Ok(this)
891                         },
892                         |this| this.print_type(ct.ty),
893                         ": ",
894                     )?;
895                 } else {
896                     write!(self, "_")?;
897                 }
898             }};
899         }
900
901         match ct.val {
902             ty::ConstKind::Unevaluated(did, substs, promoted) => {
903                 if let Some(promoted) = promoted {
904                     p!(print_value_path(did, substs));
905                     p!(write("::{:?}", promoted));
906                 } else {
907                     match self.tcx().def_kind(did) {
908                         Some(DefKind::Static | DefKind::Const | DefKind::AssocConst) => {
909                             p!(print_value_path(did, substs))
910                         }
911                         _ => {
912                             if did.is_local() {
913                                 let span = self.tcx().def_span(did);
914                                 if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
915                                 {
916                                     p!(write("{}", snip))
917                                 } else {
918                                     print_underscore!()
919                                 }
920                             } else {
921                                 print_underscore!()
922                             }
923                         }
924                     }
925                 }
926             }
927             ty::ConstKind::Infer(..) => print_underscore!(),
928             ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
929             ty::ConstKind::Value(value) => {
930                 return self.pretty_print_const_value(value, ct.ty, print_ty);
931             }
932
933             ty::ConstKind::Bound(debruijn, bound_var) => {
934                 self.pretty_print_bound_var(debruijn, bound_var)?
935             }
936             ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
937             ty::ConstKind::Error => p!(write("[const error]")),
938         };
939         Ok(self)
940     }
941
942     fn pretty_print_const_scalar(
943         mut self,
944         scalar: Scalar,
945         ty: Ty<'tcx>,
946         print_ty: bool,
947     ) -> Result<Self::Const, Self::Error> {
948         define_scoped_cx!(self);
949
950         match (scalar, &ty.kind) {
951             // Byte strings (&[u8; N])
952             (
953                 Scalar::Ptr(ptr),
954                 ty::Ref(
955                     _,
956                     ty::TyS {
957                         kind:
958                             ty::Array(
959                                 ty::TyS { kind: ty::Uint(ast::UintTy::U8), .. },
960                                 ty::Const {
961                                     val:
962                                         ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw {
963                                             data,
964                                             ..
965                                         })),
966                                     ..
967                                 },
968                             ),
969                         ..
970                     },
971                     _,
972                 ),
973             ) => {
974                 let byte_str = self
975                     .tcx()
976                     .alloc_map
977                     .lock()
978                     .unwrap_memory(ptr.alloc_id)
979                     .get_bytes(&self.tcx(), ptr, Size::from_bytes(*data))
980                     .unwrap();
981                 p!(pretty_print_byte_str(byte_str));
982             }
983             // Bool
984             (Scalar::Raw { data: 0, .. }, ty::Bool) => p!(write("false")),
985             (Scalar::Raw { data: 1, .. }, ty::Bool) => p!(write("true")),
986             // Float
987             (Scalar::Raw { data, .. }, ty::Float(ast::FloatTy::F32)) => {
988                 p!(write("{}f32", Single::from_bits(data)))
989             }
990             (Scalar::Raw { data, .. }, ty::Float(ast::FloatTy::F64)) => {
991                 p!(write("{}f64", Double::from_bits(data)))
992             }
993             // Int
994             (Scalar::Raw { data, .. }, ty::Uint(ui)) => {
995                 let bit_size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size();
996                 let max = truncate(u128::MAX, bit_size);
997
998                 let ui_str = ui.name_str();
999                 if data == max {
1000                     p!(write("std::{}::MAX", ui_str))
1001                 } else {
1002                     if print_ty { p!(write("{}{}", data, ui_str)) } else { p!(write("{}", data)) }
1003                 };
1004             }
1005             (Scalar::Raw { data, .. }, ty::Int(i)) => {
1006                 let size = Integer::from_attr(&self.tcx(), SignedInt(*i)).size();
1007                 let bit_size = size.bits() as u128;
1008                 let min = 1u128 << (bit_size - 1);
1009                 let max = min - 1;
1010
1011                 let i_str = i.name_str();
1012                 match data {
1013                     d if d == min => p!(write("std::{}::MIN", i_str)),
1014                     d if d == max => p!(write("std::{}::MAX", i_str)),
1015                     _ => {
1016                         let data = sign_extend(data, size) as i128;
1017                         if print_ty {
1018                             p!(write("{}{}", data, i_str))
1019                         } else {
1020                             p!(write("{}", data))
1021                         }
1022                     }
1023                 }
1024             }
1025             // Char
1026             (Scalar::Raw { data, .. }, ty::Char) if char::from_u32(data as u32).is_some() => {
1027                 p!(write("{:?}", char::from_u32(data as u32).unwrap()))
1028             }
1029             // Raw pointers
1030             (Scalar::Raw { data, .. }, ty::RawPtr(_)) => {
1031                 self = self.typed_value(
1032                     |mut this| {
1033                         write!(this, "0x{:x}", data)?;
1034                         Ok(this)
1035                     },
1036                     |this| this.print_type(ty),
1037                     " as ",
1038                 )?;
1039             }
1040             (Scalar::Ptr(ptr), ty::FnPtr(_)) => {
1041                 let instance = {
1042                     let alloc_map = self.tcx().alloc_map.lock();
1043                     alloc_map.unwrap_fn(ptr.alloc_id)
1044                 };
1045                 self = self.typed_value(
1046                     |this| this.print_value_path(instance.def_id(), instance.substs),
1047                     |this| this.print_type(ty),
1048                     " as ",
1049                 )?;
1050             }
1051             // For function type zsts just printing the path is enough
1052             (Scalar::Raw { size: 0, .. }, ty::FnDef(d, s)) => p!(print_value_path(*d, s)),
1053             // Empty tuples are frequently occurring, so don't print the fallback.
1054             (Scalar::Raw { size: 0, .. }, ty::Tuple(ts)) if ts.is_empty() => p!(write("()")),
1055             // Zero element arrays have a trivial representation.
1056             (
1057                 Scalar::Raw { size: 0, .. },
1058                 ty::Array(
1059                     _,
1060                     ty::Const {
1061                         val: ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw { data: 0, .. })),
1062                         ..
1063                     },
1064                 ),
1065             ) => p!(write("[]")),
1066             // Nontrivial types with scalar bit representation
1067             (Scalar::Raw { data, size }, _) => {
1068                 let print = |mut this: Self| {
1069                     if size == 0 {
1070                         write!(this, "transmute(())")?;
1071                     } else {
1072                         write!(this, "transmute(0x{:01$x})", data, size as usize * 2)?;
1073                     }
1074                     Ok(this)
1075                 };
1076                 self = if print_ty {
1077                     self.typed_value(print, |this| this.print_type(ty), ": ")?
1078                 } else {
1079                     print(self)?
1080                 };
1081             }
1082             // Any pointer values not covered by a branch above
1083             (Scalar::Ptr(p), _) => {
1084                 self = self.pretty_print_const_pointer(p, ty, print_ty)?;
1085             }
1086         }
1087         Ok(self)
1088     }
1089
1090     /// This is overridden for MIR printing because we only want to hide alloc ids from users, not
1091     /// from MIR where it is actually useful.
1092     fn pretty_print_const_pointer(
1093         mut self,
1094         _: Pointer,
1095         ty: Ty<'tcx>,
1096         print_ty: bool,
1097     ) -> Result<Self::Const, Self::Error> {
1098         if print_ty {
1099             self.typed_value(
1100                 |mut this| {
1101                     this.write_str("&_")?;
1102                     Ok(this)
1103                 },
1104                 |this| this.print_type(ty),
1105                 ": ",
1106             )
1107         } else {
1108             self.write_str("&_")?;
1109             Ok(self)
1110         }
1111     }
1112
1113     fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result<Self::Const, Self::Error> {
1114         define_scoped_cx!(self);
1115         p!(write("b\""));
1116         for &c in byte_str {
1117             for e in std::ascii::escape_default(c) {
1118                 self.write_char(e as char)?;
1119             }
1120         }
1121         p!(write("\""));
1122         Ok(self)
1123     }
1124
1125     fn pretty_print_const_value(
1126         mut self,
1127         ct: ConstValue<'tcx>,
1128         ty: Ty<'tcx>,
1129         print_ty: bool,
1130     ) -> Result<Self::Const, Self::Error> {
1131         define_scoped_cx!(self);
1132
1133         if self.tcx().sess.verbose() {
1134             p!(write("ConstValue({:?}: {:?})", ct, ty));
1135             return Ok(self);
1136         }
1137
1138         let u8_type = self.tcx().types.u8;
1139
1140         match (ct, &ty.kind) {
1141             (ConstValue::Scalar(scalar), _) => self.pretty_print_const_scalar(scalar, ty, print_ty),
1142             (
1143                 ConstValue::Slice { data, start, end },
1144                 ty::Ref(_, ty::TyS { kind: ty::Slice(t), .. }, _),
1145             ) if *t == u8_type => {
1146                 // The `inspect` here is okay since we checked the bounds, and there are
1147                 // no relocations (we have an active slice reference here). We don't use
1148                 // this result to affect interpreter execution.
1149                 let byte_str = data.inspect_with_undef_and_ptr_outside_interpreter(start..end);
1150                 self.pretty_print_byte_str(byte_str)
1151             }
1152             (
1153                 ConstValue::Slice { data, start, end },
1154                 ty::Ref(_, ty::TyS { kind: ty::Str, .. }, _),
1155             ) => {
1156                 // The `inspect` here is okay since we checked the bounds, and there are no
1157                 // relocations (we have an active `str` reference here). We don't use this
1158                 // result to affect interpreter execution.
1159                 let slice = data.inspect_with_undef_and_ptr_outside_interpreter(start..end);
1160                 let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
1161                 p!(write("{:?}", s));
1162                 Ok(self)
1163             }
1164             (ConstValue::ByRef { alloc, offset }, ty::Array(t, n)) if *t == u8_type => {
1165                 let n = n.val.try_to_bits(self.tcx().data_layout.pointer_size).unwrap();
1166                 // cast is ok because we already checked for pointer size (32 or 64 bit) above
1167                 let n = Size::from_bytes(n);
1168                 let ptr = Pointer::new(AllocId(0), offset);
1169
1170                 let byte_str = alloc.get_bytes(&self.tcx(), ptr, n).unwrap();
1171                 p!(write("*"));
1172                 p!(pretty_print_byte_str(byte_str));
1173                 Ok(self)
1174             }
1175             // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
1176             // their fields instead of just dumping the memory.
1177             _ => {
1178                 // fallback
1179                 p!(write("{:?}", ct));
1180                 if print_ty {
1181                     p!(write(": "), print(ty));
1182                 }
1183                 Ok(self)
1184             }
1185         }
1186     }
1187 }
1188
1189 // HACK(eddyb) boxed to avoid moving around a large struct by-value.
1190 pub struct FmtPrinter<'a, 'tcx, F>(Box<FmtPrinterData<'a, 'tcx, F>>);
1191
1192 pub struct FmtPrinterData<'a, 'tcx, F> {
1193     tcx: TyCtxt<'tcx>,
1194     fmt: F,
1195
1196     empty_path: bool,
1197     in_value: bool,
1198     pub print_alloc_ids: bool,
1199
1200     used_region_names: FxHashSet<Symbol>,
1201     region_index: usize,
1202     binder_depth: usize,
1203
1204     pub region_highlight_mode: RegionHighlightMode,
1205
1206     pub name_resolver: Option<Box<&'a dyn Fn(ty::sty::TyVid) -> Option<String>>>,
1207 }
1208
1209 impl<F> Deref for FmtPrinter<'a, 'tcx, F> {
1210     type Target = FmtPrinterData<'a, 'tcx, F>;
1211     fn deref(&self) -> &Self::Target {
1212         &self.0
1213     }
1214 }
1215
1216 impl<F> DerefMut for FmtPrinter<'_, '_, F> {
1217     fn deref_mut(&mut self) -> &mut Self::Target {
1218         &mut self.0
1219     }
1220 }
1221
1222 impl<F> FmtPrinter<'a, 'tcx, F> {
1223     pub fn new(tcx: TyCtxt<'tcx>, fmt: F, ns: Namespace) -> Self {
1224         FmtPrinter(Box::new(FmtPrinterData {
1225             tcx,
1226             fmt,
1227             empty_path: false,
1228             in_value: ns == Namespace::ValueNS,
1229             print_alloc_ids: false,
1230             used_region_names: Default::default(),
1231             region_index: 0,
1232             binder_depth: 0,
1233             region_highlight_mode: RegionHighlightMode::default(),
1234             name_resolver: None,
1235         }))
1236     }
1237 }
1238
1239 // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
1240 // (but also some things just print a `DefId` generally so maybe we need this?)
1241 fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace {
1242     match tcx.def_key(def_id).disambiguated_data.data {
1243         DefPathData::TypeNs(..) | DefPathData::CrateRoot | DefPathData::ImplTrait => {
1244             Namespace::TypeNS
1245         }
1246
1247         DefPathData::ValueNs(..)
1248         | DefPathData::AnonConst
1249         | DefPathData::ClosureExpr
1250         | DefPathData::Ctor => Namespace::ValueNS,
1251
1252         DefPathData::MacroNs(..) => Namespace::MacroNS,
1253
1254         _ => Namespace::TypeNS,
1255     }
1256 }
1257
1258 impl TyCtxt<'t> {
1259     /// Returns a string identifying this `DefId`. This string is
1260     /// suitable for user output.
1261     pub fn def_path_str(self, def_id: DefId) -> String {
1262         self.def_path_str_with_substs(def_id, &[])
1263     }
1264
1265     pub fn def_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String {
1266         let ns = guess_def_namespace(self, def_id);
1267         debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns);
1268         let mut s = String::new();
1269         let _ = FmtPrinter::new(self, &mut s, ns).print_def_path(def_id, substs);
1270         s
1271     }
1272 }
1273
1274 impl<F: fmt::Write> fmt::Write for FmtPrinter<'_, '_, F> {
1275     fn write_str(&mut self, s: &str) -> fmt::Result {
1276         self.fmt.write_str(s)
1277     }
1278 }
1279
1280 impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
1281     type Error = fmt::Error;
1282
1283     type Path = Self;
1284     type Region = Self;
1285     type Type = Self;
1286     type DynExistential = Self;
1287     type Const = Self;
1288
1289     fn tcx(&'a self) -> TyCtxt<'tcx> {
1290         self.tcx
1291     }
1292
1293     fn print_def_path(
1294         mut self,
1295         def_id: DefId,
1296         substs: &'tcx [GenericArg<'tcx>],
1297     ) -> Result<Self::Path, Self::Error> {
1298         define_scoped_cx!(self);
1299
1300         if substs.is_empty() {
1301             match self.try_print_visible_def_path(def_id)? {
1302                 (cx, true) => return Ok(cx),
1303                 (cx, false) => self = cx,
1304             }
1305         }
1306
1307         let key = self.tcx.def_key(def_id);
1308         if let DefPathData::Impl = key.disambiguated_data.data {
1309             // Always use types for non-local impls, where types are always
1310             // available, and filename/line-number is mostly uninteresting.
1311             let use_types = !def_id.is_local() || {
1312                 // Otherwise, use filename/line-number if forced.
1313                 let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
1314                 !force_no_types
1315             };
1316
1317             if !use_types {
1318                 // If no type info is available, fall back to
1319                 // pretty printing some span information. This should
1320                 // only occur very early in the compiler pipeline.
1321                 let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
1322                 let span = self.tcx.def_span(def_id);
1323
1324                 self = self.print_def_path(parent_def_id, &[])?;
1325
1326                 // HACK(eddyb) copy of `path_append` to avoid
1327                 // constructing a `DisambiguatedDefPathData`.
1328                 if !self.empty_path {
1329                     write!(self, "::")?;
1330                 }
1331                 write!(self, "<impl at {:?}>", span)?;
1332                 self.empty_path = false;
1333
1334                 return Ok(self);
1335             }
1336         }
1337
1338         self.default_print_def_path(def_id, substs)
1339     }
1340
1341     fn print_region(self, region: ty::Region<'_>) -> Result<Self::Region, Self::Error> {
1342         self.pretty_print_region(region)
1343     }
1344
1345     fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
1346         self.pretty_print_type(ty)
1347     }
1348
1349     fn print_dyn_existential(
1350         self,
1351         predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
1352     ) -> Result<Self::DynExistential, Self::Error> {
1353         self.pretty_print_dyn_existential(predicates)
1354     }
1355
1356     fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
1357         self.pretty_print_const(ct, true)
1358     }
1359
1360     fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
1361         self.empty_path = true;
1362         if cnum == LOCAL_CRATE {
1363             if self.tcx.sess.rust_2018() {
1364                 // We add the `crate::` keyword on Rust 2018, only when desired.
1365                 if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
1366                     write!(self, "{}", kw::Crate)?;
1367                     self.empty_path = false;
1368                 }
1369             }
1370         } else {
1371             write!(self, "{}", self.tcx.crate_name(cnum))?;
1372             self.empty_path = false;
1373         }
1374         Ok(self)
1375     }
1376
1377     fn path_qualified(
1378         mut self,
1379         self_ty: Ty<'tcx>,
1380         trait_ref: Option<ty::TraitRef<'tcx>>,
1381     ) -> Result<Self::Path, Self::Error> {
1382         self = self.pretty_path_qualified(self_ty, trait_ref)?;
1383         self.empty_path = false;
1384         Ok(self)
1385     }
1386
1387     fn path_append_impl(
1388         mut self,
1389         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
1390         _disambiguated_data: &DisambiguatedDefPathData,
1391         self_ty: Ty<'tcx>,
1392         trait_ref: Option<ty::TraitRef<'tcx>>,
1393     ) -> Result<Self::Path, Self::Error> {
1394         self = self.pretty_path_append_impl(
1395             |mut cx| {
1396                 cx = print_prefix(cx)?;
1397                 if !cx.empty_path {
1398                     write!(cx, "::")?;
1399                 }
1400
1401                 Ok(cx)
1402             },
1403             self_ty,
1404             trait_ref,
1405         )?;
1406         self.empty_path = false;
1407         Ok(self)
1408     }
1409
1410     fn path_append(
1411         mut self,
1412         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
1413         disambiguated_data: &DisambiguatedDefPathData,
1414     ) -> Result<Self::Path, Self::Error> {
1415         self = print_prefix(self)?;
1416
1417         // Skip `::{{constructor}}` on tuple/unit structs.
1418         if let DefPathData::Ctor = disambiguated_data.data {
1419             return Ok(self);
1420         }
1421
1422         // FIXME(eddyb) `name` should never be empty, but it
1423         // currently is for `extern { ... }` "foreign modules".
1424         let name = disambiguated_data.data.as_symbol().as_str();
1425         if !name.is_empty() {
1426             if !self.empty_path {
1427                 write!(self, "::")?;
1428             }
1429             if ast::Ident::from_str(&name).is_raw_guess() {
1430                 write!(self, "r#")?;
1431             }
1432             write!(self, "{}", name)?;
1433
1434             // FIXME(eddyb) this will print e.g. `{{closure}}#3`, but it
1435             // might be nicer to use something else, e.g. `{closure#3}`.
1436             let dis = disambiguated_data.disambiguator;
1437             let print_dis = disambiguated_data.data.get_opt_name().is_none()
1438                 || dis != 0 && self.tcx.sess.verbose();
1439             if print_dis {
1440                 write!(self, "#{}", dis)?;
1441             }
1442
1443             self.empty_path = false;
1444         }
1445
1446         Ok(self)
1447     }
1448
1449     fn path_generic_args(
1450         mut self,
1451         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
1452         args: &[GenericArg<'tcx>],
1453     ) -> Result<Self::Path, Self::Error> {
1454         self = print_prefix(self)?;
1455
1456         // Don't print `'_` if there's no unerased regions.
1457         let print_regions = args.iter().any(|arg| match arg.unpack() {
1458             GenericArgKind::Lifetime(r) => *r != ty::ReErased,
1459             _ => false,
1460         });
1461         let args = args.iter().cloned().filter(|arg| match arg.unpack() {
1462             GenericArgKind::Lifetime(_) => print_regions,
1463             _ => true,
1464         });
1465
1466         if args.clone().next().is_some() {
1467             if self.in_value {
1468                 write!(self, "::")?;
1469             }
1470             self.generic_delimiters(|cx| cx.comma_sep(args))
1471         } else {
1472             Ok(self)
1473         }
1474     }
1475 }
1476
1477 impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
1478     fn infer_ty_name(&self, id: ty::TyVid) -> Option<String> {
1479         self.0.name_resolver.as_ref().and_then(|func| func(id))
1480     }
1481
1482     fn print_value_path(
1483         mut self,
1484         def_id: DefId,
1485         substs: &'tcx [GenericArg<'tcx>],
1486     ) -> Result<Self::Path, Self::Error> {
1487         let was_in_value = std::mem::replace(&mut self.in_value, true);
1488         self = self.print_def_path(def_id, substs)?;
1489         self.in_value = was_in_value;
1490
1491         Ok(self)
1492     }
1493
1494     fn in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, Self::Error>
1495     where
1496         T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
1497     {
1498         self.pretty_in_binder(value)
1499     }
1500
1501     fn typed_value(
1502         mut self,
1503         f: impl FnOnce(Self) -> Result<Self, Self::Error>,
1504         t: impl FnOnce(Self) -> Result<Self, Self::Error>,
1505         conversion: &str,
1506     ) -> Result<Self::Const, Self::Error> {
1507         self.write_str("{")?;
1508         self = f(self)?;
1509         self.write_str(conversion)?;
1510         let was_in_value = std::mem::replace(&mut self.in_value, false);
1511         self = t(self)?;
1512         self.in_value = was_in_value;
1513         self.write_str("}")?;
1514         Ok(self)
1515     }
1516
1517     fn generic_delimiters(
1518         mut self,
1519         f: impl FnOnce(Self) -> Result<Self, Self::Error>,
1520     ) -> Result<Self, Self::Error> {
1521         write!(self, "<")?;
1522
1523         let was_in_value = std::mem::replace(&mut self.in_value, false);
1524         let mut inner = f(self)?;
1525         inner.in_value = was_in_value;
1526
1527         write!(inner, ">")?;
1528         Ok(inner)
1529     }
1530
1531     fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool {
1532         let highlight = self.region_highlight_mode;
1533         if highlight.region_highlighted(region).is_some() {
1534             return true;
1535         }
1536
1537         if self.tcx.sess.verbose() {
1538             return true;
1539         }
1540
1541         let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;
1542
1543         match *region {
1544             ty::ReEarlyBound(ref data) => {
1545                 data.name != kw::Invalid && data.name != kw::UnderscoreLifetime
1546             }
1547
1548             ty::ReLateBound(_, br)
1549             | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
1550             | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
1551                 if let ty::BrNamed(_, name) = br {
1552                     if name != kw::Invalid && name != kw::UnderscoreLifetime {
1553                         return true;
1554                     }
1555                 }
1556
1557                 if let Some((region, _)) = highlight.highlight_bound_region {
1558                     if br == region {
1559                         return true;
1560                     }
1561                 }
1562
1563                 false
1564             }
1565
1566             ty::ReScope(_) | ty::ReVar(_) if identify_regions => true,
1567
1568             ty::ReVar(_) | ty::ReScope(_) | ty::ReErased => false,
1569
1570             ty::ReStatic | ty::ReEmpty(_) => true,
1571         }
1572     }
1573
1574     fn pretty_print_const_pointer(
1575         self,
1576         p: Pointer,
1577         ty: Ty<'tcx>,
1578         print_ty: bool,
1579     ) -> Result<Self::Const, Self::Error> {
1580         let print = |mut this: Self| {
1581             define_scoped_cx!(this);
1582             if this.print_alloc_ids {
1583                 p!(write("{:?}", p));
1584             } else {
1585                 p!(write("&_"));
1586             }
1587             Ok(this)
1588         };
1589         if print_ty {
1590             self.typed_value(print, |this| this.print_type(ty), ": ")
1591         } else {
1592             print(self)
1593         }
1594     }
1595 }
1596
1597 // HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
1598 impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
1599     pub fn pretty_print_region(mut self, region: ty::Region<'_>) -> Result<Self, fmt::Error> {
1600         define_scoped_cx!(self);
1601
1602         // Watch out for region highlights.
1603         let highlight = self.region_highlight_mode;
1604         if let Some(n) = highlight.region_highlighted(region) {
1605             p!(write("'{}", n));
1606             return Ok(self);
1607         }
1608
1609         if self.tcx.sess.verbose() {
1610             p!(write("{:?}", region));
1611             return Ok(self);
1612         }
1613
1614         let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;
1615
1616         // These printouts are concise.  They do not contain all the information
1617         // the user might want to diagnose an error, but there is basically no way
1618         // to fit that into a short string.  Hence the recommendation to use
1619         // `explain_region()` or `note_and_explain_region()`.
1620         match *region {
1621             ty::ReEarlyBound(ref data) => {
1622                 if data.name != kw::Invalid {
1623                     p!(write("{}", data.name));
1624                     return Ok(self);
1625                 }
1626             }
1627             ty::ReLateBound(_, br)
1628             | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
1629             | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
1630                 if let ty::BrNamed(_, name) = br {
1631                     if name != kw::Invalid && name != kw::UnderscoreLifetime {
1632                         p!(write("{}", name));
1633                         return Ok(self);
1634                     }
1635                 }
1636
1637                 if let Some((region, counter)) = highlight.highlight_bound_region {
1638                     if br == region {
1639                         p!(write("'{}", counter));
1640                         return Ok(self);
1641                     }
1642                 }
1643             }
1644             ty::ReScope(scope) if identify_regions => {
1645                 match scope.data {
1646                     region::ScopeData::Node => p!(write("'{}s", scope.item_local_id().as_usize())),
1647                     region::ScopeData::CallSite => {
1648                         p!(write("'{}cs", scope.item_local_id().as_usize()))
1649                     }
1650                     region::ScopeData::Arguments => {
1651                         p!(write("'{}as", scope.item_local_id().as_usize()))
1652                     }
1653                     region::ScopeData::Destruction => {
1654                         p!(write("'{}ds", scope.item_local_id().as_usize()))
1655                     }
1656                     region::ScopeData::Remainder(first_statement_index) => p!(write(
1657                         "'{}_{}rs",
1658                         scope.item_local_id().as_usize(),
1659                         first_statement_index.index()
1660                     )),
1661                 }
1662                 return Ok(self);
1663             }
1664             ty::ReVar(region_vid) if identify_regions => {
1665                 p!(write("{:?}", region_vid));
1666                 return Ok(self);
1667             }
1668             ty::ReVar(_) => {}
1669             ty::ReScope(_) | ty::ReErased => {}
1670             ty::ReStatic => {
1671                 p!(write("'static"));
1672                 return Ok(self);
1673             }
1674             ty::ReEmpty(ty::UniverseIndex::ROOT) => {
1675                 p!(write("'<empty>"));
1676                 return Ok(self);
1677             }
1678             ty::ReEmpty(ui) => {
1679                 p!(write("'<empty:{:?}>", ui));
1680                 return Ok(self);
1681             }
1682         }
1683
1684         p!(write("'_"));
1685
1686         Ok(self)
1687     }
1688 }
1689
1690 // HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
1691 // `region_index` and `used_region_names`.
1692 impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
1693     pub fn name_all_regions<T>(
1694         mut self,
1695         value: &ty::Binder<T>,
1696     ) -> Result<(Self, (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)), fmt::Error>
1697     where
1698         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
1699     {
1700         fn name_by_region_index(index: usize) -> Symbol {
1701             match index {
1702                 0 => Symbol::intern("'r"),
1703                 1 => Symbol::intern("'s"),
1704                 i => Symbol::intern(&format!("'t{}", i - 2)),
1705             }
1706         }
1707
1708         // Replace any anonymous late-bound regions with named
1709         // variants, using new unique identifiers, so that we can
1710         // clearly differentiate between named and unnamed regions in
1711         // the output. We'll probably want to tweak this over time to
1712         // decide just how much information to give.
1713         if self.binder_depth == 0 {
1714             self.prepare_late_bound_region_info(value);
1715         }
1716
1717         let mut empty = true;
1718         let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
1719             write!(
1720                 cx,
1721                 "{}",
1722                 if empty {
1723                     empty = false;
1724                     start
1725                 } else {
1726                     cont
1727                 }
1728             )
1729         };
1730
1731         define_scoped_cx!(self);
1732
1733         let mut region_index = self.region_index;
1734         let new_value = self.tcx.replace_late_bound_regions(value, |br| {
1735             let _ = start_or_continue(&mut self, "for<", ", ");
1736             let br = match br {
1737                 ty::BrNamed(_, name) => {
1738                     let _ = write!(self, "{}", name);
1739                     br
1740                 }
1741                 ty::BrAnon(_) | ty::BrEnv => {
1742                     let name = loop {
1743                         let name = name_by_region_index(region_index);
1744                         region_index += 1;
1745                         if !self.used_region_names.contains(&name) {
1746                             break name;
1747                         }
1748                     };
1749                     let _ = write!(self, "{}", name);
1750                     ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
1751                 }
1752             };
1753             self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
1754         });
1755         start_or_continue(&mut self, "", "> ")?;
1756
1757         self.binder_depth += 1;
1758         self.region_index = region_index;
1759         Ok((self, new_value))
1760     }
1761
1762     pub fn pretty_in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, fmt::Error>
1763     where
1764         T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
1765     {
1766         let old_region_index = self.region_index;
1767         let (new, new_value) = self.name_all_regions(value)?;
1768         let mut inner = new_value.0.print(new)?;
1769         inner.region_index = old_region_index;
1770         inner.binder_depth -= 1;
1771         Ok(inner)
1772     }
1773
1774     fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<T>)
1775     where
1776         T: TypeFoldable<'tcx>,
1777     {
1778         struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<Symbol>);
1779         impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
1780             fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
1781                 if let ty::ReLateBound(_, ty::BrNamed(_, name)) = *r {
1782                     self.0.insert(name);
1783                 }
1784                 r.super_visit_with(self)
1785             }
1786         }
1787
1788         self.used_region_names.clear();
1789         let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names);
1790         value.visit_with(&mut collector);
1791         self.region_index = 0;
1792     }
1793 }
1794
1795 impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<T>
1796 where
1797     T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>,
1798 {
1799     type Output = P;
1800     type Error = P::Error;
1801     fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
1802         cx.in_binder(self)
1803     }
1804 }
1805
1806 impl<'tcx, T, U, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<T, U>
1807 where
1808     T: Print<'tcx, P, Output = P, Error = P::Error>,
1809     U: Print<'tcx, P, Output = P, Error = P::Error>,
1810 {
1811     type Output = P;
1812     type Error = P::Error;
1813     fn print(&self, mut cx: P) -> Result<Self::Output, Self::Error> {
1814         define_scoped_cx!(cx);
1815         p!(print(self.0), write(": "), print(self.1));
1816         Ok(cx)
1817     }
1818 }
1819
1820 macro_rules! forward_display_to_print {
1821     ($($ty:ty),+) => {
1822         $(impl fmt::Display for $ty {
1823             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1824                 ty::tls::with(|tcx| {
1825                     tcx.lift(self)
1826                         .expect("could not lift for printing")
1827                         .print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
1828                     Ok(())
1829                 })
1830             }
1831         })+
1832     };
1833 }
1834
1835 macro_rules! define_print_and_forward_display {
1836     (($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
1837         $(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty {
1838             type Output = P;
1839             type Error = fmt::Error;
1840             fn print(&$self, $cx: P) -> Result<Self::Output, Self::Error> {
1841                 #[allow(unused_mut)]
1842                 let mut $cx = $cx;
1843                 define_scoped_cx!($cx);
1844                 let _: () = $print;
1845                 #[allow(unreachable_code)]
1846                 Ok($cx)
1847             }
1848         })+
1849
1850         forward_display_to_print!($($ty),+);
1851     };
1852 }
1853
1854 // HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
1855 impl fmt::Display for ty::RegionKind {
1856     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1857         ty::tls::with(|tcx| {
1858             self.print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
1859             Ok(())
1860         })
1861     }
1862 }
1863
1864 /// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
1865 /// the trait path. That is, it will print `Trait<U>` instead of
1866 /// `<T as Trait<U>>`.
1867 #[derive(Copy, Clone, TypeFoldable, Lift)]
1868 pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);
1869
1870 impl fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
1871     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1872         fmt::Display::fmt(self, f)
1873     }
1874 }
1875
1876 impl ty::TraitRef<'tcx> {
1877     pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
1878         TraitRefPrintOnlyTraitPath(self)
1879     }
1880 }
1881
1882 impl ty::Binder<ty::TraitRef<'tcx>> {
1883     pub fn print_only_trait_path(self) -> ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>> {
1884         self.map_bound(|tr| tr.print_only_trait_path())
1885     }
1886 }
1887
1888 forward_display_to_print! {
1889     Ty<'tcx>,
1890     &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
1891     &'tcx ty::Const<'tcx>,
1892
1893     // HACK(eddyb) these are exhaustive instead of generic,
1894     // because `for<'tcx>` isn't possible yet.
1895     ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
1896     ty::Binder<ty::TraitRef<'tcx>>,
1897     ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>>,
1898     ty::Binder<ty::FnSig<'tcx>>,
1899     ty::Binder<ty::TraitPredicate<'tcx>>,
1900     ty::Binder<ty::SubtypePredicate<'tcx>>,
1901     ty::Binder<ty::ProjectionPredicate<'tcx>>,
1902     ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
1903     ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>,
1904
1905     ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
1906     ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
1907 }
1908
1909 define_print_and_forward_display! {
1910     (self, cx):
1911
1912     &'tcx ty::List<Ty<'tcx>> {
1913         p!(write("{{"));
1914         let mut tys = self.iter();
1915         if let Some(&ty) = tys.next() {
1916             p!(print(ty));
1917             for &ty in tys {
1918                 p!(write(", "), print(ty));
1919             }
1920         }
1921         p!(write("}}"))
1922     }
1923
1924     ty::TypeAndMut<'tcx> {
1925         p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
1926     }
1927
1928     ty::ExistentialTraitRef<'tcx> {
1929         // Use a type that can't appear in defaults of type parameters.
1930         let dummy_self = cx.tcx().mk_ty_infer(ty::FreshTy(0));
1931         let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
1932         p!(print(trait_ref.print_only_trait_path()))
1933     }
1934
1935     ty::ExistentialProjection<'tcx> {
1936         let name = cx.tcx().associated_item(self.item_def_id).ident;
1937         p!(write("{} = ", name), print(self.ty))
1938     }
1939
1940     ty::ExistentialPredicate<'tcx> {
1941         match *self {
1942             ty::ExistentialPredicate::Trait(x) => p!(print(x)),
1943             ty::ExistentialPredicate::Projection(x) => p!(print(x)),
1944             ty::ExistentialPredicate::AutoTrait(def_id) => {
1945                 p!(print_def_path(def_id, &[]));
1946             }
1947         }
1948     }
1949
1950     ty::FnSig<'tcx> {
1951         p!(write("{}", self.unsafety.prefix_str()));
1952
1953         if self.abi != Abi::Rust {
1954             p!(write("extern {} ", self.abi));
1955         }
1956
1957         p!(write("fn"), pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
1958     }
1959
1960     ty::InferTy {
1961         if cx.tcx().sess.verbose() {
1962             p!(write("{:?}", self));
1963             return Ok(cx);
1964         }
1965         match *self {
1966             ty::TyVar(_) => p!(write("_")),
1967             ty::IntVar(_) => p!(write("{}", "{integer}")),
1968             ty::FloatVar(_) => p!(write("{}", "{float}")),
1969             ty::FreshTy(v) => p!(write("FreshTy({})", v)),
1970             ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)),
1971             ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v))
1972         }
1973     }
1974
1975     ty::TraitRef<'tcx> {
1976         p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
1977     }
1978
1979     TraitRefPrintOnlyTraitPath<'tcx> {
1980         p!(print_def_path(self.0.def_id, self.0.substs));
1981     }
1982
1983     ty::ParamTy {
1984         p!(write("{}", self.name))
1985     }
1986
1987     ty::ParamConst {
1988         p!(write("{}", self.name))
1989     }
1990
1991     ty::SubtypePredicate<'tcx> {
1992         p!(print(self.a), write(" <: "), print(self.b))
1993     }
1994
1995     ty::TraitPredicate<'tcx> {
1996         p!(print(self.trait_ref.self_ty()), write(": "),
1997            print(self.trait_ref.print_only_trait_path()))
1998     }
1999
2000     ty::ProjectionPredicate<'tcx> {
2001         p!(print(self.projection_ty), write(" == "), print(self.ty))
2002     }
2003
2004     ty::ProjectionTy<'tcx> {
2005         p!(print_def_path(self.item_def_id, self.substs));
2006     }
2007
2008     ty::ClosureKind {
2009         match *self {
2010             ty::ClosureKind::Fn => p!(write("Fn")),
2011             ty::ClosureKind::FnMut => p!(write("FnMut")),
2012             ty::ClosureKind::FnOnce => p!(write("FnOnce")),
2013         }
2014     }
2015
2016     ty::Predicate<'tcx> {
2017         match *self {
2018             ty::Predicate::Trait(ref data, constness) => {
2019                 if let hir::Constness::Const = constness {
2020                     p!(write("const "));
2021                 }
2022                 p!(print(data))
2023             }
2024             ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
2025             ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
2026             ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
2027             ty::Predicate::Projection(ref predicate) => p!(print(predicate)),
2028             ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
2029             ty::Predicate::ObjectSafe(trait_def_id) => {
2030                 p!(write("the trait `"),
2031                    print_def_path(trait_def_id, &[]),
2032                    write("` is object-safe"))
2033             }
2034             ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
2035                 p!(write("the closure `"),
2036                    print_value_path(closure_def_id, &[]),
2037                    write("` implements the trait `{}`", kind))
2038             }
2039             ty::Predicate::ConstEvaluatable(def_id, substs) => {
2040                 p!(write("the constant `"),
2041                    print_value_path(def_id, substs),
2042                    write("` can be evaluated"))
2043             }
2044         }
2045     }
2046
2047     GenericArg<'tcx> {
2048         match self.unpack() {
2049             GenericArgKind::Lifetime(lt) => p!(print(lt)),
2050             GenericArgKind::Type(ty) => p!(print(ty)),
2051             GenericArgKind::Const(ct) => p!(print(ct)),
2052         }
2053     }
2054 }