@@ -1652,6 +1652,49 @@ impl Compiler<'_> {
1652
1652
}
1653
1653
}
1654
1654
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
+
1655
1698
/// Store each type parameter so it is accessible to the current scope, and leave a tuple of
1656
1699
/// all the type parameters on the stack.
1657
1700
fn compile_type_params ( & mut self , type_params : & TypeParams ) -> CompileResult < ( ) > {
@@ -1664,21 +1707,25 @@ impl Compiler<'_> {
1664
1707
default,
1665
1708
..
1666
1709
} ) => {
1710
+ self . emit_load_const ( ConstantData :: Str {
1711
+ value : name. as_str ( ) . into ( ) ,
1712
+ } ) ;
1713
+
1667
1714
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 } ) ;
1678
1728
} else {
1679
- self . emit_load_const ( ConstantData :: Str {
1680
- value : name. as_str ( ) . into ( ) ,
1681
- } ) ;
1682
1729
emit ! (
1683
1730
self ,
1684
1731
Instruction :: CallIntrinsic1 {
@@ -1689,9 +1736,8 @@ impl Compiler<'_> {
1689
1736
1690
1737
// Handle default value if present (PEP 695)
1691
1738
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 ) ?;
1695
1741
emit ! (
1696
1742
self ,
1697
1743
Instruction :: CallIntrinsic2 {
@@ -1716,9 +1762,8 @@ impl Compiler<'_> {
1716
1762
1717
1763
// Handle default value if present (PEP 695)
1718
1764
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 ) ?;
1722
1767
emit ! (
1723
1768
self ,
1724
1769
Instruction :: CallIntrinsic2 {
@@ -1743,10 +1788,9 @@ impl Compiler<'_> {
1743
1788
1744
1789
// Handle default value if present (PEP 695)
1745
1790
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 ) ?;
1750
1794
emit ! (
1751
1795
self ,
1752
1796
Instruction :: CallIntrinsic2 {
0 commit comments