]> git.proxmox.com Git - rustc.git/blame - src/librustc/util/ppaux.rs
Imported Upstream version 1.2.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
62682a34 12use middle::subst::{self, Subst};
1a4d82fc
JJ
13use middle::ty::{BoundRegion, BrAnon, BrNamed};
14use middle::ty::{ReEarlyBound, BrFresh, ctxt};
15use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty};
16use middle::ty::{ReSkolemized, ReVar, BrEnv};
62682a34
SL
17use middle::ty::{mt, Ty};
18use middle::ty::{TyBool, TyChar, TyStruct, TyEnum};
19use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyBareFn};
20use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple};
21use middle::ty::TyClosure;
22use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
970d7e83 23use middle::ty;
62682a34 24use middle::ty_fold::{self, TypeFoldable};
1a4d82fc 25
62682a34 26use std::fmt;
1a4d82fc 27use syntax::abi;
970d7e83 28use syntax::parse::token;
223e47cc 29use syntax::{ast, ast_util};
223e47cc 30
62682a34
SL
31pub fn verbose() -> bool {
32 ty::tls::with(|tcx| tcx.sess.verbose())
970d7e83
LB
33}
34
62682a34
SL
35fn fn_sig(f: &mut fmt::Formatter,
36 inputs: &[Ty],
37 variadic: bool,
38 output: ty::FnOutput)
39 -> fmt::Result {
40 try!(write!(f, "("));
41 let mut inputs = inputs.iter();
42 if let Some(&ty) = inputs.next() {
43 try!(write!(f, "{}", ty));
44 for &ty in inputs {
45 try!(write!(f, ", {}", ty));
970d7e83 46 }
62682a34
SL
47 if variadic {
48 try!(write!(f, ", ..."));
1a4d82fc
JJ
49 }
50 }
62682a34 51 try!(write!(f, ")"));
223e47cc 52
62682a34
SL
53 match output {
54 ty::FnConverging(ty) => {
55 if !ty::type_is_nil(ty) {
56 try!(write!(f, " -> {}", ty));
1a4d82fc 57 }
62682a34 58 Ok(())
1a4d82fc 59 }
62682a34
SL
60 ty::FnDiverging => {
61 write!(f, " -> !")
1a4d82fc
JJ
62 }
63 }
64}
970d7e83 65
62682a34
SL
66fn parameterized<GG>(f: &mut fmt::Formatter,
67 substs: &subst::Substs,
68 did: ast::DefId,
69 projections: &[ty::ProjectionPredicate],
70 get_generics: GG)
71 -> fmt::Result
72 where GG: for<'tcx> FnOnce(&ty::ctxt<'tcx>) -> ty::Generics<'tcx>
73{
74 let (fn_trait_kind, verbose) = try!(ty::tls::with(|tcx| {
75 try!(write!(f, "{}", ty::item_path_str(tcx, did)));
76 Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose()))
77 }));
78
79 let mut empty = true;
80 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
81 if empty {
82 empty = false;
83 write!(f, "{}", start)
84 } else {
85 write!(f, "{}", cont)
1a4d82fc 86 }
62682a34 87 };
223e47cc 88
62682a34 89 if verbose {
85aaf69f
SL
90 match substs.regions {
91 subst::ErasedRegions => {
62682a34
SL
92 try!(start_or_continue(f, "<", ", "));
93 try!(write!(f, ".."));
85aaf69f
SL
94 }
95 subst::NonerasedRegions(ref regions) => {
62682a34
SL
96 for region in regions {
97 try!(start_or_continue(f, "<", ", "));
98 try!(write!(f, "{:?}", region));
85aaf69f
SL
99 }
100 }
101 }
62682a34
SL
102 for &ty in &substs.types {
103 try!(start_or_continue(f, "<", ", "));
104 try!(write!(f, "{}", ty));
1a4d82fc 105 }
62682a34
SL
106 for projection in projections {
107 try!(start_or_continue(f, "<", ", "));
108 try!(write!(f, "{}={}",
109 projection.projection_ty.item_name,
110 projection.ty));
85aaf69f 111 }
62682a34 112 return start_or_continue(f, "", ">");
1a4d82fc 113 }
223e47cc 114
62682a34
SL
115 if fn_trait_kind.is_some() && projections.len() == 1 {
116 let projection_ty = projections[0].ty;
117 if let TyTuple(ref args) = substs.types.get_slice(subst::TypeSpace)[0].sty {
118 return fn_sig(f, args, false, ty::FnConverging(projection_ty));
119 }
120 }
1a4d82fc
JJ
121
122 match substs.regions {
123 subst::ErasedRegions => { }
124 subst::NonerasedRegions(ref regions) => {
62682a34
SL
125 for &r in regions {
126 try!(start_or_continue(f, "<", ", "));
127 let s = r.to_string();
1a4d82fc
JJ
128 if s.is_empty() {
129 // This happens when the value of the region
130 // parameter is not easily serialized. This may be
131 // because the user omitted it in the first place,
132 // or because it refers to some block in the code,
133 // etc. I'm not sure how best to serialize this.
62682a34 134 try!(write!(f, "'_"));
1a4d82fc 135 } else {
62682a34 136 try!(write!(f, "{}", s));
1a4d82fc
JJ
137 }
138 }
970d7e83 139 }
1a4d82fc
JJ
140 }
141
85aaf69f
SL
142 // It is important to execute this conditionally, only if -Z
143 // verbose is false. Otherwise, debug logs can sometimes cause
144 // ICEs trying to fetch the generics early in the pipeline. This
145 // is kind of a hacky workaround in that -Z verbose is required to
146 // avoid those ICEs.
1a4d82fc 147 let tps = substs.types.get_slice(subst::TypeSpace);
62682a34
SL
148 let num_defaults = ty::tls::with(|tcx| {
149 let generics = get_generics(tcx);
150
151 let has_self = substs.self_ty().is_some();
152 let ty_params = generics.types.get_slice(subst::TypeSpace);
153 if ty_params.last().map_or(false, |def| def.default.is_some()) {
154 let substs = tcx.lift(&substs);
155 ty_params.iter().zip(tps).rev().take_while(|&(def, &actual)| {
156 match def.default {
157 Some(default) => {
158 if !has_self && ty::type_has_self(default) {
159 // In an object type, there is no `Self`, and
160 // thus if the default value references Self,
161 // the user will be required to give an
162 // explicit value. We can't even do the
163 // substitution below to check without causing
164 // an ICE. (#18956).
165 false
166 } else {
167 let default = tcx.lift(&default);
168 substs.and_then(|substs| default.subst(tcx, substs)) == Some(actual)
169 }
85aaf69f 170 }
62682a34 171 None => false
85aaf69f 172 }
62682a34
SL
173 }).count()
174 } else {
175 0
176 }
177 });
223e47cc 178
62682a34
SL
179 for &ty in &tps[..tps.len() - num_defaults] {
180 try!(start_or_continue(f, "<", ", "));
181 try!(write!(f, "{}", ty));
970d7e83
LB
182 }
183
85aaf69f 184 for projection in projections {
62682a34
SL
185 try!(start_or_continue(f, "<", ", "));
186 try!(write!(f, "{}={}",
187 projection.projection_ty.item_name,
188 projection.ty));
223e47cc 189 }
223e47cc 190
62682a34 191 start_or_continue(f, "", ">")
223e47cc
LB
192}
193
62682a34
SL
194fn in_binder<'tcx, T, U>(f: &mut fmt::Formatter,
195 tcx: &ty::ctxt<'tcx>,
196 original: &ty::Binder<T>,
197 lifted: Option<ty::Binder<U>>) -> fmt::Result
198 where T: fmt::Display, U: fmt::Display + TypeFoldable<'tcx>
199{
200 // Replace any anonymous late-bound regions with named
201 // variants, using gensym'd identifiers, so that we can
202 // clearly differentiate between named and unnamed regions in
203 // the output. We'll probably want to tweak this over time to
204 // decide just how much information to give.
205 let value = if let Some(v) = lifted {
206 v
207 } else {
208 return write!(f, "{}", original.0);
209 };
1a4d82fc 210
62682a34
SL
211 let mut empty = true;
212 let mut start_or_continue = |f: &mut fmt::Formatter, start: &str, cont: &str| {
213 if empty {
214 empty = false;
215 write!(f, "{}", start)
216 } else {
217 write!(f, "{}", cont)
970d7e83 218 }
62682a34 219 };
1a4d82fc 220
62682a34
SL
221 let new_value = ty_fold::replace_late_bound_regions(tcx, &value, |br| {
222 let _ = start_or_continue(f, "for<", ", ");
223 ty::ReLateBound(ty::DebruijnIndex::new(1), match br {
224 ty::BrNamed(_, name) => {
225 let _ = write!(f, "{}", name);
226 br
227 }
228 ty::BrAnon(_) |
229 ty::BrFresh(_) |
230 ty::BrEnv => {
231 let name = token::intern("'r");
232 let _ = write!(f, "{}", name);
233 ty::BrNamed(ast_util::local_def(ast::DUMMY_NODE_ID), name)
234 }
235 })
236 }).0;
1a4d82fc 237
62682a34
SL
238 try!(start_or_continue(f, "", "> "));
239 write!(f, "{}", new_value)
1a4d82fc
JJ
240}
241
85aaf69f
SL
242/// This curious type is here to help pretty-print trait objects. In
243/// a trait object, the projections are stored separately from the
244/// main trait bound, but in fact we want to package them together
245/// when printing out; they also have separate binders, but we want
246/// them to share a binder when we print them out. (And the binder
247/// pretty-printing logic is kind of clever and we don't want to
248/// reproduce it.) So we just repackage up the structure somewhat.
249///
250/// Right now there is only one trait in an object that can have
251/// projection bounds, so we just stuff them altogether. But in
252/// reality we should eventually sort things out better.
62682a34
SL
253#[derive(Clone, Debug)]
254struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>, Vec<ty::ProjectionPredicate<'tcx>>);
255
256impl<'tcx> TypeFoldable<'tcx> for TraitAndProjections<'tcx> {
257 fn fold_with<F:ty_fold::TypeFolder<'tcx>>(&self, folder: &mut F)
258 -> TraitAndProjections<'tcx> {
259 TraitAndProjections(self.0.fold_with(folder), self.1.fold_with(folder))
85aaf69f
SL
260 }
261}
262
62682a34
SL
263impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
264 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
265 let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
266 parameterized(f, trait_ref.substs,
267 trait_ref.def_id,
268 projection_bounds,
269 |tcx| ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone())
270 }
271}
85aaf69f 272
62682a34
SL
273impl<'tcx> fmt::Display for ty::TraitTy<'tcx> {
274 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
275 let bounds = &self.bounds;
85aaf69f
SL
276
277 // Generate the main trait ref, including associated types.
62682a34
SL
278 try!(ty::tls::with(|tcx| {
279 let principal = tcx.lift(&self.principal.0)
280 .expect("could not lift TraitRef for printing");
281 let projections = tcx.lift(&bounds.projection_bounds[..])
282 .expect("could not lift projections for printing");
283 let projections = projections.map_in_place(|p| p.0);
284
285 let tap = ty::Binder(TraitAndProjections(principal, projections));
286 in_binder(f, tcx, &ty::Binder(""), Some(tap))
287 }));
85aaf69f
SL
288
289 // Builtin bounds.
290 for bound in &bounds.builtin_bounds {
62682a34 291 try!(write!(f, " + {:?}", bound));
85aaf69f
SL
292 }
293
62682a34
SL
294 // FIXME: It'd be nice to compute from context when this bound
295 // is implied, but that's non-trivial -- we'd perhaps have to
296 // use thread-local data of some kind? There are also
297 // advantages to just showing the region, since it makes
298 // people aware that it's there.
299 let bound = bounds.region_bound.to_string();
300 if !bound.is_empty() {
301 try!(write!(f, " + {}", bound));
85aaf69f
SL
302 }
303
62682a34
SL
304 if bounds.region_bound_will_change && verbose() {
305 try!(write!(f, " [WILL-CHANGE]"));
306 }
1a4d82fc 307
62682a34 308 Ok(())
1a4d82fc
JJ
309 }
310}
311
62682a34
SL
312impl<'tcx> fmt::Debug for ty::TypeParameterDef<'tcx> {
313 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
314 write!(f, "TypeParameterDef({:?}, {:?}/{})",
315 self.def_id, self.space, self.index)
1a4d82fc
JJ
316 }
317}
318
62682a34
SL
319impl<'tcx> fmt::Debug for ty::TyS<'tcx> {
320 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
321 write!(f, "{}", *self)
1a4d82fc
JJ
322 }
323}
324
62682a34
SL
325impl<'tcx> fmt::Display for ty::mt<'tcx> {
326 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
327 write!(f, "{}{}",
328 if self.mutbl == ast::MutMutable { "mut " } else { "" },
329 self.ty)
970d7e83
LB
330 }
331}
332
62682a34
SL
333impl<'tcx> fmt::Debug for subst::Substs<'tcx> {
334 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
335 write!(f, "Substs[types={:?}, regions={:?}]",
336 self.types, self.regions)
970d7e83
LB
337 }
338}
339
62682a34
SL
340impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
341 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
342 write!(f, "ItemSubsts({:?})", self.substs)
970d7e83
LB
343 }
344}
345
62682a34
SL
346impl fmt::Debug for subst::RegionSubsts {
347 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc 348 match *self {
62682a34
SL
349 subst::ErasedRegions => write!(f, "erased"),
350 subst::NonerasedRegions(ref regions) => write!(f, "{:?}", regions)
970d7e83 351 }
970d7e83
LB
352 }
353}
354
62682a34
SL
355impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
356 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc
JJ
357 // when printing out the debug representation, we don't need
358 // to enumerate the `for<...>` etc because the debruijn index
359 // tells you everything you need to know.
d9579d0f 360 match self.substs.self_ty() {
62682a34
SL
361 None => write!(f, "{}", *self),
362 Some(self_ty) => write!(f, "<{:?} as {}>", self_ty, *self)
d9579d0f 363 }
1a4d82fc
JJ
364 }
365}
366
62682a34
SL
367impl<'tcx> fmt::Debug for ty::TraitDef<'tcx> {
368 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
369 write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
370 self.generics, self.trait_ref)
1a4d82fc
JJ
371 }
372}
373
62682a34
SL
374impl fmt::Display for ty::BoundRegion {
375 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
376 if verbose() {
377 return write!(f, "{:?}", *self);
378 }
970d7e83 379
1a4d82fc 380 match *self {
62682a34
SL
381 BrNamed(_, name) => write!(f, "{}", name),
382 BrAnon(_) | BrFresh(_) | BrEnv => Ok(())
1a4d82fc
JJ
383 }
384 }
385}
386
62682a34
SL
387impl fmt::Debug for ty::Region {
388 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc 389 match *self {
9346a6ac 390 ty::ReEarlyBound(ref data) => {
62682a34
SL
391 write!(f, "ReEarlyBound({}, {:?}, {}, {})",
392 data.param_id,
393 data.space,
394 data.index,
395 data.name)
1a4d82fc
JJ
396 }
397
398 ty::ReLateBound(binder_id, ref bound_region) => {
62682a34
SL
399 write!(f, "ReLateBound({:?}, {:?})",
400 binder_id,
401 bound_region)
1a4d82fc
JJ
402 }
403
62682a34 404 ty::ReFree(ref fr) => write!(f, "{:?}", fr),
1a4d82fc
JJ
405
406 ty::ReScope(id) => {
62682a34 407 write!(f, "ReScope({:?})", id)
1a4d82fc
JJ
408 }
409
62682a34 410 ty::ReStatic => write!(f, "ReStatic"),
1a4d82fc
JJ
411
412 ty::ReInfer(ReVar(ref vid)) => {
62682a34 413 write!(f, "{:?}", vid)
1a4d82fc
JJ
414 }
415
416 ty::ReInfer(ReSkolemized(id, ref bound_region)) => {
62682a34 417 write!(f, "ReSkolemized({}, {:?})", id, bound_region)
1a4d82fc
JJ
418 }
419
62682a34 420 ty::ReEmpty => write!(f, "ReEmpty")
1a4d82fc
JJ
421 }
422 }
423}
424
62682a34
SL
425impl fmt::Display for ty::Region {
426 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
427 if verbose() {
428 return write!(f, "{:?}", *self);
85aaf69f 429 }
85aaf69f 430
62682a34
SL
431 // These printouts are concise. They do not contain all the information
432 // the user might want to diagnose an error, but there is basically no way
433 // to fit that into a short string. Hence the recommendation to use
434 // `explain_region()` or `note_and_explain_region()`.
85aaf69f 435 match *self {
62682a34
SL
436 ty::ReEarlyBound(ref data) => {
437 write!(f, "{}", data.name)
438 }
439 ty::ReLateBound(_, br) |
440 ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
441 ty::ReInfer(ReSkolemized(_, br)) => {
442 write!(f, "{}", br)
970d7e83 443 }
62682a34
SL
444 ty::ReScope(_) |
445 ty::ReInfer(ReVar(_)) => Ok(()),
446 ty::ReStatic => write!(f, "'static"),
447 ty::ReEmpty => write!(f, "'<empty>"),
970d7e83 448 }
970d7e83
LB
449 }
450}
451
62682a34
SL
452impl fmt::Debug for ty::FreeRegion {
453 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
454 write!(f, "ReFree({:?}, {:?})",
455 self.scope, self.bound_region)
970d7e83
LB
456 }
457}
458
62682a34
SL
459impl fmt::Debug for ty::ItemVariances {
460 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
461 write!(f, "ItemVariances(types={:?}, regions={:?})",
462 self.types, self.regions)
970d7e83
LB
463 }
464}
465
62682a34
SL
466impl<'tcx> fmt::Debug for ty::GenericPredicates<'tcx> {
467 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
468 write!(f, "GenericPredicates({:?})", self.predicates)
970d7e83
LB
469 }
470}
471
62682a34
SL
472impl<'tcx> fmt::Debug for ty::InstantiatedPredicates<'tcx> {
473 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
474 write!(f, "InstantiatedPredicates({:?})",
475 self.predicates)
970d7e83
LB
476 }
477}
478
62682a34
SL
479impl<'tcx> fmt::Debug for ty::ImplOrTraitItem<'tcx> {
480 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
481 try!(write!(f, "ImplOrTraitItem("));
482 try!(match *self {
483 ty::ImplOrTraitItem::MethodTraitItem(ref i) => write!(f, "{:?}", i),
484 ty::ImplOrTraitItem::ConstTraitItem(ref i) => write!(f, "{:?}", i),
485 ty::ImplOrTraitItem::TypeTraitItem(ref i) => write!(f, "{:?}", i),
486 });
487 write!(f, ")")
970d7e83
LB
488 }
489}
490
62682a34
SL
491impl<'tcx> fmt::Display for ty::FnSig<'tcx> {
492 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
493 try!(write!(f, "fn"));
494 fn_sig(f, &self.inputs, self.variadic, self.output)
970d7e83
LB
495 }
496}
497
62682a34
SL
498impl<'tcx> fmt::Debug for ty::MethodOrigin<'tcx> {
499 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc 500 match *self {
62682a34
SL
501 ty::MethodStatic(def_id) => {
502 write!(f, "MethodStatic({:?})", def_id)
970d7e83 503 }
62682a34
SL
504 ty::MethodStaticClosure(def_id) => {
505 write!(f, "MethodStaticClosure({:?})", def_id)
970d7e83 506 }
62682a34
SL
507 ty::MethodTypeParam(ref p) => write!(f, "{:?}", p),
508 ty::MethodTraitObject(ref p) => write!(f, "{:?}", p)
970d7e83
LB
509 }
510 }
511}
512
62682a34
SL
513impl<'tcx> fmt::Debug for ty::MethodParam<'tcx> {
514 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
515 write!(f, "MethodParam({:?},{})",
516 self.trait_ref,
517 self.method_num)
970d7e83
LB
518 }
519}
520
62682a34
SL
521impl<'tcx> fmt::Debug for ty::MethodObject<'tcx> {
522 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
523 write!(f, "MethodObject({:?},{},{})",
524 self.trait_ref,
525 self.method_num,
526 self.vtable_index)
970d7e83
LB
527 }
528}
529
62682a34
SL
530impl<'tcx> fmt::Debug for ty::ExistentialBounds<'tcx> {
531 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
532 let mut empty = true;
533 let mut maybe_continue = |f: &mut fmt::Formatter| {
534 if empty {
535 empty = false;
536 Ok(())
537 } else {
538 write!(f, " + ")
539 }
540 };
1a4d82fc 541
62682a34 542 let region_str = format!("{:?}", self.region_bound);
1a4d82fc 543 if !region_str.is_empty() {
62682a34
SL
544 try!(maybe_continue(f));
545 try!(write!(f, "{}", region_str));
1a4d82fc
JJ
546 }
547
85aaf69f 548 for bound in &self.builtin_bounds {
62682a34
SL
549 try!(maybe_continue(f));
550 try!(write!(f, "{:?}", bound));
970d7e83 551 }
1a4d82fc 552
85aaf69f 553 for projection_bound in &self.projection_bounds {
62682a34
SL
554 try!(maybe_continue(f));
555 try!(write!(f, "{:?}", projection_bound));
85aaf69f
SL
556 }
557
62682a34 558 Ok(())
1a4d82fc
JJ
559 }
560}
561
62682a34
SL
562impl fmt::Display for ty::BuiltinBounds {
563 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
564 let mut bounds = self.iter();
565 if let Some(bound) = bounds.next() {
566 try!(write!(f, "{:?}", bound));
567 for bound in bounds {
568 try!(write!(f, " + {:?}", bound));
569 }
970d7e83 570 }
62682a34 571 Ok(())
970d7e83
LB
572 }
573}
574
62682a34
SL
575// The generic impl doesn't work yet because projections are not
576// normalized under HRTB.
577/*impl<T> fmt::Display for ty::Binder<T>
578 where T: fmt::Display + for<'a> ty::Lift<'a>,
579 for<'a> <T as ty::Lift<'a>>::Lifted: fmt::Display + TypeFoldable<'a>
580{
581 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
582 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc 583 }
62682a34 584}*/
1a4d82fc 585
62682a34
SL
586impl<'tcx> fmt::Display for ty::Binder<ty::TraitRef<'tcx>> {
587 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
588 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
589 }
590}
591
62682a34
SL
592impl<'tcx> fmt::Display for ty::Binder<ty::TraitPredicate<'tcx>> {
593 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
594 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
595 }
596}
597
62682a34
SL
598impl<'tcx> fmt::Display for ty::Binder<ty::EquatePredicate<'tcx>> {
599 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
600 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
601 }
602}
603
62682a34
SL
604impl<'tcx> fmt::Display for ty::Binder<ty::ProjectionPredicate<'tcx>> {
605 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
606 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
607 }
608}
609
62682a34
SL
610impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region>> {
611 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
612 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
613 }
614}
615
62682a34
SL
616impl fmt::Display for ty::Binder<ty::OutlivesPredicate<ty::Region, ty::Region>> {
617 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
618 ty::tls::with(|tcx| in_binder(f, tcx, self, tcx.lift(self)))
1a4d82fc
JJ
619 }
620}
621
62682a34
SL
622impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
623 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
624 parameterized(f, self.substs, self.def_id, &[],
625 |tcx| ty::lookup_trait_def(tcx, self.def_id).generics.clone())
1a4d82fc
JJ
626 }
627}
628
62682a34
SL
629impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
630 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85aaf69f 631 match *self {
62682a34
SL
632 TyBool => write!(f, "bool"),
633 TyChar => write!(f, "char"),
634 TyInt(t) => write!(f, "{}", ast_util::int_ty_to_string(t, None)),
635 TyUint(t) => write!(f, "{}", ast_util::uint_ty_to_string(t, None)),
636 TyFloat(t) => write!(f, "{}", ast_util::float_ty_to_string(t)),
637 TyBox(typ) => write!(f, "Box<{}>", typ),
638 TyRawPtr(ref tm) => {
639 write!(f, "*{} {}", match tm.mutbl {
640 ast::MutMutable => "mut",
641 ast::MutImmutable => "const",
642 }, tm.ty)
643 }
644 TyRef(r, ref tm) => {
645 try!(write!(f, "&"));
646 let s = r.to_string();
647 try!(write!(f, "{}", s));
648 if !s.is_empty() {
649 try!(write!(f, " "));
650 }
651 write!(f, "{}", tm)
652 }
653 TyTuple(ref tys) => {
654 try!(write!(f, "("));
655 let mut tys = tys.iter();
656 if let Some(&ty) = tys.next() {
657 try!(write!(f, "{},", ty));
658 if let Some(&ty) = tys.next() {
659 try!(write!(f, " {}", ty));
660 for &ty in tys {
661 try!(write!(f, ", {}", ty));
662 }
663 }
664 }
665 write!(f, ")")
666 }
667 TyBareFn(opt_def_id, ref bare_fn) => {
668 if bare_fn.unsafety == ast::Unsafety::Unsafe {
669 try!(write!(f, "unsafe "));
670 }
1a4d82fc 671
62682a34
SL
672 if bare_fn.abi != abi::Rust {
673 try!(write!(f, "extern {} ", bare_fn.abi));
674 }
1a4d82fc 675
62682a34 676 try!(write!(f, "{}", bare_fn.sig.0));
1a4d82fc 677
62682a34
SL
678 if let Some(def_id) = opt_def_id {
679 try!(write!(f, " {{{}}}", ty::tls::with(|tcx| {
680 ty::item_path_str(tcx, def_id)
681 })));
682 }
683 Ok(())
684 }
685 TyInfer(infer_ty) => write!(f, "{}", infer_ty),
686 TyError => write!(f, "[type error]"),
687 TyParam(ref param_ty) => write!(f, "{}", param_ty),
688 TyEnum(did, substs) | TyStruct(did, substs) => {
689 parameterized(f, substs, did, &[],
690 |tcx| ty::lookup_item_type(tcx, did).generics)
691 }
692 TyTrait(ref data) => write!(f, "{}", data),
693 ty::TyProjection(ref data) => write!(f, "{}", data),
694 TyStr => write!(f, "str"),
695 TyClosure(ref did, substs) => ty::tls::with(|tcx| {
696 try!(write!(f, "[closure"));
697 let closure_tys = tcx.closure_tys.borrow();
698 try!(closure_tys.get(did).map(|cty| &cty.sig).and_then(|sig| {
699 tcx.lift(&substs).map(|substs| sig.subst(tcx, substs))
700 }).map(|sig| {
701 fn_sig(f, &sig.0.inputs, false, sig.0.output)
702 }).unwrap_or_else(|| {
703 if did.krate == ast::LOCAL_CRATE {
704 try!(write!(f, " {:?}", tcx.map.span(did.node)));
705 }
706 Ok(())
707 }));
708 if verbose() {
709 try!(write!(f, " id={:?}", did));
710 }
711 write!(f, "]")
712 }),
713 TyArray(ty, sz) => write!(f, "[{}; {}]", ty, sz),
714 TySlice(ty) => write!(f, "[{}]", ty)
715 }
1a4d82fc
JJ
716 }
717}
718
62682a34
SL
719impl<'tcx> fmt::Display for ty::TyS<'tcx> {
720 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
721 write!(f, "{}", self.sty)
1a4d82fc
JJ
722 }
723}
724
62682a34
SL
725impl fmt::Debug for ty::UpvarId {
726 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
727 write!(f, "UpvarId({};`{}`;{})",
728 self.var_id,
729 ty::tls::with(|tcx| ty::local_var_name_str(tcx, self.var_id)),
730 self.closure_expr_id)
1a4d82fc
JJ
731 }
732}
733
62682a34
SL
734impl fmt::Debug for ty::UpvarBorrow {
735 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
736 write!(f, "UpvarBorrow({:?}, {:?})",
737 self.kind, self.region)
1a4d82fc
JJ
738 }
739}
740
62682a34
SL
741impl fmt::Display for ty::InferTy {
742 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
743 let print_var_ids = verbose();
744 match *self {
745 ty::TyVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
746 ty::IntVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
747 ty::FloatVar(ref vid) if print_var_ids => write!(f, "{:?}", vid),
748 ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => write!(f, "_"),
749 ty::FreshTy(v) => write!(f, "FreshTy({})", v),
750 ty::FreshIntTy(v) => write!(f, "FreshIntTy({})", v),
751 ty::FreshFloatTy(v) => write!(f, "FreshFloatTy({})", v)
752 }
1a4d82fc
JJ
753 }
754}
755
62682a34
SL
756impl fmt::Display for ty::ExplicitSelfCategory {
757 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
758 f.write_str(match *self {
759 ty::StaticExplicitSelfCategory => "static",
760 ty::ByValueExplicitSelfCategory => "self",
761 ty::ByReferenceExplicitSelfCategory(_, ast::MutMutable) => {
762 "&mut self"
763 }
764 ty::ByReferenceExplicitSelfCategory(_, ast::MutImmutable) => "&self",
765 ty::ByBoxExplicitSelfCategory => "Box<self>",
766 })
1a4d82fc
JJ
767 }
768}
769
62682a34
SL
770impl fmt::Display for ty::ParamTy {
771 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
772 write!(f, "{}", self.name)
85aaf69f
SL
773 }
774}
775
62682a34
SL
776impl fmt::Debug for ty::ParamTy {
777 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
778 write!(f, "{}/{:?}.{}", self, self.space, self.idx)
1a4d82fc
JJ
779 }
780}
781
62682a34
SL
782impl<'tcx, T, U> fmt::Display for ty::OutlivesPredicate<T,U>
783 where T: fmt::Display, U: fmt::Display
1a4d82fc 784{
62682a34
SL
785 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
786 write!(f, "{} : {}", self.0, self.1)
1a4d82fc
JJ
787 }
788}
789
62682a34
SL
790impl<'tcx> fmt::Display for ty::EquatePredicate<'tcx> {
791 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
792 write!(f, "{} == {}", self.0, self.1)
1a4d82fc
JJ
793 }
794}
795
62682a34
SL
796impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
797 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
798 write!(f, "TraitPredicate({:?})",
799 self.trait_ref)
1a4d82fc
JJ
800 }
801}
802
62682a34
SL
803impl<'tcx> fmt::Display for ty::TraitPredicate<'tcx> {
804 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
805 write!(f, "{} : {}",
806 self.trait_ref.self_ty(),
807 self.trait_ref)
1a4d82fc
JJ
808 }
809}
810
62682a34
SL
811impl<'tcx> fmt::Debug for ty::ProjectionPredicate<'tcx> {
812 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
813 write!(f, "ProjectionPredicate({:?}, {:?})",
814 self.projection_ty,
815 self.ty)
1a4d82fc
JJ
816 }
817}
818
62682a34
SL
819impl<'tcx> fmt::Display for ty::ProjectionPredicate<'tcx> {
820 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
821 write!(f, "{} == {}",
822 self.projection_ty,
823 self.ty)
1a4d82fc
JJ
824 }
825}
826
62682a34
SL
827impl<'tcx> fmt::Display for ty::ProjectionTy<'tcx> {
828 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
829 write!(f, "{:?}::{}",
830 self.trait_ref,
831 self.item_name)
1a4d82fc
JJ
832 }
833}
834
62682a34
SL
835impl<'tcx> fmt::Display for ty::Predicate<'tcx> {
836 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1a4d82fc 837 match *self {
62682a34
SL
838 ty::Predicate::Trait(ref data) => write!(f, "{}", data),
839 ty::Predicate::Equate(ref predicate) => write!(f, "{}", predicate),
840 ty::Predicate::RegionOutlives(ref predicate) => write!(f, "{}", predicate),
841 ty::Predicate::TypeOutlives(ref predicate) => write!(f, "{}", predicate),
842 ty::Predicate::Projection(ref predicate) => write!(f, "{}", predicate),
1a4d82fc 843 }
970d7e83
LB
844 }
845}