1111mod program_clauses;
1212
1313use chalk_engine:: fallible:: Fallible as ChalkEngineFallible ;
14- use chalk_engine:: { context, hh:: HhGoal , DelayedLiteral , ExClause } ;
14+ use chalk_engine:: { context, hh:: HhGoal , DelayedLiteral , Literal , ExClause } ;
1515use rustc:: infer:: canonical:: {
1616 Canonical , CanonicalVarValues , OriginalQueryValues , QueryRegionConstraint , QueryResponse ,
1717} ;
@@ -28,7 +28,7 @@ use rustc::traits::{
2828 InEnvironment ,
2929} ;
3030use rustc:: ty:: fold:: { TypeFoldable , TypeFolder , TypeVisitor } ;
31- use rustc:: ty:: subst:: Kind ;
31+ use rustc:: ty:: subst:: { Kind , UnpackedKind } ;
3232use rustc:: ty:: { self , TyCtxt } ;
3333
3434use std:: fmt:: { self , Debug } ;
@@ -44,7 +44,7 @@ crate struct ChalkArenas<'gcx> {
4444#[ derive( Copy , Clone ) ]
4545crate struct ChalkContext < ' cx , ' gcx : ' cx > {
4646 _arenas : ChalkArenas < ' gcx > ,
47- _tcx : TyCtxt < ' cx , ' gcx , ' gcx > ,
47+ tcx : TyCtxt < ' cx , ' gcx , ' gcx > ,
4848}
4949
5050#[ derive( Copy , Clone ) ]
@@ -68,7 +68,7 @@ BraceStructTypeFoldableImpl! {
6868}
6969
7070impl context:: Context for ChalkArenas < ' tcx > {
71- type CanonicalExClause = Canonical < ' tcx , ExClause < Self > > ;
71+ type CanonicalExClause = Canonical < ' tcx , ChalkExClause < ' tcx > > ;
7272
7373 type CanonicalGoalInEnvironment = Canonical < ' tcx , InEnvironment < ' tcx , Goal < ' tcx > > > ;
7474
@@ -147,19 +147,29 @@ impl context::ContextOps<ChalkArenas<'gcx>> for ChalkContext<'cx, 'gcx> {
147147 /// - the environment and goal found by substitution `S` into `arg`
148148 fn instantiate_ucanonical_goal < R > (
149149 & self ,
150- _arg : & Canonical < ' gcx , InEnvironment < ' gcx , Goal < ' gcx > > > ,
151- _op : impl context:: WithInstantiatedUCanonicalGoal < ChalkArenas < ' gcx > , Output = R > ,
150+ arg : & Canonical < ' gcx , InEnvironment < ' gcx , Goal < ' gcx > > > ,
151+ op : impl context:: WithInstantiatedUCanonicalGoal < ChalkArenas < ' gcx > , Output = R > ,
152152 ) -> R {
153- unimplemented ! ( )
153+ self . tcx . infer_ctxt ( ) . enter_with_canonical ( DUMMY_SP , arg, |ref infcx, arg, subst| {
154+ let chalk_infcx = & mut ChalkInferenceContext {
155+ infcx,
156+ } ;
157+ op. with ( chalk_infcx, subst, arg. environment , arg. goal )
158+ } )
154159 }
155160
156161 fn instantiate_ex_clause < R > (
157162 & self ,
158163 _num_universes : usize ,
159- _canonical_ex_clause : & Canonical < ' gcx , ChalkExClause < ' gcx > > ,
160- _op : impl context:: WithInstantiatedExClause < ChalkArenas < ' gcx > , Output = R > ,
164+ arg : & Canonical < ' gcx , ChalkExClause < ' gcx > > ,
165+ op : impl context:: WithInstantiatedExClause < ChalkArenas < ' gcx > , Output = R > ,
161166 ) -> R {
162- unimplemented ! ( )
167+ self . tcx . infer_ctxt ( ) . enter_with_canonical ( DUMMY_SP , & arg. upcast ( ) , |ref infcx, arg, _| {
168+ let chalk_infcx = & mut ChalkInferenceContext {
169+ infcx,
170+ } ;
171+ op. with ( chalk_infcx, arg)
172+ } )
163173 }
164174
165175 /// True if this solution has no region constraints.
@@ -186,14 +196,33 @@ impl context::ContextOps<ChalkArenas<'gcx>> for ChalkContext<'cx, 'gcx> {
186196 }
187197
188198 fn is_trivial_substitution (
189- _u_canon : & Canonical < ' gcx , InEnvironment < ' gcx , Goal < ' gcx > > > ,
190- _canonical_subst : & Canonical < ' gcx , ConstrainedSubst < ' gcx > > ,
199+ u_canon : & Canonical < ' gcx , InEnvironment < ' gcx , Goal < ' gcx > > > ,
200+ canonical_subst : & Canonical < ' tcx , ConstrainedSubst < ' tcx > > ,
191201 ) -> bool {
192- unimplemented ! ( )
193- }
194-
195- fn num_universes ( _: & Canonical < ' gcx , InEnvironment < ' gcx , Goal < ' gcx > > > ) -> usize {
196- 0 // FIXME
202+ let subst = & canonical_subst. value . subst ;
203+ assert_eq ! ( u_canon. variables. len( ) , subst. var_values. len( ) ) ;
204+ subst. var_values
205+ . iter_enumerated ( )
206+ . all ( |( cvar, kind) | match kind. unpack ( ) {
207+ UnpackedKind :: Lifetime ( r) => match r {
208+ & ty:: ReLateBound ( debruijn, br) => {
209+ debug_assert_eq ! ( debruijn, ty:: INNERMOST ) ;
210+ cvar == br. assert_bound_var ( )
211+ }
212+ _ => false ,
213+ } ,
214+ UnpackedKind :: Type ( ty) => match ty. sty {
215+ ty:: Bound ( debruijn, bound_ty) => {
216+ debug_assert_eq ! ( debruijn, ty:: INNERMOST ) ;
217+ cvar == bound_ty. var
218+ }
219+ _ => false ,
220+ } ,
221+ } )
222+ }
223+
224+ fn num_universes ( canon : & Canonical < ' gcx , InEnvironment < ' gcx , Goal < ' gcx > > > ) -> usize {
225+ canon. max_universe . index ( ) + 1
197226 }
198227
199228 /// Convert a goal G *from* the canonical universes *into* our
@@ -214,39 +243,6 @@ impl context::ContextOps<ChalkArenas<'gcx>> for ChalkContext<'cx, 'gcx> {
214243 }
215244}
216245
217- //impl context::UCanonicalGoalInEnvironment<ChalkContext<'cx, 'gcx>>
218- // for Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>>
219- //{
220- // fn canonical(&self) -> &Canonical<'gcx, ty::ParamEnvAnd<'gcx, Goal<'gcx>>> {
221- // self
222- // }
223- //
224- // fn is_trivial_substitution(
225- // &self,
226- // canonical_subst: &Canonical<'tcx, ConstrainedSubst<'tcx>>,
227- // ) -> bool {
228- // let subst = &canonical_subst.value.subst;
229- // assert_eq!(self.canonical.variables.len(), subst.var_values.len());
230- // subst
231- // .var_values
232- // .iter_enumerated()
233- // .all(|(cvar, kind)| match kind.unpack() {
234- // Kind::Lifetime(r) => match r {
235- // ty::ReCanonical(cvar1) => cvar == cvar1,
236- // _ => false,
237- // },
238- // Kind::Type(ty) => match ty.sty {
239- // ty::Infer(ty::InferTy::CanonicalTy(cvar1)) => cvar == cvar1,
240- // _ => false,
241- // },
242- // })
243- // }
244- //
245- // fn num_universes(&self) -> usize {
246- // 0 // FIXME
247- // }
248- //}
249-
250246impl context:: InferenceTable < ChalkArenas < ' gcx > , ChalkArenas < ' tcx > >
251247 for ChalkInferenceContext < ' cx , ' gcx , ' tcx >
252248{
@@ -338,9 +334,9 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
338334
339335 fn instantiate_binders_universally (
340336 & mut self ,
341- _arg : & ty:: Binder < Goal < ' tcx > > ,
337+ arg : & ty:: Binder < Goal < ' tcx > > ,
342338 ) -> Goal < ' tcx > {
343- panic ! ( "FIXME -- universal instantiation needs sgrif's branch" )
339+ self . infcx . replace_bound_vars_with_placeholders ( arg ) . 0
344340 }
345341
346342 fn instantiate_binders_existentially (
@@ -491,3 +487,68 @@ BraceStructLiftImpl! {
491487 subst, constraints
492488 }
493489}
490+
491+ trait Upcast < ' tcx , ' gcx : ' tcx > : ' gcx {
492+ type Upcasted : ' tcx ;
493+
494+ fn upcast ( & self ) -> Self :: Upcasted ;
495+ }
496+
497+ impl < ' tcx , ' gcx : ' tcx > Upcast < ' tcx , ' gcx > for DelayedLiteral < ChalkArenas < ' gcx > > {
498+ type Upcasted = DelayedLiteral < ChalkArenas < ' tcx > > ;
499+
500+ fn upcast ( & self ) -> Self :: Upcasted {
501+ match self {
502+ & DelayedLiteral :: CannotProve ( ..) => DelayedLiteral :: CannotProve ( ( ) ) ,
503+ & DelayedLiteral :: Negative ( index) => DelayedLiteral :: Negative ( index) ,
504+ DelayedLiteral :: Positive ( index, subst) => DelayedLiteral :: Positive (
505+ * index,
506+ subst. clone ( )
507+ ) ,
508+ }
509+ }
510+ }
511+
512+ impl < ' tcx , ' gcx : ' tcx > Upcast < ' tcx , ' gcx > for Literal < ChalkArenas < ' gcx > > {
513+ type Upcasted = Literal < ChalkArenas < ' tcx > > ;
514+
515+ fn upcast ( & self ) -> Self :: Upcasted {
516+ match self {
517+ & Literal :: Negative ( goal) => Literal :: Negative ( goal) ,
518+ & Literal :: Positive ( goal) => Literal :: Positive ( goal) ,
519+ }
520+ }
521+ }
522+
523+ impl < ' tcx , ' gcx : ' tcx > Upcast < ' tcx , ' gcx > for ExClause < ChalkArenas < ' gcx > > {
524+ type Upcasted = ExClause < ChalkArenas < ' tcx > > ;
525+
526+ fn upcast ( & self ) -> Self :: Upcasted {
527+ ExClause {
528+ subst : self . subst . clone ( ) ,
529+ delayed_literals : self . delayed_literals
530+ . iter ( )
531+ . map ( |l| l. upcast ( ) )
532+ . collect ( ) ,
533+ constraints : self . constraints . clone ( ) ,
534+ subgoals : self . subgoals
535+ . iter ( )
536+ . map ( |g| g. upcast ( ) )
537+ . collect ( ) ,
538+ }
539+ }
540+ }
541+
542+ impl < ' tcx , ' gcx : ' tcx , T > Upcast < ' tcx , ' gcx > for Canonical < ' gcx , T >
543+ where T : Upcast < ' tcx , ' gcx >
544+ {
545+ type Upcasted = Canonical < ' tcx , T :: Upcasted > ;
546+
547+ fn upcast ( & self ) -> Self :: Upcasted {
548+ Canonical {
549+ max_universe : self . max_universe ,
550+ value : self . value . upcast ( ) ,
551+ variables : self . variables ,
552+ }
553+ }
554+ }
0 commit comments