1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use middle::def_id::DefId;
13 use middle::subst::{self, Subst};
14 use middle::ty::{BrAnon, BrEnv, BrFresh, BrNamed};
15 use middle::ty::{TyBool, TyChar, TyStruct, TyEnum};
16 use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
17 use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple};
18 use middle::ty::TyClosure;
19 use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
20 use middle::ty::{self, Ty, TyCtxt, TypeFoldable};
24 use syntax::parse::token;
25 use syntax::ast::CRATE_NODE_ID;
28 pub fn verbose() -> bool {
29 ty::tls::with(|tcx| tcx.sess.verbose())
32 fn fn_sig(f: &mut fmt::Formatter,
38 let mut inputs = inputs.iter();
39 if let Some(&ty) = inputs.next() {
42 write!(f, ", {}", ty)?;
51 ty::FnConverging(ty) => {
53 write!(f, " -> {}", ty)?;
63 /// Namespace of the path given to parameterized to print.
64 #[derive(Copy, Clone, PartialEq)]
70 pub fn parameterized<GG>(f: &mut fmt::Formatter,
71 substs: &subst::Substs,
74 projections: &[ty::ProjectionPredicate],
77 where GG: for<'tcx> FnOnce(&TyCtxt<'tcx>) -> ty::Generics<'tcx>
79 if let (Ns::Value, Some(self_ty)) = (ns, substs.self_ty()) {
80 write!(f, "<{} as ", self_ty)?;
83 let (fn_trait_kind, verbose, last_name) = ty::tls::with(|tcx| {
84 let (did, last_name) = if ns == Ns::Value {
85 // Try to get the impl/trait parent, if this is an
86 // associated value item (method or constant).
87 tcx.trait_of_item(did).or_else(|| tcx.impl_of_method(did))
88 .map_or((did, None), |parent| (parent, Some(tcx.item_name(did))))
92 write!(f, "{}", tcx.item_path_str(did))?;
93 Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose(), last_name))
97 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
100 write!(f, "{}", start)
102 write!(f, "{}", cont)
107 match substs.regions {
108 subst::ErasedRegions => {
109 start_or_continue(f, "<", ", ")?;
112 subst::NonerasedRegions(ref regions) => {
113 for region in regions {
114 start_or_continue(f, "<", ", ")?;
115 write!(f, "{:?}", region)?;
119 for &ty in &substs.types {
120 start_or_continue(f, "<", ", ")?;
121 write!(f, "{}", ty)?;
123 for projection in projections {
124 start_or_continue(f, "<", ", ")?;
126 projection.projection_ty.item_name,
129 return start_or_continue(f, "", ">");
132 if fn_trait_kind.is_some() && projections.len() == 1 {
133 let projection_ty = projections[0].ty;
134 if let TyTuple(ref args) = substs.types.get_slice(subst::TypeSpace)[0].sty {
135 return fn_sig(f, args, false, ty::FnConverging(projection_ty));
139 match substs.regions {
140 subst::ErasedRegions => { }
141 subst::NonerasedRegions(ref regions) => {
143 start_or_continue(f, "<", ", ")?;
144 let s = r.to_string();
146 // This happens when the value of the region
147 // parameter is not easily serialized. This may be
148 // because the user omitted it in the first place,
149 // or because it refers to some block in the code,
150 // etc. I'm not sure how best to serialize this.
159 // It is important to execute this conditionally, only if -Z
160 // verbose is false. Otherwise, debug logs can sometimes cause
161 // ICEs trying to fetch the generics early in the pipeline. This
162 // is kind of a hacky workaround in that -Z verbose is required to
164 let tps = substs.types.get_slice(subst::TypeSpace);
165 let num_defaults = ty::tls::with(|tcx| {
166 let generics = get_generics(tcx);
168 let has_self = substs.self_ty().is_some();
169 let ty_params = generics.types.get_slice(subst::TypeSpace);
170 if ty_params.last().map_or(false, |def| def.default.is_some()) {
171 let substs = tcx.lift(&substs);
172 ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
175 if !has_self && default.has_self_ty() {
176 // In an object type, there is no `Self`, and
177 // thus if the default value references Self,
178 // the user will be required to give an
179 // explicit value. We can't even do the
180 // substitution below to check without causing
184 let default = tcx.lift(&default);
185 substs.and_then(|substs| default.subst(tcx, substs)) == Some(actual)
196 for &ty in &tps[..tps.len() - num_defaults] {
197 start_or_continue(f, "<", ", ")?;
198 write!(f, "{}", ty)?;
201 for projection in projections {
202 start_or_continue(f, "<", ", ")?;
204 projection.projection_ty.item_name,
208 start_or_continue(f, "", ">")?;
210 // For values, also print their name and type parameters.
212 if substs.self_ty().is_some() {
216 if let Some(name) = last_name {
217 write!(f, "::{}", name)?;
219 let tps = substs.types.get_slice(subst::FnSpace);
221 write!(f, "::<{}", tps[0])?;
222 for ty in &tps[1..] {
223 write!(f, ", {}", ty)?;
232 fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
234 original: &ty::Binder<T>,
235 lifted: Option<ty::Binder<U>>) -> fmt::Result
236 where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx>
238 // Replace any anonymous late-bound regions with named
239 // variants, using gensym'd identifiers, so that we can
240 // clearly differentiate between named and unnamed regions in
241 // the output. We'll probably want to tweak this over time to
242 // decide just how much information to give.
243 let value = if let Some(v) = lifted {
246 return write!(f, "{}", original.0);
249 let mut empty = true;
250 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
253 write!(f, "{}", start)
255 write!(f, "{}", cont)
259 let new_value = tcx.replace_late_bound_regions(&value, |br| {
260 let _ = start_or_continue(f, "for<", ", ");
261 ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
262 ty::BrNamed(_, name) => {
263 let _ = write!(f, "{}", name);
269 let name = token::intern("'r");
270 let _ = write!(f, "{}", name);
271 ty::BrNamed(tcx.map.local_def_id(CRATE_NODE_ID), name)
276 start_or_continue(f, "", "> ")?;
277 write!(f, "{}", new_value)
280 /// This curious type is here to help pretty-print trait objects. In
281 /// a trait object, the projections are stored separately from the
282 /// main trait bound, but in fact we want to package them together
283 /// when printing out; they also have separate binders, but we want
284 /// them to share a binder when we print them out. (And the binder
285 /// pretty-printing logic is kind of clever and we don't want to
286 /// reproduce it.) So we just repackage up the structure somewhat.
288 /// Right now there is only one trait in an object that can have
289 /// projection bounds, so we just stuff them altogether. But in
290 /// reality we should eventually sort things out better.
291 #[derive(Clone, Debug)]
292 struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>, Vec<ty::ProjectionPredicate<'tcx>>);
294 impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> {
295 fn super_fold_with<F:ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
296 TraitAndProjections(self.0.fold_with(folder), self.1.fold_with(folder))
299 fn super_visit_with<V: ty::fold::TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
300 self.0.visit_with(visitor) || self.1.visit_with(visitor)
304 impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
305 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
306 let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
307 parameterized(f, trait_ref.substs,
311 |tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone())
315 impl<'tcx> fmt::Display for ty::TraitTy<'tcx> {
316 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317 let bounds = &self.bounds;
319 // Generate the main trait ref, including associated types.
320 ty::tls::with(|tcx| {
321 let principal = tcx.lift(&self.principal.0)
322 .expect("could not lift TraitRef for printing");
323 let projections = tcx.lift(&bounds.projection_bounds[..])
324 .expect("could not lift projections for printing");
325 let projections = projections.into_iter().map(|p| p.0).collect();
327 let tap = ty::Binder(TraitAndProjections(principal, projections));
328 in_binder(f, tcx, &ty::Binder(""), Some(tap))
332 for bound in &bounds.builtin_bounds {
333 write!(f, " + {:?}", bound)?;
336 // FIXME: It'd be nice to compute from context when this bound
337 // is implied, but that's non-trivial -- we'd perhaps have to
338 // use thread-local data of some kind? There are also
339 // advantages to just showing the region, since it makes
340 // people aware that it's there.
341 let bound = bounds.region_bound.to_string();
342 if !bound.is_empty() {
343 write!(f, " + {}", bound)?;
350 impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
351 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
352 write!(f, "TypeParameterDef({}, {:?}, {:?}/{})",
355 self.space, self.index)
359 impl fmt::Debug for ty::RegionParameterDef {
360 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
361 write!(f, "RegionParameterDef({}, {:?}, {:?}/{}, {:?})",
364 self.space, self.index,
369 impl<'tcx> fmt::Debug for ty::TyS<'tcx> {
370 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
371 write!(f, "{}", *self)
375 impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
376 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378 if self.mutbl == hir::MutMutable { "mut " } else { "" },
383 impl<'tcx> fmt::Debug for subst::Substs<'tcx> {
384 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
385 write!(f, "Substs[types={:?}, regions={:?}]",
386 self.types, self.regions)
390 impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
391 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
392 write!(f, "ItemSubsts({:?})", self.substs)
396 impl fmt::Debug for subst::RegionSubsts {
397 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
399 subst::ErasedRegions => write!(f, "erased"),
400 subst::NonerasedRegions(ref regions) => write!(f, "{:?}", regions)
405 impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
406 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
407 // when printing out the debug representation, we don't need
408 // to enumerate the `for<...>` etc because the debruijn index
409 // tells you everything you need to know.
410 match self.substs.self_ty() {
411 None => write!(f, "{}", *self),
412 Some(self_ty) => write!(f, "<{:?} as {}>", self_ty, *self)
417 impl<'tcx> fmt::Debug for ty::TraitDef<'tcx> {
418 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
419 write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
420 self.generics, self.trait_ref)
424 impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> {
425 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
426 ty::tls::with(|tcx| {
427 write!(f, "{}", tcx.item_path_str(self.did))
432 impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> {
433 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
435 ty::adjustment::AdjustReifyFnPointer => {
436 write!(f, "AdjustReifyFnPointer")
438 ty::adjustment::AdjustUnsafeFnPointer => {
439 write!(f, "AdjustUnsafeFnPointer")
441 ty::adjustment::AdjustMutToConstPointer => {
442 write!(f, "AdjustMutToConstPointer")
444 ty::adjustment::AdjustDerefRef(ref data) => {
445 write!(f, "{:?}", data)
451 impl<'tcx> fmt::Debug for ty::adjustment::AutoDerefRef<'tcx> {
452 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
453 write!(f, "AutoDerefRef({}, unsize={:?}, {:?})",
454 self.autoderefs, self.unsize, self.autoref)
458 impl<'tcx> fmt::Debug for ty::TraitTy<'tcx> {
459 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
460 write!(f, "TraitTy({:?},{:?})",
466 impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
467 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
469 ty::Predicate::Trait(ref a) => write!(f, "{:?}", a),
470 ty::Predicate::Equate(ref pair) => write!(f, "{:?}", pair),
471 ty::Predicate::RegionOutlives(ref pair) => write!(f, "{:?}", pair),
472 ty::Predicate::TypeOutlives(ref pair) => write!(f, "{:?}", pair),
473 ty::Predicate::Projection(ref pair) => write!(f, "{:?}", pair),
474 ty::Predicate::WellFormed(ty) => write!(f, "WF({:?})", ty),
475 ty::Predicate::ObjectSafe(trait_def_id) => {
476 write!(f, "ObjectSafe({:?})", trait_def_id)
482 impl fmt::Display for ty::BoundRegion {
483 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
485 return write!(f, "{:?}", *self);
489 BrNamed(_, name) => write!(f, "{}", name),
490 BrAnon(_) | BrFresh(_) | BrEnv => Ok(())
495 impl fmt::Debug for ty::BoundRegion {
496 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
498 BrAnon(n) => write!(f, "BrAnon({:?})", n),
499 BrFresh(n) => write!(f, "BrFresh({:?})", n),
500 BrNamed(did, name) => {
501 write!(f, "BrNamed({:?}, {:?})", did, name)
503 BrEnv => "BrEnv".fmt(f),
508 impl fmt::Debug for ty::Region {
509 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
511 ty::ReEarlyBound(ref data) => {
512 write!(f, "ReEarlyBound({:?}, {}, {})",
518 ty::ReLateBound(binder_id, ref bound_region) => {
519 write!(f, "ReLateBound({:?}, {:?})",
524 ty::ReFree(ref fr) => write!(f, "{:?}", fr),
527 write!(f, "ReScope({:?})", id)
530 ty::ReStatic => write!(f, "ReStatic"),
532 ty::ReVar(ref vid) => {
533 write!(f, "{:?}", vid)
536 ty::ReSkolemized(id, ref bound_region) => {
537 write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
540 ty::ReEmpty => write!(f, "ReEmpty")
545 impl<'tcx> fmt::Debug for ty::ClosureTy<'tcx> {
546 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
547 write!(f, "ClosureTy({},{:?},{})",
554 impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
555 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
556 write!(f, "ClosureUpvar({:?},{:?})",
562 impl<'a, 'tcx> fmt::Debug for ty::ParameterEnvironment<'a, 'tcx> {
563 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
564 write!(f, "ParameterEnvironment(\
566 implicit_region_bound={:?}, \
567 caller_bounds={:?})",
569 self.implicit_region_bound,
574 impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault {
575 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
577 ty::ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
578 ty::ObjectLifetimeDefault::BaseDefault => write!(f, "BaseDefault"),
579 ty::ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
584 impl fmt::Display for ty::Region {
585 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
587 return write!(f, "{:?}", *self);
590 // These printouts are concise. They do not contain all the information
591 // the user might want to diagnose an error, but there is basically no way
592 // to fit that into a short string. Hence the recommendation to use
593 // `explain_region()` or `note_and_explain_region()`.
595 ty::ReEarlyBound(ref data) => {
596 write!(f, "{}", data.name)
598 ty::ReLateBound(_, br) |
599 ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
600 ty::ReSkolemized(_, br) => {
604 ty::ReVar(_) => Ok(()),
605 ty::ReStatic => write!(f, "'static"),
606 ty::ReEmpty => write!(f, "'<empty>"),
611 impl fmt::Debug for ty::FreeRegion {
612 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
613 write!(f, "ReFree({:?}, {:?})",
614 self.scope, self.bound_region)
618 impl fmt::Debug for ty::Variance {
619 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
620 f.write_str(match *self {
621 ty::Covariant => "+",
622 ty::Contravariant => "-",
623 ty::Invariant => "o",
624 ty::Bivariant => "*",
629 impl fmt::Debug for ty::ItemVariances {
630 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
631 write!(f, "ItemVariances(types={:?}, regions={:?})",
632 self.types, self.regions)
636 impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> {
637 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
638 write!(f, "GenericPredicates({:?})", self.predicates)
642 impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
643 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
644 write!(f, "InstantiatedPredicates({:?})",
649 impl<'tcx> fmt::Debug for ty::ImplOrTraitItem<'tcx> {
650 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
651 write!(f, "ImplOrTraitItem(")?;
653 ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i),
654 ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i),
655 ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i),
661 impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
662 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
664 fn_sig(f, &self.inputs, self.variadic, self.output)
668 impl<'tcx> fmt::Debug for ty::ExistentialBounds<'tcx> {
669 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
670 let mut empty = true;
671 let mut maybe_continue = |f: &mut fmt::Formatter| {
680 let region_str = format!("{:?}", self.region_bound);
681 if !region_str.is_empty() {
683 write!(f, "{}", region_str)?;
686 for bound in &self.builtin_bounds {
688 write!(f, "{:?}", bound)?;
691 for projection_bound in &self.projection_bounds {
693 write!(f, "{:?}", projection_bound)?;
700 impl fmt::Display for ty::BuiltinBounds {
701 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
702 let mut bounds = self.iter();
703 if let Some(bound) = bounds.next() {
704 write!(f, "{:?}", bound)?;
705 for bound in bounds {
706 write!(f, " + {:?}", bound)?;
713 impl fmt::Debug for ty::TyVid {
714 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
715 write!(f, "_#{}t", self.index)
719 impl fmt::Debug for ty::IntVid {
720 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
721 write!(f, "_#{}i", self.index)
725 impl fmt::Debug for ty::FloatVid {
726 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
727 write!(f, "_#{}f", self.index)
731 impl fmt::Debug for ty::RegionVid {
732 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
733 write!(f, "'_#{}r", self.index)
737 impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
738 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
739 write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
743 impl fmt::Debug for ty::InferTy {
744 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
746 ty::TyVar(ref v) => v.fmt(f),
747 ty::IntVar(ref v) => v.fmt(f),
748 ty::FloatVar(ref v) => v.fmt(f),
749 ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
750 ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
751 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
756 impl fmt::Debug for ty::IntVarValue {
757 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
759 ty::IntType(ref v) => v.fmt(f),
760 ty::UintType(ref v) => v.fmt(f),
765 // The generic impl doesn't work yet because projections are not
766 // normalized under HRTB.
767 /*impl<T> fmt::Display for ty::Binder<T>
768 where T: fmt::Display + for<'a> ty::Lift<'a>,
769 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
771 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
772 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
776 impl<'tcx> fmt::Display for ty::Binder<ty::TraitRef<'tcx>> {
777 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
778 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
782 impl<'tcx> fmt::Display for ty::Binder<ty::TraitPredicate<'tcx>> {
783 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
784 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
788 impl<'tcx> fmt::Display for ty::Binder<ty::EquatePredicate<'tcx>> {
789 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
790 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
794 impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
795 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
796 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
800 impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region>> {
801 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
802 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
806 impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>> {
807 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
808 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
812 impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
813 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
814 parameterized(f, self.substs, self.def_id, Ns::Type, &[],
815 |tcx| tcx.lookup_trait_def(self.def_id).generics.clone())
819 impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
820 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
822 TyBool => write!(f, "bool"),
823 TyChar => write!(f, "char"),
824 TyInt(t) => write!(f, "{}", t.ty_to_string()),
825 TyUint(t) => write!(f, "{}", t.ty_to_string()),
826 TyFloat(t) => write!(f, "{}", t.ty_to_string()),
827 TyBox(typ) => write!(f, "Box<{}>", typ),
828 TyRawPtr(ref tm) => {
829 write!(f, "*{} {}", match tm.mutbl {
830 hir::MutMutable => "mut",
831 hir::MutImmutable => "const",
834 TyRef(r, ref tm) => {
836 let s = r.to_string();
843 TyTuple(ref tys) => {
845 let mut tys = tys.iter();
846 if let Some(&ty) = tys.next() {
847 write!(f, "{},", ty)?;
848 if let Some(&ty) = tys.next() {
849 write!(f, " {}", ty)?;
851 write!(f, ", {}", ty)?;
857 TyFnDef(def_id, substs, ref bare_fn) => {
858 if bare_fn.unsafety == hir::Unsafety::Unsafe {
859 write!(f, "unsafe ")?;
862 if bare_fn.abi != Abi::Rust {
863 write!(f, "extern {} ", bare_fn.abi)?;
866 write!(f, "{} {{", bare_fn.sig.0)?;
867 parameterized(f, substs, def_id, Ns::Value, &[],
868 |tcx| tcx.lookup_item_type(def_id).generics)?;
871 TyFnPtr(ref bare_fn) => {
872 if bare_fn.unsafety == hir::Unsafety::Unsafe {
873 write!(f, "unsafe ")?;
876 if bare_fn.abi != Abi::Rust {
877 write!(f, "extern {} ", bare_fn.abi)?;
880 write!(f, "{}", bare_fn.sig.0)
882 TyInfer(infer_ty) => write!(f, "{}", infer_ty),
883 TyError => write!(f, "[type error]"),
884 TyParam(ref param_ty) => write!(f, "{}", param_ty),
885 TyEnum(def, substs) | TyStruct(def, substs) => {
886 ty::tls::with(|tcx| {
887 if def.did.is_local() &&
888 !tcx.tcache.borrow().contains_key(&def.did) {
889 write!(f, "{}<..>", tcx.item_path_str(def.did))
891 parameterized(f, substs, def.did, Ns::Type, &[],
892 |tcx| tcx.lookup_item_type(def.did).generics)
896 TyTrait(ref data) => write!(f, "{}", data),
897 ty::TyProjection(ref data) => write!(f, "{}", data),
898 TyStr => write!(f, "str"),
899 TyClosure(did, ref substs) => ty::tls::with(|tcx| {
900 write!(f, "[closure")?;
902 if let Some(node_id) = tcx.map.as_local_node_id(did) {
903 write!(f, "@{:?}", tcx.map.span(node_id))?;
905 tcx.with_freevars(node_id, |freevars| {
906 for (freevar, upvar_ty) in freevars.iter().zip(&substs.upvar_tys) {
907 let node_id = freevar.def.var_id();
911 tcx.local_var_name_str(node_id),
918 // cross-crate closure types should only be
919 // visible in trans bug reports, I imagine.
920 write!(f, "@{:?}", did)?;
922 for (index, upvar_ty) in substs.upvar_tys.iter().enumerate() {
923 write!(f, "{}{}:{}", sep, index, upvar_ty)?;
930 TyArray(ty, sz) => write!(f, "[{}; {}]", ty, sz),
931 TySlice(ty) => write!(f, "[{}]", ty)
936 impl<'tcx> fmt::Display for ty::TyS<'tcx> {
937 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
938 write!(f, "{}", self.sty)
942 impl fmt::Debug for ty::UpvarId {
943 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
944 write!(f, "UpvarId({};`{}`;{})",
946 ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)),
947 self.closure_expr_id)
951 impl fmt::Debug for ty::UpvarBorrow {
952 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
953 write!(f, "UpvarBorrow({:?}, {:?})",
954 self.kind, self.region)
958 impl fmt::Display for ty::InferTy {
959 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
960 let print_var_ids = verbose();
962 ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
963 ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
964 ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
965 ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => write!(f, "_"),
966 ty::FreshTy(v) => write!(f, "FreshTy({})", v),
967 ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
968 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
973 impl fmt::Display for ty::ExplicitSelfCategory {
974 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
975 f.write_str(match *self {
976 ty::ExplicitSelfCategory::Static => "static",
977 ty::ExplicitSelfCategory::ByValue => "self",
978 ty::ExplicitSelfCategory::ByReference(_, hir::MutMutable) => {
981 ty::ExplicitSelfCategory::ByReference(_, hir::MutImmutable) => "&self",
982 ty::ExplicitSelfCategory::ByBox => "Box<self>",
987 impl fmt::Display for ty::ParamTy {
988 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
989 write!(f, "{}", self.name)
993 impl fmt::Debug for ty::ParamTy {
994 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
995 write!(f, "{}/{:?}.{}", self, self.space, self.idx)
999 impl<'tcx, T, U> fmt::Display for ty::OutlivesPredicate<T,U>
1000 where T: fmt::Display, U: fmt::Display
1002 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1003 write!(f, "{} : {}", self.0, self.1)
1007 impl<'tcx> fmt::Display for ty::EquatePredicate<'tcx> {
1008 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1009 write!(f, "{} == {}", self.0, self.1)
1013 impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
1014 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1015 write!(f, "TraitPredicate({:?})",
1020 impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> {
1021 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1022 write!(f, "{} : {}",
1023 self.trait_ref.self_ty(),
1028 impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
1029 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1030 write!(f, "ProjectionPredicate({:?}, {:?})",
1036 impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> {
1037 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1038 write!(f, "{} == {}",
1044 impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> {
1045 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1046 write!(f, "{:?}::{}",
1052 impl<'tcx> fmt::Display for ty::Predicate<'tcx> {
1053 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1055 ty::Predicate::Trait(ref data) => write!(f, "{}", data),
1056 ty::Predicate::Equate(ref predicate) => write!(f, "{}", predicate),
1057 ty::Predicate::RegionOutlives(ref predicate) => write!(f, "{}", predicate),
1058 ty::Predicate::TypeOutlives(ref predicate) => write!(f, "{}", predicate),
1059 ty::Predicate::Projection(ref predicate) => write!(f, "{}", predicate),
1060 ty::Predicate::WellFormed(ty) => write!(f, "{} well-formed", ty),
1061 ty::Predicate::ObjectSafe(trait_def_id) =>
1062 ty::tls::with(|tcx| {
1063 write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id))