Skip to content

Commit 3b1f74c

Browse files
committed
Implement some instantiate / canonical routines
1 parent 05f1847 commit 3b1f74c

File tree

1 file changed

+113
-52
lines changed
  • src/librustc_traits/chalk_context

1 file changed

+113
-52
lines changed

src/librustc_traits/chalk_context/mod.rs

+113-52
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
mod program_clauses;
1212

1313
use 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};
1515
use rustc::infer::canonical::{
1616
Canonical, CanonicalVarValues, OriginalQueryValues, QueryRegionConstraint, QueryResponse,
1717
};
@@ -28,7 +28,7 @@ use rustc::traits::{
2828
InEnvironment,
2929
};
3030
use rustc::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
31-
use rustc::ty::subst::Kind;
31+
use rustc::ty::subst::{Kind, UnpackedKind};
3232
use rustc::ty::{self, TyCtxt};
3333

3434
use std::fmt::{self, Debug};
@@ -44,7 +44,7 @@ crate struct ChalkArenas<'gcx> {
4444
#[derive(Copy, Clone)]
4545
crate 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

7070
impl 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-
250246
impl 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

Comments
 (0)