]> git.proxmox.com Git - rustc.git/blame - src/librustc/util/ppaux.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librustc / util / ppaux.rs
CommitLineData
223e47cc
LB
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.
4//
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.
10
223e47cc 11
54a0048b
SL
12use hir::def_id::DefId;
13use ty::subst::{self, Subst};
14use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
15use ty::{TyBool, TyChar, TyStruct, TyEnum};
16use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
17use ty::{TyParam, TyRawPtr, TyRef, TyTuple};
18use ty::TyClosure;
19use ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
20use ty::{self, Ty, TyCtxt, TypeFoldable};
21
22use std::cell::Cell;
62682a34 23use std::fmt;
7453a54e 24use syntax::abi::Abi;
970d7e83 25use syntax::parse::token;
b039eaaf 26use syntax::ast::CRATE_NODE_ID;
54a0048b 27use hir;
223e47cc 28
62682a34
SL
29pub fn verbose() -> bool {
30 ty::tls::with(|tcx| tcx.sess.verbose())
970d7e83
LB
31}
32
62682a34
SL
33fn fn_sig(f: &mut fmt::Formatter,
34 inputs: &[Ty],
35 variadic: bool,
36 output: ty::FnOutput)
37 -> fmt::Result {
54a0048b 38 write!(f, "(")?;
62682a34
SL
39 let mut inputs = inputs.iter();
40 if let Some(&ty) = inputs.next() {
54a0048b 41 write!(f, "{}", ty)?;
62682a34 42 for &ty in inputs {
54a0048b 43 write!(f, ", {}", ty)?;
970d7e83 44 }
62682a34 45 if variadic {
54a0048b 46 write!(f, ", ...")?;
1a4d82fc
JJ
47 }
48 }
54a0048b 49 write!(f, ")")?;
223e47cc 50
62682a34
SL
51 match output {
52 ty::FnConverging(ty) => {
c1a9b12d 53 if !ty.is_nil() {
54a0048b 54 write!(f, " -> {}", ty)?;
1a4d82fc 55 }
62682a34 56 Ok(())
1a4d82fc 57 }
62682a34
SL
58 ty::FnDiverging => {
59 write!(f, " -> !")
1a4d82fc
JJ
60 }
61 }
62}
970d7e83 63
54a0048b
SL
64/// Namespace of the path given to parameterized to print.
65#[derive(Copy, Clone, PartialEq)]
66pub enum Ns {
67 Type,
68 Value
69}
223e47cc 70
54a0048b
SL
71fn number_of_supplied_defaults<'tcx, GG>(tcx: &ty::TyCtxt<'tcx>,
72 substs: &subst::Substs,
73 space: subst::ParamSpace,
74 get_generics: GG)
75 -> usize
76 where GG: FnOnce(&TyCtxt<'tcx>) -> ty::Generics<'tcx>
77{
78 let generics = get_generics(tcx);
79
80 let has_self = substs.self_ty().is_some();
81 let ty_params = generics.types.get_slice(space);
82 let tps = substs.types.get_slice(space);
83 if ty_params.last().map_or(false, |def| def.default.is_some()) {
84 let substs = tcx.lift(&substs);
85 ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
86 match def.default {
87 Some(default) => {
88 if !has_self && default.has_self_ty() {
89 // In an object type, there is no `Self`, and
90 // thus if the default value references Self,
91 // the user will be required to give an
92 // explicit value. We can't even do the
93 // substitution below to check without causing
94 // an ICE. (#18956).
95 false
96 } else {
97 let default = tcx.lift(&default);
98 substs.and_then(|substs| default.subst(tcx, substs))
99 == Some(actual)
100 }
85aaf69f 101 }
54a0048b 102 None => false
85aaf69f 103 }
54a0048b
SL
104 }).count()
105 } else {
106 0
107 }
108}
109
110pub fn parameterized<GG>(f: &mut fmt::Formatter,
111 substs: &subst::Substs,
112 did: DefId,
113 ns: Ns,
114 projections: &[ty::ProjectionPredicate],
115 get_generics: GG)
116 -> fmt::Result
117 where GG: for<'tcx> FnOnce(&TyCtxt<'tcx>) -> ty::Generics<'tcx>
118{
119 if let (Ns::Value, Some(self_ty)) = (ns, substs.self_ty()) {
120 write!(f, "<{} as ", self_ty)?;
1a4d82fc 121 }
223e47cc 122
54a0048b
SL
123 let (fn_trait_kind, verbose, item_name) = ty::tls::with(|tcx| {
124 let (did, item_name) = if ns == Ns::Value {
125 // Try to get the impl/trait parent, if this is an
126 // associated value item (method or constant).
127 tcx.trait_of_item(did).or_else(|| tcx.impl_of_method(did))
128 .map_or((did, None), |parent| (parent, Some(tcx.item_name(did))))
129 } else {
130 (did, None)
131 };
132 write!(f, "{}", tcx.item_path_str(did))?;
133 Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose(), item_name))
134 })?;
135
136 if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
62682a34
SL
137 let projection_ty = projections[0].ty;
138 if let TyTuple(ref args) = substs.types.get_slice(subst::TypeSpace)[0].sty {
139 return fn_sig(f, args, false, ty::FnConverging(projection_ty));
140 }
141 }
1a4d82fc 142
54a0048b
SL
143 let empty = Cell::new(true);
144 let start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
145 if empty.get() {
146 empty.set(false);
147 write!(f, "{}", start)
148 } else {
149 write!(f, "{}", cont)
150 }
151 };
152 let print_region = |f: &mut fmt::Formatter, region: &ty::Region| -> _ {
153 if verbose {
154 write!(f, "{:?}", region)
155 } else {
156 let s = region.to_string();
157 if s.is_empty() {
158 // This happens when the value of the region
159 // parameter is not easily serialized. This may be
160 // because the user omitted it in the first place,
161 // or because it refers to some block in the code,
162 // etc. I'm not sure how best to serialize this.
163 write!(f, "'_")
164 } else {
165 write!(f, "{}", s)
1a4d82fc 166 }
970d7e83 167 }
54a0048b
SL
168 };
169
170 for region in substs.regions.get_slice(subst::TypeSpace) {
171 start_or_continue(f, "<", ", ")?;
172 print_region(f, region)?;
1a4d82fc
JJ
173 }
174
54a0048b
SL
175 let num_supplied_defaults = if verbose {
176 0
177 } else {
178 // It is important to execute this conditionally, only if -Z
179 // verbose is false. Otherwise, debug logs can sometimes cause
180 // ICEs trying to fetch the generics early in the pipeline. This
181 // is kind of a hacky workaround in that -Z verbose is required to
182 // avoid those ICEs.
183 ty::tls::with(|tcx| {
184 number_of_supplied_defaults(tcx, substs, subst::TypeSpace, get_generics)
185 })
186 };
187
1a4d82fc 188 let tps = substs.types.get_slice(subst::TypeSpace);
223e47cc 189
54a0048b
SL
190 for &ty in &tps[..tps.len() - num_supplied_defaults] {
191 start_or_continue(f, "<", ", ")?;
192 write!(f, "{}", ty)?;
970d7e83
LB
193 }
194
85aaf69f 195 for projection in projections {
54a0048b
SL
196 start_or_continue(f, "<", ", ")?;
197 write!(f, "{}={}",
198 projection.projection_ty.item_name,
199 projection.ty)?;
200 }
201
202 start_or_continue(f, "", ">")?;
203
204 // For values, also print their name and type parameters.
205 if ns == Ns::Value {
206 empty.set(true);
207
208 if substs.self_ty().is_some() {
209 write!(f, ">")?;
210 }
211
212 if let Some(item_name) = item_name {
213 write!(f, "::{}", item_name)?;
214 }
215
216 for region in substs.regions.get_slice(subst::FnSpace) {
217 start_or_continue(f, "::<", ", ")?;
218 print_region(f, region)?;
219 }
220
221 // FIXME: consider being smart with defaults here too
222 for ty in substs.types.get_slice(subst::FnSpace) {
223 start_or_continue(f, "::<", ", ")?;
224 write!(f, "{}", ty)?;
225 }
226
227 start_or_continue(f, "", ">")?;
223e47cc 228 }
223e47cc 229
54a0048b 230 Ok(())
223e47cc
LB
231}
232
62682a34 233fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
54a0048b 234 tcx: &TyCtxt<'tcx>,
62682a34
SL
235 original: &ty::Binder<T>,
236 lifted: Option<ty::Binder<U>>) -> fmt::Result
237 where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx>
238{
239 // Replace any anonymous late-bound regions with named
240 // variants, using gensym'd identifiers, so that we can
241 // clearly differentiate between named and unnamed regions in
242 // the output. We'll probably want to tweak this over time to
243 // decide just how much information to give.
244 let value = if let Some(v) = lifted {
245 v
246 } else {
247 return write!(f, "{}", original.0);
248 };
1a4d82fc 249
62682a34
SL
250 let mut empty = true;
251 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
252 if empty {
253 empty = false;
254 write!(f, "{}", start)
255 } else {
256 write!(f, "{}", cont)
970d7e83 257 }
62682a34 258 };
1a4d82fc 259
e9174d1e 260 let new_value = tcx.replace_late_bound_regions(&value, |br| {
62682a34
SL
261 let _ = start_or_continue(f, "for<", ", ");
262 ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
263 ty::BrNamed(_, name) => {
264 let _ = write!(f, "{}", name);
265 br
266 }
267 ty::BrAnon(_) |
268 ty::BrFresh(_) |
269 ty::BrEnv => {
270 let name = token::intern("'r");
271 let _ = write!(f, "{}", name);
b039eaaf 272 ty::BrNamed(tcx.map.local_def_id(CRATE_NODE_ID), name)
62682a34
SL
273 }
274 })
275 }).0;
1a4d82fc 276
54a0048b 277 start_or_continue(f, "", "> ")?;
62682a34 278 write!(f, "{}", new_value)
1a4d82fc
JJ
279}
280
85aaf69f
SL
281/// This curious type is here to help pretty-print trait objects. In
282/// a trait object, the projections are stored separately from the
283/// main trait bound, but in fact we want to package them together
284/// when printing out; they also have separate binders, but we want
285/// them to share a binder when we print them out. (And the binder
286/// pretty-printing logic is kind of clever and we don't want to
287/// reproduce it.) So we just repackage up the structure somewhat.
288///
289/// Right now there is only one trait in an object that can have
290/// projection bounds, so we just stuff them altogether. But in
291/// reality we should eventually sort things out better.
62682a34
SL
292#[derive(Clone, Debug)]
293struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>, Vec<ty::ProjectionPredicate<'tcx>>);
294
295impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> {
9cc50fc6 296 fn super_fold_with<F:ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
62682a34 297 TraitAndProjections(self.0.fold_with(folder), self.1.fold_with(folder))
85aaf69f 298 }
9cc50fc6
SL
299
300 fn super_visit_with<V: ty::fold::TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
301 self.0.visit_with(visitor) || self.1.visit_with(visitor)
302 }
85aaf69f
SL
303}
304
62682a34
SL
305impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
306 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
307 let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
308 parameterized(f, trait_ref.substs,
309 trait_ref.def_id,
54a0048b 310 Ns::Type,
62682a34 311 projection_bounds,
c1a9b12d 312 |tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone())
62682a34
SL
313 }
314}
85aaf69f 315
62682a34
SL
316impl<'tcx> fmt::Display for ty::TraitTy<'tcx> {
317 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
318 let bounds = &self.bounds;
85aaf69f
SL
319
320 // Generate the main trait ref, including associated types.
54a0048b 321 ty::tls::with(|tcx| {
62682a34
SL
322 let principal = tcx.lift(&self.principal.0)
323 .expect("could not lift TraitRef for printing");
324 let projections = tcx.lift(&bounds.projection_bounds[..])
325 .expect("could not lift projections for printing");
c1a9b12d 326 let projections = projections.into_iter().map(|p| p.0).collect();
62682a34
SL
327
328 let tap = ty::Binder(TraitAndProjections(principal, projections));
329 in_binder(f, tcx, &ty::Binder(""), Some(tap))
54a0048b 330 })?;
85aaf69f
SL
331
332 // Builtin bounds.
333 for bound in &bounds.builtin_bounds {
54a0048b 334 write!(f, " + {:?}", bound)?;
85aaf69f
SL
335 }
336
62682a34
SL
337 // FIXME: It'd be nice to compute from context when this bound
338 // is implied, but that's non-trivial -- we'd perhaps have to
339 // use thread-local data of some kind? There are also
340 // advantages to just showing the region, since it makes
341 // people aware that it's there.
342 let bound = bounds.region_bound.to_string();
343 if !bound.is_empty() {
54a0048b 344 write!(f, " + {}", bound)?;
85aaf69f
SL
345 }
346
62682a34 347 Ok(())
1a4d82fc
JJ
348 }
349}
350
62682a34
SL
351impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
352 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
b039eaaf 353 write!(f, "TypeParameterDef({}, {:?}, {:?}/{})",
e9174d1e 354 self.name,
b039eaaf 355 self.def_id,
e9174d1e
SL
356 self.space, self.index)
357 }
358}
359
360impl fmt::Debug for ty::RegionParameterDef {
361 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
b039eaaf 362 write!(f, "RegionParameterDef({}, {:?}, {:?}/{}, {:?})",
e9174d1e 363 self.name,
b039eaaf 364 self.def_id,
e9174d1e
SL
365 self.space, self.index,
366 self.bounds)
1a4d82fc
JJ
367 }
368}
369
62682a34
SL
370impl<'tcx> fmt::Debug for ty::TyS<'tcx> {
371 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
372 write!(f, "{}", *self)
1a4d82fc
JJ
373 }
374}
375
c1a9b12d 376impl<'tcx> fmt::Display for ty::TypeAndMut<'tcx> {
62682a34
SL
377 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378 write!(f, "{}{}",
b039eaaf 379 if self.mutbl == hir::MutMutable { "mut " } else { "" },
62682a34 380 self.ty)
970d7e83
LB
381 }
382}
383
62682a34
SL
384impl<'tcx> fmt::Debug for subst::Substs<'tcx> {
385 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
386 write!(f, "Substs[types={:?}, regions={:?}]",
387 self.types, self.regions)
970d7e83
LB
388 }
389}
390
62682a34
SL
391impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
392 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
393 write!(f, "ItemSubsts({:?})", self.substs)
970d7e83
LB
394 }
395}
396
62682a34
SL
397impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
398 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc
JJ
399 // when printing out the debug representation, we don't need
400 // to enumerate the `for<...>` etc because the debruijn index
401 // tells you everything you need to know.
d9579d0f 402 match self.substs.self_ty() {
62682a34
SL
403 None => write!(f, "{}", *self),
404 Some(self_ty) => write!(f, "<{:?} as {}>", self_ty, *self)
d9579d0f 405 }
1a4d82fc
JJ
406 }
407}
408
62682a34
SL
409impl<'tcx> fmt::Debug for ty::TraitDef<'tcx> {
410 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
411 write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
412 self.generics, self.trait_ref)
1a4d82fc
JJ
413 }
414}
415
e9174d1e
SL
416impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> {
417 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
418 ty::tls::with(|tcx| {
419 write!(f, "{}", tcx.item_path_str(self.did))
420 })
421 }
422}
423
424impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> {
425 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
426 match *self {
427 ty::adjustment::AdjustReifyFnPointer => {
428 write!(f, "AdjustReifyFnPointer")
429 }
430 ty::adjustment::AdjustUnsafeFnPointer => {
431 write!(f, "AdjustUnsafeFnPointer")
432 }
7453a54e
SL
433 ty::adjustment::AdjustMutToConstPointer => {
434 write!(f, "AdjustMutToConstPointer")
435 }
e9174d1e
SL
436 ty::adjustment::AdjustDerefRef(ref data) => {
437 write!(f, "{:?}", data)
438 }
439 }
440 }
441}
442
443impl<'tcx> fmt::Debug for ty::adjustment::AutoDerefRef<'tcx> {
444 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
445 write!(f, "AutoDerefRef({}, unsize={:?}, {:?})",
446 self.autoderefs, self.unsize, self.autoref)
447 }
448}
449
450impl<'tcx> fmt::Debug for ty::TraitTy<'tcx> {
451 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
452 write!(f, "TraitTy({:?},{:?})",
453 self.principal,
454 self.bounds)
455 }
456}
457
458impl<'tcx> fmt::Debug for ty::Predicate<'tcx> {
459 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
460 match *self {
461 ty::Predicate::Trait(ref a) => write!(f, "{:?}", a),
462 ty::Predicate::Equate(ref pair) => write!(f, "{:?}", pair),
463 ty::Predicate::RegionOutlives(ref pair) => write!(f, "{:?}", pair),
464 ty::Predicate::TypeOutlives(ref pair) => write!(f, "{:?}", pair),
465 ty::Predicate::Projection(ref pair) => write!(f, "{:?}", pair),
466 ty::Predicate::WellFormed(ty) => write!(f, "WF({:?})", ty),
467 ty::Predicate::ObjectSafe(trait_def_id) => {
468 write!(f, "ObjectSafe({:?})", trait_def_id)
469 }
470 }
471 }
472}
473
62682a34
SL
474impl fmt::Display for ty::BoundRegion {
475 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
476 if verbose() {
477 return write!(f, "{:?}", *self);
478 }
970d7e83 479
1a4d82fc 480 match *self {
62682a34
SL
481 BrNamed(_, name) => write!(f, "{}", name),
482 BrAnon(_) | BrFresh(_) | BrEnv => Ok(())
1a4d82fc
JJ
483 }
484 }
485}
486
e9174d1e
SL
487impl fmt::Debug for ty::BoundRegion {
488 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
489 match *self {
490 BrAnon(n) => write!(f, "BrAnon({:?})", n),
491 BrFresh(n) => write!(f, "BrFresh({:?})", n),
492 BrNamed(did, name) => {
b039eaaf 493 write!(f, "BrNamed({:?}, {:?})", did, name)
e9174d1e
SL
494 }
495 BrEnv => "BrEnv".fmt(f),
496 }
497 }
498}
499
62682a34
SL
500impl fmt::Debug for ty::Region {
501 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc 502 match *self {
9346a6ac 503 ty::ReEarlyBound(ref data) => {
9cc50fc6 504 write!(f, "ReEarlyBound({:?}, {}, {})",
62682a34
SL
505 data.space,
506 data.index,
507 data.name)
1a4d82fc
JJ
508 }
509
510 ty::ReLateBound(binder_id, ref bound_region) => {
62682a34
SL
511 write!(f, "ReLateBound({:?}, {:?})",
512 binder_id,
513 bound_region)
1a4d82fc
JJ
514 }
515
62682a34 516 ty::ReFree(ref fr) => write!(f, "{:?}", fr),
1a4d82fc
JJ
517
518 ty::ReScope(id) => {
62682a34 519 write!(f, "ReScope({:?})", id)
1a4d82fc
JJ
520 }
521
62682a34 522 ty::ReStatic => write!(f, "ReStatic"),
1a4d82fc 523
e9174d1e 524 ty::ReVar(ref vid) => {
62682a34 525 write!(f, "{:?}", vid)
1a4d82fc
JJ
526 }
527
e9174d1e
SL
528 ty::ReSkolemized(id, ref bound_region) => {
529 write!(f, "ReSkolemized({}, {:?})", id.index, bound_region)
1a4d82fc
JJ
530 }
531
62682a34 532 ty::ReEmpty => write!(f, "ReEmpty")
1a4d82fc
JJ
533 }
534 }
535}
536
e9174d1e
SL
537impl<'tcx> fmt::Debug for ty::ClosureTy<'tcx> {
538 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
539 write!(f, "ClosureTy({},{:?},{})",
540 self.unsafety,
541 self.sig,
542 self.abi)
543 }
544}
545
546impl<'tcx> fmt::Debug for ty::ClosureUpvar<'tcx> {
547 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
548 write!(f, "ClosureUpvar({:?},{:?})",
549 self.def,
550 self.ty)
551 }
552}
553
554impl<'a, 'tcx> fmt::Debug for ty::ParameterEnvironment<'a, 'tcx> {
555 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
556 write!(f, "ParameterEnvironment(\
557 free_substs={:?}, \
558 implicit_region_bound={:?}, \
559 caller_bounds={:?})",
560 self.free_substs,
561 self.implicit_region_bound,
562 self.caller_bounds)
563 }
564}
565
566impl<'tcx> fmt::Debug for ty::ObjectLifetimeDefault {
567 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
568 match *self {
569 ty::ObjectLifetimeDefault::Ambiguous => write!(f, "Ambiguous"),
570 ty::ObjectLifetimeDefault::BaseDefault => write!(f, "BaseDefault"),
571 ty::ObjectLifetimeDefault::Specific(ref r) => write!(f, "{:?}", r),
572 }
573 }
574}
575
62682a34
SL
576impl fmt::Display for ty::Region {
577 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
578 if verbose() {
579 return write!(f, "{:?}", *self);
85aaf69f 580 }
85aaf69f 581
62682a34
SL
582 // These printouts are concise. They do not contain all the information
583 // the user might want to diagnose an error, but there is basically no way
584 // to fit that into a short string. Hence the recommendation to use
585 // `explain_region()` or `note_and_explain_region()`.
85aaf69f 586 match *self {
62682a34
SL
587 ty::ReEarlyBound(ref data) => {
588 write!(f, "{}", data.name)
589 }
590 ty::ReLateBound(_, br) |
591 ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
e9174d1e 592 ty::ReSkolemized(_, br) => {
62682a34 593 write!(f, "{}", br)
970d7e83 594 }
62682a34 595 ty::ReScope(_) |
e9174d1e 596 ty::ReVar(_) => Ok(()),
62682a34
SL
597 ty::ReStatic => write!(f, "'static"),
598 ty::ReEmpty => write!(f, "'<empty>"),
970d7e83 599 }
970d7e83
LB
600 }
601}
602
62682a34
SL
603impl fmt::Debug for ty::FreeRegion {
604 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
605 write!(f, "ReFree({:?}, {:?})",
606 self.scope, self.bound_region)
970d7e83
LB
607 }
608}
609
e9174d1e
SL
610impl fmt::Debug for ty::Variance {
611 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
612 f.write_str(match *self {
613 ty::Covariant => "+",
614 ty::Contravariant => "-",
615 ty::Invariant => "o",
616 ty::Bivariant => "*",
617 })
618 }
619}
620
62682a34
SL
621impl fmt::Debug for ty::ItemVariances {
622 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
623 write!(f, "ItemVariances(types={:?}, regions={:?})",
624 self.types, self.regions)
970d7e83
LB
625 }
626}
627
62682a34
SL
628impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> {
629 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
630 write!(f, "GenericPredicates({:?})", self.predicates)
970d7e83
LB
631 }
632}
633
62682a34
SL
634impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
635 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
636 write!(f, "InstantiatedPredicates({:?})",
637 self.predicates)
970d7e83
LB
638 }
639}
640
62682a34
SL
641impl<'tcx> fmt::Debug for ty::ImplOrTraitItem<'tcx> {
642 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54a0048b
SL
643 write!(f, "ImplOrTraitItem(")?;
644 match *self {
62682a34
SL
645 ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i),
646 ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i),
647 ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i),
54a0048b 648 }?;
62682a34 649 write!(f, ")")
970d7e83
LB
650 }
651}
652
62682a34
SL
653impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
654 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54a0048b 655 write!(f, "fn")?;
62682a34 656 fn_sig(f, &self.inputs, self.variadic, self.output)
970d7e83
LB
657 }
658}
659
62682a34
SL
660impl<'tcx> fmt::Debug for ty::ExistentialBounds<'tcx> {
661 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
662 let mut empty = true;
663 let mut maybe_continue = |f: &mut fmt::Formatter| {
664 if empty {
665 empty = false;
666 Ok(())
667 } else {
668 write!(f, " + ")
669 }
670 };
1a4d82fc 671
62682a34 672 let region_str = format!("{:?}", self.region_bound);
1a4d82fc 673 if !region_str.is_empty() {
54a0048b
SL
674 maybe_continue(f)?;
675 write!(f, "{}", region_str)?;
1a4d82fc
JJ
676 }
677
85aaf69f 678 for bound in &self.builtin_bounds {
54a0048b
SL
679 maybe_continue(f)?;
680 write!(f, "{:?}", bound)?;
970d7e83 681 }
1a4d82fc 682
85aaf69f 683 for projection_bound in &self.projection_bounds {
54a0048b
SL
684 maybe_continue(f)?;
685 write!(f, "{:?}", projection_bound)?;
85aaf69f
SL
686 }
687
62682a34 688 Ok(())
1a4d82fc
JJ
689 }
690}
691
62682a34
SL
692impl fmt::Display for ty::BuiltinBounds {
693 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
694 let mut bounds = self.iter();
695 if let Some(bound) = bounds.next() {
54a0048b 696 write!(f, "{:?}", bound)?;
62682a34 697 for bound in bounds {
54a0048b 698 write!(f, " + {:?}", bound)?;
62682a34 699 }
970d7e83 700 }
62682a34 701 Ok(())
970d7e83
LB
702 }
703}
704
e9174d1e
SL
705impl fmt::Debug for ty::TyVid {
706 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
707 write!(f, "_#{}t", self.index)
708 }
709}
710
711impl fmt::Debug for ty::IntVid {
712 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
713 write!(f, "_#{}i", self.index)
714 }
715}
716
717impl fmt::Debug for ty::FloatVid {
718 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
719 write!(f, "_#{}f", self.index)
720 }
721}
722
723impl fmt::Debug for ty::RegionVid {
724 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
725 write!(f, "'_#{}r", self.index)
726 }
727}
728
729impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
730 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
731 write!(f, "({:?}; variadic: {})->{:?}", self.inputs, self.variadic, self.output)
732 }
733}
734
735impl fmt::Debug for ty::InferTy {
736 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
737 match *self {
738 ty::TyVar(ref v) => v.fmt(f),
739 ty::IntVar(ref v) => v.fmt(f),
740 ty::FloatVar(ref v) => v.fmt(f),
741 ty::FreshTy(v) => write!(f, "FreshTy({:?})", v),
742 ty::FreshIntTy(v) => write!(f, "FreshIntTy({:?})", v),
743 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({:?})", v)
744 }
745 }
746}
747
748impl fmt::Debug for ty::IntVarValue {
749 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
750 match *self {
751 ty::IntType(ref v) => v.fmt(f),
752 ty::UintType(ref v) => v.fmt(f),
753 }
754 }
755}
756
62682a34
SL
757// The generic impl doesn't work yet because projections are not
758// normalized under HRTB.
759/*impl<T> fmt::Display for ty::Binder<T>
760 where T: fmt::Display + for<'a> ty::Lift<'a>,
761 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
762{
763 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
764 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc 765 }
62682a34 766}*/
1a4d82fc 767
62682a34
SL
768impl<'tcx> fmt::Display for ty::Binder<ty::TraitRef<'tcx>> {
769 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
770 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
771 }
772}
773
62682a34
SL
774impl<'tcx> fmt::Display for ty::Binder<ty::TraitPredicate<'tcx>> {
775 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
776 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
777 }
778}
779
62682a34
SL
780impl<'tcx> fmt::Display for ty::Binder<ty::EquatePredicate<'tcx>> {
781 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
782 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
783 }
784}
785
62682a34
SL
786impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
787 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
788 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
789 }
790}
791
62682a34
SL
792impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region>> {
793 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
794 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
795 }
796}
797
62682a34
SL
798impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>> {
799 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
800 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
801 }
802}
803
62682a34
SL
804impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
805 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54a0048b 806 parameterized(f, self.substs, self.def_id, Ns::Type, &[],
c1a9b12d 807 |tcx| tcx.lookup_trait_def(self.def_id).generics.clone())
1a4d82fc
JJ
808 }
809}
810
62682a34
SL
811impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
812 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85aaf69f 813 match *self {
62682a34
SL
814 TyBool => write!(f, "bool"),
815 TyChar => write!(f, "char"),
9cc50fc6
SL
816 TyInt(t) => write!(f, "{}", t.ty_to_string()),
817 TyUint(t) => write!(f, "{}", t.ty_to_string()),
818 TyFloat(t) => write!(f, "{}", t.ty_to_string()),
62682a34
SL
819 TyBox(typ) => write!(f, "Box<{}>", typ),
820 TyRawPtr(ref tm) => {
821 write!(f, "*{} {}", match tm.mutbl {
b039eaaf
SL
822 hir::MutMutable => "mut",
823 hir::MutImmutable => "const",
62682a34
SL
824 }, tm.ty)
825 }
826 TyRef(r, ref tm) => {
54a0048b 827 write!(f, "&")?;
62682a34 828 let s = r.to_string();
54a0048b 829 write!(f, "{}", s)?;
62682a34 830 if !s.is_empty() {
54a0048b 831 write!(f, " ")?;
62682a34
SL
832 }
833 write!(f, "{}", tm)
834 }
835 TyTuple(ref tys) => {
54a0048b 836 write!(f, "(")?;
62682a34
SL
837 let mut tys = tys.iter();
838 if let Some(&ty) = tys.next() {
54a0048b 839 write!(f, "{},", ty)?;
62682a34 840 if let Some(&ty) = tys.next() {
54a0048b 841 write!(f, " {}", ty)?;
62682a34 842 for &ty in tys {
54a0048b 843 write!(f, ", {}", ty)?;
62682a34
SL
844 }
845 }
846 }
847 write!(f, ")")
848 }
54a0048b 849 TyFnDef(def_id, substs, ref bare_fn) => {
b039eaaf 850 if bare_fn.unsafety == hir::Unsafety::Unsafe {
54a0048b 851 write!(f, "unsafe ")?;
62682a34 852 }
1a4d82fc 853
7453a54e 854 if bare_fn.abi != Abi::Rust {
54a0048b 855 write!(f, "extern {} ", bare_fn.abi)?;
62682a34 856 }
1a4d82fc 857
54a0048b
SL
858 write!(f, "{} {{", bare_fn.sig.0)?;
859 parameterized(f, substs, def_id, Ns::Value, &[],
860 |tcx| tcx.lookup_item_type(def_id).generics)?;
861 write!(f, "}}")
862 }
863 TyFnPtr(ref bare_fn) => {
864 if bare_fn.unsafety == hir::Unsafety::Unsafe {
865 write!(f, "unsafe ")?;
866 }
1a4d82fc 867
54a0048b
SL
868 if bare_fn.abi != Abi::Rust {
869 write!(f, "extern {} ", bare_fn.abi)?;
62682a34 870 }
54a0048b
SL
871
872 write!(f, "{}", bare_fn.sig.0)
62682a34
SL
873 }
874 TyInfer(infer_ty) => write!(f, "{}", infer_ty),
875 TyError => write!(f, "[type error]"),
876 TyParam(ref param_ty) => write!(f, "{}", param_ty),
e9174d1e 877 TyEnum(def, substs) | TyStruct(def, substs) => {
c1a9b12d 878 ty::tls::with(|tcx| {
e9174d1e
SL
879 if def.did.is_local() &&
880 !tcx.tcache.borrow().contains_key(&def.did) {
881 write!(f, "{}<..>", tcx.item_path_str(def.did))
c1a9b12d 882 } else {
54a0048b 883 parameterized(f, substs, def.did, Ns::Type, &[],
e9174d1e 884 |tcx| tcx.lookup_item_type(def.did).generics)
c1a9b12d
SL
885 }
886 })
62682a34
SL
887 }
888 TyTrait(ref data) => write!(f, "{}", data),
889 ty::TyProjection(ref data) => write!(f, "{}", data),
890 TyStr => write!(f, "str"),
b039eaaf 891 TyClosure(did, ref substs) => ty::tls::with(|tcx| {
54a0048b 892 write!(f, "[closure")?;
c1a9b12d 893
b039eaaf 894 if let Some(node_id) = tcx.map.as_local_node_id(did) {
54a0048b 895 write!(f, "@{:?}", tcx.map.span(node_id))?;
c1a9b12d 896 let mut sep = " ";
54a0048b 897 tcx.with_freevars(node_id, |freevars| {
c1a9b12d 898 for (freevar, upvar_ty) in freevars.iter().zip(&substs.upvar_tys) {
b039eaaf 899 let node_id = freevar.def.var_id();
54a0048b 900 write!(f,
c1a9b12d
SL
901 "{}{}:{}",
902 sep,
903 tcx.local_var_name_str(node_id),
54a0048b 904 upvar_ty)?;
c1a9b12d
SL
905 sep = ", ";
906 }
907 Ok(())
54a0048b 908 })?
c1a9b12d
SL
909 } else {
910 // cross-crate closure types should only be
911 // visible in trans bug reports, I imagine.
54a0048b 912 write!(f, "@{:?}", did)?;
c1a9b12d
SL
913 let mut sep = " ";
914 for (index, upvar_ty) in substs.upvar_tys.iter().enumerate() {
54a0048b 915 write!(f, "{}{}:{}", sep, index, upvar_ty)?;
c1a9b12d 916 sep = ", ";
62682a34 917 }
62682a34 918 }
c1a9b12d 919
62682a34
SL
920 write!(f, "]")
921 }),
922 TyArray(ty, sz) => write!(f, "[{}; {}]", ty, sz),
923 TySlice(ty) => write!(f, "[{}]", ty)
924 }
1a4d82fc
JJ
925 }
926}
927
62682a34
SL
928impl<'tcx> fmt::Display for ty::TyS<'tcx> {
929 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
930 write!(f, "{}", self.sty)
1a4d82fc
JJ
931 }
932}
933
62682a34
SL
934impl fmt::Debug for ty::UpvarId {
935 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
936 write!(f, "UpvarId({};`{}`;{})",
937 self.var_id,
c1a9b12d 938 ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)),
62682a34 939 self.closure_expr_id)
1a4d82fc
JJ
940 }
941}
942
62682a34
SL
943impl fmt::Debug for ty::UpvarBorrow {
944 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
945 write!(f, "UpvarBorrow({:?}, {:?})",
946 self.kind, self.region)
1a4d82fc
JJ
947 }
948}
949
62682a34
SL
950impl fmt::Display for ty::InferTy {
951 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
952 let print_var_ids = verbose();
953 match *self {
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)
961 }
1a4d82fc
JJ
962 }
963}
964
62682a34
SL
965impl fmt::Display for ty::ExplicitSelfCategory {
966 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
967 f.write_str(match *self {
9cc50fc6
SL
968 ty::ExplicitSelfCategory::Static => "static",
969 ty::ExplicitSelfCategory::ByValue => "self",
970 ty::ExplicitSelfCategory::ByReference(_, hir::MutMutable) => {
62682a34
SL
971 "&mut self"
972 }
9cc50fc6
SL
973 ty::ExplicitSelfCategory::ByReference(_, hir::MutImmutable) => "&self",
974 ty::ExplicitSelfCategory::ByBox => "Box<self>",
62682a34 975 })
1a4d82fc
JJ
976 }
977}
978
62682a34
SL
979impl fmt::Display for ty::ParamTy {
980 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
981 write!(f, "{}", self.name)
85aaf69f
SL
982 }
983}
984
62682a34
SL
985impl fmt::Debug for ty::ParamTy {
986 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
987 write!(f, "{}/{:?}.{}", self, self.space, self.idx)
1a4d82fc
JJ
988 }
989}
990
62682a34
SL
991impl<'tcx, T, U> fmt::Display for ty::OutlivesPredicate<T,U>
992 where T: fmt::Display, U: fmt::Display
1a4d82fc 993{
62682a34
SL
994 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
995 write!(f, "{} : {}", self.0, self.1)
1a4d82fc
JJ
996 }
997}
998
62682a34
SL
999impl<'tcx> fmt::Display for ty::EquatePredicate<'tcx> {
1000 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1001 write!(f, "{} == {}", self.0, self.1)
1a4d82fc
JJ
1002 }
1003}
1004
62682a34
SL
1005impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
1006 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1007 write!(f, "TraitPredicate({:?})",
1008 self.trait_ref)
1a4d82fc
JJ
1009 }
1010}
1011
62682a34
SL
1012impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> {
1013 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54a0048b 1014 write!(f, "{}: {}", self.trait_ref.self_ty(), self.trait_ref)
1a4d82fc
JJ
1015 }
1016}
1017
62682a34
SL
1018impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
1019 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1020 write!(f, "ProjectionPredicate({:?}, {:?})",
1021 self.projection_ty,
1022 self.ty)
1a4d82fc
JJ
1023 }
1024}
1025
62682a34
SL
1026impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> {
1027 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1028 write!(f, "{} == {}",
1029 self.projection_ty,
1030 self.ty)
1a4d82fc
JJ
1031 }
1032}
1033
62682a34
SL
1034impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> {
1035 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1036 write!(f, "{:?}::{}",
1037 self.trait_ref,
1038 self.item_name)
1a4d82fc
JJ
1039 }
1040}
1041
62682a34
SL
1042impl<'tcx> fmt::Display for ty::Predicate<'tcx> {
1043 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc 1044 match *self {
62682a34
SL
1045 ty::Predicate::Trait(ref data) => write!(f, "{}", data),
1046 ty::Predicate::Equate(ref predicate) => write!(f, "{}", predicate),
1047 ty::Predicate::RegionOutlives(ref predicate) => write!(f, "{}", predicate),
1048 ty::Predicate::TypeOutlives(ref predicate) => write!(f, "{}", predicate),
1049 ty::Predicate::Projection(ref predicate) => write!(f, "{}", predicate),
e9174d1e
SL
1050 ty::Predicate::WellFormed(ty) => write!(f, "{} well-formed", ty),
1051 ty::Predicate::ObjectSafe(trait_def_id) =>
1052 ty::tls::with(|tcx| {
1053 write!(f, "the trait `{}` is object-safe", tcx.item_path_str(trait_def_id))
1054 }),
1a4d82fc 1055 }
970d7e83
LB
1056 }
1057}