@@ -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
@@ -715,14 +713,20 @@ impl Compiler {
715713 return None ;
716714 }
717715
718- // 6. "super" must be GlobalImplicit (not redefined locally)
716+ // 6. "super" must be GlobalImplicit (not redefined locally or at module level )
719717 let table = self . current_symbol_table ( ) ;
720- if let Some ( symbol) = table. lookup ( "super" ) {
721- if symbol. scope != SymbolScope :: GlobalImplicit {
722- return None ;
723- }
724- } else {
725- // super not found in symbol table - assume it's a global builtin
718+ if let Some ( symbol) = table. lookup ( "super" )
719+ && symbol. scope != SymbolScope :: GlobalImplicit
720+ {
721+ return None ;
722+ }
723+ // Also check top-level scope to detect module-level shadowing.
724+ // Only block if super is actually *bound* at module level (not just used).
725+ if let Some ( top_table) = self . symbol_table_stack . first ( )
726+ && let Some ( sym) = top_table. lookup ( "super" )
727+ && sym. scope != SymbolScope :: GlobalImplicit
728+ {
729+ return None ;
726730 }
727731
728732 // 7. Check argument pattern
@@ -743,10 +747,26 @@ impl Compiler {
743747 }
744748 0 => {
745749 // 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
750+ // Enclosing function should have at least one positional argument
751+ let info = self . code_stack . last ( ) ?;
752+ if info. metadata . argcount == 0 && info. metadata . posonlyargcount == 0 {
753+ return None ;
754+ }
755+
756+ // Check if __class__ is available as a cell/free variable
757+ // The scope must be Free (from enclosing class) or have FREE_CLASS flag
758+ if let Some ( symbol) = table. lookup ( "__class__" ) {
759+ if symbol. scope != SymbolScope :: Free
760+ && !symbol. flags . contains ( SymbolFlags :: FREE_CLASS )
761+ {
762+ return None ;
763+ }
764+ } else {
765+ // __class__ not in symbol table, optimization not possible
766+ return None ;
767+ }
768+
769+ Some ( SuperCallType :: ZeroArg )
750770 }
751771 _ => None , // 1 or 3+ args - not optimizable
752772 }
@@ -3494,12 +3514,14 @@ impl Compiler {
34943514 /// Determines if a variable should be CELL or FREE type
34953515 // = get_ref_type
34963516 fn get_ref_type ( & self , name : & str ) -> Result < SymbolScope , CodegenErrorType > {
3517+ let table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
3518+
34973519 // Special handling for __class__ and __classdict__ in class scope
3498- if self . ctx . in_class && ( name == "__class__" || name == "__classdict__" ) {
3520+ // This should only apply when we're actually IN a class body,
3521+ // not when we're in a method nested inside a class.
3522+ if table. typ == CompilerScope :: Class && ( name == "__class__" || name == "__classdict__" ) {
34993523 return Ok ( SymbolScope :: Cell ) ;
35003524 }
3501-
3502- let table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
35033525 match table. lookup ( name) {
35043526 Some ( symbol) => match symbol. scope {
35053527 SymbolScope :: Cell => Ok ( SymbolScope :: Cell ) ,
0 commit comments