Fix TypeParams, TypeAlias compile (#5862)

This commit is contained in:
Jeong, YunWon
2025-06-29 11:24:15 +09:00
committed by GitHub
parent 0ef22ab6f2
commit 28dff8af6c
2 changed files with 34 additions and 8 deletions

View File

@@ -1042,14 +1042,32 @@ impl Compiler<'_> {
)));
};
let name_string = name.id.to_string();
if type_params.is_some() {
self.push_symbol_table();
}
self.compile_expression(value)?;
// For PEP 695 syntax, we need to compile type_params first
// so that they're available when compiling the value expression
if let Some(type_params) = type_params {
self.push_symbol_table();
// Compile type params first to define T1, T2, etc.
self.compile_type_params(type_params)?;
// Stack now has type_params tuple at top
// Compile value expression (can now see T1, T2)
self.compile_expression(value)?;
// Stack: [type_params_tuple, value]
// We need [value, type_params_tuple] for TypeAlias instruction
emit!(self, Instruction::Rotate2);
self.pop_symbol_table();
} else {
// No type params - push value first, then None (not empty tuple)
self.compile_expression(value)?;
// Push None for type_params (matching CPython)
self.emit_load_const(ConstantData::None);
}
// Push name last
self.emit_load_const(ConstantData::Str {
value: name_string.clone().into(),
});

View File

@@ -1266,10 +1266,18 @@ impl ExecutingFrame<'_> {
}
bytecode::Instruction::TypeAlias => {
let name = self.pop_value();
let type_params: PyTupleRef = self
.pop_value()
.downcast()
.map_err(|_| vm.new_type_error("Type params must be a tuple."))?;
let type_params_obj = self.pop_value();
// CPython allows None or tuple for type_params
let type_params: PyTupleRef = if vm.is_none(&type_params_obj) {
// If None, use empty tuple (matching CPython's behavior)
vm.ctx.empty_tuple.clone()
} else {
type_params_obj
.downcast()
.map_err(|_| vm.new_type_error("Type params must be a tuple."))?
};
let value = self.pop_value();
let type_alias = typing::TypeAliasType::new(name, type_params, value);
self.push_value(type_alias.into_ref(&vm.ctx).into());