2 use crate::hir
::def
::{Namespace, DefKind}
;
3 use crate::hir
::map
::{DefPathData, DisambiguatedDefPathData}
;
4 use crate::hir
::def_id
::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}
;
5 use crate::middle
::cstore
::{ExternCrate, ExternCrateSource}
;
6 use crate::middle
::region
;
7 use crate::ty
::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable}
;
8 use crate::ty
::subst
::{Kind, Subst, UnpackedKind}
;
9 use crate::ty
::layout
::Size
;
10 use crate::mir
::interpret
::{ConstValue, sign_extend, Scalar}
;
12 use rustc_apfloat
::ieee
::{Double, Single}
;
13 use rustc_apfloat
::Float
;
14 use rustc_target
::spec
::abi
::Abi
;
15 use syntax
::symbol
::{kw, InternedString}
;
18 use std
::fmt
::{self, Write as _}
;
19 use std
::ops
::{Deref, DerefMut}
;
21 // `pretty` is a separate module only for organization.
25 (@
write($
($data
:expr
),+)) => {
26 write
!(scoped_cx
!(), $
($data
),+)?
28 (@
print($x
:expr
)) => {
29 scoped_cx
!() = $x
.print(scoped_cx
!())?
31 (@$method
:ident($
($arg
:expr
),*)) => {
32 scoped_cx
!() = scoped_cx
!().$
method($
($arg
),*)?
34 ($
($kind
:ident $data
:tt
),+) => {{
38 macro_rules
! define_scoped_cx
{
40 #[allow(unused_macros)]
41 macro_rules
! scoped_cx
{
48 static FORCE_IMPL_FILENAME_LINE
: Cell
<bool
> = Cell
::new(false);
49 static SHOULD_PREFIX_WITH_CRATE
: Cell
<bool
> = Cell
::new(false);
52 /// Force us to name impls with just the filename/line number. We
53 /// normally try to use types. But at some points, notably while printing
54 /// cycle errors, this can result in extra or suboptimal error output,
55 /// so this variable disables that check.
56 pub fn with_forced_impl_filename_line
<F
: FnOnce() -> R
, R
>(f
: F
) -> R
{
57 FORCE_IMPL_FILENAME_LINE
.with(|force
| {
58 let old
= force
.get();
66 /// Adds the `crate::` prefix to paths where appropriate.
67 pub fn with_crate_prefix
<F
: FnOnce() -> R
, R
>(f
: F
) -> R
{
68 SHOULD_PREFIX_WITH_CRATE
.with(|flag
| {
77 /// The "region highlights" are used to control region printing during
78 /// specific error messages. When a "region highlight" is enabled, it
79 /// gives an alternate way to print specific regions. For now, we
80 /// always print those regions using a number, so something like "`'0`".
82 /// Regions not selected by the region highlight mode are presently
84 #[derive(Copy, Clone, Default)]
85 pub struct RegionHighlightMode
{
86 /// If enabled, when we see the selected region, use "`'N`"
87 /// instead of the ordinary behavior.
88 highlight_regions
: [Option
<(ty
::RegionKind
, usize)>; 3],
90 /// If enabled, when printing a "free region" that originated from
91 /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily
92 /// have names print as normal.
94 /// This is used when you have a signature like `fn foo(x: &u32,
95 /// y: &'a u32)` and we want to give a name to the region of the
97 highlight_bound_region
: Option
<(ty
::BoundRegion
, usize)>,
100 impl RegionHighlightMode
{
101 /// If `region` and `number` are both `Some`, invokes
102 /// `highlighting_region`.
103 pub fn maybe_highlighting_region(
105 region
: Option
<ty
::Region
<'_
>>,
106 number
: Option
<usize>,
108 if let Some(k
) = region
{
109 if let Some(n
) = number
{
110 self.highlighting_region(k
, n
);
115 /// Highlights the region inference variable `vid` as `'N`.
116 pub fn highlighting_region(
118 region
: ty
::Region
<'_
>,
121 let num_slots
= self.highlight_regions
.len();
122 let first_avail_slot
= self.highlight_regions
.iter_mut()
123 .filter(|s
| s
.is_none())
127 "can only highlight {} placeholders at a time",
131 *first_avail_slot
= Some((*region
, number
));
134 /// Convenience wrapper for `highlighting_region`.
135 pub fn highlighting_region_vid(
140 self.highlighting_region(&ty
::ReVar(vid
), number
)
143 /// Returns `Some(n)` with the number to use for the given region, if any.
144 fn region_highlighted(&self, region
: ty
::Region
<'_
>) -> Option
<usize> {
148 .filter_map(|h
| match h
{
149 Some((r
, n
)) if r
== region
=> Some(*n
),
155 /// Highlight the given bound region.
156 /// We can only highlight one bound region at a time. See
157 /// the field `highlight_bound_region` for more detailed notes.
158 pub fn highlighting_bound_region(
163 assert
!(self.highlight_bound_region
.is_none());
164 self.highlight_bound_region
= Some((br
, number
));
168 /// Trait for printers that pretty-print using `fmt::Write` to the printer.
169 pub trait PrettyPrinter
<'tcx
>:
176 DynExistential
= Self,
180 /// Like `print_def_path` but for value paths.
184 substs
: &'tcx
[Kind
<'tcx
>],
185 ) -> Result
<Self::Path
, Self::Error
> {
186 self.print_def_path(def_id
, substs
)
189 fn in_binder
<T
>(self, value
: &ty
::Binder
<T
>) -> Result
<Self, Self::Error
>
191 T
: Print
<'tcx
, Self, Output
= Self, Error
= Self::Error
> + TypeFoldable
<'tcx
>,
193 value
.skip_binder().print(self)
196 /// Print comma-separated elements.
197 fn comma_sep
<T
>(mut self, mut elems
: impl Iterator
<Item
= T
>) -> Result
<Self, Self::Error
>
199 T
: Print
<'tcx
, Self, Output
= Self, Error
= Self::Error
>,
201 if let Some(first
) = elems
.next() {
202 self = first
.print(self)?
;
204 self.write_str(", ")?
;
205 self = elem
.print(self)?
;
211 /// Print `<...>` around what `f` prints.
212 fn generic_delimiters(
214 f
: impl FnOnce(Self) -> Result
<Self, Self::Error
>,
215 ) -> Result
<Self, Self::Error
>;
217 /// Return `true` if the region should be printed in
218 /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`.
219 /// This is typically the case for all non-`'_` regions.
220 fn region_should_not_be_omitted(
222 region
: ty
::Region
<'_
>,
225 // Defaults (should not be overriden):
227 /// If possible, this returns a global path resolving to `def_id` that is visible
228 /// from at least one local module and returns true. If the crate defining `def_id` is
229 /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
230 fn try_print_visible_def_path(
233 ) -> Result
<(Self, bool
), Self::Error
> {
234 define_scoped_cx
!(self);
236 debug
!("try_print_visible_def_path: def_id={:?}", def_id
);
238 // If `def_id` is a direct or injected extern crate, return the
239 // path to the crate followed by the path to the item within the crate.
240 if def_id
.index
== CRATE_DEF_INDEX
{
241 let cnum
= def_id
.krate
;
243 if cnum
== LOCAL_CRATE
{
244 return Ok((self.path_crate(cnum
)?
, true));
247 // In local mode, when we encounter a crate other than
248 // LOCAL_CRATE, execution proceeds in one of two ways:
250 // 1. for a direct dependency, where user added an
251 // `extern crate` manually, we put the `extern
252 // crate` as the parent. So you wind up with
253 // something relative to the current crate.
254 // 2. for an extern inferred from a path or an indirect crate,
255 // where there is no explicit `extern crate`, we just prepend
257 match self.tcx().extern_crate(def_id
) {
259 src
: ExternCrateSource
::Extern(def_id
),
264 debug
!("try_print_visible_def_path: def_id={:?}", def_id
);
265 return Ok((if !span
.is_dummy() {
266 self.print_def_path(def_id
, &[])?
268 self.path_crate(cnum
)?
272 return Ok((self.path_crate(cnum
)?
, true));
278 if def_id
.is_local() {
279 return Ok((self, false));
282 let visible_parent_map
= self.tcx().visible_parent_map(LOCAL_CRATE
);
284 let mut cur_def_key
= self.tcx().def_key(def_id
);
285 debug
!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key
);
287 // For a constructor we want the name of its parent rather than <unnamed>.
288 match cur_def_key
.disambiguated_data
.data
{
289 DefPathData
::Ctor
=> {
292 index
: cur_def_key
.parent
293 .expect("DefPathData::Ctor/VariantData missing a parent"),
296 cur_def_key
= self.tcx().def_key(parent
);
301 let visible_parent
= match visible_parent_map
.get(&def_id
).cloned() {
302 Some(parent
) => parent
,
303 None
=> return Ok((self, false)),
305 // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid
306 // knowing ahead of time whether the entire path will succeed or not.
307 // To support printers that do not implement `PrettyPrinter`, a `Vec` or
308 // linked list on the stack would need to be built, before any printing.
309 match self.try_print_visible_def_path(visible_parent
)?
{
310 (cx
, false) => return Ok((cx
, false)),
311 (cx
, true) => self = cx
,
313 let actual_parent
= self.tcx().parent(def_id
);
315 "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
316 visible_parent
, actual_parent
,
319 let mut data
= cur_def_key
.disambiguated_data
.data
;
321 "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}",
322 data
, visible_parent
, actual_parent
,
326 // In order to output a path that could actually be imported (valid and visible),
327 // we need to handle re-exports correctly.
329 // For example, take `std::os::unix::process::CommandExt`, this trait is actually
330 // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing).
332 // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is
333 // private so the "true" path to `CommandExt` isn't accessible.
335 // In this case, the `visible_parent_map` will look something like this:
337 // (child) -> (parent)
338 // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process`
339 // `std::sys::unix::ext::process` -> `std::sys::unix::ext`
340 // `std::sys::unix::ext` -> `std::os`
342 // This is correct, as the visible parent of `std::sys::unix::ext` is in fact
345 // When printing the path to `CommandExt` and looking at the `cur_def_key` that
346 // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go
347 // to the parent - resulting in a mangled path like
348 // `std::os::ext::process::CommandExt`.
350 // Instead, we must detect that there was a re-export and instead print `unix`
351 // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To
352 // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with
353 // the visible parent (`std::os`). If these do not match, then we iterate over
354 // the children of the visible parent (as was done when computing
355 // `visible_parent_map`), looking for the specific child we currently have and then
356 // have access to the re-exported name.
357 DefPathData
::TypeNs(ref mut name
) if Some(visible_parent
) != actual_parent
=> {
358 let reexport
= self.tcx().item_children(visible_parent
)
360 .find(|child
| child
.res
.def_id() == def_id
)
361 .map(|child
| child
.ident
.as_interned_str());
362 if let Some(reexport
) = reexport
{
366 // Re-exported `extern crate` (#43189).
367 DefPathData
::CrateRoot
=> {
368 data
= DefPathData
::TypeNs(
369 self.tcx().original_crate_name(def_id
.krate
).as_interned_str(),
374 debug
!("try_print_visible_def_path: data={:?}", data
);
376 Ok((self.path_append(Ok
, &DisambiguatedDefPathData
{
382 fn pretty_path_qualified(
385 trait_ref
: Option
<ty
::TraitRef
<'tcx
>>,
386 ) -> Result
<Self::Path
, Self::Error
> {
387 if trait_ref
.is_none() {
388 // Inherent impls. Try to print `Foo::bar` for an inherent
389 // impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
390 // anything other than a simple path.
392 ty
::Adt(..) | ty
::Foreign(_
) |
393 ty
::Bool
| ty
::Char
| ty
::Str
|
394 ty
::Int(_
) | ty
::Uint(_
) | ty
::Float(_
) => {
395 return self_ty
.print(self);
402 self.generic_delimiters(|mut cx
| {
403 define_scoped_cx
!(cx
);
406 if let Some(trait_ref
) = trait_ref
{
407 p
!(write(" as "), print(trait_ref
));
413 fn pretty_path_append_impl(
415 print_prefix
: impl FnOnce(Self) -> Result
<Self::Path
, Self::Error
>,
417 trait_ref
: Option
<ty
::TraitRef
<'tcx
>>,
418 ) -> Result
<Self::Path
, Self::Error
> {
419 self = print_prefix(self)?
;
421 self.generic_delimiters(|mut cx
| {
422 define_scoped_cx
!(cx
);
425 if let Some(trait_ref
) = trait_ref
{
426 p
!(print(trait_ref
), write(" for "));
434 fn pretty_print_type(
437 ) -> Result
<Self::Type
, Self::Error
> {
438 define_scoped_cx
!(self);
441 ty
::Bool
=> p
!(write("bool")),
442 ty
::Char
=> p
!(write("char")),
443 ty
::Int(t
) => p
!(write("{}", t
.ty_to_string())),
444 ty
::Uint(t
) => p
!(write("{}", t
.ty_to_string())),
445 ty
::Float(t
) => p
!(write("{}", t
.ty_to_string())),
446 ty
::RawPtr(ref tm
) => {
447 p
!(write("*{} ", match tm
.mutbl
{
448 hir
::MutMutable
=> "mut",
449 hir
::MutImmutable
=> "const",
453 ty
::Ref(r
, ty
, mutbl
) => {
455 if self.region_should_not_be_omitted(r
) {
456 p
!(print(r
), write(" "));
458 p
!(print(ty
::TypeAndMut { ty, mutbl }
))
460 ty
::Never
=> p
!(write("!")),
461 ty
::Tuple(ref tys
) => {
463 let mut tys
= tys
.iter();
464 if let Some(&ty
) = tys
.next() {
465 p
!(print(ty
), write(","));
466 if let Some(&ty
) = tys
.next() {
467 p
!(write(" "), print(ty
));
469 p
!(write(", "), print(ty
));
475 ty
::FnDef(def_id
, substs
) => {
476 let sig
= self.tcx().fn_sig(def_id
).subst(self.tcx(), substs
);
477 p
!(print(sig
), write(" {{"), print_value_path(def_id, substs), write("}}"));
479 ty
::FnPtr(ref bare_fn
) => {
482 ty
::Infer(infer_ty
) => {
483 if let ty
::TyVar(ty_vid
) = infer_ty
{
484 if let Some(name
) = self.infer_ty_name(ty_vid
) {
485 p
!(write("{}", name
))
487 p
!(write("{}", infer_ty
))
490 p
!(write("{}", infer_ty
))
493 ty
::Error
=> p
!(write("[type error]")),
494 ty
::Param(ref param_ty
) => p
!(write("{}", param_ty
)),
495 ty
::Bound(debruijn
, bound_ty
) => {
496 match bound_ty
.kind
{
497 ty
::BoundTyKind
::Anon
=> {
498 if debruijn
== ty
::INNERMOST
{
499 p
!(write("^{}", bound_ty
.var
.index()))
501 p
!(write("^{}_{}", debruijn
.index(), bound_ty
.var
.index()))
505 ty
::BoundTyKind
::Param(p
) => p
!(write("{}", p
)),
508 ty
::Adt(def
, substs
) => {
509 p
!(print_def_path(def
.did
, substs
));
511 ty
::Dynamic(data
, r
) => {
512 let print_r
= self.region_should_not_be_omitted(r
);
516 p
!(write("dyn "), print(data
));
518 p
!(write(" + "), print(r
), write(")"));
521 ty
::Foreign(def_id
) => {
522 p
!(print_def_path(def_id
, &[]));
524 ty
::Projection(ref data
) => p
!(print(data
)),
525 ty
::UnnormalizedProjection(ref data
) => {
526 p
!(write("Unnormalized("), print(data
), write(")"))
528 ty
::Placeholder(placeholder
) => {
529 p
!(write("Placeholder({:?})", placeholder
))
531 ty
::Opaque(def_id
, substs
) => {
532 // FIXME(eddyb) print this with `print_def_path`.
533 if self.tcx().sess
.verbose() {
534 p
!(write("Opaque({:?}, {:?})", def_id
, substs
));
538 let def_key
= self.tcx().def_key(def_id
);
539 if let Some(name
) = def_key
.disambiguated_data
.data
.get_opt_name() {
540 p
!(write("{}", name
));
541 let mut substs
= substs
.iter();
542 // FIXME(eddyb) print this with `print_def_path`.
543 if let Some(first
) = substs
.next() {
546 for subst
in substs
{
547 p
!(write(", "), print(subst
));
553 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
554 // by looking up the projections associated with the def_id.
555 let bounds
= self.tcx().predicates_of(def_id
).instantiate(self.tcx(), substs
);
557 let mut first
= true;
558 let mut is_sized
= false;
560 for predicate
in bounds
.predicates
{
561 if let Some(trait_ref
) = predicate
.to_opt_poly_trait_ref() {
562 // Don't print +Sized, but rather +?Sized if absent.
563 if Some(trait_ref
.def_id()) == self.tcx().lang_items().sized_trait() {
569 write("{}", if first { " " }
else { "+" }
),
575 p
!(write("{}?Sized", if first { " " }
else { "+" }
));
580 ty
::Str
=> p
!(write("str")),
581 ty
::Generator(did
, substs
, movability
) => {
582 let upvar_tys
= substs
.upvar_tys(did
, self.tcx());
583 let witness
= substs
.witness(did
, self.tcx());
584 if movability
== hir
::GeneratorMovability
::Movable
{
585 p
!(write("[generator"));
587 p
!(write("[static generator"));
590 // FIXME(eddyb) should use `def_span`.
591 if let Some(hir_id
) = self.tcx().hir().as_local_hir_id(did
) {
592 p
!(write("@{:?}", self.tcx().hir().span(hir_id
)));
594 for (&var_id
, upvar_ty
) in self.tcx().upvars(did
)
597 .flat_map(|v
| v
.keys())
603 self.tcx().hir().name(var_id
)),
608 // cross-crate closure types should only be
609 // visible in codegen bug reports, I imagine.
610 p
!(write("@{:?}", did
));
612 for (index
, upvar_ty
) in upvar_tys
.enumerate() {
614 write("{}{}:", sep
, index
),
620 p
!(write(" "), print(witness
), write("]"))
622 ty
::GeneratorWitness(types
) => {
623 p
!(in_binder(&types
));
625 ty
::Closure(did
, substs
) => {
626 let upvar_tys
= substs
.upvar_tys(did
, self.tcx());
627 p
!(write("[closure"));
629 // FIXME(eddyb) should use `def_span`.
630 if let Some(hir_id
) = self.tcx().hir().as_local_hir_id(did
) {
631 if self.tcx().sess
.opts
.debugging_opts
.span_free_formats
{
632 p
!(write("@{:?}", hir_id
));
634 p
!(write("@{:?}", self.tcx().hir().span(hir_id
)));
637 for (&var_id
, upvar_ty
) in self.tcx().upvars(did
)
640 .flat_map(|v
| v
.keys())
646 self.tcx().hir().name(var_id
)),
651 // cross-crate closure types should only be
652 // visible in codegen bug reports, I imagine.
653 p
!(write("@{:?}", did
));
655 for (index
, upvar_ty
) in upvar_tys
.enumerate() {
657 write("{}{}:", sep
, index
),
663 if self.tcx().sess
.verbose() {
665 " closure_kind_ty={:?} closure_sig_ty={:?}",
666 substs
.closure_kind_ty(did
, self.tcx()),
667 substs
.closure_sig_ty(did
, self.tcx())
673 ty
::Array(ty
, sz
) => {
674 p
!(write("["), print(ty
), write("; "));
675 if let Some(n
) = sz
.assert_usize(self.tcx()) {
683 p
!(write("["), print(ty
), write("]"))
690 fn infer_ty_name(&self, _
: ty
::TyVid
) -> Option
<String
> {
694 fn pretty_print_dyn_existential(
696 predicates
: &'tcx ty
::List
<ty
::ExistentialPredicate
<'tcx
>>,
697 ) -> Result
<Self::DynExistential
, Self::Error
> {
698 define_scoped_cx
!(self);
700 // Generate the main trait ref, including associated types.
701 let mut first
= true;
703 if let Some(principal
) = predicates
.principal() {
704 p
!(print_def_path(principal
.def_id
, &[]));
706 let mut resugared
= false;
708 // Special-case `Fn(...) -> ...` and resugar it.
709 let fn_trait_kind
= self.tcx().lang_items().fn_trait_kind(principal
.def_id
);
710 if !self.tcx().sess
.verbose() && fn_trait_kind
.is_some() {
711 if let ty
::Tuple(ref args
) = principal
.substs
.type_at(0).sty
{
712 let mut projections
= predicates
.projection_bounds();
713 if let (Some(proj
), None
) = (projections
.next(), projections
.next()) {
714 let tys
: Vec
<_
> = args
.iter().map(|k
| k
.expect_ty()).collect();
715 p
!(pretty_fn_sig(&tys
, false, proj
.ty
));
721 // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`,
722 // in order to place the projections inside the `<...>`.
724 // Use a type that can't appear in defaults of type parameters.
725 let dummy_self
= self.tcx().mk_ty_infer(ty
::FreshTy(0));
726 let principal
= principal
.with_self_ty(self.tcx(), dummy_self
);
728 let args
= self.generic_args_to_print(
729 self.tcx().generics_of(principal
.def_id
),
733 // Don't print `'_` if there's no unerased regions.
734 let print_regions
= args
.iter().any(|arg
| {
736 UnpackedKind
::Lifetime(r
) => *r
!= ty
::ReErased
,
740 let mut args
= args
.iter().cloned().filter(|arg
| {
742 UnpackedKind
::Lifetime(_
) => print_regions
,
746 let mut projections
= predicates
.projection_bounds();
748 let arg0
= args
.next();
749 let projection0
= projections
.next();
750 if arg0
.is_some() || projection0
.is_some() {
751 let args
= arg0
.into_iter().chain(args
);
752 let projections
= projection0
.into_iter().chain(projections
);
754 p
!(generic_delimiters(|mut cx
| {
755 cx
= cx
.comma_sep(args
)?
;
756 if arg0
.is_some() && projection0
.is_some() {
759 cx
.comma_sep(projections
)
767 // FIXME(eddyb) avoid printing twice (needed to ensure
768 // that the auto traits are sorted *and* printed via cx).
769 let mut auto_traits
: Vec
<_
> = predicates
.auto_traits().map(|did
| {
770 (self.tcx().def_path_str(did
), did
)
773 // The auto traits come ordered by `DefPathHash`. While
774 // `DefPathHash` is *stable* in the sense that it depends on
775 // neither the host nor the phase of the moon, it depends
776 // "pseudorandomly" on the compiler version and the target.
778 // To avoid that causing instabilities in compiletest
779 // output, sort the auto-traits alphabetically.
782 for (_
, def_id
) in auto_traits
{
788 p
!(print_def_path(def_id
, &[]));
799 ) -> Result
<Self, Self::Error
> {
800 define_scoped_cx
!(self);
803 let mut inputs
= inputs
.iter();
804 if let Some(&ty
) = inputs
.next() {
807 p
!(write(", "), print(ty
));
814 if !output
.is_unit() {
815 p
!(write(" -> "), print(output
));
821 fn pretty_print_const(
823 ct
: &'tcx ty
::Const
<'tcx
>,
824 ) -> Result
<Self::Const
, Self::Error
> {
825 define_scoped_cx
!(self);
827 let u8 = self.tcx().types
.u8;
828 if let ty
::FnDef(did
, substs
) = ct
.ty
.sty
{
829 p
!(print_value_path(did
, substs
));
832 if let ConstValue
::Unevaluated(did
, substs
) = ct
.val
{
833 match self.tcx().def_kind(did
) {
834 | Some(DefKind
::Static
)
835 | Some(DefKind
::Const
)
836 | Some(DefKind
::AssocConst
) => p
!(print_value_path(did
, substs
)),
837 _
=> if did
.is_local() {
838 let span
= self.tcx().def_span(did
);
839 if let Ok(snip
) = self.tcx().sess
.source_map().span_to_snippet(span
) {
840 p
!(write("{}", snip
))
842 p
!(write("_: "), print(ct
.ty
))
845 p
!(write("_: "), print(ct
.ty
))
850 if let ConstValue
::Infer(..) = ct
.val
{
851 p
!(write("_: "), print(ct
.ty
));
854 if let ConstValue
::Param(ParamConst { name, .. }
) = ct
.val
{
855 p
!(write("{}", name
));
858 if let ConstValue
::Scalar(Scalar
::Raw { data, .. }
) = ct
.val
{
861 p
!(write("{}", if data
== 0 { "false" }
else { "true" }
));
864 ty
::Float(ast
::FloatTy
::F32
) => {
865 p
!(write("{}f32", Single
::from_bits(data
)));
868 ty
::Float(ast
::FloatTy
::F64
) => {
869 p
!(write("{}f64", Double
::from_bits(data
)));
873 p
!(write("{}{}", data
, ui
));
877 let ty
= self.tcx().lift_to_global(&ct
.ty
).unwrap();
878 let size
= self.tcx().layout_of(ty
::ParamEnv
::empty().and(ty
))
881 p
!(write("{}{}", sign_extend(data
, size
) as i128
, i
));
885 p
!(write("{:?}", ::std
::char::from_u32(data
as u32).unwrap()));
891 if let ty
::Ref(_
, ref_ty
, _
) = ct
.ty
.sty
{
892 let byte_str
= match (ct
.val
, &ref_ty
.sty
) {
893 (ConstValue
::Scalar(Scalar
::Ptr(ptr
)), ty
::Array(t
, n
)) if *t
== u8 => {
894 let n
= n
.unwrap_usize(self.tcx());
897 .unwrap_memory(ptr
.alloc_id
)
898 .get_bytes(&self.tcx(), ptr
, Size
::from_bytes(n
)).unwrap())
900 (ConstValue
::Slice { data, start, end }
, ty
::Slice(t
)) if *t
== u8 => {
901 Some(&data
.bytes
[start
..end
])
903 (ConstValue
::Slice { data, start, end }
, ty
::Str
) => {
904 let slice
= &data
.bytes
[start
..end
];
905 let s
= ::std
::str::from_utf8(slice
)
906 .expect("non utf8 str from miri");
907 p
!(write("{:?}", s
));
912 if let Some(byte_str
) = byte_str
{
915 for e
in std
::ascii
::escape_default(c
) {
916 self.write_char(e
as char)?
;
923 p
!(write("{:?} : ", ct
.val
), print(ct
.ty
));
929 // HACK(eddyb) boxed to avoid moving around a large struct by-value.
930 pub struct FmtPrinter
<'a
, 'tcx
, F
>(Box
<FmtPrinterData
<'a
, 'tcx
, F
>>);
932 pub struct FmtPrinterData
<'a
, 'tcx
, F
> {
939 used_region_names
: FxHashSet
<InternedString
>,
943 pub region_highlight_mode
: RegionHighlightMode
,
945 pub name_resolver
: Option
<Box
<&'a
dyn Fn(ty
::sty
::TyVid
) -> Option
<String
>>>,
948 impl<F
> Deref
for FmtPrinter
<'a
, 'tcx
, F
> {
949 type Target
= FmtPrinterData
<'a
, 'tcx
, F
>;
950 fn deref(&self) -> &Self::Target
{
955 impl<F
> DerefMut
for FmtPrinter
<'_
, '_
, F
> {
956 fn deref_mut(&mut self) -> &mut Self::Target
{
961 impl<F
> FmtPrinter
<'a
, 'tcx
, F
> {
962 pub fn new(tcx
: TyCtxt
<'tcx
>, fmt
: F
, ns
: Namespace
) -> Self {
963 FmtPrinter(Box
::new(FmtPrinterData
{
967 in_value
: ns
== Namespace
::ValueNS
,
968 used_region_names
: Default
::default(),
971 region_highlight_mode
: RegionHighlightMode
::default(),
978 // HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
979 // (but also some things just print a `DefId` generally so maybe we need this?)
980 fn guess_def_namespace(self, def_id
: DefId
) -> Namespace
{
981 match self.def_key(def_id
).disambiguated_data
.data
{
982 DefPathData
::TypeNs(..)
983 | DefPathData
::CrateRoot
984 | DefPathData
::ImplTrait
=> Namespace
::TypeNS
,
986 DefPathData
::ValueNs(..)
987 | DefPathData
::AnonConst
988 | DefPathData
::ClosureExpr
989 | DefPathData
::Ctor
=> Namespace
::ValueNS
,
991 DefPathData
::MacroNs(..) => Namespace
::MacroNS
,
993 _
=> Namespace
::TypeNS
,
997 /// Returns a string identifying this `DefId`. This string is
998 /// suitable for user output.
999 pub fn def_path_str(self, def_id
: DefId
) -> String
{
1000 let ns
= self.guess_def_namespace(def_id
);
1001 debug
!("def_path_str: def_id={:?}, ns={:?}", def_id
, ns
);
1002 let mut s
= String
::new();
1003 let _
= FmtPrinter
::new(self, &mut s
, ns
)
1004 .print_def_path(def_id
, &[]);
1009 impl<F
: fmt
::Write
> fmt
::Write
for FmtPrinter
<'_
, '_
, F
> {
1010 fn write_str(&mut self, s
: &str) -> fmt
::Result
{
1011 self.fmt
.write_str(s
)
1015 impl<F
: fmt
::Write
> Printer
<'tcx
> for FmtPrinter
<'_
, 'tcx
, F
> {
1016 type Error
= fmt
::Error
;
1021 type DynExistential
= Self;
1024 fn tcx(&'a
self) -> TyCtxt
<'tcx
> {
1031 substs
: &'tcx
[Kind
<'tcx
>],
1032 ) -> Result
<Self::Path
, Self::Error
> {
1033 define_scoped_cx
!(self);
1035 if substs
.is_empty() {
1036 match self.try_print_visible_def_path(def_id
)?
{
1037 (cx
, true) => return Ok(cx
),
1038 (cx
, false) => self = cx
,
1042 let key
= self.tcx
.def_key(def_id
);
1043 if let DefPathData
::Impl
= key
.disambiguated_data
.data
{
1044 // Always use types for non-local impls, where types are always
1045 // available, and filename/line-number is mostly uninteresting.
1047 !def_id
.is_local() || {
1048 // Otherwise, use filename/line-number if forced.
1049 let force_no_types
= FORCE_IMPL_FILENAME_LINE
.with(|f
| f
.get());
1054 // If no type info is available, fall back to
1055 // pretty printing some span information. This should
1056 // only occur very early in the compiler pipeline.
1057 let parent_def_id
= DefId { index: key.parent.unwrap(), ..def_id }
;
1058 let span
= self.tcx
.def_span(def_id
);
1060 self = self.print_def_path(parent_def_id
, &[])?
;
1062 // HACK(eddyb) copy of `path_append` to avoid
1063 // constructing a `DisambiguatedDefPathData`.
1064 if !self.empty_path
{
1065 write
!(self, "::")?
;
1067 write
!(self, "<impl at {:?}>", span
)?
;
1068 self.empty_path
= false;
1074 self.default_print_def_path(def_id
, substs
)
1079 region
: ty
::Region
<'_
>,
1080 ) -> Result
<Self::Region
, Self::Error
> {
1081 self.pretty_print_region(region
)
1087 ) -> Result
<Self::Type
, Self::Error
> {
1088 self.pretty_print_type(ty
)
1091 fn print_dyn_existential(
1093 predicates
: &'tcx ty
::List
<ty
::ExistentialPredicate
<'tcx
>>,
1094 ) -> Result
<Self::DynExistential
, Self::Error
> {
1095 self.pretty_print_dyn_existential(predicates
)
1100 ct
: &'tcx ty
::Const
<'tcx
>,
1101 ) -> Result
<Self::Const
, Self::Error
> {
1102 self.pretty_print_const(ct
)
1108 ) -> Result
<Self::Path
, Self::Error
> {
1109 self.empty_path
= true;
1110 if cnum
== LOCAL_CRATE
{
1111 if self.tcx
.sess
.rust_2018() {
1112 // We add the `crate::` keyword on Rust 2018, only when desired.
1113 if SHOULD_PREFIX_WITH_CRATE
.with(|flag
| flag
.get()) {
1114 write
!(self, "{}", kw
::Crate
)?
;
1115 self.empty_path
= false;
1119 write
!(self, "{}", self.tcx
.crate_name(cnum
))?
;
1120 self.empty_path
= false;
1127 trait_ref
: Option
<ty
::TraitRef
<'tcx
>>,
1128 ) -> Result
<Self::Path
, Self::Error
> {
1129 self = self.pretty_path_qualified(self_ty
, trait_ref
)?
;
1130 self.empty_path
= false;
1134 fn path_append_impl(
1136 print_prefix
: impl FnOnce(Self) -> Result
<Self::Path
, Self::Error
>,
1137 _disambiguated_data
: &DisambiguatedDefPathData
,
1139 trait_ref
: Option
<ty
::TraitRef
<'tcx
>>,
1140 ) -> Result
<Self::Path
, Self::Error
> {
1141 self = self.pretty_path_append_impl(|mut cx
| {
1142 cx
= print_prefix(cx
)?
;
1148 }, self_ty
, trait_ref
)?
;
1149 self.empty_path
= false;
1154 print_prefix
: impl FnOnce(Self) -> Result
<Self::Path
, Self::Error
>,
1155 disambiguated_data
: &DisambiguatedDefPathData
,
1156 ) -> Result
<Self::Path
, Self::Error
> {
1157 self = print_prefix(self)?
;
1159 // Skip `::{{constructor}}` on tuple/unit structs.
1160 match disambiguated_data
.data
{
1161 DefPathData
::Ctor
=> return Ok(self),
1165 // FIXME(eddyb) `name` should never be empty, but it
1166 // currently is for `extern { ... }` "foreign modules".
1167 let name
= disambiguated_data
.data
.as_interned_str().as_str();
1168 if !name
.is_empty() {
1169 if !self.empty_path
{
1170 write
!(self, "::")?
;
1172 write
!(self, "{}", name
)?
;
1174 // FIXME(eddyb) this will print e.g. `{{closure}}#3`, but it
1175 // might be nicer to use something else, e.g. `{closure#3}`.
1176 let dis
= disambiguated_data
.disambiguator
;
1178 disambiguated_data
.data
.get_opt_name().is_none() ||
1179 dis
!= 0 && self.tcx
.sess
.verbose();
1181 write
!(self, "#{}", dis
)?
;
1184 self.empty_path
= false;
1189 fn path_generic_args(
1191 print_prefix
: impl FnOnce(Self) -> Result
<Self::Path
, Self::Error
>,
1192 args
: &[Kind
<'tcx
>],
1193 ) -> Result
<Self::Path
, Self::Error
> {
1194 self = print_prefix(self)?
;
1196 // Don't print `'_` if there's no unerased regions.
1197 let print_regions
= args
.iter().any(|arg
| {
1198 match arg
.unpack() {
1199 UnpackedKind
::Lifetime(r
) => *r
!= ty
::ReErased
,
1203 let args
= args
.iter().cloned().filter(|arg
| {
1204 match arg
.unpack() {
1205 UnpackedKind
::Lifetime(_
) => print_regions
,
1210 if args
.clone().next().is_some() {
1212 write
!(self, "::")?
;
1214 self.generic_delimiters(|cx
| cx
.comma_sep(args
))
1221 impl<F
: fmt
::Write
> PrettyPrinter
<'tcx
> for FmtPrinter
<'_
, 'tcx
, F
> {
1222 fn infer_ty_name(&self, id
: ty
::TyVid
) -> Option
<String
> {
1223 self.0.name_resolver
.as_ref().and_then(|func
| func(id
))
1226 fn print_value_path(
1229 substs
: &'tcx
[Kind
<'tcx
>],
1230 ) -> Result
<Self::Path
, Self::Error
> {
1231 let was_in_value
= std
::mem
::replace(&mut self.in_value
, true);
1232 self = self.print_def_path(def_id
, substs
)?
;
1233 self.in_value
= was_in_value
;
1238 fn in_binder
<T
>(self, value
: &ty
::Binder
<T
>) -> Result
<Self, Self::Error
>
1240 T
: Print
<'tcx
, Self, Output
= Self, Error
= Self::Error
> + TypeFoldable
<'tcx
>,
1242 self.pretty_in_binder(value
)
1245 fn generic_delimiters(
1247 f
: impl FnOnce(Self) -> Result
<Self, Self::Error
>,
1248 ) -> Result
<Self, Self::Error
> {
1251 let was_in_value
= std
::mem
::replace(&mut self.in_value
, false);
1252 let mut inner
= f(self)?
;
1253 inner
.in_value
= was_in_value
;
1255 write
!(inner
, ">")?
;
1259 fn region_should_not_be_omitted(
1261 region
: ty
::Region
<'_
>,
1263 let highlight
= self.region_highlight_mode
;
1264 if highlight
.region_highlighted(region
).is_some() {
1268 if self.tcx
.sess
.verbose() {
1272 let identify_regions
= self.tcx
.sess
.opts
.debugging_opts
.identify_regions
;
1275 ty
::ReEarlyBound(ref data
) => {
1276 data
.name
.as_symbol() != kw
::Invalid
&&
1277 data
.name
.as_symbol() != kw
::UnderscoreLifetime
1280 ty
::ReLateBound(_
, br
) |
1281 ty
::ReFree(ty
::FreeRegion { bound_region: br, .. }
) |
1282 ty
::RePlaceholder(ty
::Placeholder { name: br, .. }
) => {
1283 if let ty
::BrNamed(_
, name
) = br
{
1284 if name
.as_symbol() != kw
::Invalid
&&
1285 name
.as_symbol() != kw
::UnderscoreLifetime
{
1290 if let Some((region
, _
)) = highlight
.highlight_bound_region
{
1300 ty
::ReVar(_
) if identify_regions
=> true,
1304 ty
::ReErased
=> false,
1308 ty
::ReClosureBound(_
) => true,
1313 // HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
1314 impl<F
: fmt
::Write
> FmtPrinter
<'_
, '_
, F
> {
1315 pub fn pretty_print_region(
1317 region
: ty
::Region
<'_
>,
1318 ) -> Result
<Self, fmt
::Error
> {
1319 define_scoped_cx
!(self);
1321 // Watch out for region highlights.
1322 let highlight
= self.region_highlight_mode
;
1323 if let Some(n
) = highlight
.region_highlighted(region
) {
1324 p
!(write("'{}", n
));
1328 if self.tcx
.sess
.verbose() {
1329 p
!(write("{:?}", region
));
1333 let identify_regions
= self.tcx
.sess
.opts
.debugging_opts
.identify_regions
;
1335 // These printouts are concise. They do not contain all the information
1336 // the user might want to diagnose an error, but there is basically no way
1337 // to fit that into a short string. Hence the recommendation to use
1338 // `explain_region()` or `note_and_explain_region()`.
1340 ty
::ReEarlyBound(ref data
) => {
1341 if data
.name
.as_symbol() != kw
::Invalid
{
1342 p
!(write("{}", data
.name
));
1346 ty
::ReLateBound(_
, br
) |
1347 ty
::ReFree(ty
::FreeRegion { bound_region: br, .. }
) |
1348 ty
::RePlaceholder(ty
::Placeholder { name: br, .. }
) => {
1349 if let ty
::BrNamed(_
, name
) = br
{
1350 if name
.as_symbol() != kw
::Invalid
&&
1351 name
.as_symbol() != kw
::UnderscoreLifetime
{
1352 p
!(write("{}", name
));
1357 if let Some((region
, counter
)) = highlight
.highlight_bound_region
{
1359 p
!(write("'{}", counter
));
1364 ty
::ReScope(scope
) if identify_regions
=> {
1366 region
::ScopeData
::Node
=>
1367 p
!(write("'{}s", scope
.item_local_id().as_usize())),
1368 region
::ScopeData
::CallSite
=>
1369 p
!(write("'{}cs", scope
.item_local_id().as_usize())),
1370 region
::ScopeData
::Arguments
=>
1371 p
!(write("'{}as", scope
.item_local_id().as_usize())),
1372 region
::ScopeData
::Destruction
=>
1373 p
!(write("'{}ds", scope
.item_local_id().as_usize())),
1374 region
::ScopeData
::Remainder(first_statement_index
) => p
!(write(
1376 scope
.item_local_id().as_usize(),
1377 first_statement_index
.index()
1382 ty
::ReVar(region_vid
) if identify_regions
=> {
1383 p
!(write("{:?}", region_vid
));
1390 p
!(write("'static"));
1394 p
!(write("'<empty>"));
1398 // The user should never encounter these in unsubstituted form.
1399 ty
::ReClosureBound(vid
) => {
1400 p
!(write("{:?}", vid
));
1411 // HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
1412 // `region_index` and `used_region_names`.
1413 impl<F
: fmt
::Write
> FmtPrinter
<'_
, 'tcx
, F
> {
1414 pub fn pretty_in_binder
<T
>(mut self, value
: &ty
::Binder
<T
>) -> Result
<Self, fmt
::Error
>
1416 T
: Print
<'tcx
, Self, Output
= Self, Error
= fmt
::Error
> + TypeFoldable
<'tcx
>,
1418 fn name_by_region_index(index
: usize) -> InternedString
{
1420 0 => InternedString
::intern("'r"),
1421 1 => InternedString
::intern("'s"),
1422 i
=> InternedString
::intern(&format
!("'t{}", i
-2)),
1426 // Replace any anonymous late-bound regions with named
1427 // variants, using gensym'd identifiers, so that we can
1428 // clearly differentiate between named and unnamed regions in
1429 // the output. We'll probably want to tweak this over time to
1430 // decide just how much information to give.
1431 if self.binder_depth
== 0 {
1432 self.prepare_late_bound_region_info(value
);
1435 let mut empty
= true;
1436 let mut start_or_continue
= |cx
: &mut Self, start
: &str, cont
: &str| {
1437 write
!(cx
, "{}", if empty
{
1445 define_scoped_cx
!(self);
1447 let old_region_index
= self.region_index
;
1448 let mut region_index
= old_region_index
;
1449 let new_value
= self.tcx
.replace_late_bound_regions(value
, |br
| {
1450 let _
= start_or_continue(&mut self, "for<", ", ");
1452 ty
::BrNamed(_
, name
) => {
1453 let _
= write
!(self, "{}", name
);
1459 let name
= name_by_region_index(region_index
);
1461 if !self.used_region_names
.contains(&name
) {
1465 let _
= write
!(self, "{}", name
);
1466 ty
::BrNamed(DefId
::local(CRATE_DEF_INDEX
), name
)
1469 self.tcx
.mk_region(ty
::ReLateBound(ty
::INNERMOST
, br
))
1471 start_or_continue(&mut self, "", "> ")?
;
1473 self.binder_depth
+= 1;
1474 self.region_index
= region_index
;
1475 let mut inner
= new_value
.print(self)?
;
1476 inner
.region_index
= old_region_index
;
1477 inner
.binder_depth
-= 1;
1481 fn prepare_late_bound_region_info
<T
>(&mut self, value
: &ty
::Binder
<T
>)
1482 where T
: TypeFoldable
<'tcx
>
1485 struct LateBoundRegionNameCollector
<'a
>(&'a
mut FxHashSet
<InternedString
>);
1486 impl<'tcx
> ty
::fold
::TypeVisitor
<'tcx
> for LateBoundRegionNameCollector
<'_
> {
1487 fn visit_region(&mut self, r
: ty
::Region
<'tcx
>) -> bool
{
1489 ty
::ReLateBound(_
, ty
::BrNamed(_
, name
)) => {
1490 self.0.insert
(name
);
1494 r
.super_visit_with(self)
1498 self.used_region_names
.clear();
1499 let mut collector
= LateBoundRegionNameCollector(&mut self.used_region_names
);
1500 value
.visit_with(&mut collector
);
1501 self.region_index
= 0;
1505 impl<'tcx
, T
, P
: PrettyPrinter
<'tcx
>> Print
<'tcx
, P
> for ty
::Binder
<T
>
1507 T
: Print
<'tcx
, P
, Output
= P
, Error
= P
::Error
> + TypeFoldable
<'tcx
>,
1510 type Error
= P
::Error
;
1511 fn print(&self, cx
: P
) -> Result
<Self::Output
, Self::Error
> {
1516 impl<'tcx
, T
, U
, P
: PrettyPrinter
<'tcx
>> Print
<'tcx
, P
> for ty
::OutlivesPredicate
<T
, U
>
1518 T
: Print
<'tcx
, P
, Output
= P
, Error
= P
::Error
>,
1519 U
: Print
<'tcx
, P
, Output
= P
, Error
= P
::Error
>,
1522 type Error
= P
::Error
;
1523 fn print(&self, mut cx
: P
) -> Result
<Self::Output
, Self::Error
> {
1524 define_scoped_cx
!(cx
);
1525 p
!(print(self.0), write(" : "), print(self.1));
1530 macro_rules
! forward_display_to_print
{
1532 $
(impl fmt
::Display
for $ty
{
1533 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1534 ty
::tls
::with(|tcx
| {
1536 .expect("could not lift for printing")
1537 .print(FmtPrinter
::new(tcx
, f
, Namespace
::TypeNS
))?
;
1545 macro_rules
! define_print_and_forward_display
{
1546 (($
self:ident
, $cx
:ident
): $
($ty
:ty $print
:block
)+) => {
1547 $
(impl<'tcx
, P
: PrettyPrinter
<'tcx
>> Print
<'tcx
, P
> for $ty
{
1549 type Error
= fmt
::Error
;
1550 fn print(&$
self, $cx
: P
) -> Result
<Self::Output
, Self::Error
> {
1551 #[allow(unused_mut)]
1553 define_scoped_cx
!($cx
);
1555 #[allow(unreachable_code)]
1560 forward_display_to_print
!($
($ty
),+);
1564 // HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
1565 impl fmt
::Display
for ty
::RegionKind
{
1566 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1567 ty
::tls
::with(|tcx
| {
1568 self.print(FmtPrinter
::new(tcx
, f
, Namespace
::TypeNS
))?
;
1574 forward_display_to_print
! {
1576 &'tcx ty
::List
<ty
::ExistentialPredicate
<'tcx
>>,
1577 &'tcx ty
::Const
<'tcx
>,
1579 // HACK(eddyb) these are exhaustive instead of generic,
1580 // because `for<'tcx>` isn't possible yet.
1581 ty
::Binder
<&'tcx ty
::List
<ty
::ExistentialPredicate
<'tcx
>>>,
1582 ty
::Binder
<ty
::TraitRef
<'tcx
>>,
1583 ty
::Binder
<ty
::FnSig
<'tcx
>>,
1584 ty
::Binder
<ty
::TraitPredicate
<'tcx
>>,
1585 ty
::Binder
<ty
::SubtypePredicate
<'tcx
>>,
1586 ty
::Binder
<ty
::ProjectionPredicate
<'tcx
>>,
1587 ty
::Binder
<ty
::OutlivesPredicate
<Ty
<'tcx
>, ty
::Region
<'tcx
>>>,
1588 ty
::Binder
<ty
::OutlivesPredicate
<ty
::Region
<'tcx
>, ty
::Region
<'tcx
>>>,
1590 ty
::OutlivesPredicate
<Ty
<'tcx
>, ty
::Region
<'tcx
>>,
1591 ty
::OutlivesPredicate
<ty
::Region
<'tcx
>, ty
::Region
<'tcx
>>
1594 define_print_and_forward_display
! {
1597 &'tcx ty
::List
<Ty
<'tcx
>> {
1599 let mut tys
= self.iter();
1600 if let Some(&ty
) = tys
.next() {
1603 p
!(write(", "), print(ty
));
1609 ty
::TypeAndMut
<'tcx
> {
1610 p
!(write("{}", if self.mutbl
== hir
::MutMutable { "mut " }
else { "" }
),
1614 ty
::ExistentialTraitRef
<'tcx
> {
1615 // Use a type that can't appear in defaults of type parameters.
1616 let dummy_self
= cx
.tcx().mk_ty_infer(ty
::FreshTy(0));
1617 let trait_ref
= self.with_self_ty(cx
.tcx(), dummy_self
);
1618 p
!(print(trait_ref
))
1621 ty
::ExistentialProjection
<'tcx
> {
1622 let name
= cx
.tcx().associated_item(self.item_def_id
).ident
;
1623 p
!(write("{} = ", name
), print(self.ty
))
1626 ty
::ExistentialPredicate
<'tcx
> {
1628 ty
::ExistentialPredicate
::Trait(x
) => p
!(print(x
)),
1629 ty
::ExistentialPredicate
::Projection(x
) => p
!(print(x
)),
1630 ty
::ExistentialPredicate
::AutoTrait(def_id
) => {
1631 p
!(print_def_path(def_id
, &[]));
1637 if self.unsafety
== hir
::Unsafety
::Unsafe
{
1638 p
!(write("unsafe "));
1641 if self.abi
!= Abi
::Rust
{
1642 p
!(write("extern {} ", self.abi
));
1645 p
!(write("fn"), pretty_fn_sig(self.inputs(), self.c_variadic
, self.output()));
1649 if cx
.tcx().sess
.verbose() {
1650 p
!(write("{:?}", self));
1654 ty
::TyVar(_
) => p
!(write("_")),
1655 ty
::IntVar(_
) => p
!(write("{}", "{integer}")),
1656 ty
::FloatVar(_
) => p
!(write("{}", "{float}")),
1657 ty
::FreshTy(v
) => p
!(write("FreshTy({})", v
)),
1658 ty
::FreshIntTy(v
) => p
!(write("FreshIntTy({})", v
)),
1659 ty
::FreshFloatTy(v
) => p
!(write("FreshFloatTy({})", v
))
1663 ty
::TraitRef
<'tcx
> {
1664 p
!(print_def_path(self.def_id
, self.substs
));
1668 p
!(write("{}", self.name
))
1672 p
!(write("{}", self.name
))
1675 ty
::SubtypePredicate
<'tcx
> {
1676 p
!(print(self.a
), write(" <: "), print(self.b
))
1679 ty
::TraitPredicate
<'tcx
> {
1680 p
!(print(self.trait_ref
.self_ty()), write(": "), print(self.trait_ref
))
1683 ty
::ProjectionPredicate
<'tcx
> {
1684 p
!(print(self.projection_ty
), write(" == "), print(self.ty
))
1687 ty
::ProjectionTy
<'tcx
> {
1688 p
!(print_def_path(self.item_def_id
, self.substs
));
1693 ty
::ClosureKind
::Fn
=> p
!(write("Fn")),
1694 ty
::ClosureKind
::FnMut
=> p
!(write("FnMut")),
1695 ty
::ClosureKind
::FnOnce
=> p
!(write("FnOnce")),
1699 ty
::Predicate
<'tcx
> {
1701 ty
::Predicate
::Trait(ref data
) => p
!(print(data
)),
1702 ty
::Predicate
::Subtype(ref predicate
) => p
!(print(predicate
)),
1703 ty
::Predicate
::RegionOutlives(ref predicate
) => p
!(print(predicate
)),
1704 ty
::Predicate
::TypeOutlives(ref predicate
) => p
!(print(predicate
)),
1705 ty
::Predicate
::Projection(ref predicate
) => p
!(print(predicate
)),
1706 ty
::Predicate
::WellFormed(ty
) => p
!(print(ty
), write(" well-formed")),
1707 ty
::Predicate
::ObjectSafe(trait_def_id
) => {
1708 p
!(write("the trait `"),
1709 print_def_path(trait_def_id
, &[]),
1710 write("` is object-safe"))
1712 ty
::Predicate
::ClosureKind(closure_def_id
, _closure_substs
, kind
) => {
1713 p
!(write("the closure `"),
1714 print_value_path(closure_def_id
, &[]),
1715 write("` implements the trait `{}`", kind
))
1717 ty
::Predicate
::ConstEvaluatable(def_id
, substs
) => {
1718 p
!(write("the constant `"),
1719 print_value_path(def_id
, substs
),
1720 write("` can be evaluated"))
1726 match self.unpack() {
1727 UnpackedKind
::Lifetime(lt
) => p
!(print(lt
)),
1728 UnpackedKind
::Type(ty
) => p
!(print(ty
)),
1729 UnpackedKind
::Const(ct
) => p
!(print(ct
)),