]> git.lizzy.rs Git - rust.git/blob - src/librustc/traits/structural_impls.rs
Rollup merge of #47896 - zackmdavis:and_the_case_of_the_necessary_unnecessary_parens...
[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::SizedYieldType => Some(super::SizedYieldType),
213             super::RepeatVec => Some(super::RepeatVec),
214             super::FieldSized(item) => Some(super::FieldSized(item)),
215             super::ConstSized => Some(super::ConstSized),
216             super::SharedStatic => Some(super::SharedStatic),
217             super::BuiltinDerivedObligation(ref cause) => {
218                 tcx.lift(cause).map(super::BuiltinDerivedObligation)
219             }
220             super::ImplDerivedObligation(ref cause) => {
221                 tcx.lift(cause).map(super::ImplDerivedObligation)
222             }
223             super::CompareImplMethodObligation { item_name,
224                                                  impl_item_def_id,
225                                                  trait_item_def_id } => {
226                 Some(super::CompareImplMethodObligation {
227                     item_name,
228                     impl_item_def_id,
229                     trait_item_def_id,
230                 })
231             }
232             super::ExprAssignable => Some(super::ExprAssignable),
233             super::MatchExpressionArm { arm_span, source } => {
234                 Some(super::MatchExpressionArm { arm_span,
235                                                  source: source })
236             }
237             super::IfExpression => Some(super::IfExpression),
238             super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
239             super::EquatePredicate => Some(super::EquatePredicate),
240             super::MainFunctionType => Some(super::MainFunctionType),
241             super::StartFunctionType => Some(super::StartFunctionType),
242             super::IntrinsicType => Some(super::IntrinsicType),
243             super::MethodReceiver => Some(super::MethodReceiver),
244             super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
245         }
246     }
247 }
248
249 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
250     type Lifted = traits::DerivedObligationCause<'tcx>;
251     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
252         tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
253             tcx.lift(&*self.parent_code).map(|code| {
254                 traits::DerivedObligationCause {
255                     parent_trait_ref: trait_ref,
256                     parent_code: Rc::new(code)
257                 }
258             })
259         })
260     }
261 }
262
263 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
264     type Lifted = traits::ObligationCause<'tcx>;
265     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
266         tcx.lift(&self.code).map(|code| {
267             traits::ObligationCause {
268                 span: self.span,
269                 body_id: self.body_id,
270                 code,
271             }
272         })
273     }
274 }
275
276 // For trans only.
277 impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
278     type Lifted = traits::Vtable<'tcx, ()>;
279     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
280         match self.clone() {
281             traits::VtableImpl(traits::VtableImplData {
282                 impl_def_id,
283                 substs,
284                 nested
285             }) => {
286                 tcx.lift(&substs).map(|substs| {
287                     traits::VtableImpl(traits::VtableImplData {
288                         impl_def_id,
289                         substs,
290                         nested,
291                     })
292                 })
293             }
294             traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
295             traits::VtableGenerator(traits::VtableGeneratorData {
296                 closure_def_id,
297                 substs,
298                 nested
299             }) => {
300                 tcx.lift(&substs).map(|substs| {
301                     traits::VtableGenerator(traits::VtableGeneratorData {
302                         closure_def_id: closure_def_id,
303                         substs: substs,
304                         nested: nested
305                     })
306                 })
307             }
308             traits::VtableClosure(traits::VtableClosureData {
309                 closure_def_id,
310                 substs,
311                 nested
312             }) => {
313                 tcx.lift(&substs).map(|substs| {
314                     traits::VtableClosure(traits::VtableClosureData {
315                         closure_def_id,
316                         substs,
317                         nested,
318                     })
319                 })
320             }
321             traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
322                 tcx.lift(&fn_ty).map(|fn_ty| {
323                     traits::VtableFnPointer(traits::VtableFnPointerData {
324                         fn_ty,
325                         nested,
326                     })
327                 })
328             }
329             traits::VtableParam(n) => Some(traits::VtableParam(n)),
330             traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)),
331             traits::VtableObject(traits::VtableObjectData {
332                 upcast_trait_ref,
333                 vtable_base,
334                 nested
335             }) => {
336                 tcx.lift(&upcast_trait_ref).map(|trait_ref| {
337                     traits::VtableObject(traits::VtableObjectData {
338                         upcast_trait_ref: trait_ref,
339                         vtable_base,
340                         nested,
341                     })
342                 })
343             }
344         }
345     }
346 }
347
348 ///////////////////////////////////////////////////////////////////////////
349 // TypeFoldable implementations.
350
351 impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O>
352 {
353     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
354         traits::Obligation {
355             cause: self.cause.clone(),
356             recursion_depth: self.recursion_depth,
357             predicate: self.predicate.fold_with(folder),
358             param_env: self.param_env.fold_with(folder),
359         }
360     }
361
362     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
363         self.predicate.visit_with(visitor)
364     }
365 }
366
367 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
368     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
369         traits::VtableImplData {
370             impl_def_id: self.impl_def_id,
371             substs: self.substs.fold_with(folder),
372             nested: self.nested.fold_with(folder),
373         }
374     }
375
376     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
377         self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
378     }
379 }
380
381 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
382     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
383         traits::VtableGeneratorData {
384             closure_def_id: self.closure_def_id,
385             substs: self.substs.fold_with(folder),
386             nested: self.nested.fold_with(folder),
387         }
388     }
389
390     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
391         self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
392     }
393 }
394
395 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
396     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
397         traits::VtableClosureData {
398             closure_def_id: self.closure_def_id,
399             substs: self.substs.fold_with(folder),
400             nested: self.nested.fold_with(folder),
401         }
402     }
403
404     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
405         self.substs.visit_with(visitor) || self.nested.visit_with(visitor)
406     }
407 }
408
409 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
410     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
411         traits::VtableAutoImplData {
412             trait_def_id: self.trait_def_id,
413             nested: self.nested.fold_with(folder),
414         }
415     }
416
417     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
418         self.nested.visit_with(visitor)
419     }
420 }
421
422 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
423     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
424         traits::VtableBuiltinData {
425             nested: self.nested.fold_with(folder),
426         }
427     }
428
429     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
430         self.nested.visit_with(visitor)
431     }
432 }
433
434 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
435     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
436         traits::VtableObjectData {
437             upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
438             vtable_base: self.vtable_base,
439             nested: self.nested.fold_with(folder),
440         }
441     }
442
443     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
444         self.upcast_trait_ref.visit_with(visitor) || self.nested.visit_with(visitor)
445     }
446 }
447
448 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
449     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
450         traits::VtableFnPointerData {
451             fn_ty: self.fn_ty.fold_with(folder),
452             nested: self.nested.fold_with(folder),
453         }
454     }
455
456     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
457         self.fn_ty.visit_with(visitor) || self.nested.visit_with(visitor)
458     }
459 }
460
461 impl<'tcx, N: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
462     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
463         match *self {
464             traits::VtableImpl(ref v) => traits::VtableImpl(v.fold_with(folder)),
465             traits::VtableAutoImpl(ref t) => traits::VtableAutoImpl(t.fold_with(folder)),
466             traits::VtableGenerator(ref d) => {
467                 traits::VtableGenerator(d.fold_with(folder))
468             }
469             traits::VtableClosure(ref d) => {
470                 traits::VtableClosure(d.fold_with(folder))
471             }
472             traits::VtableFnPointer(ref d) => {
473                 traits::VtableFnPointer(d.fold_with(folder))
474             }
475             traits::VtableParam(ref n) => traits::VtableParam(n.fold_with(folder)),
476             traits::VtableBuiltin(ref d) => traits::VtableBuiltin(d.fold_with(folder)),
477             traits::VtableObject(ref d) => traits::VtableObject(d.fold_with(folder)),
478         }
479     }
480
481     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
482         match *self {
483             traits::VtableImpl(ref v) => v.visit_with(visitor),
484             traits::VtableAutoImpl(ref t) => t.visit_with(visitor),
485             traits::VtableGenerator(ref d) => d.visit_with(visitor),
486             traits::VtableClosure(ref d) => d.visit_with(visitor),
487             traits::VtableFnPointer(ref d) => d.visit_with(visitor),
488             traits::VtableParam(ref n) => n.visit_with(visitor),
489             traits::VtableBuiltin(ref d) => d.visit_with(visitor),
490             traits::VtableObject(ref d) => d.visit_with(visitor),
491         }
492     }
493 }
494
495 impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
496     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
497         Normalized {
498             value: self.value.fold_with(folder),
499             obligations: self.obligations.fold_with(folder),
500         }
501     }
502
503     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
504         self.value.visit_with(visitor) || self.obligations.visit_with(visitor)
505     }
506 }
507
508 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
509     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
510         match *self {
511             super::ExprAssignable |
512             super::MatchExpressionArm { arm_span: _, source: _ } |
513             super::IfExpression |
514             super::IfExpressionWithNoElse |
515             super::EquatePredicate |
516             super::MainFunctionType |
517             super::StartFunctionType |
518             super::IntrinsicType |
519             super::MethodReceiver |
520             super::MiscObligation |
521             super::SliceOrArrayElem |
522             super::TupleElem |
523             super::ItemObligation(_) |
524             super::AssignmentLhsSized |
525             super::TupleInitializerSized |
526             super::StructInitializerSized |
527             super::VariableType(_) |
528             super::ReturnType(_) |
529             super::SizedReturnType |
530             super::SizedYieldType |
531             super::ReturnNoExpression |
532             super::RepeatVec |
533             super::FieldSized(_) |
534             super::ConstSized |
535             super::SharedStatic |
536             super::BlockTailExpression(_) |
537             super::CompareImplMethodObligation { .. } => self.clone(),
538
539             super::ProjectionWf(proj) => super::ProjectionWf(proj.fold_with(folder)),
540             super::ReferenceOutlivesReferent(ty) => {
541                 super::ReferenceOutlivesReferent(ty.fold_with(folder))
542             }
543             super::ObjectTypeBound(ty, r) => {
544                 super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder))
545             }
546             super::ObjectCastObligation(ty) => {
547                 super::ObjectCastObligation(ty.fold_with(folder))
548             }
549             super::BuiltinDerivedObligation(ref cause) => {
550                 super::BuiltinDerivedObligation(cause.fold_with(folder))
551             }
552             super::ImplDerivedObligation(ref cause) => {
553                 super::ImplDerivedObligation(cause.fold_with(folder))
554             }
555         }
556     }
557
558     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
559         match *self {
560             super::ExprAssignable |
561             super::MatchExpressionArm { arm_span: _, source: _ } |
562             super::IfExpression |
563             super::IfExpressionWithNoElse |
564             super::EquatePredicate |
565             super::MainFunctionType |
566             super::StartFunctionType |
567             super::IntrinsicType |
568             super::MethodReceiver |
569             super::MiscObligation |
570             super::SliceOrArrayElem |
571             super::TupleElem |
572             super::ItemObligation(_) |
573             super::AssignmentLhsSized |
574             super::TupleInitializerSized |
575             super::StructInitializerSized |
576             super::VariableType(_) |
577             super::ReturnType(_) |
578             super::SizedReturnType |
579             super::SizedYieldType |
580             super::ReturnNoExpression |
581             super::RepeatVec |
582             super::FieldSized(_) |
583             super::ConstSized |
584             super::SharedStatic |
585             super::BlockTailExpression(_) |
586             super::CompareImplMethodObligation { .. } => false,
587
588             super::ProjectionWf(proj) => proj.visit_with(visitor),
589             super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor),
590             super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor),
591             super::ObjectCastObligation(ty) => ty.visit_with(visitor),
592             super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor),
593             super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor)
594         }
595     }
596 }
597
598 impl<'tcx> TypeFoldable<'tcx> for traits::DerivedObligationCause<'tcx> {
599     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
600         traits::DerivedObligationCause {
601             parent_trait_ref: self.parent_trait_ref.fold_with(folder),
602             parent_code: self.parent_code.fold_with(folder)
603         }
604     }
605
606     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
607         self.parent_trait_ref.visit_with(visitor) || self.parent_code.visit_with(visitor)
608     }
609 }
610
611 impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCause<'tcx> {
612     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
613         traits::ObligationCause {
614             span: self.span,
615             body_id: self.body_id,
616             code: self.code.fold_with(folder),
617         }
618     }
619
620     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
621         self.code.visit_with(visitor)
622     }
623 }