Skip to content

Commit c13aa09

Browse files
yodaldevoidvarkor
authored andcommitted
impl fold_const for TypeFreshener
Signed-off-by: Gabriel Smith <ga29smith@gmail.com>
1 parent e965b75 commit c13aa09

File tree

1 file changed

+92
-22
lines changed

1 file changed

+92
-22
lines changed

src/librustc/infer/freshen.rs

Lines changed: 92 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
//! variable only once, and it does so as soon as it can, so it is reasonable to ask what the type
3232
//! inferencer knows "so far".
3333
34+
use crate::mir::interpret::ConstValue;
3435
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
3536
use crate::ty::fold::TypeFolder;
3637
use crate::util::nodemap::FxHashMap;
@@ -42,42 +43,74 @@ use super::unify_key::ToType;
4243

4344
pub struct TypeFreshener<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
4445
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
45-
freshen_count: u32,
46-
freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
46+
ty_freshen_count: u32,
47+
const_freshen_count: u32,
48+
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
49+
const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::LazyConst<'tcx>>,
4750
}
4851

4952
impl<'a, 'gcx, 'tcx> TypeFreshener<'a, 'gcx, 'tcx> {
5053
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>)
5154
-> TypeFreshener<'a, 'gcx, 'tcx> {
5255
TypeFreshener {
5356
infcx,
54-
freshen_count: 0,
55-
freshen_map: Default::default(),
57+
ty_freshen_count: 0,
58+
const_freshen_count: 0,
59+
ty_freshen_map: Default::default(),
60+
const_freshen_map: Default::default(),
5661
}
5762
}
5863

59-
fn freshen<F>(&mut self,
60-
opt_ty: Option<Ty<'tcx>>,
61-
key: ty::InferTy,
62-
freshener: F)
63-
-> Ty<'tcx> where
64+
fn freshen_ty<F>(
65+
&mut self,
66+
opt_ty: Option<Ty<'tcx>>,
67+
key: ty::InferTy,
68+
freshener: F,
69+
) -> Ty<'tcx>
70+
where
6471
F: FnOnce(u32) -> ty::InferTy,
6572
{
6673
if let Some(ty) = opt_ty {
6774
return ty.fold_with(self);
6875
}
6976

70-
match self.freshen_map.entry(key) {
77+
match self.ty_freshen_map.entry(key) {
7178
Entry::Occupied(entry) => *entry.get(),
7279
Entry::Vacant(entry) => {
73-
let index = self.freshen_count;
74-
self.freshen_count += 1;
80+
let index = self.ty_freshen_count;
81+
self.ty_freshen_count += 1;
7582
let t = self.infcx.tcx.mk_ty_infer(freshener(index));
7683
entry.insert(t);
7784
t
7885
}
7986
}
8087
}
88+
89+
fn freshen_const<F>(
90+
&mut self,
91+
opt_ct: Option<&'tcx ty::LazyConst<'tcx>>,
92+
key: ty::InferConst<'tcx>,
93+
freshener: F,
94+
ty: Ty<'tcx>,
95+
) -> &'tcx ty::LazyConst<'tcx>
96+
where
97+
F: FnOnce(u32) -> ty::InferConst<'tcx>,
98+
{
99+
if let Some(ct) = opt_ct {
100+
return ct.fold_with(self);
101+
}
102+
103+
match self.const_freshen_map.entry(key) {
104+
Entry::Occupied(entry) => *entry.get(),
105+
Entry::Vacant(entry) => {
106+
let index = self.const_freshen_count;
107+
self.const_freshen_count += 1;
108+
let ct = self.infcx.tcx.mk_const_infer(freshener(index), ty);
109+
entry.insert(ct);
110+
ct
111+
}
112+
}
113+
}
81114
}
82115

83116
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
@@ -124,14 +157,14 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
124157
match t.sty {
125158
ty::Infer(ty::TyVar(v)) => {
126159
let opt_ty = self.infcx.type_variables.borrow_mut().probe(v).known();
127-
self.freshen(
160+
self.freshen_ty(
128161
opt_ty,
129162
ty::TyVar(v),
130163
ty::FreshTy)
131164
}
132165

133166
ty::Infer(ty::IntVar(v)) => {
134-
self.freshen(
167+
self.freshen_ty(
135168
self.infcx.int_unification_table.borrow_mut()
136169
.probe_value(v)
137170
.map(|v| v.to_type(tcx)),
@@ -140,22 +173,22 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
140173
}
141174

142175
ty::Infer(ty::FloatVar(v)) => {
143-
self.freshen(
176+
self.freshen_ty(
144177
self.infcx.float_unification_table.borrow_mut()
145178
.probe_value(v)
146179
.map(|v| v.to_type(tcx)),
147180
ty::FloatVar(v),
148181
ty::FreshFloatTy)
149182
}
150183

151-
ty::Infer(ty::FreshTy(c)) |
152-
ty::Infer(ty::FreshIntTy(c)) |
153-
ty::Infer(ty::FreshFloatTy(c)) => {
154-
if c >= self.freshen_count {
184+
ty::Infer(ty::FreshTy(ct)) |
185+
ty::Infer(ty::FreshIntTy(ct)) |
186+
ty::Infer(ty::FreshFloatTy(ct)) => {
187+
if ct >= self.ty_freshen_count {
155188
bug!("Encountered a freshend type with id {} \
156189
but our counter is only at {}",
157-
c,
158-
self.freshen_count);
190+
ct,
191+
self.ty_freshen_count);
159192
}
160193
t
161194
}
@@ -194,6 +227,43 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
194227
}
195228

196229
fn fold_const(&mut self, ct: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
197-
ct // FIXME(const_generics)
230+
if let ty::LazyConst::Evaluated(ty::Const{ val, ty }) = ct {
231+
match val {
232+
ConstValue::Infer(ty::InferConst::Var(v)) => {
233+
let opt_ct = self.infcx.const_unification_table
234+
.borrow_mut()
235+
.probe(*v)
236+
.known();
237+
return self.freshen_const(
238+
opt_ct,
239+
ty::InferConst::Var(*v),
240+
ty::InferConst::Fresh,
241+
ty,
242+
);
243+
}
244+
ConstValue::Infer(ty::InferConst::Fresh(i)) => {
245+
if *i >= self.const_freshen_count {
246+
bug!(
247+
"Encountered a freshend const with id {} \
248+
but our counter is only at {}",
249+
i,
250+
self.const_freshen_count,
251+
);
252+
}
253+
return ct;
254+
}
255+
256+
ConstValue::Infer(ty::InferConst::Canonical(..)) => {
257+
bug!("unexpected const {:?}", ct)
258+
}
259+
260+
ConstValue::Param(_) |
261+
ConstValue::Scalar(_) |
262+
ConstValue::Slice(..) |
263+
ConstValue::ByRef(..) => {}
264+
}
265+
}
266+
267+
ct.super_fold_with(self)
198268
}
199269
}

0 commit comments

Comments
 (0)