Skip to content

Commit 2d193f3

Browse files
committed
Move generalizer to its own module
1 parent 9166f3e commit 2d193f3

File tree

2 files changed

+81
-77
lines changed

2 files changed

+81
-77
lines changed

chalk-solve/src/clauses.rs

Lines changed: 1 addition & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_hash::FxHashSet;
1313
pub mod builder;
1414
mod builtin_traits;
1515
mod env_elaborator;
16+
mod generalize;
1617
pub mod program_clauses;
1718

1819
/// For auto-traits, we generate a default rule for every struct,
@@ -436,80 +437,3 @@ fn program_clauses_for_env<'db, I: Interner>(
436437

437438
clauses.extend(closure.drain())
438439
}
439-
440-
mod generalize {
441-
use chalk_engine::fallible::Fallible;
442-
use chalk_ir::{
443-
fold::{Fold, Folder},
444-
interner::Interner,
445-
Binders, BoundVar, DebruijnIndex, Lifetime, LifetimeData, ParameterKind, Ty, TyData,
446-
};
447-
use std::collections::HashMap;
448-
449-
pub struct Generalize<'i, I: Interner> {
450-
binders: Vec<ParameterKind<()>>,
451-
mapping: HashMap<BoundVar, usize>,
452-
interner: &'i I,
453-
}
454-
455-
impl<I: Interner> Generalize<'_, I> {
456-
pub fn apply<T: Fold<I, I>>(interner: &I, value: &T) -> Binders<T::Result> {
457-
let mut generalize = Generalize {
458-
binders: Vec::new(),
459-
mapping: HashMap::new(),
460-
interner,
461-
};
462-
let value = value
463-
.fold_with(&mut generalize, DebruijnIndex::INNERMOST)
464-
.unwrap();
465-
Binders {
466-
binders: generalize.binders,
467-
value,
468-
}
469-
}
470-
}
471-
472-
impl<'i, I: Interner> Folder<'i, I> for Generalize<'i, I> {
473-
fn as_dyn(&mut self) -> &mut dyn Folder<'i, I> {
474-
self
475-
}
476-
477-
fn fold_free_var_ty(
478-
&mut self,
479-
bound_var: BoundVar,
480-
outer_binder: DebruijnIndex,
481-
) -> Fallible<Ty<I>> {
482-
let binder_vec = &mut self.binders;
483-
let new_index = self.mapping.entry(bound_var).or_insert_with(|| {
484-
let i = binder_vec.len();
485-
binder_vec.push(ParameterKind::Ty(()));
486-
i
487-
});
488-
let new_var = BoundVar::new(outer_binder, *new_index);
489-
Ok(TyData::BoundVar(new_var).intern(self.interner()))
490-
}
491-
492-
fn fold_free_var_lifetime(
493-
&mut self,
494-
bound_var: BoundVar,
495-
outer_binder: DebruijnIndex,
496-
) -> Fallible<Lifetime<I>> {
497-
let binder_vec = &mut self.binders;
498-
let new_index = self.mapping.entry(bound_var).or_insert_with(|| {
499-
let i = binder_vec.len();
500-
binder_vec.push(ParameterKind::Ty(()));
501-
i
502-
});
503-
let new_var = BoundVar::new(outer_binder, *new_index);
504-
Ok(LifetimeData::BoundVar(new_var).intern(self.interner()))
505-
}
506-
507-
fn interner(&self) -> &'i I {
508-
self.interner
509-
}
510-
511-
fn target_interner(&self) -> &'i I {
512-
self.interner
513-
}
514-
}
515-
}

chalk-solve/src/clauses/generalize.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//! This gets rid of free variables in a type by replacing them by fresh bound
2+
//! ones. We use this when building clauses that contain types passed to
3+
//! `program_clauses`; these may contain variables, and just copying those
4+
//! variables verbatim leads to problems. Instead, we return a slightly more
5+
//! general program clause, with new variables in those places.
6+
7+
use chalk_engine::fallible::Fallible;
8+
use chalk_ir::{
9+
fold::{Fold, Folder},
10+
interner::Interner,
11+
Binders, BoundVar, DebruijnIndex, Lifetime, LifetimeData, ParameterKind, Ty, TyData,
12+
};
13+
use std::collections::HashMap;
14+
15+
pub struct Generalize<'i, I: Interner> {
16+
binders: Vec<ParameterKind<()>>,
17+
mapping: HashMap<BoundVar, usize>,
18+
interner: &'i I,
19+
}
20+
21+
impl<I: Interner> Generalize<'_, I> {
22+
pub fn apply<T: Fold<I, I>>(interner: &I, value: &T) -> Binders<T::Result> {
23+
let mut generalize = Generalize {
24+
binders: Vec::new(),
25+
mapping: HashMap::new(),
26+
interner,
27+
};
28+
let value = value
29+
.fold_with(&mut generalize, DebruijnIndex::INNERMOST)
30+
.unwrap();
31+
Binders {
32+
binders: generalize.binders,
33+
value,
34+
}
35+
}
36+
}
37+
38+
impl<'i, I: Interner> Folder<'i, I> for Generalize<'i, I> {
39+
fn as_dyn(&mut self) -> &mut dyn Folder<'i, I> {
40+
self
41+
}
42+
43+
fn fold_free_var_ty(
44+
&mut self,
45+
bound_var: BoundVar,
46+
outer_binder: DebruijnIndex,
47+
) -> Fallible<Ty<I>> {
48+
let binder_vec = &mut self.binders;
49+
let new_index = self.mapping.entry(bound_var).or_insert_with(|| {
50+
let i = binder_vec.len();
51+
binder_vec.push(ParameterKind::Ty(()));
52+
i
53+
});
54+
let new_var = BoundVar::new(outer_binder, *new_index);
55+
Ok(TyData::BoundVar(new_var).intern(self.interner()))
56+
}
57+
58+
fn fold_free_var_lifetime(
59+
&mut self,
60+
bound_var: BoundVar,
61+
outer_binder: DebruijnIndex,
62+
) -> Fallible<Lifetime<I>> {
63+
let binder_vec = &mut self.binders;
64+
let new_index = self.mapping.entry(bound_var).or_insert_with(|| {
65+
let i = binder_vec.len();
66+
binder_vec.push(ParameterKind::Ty(()));
67+
i
68+
});
69+
let new_var = BoundVar::new(outer_binder, *new_index);
70+
Ok(LifetimeData::BoundVar(new_var).intern(self.interner()))
71+
}
72+
73+
fn interner(&self) -> &'i I {
74+
self.interner
75+
}
76+
77+
fn target_interner(&self) -> &'i I {
78+
self.interner
79+
}
80+
}

0 commit comments

Comments
 (0)