Skip to content
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fix formatting and collapsible_if clippy warnings in compile.rs
  • Loading branch information
youknowone committed Mar 25, 2026
commit 6d4ed646967a5138e66286eeff2810828a51cfff
28 changes: 11 additions & 17 deletions crates/codegen/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1201,8 +1201,8 @@ impl Compiler {
/// codegen_enter_scope equivalent for RESUME emission.
fn emit_resume_for_scope(&mut self, scope_type: CompilerScope, lineno: u32) {
// For generators and async functions, emit RETURN_GENERATOR + POP_TOP before RESUME
let is_gen = scope_type == CompilerScope::AsyncFunction
|| self.current_symbol_table().is_generator;
let is_gen =
scope_type == CompilerScope::AsyncFunction || self.current_symbol_table().is_generator;
if is_gen {
Comment on lines +1203 to +1206
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 | 🟠 Major

Propagate generator classification to the async return value check.

This preamble now knows a scope is a generator before body compilation, but the async-generator guard still keys off CodeFlags::GENERATOR later in compile_statement. async def f(): return 1; yield 2 will still compile because the return is visited before mark_generator() runs. Either set the generator flag here when self.current_symbol_table().is_generator is true, or switch the Line 2498 check to the symbol-table bit.

Possible fix
-        let is_gen =
-            scope_type == CompilerScope::AsyncFunction || self.current_symbol_table().is_generator;
-        if is_gen {
+        let is_generator = self.current_symbol_table().is_generator;
+        let needs_return_generator =
+            scope_type == CompilerScope::AsyncFunction || is_generator;
+        if is_generator {
+            self.current_code_info().flags |= bytecode::CodeFlags::GENERATOR;
+        }
+        if needs_return_generator {
             emit!(self, Instruction::ReturnGenerator);
             emit!(self, Instruction::PopTop);
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// For generators and async functions, emit RETURN_GENERATOR + POP_TOP before RESUME
let is_gen =
scope_type == CompilerScope::AsyncFunction || self.current_symbol_table().is_generator;
if is_gen {
// For generators and async functions, emit RETURN_GENERATOR + POP_TOP before RESUME
let is_generator = self.current_symbol_table().is_generator;
let needs_return_generator =
scope_type == CompilerScope::AsyncFunction || is_generator;
if is_generator {
self.current_code_info().flags |= bytecode::CodeFlags::GENERATOR;
}
if needs_return_generator {
emit!(self, Instruction::ReturnGenerator);
emit!(self, Instruction::PopTop);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/codegen/src/compile.rs` around lines 1203 - 1206, The async-generator
check is using CodeFlags::GENERATOR in compile_statement which runs before
mark_generator(), so async defs that are generators slip through; when you
compute is_gen (using scope_type == CompilerScope::AsyncFunction ||
self.current_symbol_table().is_generator) propagate that generator
classification into the code flags immediately (or alternatively change the
later check in compile_statement to consult
self.current_symbol_table().is_generator instead of CodeFlags::GENERATOR).
Concretely, set the generator bit on the current CodeFlags/state when is_gen is
true (or update the Line 2498 check to use current_symbol_table().is_generator)
so the async return-value guard sees the generator status before
mark_generator() is called.

emit!(self, Instruction::ReturnGenerator);
emit!(self, Instruction::PopTop);
Expand Down Expand Up @@ -4540,35 +4540,29 @@ impl Compiler {
ast::Stmt::Assign(a) => {
for target in &a.targets {
if let ast::Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = target
&& let ast::Expr::Name(n) = value.as_ref()
&& n.id.as_str() == name
{
if let ast::Expr::Name(n) = value.as_ref() {
if n.id.as_str() == name {
attrs.insert(attr.to_string());
}
}
attrs.insert(attr.to_string());
}
}
}
ast::Stmt::AnnAssign(a) => {
if let ast::Expr::Attribute(ast::ExprAttribute { value, attr, .. }) =
a.target.as_ref()
&& let ast::Expr::Name(n) = value.as_ref()
&& n.id.as_str() == name
{
if let ast::Expr::Name(n) = value.as_ref() {
if n.id.as_str() == name {
attrs.insert(attr.to_string());
}
}
attrs.insert(attr.to_string());
}
}
ast::Stmt::AugAssign(a) => {
if let ast::Expr::Attribute(ast::ExprAttribute { value, attr, .. }) =
a.target.as_ref()
&& let ast::Expr::Name(n) = value.as_ref()
&& n.id.as_str() == name
{
if let ast::Expr::Name(n) = value.as_ref() {
if n.id.as_str() == name {
attrs.insert(attr.to_string());
}
}
attrs.insert(attr.to_string());
}
}
ast::Stmt::If(s) => {
Expand Down