Fix crash on affine pass when some variables are erased

This commit is contained in:
Nicolas Abril 2023-09-20 20:16:47 +02:00
parent 34e28659bb
commit a75932aeee
3 changed files with 21 additions and 11 deletions

View File

@ -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 {

View File

@ -0,0 +1 @@
Unbound variable 'two'

View File

@ -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.
)