mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Assert final constant-list iterable folding in compiler regression
Preserve the 31-string fixture and require one ordered tuple constant load, one GET_ITER, and no streaming list builders, matching final CPython optimizer output. Assisted-by: OpenAI Codex:model identifier unavailable
This commit is contained in:
1 parent
246c309322
commit
7ecedcf187
1 file changed
+37
-9
@@ -32613,7 +32613,7 @@ def f(g, kwargs, ns):
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn large_constant_list_iterable_keeps_streaming_list_build() {
|
fn large_constant_list_iterable_folds_to_tuple_like_cpython() {
|
||||||
let source = format!(
|
let source = format!(
|
||||||
"def f():\n for x in [{}]:\n pass\n",
|
"def f():\n for x in [{}]:\n pass\n",
|
||||||
(0..=STACK_USE_GUIDELINE)
|
(0..=STACK_USE_GUIDELINE)
|
||||||
@@ -32624,19 +32624,47 @@ def f(g, kwargs, ns):
|
|||||||
let code = compile_exec(&source);
|
let code = compile_exec(&source);
|
||||||
let f = find_code(&code, "f").expect("missing function code");
|
let f = find_code(&code, "f").expect("missing function code");
|
||||||
|
|
||||||
assert!(
|
// Final CPython folds the stack-limited BUILD_LIST/LIST_APPEND sequence
|
||||||
f.instructions
|
// before GET_ITER, preserving every constant in its original order.
|
||||||
|
let tuple_loads = f
|
||||||
|
.instructions
|
||||||
.iter()
|
.iter()
|
||||||
.any(|unit| matches!(unit.op, Instruction::BuildList { .. })),
|
.filter_map(|unit| match unit.op {
|
||||||
"large list iterable should keep CPython streaming BUILD_LIST form, got instructions={:?}",
|
Instruction::LoadConst { consti } => {
|
||||||
|
match &f.constants[consti.get(OpArg::new(u32::from(u8::from(unit.arg))))] {
|
||||||
|
ConstantData::Tuple { elements } => Some(elements),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(tuple_loads.len(), 1);
|
||||||
|
let elements = tuple_loads[0];
|
||||||
|
assert_eq!(
|
||||||
|
elements.len(),
|
||||||
|
usize::try_from(STACK_USE_GUIDELINE + 1).unwrap()
|
||||||
|
);
|
||||||
|
for (i, element) in elements.iter().enumerate() {
|
||||||
|
assert!(matches!(
|
||||||
|
element,
|
||||||
|
ConstantData::Str { value } if value.to_string() == format!("v{i}")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
assert!(
|
||||||
|
!f.instructions.iter().any(|unit| matches!(
|
||||||
|
unit.op,
|
||||||
|
Instruction::BuildList { .. } | Instruction::ListAppend { .. }
|
||||||
|
)),
|
||||||
|
"constant iterable should use the folded tuple, got instructions={:?}",
|
||||||
f.instructions
|
f.instructions
|
||||||
);
|
);
|
||||||
assert!(
|
assert_eq!(
|
||||||
f.instructions
|
f.instructions
|
||||||
.iter()
|
.iter()
|
||||||
.any(|unit| matches!(unit.op, Instruction::ListAppend { .. })),
|
.filter(|unit| matches!(unit.op, Instruction::GetIter { .. }))
|
||||||
"large list iterable should use LIST_APPEND streaming form, got instructions={:?}",
|
.count(),
|
||||||
f.instructions
|
1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user