Skip to content

Commit

Permalink
fix: Fix an ICE when reassigning a mutable lambda variable to one wit…
Browse files Browse the repository at this point in the history
…h a different environment type (#2172)

* fix: don't allow lambda reassignment if closure types dont match

* fix: add test for bad lambda reassignment

* fix: cargo fmt & clippy

* fix: alternate approach

---------

Co-authored-by: Alex Vitkov <[email protected]>
  • Loading branch information
alexvitkov and Alex Vitkov authored Aug 7, 2023
1 parent 14cbdbc commit a56db3e
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
fn bad() {
let a: i32 = 100;
let b: i32 = 200;

let mut f = || a;

// this should fail with a type error, since the closures have different environments & types
f = || a + b;
}
8 changes: 6 additions & 2 deletions crates/noirc_frontend/src/hir_def/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1206,12 +1206,14 @@ impl Type {
}
}

(Function(params_a, ret_a, _env_a), Function(params_b, ret_b, _env_b)) => {
(Function(params_a, ret_a, env_a), Function(params_b, ret_b, env_b)) => {
if params_a.len() == params_b.len() {
for (a, b) in params_a.iter().zip(params_b.iter()) {
a.try_unify(b, span)?;
}

env_a.try_unify(env_b, span)?;

ret_b.try_unify(ret_a, span)
} else {
Err(SpanKind::None)
Expand Down Expand Up @@ -1413,12 +1415,14 @@ impl Type {
}
}

(Function(params_a, ret_a, _env_a), Function(params_b, ret_b, _env_b)) => {
(Function(params_a, ret_a, env_a), Function(params_b, ret_b, env_b)) => {
if params_a.len() == params_b.len() {
for (a, b) in params_a.iter().zip(params_b) {
a.is_subtype_of(b, span)?;
}

env_a.is_subtype_of(env_b, span)?;

// return types are contravariant, so this must be ret_b <: ret_a instead of the reverse
ret_b.is_subtype_of(ret_a, span)
} else {
Expand Down

0 comments on commit a56db3e

Please sign in to comment.