]> git.lizzy.rs Git - rust.git/blob - src/librustc/traits/structural_impls.rs
Rollup merge of #51765 - jonas-schievink:patch-1, r=KodrAus
[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 chalk_engine;
12 use rustc_data_structures::accumulate_vec::AccumulateVec;
13 use traits;
14 use traits::project::Normalized;
15 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
16 use ty::{self, Lift, TyCtxt};
17
18 use std::fmt;
19 use std::rc::Rc;
20
21 // structural impls for the structs in traits
22
23 impl<'tcx, T: fmt::Debug> fmt::Debug for Normalized<'tcx, T> {
24     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25         write!(f, "Normalized({:?},{:?})", self.value, 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!(
33                 f,
34                 "Obligation(predicate={:?},cause={:?},depth={})",
35                 self.predicate, self.cause, self.recursion_depth
36             )
37         } else {
38             write!(
39                 f,
40                 "Obligation(predicate={:?},depth={})",
41                 self.predicate, self.recursion_depth
42             )
43         }
44     }
45 }
46
47 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::Vtable<'tcx, N> {
48     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
49         match *self {
50             super::VtableImpl(ref v) => write!(f, "{:?}", v),
51
52             super::VtableAutoImpl(ref t) => write!(f, "{:?}", t),
53
54             super::VtableClosure(ref d) => write!(f, "{:?}", d),
55
56             super::VtableGenerator(ref d) => write!(f, "{:?}", d),
57
58             super::VtableFnPointer(ref d) => write!(f, "VtableFnPointer({:?})", d),
59
60             super::VtableObject(ref d) => write!(f, "{:?}", d),
61
62             super::VtableParam(ref n) => write!(f, "VtableParam({:?})", n),
63
64             super::VtableBuiltin(ref d) => write!(f, "{:?}", d),
65         }
66     }
67 }
68
69 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> {
70     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71         write!(
72             f,
73             "VtableImpl(impl_def_id={:?}, substs={:?}, nested={:?})",
74             self.impl_def_id, self.substs, self.nested
75         )
76     }
77 }
78
79 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> {
80     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81         write!(
82             f,
83             "VtableGenerator(generator_def_id={:?}, substs={:?}, nested={:?})",
84             self.generator_def_id, self.substs, self.nested
85         )
86     }
87 }
88
89 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> {
90     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
91         write!(
92             f,
93             "VtableClosure(closure_def_id={:?}, substs={:?}, nested={:?})",
94             self.closure_def_id, self.substs, self.nested
95         )
96     }
97 }
98
99 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> {
100     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
101         write!(f, "VtableBuiltin(nested={:?})", self.nested)
102     }
103 }
104
105 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableAutoImplData<N> {
106     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107         write!(
108             f,
109             "VtableAutoImplData(trait_def_id={:?}, nested={:?})",
110             self.trait_def_id, self.nested
111         )
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!(
118             f,
119             "VtableObject(upcast={:?}, vtable_base={}, nested={:?})",
120             self.upcast_trait_ref, self.vtable_base, self.nested
121         )
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!(
128             f,
129             "VtableFnPointer(fn_ty={:?}, nested={:?})",
130             self.fn_ty, self.nested
131         )
132     }
133 }
134
135 impl<'tcx> fmt::Debug for traits::FulfillmentError<'tcx> {
136     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
137         write!(f, "FulfillmentError({:?},{:?})", self.obligation, 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             }
149             super::CodeAmbiguity => write!(f, "Ambiguity"),
150         }
151     }
152 }
153
154 impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> {
155     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156         write!(f, "MismatchedProjectionTypes({:?})", self.err)
157     }
158 }
159
160 ///////////////////////////////////////////////////////////////////////////
161 // Lift implementations
162
163 impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
164     type Lifted = traits::SelectionError<'tcx>;
165     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
166         match *self {
167             super::Unimplemented => Some(super::Unimplemented),
168             super::OutputTypeParameterMismatch(a, b, ref err) => {
169                 tcx.lift(&(a, b)).and_then(|(a, b)| {
170                     tcx.lift(err)
171                         .map(|err| super::OutputTypeParameterMismatch(a, b, err))
172                 })
173             }
174             super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
175             super::ConstEvalFailure(ref err) => tcx.lift(&**err).map(|err| super::ConstEvalFailure(
176                 err.into(),
177             )),
178             super::Overflow => bug!(), // FIXME: ape ConstEvalFailure?
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) => tcx.lift(&ty).and_then(|ty| {
197                 tcx.lift(&r)
198                     .and_then(|r| Some(super::ObjectTypeBound(ty, r)))
199             }),
200             super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation),
201             super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
202             super::TupleInitializerSized => Some(super::TupleInitializerSized),
203             super::StructInitializerSized => Some(super::StructInitializerSized),
204             super::VariableType(id) => Some(super::VariableType(id)),
205             super::ReturnType(id) => Some(super::ReturnType(id)),
206             super::SizedReturnType => Some(super::SizedReturnType),
207             super::SizedYieldType => Some(super::SizedYieldType),
208             super::RepeatVec => Some(super::RepeatVec),
209             super::FieldSized(item) => Some(super::FieldSized(item)),
210             super::ConstSized => Some(super::ConstSized),
211             super::SharedStatic => Some(super::SharedStatic),
212             super::BuiltinDerivedObligation(ref cause) => {
213                 tcx.lift(cause).map(super::BuiltinDerivedObligation)
214             }
215             super::ImplDerivedObligation(ref cause) => {
216                 tcx.lift(cause).map(super::ImplDerivedObligation)
217             }
218             super::CompareImplMethodObligation {
219                 item_name,
220                 impl_item_def_id,
221                 trait_item_def_id,
222             } => Some(super::CompareImplMethodObligation {
223                 item_name,
224                 impl_item_def_id,
225                 trait_item_def_id,
226             }),
227             super::ExprAssignable => Some(super::ExprAssignable),
228             super::MatchExpressionArm { arm_span, source } => Some(super::MatchExpressionArm {
229                 arm_span,
230                 source: source,
231             }),
232             super::IfExpression => Some(super::IfExpression),
233             super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
234             super::MainFunctionType => Some(super::MainFunctionType),
235             super::StartFunctionType => Some(super::StartFunctionType),
236             super::IntrinsicType => Some(super::IntrinsicType),
237             super::MethodReceiver => Some(super::MethodReceiver),
238             super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
239             super::TrivialBound => Some(super::TrivialBound),
240         }
241     }
242 }
243
244 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
245     type Lifted = traits::DerivedObligationCause<'tcx>;
246     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
247         tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
248             tcx.lift(&*self.parent_code)
249                 .map(|code| traits::DerivedObligationCause {
250                     parent_trait_ref: trait_ref,
251                     parent_code: Rc::new(code),
252                 })
253         })
254     }
255 }
256
257 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
258     type Lifted = traits::ObligationCause<'tcx>;
259     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
260         tcx.lift(&self.code).map(|code| traits::ObligationCause {
261             span: self.span,
262             body_id: self.body_id,
263             code,
264         })
265     }
266 }
267
268 // For codegen only.
269 impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
270     type Lifted = traits::Vtable<'tcx, ()>;
271     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
272         match self.clone() {
273             traits::VtableImpl(traits::VtableImplData {
274                 impl_def_id,
275                 substs,
276                 nested,
277             }) => tcx.lift(&substs).map(|substs| {
278                 traits::VtableImpl(traits::VtableImplData {
279                     impl_def_id,
280                     substs,
281                     nested,
282                 })
283             }),
284             traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
285             traits::VtableGenerator(traits::VtableGeneratorData {
286                 generator_def_id,
287                 substs,
288                 nested,
289             }) => tcx.lift(&substs).map(|substs| {
290                 traits::VtableGenerator(traits::VtableGeneratorData {
291                     generator_def_id: generator_def_id,
292                     substs: substs,
293                     nested: nested,
294                 })
295             }),
296             traits::VtableClosure(traits::VtableClosureData {
297                 closure_def_id,
298                 substs,
299                 nested,
300             }) => tcx.lift(&substs).map(|substs| {
301                 traits::VtableClosure(traits::VtableClosureData {
302                     closure_def_id,
303                     substs,
304                     nested,
305                 })
306             }),
307             traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
308                 tcx.lift(&fn_ty).map(|fn_ty| {
309                     traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested })
310                 })
311             }
312             traits::VtableParam(n) => Some(traits::VtableParam(n)),
313             traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)),
314             traits::VtableObject(traits::VtableObjectData {
315                 upcast_trait_ref,
316                 vtable_base,
317                 nested,
318             }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| {
319                 traits::VtableObject(traits::VtableObjectData {
320                     upcast_trait_ref: trait_ref,
321                     vtable_base,
322                     nested,
323                 })
324             }),
325         }
326     }
327 }
328
329 ///////////////////////////////////////////////////////////////////////////
330 // TypeFoldable implementations.
331
332 impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> {
333     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
334         traits::Obligation {
335             cause: self.cause.clone(),
336             recursion_depth: self.recursion_depth,
337             predicate: self.predicate.fold_with(folder),
338             param_env: self.param_env.fold_with(folder),
339         }
340     }
341
342     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
343         self.predicate.visit_with(visitor)
344     }
345 }
346
347 BraceStructTypeFoldableImpl! {
348     impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableImplData<'tcx, N> {
349         impl_def_id, substs, nested
350     } where N: TypeFoldable<'tcx>
351 }
352
353 BraceStructTypeFoldableImpl! {
354     impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
355         generator_def_id, substs, nested
356     } where N: TypeFoldable<'tcx>
357 }
358
359 BraceStructTypeFoldableImpl! {
360     impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableClosureData<'tcx, N> {
361         closure_def_id, substs, nested
362     } where N: TypeFoldable<'tcx>
363 }
364
365 BraceStructTypeFoldableImpl! {
366     impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableAutoImplData<N> {
367         trait_def_id, nested
368     } where N: TypeFoldable<'tcx>
369 }
370
371 BraceStructTypeFoldableImpl! {
372     impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableBuiltinData<N> {
373         nested
374     } where N: TypeFoldable<'tcx>
375 }
376
377 BraceStructTypeFoldableImpl! {
378     impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx, N> {
379         upcast_trait_ref, vtable_base, nested
380     } where N: TypeFoldable<'tcx>
381 }
382
383 BraceStructTypeFoldableImpl! {
384     impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableFnPointerData<'tcx, N> {
385         fn_ty,
386         nested
387     } where N: TypeFoldable<'tcx>
388 }
389
390 EnumTypeFoldableImpl! {
391     impl<'tcx, N> TypeFoldable<'tcx> for traits::Vtable<'tcx, N> {
392         (traits::VtableImpl)(a),
393         (traits::VtableAutoImpl)(a),
394         (traits::VtableGenerator)(a),
395         (traits::VtableClosure)(a),
396         (traits::VtableFnPointer)(a),
397         (traits::VtableParam)(a),
398         (traits::VtableBuiltin)(a),
399         (traits::VtableObject)(a),
400     } where N: TypeFoldable<'tcx>
401 }
402
403 BraceStructTypeFoldableImpl! {
404     impl<'tcx, T> TypeFoldable<'tcx> for Normalized<'tcx, T> {
405         value,
406         obligations
407     } where T: TypeFoldable<'tcx>
408 }
409
410 impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
411     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
412         use traits::WhereClause::*;
413
414         match self {
415             Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref),
416             ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection),
417             RegionOutlives(predicate) => write!(fmt, "RegionOutlives({})", predicate),
418             TypeOutlives(predicate) => write!(fmt, "TypeOutlives({})", predicate),
419         }
420     }
421 }
422
423 impl<'tcx> fmt::Display for traits::WellFormed<'tcx> {
424     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
425         use traits::WellFormed::*;
426
427         match self {
428             Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref),
429             Ty(ty) => write!(fmt, "WellFormed({})", ty),
430         }
431     }
432 }
433
434 impl<'tcx> fmt::Display for traits::FromEnv<'tcx> {
435     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
436         use traits::FromEnv::*;
437
438         match self {
439             Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref),
440             Ty(ty) => write!(fmt, "FromEnv({})", ty),
441         }
442     }
443 }
444
445 impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> {
446     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
447         use traits::DomainGoal::*;
448
449         match self {
450             Holds(wc) => write!(fmt, "{}", wc),
451             WellFormed(wf) => write!(fmt, "{}", wf),
452             FromEnv(from_env) => write!(fmt, "{}", from_env),
453             Normalize(projection) => write!(fmt, "Normalize({})", projection),
454         }
455     }
456 }
457
458 impl fmt::Display for traits::QuantifierKind {
459     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
460         use traits::QuantifierKind::*;
461
462         match self {
463             Universal => write!(fmt, "forall"),
464             Existential => write!(fmt, "exists"),
465         }
466     }
467 }
468
469 impl<'tcx> fmt::Display for traits::Goal<'tcx> {
470     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
471         use traits::Goal::*;
472
473         match self {
474             Implies(hypotheses, goal) => {
475                 write!(fmt, "if (")?;
476                 for (index, hyp) in hypotheses.iter().enumerate() {
477                     if index > 0 {
478                         write!(fmt, ", ")?;
479                     }
480                     write!(fmt, "{}", hyp)?;
481                 }
482                 write!(fmt, ") {{ {} }}", goal)
483             }
484             And(goal1, goal2) => write!(fmt, "({} && {})", goal1, goal2),
485             Not(goal) => write!(fmt, "not {{ {} }}", goal),
486             DomainGoal(goal) => write!(fmt, "{}", goal),
487             Quantified(qkind, goal) => {
488                 // FIXME: appropriate binder names
489                 write!(fmt, "{}<> {{ {} }}", qkind, goal.skip_binder())
490             }
491             CannotProve => write!(fmt, "CannotProve"),
492         }
493     }
494 }
495
496 impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> {
497     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
498         let traits::ProgramClause { goal, hypotheses } = self;
499         write!(fmt, "{}", goal)?;
500         if !hypotheses.is_empty() {
501             write!(fmt, " :- ")?;
502             for (index, condition) in hypotheses.iter().enumerate() {
503                 if index > 0 {
504                     write!(fmt, ", ")?;
505                 }
506                 write!(fmt, "{}", condition)?;
507             }
508         }
509         write!(fmt, ".")
510     }
511 }
512
513 impl<'tcx> fmt::Display for traits::Clause<'tcx> {
514     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
515         use traits::Clause::*;
516
517         match self {
518             Implies(clause) => write!(fmt, "{}", clause),
519             ForAll(clause) => {
520                 // FIXME: appropriate binder names
521                 write!(fmt, "forall<> {{ {} }}", clause.skip_binder())
522             }
523         }
524     }
525 }
526
527 EnumTypeFoldableImpl! {
528     impl<'tcx> TypeFoldable<'tcx> for traits::WhereClause<'tcx> {
529         (traits::WhereClause::Implemented)(trait_ref),
530         (traits::WhereClause::ProjectionEq)(projection),
531         (traits::WhereClause::TypeOutlives)(ty_outlives),
532         (traits::WhereClause::RegionOutlives)(region_outlives),
533     }
534 }
535
536 EnumLiftImpl! {
537     impl<'a, 'tcx> Lift<'tcx> for traits::WhereClause<'a> {
538         type Lifted = traits::WhereClause<'tcx>;
539         (traits::WhereClause::Implemented)(trait_ref),
540         (traits::WhereClause::ProjectionEq)(projection),
541         (traits::WhereClause::TypeOutlives)(ty_outlives),
542         (traits::WhereClause::RegionOutlives)(region_outlives),
543     }
544 }
545
546 EnumTypeFoldableImpl! {
547     impl<'tcx> TypeFoldable<'tcx> for traits::WellFormed<'tcx> {
548         (traits::WellFormed::Trait)(trait_ref),
549         (traits::WellFormed::Ty)(ty),
550     }
551 }
552
553 EnumLiftImpl! {
554     impl<'a, 'tcx> Lift<'tcx> for traits::WellFormed<'a> {
555         type Lifted = traits::WellFormed<'tcx>;
556         (traits::WellFormed::Trait)(trait_ref),
557         (traits::WellFormed::Ty)(ty),
558     }
559 }
560
561 EnumTypeFoldableImpl! {
562     impl<'tcx> TypeFoldable<'tcx> for traits::FromEnv<'tcx> {
563         (traits::FromEnv::Trait)(trait_ref),
564         (traits::FromEnv::Ty)(ty),
565     }
566 }
567
568 EnumLiftImpl! {
569     impl<'a, 'tcx> Lift<'tcx> for traits::FromEnv<'a> {
570         type Lifted = traits::FromEnv<'tcx>;
571         (traits::FromEnv::Trait)(trait_ref),
572         (traits::FromEnv::Ty)(ty),
573     }
574 }
575
576 EnumTypeFoldableImpl! {
577     impl<'tcx> TypeFoldable<'tcx> for traits::DomainGoal<'tcx> {
578         (traits::DomainGoal::Holds)(wc),
579         (traits::DomainGoal::WellFormed)(wf),
580         (traits::DomainGoal::FromEnv)(from_env),
581         (traits::DomainGoal::Normalize)(projection),
582     }
583 }
584
585 EnumLiftImpl! {
586     impl<'a, 'tcx> Lift<'tcx> for traits::DomainGoal<'a> {
587         type Lifted = traits::DomainGoal<'tcx>;
588         (traits::DomainGoal::Holds)(wc),
589         (traits::DomainGoal::WellFormed)(wf),
590         (traits::DomainGoal::FromEnv)(from_env),
591         (traits::DomainGoal::Normalize)(projection),
592     }
593 }
594
595 CloneTypeFoldableAndLiftImpls! {
596     traits::QuantifierKind,
597 }
598
599 EnumTypeFoldableImpl! {
600     impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
601         (traits::Goal::Implies)(hypotheses, goal),
602         (traits::Goal::And)(goal1, goal2),
603         (traits::Goal::Not)(goal),
604         (traits::Goal::DomainGoal)(domain_goal),
605         (traits::Goal::Quantified)(qkind, goal),
606         (traits::Goal::CannotProve),
607     }
608 }
609
610 EnumLiftImpl! {
611     impl<'a, 'tcx> Lift<'tcx> for traits::Goal<'a> {
612         type Lifted = traits::Goal<'tcx>;
613         (traits::Goal::Implies)(hypotheses, goal),
614         (traits::Goal::And)(goal1, goal2),
615         (traits::Goal::Not)(goal),
616         (traits::Goal::DomainGoal)(domain_goal),
617         (traits::Goal::Quantified)(kind, goal),
618         (traits::Goal::CannotProve),
619     }
620 }
621
622 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<traits::Goal<'tcx>> {
623     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
624         let v = self.iter()
625             .map(|t| t.fold_with(folder))
626             .collect::<AccumulateVec<[_; 8]>>();
627         folder.tcx().intern_goals(&v)
628     }
629
630     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
631         self.iter().any(|t| t.visit_with(visitor))
632     }
633 }
634
635 impl<'tcx> TypeFoldable<'tcx> for &'tcx traits::Goal<'tcx> {
636     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
637         let v = (**self).fold_with(folder);
638         folder.tcx().mk_goal(v)
639     }
640
641     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
642         (**self).visit_with(visitor)
643     }
644 }
645
646 BraceStructTypeFoldableImpl! {
647     impl<'tcx> TypeFoldable<'tcx> for traits::ProgramClause<'tcx> {
648         goal,
649         hypotheses
650     }
651 }
652
653 EnumTypeFoldableImpl! {
654     impl<'tcx> TypeFoldable<'tcx> for traits::Clause<'tcx> {
655         (traits::Clause::Implies)(clause),
656         (traits::Clause::ForAll)(clause),
657     }
658 }
659
660 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Slice<traits::Clause<'tcx>> {
661     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
662         let v = self.iter()
663             .map(|t| t.fold_with(folder))
664             .collect::<AccumulateVec<[_; 8]>>();
665         folder.tcx().intern_clauses(&v)
666     }
667
668     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
669         self.iter().any(|t| t.visit_with(visitor))
670     }
671 }
672
673 impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::ExClause<C>
674 where
675     C: traits::ExClauseFold<'tcx>,
676     C::Substitution: Clone,
677     C::RegionConstraint: Clone,
678 {
679     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
680         <C as traits::ExClauseFold>::fold_ex_clause_with(
681             self,
682             folder,
683         )
684     }
685
686     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
687         <C as traits::ExClauseFold>::visit_ex_clause_with(
688             self,
689             visitor,
690         )
691     }
692 }
693
694 impl<'tcx, C> Lift<'tcx> for chalk_engine::ExClause<C>
695 where
696     C: chalk_engine::context::Context + Clone,
697     C: traits::ExClauseLift<'tcx>,
698 {
699     type Lifted = C::LiftedExClause;
700
701     fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option<Self::Lifted> {
702         <C as traits::ExClauseLift>::lift_ex_clause_to_tcx(self, tcx)
703     }
704 }
705
706 EnumTypeFoldableImpl! {
707     impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::DelayedLiteral<C> {
708         (chalk_engine::DelayedLiteral::CannotProve)(a),
709         (chalk_engine::DelayedLiteral::Negative)(a),
710         (chalk_engine::DelayedLiteral::Positive)(a, b),
711     } where
712         C: chalk_engine::context::Context + Clone,
713         C::CanonicalConstrainedSubst: TypeFoldable<'tcx>,
714 }
715
716 EnumTypeFoldableImpl! {
717     impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::Literal<C> {
718         (chalk_engine::Literal::Negative)(a),
719         (chalk_engine::Literal::Positive)(a),
720     } where
721         C: chalk_engine::context::Context + Clone,
722         C::GoalInEnvironment: Clone + TypeFoldable<'tcx>,
723 }
724
725 CloneTypeFoldableAndLiftImpls! {
726     chalk_engine::TableIndex,
727 }