@@ -1652,6 +1652,49 @@ impl Compiler<'_> {
16521652 }
16531653 }
16541654
1655+ /// Compile type parameter bound or default in a separate scope and return closure
1656+ fn compile_type_param_bound_or_default (
1657+ & mut self ,
1658+ expr : & Expr ,
1659+ name : & str ,
1660+ allow_starred : bool ,
1661+ ) -> CompileResult < ( ) > {
1662+ // Push the next symbol table onto the stack
1663+ self . push_symbol_table ( ) ;
1664+
1665+ // Get the current symbol table
1666+ let key = self . symbol_table_stack . len ( ) - 1 ;
1667+ let lineno = expr. range ( ) . start ( ) . to_u32 ( ) ;
1668+
1669+ // Enter scope with the type parameter name
1670+ self . enter_scope ( name, CompilerScope :: TypeParams , key, lineno) ?;
1671+
1672+ // Compile the expression
1673+ if allow_starred && matches ! ( expr, Expr :: Starred ( _) ) {
1674+ if let Expr :: Starred ( starred) = expr {
1675+ self . compile_expression ( & starred. value ) ?;
1676+ emit ! ( self , Instruction :: UnpackSequence { size: 1 } ) ;
1677+ }
1678+ } else {
1679+ self . compile_expression ( expr) ?;
1680+ }
1681+
1682+ // Return value
1683+ emit ! ( self , Instruction :: ReturnValue ) ;
1684+
1685+ // Exit scope and create closure
1686+ let code = self . exit_scope ( ) ;
1687+ // Note: exit_scope already calls pop_symbol_table, so we don't need to call it again
1688+
1689+ // Create type params function with closure
1690+ self . make_closure ( code, bytecode:: MakeFunctionFlags :: empty ( ) ) ?;
1691+
1692+ // Call the function immediately
1693+ emit ! ( self , Instruction :: CallFunctionPositional { nargs: 0 } ) ;
1694+
1695+ Ok ( ( ) )
1696+ }
1697+
16551698 /// Store each type parameter so it is accessible to the current scope, and leave a tuple of
16561699 /// all the type parameters on the stack.
16571700 fn compile_type_params ( & mut self , type_params : & TypeParams ) -> CompileResult < ( ) > {
@@ -1664,21 +1707,25 @@ impl Compiler<'_> {
16641707 default,
16651708 ..
16661709 } ) => {
1710+ self . emit_load_const ( ConstantData :: Str {
1711+ value : name. as_str ( ) . into ( ) ,
1712+ } ) ;
1713+
16671714 if let Some ( expr) = & bound {
1668- self . compile_expression ( expr) ?;
1669- self . emit_load_const ( ConstantData :: Str {
1670- value : name. as_str ( ) . into ( ) ,
1671- } ) ;
1672- emit ! (
1673- self ,
1674- Instruction :: CallIntrinsic2 {
1675- func: bytecode:: IntrinsicFunction2 :: TypeVarWithBound
1676- }
1677- ) ;
1715+ let scope_name = if expr. is_tuple_expr ( ) {
1716+ format ! ( "<TypeVar constraint of {name}>" )
1717+ } else {
1718+ format ! ( "<TypeVar bound of {name}>" )
1719+ } ;
1720+ self . compile_type_param_bound_or_default ( expr, & scope_name, false ) ?;
1721+
1722+ let intrinsic = if expr. is_tuple_expr ( ) {
1723+ bytecode:: IntrinsicFunction2 :: TypeVarWithConstraint
1724+ } else {
1725+ bytecode:: IntrinsicFunction2 :: TypeVarWithBound
1726+ } ;
1727+ emit ! ( self , Instruction :: CallIntrinsic2 { func: intrinsic } ) ;
16781728 } else {
1679- self . emit_load_const ( ConstantData :: Str {
1680- value : name. as_str ( ) . into ( ) ,
1681- } ) ;
16821729 emit ! (
16831730 self ,
16841731 Instruction :: CallIntrinsic1 {
@@ -1689,9 +1736,8 @@ impl Compiler<'_> {
16891736
16901737 // Handle default value if present (PEP 695)
16911738 if let Some ( default_expr) = default {
1692- // Compile the default expression
1693- self . compile_expression ( default_expr) ?;
1694-
1739+ let scope_name = format ! ( "<TypeVar default of {name}>" ) ;
1740+ self . compile_type_param_bound_or_default ( default_expr, & scope_name, false ) ?;
16951741 emit ! (
16961742 self ,
16971743 Instruction :: CallIntrinsic2 {
@@ -1716,9 +1762,8 @@ impl Compiler<'_> {
17161762
17171763 // Handle default value if present (PEP 695)
17181764 if let Some ( default_expr) = default {
1719- // Compile the default expression
1720- self . compile_expression ( default_expr) ?;
1721-
1765+ let scope_name = format ! ( "<ParamSpec default of {name}>" ) ;
1766+ self . compile_type_param_bound_or_default ( default_expr, & scope_name, false ) ?;
17221767 emit ! (
17231768 self ,
17241769 Instruction :: CallIntrinsic2 {
@@ -1743,10 +1788,9 @@ impl Compiler<'_> {
17431788
17441789 // Handle default value if present (PEP 695)
17451790 if let Some ( default_expr) = default {
1746- // Compile the default expression
1747- self . compile_expression ( default_expr) ?;
1748-
1749- // Handle starred expression (*default)
1791+ // TypeVarTuple allows starred expressions
1792+ let scope_name = format ! ( "<TypeVarTuple default of {name}>" ) ;
1793+ self . compile_type_param_bound_or_default ( default_expr, & scope_name, true ) ?;
17501794 emit ! (
17511795 self ,
17521796 Instruction :: CallIntrinsic2 {
0 commit comments