Skip to content

Commit 62d7e66

Browse files
committed
ZeroArg
1 parent da5328f commit 62d7e66

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

crates/codegen/src/compile.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ enum SuperCallType<'a> {
8484
self_arg: &'a Expr,
8585
},
8686
/// super() - implicit 0-argument form (uses __class__ cell)
87-
/// TODO: Enable after fixing __class__ cell handling in nested classes
88-
#[allow(dead_code)]
8987
ZeroArg,
9088
}
9189

@@ -743,10 +741,26 @@ impl Compiler {
743741
}
744742
0 => {
745743
// 0-arg: super() - need __class__ cell and first parameter
746-
// TODO: 0-arg super() optimization is disabled due to __class__ cell issues
747-
// The __class__ cell handling in nested class definitions needs more work.
748-
// For now, fall back to regular super() call.
749-
None
744+
// Check if we're in a function with at least one parameter
745+
let info = self.code_stack.last()?;
746+
if info.metadata.varnames.is_empty() {
747+
return None;
748+
}
749+
750+
// Check if __class__ is available as a cell/free variable
751+
// The scope must be Free (from enclosing class) or have FREE_CLASS flag
752+
if let Some(symbol) = table.lookup("__class__") {
753+
if symbol.scope != SymbolScope::Free
754+
&& !symbol.flags.contains(SymbolFlags::FREE_CLASS)
755+
{
756+
return None;
757+
}
758+
} else {
759+
// __class__ not in symbol table, optimization not possible
760+
return None;
761+
}
762+
763+
Some(SuperCallType::ZeroArg)
750764
}
751765
_ => None, // 1 or 3+ args - not optimizable
752766
}
@@ -3494,12 +3508,14 @@ impl Compiler {
34943508
/// Determines if a variable should be CELL or FREE type
34953509
// = get_ref_type
34963510
fn get_ref_type(&self, name: &str) -> Result<SymbolScope, CodegenErrorType> {
3511+
let table = self.symbol_table_stack.last().unwrap();
3512+
34973513
// Special handling for __class__ and __classdict__ in class scope
3498-
if self.ctx.in_class && (name == "__class__" || name == "__classdict__") {
3514+
// This should only apply when we're actually IN a class body,
3515+
// not when we're in a method nested inside a class.
3516+
if table.typ == CompilerScope::Class && (name == "__class__" || name == "__classdict__") {
34993517
return Ok(SymbolScope::Cell);
35003518
}
3501-
3502-
let table = self.symbol_table_stack.last().unwrap();
35033519
match table.lookup(name) {
35043520
Some(symbol) => match symbol.scope {
35053521
SymbolScope::Cell => Ok(SymbolScope::Cell),

0 commit comments

Comments
 (0)