]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/rust/checks/lints/rust-lint-scan-deadcode.h
0fc203b03189355f6295b345cc87a62bdc92ccd7
1 // Copyright (C) 2021-2025 Free Software Foundation, Inc.
3 // This file is part of GCC.
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
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
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/>.
19 #ifndef RUST_HIR_SCAN_DEADCODE
20 #define RUST_HIR_SCAN_DEADCODE
22 #include "rust-hir-full-decls.h"
23 #include "rust-hir-map.h"
24 #include "rust-lint-marklive.h"
25 #include "rust-name-resolver.h"
26 #include "rust-diagnostics.h"
31 // Scan item symbols and warn the symbol if it is not in the live_symbols set.
32 // There are three kinds of item we should handle in this pass.
34 // 2. The function item in the impl block without trait
35 // 3. StructStruct, e.g., `Struct Foo{one: 1, two: 2}`. Furthermore, the unused
36 // struct fields will be warned too.
37 // 4. TupleStruct, e.g., `Struct Foo(i32, i32)`
38 class ScanDeadcode
: public MarkLiveBase
40 using Rust::Analysis::MarkLiveBase::visit
;
43 static void Scan (HIR::Crate
&crate
)
45 std::set
<HirId
> live_symbols
= Analysis::MarkLive::Analysis (crate
);
46 ScanDeadcode
sdc (live_symbols
);
47 for (auto &it
: crate
.get_items ())
48 it
.get ()->accept_vis (sdc
);
51 void visit (HIR::Function
&function
) override
53 HirId hirId
= function
.get_mappings ().get_hirid ();
54 if (should_warn (hirId
) && !function
.get_visibility ().is_public ())
56 if (mappings
.is_impl_item (hirId
))
58 HIR::ImplBlock
*implBlock
= mappings
.lookup_associated_impl (hirId
);
59 if (!implBlock
->has_trait_ref ())
62 function
.get_function_name ().get_locus (), 0,
63 "associated function is never used: %qs",
64 function
.get_function_name ().as_string ().c_str ());
70 function
.get_function_name ().get_locus (), 0,
71 "function is never used: %qs",
72 function
.get_function_name ().as_string ().c_str ());
77 void visit (HIR::StructStruct
&stct
) override
79 HirId hirId
= stct
.get_mappings ().get_hirid ();
80 if (should_warn (hirId
) && !stct
.get_visibility ().is_public ())
82 bool name_starts_underscore
83 = stct
.get_identifier ().as_string ().at (0) == '_';
84 if (!name_starts_underscore
)
85 rust_warning_at (stct
.get_locus (), 0,
86 "struct is never constructed: %qs",
87 stct
.get_identifier ().as_string ().c_str ());
91 // only warn the unused fields when in unwarned struct.
92 for (auto &field
: stct
.get_fields ())
94 HirId field_hir_id
= field
.get_mappings ().get_hirid ();
95 if (should_warn (field_hir_id
)
96 && !field
.get_visibility ().is_public ()
97 && field
.get_field_name ().as_string ().at (0) != '_')
99 rust_warning_at (field
.get_locus (), 0,
100 "field is never read: %qs",
101 field
.get_field_name ().as_string ().c_str ());
107 void visit (HIR::TupleStruct
&stct
) override
109 // only warn tuple struct unconstructed, and ignoring unused field
110 HirId hirId
= stct
.get_mappings ().get_hirid ();
111 if (should_warn (hirId
) && !stct
.get_visibility ().is_public ())
113 rust_warning_at (stct
.get_locus (), 0,
114 "struct is never constructed: %qs",
115 stct
.get_identifier ().as_string ().c_str ());
119 void visit (HIR::ImplBlock
&blc
) override
121 if (blc
.has_impl_items ())
123 for (auto &implItem
: blc
.get_impl_items ())
125 implItem
->accept_vis (*this);
130 void visit (HIR::Module
&mod
) override
132 for (auto &item
: mod
.get_items ())
133 item
->accept_vis (*this);
137 std::set
<HirId
> live_symbols
;
138 Resolver::Resolver
*resolver
;
139 Analysis::Mappings
&mappings
;
141 ScanDeadcode (std::set
<HirId
> &live_symbols
)
142 : live_symbols (live_symbols
), resolver (Resolver::Resolver::get ()),
143 mappings (Analysis::Mappings::get ()){};
145 bool should_warn (HirId hirId
)
147 // TODO: There are more condition to check if should warn, i.e visibility,
149 return live_symbols
.find (hirId
) == live_symbols
.end ();
153 } // namespace Analysis