diff --git a/crates/erg_compiler/codegen.rs b/crates/erg_compiler/codegen.rs index 8339dbfb..ac162ff8 100644 --- a/crates/erg_compiler/codegen.rs +++ b/crates/erg_compiler/codegen.rs @@ -1484,15 +1484,24 @@ impl PyCodeGenerator { fn register_cellvars(&mut self, flag: &mut usize) { if !self.cur_block_codeobj().cellvars.is_empty() { let cellvars_len = self.cur_block_codeobj().cellvars.len(); - for i in 0..cellvars_len { + let cellvars = self.cur_block_codeobj().cellvars.clone(); + for (i, name) in cellvars.iter().enumerate() { + // Since 3.11, LOAD_CLOSURE is simply an alias for LOAD_FAST. if self.py_version.minor >= Some(11) { + let idx = self + .cur_block_codeobj() + .varnames + .iter() + .position(|n| n == name) + .unwrap(); self.write_instr(Opcode311::MAKE_CELL); - self.write_arg(i); + self.write_arg(idx); self.write_instr(Opcode311::LOAD_CLOSURE); + self.write_arg(idx); } else { self.write_instr(Opcode310::LOAD_CLOSURE); + self.write_arg(i); } - self.write_arg(i); } self.write_instr(BUILD_TUPLE); self.write_arg(cellvars_len); diff --git a/crates/erg_compiler/ty/codeobj.rs b/crates/erg_compiler/ty/codeobj.rs index c494f866..c6f256bd 100644 --- a/crates/erg_compiler/ty/codeobj.rs +++ b/crates/erg_compiler/ty/codeobj.rs @@ -745,7 +745,7 @@ impl CodeObj { write!(instrs, "{arg} ({})", self.varnames.get(arg).unwrap()).unwrap(); } Opcode311::MAKE_CELL | Opcode311::LOAD_CLOSURE => { - write!(instrs, "{arg} ({})", self.cellvars.get(arg).unwrap()).unwrap(); + write!(instrs, "{arg} ({})", self.varnames.get(arg).unwrap()).unwrap(); } Opcode311::POP_JUMP_FORWARD_IF_FALSE | Opcode311::POP_JUMP_FORWARD_IF_TRUE => { write!(instrs, "{arg} (to {})", idx + arg * 2 + 2).unwrap(); diff --git a/tests/should_ok/closure.er b/tests/should_ok/closure.er new file mode 100644 index 00000000..3ac89174 --- /dev/null +++ b/tests/should_ok/closure.er @@ -0,0 +1,4 @@ +func vers: Array(Int), version: Int = + all map(v -> v == version, vers) + +assert func([1, 1], 1) diff --git a/tests/test.rs b/tests/test.rs index 6079856f..e9dd2eb5 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -51,6 +51,11 @@ fn exec_class_attr() -> Result<(), ()> { expect_success("tests/should_ok/class_attr.er", 2) } +#[test] +fn exec_closure() -> Result<(), ()> { + expect_success("tests/should_ok/closure.er", 0) +} + #[test] fn exec_collection() -> Result<(), ()> { expect_success("tests/should_ok/collection.er", 0)