1 use chalk_ir
::fold
::shift
::Shift
;
2 use chalk_ir
::fold
::{Fold, Folder}
;
3 use chalk_ir
::interner
::Interner
;
5 use chalk_solve
::infer
::InferenceTable
;
7 pub(crate) struct DeepNormalizer
<'table
, 'i
, I
: Interner
> {
8 table
: &'table
mut InferenceTable
<I
>,
12 impl<I
: Interner
> DeepNormalizer
<'_
, '_
, I
> {
13 /// Given a value `value` with variables in it, replaces those variables
14 /// with their instantiated values (if any). Uninstantiated variables are
17 /// This is mainly intended for getting final values to dump to
18 /// the user and its use should otherwise be avoided, particularly
19 /// given the possibility of snapshots and rollbacks.
21 /// See also `InferenceTable::canonicalize`, which -- during real
22 /// processing -- is often used to capture the "current state" of
24 pub fn normalize_deep
<T
: Fold
<I
>>(
25 table
: &mut InferenceTable
<I
>,
31 &mut DeepNormalizer { interner, table }
,
32 DebruijnIndex
::INNERMOST
,
38 impl<'i
, I
: Interner
> Folder
<'i
, I
> for DeepNormalizer
<'_
, 'i
, I
>
42 fn as_dyn(&mut self) -> &mut dyn Folder
<'i
, I
> {
50 _outer_binder
: DebruijnIndex
,
51 ) -> Fallible
<Ty
<I
>> {
52 let interner
= self.interner
;
53 match self.table
.probe_var(var
) {
55 .assert_ty_ref(interner
)
56 .fold_with(self, DebruijnIndex
::INNERMOST
)?
57 .shifted_in(interner
)), // FIXME shift
58 None
=> Ok(var
.to_ty(interner
, kind
)),
62 fn fold_inference_lifetime(
65 _outer_binder
: DebruijnIndex
,
66 ) -> Fallible
<Lifetime
<I
>> {
67 let interner
= self.interner
;
68 match self.table
.probe_var(var
) {
70 .assert_lifetime_ref(interner
)
71 .fold_with(self, DebruijnIndex
::INNERMOST
)?
72 .shifted_in(interner
)),
73 None
=> Ok(var
.to_lifetime(interner
)), // FIXME shift
77 fn fold_inference_const(
81 _outer_binder
: DebruijnIndex
,
82 ) -> Fallible
<Const
<I
>> {
83 let interner
= self.interner
;
84 match self.table
.probe_var(var
) {
86 .assert_const_ref(interner
)
87 .fold_with(self, DebruijnIndex
::INNERMOST
)?
88 .shifted_in(interner
)),
89 None
=> Ok(var
.to_const(interner
, ty
.clone())), // FIXME shift
93 fn forbid_free_vars(&self) -> bool
{
97 fn interner(&self) -> &'i I
{
101 fn target_interner(&self) -> &'i I
{
109 use chalk_integration
::interner
::ChalkIr
;
110 use chalk_integration
::{arg, ty, ty_name}
;
112 const U0
: UniverseIndex
= UniverseIndex { counter: 0 }
;
116 let interner
= &ChalkIr
;
117 let mut table
: InferenceTable
<ChalkIr
> = InferenceTable
::new();
118 let environment0
= Environment
::new(interner
);
119 let a
= table
.new_variable(U0
).to_ty(interner
);
120 let b
= table
.new_variable(U0
).to_ty(interner
);
122 .unify(interner
, &environment0
, &a
, &ty
!(apply (item
0) (expr b
)))
125 DeepNormalizer
::normalize_deep(&mut table
, interner
, &a
),
126 ty
!(apply (item
0) (expr b
))
129 .unify(interner
, &environment0
, &b
, &ty
!(apply (item
1)))
132 DeepNormalizer
::normalize_deep(&mut table
, interner
, &a
),
133 ty
!(apply (item
0) (apply (item
1)))