@@ -528,7 +528,6 @@ impl SymbolTableAnalyzer {
528528 if !self . tables . as_ref ( ) . is_empty ( ) {
529529 let scope_depth = self . tables . as_ref ( ) . len ( ) ;
530530 // check if the name is already defined in any outer scope
531- // therefore
532531 if scope_depth < 2
533532 || self . found_in_outer_scope ( & symbol. name , st_typ)
534533 != Some ( SymbolScope :: Free )
@@ -539,6 +538,25 @@ impl SymbolTableAnalyzer {
539538 location : None ,
540539 } ) ;
541540 }
541+ // Check if the nonlocal binding refers to a type parameter
542+ if symbol. flags . contains ( SymbolFlags :: NONLOCAL ) {
543+ for ( symbols, _typ) in self . tables . iter ( ) . rev ( ) {
544+ if let Some ( sym) = symbols. get ( & symbol. name ) {
545+ if sym. flags . contains ( SymbolFlags :: TYPE_PARAM ) {
546+ return Err ( SymbolTableError {
547+ error : format ! (
548+ "nonlocal binding not allowed for type parameter '{}'" ,
549+ symbol. name
550+ ) ,
551+ location : None ,
552+ } ) ;
553+ }
554+ if sym. is_bound ( ) {
555+ break ;
556+ }
557+ }
558+ }
559+ }
542560 } else {
543561 return Err ( SymbolTableError {
544562 error : format ! (
@@ -933,7 +951,8 @@ impl SymbolTableBuilder {
933951 /// Creates or reuses the annotation block for the current scope
934952 fn enter_annotation_scope ( & mut self , line_number : u32 ) {
935953 let current = self . tables . last_mut ( ) . unwrap ( ) ;
936- let can_see_class_scope = current. typ == CompilerScope :: Class ;
954+ let can_see_class_scope =
955+ current. typ == CompilerScope :: Class || current. can_see_class_scope ;
937956 let has_conditional = current. has_conditional_annotations ;
938957
939958 // Create annotation block if not exists
@@ -1485,6 +1504,8 @@ impl SymbolTableBuilder {
14851504 CompilerScope :: TypeParams ,
14861505 self . line_index_start ( value. range ( ) ) ,
14871506 ) ;
1507+ // Evaluator takes a format parameter
1508+ self . register_name ( "format" , SymbolUsage :: Parameter , TextRange :: default ( ) ) ?;
14881509 if in_class {
14891510 if let Some ( table) = self . tables . last_mut ( ) {
14901511 table. can_see_class_scope = true ;
@@ -1990,6 +2011,8 @@ impl SymbolTableBuilder {
19902011 let in_class = self . tables . last ( ) . is_some_and ( |t| t. can_see_class_scope ) ;
19912012 let line_number = self . line_index_start ( expr. range ( ) ) ;
19922013 self . enter_scope ( scope_name, CompilerScope :: TypeParams , line_number) ;
2014+ // Evaluator takes a format parameter
2015+ self . register_name ( "format" , SymbolUsage :: Parameter , TextRange :: default ( ) ) ?;
19932016
19942017 if in_class {
19952018 if let Some ( table) = self . tables . last_mut ( ) {
@@ -2015,11 +2038,15 @@ impl SymbolTableBuilder {
20152038 fn scan_type_params ( & mut self , type_params : & ast:: TypeParams ) -> SymbolTableResult {
20162039 // Check for duplicate type parameter names
20172040 let mut seen_names: IndexSet < & str > = IndexSet :: default ( ) ;
2041+ // Check for non-default type parameter after default type parameter
2042+ let mut default_seen = false ;
20182043 for type_param in & type_params. type_params {
2019- let ( name, range) = match type_param {
2020- ast:: TypeParam :: TypeVar ( tv) => ( tv. name . as_str ( ) , tv. range ) ,
2021- ast:: TypeParam :: ParamSpec ( ps) => ( ps. name . as_str ( ) , ps. range ) ,
2022- ast:: TypeParam :: TypeVarTuple ( tvt) => ( tvt. name . as_str ( ) , tvt. range ) ,
2044+ let ( name, range, has_default) = match type_param {
2045+ ast:: TypeParam :: TypeVar ( tv) => ( tv. name . as_str ( ) , tv. range , tv. default . is_some ( ) ) ,
2046+ ast:: TypeParam :: ParamSpec ( ps) => ( ps. name . as_str ( ) , ps. range , ps. default . is_some ( ) ) ,
2047+ ast:: TypeParam :: TypeVarTuple ( tvt) => {
2048+ ( tvt. name . as_str ( ) , tvt. range , tvt. default . is_some ( ) )
2049+ }
20232050 } ;
20242051 if !seen_names. insert ( name) {
20252052 return Err ( SymbolTableError {
@@ -2031,6 +2058,21 @@ impl SymbolTableBuilder {
20312058 ) ,
20322059 } ) ;
20332060 }
2061+ if has_default {
2062+ default_seen = true ;
2063+ } else if default_seen {
2064+ return Err ( SymbolTableError {
2065+ error : format ! (
2066+ "non-default type parameter '{}' follows default type parameter" ,
2067+ name
2068+ ) ,
2069+ location : Some (
2070+ self . source_file
2071+ . to_source_code ( )
2072+ . source_location ( range. start ( ) , PositionEncoding :: Utf8 ) ,
2073+ ) ,
2074+ } ) ;
2075+ }
20342076 }
20352077
20362078 // Register .type_params as a type parameter (automatically becomes cell variable)
0 commit comments