]> git.lizzy.rs Git - rust.git/blob - src/librustc/traits/structural_impls.rs
Auto merge of #45837 - SimonSapin:file_read_write, r=dtolnay
[rust.git] / src / librustc / traits / structural_impls.rs
1 // Copyright 2012-2015 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
11 use traits;
12 use traits::project::Normalized;
13 use ty::{self, Lift, TyCtxt};
14 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
15
16 use std::fmt;
17 use std::rc::Rc;
18
19 // structural impls for the structs in traits
20
21 impl<'tcx, T: fmt::Debug> fmt::Debug for Normalized<'tcx, T> {
22     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23         write!(f, "Normalized({:?},{:?})",
24                self.value,
25                self.obligations)
26     }
27 }
28
29 impl<'tcx, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> {
30     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31         if ty::tls::with(|tcx| tcx.sess.verbose()) {
32             write!(f, "Obligation(predicate={:?},cause={:?},depth={})",
33                    self.predicate,
34                    self.cause,
35                    self.recursion_depth)
36         } else {
37             write!(f, "Obligation(predicate={:?},depth={})",
38                    self.predicate,
39                    self.recursion_depth)
40         }
41     }
42 }
43
44 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::Vtable<'tcx, N> {
45     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
46         match *self {
47             super::VtableImpl(ref v) =>
48                 write!(f, "{:?}", v),
49
50             super::VtableAutoImpl(ref t) =>
51                 write!(f, "{:?}", t),
52
53             super::VtableClosure(ref d) =>
54                 write!(f, "{:?}", d),
55
56             super::VtableGenerator(ref d) =>
57                 write!(f, "{:?}", d),
58
59             super::VtableFnPointer(ref d) =>
60                 write!(f, "VtableFnPointer({:?})", d),
61
62             super::VtableObject(ref d) =>
63                 write!(f, "{:?}", d),
64
65             super::VtableParam(ref n) =>
66                 write!(f, "VtableParam({:?})", n),
67
68             super::VtableBuiltin(ref d) =>
69                 write!(f, "{:?}", d)
70         }
71     }
72 }
73
74 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> {
75     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
76         write!(f, "VtableImpl(impl_def_id={:?}, substs={:?}, nested={:?})",
77                self.impl_def_id,
78                self.substs,
79                self.nested)
80     }
81 }
82
83 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> {
84     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85         write!(f, "VtableGenerator(closure_def_id={:?}, substs={:?}, nested={:?})",
86                self.closure_def_id,
87                self.substs,
88                self.nested)
89     }
90 }
91
92 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> {
93     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94         write!(f, "VtableClosure(closure_def_id={:?}, substs={:?}, nested={:?})",
95                self.closure_def_id,
96                self.substs,
97                self.nested)
98     }
99 }
100
101 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> {
102     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103         write!(f, "VtableBuiltin(nested={:?})", self.nested)
104     }
105 }
106
107 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableAutoImplData<N> {
108     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109         write!(f, "VtableAutoImplData(trait_def_id={:?}, nested={:?})",
110                self.trait_def_id,
111                self.nested)
112     }
113 }
114
115 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> {
116     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117         write!(f, "VtableObject(upcast={:?}, vtable_base={}, nested={:?})",
118                self.upcast_trait_ref,
119                self.vtable_base,
120                self.nested)
121     }
122 }
123
124 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> {
125     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126         write!(f, "VtableFnPointer(fn_ty={:?}, nested={:?})",
127                self.fn_ty,
128                self.nested)
129     }
130 }
131
132 impl<'tcx> fmt::Debug for traits::FulfillmentError<'tcx> {
133     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
134         write!(f, "FulfillmentError({:?},{:?})",
135                self.obligation,
136                self.code)
137     }
138 }
139
140 impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> {
141     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142         match *self {
143             super::CodeSelectionError(ref e) => write!(f, "{:?}", e),
144             super::CodeProjectionError(ref e) => write!(f, "{:?}", e),
145             super::CodeSubtypeError(ref a, ref b) =>
146                 write!(f, "CodeSubtypeError({:?}, {:?})", a, b),
147             super::CodeAmbiguity => write!(f, "Ambiguity")
148         }
149     }
150 }
151
152 impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> {
153     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154         write!(f, "MismatchedProjectionTypes({:?})", self.err)
155     }
156 }
157
158 ///////////////////////////////////////////////////////////////////////////
159 // Lift implementations
160
161 impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
162     type Lifted = traits::SelectionError<'tcx>;
163     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
164         match *self {
165             super::Unimplemented => Some(super::Unimplemented),
166             super::OutputTypeParameterMismatch(a, b, ref err) => {
167                 tcx.lift(&(a, b)).and_then(|(a, b)| {
168                     tcx.lift(err).map(|err| {
169                         super::OutputTypeParameterMismatch(a, b, err)
170                     })
171                 })
172             }
173             super::TraitNotObjectSafe(def_id) => {
174                 Some(super::TraitNotObjectSafe(def_id))
175             }
176             super::ConstEvalFailure(ref err) => {
177                 tcx.lift(err).map(super::ConstEvalFailure)
178             }
179         }
180     }
181 }
182
183 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
184     type Lifted = traits::ObligationCauseCode<'tcx>;
185     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
186         match *self {
187             super::ReturnNoExpression => Some(super::ReturnNoExpression),
188             super::MiscObligation => Some(super::MiscObligation),
189             super::SliceOrArrayElem => Some(super::SliceOrArrayElem),
190             super::TupleElem => Some(super::TupleElem),
191             super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf),
192             super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)),
193             super::ReferenceOutlivesReferent(ty) => {
194                 tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
195             }
196             super::ObjectTypeBound(ty, r) => {
197                 tcx.lift(&ty).and_then(|ty| {
198                     tcx.lift(&r).and_then(|r| {
199                         Some(super::ObjectTypeBound(ty, r))
200                     })
201                 })
202             }
203             super::ObjectCastObligation(ty) => {
204                 tcx.lift(&ty).map(super::ObjectCastObligation)
205             }
206             super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
207             super::TupleInitializerSized => Some(super::TupleInitializerSized),
208             super::StructInitializerSized => Some(super::StructInitializerSized),
209             super::VariableType(id) => Some(super::VariableType(id)),
210             super::ReturnType(id) => Some(super::ReturnType(id)),
211             super::SizedReturnType => Some(super::SizedReturnType),
212             super::RepeatVec => Some(super::RepeatVec),
213             super::FieldSized(item) => Some(super::FieldSized(item)),
214             super::ConstSized => Some(super::ConstSized),
215             super::SharedStatic => Some(super::SharedStatic),
216             super::BuiltinDerivedObligation(ref cause) => {
217                 tcx.lift(cause).map(super::BuiltinDerivedObligation)
218             }
219             super::ImplDerivedObligation(ref cause) => {
220                 tcx.lift(cause).map(super::ImplDerivedObligation)
221             }
222             super::CompareImplMethodObligation { item_name,
223                                                  impl_item_def_id,
224                                                  trait_item_def_id } => {
225                 Some(super::CompareImplMethodObligation {
226                     item_name,
227                     impl_item_def_id,
228                     trait_item_def_id,
229                 })
230             }
231             super::ExprAssignable => Some(super::ExprAssignable),
232             super::MatchExpressionArm { arm_span, source } => {
233                 Some(super::MatchExpressionArm { arm_span,
234                                                  source: source })
235             }
236             super::IfExpression => Some(super::IfExpression),
237             super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
238             super::EquatePredicate => Some(super::EquatePredicate),
239             super::MainFunctionType => Some(super::MainFunctionType),
240             super::StartFunctionType => Some(super::StartFunctionType),
241             super::IntrinsicType => Some(super::IntrinsicType),
242             super::MethodReceiver => Some(super::MethodReceiver),
243             super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
244         }
245     }
246 }
247
248 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
249     type Lifted = traits::DerivedObligationCause<'tcx>;
250     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
251         tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
252             tcx.lift(&*self.parent_code).map(|code| {
253                 traits::DerivedObligationCause {
254                     parent_trait_ref: trait_ref,
255                     parent_code: Rc::new(code)
256                 }
257             })
258         })
259     }
260 }
261
262 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
263     type Lifted = traits::ObligationCause<'tcx>;
264     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
265         tcx.lift(&self.code).map(|code| {
266             traits::ObligationCause {
267                 span: self.span,
268                 body_id: self.body_id,
269                 code,
270             }
271         })
272     }
273 }
274
275 // For trans only.
276 impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
277     type Lifted = traits::Vtable<'tcx, ()>;
278     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
279         match self.clone() {
280             traits::VtableImpl(traits::VtableImplData {
281                 impl_def_id,
282                 substs,
283                 nested
284             }) => {
285                 tcx.lift(&substs).map(|substs| {
286                     traits::VtableImpl(traits::VtableImplData {
287                         impl_def_id,
288                         substs,
289                         nested,
290                     })
291                 })
292             }
293             traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
294             traits::VtableGenerator(traits::VtableGeneratorData {
295                 closure_def_id,
296                 substs,
297                 nested
298             }) => {
299                 tcx.lift(&substs).map(|substs| {
300                     traits::VtableGenerator(traits::VtableGeneratorData {
301                         closure_def_id: closure_def_id,
302                         substs: substs,
303                         nested: nested
304                     })
305                 })
306             }
307             traits::VtableClosure(traits::VtableClosureData {
308                 closure_def_id,
309                 substs,
310                 nested
311             }) => {
312                 tcx.lift(&substs).map(|substs| {
313                     traits::VtableClosure(traits::VtableClosureData {
314                         closure_def_id,
315                         substs,
316                         nested,
317                     })
318                 })
319             }
320             traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
321                 tcx.lift(&fn_ty).map(|fn_ty| {
322                     traits::VtableFnPointer(traits::VtableFnPointerData {
323                         fn_ty,
324                         nested,
325                     })
326                 })
327             }
328             traits::VtableParam(n) => Some(traits::VtableParam(n)),
329             traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)),
330             traits::VtableObject(traits::VtableObjectData {
331                 upcast_trait_ref,
332                 vtable_base,
333                 nested
334             }) => {
335                 tcx.lift(&upcast_trait_ref).map(|trait_ref| {
336                     traits::VtableObject(traits::VtableObjectData {
337                         upcast_trait_ref: trait_ref,
338                         vtable_base,
339                         nested,
340                     })
341                 })
342             }
343         }
344     }
345 }
346
347 ///////////////////////////////////////////////////////////////////////////
348 // TypeFoldable implementations.
349
350 impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O>
351 {
352     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
353         traits::Obligation {
354             cause: self.cause.clone(),
355             recursion_depth: self.recursion_depth,
356             predicate: self.predicate.fold_with(folder),
357             param_env: self.param_env.fold_with(folder),
358         }
359     }
360
361     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
362         self.predicate.visit_with(visitor)
363     }
364 }
365
366 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
367     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
368         traits::VtableImplData {
369             impl_def_id: self.impl_def_id,
370             substs: self.substs.fold_with(folder),
371             nested: self.nested.fold_with(folder),
372         }
373     }
374
375     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
376         self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
377     }
378 }
379
380 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
381     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
382         traits::VtableGeneratorData {
383             closure_def_id: self.closure_def_id,
384             substs: self.substs.fold_with(folder),
385             nested: self.nested.fold_with(folder),
386         }
387     }
388
389     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
390         self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
391     }
392 }
393
394 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
395     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
396         traits::VtableClosureData {
397             closure_def_id: self.closure_def_id,
398             substs: self.substs.fold_with(folder),
399             nested: self.nested.fold_with(folder),
400         }
401     }
402
403     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
404         self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
405     }
406 }
407
408 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
409     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
410         traits::VtableAutoImplData {
411             trait_def_id: self.trait_def_id,
412             nested: self.nested.fold_with(folder),
413         }
414     }
415
416     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
417         self.nested.visit_with(visitor)
418     }
419 }
420
421 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
422     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
423         traits::VtableBuiltinData {
424             nested: self.nested.fold_with(folder),
425         }
426     }
427
428     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
429         self.nested.visit_with(visitor)
430     }
431 }
432
433 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
434     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
435         traits::VtableObjectData {
436             upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
437             vtable_base: self.vtable_base,
438             nested: self.nested.fold_with(folder),
439         }
440     }
441
442     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
443         self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor)
444     }
445 }
446
447 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
448     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
449         traits::VtableFnPointerData {
450             fn_ty: self.fn_ty.fold_with(folder),
451             nested: self.nested.fold_with(folder),
452         }
453     }
454
455     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
456         self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor)
457     }
458 }
459
460 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
461     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
462         match *self {
463             traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
464             traits::VtableAutoImpl(ref t) => traits::VtableAutoImpl(t.fold_with(folder)),
465             traits::VtableGenerator(ref d) => {
466                 traits::VtableGenerator(d.fold_with(folder))
467             }
468             traits::VtableClosure(ref d) => {
469                 traits::VtableClosure(d.fold_with(folder))
470             }
471             traits::VtableFnPointer(ref d) => {
472                 traits::VtableFnPointer(d.fold_with(folder))
473             }
474             traits::VtableParam(ref n) => traits::VtableParam(n.fold_with(folder)),
475             traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)),
476             traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)),
477         }
478     }
479
480     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
481         match *self {
482             traits::VtableImpl(ref v) => v.visit_with(visitor),
483             traits::VtableAutoImpl(ref t) => t.visit_with(visitor),
484             traits::VtableGenerator(ref d) => d.visit_with(visitor),
485             traits::VtableClosure(ref d) => d.visit_with(visitor),
486             traits::VtableFnPointer(ref d) => d.visit_with(visitor),
487             traits::VtableParam(ref n) => n.visit_with(visitor),
488             traits::VtableBuiltin(ref d) => d.visit_with(visitor),
489             traits::VtableObject(ref d) => d.visit_with(visitor),
490         }
491     }
492 }
493
494 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
495     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
496         Normalized {
497             value: self.value.fold_with(folder),
498             obligations: self.obligations.fold_with(folder),
499         }
500     }
501
502     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
503         self.value.visit_with(visitor) || self.obligations.visit_with(visitor)
504     }
505 }
506
507 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
508     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
509         match *self {
510             super::ExprAssignable |
511             super::MatchExpressionArm { arm_span: _, source: _ } |
512             super::IfExpression |
513             super::IfExpressionWithNoElse |
514             super::EquatePredicate |
515             super::MainFunctionType |
516             super::StartFunctionType |
517             super::IntrinsicType |
518             super::MethodReceiver |
519             super::MiscObligation |
520             super::SliceOrArrayElem |
521             super::TupleElem |
522             super::ItemObligation(_) |
523             super::AssignmentLhsSized |
524             super::TupleInitializerSized |
525             super::StructInitializerSized |
526             super::VariableType(_) |
527             super::ReturnType(_) |
528             super::SizedReturnType |
529             super::ReturnNoExpression |
530             super::RepeatVec |
531             super::FieldSized(_) |
532             super::ConstSized |
533             super::SharedStatic |
534             super::BlockTailExpression(_) |
535             super::CompareImplMethodObligation { .. } => self.clone(),
536
537             super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)),
538             super::ReferenceOutlivesReferent(ty) => {
539                 super::ReferenceOutlivesReferent(ty.fold_with(folder))
540             }
541             super::ObjectTypeBound(ty, r) => {
542                 super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder))
543             }
544             super::ObjectCastObligation(ty) => {
545                 super::ObjectCastObligation(ty.fold_with(folder))
546             }
547             super::BuiltinDerivedObligation(ref cause) => {
548                 super::BuiltinDerivedObligation(cause.fold_with(folder))
549             }
550             super::ImplDerivedObligation(ref cause) => {
551                 super::ImplDerivedObligation(cause.fold_with(folder))
552             }
553         }
554     }
555
556     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
557         match *self {
558             super::ExprAssignable |
559             super::MatchExpressionArm { arm_span: _, source: _ } |
560             super::IfExpression |
561             super::IfExpressionWithNoElse |
562             super::EquatePredicate |
563             super::MainFunctionType |
564             super::StartFunctionType |
565             super::IntrinsicType |
566             super::MethodReceiver |
567             super::MiscObligation |
568             super::SliceOrArrayElem |
569             super::TupleElem |
570             super::ItemObligation(_) |
571             super::AssignmentLhsSized |
572             super::TupleInitializerSized |
573             super::StructInitializerSized |
574             super::VariableType(_) |
575             super::ReturnType(_) |
576             super::SizedReturnType |
577             super::ReturnNoExpression |
578             super::RepeatVec |
579             super::FieldSized(_) |
580             super::ConstSized |
581             super::SharedStatic |
582             super::BlockTailExpression(_) |
583             super::CompareImplMethodObligation { .. } => false,
584
585             super::ProjectionWf(proj) => proj.visit_with(visitor),
586             super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor),
587             super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor),
588             super::ObjectCastObligation(ty) => ty.visit_with(visitor),
589             super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor),
590             super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor)
591         }
592     }
593 }
594
595 impl<'tcx> TypeFoldable<'tcx> for traits::DerivedObligationCause<'tcx> {
596     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
597         traits::DerivedObligationCause {
598             parent_trait_ref: self.parent_trait_ref.fold_with(folder),
599             parent_code: self.parent_code.fold_with(folder)
600         }
601     }
602
603     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
604         self.parent_trait_ref.visit_with(visitor) || self.parent_code.visit_with(visitor)
605     }
606 }
607
608 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> {
609     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
610         traits::ObligationCause {
611             span: self.span,
612             body_id: self.body_id,
613             code: self.code.fold_with(folder),
614         }
615     }
616
617     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
618         self.code.visit_with(visitor)
619     }
620 }