mirror of
https://github.com/HigherOrderCO/Bend.git
synced 2024-10-26 14:05:36 +03:00
Fix crash on affine pass when some variables are erased
This commit is contained in:
parent
34e28659bb
commit
a75932aeee
@ -56,19 +56,17 @@ fn term_to_affine(
|
||||
}
|
||||
Term::Var { nam } => {
|
||||
// Count this var use and give it a new unique name
|
||||
if let Some(mut var_use_stack) = scope.remove(&*nam) {
|
||||
let var_uses = var_use_stack.last_mut().unwrap();
|
||||
|
||||
if let Some(var_use_stack) = scope.get(&nam) {
|
||||
let var_uses = var_use_stack.last().unwrap().clone();
|
||||
// Create a new name, except for the first occurence
|
||||
let (new_name, name_idx) = if var_uses.is_empty() {
|
||||
(nam.clone(), 0)
|
||||
} else {
|
||||
make_new_dup_name(&nam, var_uses, scope, def_names)
|
||||
make_new_dup_name(&nam, &var_uses, scope, def_names)
|
||||
};
|
||||
var_uses.push(name_idx);
|
||||
// Add new name to scope
|
||||
scope.get_mut(&nam).unwrap().last_mut().unwrap().push(name_idx);
|
||||
|
||||
// Removing and adding back to avoid ownership issues
|
||||
scope.insert(nam, var_use_stack);
|
||||
let term = Term::Var { nam: new_name };
|
||||
Ok(term)
|
||||
} else {
|
||||
@ -165,12 +163,13 @@ fn pop_scope(
|
||||
def_names: &HashSet<Name>,
|
||||
) -> (Option<Name>, Box<Term>) {
|
||||
if let Some(nam) = &nam {
|
||||
// Remove variable from scope, getting all the occurences
|
||||
let var_uses = scope.get_mut(nam).unwrap().pop().unwrap();
|
||||
// Add the necessary dups to make all uses affine.
|
||||
let (new_nam, bod) = add_dups_of_var(nam, bod, &var_uses, scope, def_names);
|
||||
if let Some(new_nam) = &new_nam {
|
||||
if scope.get(new_nam).unwrap().is_empty() {
|
||||
scope.remove(new_nam);
|
||||
}
|
||||
// Remove this name from the scope if there are no variables using it.
|
||||
if scope.get(nam).unwrap().is_empty() {
|
||||
scope.remove(nam);
|
||||
}
|
||||
(new_nam, bod)
|
||||
} else {
|
||||
|
@ -0,0 +1 @@
|
||||
Unbound variable 'two'
|
@ -0,0 +1,10 @@
|
||||
X = λx x
|
||||
|
||||
(Main) = (
|
||||
let two = (λf1λx1 (f1 λf2λx2 (f2 λf0λx0 x0)));
|
||||
let qua = (λs1λz1 (s1 λs2λz2 (s2 λs3λz3 (s3 λs4λz4 (s4 λs0λz0 z0)))));
|
||||
X X (X two qua)
|
||||
// Because there is no parens around the return term, the lets are only in scope for the first X
|
||||
// This test is to make sure that the affine checking and duping infering marks them as erased as we expect.
|
||||
// We expect an unbound variable error on two and qua.
|
||||
)
|
Loading…
Reference in New Issue
Block a user