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::{BoundRegion, BrAnon, BrNamed};
15 use middle::ty::{ReEarlyBound, BrFresh, ctxt};
16 use middle::ty::{ReFree, ReScope, ReStatic, Region, ReEmpty};
17 use middle::ty::{ReSkolemized, ReVar, BrEnv};
18 use middle::ty::{TyBool, TyChar, TyStruct, TyEnum};
19 use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyBareFn};
20 use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple};
21 use middle::ty::TyClosure;
22 use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
23 use middle::ty::{self, TypeAndMut, Ty, HasTypeFlags};
24 use middle::ty::fold::TypeFoldable;
29 use syntax::parse::token;
30 use syntax::ast::CRATE_NODE_ID;
33 pub fn verbose() -> bool {
34 ty::tls::with(|tcx| tcx.sess.verbose())
37 fn fn_sig(f: &mut fmt::Formatter,
43 let mut inputs = inputs.iter();
44 if let Some(&ty) = inputs.next() {
45 try!(write!(f, "{}", ty));
47 try!(write!(f, ", {}", ty));
50 try!(write!(f, ", ..."));
56 ty::FnConverging(ty) => {
58 try!(write!(f, " -> {}", ty));
68 fn parameterized<GG>(f: &mut fmt::Formatter,
69 substs: &subst::Substs,
71 projections: &[ty::ProjectionPredicate],
74 where GG: for<'tcx> FnOnce(&ty::ctxt<'tcx>) -> ty::Generics<'tcx>
76 let (fn_trait_kind, verbose) = try!(ty::tls::with(|tcx| {
77 try!(write!(f, "{}", tcx.item_path_str(did)));
78 Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose()))
82 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
85 write!(f, "{}", start)
92 match substs.regions {
93 subst::ErasedRegions => {
94 try!(start_or_continue(f, "<", ", "));
95 try!(write!(f, ".."));
97 subst::NonerasedRegions(ref regions) => {
98 for region in regions {
99 try!(start_or_continue(f, "<", ", "));
100 try!(write!(f, "{:?}", region));
104 for &ty in &substs.types {
105 try!(start_or_continue(f, "<", ", "));
106 try!(write!(f, "{}", ty));
108 for projection in projections {
109 try!(start_or_continue(f, "<", ", "));
110 try!(write!(f, "{}={}",
111 projection.projection_ty.item_name,
114 return start_or_continue(f, "", ">");
117 if fn_trait_kind.is_some() && projections.len() == 1 {
118 let projection_ty = projections[0].ty;
119 if let TyTuple(ref args) = substs.types.get_slice(subst::TypeSpace)[0].sty {
120 return fn_sig(f, args, false, ty::FnConverging(projection_ty));
124 match substs.regions {
125 subst::ErasedRegions => { }
126 subst::NonerasedRegions(ref regions) => {
128 try!(start_or_continue(f, "<", ", "));
129 let s = r.to_string();
131 // This happens when the value of the region
132 // parameter is not easily serialized. This may be
133 // because the user omitted it in the first place,
134 // or because it refers to some block in the code,
135 // etc. I'm not sure how best to serialize this.
136 try!(write!(f, "'_"));
138 try!(write!(f, "{}", s));
144 // It is important to execute this conditionally, only if -Z
145 // verbose is false. Otherwise, debug logs can sometimes cause
146 // ICEs trying to fetch the generics early in the pipeline. This
147 // is kind of a hacky workaround in that -Z verbose is required to
149 let tps = substs.types.get_slice(subst::TypeSpace);
150 let num_defaults = ty::tls::with(|tcx| {
151 let generics = get_generics(tcx);
153 let has_self = substs.self_ty().is_some();
154 let ty_params = generics.types.get_slice(subst::TypeSpace);
155 if ty_params.last().map_or(false, |def| def.default.is_some()) {
156 let substs = tcx.lift(&substs);
157 ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
160 if !has_self && default.has_self_ty() {
161 // In an object type, there is no `Self`, and
162 // thus if the default value references Self,
163 // the user will be required to give an
164 // explicit value. We can't even do the
165 // substitution below to check without causing
169 let default = tcx.lift(&default);
170 substs.and_then(|substs| default.subst(tcx, substs)) == Some(actual)
181 for &ty in &tps[..tps.len() - num_defaults] {
182 try!(start_or_continue(f, "<", ", "));
183 try!(write!(f, "{}", ty));
186 for projection in projections {
187 try!(start_or_continue(f, "<", ", "));
188 try!(write!(f, "{}={}",
189 projection.projection_ty.item_name,
193 start_or_continue(f, "", ">")
196 fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
197 tcx: &ty::ctxt<'tcx>,
198 original: &ty::Binder<T>,
199 lifted: Option<ty::Binder<U>>) -> fmt::Result
200 where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx>
202 // Replace any anonymous late-bound regions with named
203 // variants, using gensym'd identifiers, so that we can
204 // clearly differentiate between named and unnamed regions in
205 // the output. We'll probably want to tweak this over time to
206 // decide just how much information to give.
207 let value = if let Some(v) = lifted {
210 return write!(f, "{}", original.0);
213 let mut empty = true;
214 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
217 write!(f, "{}", start)
219 write!(f, "{}", cont)
223 let new_value = tcx.replace_late_bound_regions(&value, |br| {
224 let _ = start_or_continue(f, "for<", ", ");
225 ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
226 ty::BrNamed(_, name) => {
227 let _ = write!(f, "{}", name);
233 let name = token::intern("'r");
234 let _ = write!(f, "{}", name);
235 ty::BrNamed(tcx.map.local_def_id(CRATE_NODE_ID), name)
240 try!(start_or_continue(f, "", "> "));
241 write!(f, "{}", new_value)
244 /// This curious type is here to help pretty-print trait objects. In
245 /// a trait object, the projections are stored separately from the
246 /// main trait bound, but in fact we want to package them together
247 /// when printing out; they also have separate binders, but we want
248 /// them to share a binder when we print them out. (And the binder
249 /// pretty-printing logic is kind of clever and we don't want to
250 /// reproduce it.) So we just repackage up the structure somewhat.
252 /// Right now there is only one trait in an object that can have
253 /// projection bounds, so we just stuff them altogether. But in
254 /// reality we should eventually sort things out better.
255 #[derive(Clone, Debug)]
256 struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>, Vec<ty::ProjectionPredicate<'tcx>>);
258 impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> {
259 fn fold_with<F:ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F)
260 -> TraitAndProjections<'tcx> {
261 TraitAndProjections(self.0.fold_with(folder), self.1.fold_with(folder))
265 impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
266 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
267 let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
268 parameterized(f, trait_ref.substs,
271 |tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone())
275 impl<'tcx> fmt::Display for ty::TraitTy<'tcx> {
276 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
277 let bounds = &self.bounds;
279 // Generate the main trait ref, including associated types.
280 try!(ty::tls::with(|tcx| {
281 let principal = tcx.lift(&self.principal.0)
282 .expect("could not lift TraitRef for printing");
283 let projections = tcx.lift(&bounds.projection_bounds[..])
284 .expect("could not lift projections for printing");
285 let projections = projections.into_iter().map(|p| p.0).collect();
287 let tap = ty::Binder(TraitAndProjections(principal, projections));
288 in_binder(f, tcx, &ty::Binder(""), Some(tap))
292 for bound in &bounds.builtin_bounds {
293 try!(write!(f, " + {:?}", bound));
296 // FIXME: It'd be nice to compute from context when this bound
297 // is implied, but that's non-trivial -- we'd perhaps have to
298 // use thread-local data of some kind? There are also
299 // advantages to just showing the region, since it makes
300 // people aware that it's there.
301 let bound = bounds.region_bound.to_string();
302 if !bound.is_empty() {
303 try!(write!(f, " + {}", bound));
310 impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
311 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
312 write!(f, "TypeParameterDef({}, {:?}, {:?}/{})",
315 self.space, self.index)
319 impl fmt::Debug for ty::RegionParameterDef {
320 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
321 write!(f, "RegionParameterDef({}, {:?}, {:?}/{}, {:?})",
324 self.space, self.index,
329 impl<'tcx> fmt::Debug for ty::TyS<'tcx> {
330 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
331 write!(f, "{}", *self)
335 impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
336 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
338 if self.mutbl == hir::MutMutable { "mut " } else { "" },
343 impl<'tcx> fmt::Debug for subst::Substs<'tcx> {
344 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
345 write!(f, "Substs[types={:?}, regions={:?}]",
346 self.types, self.regions)
350 impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
351 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
352 write!(f, "ItemSubsts({:?})", self.substs)
356 impl fmt::Debug for subst::RegionSubsts {
357 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
359 subst::ErasedRegions => write!(f, "erased"),
360 subst::NonerasedRegions(ref regions) => write!(f, "{:?}", regions)
365 impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
366 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
367 // when printing out the debug representation, we don't need
368 // to enumerate the `for<...>` etc because the debruijn index
369 // tells you everything you need to know.
370 match self.substs.self_ty() {
371 None => write!(f, "{}", *self),
372 Some(self_ty) => write!(f, "<{:?} as {}>", self_ty, *self)
377 impl<'tcx> fmt::Debug for ty::TraitDef<'tcx> {
378 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
379 write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
380 self.generics, self.trait_ref)
384 impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> {
385 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
386 ty::tls::with(|tcx| {
387 write!(f, "{}", tcx.item_path_str(self.did))
392 impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> {
393 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
395 ty::adjustment::AdjustReifyFnPointer => {
396 write!(f, "AdjustReifyFnPointer")
398 ty::adjustment::AdjustUnsafeFnPointer => {
399 write!(f, "AdjustUnsafeFnPointer")
401 ty::adjustment::AdjustDerefRef(ref data) => {
402 write!(f, "{:?}", data)
408 impl<'tcx> fmt::Debug for ty::adjustment::AutoDerefRef<'tcx> {
409 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
410 write!(f, "AutoDerefRef({}, unsize={:?}, {:?})",
411 self.autoderefs, self.unsize, self.autoref)
415 impl<'tcx> fmt::Debug for ty::TraitTy<'tcx> {
416 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
417 write!(f, "TraitTy({:?},{:?})",
423 impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
424 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
426 ty::Predicate::Trait(ref a) => write!(f, "{:?}", a),
427 ty::Predicate::Equate(ref pair) => write!(f, "{:?}", pair),
428 ty::Predicate::RegionOutlives(ref pair) => write!(f, "{:?}", pair),
429 ty::Predicate::TypeOutlives(ref pair) => write!(f, "{:?}", pair),
430 ty::Predicate::Projection(ref pair) => write!(f, "{:?}", pair),
431 ty::Predicate::WellFormed(ty) => write!(f, "WF({:?})", ty),
432 ty::Predicate::ObjectSafe(trait_def_id) => {
433 write!(f, "ObjectSafe({:?})", trait_def_id)
439 impl fmt::Display for ty::BoundRegion {
440 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
442 return write!(f, "{:?}", *self);
446 BrNamed(_, name) => write!(f, "{}", name),
447 BrAnon(_) | BrFresh(_) | BrEnv => Ok(())
452 impl fmt::Debug for ty::BoundRegion {
453 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
455 BrAnon(n) => write!(f, "BrAnon({:?})", n),
456 BrFresh(n) => write!(f, "BrFresh({:?})", n),
457 BrNamed(did, name) => {
458 write!(f, "BrNamed({:?}, {:?})", did, name)
460 BrEnv => "BrEnv".fmt(f),
465 impl fmt::Debug for ty::Region {
466 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
468 ty::ReEarlyBound(ref data) => {
469 write!(f, "ReEarlyBound({:?}, {:?}, {}, {})",
476 ty::ReLateBound(binder_id, ref bound_region) => {
477 write!(f, "ReLateBound({:?}, {:?})",
482 ty::ReFree(ref fr) => write!(f, "{:?}", fr),
485 write!(f, "ReScope({:?})", id)
488 ty::ReStatic => write!(f, "ReStatic"),
490 ty::ReVar(ref vid) => {
491 write!(f, "{:?}", vid)
494 ty::ReSkolemized(id, ref bound_region) => {
495 write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
498 ty::ReEmpty => write!(f, "ReEmpty")
503 impl<'tcx> fmt::Debug for ty::ClosureTy<'tcx> {
504 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
505 write!(f, "ClosureTy({},{:?},{})",
512 impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
513 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
514 write!(f, "ClosureUpvar({:?},{:?})",
520 impl<'a, 'tcx> fmt::Debug for ty::ParameterEnvironment<'a, 'tcx> {
521 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
522 write!(f, "ParameterEnvironment(\
524 implicit_region_bound={:?}, \
525 caller_bounds={:?})",
527 self.implicit_region_bound,
532 impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault {
533 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
535 ty::ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
536 ty::ObjectLifetimeDefault::BaseDefault => write!(f, "BaseDefault"),
537 ty::ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
542 impl fmt::Display for ty::Region {
543 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
545 return write!(f, "{:?}", *self);
548 // These printouts are concise. They do not contain all the information
549 // the user might want to diagnose an error, but there is basically no way
550 // to fit that into a short string. Hence the recommendation to use
551 // `explain_region()` or `note_and_explain_region()`.
553 ty::ReEarlyBound(ref data) => {
554 write!(f, "{}", data.name)
556 ty::ReLateBound(_, br) |
557 ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
558 ty::ReSkolemized(_, br) => {
562 ty::ReVar(_) => Ok(()),
563 ty::ReStatic => write!(f, "'static"),
564 ty::ReEmpty => write!(f, "'<empty>"),
569 impl fmt::Debug for ty::FreeRegion {
570 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
571 write!(f, "ReFree({:?}, {:?})",
572 self.scope, self.bound_region)
576 impl fmt::Debug for ty::Variance {
577 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
578 f.write_str(match *self {
579 ty::Covariant => "+",
580 ty::Contravariant => "-",
581 ty::Invariant => "o",
582 ty::Bivariant => "*",
587 impl fmt::Debug for ty::ItemVariances {
588 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
589 write!(f, "ItemVariances(types={:?}, regions={:?})",
590 self.types, self.regions)
594 impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> {
595 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
596 write!(f, "GenericPredicates({:?})", self.predicates)
600 impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
601 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
602 write!(f, "InstantiatedPredicates({:?})",
607 impl<'tcx> fmt::Debug for ty::ImplOrTraitItem<'tcx> {
608 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
609 try!(write!(f, "ImplOrTraitItem("));
611 ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i),
612 ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i),
613 ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i),
619 impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
620 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
621 try!(write!(f, "fn"));
622 fn_sig(f, &self.inputs, self.variadic, self.output)
626 impl<'tcx> fmt::Debug for ty::ExistentialBounds<'tcx> {
627 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
628 let mut empty = true;
629 let mut maybe_continue = |f: &mut fmt::Formatter| {
638 let region_str = format!("{:?}", self.region_bound);
639 if !region_str.is_empty() {
640 try!(maybe_continue(f));
641 try!(write!(f, "{}", region_str));
644 for bound in &self.builtin_bounds {
645 try!(maybe_continue(f));
646 try!(write!(f, "{:?}", bound));
649 for projection_bound in &self.projection_bounds {
650 try!(maybe_continue(f));
651 try!(write!(f, "{:?}", projection_bound));
658 impl fmt::Display for ty::BuiltinBounds {
659 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
660 let mut bounds = self.iter();
661 if let Some(bound) = bounds.next() {
662 try!(write!(f, "{:?}", bound));
663 for bound in bounds {
664 try!(write!(f, " + {:?}", bound));
671 impl fmt::Debug for ty::TyVid {
672 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
673 write!(f, "_#{}t", self.index)
677 impl fmt::Debug for ty::IntVid {
678 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
679 write!(f, "_#{}i", self.index)
683 impl fmt::Debug for ty::FloatVid {
684 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
685 write!(f, "_#{}f", self.index)
689 impl fmt::Debug for ty::RegionVid {
690 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
691 write!(f, "'_#{}r", self.index)
695 impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
696 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
697 write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
701 impl fmt::Debug for ty::InferTy {
702 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
704 ty::TyVar(ref v) => v.fmt(f),
705 ty::IntVar(ref v) => v.fmt(f),
706 ty::FloatVar(ref v) => v.fmt(f),
707 ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
708 ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
709 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
714 impl fmt::Debug for ty::IntVarValue {
715 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
717 ty::IntType(ref v) => v.fmt(f),
718 ty::UintType(ref v) => v.fmt(f),
723 // The generic impl doesn't work yet because projections are not
724 // normalized under HRTB.
725 /*impl<T> fmt::Display for ty::Binder<T>
726 where T: fmt::Display + for<'a> ty::Lift<'a>,
727 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
729 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
730 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
734 impl<'tcx> fmt::Display for ty::Binder<ty::TraitRef<'tcx>> {
735 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
736 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
740 impl<'tcx> fmt::Display for ty::Binder<ty::TraitPredicate<'tcx>> {
741 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
742 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
746 impl<'tcx> fmt::Display for ty::Binder<ty::EquatePredicate<'tcx>> {
747 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
748 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
752 impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
753 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
754 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
758 impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region>> {
759 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
760 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
764 impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>> {
765 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
766 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
770 impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
771 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
772 parameterized(f, self.substs, self.def_id, &[],
773 |tcx| tcx.lookup_trait_def(self.def_id).generics.clone())
777 pub fn int_ty_to_string(t: ast::IntTy, val: Option<i64>) -> String {
779 ast::TyIs => "isize",
787 // cast to a u64 so we can correctly print INT64_MIN. All integral types
788 // are parsed as u64, so we wouldn't want to print an extra negative
790 Some(n) => format!("{}{}", n as u64, s),
791 None => s.to_string()
795 pub fn uint_ty_to_string(t: ast::UintTy, val: Option<u64>) -> String {
797 ast::TyUs => "usize",
805 Some(n) => format!("{}{}", n, s),
806 None => s.to_string()
811 pub fn float_ty_to_string(t: ast::FloatTy) -> String {
813 ast::TyF32 => "f32".to_string(),
814 ast::TyF64 => "f64".to_string(),
818 impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
819 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
821 TyBool => write!(f, "bool"),
822 TyChar => write!(f, "char"),
823 TyInt(t) => write!(f, "{}", int_ty_to_string(t, None)),
824 TyUint(t) => write!(f, "{}", uint_ty_to_string(t, None)),
825 TyFloat(t) => write!(f, "{}", float_ty_to_string(t)),
826 TyBox(typ) => write!(f, "Box<{}>", typ),
827 TyRawPtr(ref tm) => {
828 write!(f, "*{} {}", match tm.mutbl {
829 hir::MutMutable => "mut",
830 hir::MutImmutable => "const",
833 TyRef(r, ref tm) => {
834 try!(write!(f, "&"));
835 let s = r.to_string();
836 try!(write!(f, "{}", s));
838 try!(write!(f, " "));
842 TyTuple(ref tys) => {
843 try!(write!(f, "("));
844 let mut tys = tys.iter();
845 if let Some(&ty) = tys.next() {
846 try!(write!(f, "{},", ty));
847 if let Some(&ty) = tys.next() {
848 try!(write!(f, " {}", ty));
850 try!(write!(f, ", {}", ty));
856 TyBareFn(opt_def_id, ref bare_fn) => {
857 if bare_fn.unsafety == hir::Unsafety::Unsafe {
858 try!(write!(f, "unsafe "));
861 if bare_fn.abi != abi::Rust {
862 try!(write!(f, "extern {} ", bare_fn.abi));
865 try!(write!(f, "{}", bare_fn.sig.0));
867 if let Some(def_id) = opt_def_id {
868 try!(write!(f, " {{{}}}", ty::tls::with(|tcx| {
869 tcx.item_path_str(def_id)
874 TyInfer(infer_ty) => write!(f, "{}", infer_ty),
875 TyError => write!(f, "[type error]"),
876 TyParam(ref param_ty) => write!(f, "{}", param_ty),
877 TyEnum(def, substs) | TyStruct(def, substs) => {
878 ty::tls::with(|tcx| {
879 if def.did.is_local() &&
880 !tcx.tcache.borrow().contains_key(&def.did) {
881 write!(f, "{}<..>", tcx.item_path_str(def.did))
883 parameterized(f, substs, def.did, &[],
884 |tcx| tcx.lookup_item_type(def.did).generics)
888 TyTrait(ref data) => write!(f, "{}", data),
889 ty::TyProjection(ref data) => write!(f, "{}", data),
890 TyStr => write!(f, "str"),
891 TyClosure(did, ref substs) => ty::tls::with(|tcx| {
892 try!(write!(f, "[closure"));
894 if let Some(node_id) = tcx.map.as_local_node_id(did) {
895 try!(write!(f, "@{:?}", tcx.map.span(node_id)));
897 try!(tcx.with_freevars(node_id, |freevars| {
898 for (freevar, upvar_ty) in freevars.iter().zip(&substs.upvar_tys) {
899 let node_id = freevar.def.var_id();
903 tcx.local_var_name_str(node_id),
910 // cross-crate closure types should only be
911 // visible in trans bug reports, I imagine.
912 try!(write!(f, "@{:?}", did));
914 for (index, upvar_ty) in substs.upvar_tys.iter().enumerate() {
915 try!(write!(f, "{}{}:{}", sep, index, upvar_ty));
922 TyArray(ty, sz) => write!(f, "[{}; {}]", ty, sz),
923 TySlice(ty) => write!(f, "[{}]", ty)
928 impl<'tcx> fmt::Display for ty::TyS<'tcx> {
929 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
930 write!(f, "{}", self.sty)
934 impl fmt::Debug for ty::UpvarId {
935 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
936 write!(f, "UpvarId({};`{}`;{})",
938 ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)),
939 self.closure_expr_id)
943 impl fmt::Debug for ty::UpvarBorrow {
944 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
945 write!(f, "UpvarBorrow({:?}, {:?})",
946 self.kind, self.region)
950 impl fmt::Display for ty::InferTy {
951 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
952 let print_var_ids = verbose();
954 ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
955 ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
956 ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
957 ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => write!(f, "_"),
958 ty::FreshTy(v) => write!(f, "FreshTy({})", v),
959 ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
960 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
965 impl fmt::Display for ty::ExplicitSelfCategory {
966 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
967 f.write_str(match *self {
968 ty::StaticExplicitSelfCategory => "static",
969 ty::ByValueExplicitSelfCategory => "self",
970 ty::ByReferenceExplicitSelfCategory(_, hir::MutMutable) => {
973 ty::ByReferenceExplicitSelfCategory(_, hir::MutImmutable) => "&self",
974 ty::ByBoxExplicitSelfCategory => "Box<self>",
979 impl fmt::Display for ty::ParamTy {
980 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
981 write!(f, "{}", self.name)
985 impl fmt::Debug for ty::ParamTy {
986 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
987 write!(f, "{}/{:?}.{}", self, self.space, self.idx)
991 impl<'tcx, T, U> fmt::Display for ty::OutlivesPredicate<T,U>
992 where T: fmt::Display, U: fmt::Display
994 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
995 write!(f, "{} : {}", self.0, self.1)
999 impl<'tcx> fmt::Display for ty::EquatePredicate<'tcx> {
1000 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1001 write!(f, "{} == {}", self.0, self.1)
1005 impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
1006 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1007 write!(f, "TraitPredicate({:?})",
1012 impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> {
1013 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1014 write!(f, "{} : {}",
1015 self.trait_ref.self_ty(),
1020 impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
1021 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1022 write!(f, "ProjectionPredicate({:?}, {:?})",
1028 impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> {
1029 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1030 write!(f, "{} == {}",
1036 impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> {
1037 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1038 write!(f, "{:?}::{}",
1044 impl<'tcx> fmt::Display for ty::Predicate<'tcx> {
1045 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1047 ty::Predicate::Trait(ref data) => write!(f, "{}", data),
1048 ty::Predicate::Equate(ref predicate) => write!(f, "{}", predicate),
1049 ty::Predicate::RegionOutlives(ref predicate) => write!(f, "{}", predicate),
1050 ty::Predicate::TypeOutlives(ref predicate) => write!(f, "{}", predicate),
1051 ty::Predicate::Projection(ref predicate) => write!(f, "{}", predicate),
1052 ty::Predicate::WellFormed(ty) => write!(f, "{} well-formed", ty),
1053 ty::Predicate::ObjectSafe(trait_def_id) =>
1054 ty::tls::with(|tcx| {
1055 write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id))