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, TyBareFn};
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, HasTypeFlags};
21 use middle::ty::fold::TypeFoldable;
25 use syntax::parse::token;
26 use syntax::ast::CRATE_NODE_ID;
29 pub fn verbose() -> bool {
30 ty::tls::with(|tcx| tcx.sess.verbose())
33 fn fn_sig(f: &mut fmt::Formatter,
39 let mut inputs = inputs.iter();
40 if let Some(&ty) = inputs.next() {
41 try!(write!(f, "{}", ty));
43 try!(write!(f, ", {}", ty));
46 try!(write!(f, ", ..."));
52 ty::FnConverging(ty) => {
54 try!(write!(f, " -> {}", ty));
64 fn parameterized<GG>(f: &mut fmt::Formatter,
65 substs: &subst::Substs,
67 projections: &[ty::ProjectionPredicate],
70 where GG: for<'tcx> FnOnce(&ty::ctxt<'tcx>) -> ty::Generics<'tcx>
72 let (fn_trait_kind, verbose) = try!(ty::tls::with(|tcx| {
73 try!(write!(f, "{}", tcx.item_path_str(did)));
74 Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose()))
78 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
81 write!(f, "{}", start)
88 match substs.regions {
89 subst::ErasedRegions => {
90 try!(start_or_continue(f, "<", ", "));
91 try!(write!(f, ".."));
93 subst::NonerasedRegions(ref regions) => {
94 for region in regions {
95 try!(start_or_continue(f, "<", ", "));
96 try!(write!(f, "{:?}", region));
100 for &ty in &substs.types {
101 try!(start_or_continue(f, "<", ", "));
102 try!(write!(f, "{}", ty));
104 for projection in projections {
105 try!(start_or_continue(f, "<", ", "));
106 try!(write!(f, "{}={}",
107 projection.projection_ty.item_name,
110 return start_or_continue(f, "", ">");
113 if fn_trait_kind.is_some() && projections.len() == 1 {
114 let projection_ty = projections[0].ty;
115 if let TyTuple(ref args) = substs.types.get_slice(subst::TypeSpace)[0].sty {
116 return fn_sig(f, args, false, ty::FnConverging(projection_ty));
120 match substs.regions {
121 subst::ErasedRegions => { }
122 subst::NonerasedRegions(ref regions) => {
124 try!(start_or_continue(f, "<", ", "));
125 let s = r.to_string();
127 // This happens when the value of the region
128 // parameter is not easily serialized. This may be
129 // because the user omitted it in the first place,
130 // or because it refers to some block in the code,
131 // etc. I'm not sure how best to serialize this.
132 try!(write!(f, "'_"));
134 try!(write!(f, "{}", s));
140 // It is important to execute this conditionally, only if -Z
141 // verbose is false. Otherwise, debug logs can sometimes cause
142 // ICEs trying to fetch the generics early in the pipeline. This
143 // is kind of a hacky workaround in that -Z verbose is required to
145 let tps = substs.types.get_slice(subst::TypeSpace);
146 let num_defaults = ty::tls::with(|tcx| {
147 let generics = get_generics(tcx);
149 let has_self = substs.self_ty().is_some();
150 let ty_params = generics.types.get_slice(subst::TypeSpace);
151 if ty_params.last().map_or(false, |def| def.default.is_some()) {
152 let substs = tcx.lift(&substs);
153 ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
156 if !has_self && default.has_self_ty() {
157 // In an object type, there is no `Self`, and
158 // thus if the default value references Self,
159 // the user will be required to give an
160 // explicit value. We can't even do the
161 // substitution below to check without causing
165 let default = tcx.lift(&default);
166 substs.and_then(|substs| default.subst(tcx, substs)) == Some(actual)
177 for &ty in &tps[..tps.len() - num_defaults] {
178 try!(start_or_continue(f, "<", ", "));
179 try!(write!(f, "{}", ty));
182 for projection in projections {
183 try!(start_or_continue(f, "<", ", "));
184 try!(write!(f, "{}={}",
185 projection.projection_ty.item_name,
189 start_or_continue(f, "", ">")
192 fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
193 tcx: &ty::ctxt<'tcx>,
194 original: &ty::Binder<T>,
195 lifted: Option<ty::Binder<U>>) -> fmt::Result
196 where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx>
198 // Replace any anonymous late-bound regions with named
199 // variants, using gensym'd identifiers, so that we can
200 // clearly differentiate between named and unnamed regions in
201 // the output. We'll probably want to tweak this over time to
202 // decide just how much information to give.
203 let value = if let Some(v) = lifted {
206 return write!(f, "{}", original.0);
209 let mut empty = true;
210 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
213 write!(f, "{}", start)
215 write!(f, "{}", cont)
219 let new_value = tcx.replace_late_bound_regions(&value, |br| {
220 let _ = start_or_continue(f, "for<", ", ");
221 ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
222 ty::BrNamed(_, name) => {
223 let _ = write!(f, "{}", name);
229 let name = token::intern("'r");
230 let _ = write!(f, "{}", name);
231 ty::BrNamed(tcx.map.local_def_id(CRATE_NODE_ID), name)
236 try!(start_or_continue(f, "", "> "));
237 write!(f, "{}", new_value)
240 /// This curious type is here to help pretty-print trait objects. In
241 /// a trait object, the projections are stored separately from the
242 /// main trait bound, but in fact we want to package them together
243 /// when printing out; they also have separate binders, but we want
244 /// them to share a binder when we print them out. (And the binder
245 /// pretty-printing logic is kind of clever and we don't want to
246 /// reproduce it.) So we just repackage up the structure somewhat.
248 /// Right now there is only one trait in an object that can have
249 /// projection bounds, so we just stuff them altogether. But in
250 /// reality we should eventually sort things out better.
251 #[derive(Clone, Debug)]
252 struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>, Vec<ty::ProjectionPredicate<'tcx>>);
254 impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> {
255 fn fold_with<F:ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F)
256 -> TraitAndProjections<'tcx> {
257 TraitAndProjections(self.0.fold_with(folder), self.1.fold_with(folder))
261 impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
262 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
263 let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
264 parameterized(f, trait_ref.substs,
267 |tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone())
271 impl<'tcx> fmt::Display for ty::TraitTy<'tcx> {
272 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
273 let bounds = &self.bounds;
275 // Generate the main trait ref, including associated types.
276 try!(ty::tls::with(|tcx| {
277 let principal = tcx.lift(&self.principal.0)
278 .expect("could not lift TraitRef for printing");
279 let projections = tcx.lift(&bounds.projection_bounds[..])
280 .expect("could not lift projections for printing");
281 let projections = projections.into_iter().map(|p| p.0).collect();
283 let tap = ty::Binder(TraitAndProjections(principal, projections));
284 in_binder(f, tcx, &ty::Binder(""), Some(tap))
288 for bound in &bounds.builtin_bounds {
289 try!(write!(f, " + {:?}", bound));
292 // FIXME: It'd be nice to compute from context when this bound
293 // is implied, but that's non-trivial -- we'd perhaps have to
294 // use thread-local data of some kind? There are also
295 // advantages to just showing the region, since it makes
296 // people aware that it's there.
297 let bound = bounds.region_bound.to_string();
298 if !bound.is_empty() {
299 try!(write!(f, " + {}", bound));
306 impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
307 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
308 write!(f, "TypeParameterDef({}, {:?}, {:?}/{})",
311 self.space, self.index)
315 impl fmt::Debug for ty::RegionParameterDef {
316 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
317 write!(f, "RegionParameterDef({}, {:?}, {:?}/{}, {:?})",
320 self.space, self.index,
325 impl<'tcx> fmt::Debug for ty::TyS<'tcx> {
326 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
327 write!(f, "{}", *self)
331 impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
332 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
334 if self.mutbl == hir::MutMutable { "mut " } else { "" },
339 impl<'tcx> fmt::Debug for subst::Substs<'tcx> {
340 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
341 write!(f, "Substs[types={:?}, regions={:?}]",
342 self.types, self.regions)
346 impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
347 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
348 write!(f, "ItemSubsts({:?})", self.substs)
352 impl fmt::Debug for subst::RegionSubsts {
353 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
355 subst::ErasedRegions => write!(f, "erased"),
356 subst::NonerasedRegions(ref regions) => write!(f, "{:?}", regions)
361 impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
362 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
363 // when printing out the debug representation, we don't need
364 // to enumerate the `for<...>` etc because the debruijn index
365 // tells you everything you need to know.
366 match self.substs.self_ty() {
367 None => write!(f, "{}", *self),
368 Some(self_ty) => write!(f, "<{:?} as {}>", self_ty, *self)
373 impl<'tcx> fmt::Debug for ty::TraitDef<'tcx> {
374 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
375 write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
376 self.generics, self.trait_ref)
380 impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> {
381 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
382 ty::tls::with(|tcx| {
383 write!(f, "{}", tcx.item_path_str(self.did))
388 impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> {
389 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
391 ty::adjustment::AdjustReifyFnPointer => {
392 write!(f, "AdjustReifyFnPointer")
394 ty::adjustment::AdjustUnsafeFnPointer => {
395 write!(f, "AdjustUnsafeFnPointer")
397 ty::adjustment::AdjustDerefRef(ref data) => {
398 write!(f, "{:?}", data)
404 impl<'tcx> fmt::Debug for ty::adjustment::AutoDerefRef<'tcx> {
405 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
406 write!(f, "AutoDerefRef({}, unsize={:?}, {:?})",
407 self.autoderefs, self.unsize, self.autoref)
411 impl<'tcx> fmt::Debug for ty::TraitTy<'tcx> {
412 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
413 write!(f, "TraitTy({:?},{:?})",
419 impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
420 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
422 ty::Predicate::Trait(ref a) => write!(f, "{:?}", a),
423 ty::Predicate::Equate(ref pair) => write!(f, "{:?}", pair),
424 ty::Predicate::RegionOutlives(ref pair) => write!(f, "{:?}", pair),
425 ty::Predicate::TypeOutlives(ref pair) => write!(f, "{:?}", pair),
426 ty::Predicate::Projection(ref pair) => write!(f, "{:?}", pair),
427 ty::Predicate::WellFormed(ty) => write!(f, "WF({:?})", ty),
428 ty::Predicate::ObjectSafe(trait_def_id) => {
429 write!(f, "ObjectSafe({:?})", trait_def_id)
435 impl fmt::Display for ty::BoundRegion {
436 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
438 return write!(f, "{:?}", *self);
442 BrNamed(_, name) => write!(f, "{}", name),
443 BrAnon(_) | BrFresh(_) | BrEnv => Ok(())
448 impl fmt::Debug for ty::BoundRegion {
449 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
451 BrAnon(n) => write!(f, "BrAnon({:?})", n),
452 BrFresh(n) => write!(f, "BrFresh({:?})", n),
453 BrNamed(did, name) => {
454 write!(f, "BrNamed({:?}, {:?})", did, name)
456 BrEnv => "BrEnv".fmt(f),
461 impl fmt::Debug for ty::Region {
462 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
464 ty::ReEarlyBound(ref data) => {
465 write!(f, "ReEarlyBound({:?}, {:?}, {}, {})",
472 ty::ReLateBound(binder_id, ref bound_region) => {
473 write!(f, "ReLateBound({:?}, {:?})",
478 ty::ReFree(ref fr) => write!(f, "{:?}", fr),
481 write!(f, "ReScope({:?})", id)
484 ty::ReStatic => write!(f, "ReStatic"),
486 ty::ReVar(ref vid) => {
487 write!(f, "{:?}", vid)
490 ty::ReSkolemized(id, ref bound_region) => {
491 write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
494 ty::ReEmpty => write!(f, "ReEmpty")
499 impl<'tcx> fmt::Debug for ty::ClosureTy<'tcx> {
500 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
501 write!(f, "ClosureTy({},{:?},{})",
508 impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
509 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
510 write!(f, "ClosureUpvar({:?},{:?})",
516 impl<'a, 'tcx> fmt::Debug for ty::ParameterEnvironment<'a, 'tcx> {
517 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
518 write!(f, "ParameterEnvironment(\
520 implicit_region_bound={:?}, \
521 caller_bounds={:?})",
523 self.implicit_region_bound,
528 impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault {
529 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
531 ty::ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
532 ty::ObjectLifetimeDefault::BaseDefault => write!(f, "BaseDefault"),
533 ty::ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
538 impl fmt::Display for ty::Region {
539 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
541 return write!(f, "{:?}", *self);
544 // These printouts are concise. They do not contain all the information
545 // the user might want to diagnose an error, but there is basically no way
546 // to fit that into a short string. Hence the recommendation to use
547 // `explain_region()` or `note_and_explain_region()`.
549 ty::ReEarlyBound(ref data) => {
550 write!(f, "{}", data.name)
552 ty::ReLateBound(_, br) |
553 ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
554 ty::ReSkolemized(_, br) => {
558 ty::ReVar(_) => Ok(()),
559 ty::ReStatic => write!(f, "'static"),
560 ty::ReEmpty => write!(f, "'<empty>"),
565 impl fmt::Debug for ty::FreeRegion {
566 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
567 write!(f, "ReFree({:?}, {:?})",
568 self.scope, self.bound_region)
572 impl fmt::Debug for ty::Variance {
573 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
574 f.write_str(match *self {
575 ty::Covariant => "+",
576 ty::Contravariant => "-",
577 ty::Invariant => "o",
578 ty::Bivariant => "*",
583 impl fmt::Debug for ty::ItemVariances {
584 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
585 write!(f, "ItemVariances(types={:?}, regions={:?})",
586 self.types, self.regions)
590 impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> {
591 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
592 write!(f, "GenericPredicates({:?})", self.predicates)
596 impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
597 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
598 write!(f, "InstantiatedPredicates({:?})",
603 impl<'tcx> fmt::Debug for ty::ImplOrTraitItem<'tcx> {
604 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
605 try!(write!(f, "ImplOrTraitItem("));
607 ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i),
608 ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i),
609 ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i),
615 impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
616 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
617 try!(write!(f, "fn"));
618 fn_sig(f, &self.inputs, self.variadic, self.output)
622 impl<'tcx> fmt::Debug for ty::ExistentialBounds<'tcx> {
623 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
624 let mut empty = true;
625 let mut maybe_continue = |f: &mut fmt::Formatter| {
634 let region_str = format!("{:?}", self.region_bound);
635 if !region_str.is_empty() {
636 try!(maybe_continue(f));
637 try!(write!(f, "{}", region_str));
640 for bound in &self.builtin_bounds {
641 try!(maybe_continue(f));
642 try!(write!(f, "{:?}", bound));
645 for projection_bound in &self.projection_bounds {
646 try!(maybe_continue(f));
647 try!(write!(f, "{:?}", projection_bound));
654 impl fmt::Display for ty::BuiltinBounds {
655 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
656 let mut bounds = self.iter();
657 if let Some(bound) = bounds.next() {
658 try!(write!(f, "{:?}", bound));
659 for bound in bounds {
660 try!(write!(f, " + {:?}", bound));
667 impl fmt::Debug for ty::TyVid {
668 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
669 write!(f, "_#{}t", self.index)
673 impl fmt::Debug for ty::IntVid {
674 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
675 write!(f, "_#{}i", self.index)
679 impl fmt::Debug for ty::FloatVid {
680 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
681 write!(f, "_#{}f", self.index)
685 impl fmt::Debug for ty::RegionVid {
686 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
687 write!(f, "'_#{}r", self.index)
691 impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
692 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
693 write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
697 impl fmt::Debug for ty::InferTy {
698 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
700 ty::TyVar(ref v) => v.fmt(f),
701 ty::IntVar(ref v) => v.fmt(f),
702 ty::FloatVar(ref v) => v.fmt(f),
703 ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
704 ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
705 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
710 impl fmt::Debug for ty::IntVarValue {
711 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
713 ty::IntType(ref v) => v.fmt(f),
714 ty::UintType(ref v) => v.fmt(f),
719 // The generic impl doesn't work yet because projections are not
720 // normalized under HRTB.
721 /*impl<T> fmt::Display for ty::Binder<T>
722 where T: fmt::Display + for<'a> ty::Lift<'a>,
723 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
725 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
726 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
730 impl<'tcx> fmt::Display for ty::Binder<ty::TraitRef<'tcx>> {
731 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
732 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
736 impl<'tcx> fmt::Display for ty::Binder<ty::TraitPredicate<'tcx>> {
737 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
738 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
742 impl<'tcx> fmt::Display for ty::Binder<ty::EquatePredicate<'tcx>> {
743 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
744 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
748 impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
749 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
750 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
754 impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region>> {
755 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
756 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
760 impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>> {
761 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
762 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
766 impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
767 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
768 parameterized(f, self.substs, self.def_id, &[],
769 |tcx| tcx.lookup_trait_def(self.def_id).generics.clone())
773 impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
774 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
776 TyBool => write!(f, "bool"),
777 TyChar => write!(f, "char"),
778 TyInt(t) => write!(f, "{}", t.ty_to_string()),
779 TyUint(t) => write!(f, "{}", t.ty_to_string()),
780 TyFloat(t) => write!(f, "{}", t.ty_to_string()),
781 TyBox(typ) => write!(f, "Box<{}>", typ),
782 TyRawPtr(ref tm) => {
783 write!(f, "*{} {}", match tm.mutbl {
784 hir::MutMutable => "mut",
785 hir::MutImmutable => "const",
788 TyRef(r, ref tm) => {
789 try!(write!(f, "&"));
790 let s = r.to_string();
791 try!(write!(f, "{}", s));
793 try!(write!(f, " "));
797 TyTuple(ref tys) => {
798 try!(write!(f, "("));
799 let mut tys = tys.iter();
800 if let Some(&ty) = tys.next() {
801 try!(write!(f, "{},", ty));
802 if let Some(&ty) = tys.next() {
803 try!(write!(f, " {}", ty));
805 try!(write!(f, ", {}", ty));
811 TyBareFn(opt_def_id, ref bare_fn) => {
812 if bare_fn.unsafety == hir::Unsafety::Unsafe {
813 try!(write!(f, "unsafe "));
816 if bare_fn.abi != abi::Rust {
817 try!(write!(f, "extern {} ", bare_fn.abi));
820 try!(write!(f, "{}", bare_fn.sig.0));
822 if let Some(def_id) = opt_def_id {
823 try!(write!(f, " {{{}}}", ty::tls::with(|tcx| {
824 tcx.item_path_str(def_id)
829 TyInfer(infer_ty) => write!(f, "{}", infer_ty),
830 TyError => write!(f, "[type error]"),
831 TyParam(ref param_ty) => write!(f, "{}", param_ty),
832 TyEnum(def, substs) | TyStruct(def, substs) => {
833 ty::tls::with(|tcx| {
834 if def.did.is_local() &&
835 !tcx.tcache.borrow().contains_key(&def.did) {
836 write!(f, "{}<..>", tcx.item_path_str(def.did))
838 parameterized(f, substs, def.did, &[],
839 |tcx| tcx.lookup_item_type(def.did).generics)
843 TyTrait(ref data) => write!(f, "{}", data),
844 ty::TyProjection(ref data) => write!(f, "{}", data),
845 TyStr => write!(f, "str"),
846 TyClosure(did, ref substs) => ty::tls::with(|tcx| {
847 try!(write!(f, "[closure"));
849 if let Some(node_id) = tcx.map.as_local_node_id(did) {
850 try!(write!(f, "@{:?}", tcx.map.span(node_id)));
852 try!(tcx.with_freevars(node_id, |freevars| {
853 for (freevar, upvar_ty) in freevars.iter().zip(&substs.upvar_tys) {
854 let node_id = freevar.def.var_id();
858 tcx.local_var_name_str(node_id),
865 // cross-crate closure types should only be
866 // visible in trans bug reports, I imagine.
867 try!(write!(f, "@{:?}", did));
869 for (index, upvar_ty) in substs.upvar_tys.iter().enumerate() {
870 try!(write!(f, "{}{}:{}", sep, index, upvar_ty));
877 TyArray(ty, sz) => write!(f, "[{}; {}]", ty, sz),
878 TySlice(ty) => write!(f, "[{}]", ty)
883 impl<'tcx> fmt::Display for ty::TyS<'tcx> {
884 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
885 write!(f, "{}", self.sty)
889 impl fmt::Debug for ty::UpvarId {
890 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
891 write!(f, "UpvarId({};`{}`;{})",
893 ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)),
894 self.closure_expr_id)
898 impl fmt::Debug for ty::UpvarBorrow {
899 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
900 write!(f, "UpvarBorrow({:?}, {:?})",
901 self.kind, self.region)
905 impl fmt::Display for ty::InferTy {
906 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
907 let print_var_ids = verbose();
909 ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
910 ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
911 ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
912 ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => write!(f, "_"),
913 ty::FreshTy(v) => write!(f, "FreshTy({})", v),
914 ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
915 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
920 impl fmt::Display for ty::ExplicitSelfCategory {
921 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
922 f.write_str(match *self {
923 ty::StaticExplicitSelfCategory => "static",
924 ty::ByValueExplicitSelfCategory => "self",
925 ty::ByReferenceExplicitSelfCategory(_, hir::MutMutable) => {
928 ty::ByReferenceExplicitSelfCategory(_, hir::MutImmutable) => "&self",
929 ty::ByBoxExplicitSelfCategory => "Box<self>",
934 impl fmt::Display for ty::ParamTy {
935 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
936 write!(f, "{}", self.name)
940 impl fmt::Debug for ty::ParamTy {
941 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
942 write!(f, "{}/{:?}.{}", self, self.space, self.idx)
946 impl<'tcx, T, U> fmt::Display for ty::OutlivesPredicate<T,U>
947 where T: fmt::Display, U: fmt::Display
949 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
950 write!(f, "{} : {}", self.0, self.1)
954 impl<'tcx> fmt::Display for ty::EquatePredicate<'tcx> {
955 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
956 write!(f, "{} == {}", self.0, self.1)
960 impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
961 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
962 write!(f, "TraitPredicate({:?})",
967 impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> {
968 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
970 self.trait_ref.self_ty(),
975 impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
976 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
977 write!(f, "ProjectionPredicate({:?}, {:?})",
983 impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> {
984 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
985 write!(f, "{} == {}",
991 impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> {
992 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
993 write!(f, "{:?}::{}",
999 impl<'tcx> fmt::Display for ty::Predicate<'tcx> {
1000 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1002 ty::Predicate::Trait(ref data) => write!(f, "{}", data),
1003 ty::Predicate::Equate(ref predicate) => write!(f, "{}", predicate),
1004 ty::Predicate::RegionOutlives(ref predicate) => write!(f, "{}", predicate),
1005 ty::Predicate::TypeOutlives(ref predicate) => write!(f, "{}", predicate),
1006 ty::Predicate::Projection(ref predicate) => write!(f, "{}", predicate),
1007 ty::Predicate::WellFormed(ty) => write!(f, "{} well-formed", ty),
1008 ty::Predicate::ObjectSafe(trait_def_id) =>
1009 ty::tls::with(|tcx| {
1010 write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id))