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