Line data Source code
1 : // Copyright (C) 2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #include "rust-compile-drop.h"
20 : #include "rust-compile-drop-builder.h"
21 : #include "rust-compile-base.h"
22 : #include "rust-compile-context.h"
23 : #include "rust-compile-implitem.h"
24 : #include "rust-hir-path-probe.h"
25 : #include "rust-hir-trait-reference.h"
26 : #include "rust-hir-type-bounds.h"
27 : #include "rust-lang-item.h"
28 : #include "rust-tyty.h"
29 :
30 : namespace Rust {
31 : namespace Compile {
32 :
33 31324 : CompileDrop::CompileDrop (Context *ctx) : ctx (ctx) {}
34 :
35 : bool
36 11346 : CompileDrop::type_has_drop_impl (TyTy::BaseType *ty)
37 : {
38 11346 : auto drop_lang_item
39 11346 : = ctx->get_mappings ().lookup_lang_item (LangItem::Kind::DROP);
40 :
41 11346 : if (!drop_lang_item.has_value ())
42 : return false;
43 :
44 25 : DefId drop_id = drop_lang_item.value ();
45 :
46 25 : auto candidates = Resolver::TypeBoundsProbe::Probe (ty);
47 36 : for (auto &candidate : candidates)
48 : {
49 25 : Resolver::TraitReference *trait_ref = candidate.first;
50 36 : if (trait_ref != nullptr && trait_ref->get_defid () == drop_id)
51 14 : return true;
52 : }
53 :
54 : return false;
55 25 : }
56 :
57 : // Find the Drop trait, look for the drop method, and build the function call.
58 : tree
59 13 : CompileDrop::compile_drop_call (Bvariable *var, TyTy::BaseType *ty,
60 : location_t locus)
61 : {
62 13 : auto drop_lang = ctx->get_mappings ().lookup_lang_item (LangItem::Kind::DROP);
63 13 : if (!drop_lang.has_value ())
64 : return NULL_TREE;
65 :
66 13 : Resolver::TraitReference *drop_ref = nullptr;
67 13 : bool ok
68 13 : = ctx->get_tyctx ()->lookup_trait_reference (drop_lang.value (), &drop_ref);
69 13 : if (!ok)
70 : return NULL_TREE;
71 :
72 13 : HIR::PathIdentSegment segment ("drop");
73 13 : auto candidates
74 13 : = Resolver::PathProbeImplTrait::Probe (ty->get_root (), segment, drop_ref);
75 :
76 13 : rust_assert (candidates.size () == 1);
77 :
78 13 : auto &candidate = *candidates.begin ();
79 13 : rust_assert (candidate.is_impl_candidate ());
80 13 : rust_assert (candidate.ty->get_kind () == TyTy::TypeKind::FNDEF);
81 :
82 13 : auto *fn_type = static_cast<TyTy::FnType *> (candidate.ty);
83 13 : tree fn_addr
84 13 : = CompileInherentImplItem::Compile (candidate.item.impl.impl_item, ctx,
85 : fn_type, locus);
86 :
87 13 : tree var_expr = Backend::var_expression (var, locus);
88 13 : tree var_addr = HIRCompileBase::address_expression (var_expr, locus);
89 :
90 13 : return Backend::call_expression (fn_addr, {var_addr}, nullptr, locus);
91 13 : }
92 :
93 : void
94 19978 : CompileDrop::emit_current_scope_drop_calls ()
95 : {
96 19978 : DropBuilder drop_builder (*ctx);
97 19978 : auto &drop_candidates = drop_builder.peek_block_drop_candidates ();
98 :
99 19991 : for (auto it = drop_candidates.rbegin (); it != drop_candidates.rend (); ++it)
100 : {
101 13 : TyTy::BaseType *ty = nullptr;
102 13 : Bvariable *var = nullptr;
103 :
104 13 : bool ok = ctx->get_tyctx ()->lookup_type (it->hirid, &ty);
105 13 : rust_assert (ok);
106 :
107 13 : ok = ctx->lookup_var_decl (it->hirid, &var);
108 13 : rust_assert (ok);
109 :
110 13 : tree drop_call = compile_drop_call (var, ty, it->locus);
111 13 : if (drop_call != NULL_TREE)
112 13 : ctx->add_statement (convert_to_void (drop_call, ICV_STATEMENT));
113 : }
114 19978 : }
115 :
116 : } // namespace Compile
117 : } // namespace Rust
|