[gccrs COMMIT] gccrs: Separate argument and function body drop scopes

[email protected] Mon, 3 Aug 2026 11:19:26 +0000
Newsgroups gmane.comp.gcc.rust,gmane.comp.gcc.patches
Message-ID <[email protected]>
From: Lishin <[email protected]>

Create the argument scope before compiling function parameters, so their
drops are registered directly in that scope.

Compile the function body in a nested scope. Clean up the body scope
before the argument scope, so body locals are dropped before parameters.

gcc/rust/ChangeLog:

	* backend/rust-compile-base.cc
	(HIRCompileBase::compile_function): Create separate argument and
	function body drop scopes. Register parameter drop candidates in
	the argument scope and clean up the function body before the arguments.

Signed-off-by: Lishin <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: https://github.com/Rust-GCC/gccrs/commit/e57e60d84b5f3f1f0f95243283bfd1466d2f2869

The commit has NOT been mentioned in any issue.

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4718

 gcc/rust/backend/rust-compile-base.cc | 47 +++++++++++++++++----------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 7f9c56ca7..3c7cb71d2 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -842,7 +842,17 @@ HIRCompileBase::compile_function (
   // setup the params
   TyTy::BaseType *tyret = fntype->get_return_type ();
   std::vector<Bvariable *> param_vars;
-  std::vector<DropCandidate> param_drop_candidates;
+
+  tree enclosing_scope = NULL_TREE;
+  location_t start_location = function_body->get_locus ();
+  location_t end_location = function_body->get_end_locus ();
+
+  tree arg_scope_block = Backend::block (fndecl, enclosing_scope, {} /*locals*/,
+					 start_location, end_location);
+  ctx->push_block (arg_scope_block);
+
+  DropBuilder drop_builder (*ctx);
+
   if (self_param)
     {
       rust_assert (fntype->is_method ());
@@ -880,25 +890,16 @@ HIRCompileBase::compile_function (
 			    compiled_param_var);
 
       if (CompileDrop (ctx).type_has_drop_impl (param_tyty))
-	param_drop_candidates.emplace_back (
+	drop_builder.note_simple_drop_candidate (
 	  param_pattern.get_mappings ().get_hirid (),
 	  param_pattern.get_locus ());
     }
 
   if (!Backend::function_set_parameters (fndecl, param_vars))
-    return error_mark_node;
-
-  tree enclosing_scope = NULL_TREE;
-  location_t start_location = function_body->get_locus ();
-  location_t end_location = function_body->get_end_locus ();
-
-  tree code_block = Backend::block (fndecl, enclosing_scope, {} /*locals*/,
-				    start_location, end_location);
-  ctx->push_block (code_block);
-
-  DropBuilder drop_builder (*ctx);
-  for (auto &candidate : param_drop_candidates)
-    drop_builder.note_simple_drop_candidate (candidate.hirid, candidate.locus);
+    {
+      ctx->pop_block ();
+      return error_mark_node;
+    }
 
   Bvariable *return_address = nullptr;
   tree return_type = TyTyResolveCompile::compile (ctx, tyret);
@@ -906,17 +907,27 @@ HIRCompileBase::compile_function (
   bool address_is_taken = false;
   tree ret_var_stmt = NULL_TREE;
   return_address
-    = Backend::temporary_variable (fndecl, code_block, return_type, NULL,
+    = Backend::temporary_variable (fndecl, arg_scope_block, return_type, NULL,
 				   address_is_taken, locus, &ret_var_stmt);
 
   ctx->add_statement (ret_var_stmt);
 
   ctx->push_fn (fndecl, return_address, tyret);
+  tree body_scope_block
+    = Backend::block (fndecl, arg_scope_block, {} /*locals*/, start_location,
+		      end_location);
+  ctx->push_block (body_scope_block);
+
   compile_function_body (fndecl, *function_body, tyret);
 
-  tree cleanup = CompileDrop (ctx).build_current_scope_drop_cleanup ();
+  tree body_cleanup = CompileDrop (ctx).build_current_scope_drop_cleanup ();
+  tree body_bind_tree
+    = ctx->pop_block_with_cleanup (body_cleanup, function_body->get_locus ());
+  ctx->add_statement (body_bind_tree);
+
+  tree arg_cleanup = CompileDrop (ctx).build_current_scope_drop_cleanup ();
   tree bind_tree
-    = ctx->pop_block_with_cleanup (cleanup, function_body->get_locus ());
+    = ctx->pop_block_with_cleanup (arg_cleanup, function_body->get_locus ());
 
   gcc_assert (TREE_CODE (bind_tree) == BIND_EXPR);
   DECL_SAVED_TREE (fndecl) = bind_tree;

base-commit: 03b5b9e4ae8e7ef12a85d1a1b619b5b94bf6f38d
-- 
2.54.0