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