2 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
3 use crate::ty::{self, Lift, Ty, TyCtxt};
4 use rustc_span::symbol::Symbol;
5 use smallvec::SmallVec;
7 use std::collections::{BTreeMap, BTreeSet};
11 // Structural impls for the structs in `traits`.
13 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::Vtable<'tcx, N> {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 super::VtableImpl(ref v) => write!(f, "{:?}", v),
18 super::VtableAutoImpl(ref t) => write!(f, "{:?}", t),
20 super::VtableClosure(ref d) => write!(f, "{:?}", d),
22 super::VtableGenerator(ref d) => write!(f, "{:?}", d),
24 super::VtableFnPointer(ref d) => write!(f, "VtableFnPointer({:?})", d),
26 super::VtableObject(ref d) => write!(f, "{:?}", d),
28 super::VtableParam(ref n) => write!(f, "VtableParam({:?})", n),
30 super::VtableBuiltin(ref d) => write!(f, "{:?}", d),
32 super::VtableTraitAlias(ref d) => write!(f, "{:?}", d),
37 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 "VtableImplData(impl_def_id={:?}, substs={:?}, nested={:?})",
42 self.impl_def_id, self.substs, self.nested
47 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 "VtableGeneratorData(generator_def_id={:?}, substs={:?}, nested={:?})",
52 self.generator_def_id, self.substs, self.nested
57 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableClosureData<'tcx, N> {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 "VtableClosureData(closure_def_id={:?}, substs={:?}, nested={:?})",
62 self.closure_def_id, self.substs, self.nested
67 impl<N: fmt::Debug> fmt::Debug for traits::VtableBuiltinData<N> {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 write!(f, "VtableBuiltinData(nested={:?})", self.nested)
73 impl<N: fmt::Debug> fmt::Debug for traits::VtableAutoImplData<N> {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77 "VtableAutoImplData(trait_def_id={:?}, nested={:?})",
78 self.trait_def_id, self.nested
83 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableObjectData<'tcx, N> {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 "VtableObjectData(upcast={:?}, vtable_base={}, nested={:?})",
88 self.upcast_trait_ref, self.vtable_base, self.nested
93 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableFnPointerData<'tcx, N> {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 write!(f, "VtableFnPointerData(fn_ty={:?}, nested={:?})", self.fn_ty, self.nested)
99 impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableTraitAliasData<'tcx, N> {
100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 "VtableTraitAlias(alias_def_id={:?}, substs={:?}, nested={:?})",
104 self.alias_def_id, self.substs, self.nested
109 impl<'tcx> fmt::Display for traits::WhereClause<'tcx> {
110 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
111 use crate::traits::WhereClause::*;
113 // Bypass `ty::print` because it does not print out anonymous regions.
114 // FIXME(eddyb) implement a custom `PrettyPrinter`, or move this to `ty::print`.
115 fn write_region_name<'tcx>(
117 fmt: &mut fmt::Formatter<'_>,
120 ty::ReLateBound(index, br) => match br {
121 ty::BoundRegion::BrNamed(_, name) => write!(fmt, "{}", name),
122 ty::BoundRegion::BrAnon(var) => {
123 if *index == ty::INNERMOST {
124 write!(fmt, "'^{}", var)
126 write!(fmt, "'^{}_{}", index.index(), var)
129 _ => write!(fmt, "'_"),
132 _ => write!(fmt, "{}", r),
137 Implemented(trait_ref) => write!(fmt, "Implemented({})", trait_ref),
138 ProjectionEq(projection) => write!(fmt, "ProjectionEq({})", projection),
139 RegionOutlives(predicate) => {
140 write!(fmt, "RegionOutlives({}: ", predicate.0)?;
141 write_region_name(predicate.1, fmt)?;
144 TypeOutlives(predicate) => {
145 write!(fmt, "TypeOutlives({}: ", predicate.0)?;
146 write_region_name(predicate.1, fmt)?;
153 impl<'tcx> fmt::Display for traits::WellFormed<'tcx> {
154 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
155 use crate::traits::WellFormed::*;
158 Trait(trait_ref) => write!(fmt, "WellFormed({})", trait_ref),
159 Ty(ty) => write!(fmt, "WellFormed({})", ty),
164 impl<'tcx> fmt::Display for traits::FromEnv<'tcx> {
165 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
166 use crate::traits::FromEnv::*;
169 Trait(trait_ref) => write!(fmt, "FromEnv({})", trait_ref),
170 Ty(ty) => write!(fmt, "FromEnv({})", ty),
175 impl<'tcx> fmt::Display for traits::DomainGoal<'tcx> {
176 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
177 use crate::traits::DomainGoal::*;
180 Holds(wc) => write!(fmt, "{}", wc),
181 WellFormed(wf) => write!(fmt, "{}", wf),
182 FromEnv(from_env) => write!(fmt, "{}", from_env),
183 Normalize(projection) => {
184 write!(fmt, "Normalize({} -> {})", projection.projection_ty, projection.ty)
190 impl fmt::Display for traits::QuantifierKind {
191 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
192 use crate::traits::QuantifierKind::*;
195 Universal => write!(fmt, "forall"),
196 Existential => write!(fmt, "exists"),
201 /// Collect names for regions / types bound by a quantified goal / clause.
202 /// This collector does not try to do anything clever like in `ty::print`, it's just used
203 /// for debug output in tests anyway.
204 struct BoundNamesCollector {
205 // Just sort by name because `BoundRegion::BrNamed` does not have a `BoundVar` index anyway.
206 regions: BTreeSet<Symbol>,
208 // Sort by `BoundVar` index, so usually this should be equivalent to the order given
209 // by the list of type parameters.
210 types: BTreeMap<u32, Symbol>,
212 binder_index: ty::DebruijnIndex,
215 impl BoundNamesCollector {
217 BoundNamesCollector {
218 regions: BTreeSet::new(),
219 types: BTreeMap::new(),
220 binder_index: ty::INNERMOST,
224 fn is_empty(&self) -> bool {
225 self.regions.is_empty() && self.types.is_empty()
228 fn write_names(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
229 let mut start = true;
230 for r in &self.regions {
235 write!(fmt, "{}", r)?;
237 for (_, t) in &self.types {
242 write!(fmt, "{}", t)?;
248 impl<'tcx> TypeVisitor<'tcx> for BoundNamesCollector {
249 fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> bool {
250 self.binder_index.shift_in(1);
251 let result = t.super_visit_with(self);
252 self.binder_index.shift_out(1);
256 fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
258 ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
260 bound_ty.var.as_u32(),
261 match bound_ty.kind {
262 ty::BoundTyKind::Param(name) => name,
263 ty::BoundTyKind::Anon => {
264 Symbol::intern(&format!("^{}", bound_ty.var.as_u32()))
273 t.super_visit_with(self)
276 fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
278 ty::ReLateBound(index, br) if *index == self.binder_index => match br {
279 ty::BoundRegion::BrNamed(_, name) => {
280 self.regions.insert(*name);
283 ty::BoundRegion::BrAnon(var) => {
284 self.regions.insert(Symbol::intern(&format!("'^{}", var)));
293 r.super_visit_with(self)
297 impl<'tcx> fmt::Display for traits::Goal<'tcx> {
298 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
299 use crate::traits::GoalKind::*;
302 Implies(hypotheses, goal) => {
303 write!(fmt, "if (")?;
304 for (index, hyp) in hypotheses.iter().enumerate() {
308 write!(fmt, "{}", hyp)?;
310 write!(fmt, ") {{ {} }}", goal)
312 And(goal1, goal2) => write!(fmt, "({} && {})", goal1, goal2),
313 Not(goal) => write!(fmt, "not {{ {} }}", goal),
314 DomainGoal(goal) => write!(fmt, "{}", goal),
315 Quantified(qkind, goal) => {
316 let mut collector = BoundNamesCollector::new();
317 goal.skip_binder().visit_with(&mut collector);
319 if !collector.is_empty() {
320 write!(fmt, "{}<", qkind)?;
321 collector.write_names(fmt)?;
322 write!(fmt, "> {{ ")?;
325 write!(fmt, "{}", goal.skip_binder())?;
327 if !collector.is_empty() {
333 Subtype(a, b) => write!(fmt, "{} <: {}", a, b),
334 CannotProve => write!(fmt, "CannotProve"),
339 impl<'tcx> fmt::Display for traits::ProgramClause<'tcx> {
340 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
341 let traits::ProgramClause { goal, hypotheses, .. } = self;
342 write!(fmt, "{}", goal)?;
343 if !hypotheses.is_empty() {
344 write!(fmt, " :- ")?;
345 for (index, condition) in hypotheses.iter().enumerate() {
349 write!(fmt, "{}", condition)?;
356 impl<'tcx> fmt::Display for traits::Clause<'tcx> {
357 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
358 use crate::traits::Clause::*;
361 Implies(clause) => write!(fmt, "{}", clause),
363 let mut collector = BoundNamesCollector::new();
364 clause.skip_binder().visit_with(&mut collector);
366 if !collector.is_empty() {
367 write!(fmt, "forall<")?;
368 collector.write_names(fmt)?;
369 write!(fmt, "> {{ ")?;
372 write!(fmt, "{}", clause.skip_binder())?;
374 if !collector.is_empty() {
384 ///////////////////////////////////////////////////////////////////////////
385 // Lift implementations
387 impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
388 type Lifted = traits::SelectionError<'tcx>;
389 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
391 super::Unimplemented => Some(super::Unimplemented),
392 super::OutputTypeParameterMismatch(a, b, ref err) => {
393 tcx.lift(&(a, b)).and_then(|(a, b)| {
394 tcx.lift(err).map(|err| super::OutputTypeParameterMismatch(a, b, err))
397 super::TraitNotObjectSafe(def_id) => Some(super::TraitNotObjectSafe(def_id)),
398 super::ConstEvalFailure(err) => Some(super::ConstEvalFailure(err)),
399 super::Overflow => Some(super::Overflow),
404 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
405 type Lifted = traits::ObligationCauseCode<'tcx>;
406 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
408 super::ReturnNoExpression => Some(super::ReturnNoExpression),
409 super::MiscObligation => Some(super::MiscObligation),
410 super::SliceOrArrayElem => Some(super::SliceOrArrayElem),
411 super::TupleElem => Some(super::TupleElem),
412 super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf),
413 super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)),
414 super::BindingObligation(def_id, span) => Some(super::BindingObligation(def_id, span)),
415 super::ReferenceOutlivesReferent(ty) => {
416 tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
418 super::ObjectTypeBound(ty, r) => tcx
420 .and_then(|ty| tcx.lift(&r).and_then(|r| Some(super::ObjectTypeBound(ty, r)))),
421 super::ObjectCastObligation(ty) => tcx.lift(&ty).map(super::ObjectCastObligation),
422 super::Coercion { source, target } => {
423 Some(super::Coercion { source: tcx.lift(&source)?, target: tcx.lift(&target)? })
425 super::AssignmentLhsSized => Some(super::AssignmentLhsSized),
426 super::TupleInitializerSized => Some(super::TupleInitializerSized),
427 super::StructInitializerSized => Some(super::StructInitializerSized),
428 super::VariableType(id) => Some(super::VariableType(id)),
429 super::ReturnValue(id) => Some(super::ReturnValue(id)),
430 super::ReturnType => Some(super::ReturnType),
431 super::SizedArgumentType => Some(super::SizedArgumentType),
432 super::SizedReturnType => Some(super::SizedReturnType),
433 super::SizedYieldType => Some(super::SizedYieldType),
434 super::RepeatVec(suggest_flag) => Some(super::RepeatVec(suggest_flag)),
435 super::FieldSized { adt_kind, last } => Some(super::FieldSized { adt_kind, last }),
436 super::ConstSized => Some(super::ConstSized),
437 super::ConstPatternStructural => Some(super::ConstPatternStructural),
438 super::SharedStatic => Some(super::SharedStatic),
439 super::BuiltinDerivedObligation(ref cause) => {
440 tcx.lift(cause).map(super::BuiltinDerivedObligation)
442 super::ImplDerivedObligation(ref cause) => {
443 tcx.lift(cause).map(super::ImplDerivedObligation)
445 super::CompareImplMethodObligation {
449 } => Some(super::CompareImplMethodObligation {
454 super::CompareImplTypeObligation { item_name, impl_item_def_id, trait_item_def_id } => {
455 Some(super::CompareImplTypeObligation {
461 super::ExprAssignable => Some(super::ExprAssignable),
462 super::MatchExpressionArm(box super::MatchExpressionArmCause {
468 }) => tcx.lift(&last_ty).map(|last_ty| {
469 super::MatchExpressionArm(box super::MatchExpressionArmCause {
472 prior_arms: prior_arms.clone(),
477 super::Pattern { span, root_ty, origin_expr } => {
478 tcx.lift(&root_ty).map(|root_ty| super::Pattern { span, root_ty, origin_expr })
480 super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => {
481 Some(super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }))
483 super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
484 super::MainFunctionType => Some(super::MainFunctionType),
485 super::StartFunctionType => Some(super::StartFunctionType),
486 super::IntrinsicType => Some(super::IntrinsicType),
487 super::MethodReceiver => Some(super::MethodReceiver),
488 super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
489 super::TrivialBound => Some(super::TrivialBound),
490 super::AssocTypeBound(ref data) => Some(super::AssocTypeBound(data.clone())),
495 impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> {
496 type Lifted = traits::DerivedObligationCause<'tcx>;
497 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
498 tcx.lift(&self.parent_trait_ref).and_then(|trait_ref| {
499 tcx.lift(&*self.parent_code).map(|code| traits::DerivedObligationCause {
500 parent_trait_ref: trait_ref,
501 parent_code: Rc::new(code),
507 impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> {
508 type Lifted = traits::ObligationCause<'tcx>;
509 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
510 tcx.lift(&self.code).map(|code| traits::ObligationCause {
512 body_id: self.body_id,
519 impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
520 type Lifted = traits::Vtable<'tcx, ()>;
521 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
523 traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested }) => {
524 tcx.lift(&substs).map(|substs| {
525 traits::VtableImpl(traits::VtableImplData { impl_def_id, substs, nested })
528 traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
529 traits::VtableGenerator(traits::VtableGeneratorData {
533 }) => tcx.lift(&substs).map(|substs| {
534 traits::VtableGenerator(traits::VtableGeneratorData {
535 generator_def_id: generator_def_id,
540 traits::VtableClosure(traits::VtableClosureData { closure_def_id, substs, nested }) => {
541 tcx.lift(&substs).map(|substs| {
542 traits::VtableClosure(traits::VtableClosureData {
549 traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested }) => {
550 tcx.lift(&fn_ty).map(|fn_ty| {
551 traits::VtableFnPointer(traits::VtableFnPointerData { fn_ty, nested })
554 traits::VtableParam(n) => Some(traits::VtableParam(n)),
555 traits::VtableBuiltin(n) => Some(traits::VtableBuiltin(n)),
556 traits::VtableObject(traits::VtableObjectData {
560 }) => tcx.lift(&upcast_trait_ref).map(|trait_ref| {
561 traits::VtableObject(traits::VtableObjectData {
562 upcast_trait_ref: trait_ref,
567 traits::VtableTraitAlias(traits::VtableTraitAliasData {
571 }) => tcx.lift(&substs).map(|substs| {
572 traits::VtableTraitAlias(traits::VtableTraitAliasData {
582 impl<'a, 'tcx> Lift<'tcx> for traits::Environment<'a> {
583 type Lifted = traits::Environment<'tcx>;
584 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
585 tcx.lift(&self.clauses).map(|clauses| traits::Environment { clauses })
589 impl<'a, 'tcx, G: Lift<'tcx>> Lift<'tcx> for traits::InEnvironment<'a, G> {
590 type Lifted = traits::InEnvironment<'tcx, G::Lifted>;
591 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
592 tcx.lift(&self.environment).and_then(|environment| {
593 tcx.lift(&self.goal).map(|goal| traits::InEnvironment { environment, goal })
598 impl<'tcx, C> Lift<'tcx> for chalk_engine::ExClause<C>
600 C: chalk_engine::context::Context + Clone,
601 C: traits::ChalkContextLift<'tcx>,
603 type Lifted = C::LiftedExClause;
605 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
606 <C as traits::ChalkContextLift>::lift_ex_clause_to_tcx(self, tcx)
610 impl<'tcx, C> Lift<'tcx> for chalk_engine::DelayedLiteral<C>
612 C: chalk_engine::context::Context + Clone,
613 C: traits::ChalkContextLift<'tcx>,
615 type Lifted = C::LiftedDelayedLiteral;
617 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
618 <C as traits::ChalkContextLift>::lift_delayed_literal_to_tcx(self, tcx)
622 impl<'tcx, C> Lift<'tcx> for chalk_engine::Literal<C>
624 C: chalk_engine::context::Context + Clone,
625 C: traits::ChalkContextLift<'tcx>,
627 type Lifted = C::LiftedLiteral;
629 fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
630 <C as traits::ChalkContextLift>::lift_literal_to_tcx(self, tcx)
634 ///////////////////////////////////////////////////////////////////////////
635 // TypeFoldable implementations.
637 CloneTypeFoldableAndLiftImpls! {
638 traits::QuantifierKind,
641 impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<traits::Goal<'tcx>> {
642 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
643 let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
644 folder.tcx().intern_goals(&v)
647 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
648 self.iter().any(|t| t.visit_with(visitor))
652 impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> {
653 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
654 let v = (**self).fold_with(folder);
655 folder.tcx().mk_goal(v)
658 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
659 (**self).visit_with(visitor)
663 CloneTypeFoldableAndLiftImpls! {
664 traits::ProgramClauseCategory,
667 impl<'tcx> TypeFoldable<'tcx> for traits::Clauses<'tcx> {
668 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
669 let v = self.iter().map(|t| t.fold_with(folder)).collect::<SmallVec<[_; 8]>>();
670 folder.tcx().intern_clauses(&v)
673 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
674 self.iter().any(|t| t.visit_with(visitor))
678 impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::ExClause<C>
680 C: traits::ExClauseFold<'tcx>,
681 C::Substitution: Clone,
682 C::RegionConstraint: Clone,
684 fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
685 <C as traits::ExClauseFold>::fold_ex_clause_with(self, folder)
688 fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
689 <C as traits::ExClauseFold>::visit_ex_clause_with(self, visitor)
693 EnumTypeFoldableImpl! {
694 impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::DelayedLiteral<C> {
695 (chalk_engine::DelayedLiteral::CannotProve)(a),
696 (chalk_engine::DelayedLiteral::Negative)(a),
697 (chalk_engine::DelayedLiteral::Positive)(a, b),
699 C: chalk_engine::context::Context<CanonicalConstrainedSubst: TypeFoldable<'tcx>> + Clone,
702 EnumTypeFoldableImpl! {
703 impl<'tcx, C> TypeFoldable<'tcx> for chalk_engine::Literal<C> {
704 (chalk_engine::Literal::Negative)(a),
705 (chalk_engine::Literal::Positive)(a),
707 C: chalk_engine::context::Context<GoalInEnvironment: Clone + TypeFoldable<'tcx>> + Clone,
710 CloneTypeFoldableAndLiftImpls! {
711 chalk_engine::TableIndex,