gccrs: Evaluate non-unit tail expressions before drops
Ensures non-unit tail expressions are evaluated before local drops in Rust functions.
This change modifies the Rust compiler frontend to correctly evaluate non-unit tail expressions before any local variable drops occur within a function body. Previously, a non-unit tail call could execute after local drops, potentially leading to incorrect program state. The fix involves storing the result of the tail expression before emitting the drops and then returning the stored value, ensuring proper execution order.
In Details
In gccrs, the HIRCompileBase::compile_function_body pass needs to ensure that the evaluation order of tail expressions respects variable drop semantics. This commit adjusts the code generation to materialize the result of a non-unit tail expression prior to emitting scope-level drops, thereby guaranteeing that the value is available and correctly handled if it's not () (unit type). This addresses a potential correctness issue in the backend's handling of control flow and destructors.
- non-unit tail expression
- In Rust, a tail expression is the last expression in a function body. If this expression does not evaluate to the unit type
(), its value is returned by the function. A non-unit tail expression means the function will return a specific value. - drops
- In Rust, when a value goes out of scope, its
dropmethod (if defined) is automatically called to clean up resources. This is Rust's mechanism for deterministic destruction. - HIR
- High-Level Intermediate Representation. This is a representation of the Rust code after parsing and some initial type checking, but before optimization or backend code generation.