aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-07-15 15:33:18 +0000
committerGitHub <noreply@github.com>2021-07-15 15:33:18 +0000
commit2404e4841d424aa05d5d218c24130cccec04eeef (patch)
treed0eb002fddc792b4ac8000da2d97c7806157159b /gcc
parent089e62f33c328afea756ec4b92f5823584b08a3a (diff)
parent9bebd1e79ca486f74f31d0e64575ac6b4f472f74 (diff)
downloadgcc-2404e4841d424aa05d5d218c24130cccec04eeef.zip
gcc-2404e4841d424aa05d5d218c24130cccec04eeef.tar.gz
gcc-2404e4841d424aa05d5d218c24130cccec04eeef.tar.bz2
Merge #567
567: warn the unused associated functions r=philberty a=thomasyonug warn the unused associated functions Co-authored-by: Thomas Young <wenzhang5800@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/lint/rust-lint-marklive.cc44
-rw-r--r--gcc/rust/lint/rust-lint-marklive.h3
-rw-r--r--gcc/rust/lint/rust-lint-scan-deadcode.h37
-rw-r--r--gcc/rust/util/rust-hir-map.h7
-rw-r--r--gcc/testsuite/rust/compile/torture/generics13.rs3
-rw-r--r--gcc/testsuite/rust/compile/torture/generics14.rs3
-rw-r--r--gcc/testsuite/rust/compile/torture/generics18.rs3
-rw-r--r--gcc/testsuite/rust/compile/torture/generics24.rs3
-rw-r--r--gcc/testsuite/rust/compile/torture/impl_block_unused.rs19
9 files changed, 103 insertions, 19 deletions
diff --git a/gcc/rust/lint/rust-lint-marklive.cc b/gcc/rust/lint/rust-lint-marklive.cc
index 8339345..87fa3ef 100644
--- a/gcc/rust/lint/rust-lint-marklive.cc
+++ b/gcc/rust/lint/rust-lint-marklive.cc
@@ -106,11 +106,42 @@ MarkLive::go (HIR::Crate &crate)
void
MarkLive::visit (HIR::PathInExpression &expr)
{
- // We should iterate every path segment in order to mark the function which is
- // called in the expression
+ // We should iterate every path segment in order to mark the struct which
+ // is used in expression like Foo::bar(), we should mark the Foo alive.
expr.iterate_path_segments ([&] (HIR::PathExprSegment &seg) -> bool {
return visit_path_segment (seg);
});
+
+ // after iterate the path segments, we should mark functions and associated
+ // functions alive.
+ NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
+ NodeId ref_node_id = UNKNOWN_NODEID;
+ find_ref_node_id (ast_node_id, ref_node_id);
+
+ // node back to HIR
+ HirId ref;
+ bool ok = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
+ ref_node_id, &ref);
+ rust_assert (ok);
+
+ // it must resolve to some kind of HIR::Item or HIR::InheritImplItem
+ HIR::Item *resolved_item
+ = mappings->lookup_hir_item (expr.get_mappings ().get_crate_num (), ref);
+ if (resolved_item != nullptr)
+ {
+ mark_hir_id (resolved_item->get_mappings ().get_hirid ());
+ }
+ else
+ {
+ HirId parent_impl_id = UNKNOWN_HIRID;
+ HIR::ImplItem *resolved_item
+ = mappings->lookup_hir_implitem (expr.get_mappings ().get_crate_num (),
+ ref, &parent_impl_id);
+ if (resolved_item != nullptr)
+ {
+ mark_hir_id (resolved_item->get_impl_mappings ().get_hirid ());
+ }
+ }
}
void
@@ -126,8 +157,7 @@ MarkLive::visit (HIR::MethodCallExpr &expr)
// Trying to find the method definition and mark it alive.
NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
NodeId ref_node_id = UNKNOWN_NODEID;
- find_ref_node_id (ast_node_id, ref_node_id, expr.get_locus (),
- expr.as_string ());
+ find_ref_node_id (ast_node_id, ref_node_id);
// node back to HIR
HirId ref;
@@ -215,8 +245,7 @@ MarkLive::visit (HIR::IdentifierExpr &expr)
{
NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
NodeId ref_node_id = UNKNOWN_NODEID;
- find_ref_node_id (ast_node_id, ref_node_id, expr.get_locus (),
- expr.as_string ());
+ find_ref_node_id (ast_node_id, ref_node_id);
// node back to HIR
HirId ref;
@@ -251,8 +280,7 @@ MarkLive::mark_hir_id (HirId id)
}
void
-MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id,
- Location locus, const std::string &node_name)
+MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id)
{
if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
diff --git a/gcc/rust/lint/rust-lint-marklive.h b/gcc/rust/lint/rust-lint-marklive.h
index e6ca4ae..780b264 100644
--- a/gcc/rust/lint/rust-lint-marklive.h
+++ b/gcc/rust/lint/rust-lint-marklive.h
@@ -267,8 +267,7 @@ private:
void mark_hir_id (HirId);
bool visit_path_segment (HIR::PathExprSegment);
- void find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id,
- Location locus, const std::string &node_name);
+ void find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id);
};
} // namespace Analysis
diff --git a/gcc/rust/lint/rust-lint-scan-deadcode.h b/gcc/rust/lint/rust-lint-scan-deadcode.h
index 6cf6281..464852a 100644
--- a/gcc/rust/lint/rust-lint-scan-deadcode.h
+++ b/gcc/rust/lint/rust-lint-scan-deadcode.h
@@ -32,7 +32,7 @@ namespace Analysis {
// Scan item symbols and warn the symbol if it is not in the live_symbols set.
// There are three kinds of item we should handle in this pass.
// 1. Function item
-// 2. TODO: The function item in the impl block without trait
+// 2. The function item in the impl block without trait
// 3. StructStruct, e.g., `Struct Foo{one: 1, two: 2}`. Furthermore, the unused
// struct fields will be warned too.
// 4. TupleStruct, e.g., `Struct Foo(i32, i32)`
@@ -56,9 +56,23 @@ public:
HirId hirId = function.get_mappings ().get_hirid ();
if (should_warn (hirId))
{
- rust_warning_at (function.get_locus (), 0,
- "function is never used: %<%s%>",
- function.get_function_name ().c_str ());
+ if (mappings->is_impl_item (hirId))
+ {
+ HIR::ImplBlock *implBlock
+ = mappings->lookup_associated_impl (hirId);
+ if (!implBlock->has_trait_ref ())
+ {
+ rust_warning_at (function.get_locus (), 0,
+ "associated function is never used: %<%s%>",
+ function.get_function_name ().c_str ());
+ }
+ }
+ else
+ {
+ rust_warning_at (function.get_locus (), 0,
+ "function is never used: %<%s%>",
+ function.get_function_name ().c_str ());
+ }
}
}
@@ -99,12 +113,25 @@ public:
}
}
+ void visit (HIR::ImplBlock &blc) override
+ {
+ if (blc.has_impl_items ())
+ {
+ for (auto &implItem : blc.get_impl_items ())
+ {
+ implItem->accept_vis (*this);
+ }
+ }
+ }
+
private:
std::set<HirId> live_symbols;
Resolver::Resolver *resolver;
+ Analysis::Mappings *mappings;
ScanDeadcode (std::set<HirId> &live_symbols)
- : live_symbols (live_symbols), resolver (Resolver::Resolver::get ()){};
+ : live_symbols (live_symbols), resolver (Resolver::Resolver::get ()),
+ mappings (Analysis::Mappings::get ()){};
bool should_warn (HirId hirId)
{
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index cb3f12b..9b67928 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -194,6 +194,13 @@ public:
void iterate_impl_items (
std::function<bool (HirId, HIR::ImplItem *, HIR::ImplBlock *)> cb);
+ bool is_impl_item (HirId id)
+ {
+ HirId parent_impl_block_id = UNKNOWN_HIRID;
+ return lookup_hir_implitem (get_current_crate (), id, &parent_impl_block_id)
+ != nullptr;
+ }
+
private:
Mappings ();
diff --git a/gcc/testsuite/rust/compile/torture/generics13.rs b/gcc/testsuite/rust/compile/torture/generics13.rs
index e924ab4..cc781d8 100644
--- a/gcc/testsuite/rust/compile/torture/generics13.rs
+++ b/gcc/testsuite/rust/compile/torture/generics13.rs
@@ -14,7 +14,8 @@ impl Foo<isize> {
}
fn bar(self) -> isize {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+ // { dg-warning "unused name" "" { target *-*-* } .-2 }
self.a
}
}
diff --git a/gcc/testsuite/rust/compile/torture/generics14.rs b/gcc/testsuite/rust/compile/torture/generics14.rs
index 0d2e390..d6fbc0c 100644
--- a/gcc/testsuite/rust/compile/torture/generics14.rs
+++ b/gcc/testsuite/rust/compile/torture/generics14.rs
@@ -9,7 +9,8 @@ impl Foo<isize> {
}
fn bar(self) -> isize {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+ // { dg-warning "unused name" "" { target *-*-* } .-2 }
self.a
}
}
diff --git a/gcc/testsuite/rust/compile/torture/generics18.rs b/gcc/testsuite/rust/compile/torture/generics18.rs
index 904cb9a..924b30c 100644
--- a/gcc/testsuite/rust/compile/torture/generics18.rs
+++ b/gcc/testsuite/rust/compile/torture/generics18.rs
@@ -2,7 +2,8 @@ struct Foo<T>(T);
impl<X> Foo<X> {
fn new(a: X) -> Self {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+ // { dg-warning "unused name" "" { target *-*-* } .-2 }
Self(a)
}
diff --git a/gcc/testsuite/rust/compile/torture/generics24.rs b/gcc/testsuite/rust/compile/torture/generics24.rs
index 9d24bce..85ea2f7 100644
--- a/gcc/testsuite/rust/compile/torture/generics24.rs
+++ b/gcc/testsuite/rust/compile/torture/generics24.rs
@@ -10,7 +10,8 @@ impl Foo<isize> {
impl Foo<char> {
fn bar(self) -> char {
- // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+ // { dg-warning "unused name" "" { target *-*-* } .-2 }
self.a
}
}
diff --git a/gcc/testsuite/rust/compile/torture/impl_block_unused.rs b/gcc/testsuite/rust/compile/torture/impl_block_unused.rs
new file mode 100644
index 0000000..ef40e18
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/impl_block_unused.rs
@@ -0,0 +1,19 @@
+struct Foo(i32, bool);
+
+impl Foo {
+ fn new(a: i32, b: bool) -> Foo {
+ // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+ // { dg-warning "unused name" "" { target *-*-* } .-2 }
+ Foo(a, b)
+ }
+
+ fn test2() -> i32 {
+ // { dg-warning "associated function is never used" "" { target *-*-* } .-1 }
+ // { dg-warning "unused name" "" { target *-*-* } .-2 }
+ 1
+ }
+}
+
+fn main() {
+ let _a = Foo(1, true);
+}