◐ Shell
clean mode source ↗

Fix "tried to pop from empty stack" with BlockExpr and const by im-0 · Pull Request #7916 · RustPython/RustPython

@im-0

Constant expressions without side effects are optimized away unless in
an interactive mode[1]. This causes panic when last statement in a block
is a constant and Mode::BlockExpr is used as this constant value must be
returned to caller.

Example panic:

    ---- vm::python_run::tests::test_block_expr_return_const stdout ----
    [crates/vm/src/frame.rs:9653:9] self = ExecutingFrame {
        code: code: <code object <module> at ??? file "<embedded>", line 1>,
        stack_len: 0,
    }

    thread 'vm::python_run::tests::test_block_expr_return_const' (2640752) panicked at crates/vm/src/frame.rs:9410:18:
    tried to pop from empty stack
    stack backtrace:
       0: __rustc::rust_begin_unwind
                 at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/std/src/panicking.rs:689:5
       1: core::panicking::panic_fmt
                 at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/core/src/panicking.rs:80:14
       2: rustpython_vm::frame::ExecutingFrame::fatal
                 at ./src/frame.rs:9654:9
       3: rustpython_vm::frame::ExecutingFrame::pop_stackref_opt
                 at ./src/frame.rs:9410:18
       4: rustpython_vm::frame::ExecutingFrame::pop_stackref
                 at ./src/frame.rs:9420:18
       5: rustpython_vm::frame::ExecutingFrame::pop_value
                 at ./src/frame.rs:9435:14
       6: rustpython_vm::frame::ExecutingFrame::execute_instruction
                 at ./src/frame.rs:3391:34
       7: rustpython_vm::frame::ExecutingFrame::run
                 at ./src/frame.rs:1623:31
       8: rustpython_vm::frame::<impl rustpython_vm::object::core::Py<rustpython_vm::frame::Frame>>::run::{{closure}}
                 at ./src/frame.rs:1098:44
       9: rustpython_vm::frame::<impl rustpython_vm::object::core::Py<rustpython_vm::frame::Frame>>::with_exec
                 at ./src/frame.rs:1093:9
      10: rustpython_vm::frame::<impl rustpython_vm::object::core::Py<rustpython_vm::frame::Frame>>::run
                 at ./src/frame.rs:1098:14
      11: rustpython_vm::vm::VirtualMachine::run_frame::{{closure}}
                 at ./src/vm/mod.rs:1201:44
      12: rustpython_vm::vm::VirtualMachine::with_frame_impl::{{closure}}::{{closure}}
                 at ./src/vm/mod.rs:1610:60
      13: rustpython_vm::vm::VirtualMachine::dispatch_traced_frame
                 at ./src/vm/mod.rs:1689:22
      14: rustpython_vm::vm::VirtualMachine::with_frame_impl::{{closure}}
                 at ./src/vm/mod.rs:1610:22
      15: rustpython_vm::vm::VirtualMachine::with_recursion
                 at ./src/vm/mod.rs:1547:9
      16: rustpython_vm::vm::VirtualMachine::with_frame_impl
                 at ./src/vm/mod.rs:1572:14
      17: rustpython_vm::vm::VirtualMachine::with_frame
                 at ./src/vm/mod.rs:1555:14
      18: rustpython_vm::vm::VirtualMachine::run_frame
                 at ./src/vm/mod.rs:1201:20
      19: rustpython_vm::vm::VirtualMachine::run_code_obj
                 at ./src/vm/mod.rs:1120:14
      20: rustpython_vm::vm::python_run::<impl rustpython_vm::vm::VirtualMachine>::run_block_expr
                 at ./src/vm/python_run.rs:51:14
      21: rustpython_vm::vm::python_run::tests::test_block_expr_return_const::{{closure}}
                 at ./src/vm/python_run.rs:190:47
      22: rustpython_vm::vm::interpreter::Interpreter::enter::{{closure}}
                 at ./src/vm/interpreter.rs:366:39
      23: rustpython_vm::vm::thread::set_current_vm::{{closure}}
                 at ./src/vm/thread.rs:107:9
      24: std::thread::local::LocalKey<T>::try_with
                 at /home/im/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:513:12
      25: std::thread::local::LocalKey<T>::with
                 at /home/im/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/local.rs:477:20
      26: rustpython_vm::vm::thread::set_current_vm
                 at ./src/vm/thread.rs:102:14
      27: rustpython_vm::vm::thread::enter_vm
                 at ./src/vm/thread.rs:132:5
      28: rustpython_vm::vm::interpreter::Interpreter::enter
                 at ./src/vm/interpreter.rs:366:9
      29: rustpython_vm::vm::python_run::tests::test_block_expr_return_const
                 at ./src/vm/python_run.rs:188:23
      30: rustpython_vm::vm::python_run::tests::test_block_expr_return_const::{{closure}}
                 at ./src/vm/python_run.rs:187:38
      31: core::ops::function::FnOnce::call_once
                 at /home/im/.rustup/toolchains/stable-aarch64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
      32: <fn() -> core::result::Result<(), alloc::string::String> as core::ops::function::FnOnce<()>>::call_once
                 at /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/core/src/ops/function.rs:250:5

[1] https://github.com/RustPython/RustPython/blob/883ce9d273db98b435eb3f51128925a1255ba88d/crates/codegen/src/compile.rs#L2990-L2997