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 hir::def_id::DefId;
13 use ty::subst::{self, Subst};
14 use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
15 use ty::{TyBool, TyChar, TyStruct, TyEnum};
16 use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
17 use ty::{TyParam, TyRawPtr, TyRef, TyTuple};
19 use ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
20 use ty::{self, Ty, TyCtxt, TypeFoldable};
21 use ty::fold::{TypeFolder, TypeVisitor};
26 use syntax::parse::token;
27 use syntax::ast::CRATE_NODE_ID;
30 pub fn verbose() -> bool {
31 ty::tls::with(|tcx| tcx.sess.verbose())
34 fn fn_sig(f: &mut fmt::Formatter,
40 let mut inputs = inputs.iter();
41 if let Some(&ty) = inputs.next() {
44 write!(f, ", {}", ty)?;
53 ty::FnConverging(ty) => {
55 write!(f, " -> {}", ty)?;
65 /// Namespace of the path given to parameterized to print.
66 #[derive(Copy, Clone, PartialEq)]
72 fn number_of_supplied_defaults<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
73 substs: &subst::Substs,
74 space: subst::ParamSpace,
75 generics: ty::Generics<'tcx>)
78 let has_self = substs.self_ty().is_some();
79 let ty_params = generics.types.get_slice(space);
80 let tps = substs.types.get_slice(space);
81 if ty_params.last().map_or(false, |def| def.default.is_some()) {
82 let substs = tcx.lift(&substs);
83 ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
86 if !has_self && default.has_self_ty() {
87 // In an object type, there is no `Self`, and
88 // thus if the default value references Self,
89 // the user will be required to give an
90 // explicit value. We can't even do the
91 // substitution below to check without causing
95 let default = tcx.lift(&default);
96 substs.and_then(|substs| default.subst(tcx, substs))
108 pub fn parameterized<GG>(f: &mut fmt::Formatter,
109 substs: &subst::Substs,
112 projections: &[ty::ProjectionPredicate],
115 where GG: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>)
116 -> Option<ty::Generics<'tcx>>
118 if let (Ns::Value, Some(self_ty)) = (ns, substs.self_ty()) {
119 write!(f, "<{} as ", self_ty)?;
122 let (fn_trait_kind, verbose, item_name) = ty::tls::with(|tcx| {
123 let (did, item_name) = if ns == Ns::Value {
124 // Try to get the impl/trait parent, if this is an
125 // associated value item (method or constant).
126 tcx.trait_of_item(did).or_else(|| tcx.impl_of_method(did))
127 .map_or((did, None), |parent| (parent, Some(tcx.item_name(did))))
131 write!(f, "{}", tcx.item_path_str(did))?;
132 Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose(), item_name))
135 if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
136 let projection_ty = projections[0].ty;
137 if let TyTuple(ref args) = substs.types.get_slice(subst::TypeSpace)[0].sty {
138 return fn_sig(f, args, false, ty::FnConverging(projection_ty));
142 let empty = Cell::new(true);
143 let start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
146 write!(f, "{}", start)
148 write!(f, "{}", cont)
152 let print_regions = |f: &mut fmt::Formatter, start: &str, regions: &[ty::Region]| {
153 // Don't print any regions if they're all erased.
154 if regions.iter().all(|r| *r == ty::ReErased) {
158 for region in regions {
159 start_or_continue(f, start, ", ")?;
161 write!(f, "{:?}", region)?;
163 let s = region.to_string();
165 // This happens when the value of the region
166 // parameter is not easily serialized. This may be
167 // because the user omitted it in the first place,
168 // or because it refers to some block in the code,
169 // etc. I'm not sure how best to serialize this.
180 print_regions(f, "<", substs.regions.get_slice(subst::TypeSpace))?;
182 let num_supplied_defaults = if verbose {
185 ty::tls::with(|tcx| {
186 if let Some(generics) = get_generics(tcx) {
187 number_of_supplied_defaults(tcx, substs, subst::TypeSpace, generics)
194 let tps = substs.types.get_slice(subst::TypeSpace);
196 for &ty in &tps[..tps.len() - num_supplied_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.
214 if substs.self_ty().is_some() {
218 if let Some(item_name) = item_name {
219 write!(f, "::{}", item_name)?;
222 print_regions(f, "::<", substs.regions.get_slice(subst::FnSpace))?;
224 // FIXME: consider being smart with defaults here too
225 for ty in substs.types.get_slice(subst::FnSpace) {
226 start_or_continue(f, "::<", ", ")?;
227 write!(f, "{}", ty)?;
230 start_or_continue(f, "", ">")?;
236 fn in_binder<'a, 'gcx, 'tcx, T, U>(f: &mut fmt::Formatter,
237 tcx: TyCtxt<'a, 'gcx, 'tcx>,
238 original: &ty::Binder<T>,
239 lifted: Option<ty::Binder<U>>) -> fmt::Result
240 where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx>
242 // Replace any anonymous late-bound regions with named
243 // variants, using gensym'd identifiers, so that we can
244 // clearly differentiate between named and unnamed regions in
245 // the output. We'll probably want to tweak this over time to
246 // decide just how much information to give.
247 let value = if let Some(v) = lifted {
250 return write!(f, "{}", original.0);
253 let mut empty = true;
254 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
257 write!(f, "{}", start)
259 write!(f, "{}", cont)
263 let new_value = tcx.replace_late_bound_regions(&value, |br| {
264 let _ = start_or_continue(f, "for<", ", ");
265 ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
266 ty::BrNamed(_, name, _) => {
267 let _ = write!(f, "{}", name);
273 let name = token::intern("'r");
274 let _ = write!(f, "{}", name);
275 ty::BrNamed(tcx.map.local_def_id(CRATE_NODE_ID),
277 ty::Issue32330::WontChange)
282 start_or_continue(f, "", "> ")?;
283 write!(f, "{}", new_value)
286 /// This curious type is here to help pretty-print trait objects. In
287 /// a trait object, the projections are stored separately from the
288 /// main trait bound, but in fact we want to package them together
289 /// when printing out; they also have separate binders, but we want
290 /// them to share a binder when we print them out. (And the binder
291 /// pretty-printing logic is kind of clever and we don't want to
292 /// reproduce it.) So we just repackage up the structure somewhat.
294 /// Right now there is only one trait in an object that can have
295 /// projection bounds, so we just stuff them altogether. But in
296 /// reality we should eventually sort things out better.
297 #[derive(Clone, Debug)]
298 struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>, Vec<ty::ProjectionPredicate<'tcx>>);
300 impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> {
301 fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
302 TraitAndProjections(self.0.fold_with(folder), self.1.fold_with(folder))
305 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
306 self.0.visit_with(visitor) || self.1.visit_with(visitor)
310 impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
311 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
312 let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
313 parameterized(f, trait_ref.substs,
317 |tcx| Some(tcx.lookup_trait_def(trait_ref.def_id).generics.clone()))
321 impl<'tcx> fmt::Display for ty::TraitTy<'tcx> {
322 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
323 let bounds = &self.bounds;
325 // Generate the main trait ref, including associated types.
326 ty::tls::with(|tcx| {
327 let principal = tcx.lift(&self.principal.0)
328 .expect("could not lift TraitRef for printing");
329 let projections = tcx.lift(&bounds.projection_bounds[..])
330 .expect("could not lift projections for printing");
331 let projections = projections.into_iter().map(|p| p.0).collect();
333 let tap = ty::Binder(TraitAndProjections(principal, projections));
334 in_binder(f, tcx, &ty::Binder(""), Some(tap))
338 for bound in &bounds.builtin_bounds {
339 write!(f, " + {:?}", bound)?;
342 // FIXME: It'd be nice to compute from context when this bound
343 // is implied, but that's non-trivial -- we'd perhaps have to
344 // use thread-local data of some kind? There are also
345 // advantages to just showing the region, since it makes
346 // people aware that it's there.
347 let bound = bounds.region_bound.to_string();
348 if !bound.is_empty() {
349 write!(f, " + {}", bound)?;
356 impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
357 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
358 write!(f, "TypeParameterDef({}, {:?}, {:?}/{})",
361 self.space, self.index)
365 impl fmt::Debug for ty::RegionParameterDef {
366 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
367 write!(f, "RegionParameterDef({}, {:?}, {:?}/{}, {:?})",
370 self.space, self.index,
375 impl<'tcx> fmt::Debug for ty::TyS<'tcx> {
376 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
377 write!(f, "{}", *self)
381 impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
382 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
384 if self.mutbl == hir::MutMutable { "mut " } else { "" },
389 impl<'tcx> fmt::Debug for subst::Substs<'tcx> {
390 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
391 write!(f, "Substs[types={:?}, regions={:?}]",
392 self.types, self.regions)
396 impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
397 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
398 write!(f, "ItemSubsts({:?})", self.substs)
402 impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
403 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
404 // when printing out the debug representation, we don't need
405 // to enumerate the `for<...>` etc because the debruijn index
406 // tells you everything you need to know.
407 match self.substs.self_ty() {
408 None => write!(f, "{}", *self),
409 Some(self_ty) => write!(f, "<{:?} as {}>", self_ty, *self)
414 impl<'tcx> fmt::Debug for ty::TraitDef<'tcx> {
415 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
416 write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
417 self.generics, self.trait_ref)
421 impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> {
422 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
423 ty::tls::with(|tcx| {
424 write!(f, "{}", tcx.item_path_str(self.did))
429 impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> {
430 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
432 ty::adjustment::AdjustReifyFnPointer => {
433 write!(f, "AdjustReifyFnPointer")
435 ty::adjustment::AdjustUnsafeFnPointer => {
436 write!(f, "AdjustUnsafeFnPointer")
438 ty::adjustment::AdjustMutToConstPointer => {
439 write!(f, "AdjustMutToConstPointer")
441 ty::adjustment::AdjustDerefRef(ref data) => {
442 write!(f, "{:?}", data)
448 impl<'tcx> fmt::Debug for ty::adjustment::AutoDerefRef<'tcx> {
449 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
450 write!(f, "AutoDerefRef({}, unsize={:?}, {:?})",
451 self.autoderefs, self.unsize, self.autoref)
455 impl<'tcx> fmt::Debug for ty::TraitTy<'tcx> {
456 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
457 write!(f, "TraitTy({:?},{:?})",
463 impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
464 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
466 ty::Predicate::Trait(ref a) => write!(f, "{:?}", a),
467 ty::Predicate::Rfc1592(ref a) => {
468 write!(f, "RFC1592({:?})", 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)
478 ty::Predicate::ClosureKind(closure_def_id, kind) => {
479 write!(f, "ClosureKind({:?}, {:?})", closure_def_id, kind)
485 impl fmt::Display for ty::BoundRegion {
486 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
488 return write!(f, "{:?}", *self);
492 BrNamed(_, name, _) => write!(f, "{}", name),
493 BrAnon(_) | BrFresh(_) | BrEnv => Ok(())
498 impl fmt::Debug for ty::BoundRegion {
499 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
501 BrAnon(n) => write!(f, "BrAnon({:?})", n),
502 BrFresh(n) => write!(f, "BrFresh({:?})", n),
503 BrNamed(did, name, issue32330) => {
504 write!(f, "BrNamed({:?}:{:?}, {:?}, {:?})",
505 did.krate, did.index, name, issue32330)
507 BrEnv => "BrEnv".fmt(f),
512 impl fmt::Debug for ty::Region {
513 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
515 ty::ReEarlyBound(ref data) => {
516 write!(f, "ReEarlyBound({:?}, {}, {})",
522 ty::ReLateBound(binder_id, ref bound_region) => {
523 write!(f, "ReLateBound({:?}, {:?})",
528 ty::ReFree(ref fr) => write!(f, "{:?}", fr),
531 write!(f, "ReScope({:?})", id)
534 ty::ReStatic => write!(f, "ReStatic"),
536 ty::ReVar(ref vid) => {
537 write!(f, "{:?}", vid)
540 ty::ReSkolemized(id, ref bound_region) => {
541 write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
544 ty::ReEmpty => write!(f, "ReEmpty"),
546 ty::ReErased => write!(f, "ReErased")
551 impl<'tcx> fmt::Debug for ty::ClosureTy<'tcx> {
552 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
553 write!(f, "ClosureTy({},{:?},{})",
560 impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
561 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
562 write!(f, "ClosureUpvar({:?},{:?})",
568 impl<'tcx> fmt::Debug for ty::ParameterEnvironment<'tcx> {
569 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
570 write!(f, "ParameterEnvironment(\
572 implicit_region_bound={:?}, \
573 caller_bounds={:?})",
575 self.implicit_region_bound,
580 impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault {
581 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
583 ty::ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
584 ty::ObjectLifetimeDefault::BaseDefault => write!(f, "BaseDefault"),
585 ty::ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
590 impl fmt::Display for ty::Region {
591 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
593 return write!(f, "{:?}", *self);
596 // These printouts are concise. They do not contain all the information
597 // the user might want to diagnose an error, but there is basically no way
598 // to fit that into a short string. Hence the recommendation to use
599 // `explain_region()` or `note_and_explain_region()`.
601 ty::ReEarlyBound(ref data) => {
602 write!(f, "{}", data.name)
604 ty::ReLateBound(_, br) |
605 ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
606 ty::ReSkolemized(_, br) => {
611 ty::ReErased => Ok(()),
612 ty::ReStatic => write!(f, "'static"),
613 ty::ReEmpty => write!(f, "'<empty>"),
618 impl fmt::Debug for ty::FreeRegion {
619 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
620 write!(f, "ReFree({:?}, {:?})",
621 self.scope, self.bound_region)
625 impl fmt::Debug for ty::Variance {
626 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
627 f.write_str(match *self {
628 ty::Covariant => "+",
629 ty::Contravariant => "-",
630 ty::Invariant => "o",
631 ty::Bivariant => "*",
636 impl fmt::Debug for ty::ItemVariances {
637 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
638 write!(f, "ItemVariances(types={:?}, regions={:?})",
639 self.types, self.regions)
643 impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> {
644 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
645 write!(f, "GenericPredicates({:?})", self.predicates)
649 impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
650 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
651 write!(f, "InstantiatedPredicates({:?})",
656 impl<'tcx> fmt::Debug for ty::ImplOrTraitItem<'tcx> {
657 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
658 write!(f, "ImplOrTraitItem(")?;
660 ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i),
661 ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i),
662 ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i),
668 impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
669 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
671 fn_sig(f, &self.inputs, self.variadic, self.output)
675 impl<'tcx> fmt::Debug for ty::ExistentialBounds<'tcx> {
676 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
677 let mut empty = true;
678 let mut maybe_continue = |f: &mut fmt::Formatter| {
687 let region_str = format!("{:?}", self.region_bound);
688 if !region_str.is_empty() {
690 write!(f, "{}", region_str)?;
693 for bound in &self.builtin_bounds {
695 write!(f, "{:?}", bound)?;
698 for projection_bound in &self.projection_bounds {
700 write!(f, "{:?}", projection_bound)?;
707 impl fmt::Display for ty::BuiltinBounds {
708 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
709 let mut bounds = self.iter();
710 if let Some(bound) = bounds.next() {
711 write!(f, "{:?}", bound)?;
712 for bound in bounds {
713 write!(f, " + {:?}", bound)?;
720 impl fmt::Debug for ty::TyVid {
721 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
722 write!(f, "_#{}t", self.index)
726 impl fmt::Debug for ty::IntVid {
727 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
728 write!(f, "_#{}i", self.index)
732 impl fmt::Debug for ty::FloatVid {
733 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
734 write!(f, "_#{}f", self.index)
738 impl fmt::Debug for ty::RegionVid {
739 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
740 write!(f, "'_#{}r", self.index)
744 impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
745 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
746 write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
750 impl fmt::Debug for ty::InferTy {
751 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
753 ty::TyVar(ref v) => v.fmt(f),
754 ty::IntVar(ref v) => v.fmt(f),
755 ty::FloatVar(ref v) => v.fmt(f),
756 ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
757 ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
758 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
763 impl fmt::Debug for ty::IntVarValue {
764 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
766 ty::IntType(ref v) => v.fmt(f),
767 ty::UintType(ref v) => v.fmt(f),
772 // The generic impl doesn't work yet because projections are not
773 // normalized under HRTB.
774 /*impl<T> fmt::Display for ty::Binder<T>
775 where T: fmt::Display + for<'a> ty::Lift<'a>,
776 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
778 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
779 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
783 impl<'tcx> fmt::Display for ty::Binder<ty::TraitRef<'tcx>> {
784 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
785 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
789 impl<'tcx> fmt::Display for ty::Binder<ty::TraitPredicate<'tcx>> {
790 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
791 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
795 impl<'tcx> fmt::Display for ty::Binder<ty::EquatePredicate<'tcx>> {
796 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
797 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
801 impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
802 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
803 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
807 impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region>> {
808 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
809 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
813 impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>> {
814 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
815 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
819 impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
820 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
821 parameterized(f, self.substs, self.def_id, Ns::Type, &[],
822 |tcx| Some(tcx.lookup_trait_def(self.def_id).generics.clone()))
826 impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
827 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
829 TyBool => write!(f, "bool"),
830 TyChar => write!(f, "char"),
831 TyInt(t) => write!(f, "{}", t.ty_to_string()),
832 TyUint(t) => write!(f, "{}", t.ty_to_string()),
833 TyFloat(t) => write!(f, "{}", t.ty_to_string()),
834 TyBox(typ) => write!(f, "Box<{}>", typ),
835 TyRawPtr(ref tm) => {
836 write!(f, "*{} {}", match tm.mutbl {
837 hir::MutMutable => "mut",
838 hir::MutImmutable => "const",
841 TyRef(r, ref tm) => {
843 let s = r.to_string();
850 TyTuple(ref tys) => {
852 let mut tys = tys.iter();
853 if let Some(&ty) = tys.next() {
854 write!(f, "{},", ty)?;
855 if let Some(&ty) = tys.next() {
856 write!(f, " {}", ty)?;
858 write!(f, ", {}", ty)?;
864 TyFnDef(def_id, substs, ref bare_fn) => {
865 if bare_fn.unsafety == hir::Unsafety::Unsafe {
866 write!(f, "unsafe ")?;
869 if bare_fn.abi != Abi::Rust {
870 write!(f, "extern {} ", bare_fn.abi)?;
873 write!(f, "{} {{", bare_fn.sig.0)?;
875 f, substs, def_id, Ns::Value, &[],
876 |tcx| tcx.opt_lookup_item_type(def_id).map(|t| t.generics))?;
879 TyFnPtr(ref bare_fn) => {
880 if bare_fn.unsafety == hir::Unsafety::Unsafe {
881 write!(f, "unsafe ")?;
884 if bare_fn.abi != Abi::Rust {
885 write!(f, "extern {} ", bare_fn.abi)?;
888 write!(f, "{}", bare_fn.sig.0)
890 TyInfer(infer_ty) => write!(f, "{}", infer_ty),
891 TyError => write!(f, "[type error]"),
892 TyParam(ref param_ty) => write!(f, "{}", param_ty),
893 TyEnum(def, substs) | TyStruct(def, substs) => {
894 ty::tls::with(|tcx| {
895 if def.did.is_local() &&
896 !tcx.tcache.borrow().contains_key(&def.did) {
897 write!(f, "{}<..>", tcx.item_path_str(def.did))
900 f, substs, def.did, Ns::Type, &[],
902 tcx.opt_lookup_item_type(def.did).
908 TyTrait(ref data) => write!(f, "{}", data),
909 ty::TyProjection(ref data) => write!(f, "{}", data),
910 ty::TyAnon(def_id, substs) => {
911 ty::tls::with(|tcx| {
912 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
913 // by looking up the projections associated with the def_id.
914 let item_predicates = tcx.lookup_predicates(def_id);
915 let substs = tcx.lift(&substs).unwrap_or_else(|| {
916 tcx.mk_substs(subst::Substs::empty())
918 let bounds = item_predicates.instantiate(tcx, substs);
920 let mut first = true;
921 let mut is_sized = false;
923 for predicate in bounds.predicates.into_vec() {
924 if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
925 // Don't print +Sized, but rather +?Sized if absent.
926 if Some(trait_ref.def_id()) == tcx.lang_items.sized_trait() {
931 write!(f, "{}{}", if first { " " } else { "+" }, trait_ref)?;
936 write!(f, "{}?Sized", if first { " " } else { "+" })?;
941 TyStr => write!(f, "str"),
942 TyClosure(did, substs) => ty::tls::with(|tcx| {
943 write!(f, "[closure")?;
945 if let Some(node_id) = tcx.map.as_local_node_id(did) {
946 write!(f, "@{:?}", tcx.map.span(node_id))?;
948 tcx.with_freevars(node_id, |freevars| {
949 for (freevar, upvar_ty) in freevars.iter().zip(substs.upvar_tys) {
950 let node_id = freevar.def.var_id();
954 tcx.local_var_name_str(node_id),
961 // cross-crate closure types should only be
962 // visible in trans bug reports, I imagine.
963 write!(f, "@{:?}", did)?;
965 for (index, upvar_ty) in substs.upvar_tys.iter().enumerate() {
966 write!(f, "{}{}:{}", sep, index, upvar_ty)?;
973 TyArray(ty, sz) => write!(f, "[{}; {}]", ty, sz),
974 TySlice(ty) => write!(f, "[{}]", ty)
979 impl<'tcx> fmt::Display for ty::TyS<'tcx> {
980 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
981 write!(f, "{}", self.sty)
985 impl fmt::Debug for ty::UpvarId {
986 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
987 write!(f, "UpvarId({};`{}`;{})",
989 ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)),
990 self.closure_expr_id)
994 impl fmt::Debug for ty::UpvarBorrow {
995 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
996 write!(f, "UpvarBorrow({:?}, {:?})",
997 self.kind, self.region)
1001 impl fmt::Display for ty::InferTy {
1002 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1003 let print_var_ids = verbose();
1005 ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
1006 ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
1007 ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
1008 ty::TyVar(_) => write!(f, "_"),
1009 ty::IntVar(_) => write!(f, "{}", "{integer}"),
1010 ty::FloatVar(_) => write!(f, "{}", "{float}"),
1011 ty::FreshTy(v) => write!(f, "FreshTy({})", v),
1012 ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
1013 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
1018 impl fmt::Display for ty::ExplicitSelfCategory {
1019 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1020 f.write_str(match *self {
1021 ty::ExplicitSelfCategory::Static => "static",
1022 ty::ExplicitSelfCategory::ByValue => "self",
1023 ty::ExplicitSelfCategory::ByReference(_, hir::MutMutable) => {
1026 ty::ExplicitSelfCategory::ByReference(_, hir::MutImmutable) => "&self",
1027 ty::ExplicitSelfCategory::ByBox => "Box<self>",
1032 impl fmt::Display for ty::ParamTy {
1033 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1034 write!(f, "{}", self.name)
1038 impl fmt::Debug for ty::ParamTy {
1039 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1040 write!(f, "{}/{:?}.{}", self, self.space, self.idx)
1044 impl<'tcx, T, U> fmt::Display for ty::OutlivesPredicate<T,U>
1045 where T: fmt::Display, U: fmt::Display
1047 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1048 write!(f, "{} : {}", self.0, self.1)
1052 impl<'tcx> fmt::Display for ty::EquatePredicate<'tcx> {
1053 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1054 write!(f, "{} == {}", self.0, self.1)
1058 impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
1059 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1060 write!(f, "TraitPredicate({:?})",
1065 impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> {
1066 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1067 write!(f, "{}: {}", self.trait_ref.self_ty(), self.trait_ref)
1071 impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
1072 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1073 write!(f, "ProjectionPredicate({:?}, {:?})",
1079 impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> {
1080 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1081 write!(f, "{} == {}",
1087 impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> {
1088 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1089 write!(f, "{:?}::{}",
1095 impl fmt::Display for ty::ClosureKind {
1096 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1098 ty::ClosureKind::Fn => write!(f, "Fn"),
1099 ty::ClosureKind::FnMut => write!(f, "FnMut"),
1100 ty::ClosureKind::FnOnce => write!(f, "FnOnce"),
1105 impl<'tcx> fmt::Display for ty::Predicate<'tcx> {
1106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1108 ty::Predicate::Trait(ref data) => write!(f, "{}", data),
1109 ty::Predicate::Rfc1592(ref data) => write!(f, "{}", data),
1110 ty::Predicate::Equate(ref predicate) => write!(f, "{}", predicate),
1111 ty::Predicate::RegionOutlives(ref predicate) => write!(f, "{}", predicate),
1112 ty::Predicate::TypeOutlives(ref predicate) => write!(f, "{}", predicate),
1113 ty::Predicate::Projection(ref predicate) => write!(f, "{}", predicate),
1114 ty::Predicate::WellFormed(ty) => write!(f, "{} well-formed", ty),
1115 ty::Predicate::ObjectSafe(trait_def_id) =>
1116 ty::tls::with(|tcx| {
1117 write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id))
1119 ty::Predicate::ClosureKind(closure_def_id, kind) =>
1120 ty::tls::with(|tcx| {
1121 write!(f, "the closure `{}` implements the trait `{}`",
1122 tcx.item_path_str(closure_def_id), kind)