diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index f0787fc7b1f..448f8ed8ddc 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -1164,14 +1164,26 @@ where ) -> bool; } -pub trait ExClauseLift<'tcx> +pub trait ChalkContextLift<'tcx> where Self: chalk_engine::context::Context + Clone, { type LiftedExClause: Debug + 'tcx; + type LiftedDelayedLiteral: Debug + 'tcx; + type LiftedLiteral: Debug + 'tcx; fn lift_ex_clause_to_tcx<'a, 'gcx>( ex_clause: &chalk_engine::ExClause, tcx: TyCtxt<'a, 'gcx, 'tcx>, ) -> Option; + + fn lift_delayed_literal_to_tcx<'a, 'gcx>( + ex_clause: &chalk_engine::DelayedLiteral, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + ) -> Option; + + fn lift_literal_to_tcx<'a, 'gcx>( + ex_clause: &chalk_engine::Literal, + tcx: TyCtxt<'a, 'gcx, 'tcx>, + ) -> Option; } diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 533fb4d14b8..3b74b251688 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -700,12 +700,36 @@ impl<'a, 'tcx, G: Lift<'tcx>> Lift<'tcx> for traits::InEnvironment<'a, G> { impl<'tcx, C> Lift<'tcx> for chalk_engine::ExClause where C: chalk_engine::context::Context + Clone, - C: traits::ExClauseLift<'tcx>, + C: traits::ChalkContextLift<'tcx>, { type Lifted = C::LiftedExClause; fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option { - ::lift_ex_clause_to_tcx(self, tcx) + ::lift_ex_clause_to_tcx(self, tcx) + } +} + +impl<'tcx, C> Lift<'tcx> for chalk_engine::DelayedLiteral +where + C: chalk_engine::context::Context + Clone, + C: traits::ChalkContextLift<'tcx>, +{ + type Lifted = C::LiftedDelayedLiteral; + + fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option { + ::lift_delayed_literal_to_tcx(self, tcx) + } +} + +impl<'tcx, C> Lift<'tcx> for chalk_engine::Literal +where + C: chalk_engine::context::Context + Clone, + C: traits::ChalkContextLift<'tcx>, +{ + type Lifted = C::LiftedLiteral; + + fn lift_to_tcx<'a, 'gcx>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Option { + ::lift_literal_to_tcx(self, tcx) } } diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 41b7e73e553..2384cbce1ab 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -21,7 +21,7 @@ use rustc::infer::canonical::{ use rustc::traits::{ DomainGoal, ExClauseFold, - ExClauseLift, + ChalkContextLift, Goal, GoalKind, Clause, @@ -441,9 +441,12 @@ impl context::UnificationOps, ChalkArenas<'tcx>> fn lift_delayed_literal( &self, - _value: DelayedLiteral>, + value: DelayedLiteral>, ) -> DelayedLiteral> { - panic!("lift") + match self.infcx.tcx.lift_to_global(&value) { + Some(literal) => literal, + None => bug!("cannot lift {:?}", value), + } } fn into_ex_clause( @@ -478,14 +481,45 @@ impl Debug for ChalkInferenceContext<'cx, 'gcx, 'tcx> { } } -impl ExClauseLift<'gcx> for ChalkArenas<'a> { - type LiftedExClause = ChalkExClause<'gcx>; +impl ChalkContextLift<'tcx> for ChalkArenas<'a> { + type LiftedExClause = ChalkExClause<'tcx>; + type LiftedDelayedLiteral = DelayedLiteral>; + type LiftedLiteral = Literal>; fn lift_ex_clause_to_tcx( - _ex_clause: &ChalkExClause<'a>, - _tcx: TyCtxt<'_, '_, 'tcx>, + ex_clause: &ChalkExClause<'a>, + tcx: TyCtxt<'_, 'gcx, 'tcx> ) -> Option { - panic!() + Some(ChalkExClause { + subst: tcx.lift(&ex_clause.subst)?, + delayed_literals: tcx.lift(&ex_clause.delayed_literals)?, + constraints: tcx.lift(&ex_clause.constraints)?, + subgoals: tcx.lift(&ex_clause.subgoals)?, + }) + } + + fn lift_delayed_literal_to_tcx( + literal: &DelayedLiteral>, + tcx: TyCtxt<'_, 'gcx, 'tcx> + ) -> Option { + Some(match literal { + DelayedLiteral::CannotProve(()) => DelayedLiteral::CannotProve(()), + DelayedLiteral::Negative(index) => DelayedLiteral::Negative(*index), + DelayedLiteral::Positive(index, subst) => DelayedLiteral::Positive( + *index, + tcx.lift(subst)? + ) + }) + } + + fn lift_literal_to_tcx( + literal: &Literal>, + tcx: TyCtxt<'_, 'gcx, 'tcx>, + ) -> Option { + Some(match literal { + Literal::Negative(goal) => Literal::Negative(tcx.lift(goal)?), + Literal::Positive(goal) => Literal::Positive(tcx.lift(goal)?), + }) } }