Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions crates/codegen/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9069,6 +9069,18 @@ mod tests {

fn compile_exec(source: &str) -> CodeObject {
let opts = CompileOpts::default();
compile_exec_with_options(source, opts)
}

fn compile_exec_optimized(source: &str) -> CodeObject {
let opts = CompileOpts {
optimize: 1,
..CompileOpts::default()
};
compile_exec_with_options(source, opts)
}

fn compile_exec_with_options(source: &str, opts: CompileOpts) -> CodeObject {
let source_file = SourceFileBuilder::new("source_path", source).finish();
let parsed = ruff_python_parser::parse(
source_file.source_text(),
Expand Down Expand Up @@ -9137,6 +9149,15 @@ x = Test() and False or False
));
}

#[test]
fn test_const_bool_not_op() {
assert_dis_snapshot!(compile_exec_optimized(
"\
x = not True
"
));
}

#[test]
fn test_nested_double_async_with() {
assert_dis_snapshot!(compile_exec(
Expand Down
27 changes: 27 additions & 0 deletions crates/codegen/src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,33 @@ impl CodeInfo {
None
}
}
(Instruction::LoadConst { consti }, Instruction::ToBool) => {
let consti = consti.get(curr.arg);
let constant = &self.metadata.consts[consti as usize];
if let ConstantData::Boolean { .. } = constant {
Some((curr_instr, OpArg::from(consti)))
} else {
None
}
}
(Instruction::LoadConst { consti }, Instruction::UnaryNot) => {
let constant = &self.metadata.consts[consti.get(curr.arg) as usize];
match constant {
ConstantData::Boolean { value } => {
let (const_idx, _) = self
.metadata
.consts
.insert_full(ConstantData::Boolean { value: !value });
Some((
(Instruction::LoadConst {
consti: Arg::marker(),
}),
OpArg::new(const_idx as u32),
))
}
_ => None,
}
}
Comment on lines +705 to +722
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Const-fold inserts can leave dead co_consts entries.

This branch adds a new boolean constant but can orphan the original one. Since remove_unused_consts() runs before peephole, unused constants introduced here are not pruned.

💡 Suggested fix
diff --git a/crates/codegen/src/ir.rs b/crates/codegen/src/ir.rs
@@
         if opts.optimize > 0 {
             self.dce();
             self.peephole_optimize();
+            self.remove_unused_consts();
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/codegen/src/ir.rs` around lines 705 - 722, The peephole for
(Instruction::LoadConst { consti }, Instruction::UnaryNot) unconditionally
inserts a new Boolean constant with the negated value which can orphan the
original co_consts entry; instead, before calling
self.metadata.consts.insert_full, search the constant pool for an existing
ConstantData::Boolean { value: !value } and reuse its index (const_idx) if
found, and only call insert_full when no matching constant exists; update the
returned tuple to use that const_idx so you never create a duplicate orphan
constant (referencing Instruction::LoadConst, Instruction::UnaryNot,
ConstantData::Boolean, self.metadata.consts.insert_full and
remove_unused_consts()/peephole to locate the logic).

_ => None,
}
};
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.