https://gcc.gnu.org/g:289436de097e2e8fead96c7d30afc9d8e7e773c6

commit r17-1892-g289436de097e2e8fead96c7d30afc9d8e7e773c6
Author: lishin <[email protected]>
Date:   Fri May 29 17:59:00 2026 +0000

    gccrs: add block-exit Drop calls
    
    Add a helper for building Drop calls, and use it when leaving a block.
    Add a block-exit test case.
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-block.cc (compile_drop_call): New helper to
            build a drop call.
            (CompileBlock::visit): Add drop calls for candidates.
            * backend/rust-compile-pattern.cc (type_has_drop_impl): New helper 
to
            check whether a type implements Drop.
            (CompilePatternLet::visit): Save initialized simple drop candidates.
    
    gcc/testsuite/ChangeLog:
    
            * rust/execute/drop-block-scope.rs: New test.
    
    Signed-off-by: lishin <[email protected]>

Diff:
---
 gcc/rust/backend/rust-compile-block.cc         | 58 ++++++++++++++++++++++++++
 gcc/rust/backend/rust-compile-pattern.cc       | 30 +++++++++++++
 gcc/testsuite/rust/execute/drop-block-scope.rs | 34 +++++++++++++++
 3 files changed, 122 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-block.cc 
b/gcc/rust/backend/rust-compile-block.cc
index 9a95d4e15787..21ee37c48b73 100644
--- a/gcc/rust/backend/rust-compile-block.cc
+++ b/gcc/rust/backend/rust-compile-block.cc
@@ -19,11 +19,51 @@
 #include "rust-compile-block.h"
 #include "rust-compile-stmt.h"
 #include "rust-compile-expr.h"
+#include "rust-compile-implitem.h"
 #include "rust-hir-expr.h"
+#include "rust-hir-path-probe.h"
+#include "rust-lang-item.h"
 
 namespace Rust {
 namespace Compile {
 
+static tree
+compile_drop_call (Context *ctx, Bvariable *var, TyTy::BaseType *ty,
+                  location_t locus)
+{
+  auto drop_lang = ctx->get_mappings ().lookup_lang_item 
(LangItem::Kind::DROP);
+  if (!drop_lang.has_value ())
+    return NULL_TREE;
+
+  Resolver::TraitReference *drop_ref = nullptr;
+  bool ok
+    = ctx->get_tyctx ()->lookup_trait_reference (drop_lang.value (), 
&drop_ref);
+  if (!ok)
+    return NULL_TREE;
+
+  HIR::PathIdentSegment segment ("drop");
+  auto candidates
+    = Resolver::PathProbeImplTrait::Probe (ty->get_root (), segment, drop_ref);
+
+  for (auto &candidate : candidates)
+    {
+      if (!candidate.is_impl_candidate ()
+         || candidate.ty->get_kind () != TyTy::TypeKind::FNDEF)
+       continue;
+
+      auto *fn_type = static_cast<TyTy::FnType *> (candidate.ty);
+      tree fn_addr
+       = CompileInherentImplItem::Compile (candidate.item.impl.impl_item, ctx,
+                                           fn_type, locus);
+
+      tree var_expr = Backend::var_expression (var, locus);
+      tree var_addr = HIRCompileBase::address_expression (var_expr, locus);
+
+      return Backend::call_expression (fn_addr, {var_addr}, nullptr, locus);
+    }
+  return NULL_TREE;
+}
+
 CompileBlock::CompileBlock (Context *ctx, Bvariable *result)
   : HIRCompileBase (ctx), translated (nullptr), result (result)
 {}
@@ -85,6 +125,24 @@ CompileBlock::visit (HIR::BlockExpr &expr)
       ctx->add_statement (assignment);
     }
 
+  auto &drop_candidates = ctx->peek_block_drop_candidates ();
+
+  for (auto it = drop_candidates.rbegin (); it != drop_candidates.rend (); 
++it)
+    {
+      TyTy::BaseType *ty = nullptr;
+      Bvariable *var = nullptr;
+
+      bool ok = ctx->get_tyctx ()->lookup_type (it->hirid, &ty);
+      rust_assert (ok);
+
+      ok = ctx->lookup_var_decl (it->hirid, &var);
+      rust_assert (ok);
+
+      tree drop_call = compile_drop_call (ctx, var, ty, it->locus);
+      if (drop_call != NULL_TREE)
+       ctx->add_statement (convert_to_void (drop_call, ICV_STATEMENT));
+    }
+
   ctx->pop_block ();
   translated = new_block;
 }
diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index d57616e6d095..eb1541c8ab2d 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -27,11 +27,36 @@
 #include "rust-hir-pattern.h"
 #include "rust-system.h"
 #include "rust-tyty.h"
+#include "rust-hir-type-bounds.h"
+#include "rust-hir-trait-reference.h"
+#include "rust-lang-item.h"
 #include "tree.h"
 
 namespace Rust {
 namespace Compile {
 
+static bool
+type_has_drop_impl (Context *ctx, TyTy::BaseType *ty)
+{
+  auto drop_lang_item
+    = ctx->get_mappings ().lookup_lang_item (LangItem::Kind::DROP);
+
+  if (!drop_lang_item.has_value ())
+    return false;
+
+  DefId drop_id = drop_lang_item.value ();
+
+  auto candidates = Resolver::TypeBoundsProbe::Probe (ty);
+  for (auto &candidate : candidates)
+    {
+      Resolver::TraitReference *trait_ref = candidate.first;
+      if (trait_ref != nullptr && trait_ref->get_defid () == drop_id)
+       return true;
+    }
+
+  return false;
+}
+
 void
 CompilePatternCheckExpr::visit (HIR::PathInExpression &pattern)
 {
@@ -1343,6 +1368,11 @@ CompilePatternLet::visit (HIR::IdentifierPattern 
&pattern)
       auto s = Backend::init_statement (fnctx.fndecl, var, init_expr);
       ctx->add_statement (s);
     }
+
+  if (!pattern.has_subpattern () && !pattern.get_is_ref ()
+      && type_has_drop_impl (ctx, ty))
+    ctx->note_simple_drop_candidate (pattern.get_mappings ().get_hirid (),
+                                    pattern.get_locus ());
 }
 
 void
diff --git a/gcc/testsuite/rust/execute/drop-block-scope.rs 
b/gcc/testsuite/rust/execute/drop-block-scope.rs
new file mode 100644
index 000000000000..678ad63d7529
--- /dev/null
+++ b/gcc/testsuite/rust/execute/drop-block-scope.rs
@@ -0,0 +1,34 @@
+// { dg-output "d\r*\n" }
+#![feature(no_core)]
+#![feature(lang_items)]
+#![no_core]
+
+extern "C" {
+    fn printf(s: *const i8, ...);
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "drop"]
+pub trait Drop {
+    fn drop(&mut self);
+}
+
+struct Droppable;
+
+impl Drop for Droppable {
+    fn drop(&mut self) {
+        let msg = "d\n\0" as *const str as *const i8;
+        unsafe {
+            printf(msg); 
+        }
+    }
+}
+
+fn main() -> i32 {
+    {
+        let _x = Droppable;
+    }
+    0
+}

Reply via email to