]>
Commit | Line | Data |
---|---|---|
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 | 12 | use middle::subst::{self, Subst}; |
1a4d82fc JJ |
13 | use middle::ty::{BoundRegion, BrAnon, BrNamed}; |
14 | use middle::ty::{ReEarlyBound, BrFresh, ctxt}; | |
15 | use middle::ty::{ReFree, ReScope, ReInfer, ReStatic, Region, ReEmpty}; | |
16 | use middle::ty::{ReSkolemized, ReVar, BrEnv}; | |
62682a34 SL |
17 | use middle::ty::{mt, Ty}; |
18 | use middle::ty::{TyBool, TyChar, TyStruct, TyEnum}; | |
19 | use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyBareFn}; | |
20 | use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple}; | |
21 | use middle::ty::TyClosure; | |
22 | use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer}; | |
970d7e83 | 23 | use middle::ty; |
62682a34 | 24 | use middle::ty_fold::{self, TypeFoldable}; |
1a4d82fc | 25 | |
62682a34 | 26 | use std::fmt; |
1a4d82fc | 27 | use syntax::abi; |
970d7e83 | 28 | use syntax::parse::token; |
223e47cc | 29 | use syntax::{ast, ast_util}; |
223e47cc | 30 | |
62682a34 SL |
31 | pub fn verbose() -> bool { |
32 | ty::tls::with(|tcx| tcx.sess.verbose()) | |
970d7e83 LB |
33 | } |
34 | ||
62682a34 SL |
35 | fn 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 |
66 | fn 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 |
194 | fn 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)] |
254 | struct TraitAndProjections<'tcx>(ty::TraitRef<'tcx>, Vec<ty::ProjectionPredicate<'tcx>>); | |
255 | ||
256 | impl<'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 |
263 | impl<'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 |
273 | impl<'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 |
312 | impl<'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 |
319 | impl<'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 |
325 | impl<'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 |
333 | impl<'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 |
340 | impl<'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 |
346 | impl 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 |
355 | impl<'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 |
367 | impl<'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 |
374 | impl 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 |
387 | impl 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 |
425 | impl 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 |
452 | impl 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 |
459 | impl 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 |
466 | impl<'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 |
472 | impl<'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 |
479 | impl<'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 |
491 | impl<'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 |
498 | impl<'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 |
513 | impl<'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 |
521 | impl<'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 |
530 | impl<'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 |
562 | impl 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 |
586 | impl<'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 |
592 | impl<'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 |
598 | impl<'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 |
604 | impl<'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 |
610 | impl<'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 |
616 | impl 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 |
622 | impl<'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 |
629 | impl<'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 |
719 | impl<'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 |
725 | impl 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 |
734 | impl 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 |
741 | impl 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 |
756 | impl 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 |
770 | impl 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 |
776 | impl 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 |
782 | impl<'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 |
790 | impl<'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 |
796 | impl<'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 |
803 | impl<'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 |
811 | impl<'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 |
819 | impl<'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 |
827 | impl<'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 |
835 | impl<'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 | } |