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