@@ -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,18 @@ 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+ if let Some ( top_table) = self . symbol_table_stack . first ( )
725+ && top_table. lookup ( "super" ) . is_some ( )
726+ {
727+ return None ;
726728 }
727729
728730 // 7. Check argument pattern
@@ -743,10 +745,26 @@ impl Compiler {
743745 }
744746 0 => {
745747 // 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
748+ // Enclosing function should have at least one positional argument
749+ let info = self . code_stack . last ( ) ?;
750+ if info. metadata . argcount == 0 && info. metadata . posonlyargcount == 0 {
751+ return None ;
752+ }
753+
754+ // Check if __class__ is available as a cell/free variable
755+ // The scope must be Free (from enclosing class) or have FREE_CLASS flag
756+ if let Some ( symbol) = table. lookup ( "__class__" ) {
757+ if symbol. scope != SymbolScope :: Free
758+ && !symbol. flags . contains ( SymbolFlags :: FREE_CLASS )
759+ {
760+ return None ;
761+ }
762+ } else {
763+ // __class__ not in symbol table, optimization not possible
764+ return None ;
765+ }
766+
767+ Some ( SuperCallType :: ZeroArg )
750768 }
751769 _ => None , // 1 or 3+ args - not optimizable
752770 }
@@ -3494,12 +3512,14 @@ impl Compiler {
34943512 /// Determines if a variable should be CELL or FREE type
34953513 // = get_ref_type
34963514 fn get_ref_type ( & self , name : & str ) -> Result < SymbolScope , CodegenErrorType > {
3515+ let table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
3516+
34973517 // Special handling for __class__ and __classdict__ in class scope
3498- if self . ctx . in_class && ( name == "__class__" || name == "__classdict__" ) {
3518+ // This should only apply when we're actually IN a class body,
3519+ // not when we're in a method nested inside a class.
3520+ if table. typ == CompilerScope :: Class && ( name == "__class__" || name == "__classdict__" ) {
34993521 return Ok ( SymbolScope :: Cell ) ;
35003522 }
3501-
3502- let table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
35033523 match table. lookup ( name) {
35043524 Some ( symbol) => match symbol. scope {
35053525 SymbolScope :: Cell => Ok ( SymbolScope :: Cell ) ,
0 commit comments