rust/rust-const-checker.o \
rust/rust-lint-marklive.o \
rust/rust-lint-unused-var.o \
+ rust/rust-unused-var-checker.o \
+ rust/rust-unused-var-collector.o \
+ rust/rust-unused-var-context.o \
rust/rust-readonly-check.o \
rust/rust-hir-type-check-path.o \
rust/rust-unsafe-checker.o \
-I $(srcdir)/rust/typecheck \
-I $(srcdir)/rust/checks/lints \
-I $(srcdir)/rust/checks/errors \
+ -I $(srcdir)/rust/checks/lints/unused-var \
-I $(srcdir)/rust/checks/errors/privacy \
-I $(srcdir)/rust/checks/errors/borrowck \
-I $(srcdir)/rust/checks/errors/feature \
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
$(POSTCOMPILE)
+# build unused variable checking pass files in rust folder
+rust/%.o: rust/checks/lints/unused-var/%.cc
+ $(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+ $(POSTCOMPILE)
+
# build rust/checks/errors files in rust folder
rust/%.o: rust/checks/errors/%.cc
$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
--- /dev/null
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-unused-var-checker.h"
+#include "rust-hir-item.h"
+
+#include "options.h"
+
+namespace Rust {
+namespace Analysis {
+UnusedVarChecker::UnusedVarChecker ()
+ : nr_context (
+ Resolver2_0::ImmutableNameResolutionContext::get ().resolver ()),
+ mappings (Analysis::Mappings::get ()),
+ unused_var_context (std::make_unique<UnusedVarContext> ())
+{}
+void
+UnusedVarChecker::go (HIR::Crate &crate)
+{
+ UnusedVarCollector collector (*unused_var_context);
+ collector.go (crate);
+ for (auto &item : crate.get_items ())
+ item->accept_vis (*this);
+}
+void
+UnusedVarChecker::visit (HIR::ConstantItem &item)
+{
+ std::string var_name = item.get_identifier ().as_string ();
+ bool starts_with_under_score = var_name.compare (0, 1, "_") == 0;
+ auto id = item.get_mappings ().get_hirid ();
+ if (!unused_var_context->is_variable_used (id) && !starts_with_under_score)
+ rust_warning_at (item.get_locus (), OPT_Wunused_variable,
+ "unused name '%s'",
+ item.get_identifier ().as_string ().c_str ());
+}
+
+void
+UnusedVarChecker::visit (HIR::StaticItem &item)
+{
+ std::string var_name = item.get_identifier ().as_string ();
+ bool starts_with_under_score = var_name.compare (0, 1, "_") == 0;
+ auto id = item.get_mappings ().get_hirid ();
+ if (!unused_var_context->is_variable_used (id) && !starts_with_under_score)
+ rust_warning_at (item.get_locus (), OPT_Wunused_variable,
+ "unused name '%s'",
+ item.get_identifier ().as_string ().c_str ());
+}
+
+void
+UnusedVarChecker::visit (HIR::TraitItemFunc &item)
+{
+ // TODO: check trait item functions if they are not derived.
+}
+void
+UnusedVarChecker::visit (HIR::IdentifierPattern &pattern)
+{
+ std::string var_name = pattern.get_identifier ().as_string ();
+ bool starts_with_under_score = var_name.compare (0, 1, "_") == 0;
+ auto id = pattern.get_mappings ().get_hirid ();
+ if (!unused_var_context->is_variable_used (id) && var_name != "self"
+ && !starts_with_under_score)
+ rust_warning_at (pattern.get_locus (), OPT_Wunused_variable,
+ "unused name '%s'",
+ pattern.get_identifier ().as_string ().c_str ());
+}
+} // namespace Analysis
+} // namespace Rust
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-hir-item.h"
+#include "rust-hir-pattern.h"
+#include "rust-hir-visitor.h"
+#include "rust-immutable-name-resolution-context.h"
+#include "rust-unused-var-collector.h"
+
+namespace Rust {
+namespace Analysis {
+class UnusedVarChecker : public HIR::DefaultHIRVisitor
+{
+public:
+ UnusedVarChecker ();
+ void go (HIR::Crate &crate);
+
+private:
+ const Resolver2_0::NameResolutionContext &nr_context;
+ Analysis::Mappings &mappings;
+ std::unique_ptr<UnusedVarContext> unused_var_context;
+
+ using HIR::DefaultHIRVisitor::visit;
+ virtual void visit (HIR::TraitItemFunc &decl) override;
+ virtual void visit (HIR::ConstantItem &item) override;
+ virtual void visit (HIR::StaticItem &item) override;
+ virtual void visit (HIR::IdentifierPattern &identifier) override;
+};
+} // namespace Analysis
+} // namespace Rust
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-unused-var-collector.h"
+#include "rust-hir-full-decls.h"
+#include "rust-hir-item.h"
+#include "rust-hir-path.h"
+#include "rust-hir-pattern.h"
+#include "rust-immutable-name-resolution-context.h"
+
+namespace Rust {
+namespace Analysis {
+UnusedVarCollector::UnusedVarCollector (UnusedVarContext &context)
+ : nr_context (
+ Resolver2_0::ImmutableNameResolutionContext::get ().resolver ()),
+ mappings (Analysis::Mappings::get ()), unused_var_context (context)
+{}
+void
+UnusedVarCollector::go (HIR::Crate &crate)
+{
+ for (auto &item : crate.get_items ())
+ item->accept_vis (*this);
+}
+
+void
+UnusedVarCollector::visit (HIR::ConstantItem &item)
+{
+ unused_var_context.add_variable (item.get_mappings ().get_hirid ());
+ walk (item);
+}
+
+void
+UnusedVarCollector::visit (HIR::StaticItem &item)
+{
+ unused_var_context.add_variable (item.get_mappings ().get_hirid ());
+ walk (item);
+}
+
+void
+UnusedVarCollector::visit (HIR::IdentifierPattern &pattern)
+{
+ auto id = pattern.get_mappings ().get_hirid ();
+ unused_var_context.add_variable (id);
+}
+
+void
+UnusedVarCollector::visit (HIR::PathInExpression &expr)
+{
+ mark_path_used (expr);
+}
+
+void
+UnusedVarCollector::visit (HIR::QualifiedPathInExpression &expr)
+{
+ mark_path_used (expr);
+}
+
+void
+UnusedVarCollector::visit (HIR::StructExprFieldIdentifier &ident)
+{
+ mark_path_used (ident);
+}
+} // namespace Analysis
+} // namespace Rust
--- /dev/null
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-hir-expr.h"
+#include "rust-hir-item.h"
+#include "rust-hir-path.h"
+#include "rust-hir-pattern.h"
+#include "rust-hir-visitor.h"
+#include "rust-mapping-common.h"
+#include "rust-name-resolution-context.h"
+#include "rust-unused-var-context.h"
+#include "rust-name-resolver.h"
+
+namespace Rust {
+namespace Analysis {
+class UnusedVarCollector : public HIR::DefaultHIRVisitor
+{
+public:
+ UnusedVarCollector (UnusedVarContext &context);
+ void go (HIR::Crate &crate);
+
+private:
+ const Resolver2_0::NameResolutionContext &nr_context;
+ Analysis::Mappings &mappings;
+ UnusedVarContext &unused_var_context;
+
+ using HIR::DefaultHIRVisitor::visit;
+ virtual void visit (HIR::PathInExpression &expr) override;
+ virtual void visit (HIR::StructExprFieldIdentifier &ident) override;
+ virtual void visit (HIR::ConstantItem &item) override;
+ virtual void visit (HIR::StaticItem &item) override;
+ virtual void visit (HIR::IdentifierPattern &pattern) override;
+ virtual void visit (HIR::QualifiedPathInExpression &expr) override;
+
+ template <typename T> void mark_path_used (T &path_expr)
+ {
+ NodeId ast_node_id = path_expr.get_mappings ().get_nodeid ();
+ NodeId def_id = nr_context.lookup (ast_node_id).value ();
+ HirId hir_id = mappings.lookup_node_to_hir (def_id).value ();
+ unused_var_context.mark_used (hir_id);
+ }
+};
+} // namespace Analysis
+} // namespace Rust
\ No newline at end of file
--- /dev/null
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-unused-var-context.h"
+
+namespace Rust {
+namespace Analysis {
+
+void
+UnusedVarContext::add_variable (HirId id)
+{
+ if (is_used.find (id) == is_used.end ())
+ is_used.insert ({id, false});
+}
+
+void
+UnusedVarContext::mark_used (HirId id)
+{
+ is_used[id] = true;
+}
+
+bool
+UnusedVarContext::is_variable_used (HirId id) const
+{
+ auto it = is_used.find (id);
+ return it != is_used.end () && it->second;
+}
+
+std::string
+UnusedVarContext::as_string () const
+{
+ std::stringstream ss;
+ ss << "UnusedVarContext: ";
+ for (const auto &pair : is_used)
+ {
+ ss << "HirId: " << pair.first << " Used: " << (pair.second ? "Yes" : "No")
+ << "\n";
+ }
+ return ss.str ();
+}
+
+} // namespace Analysis
+} // namespace Rust
--- /dev/null
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-mapping-common.h"
+
+namespace Rust {
+namespace Analysis {
+
+class UnusedVarContext
+{
+public:
+ void add_variable (HirId id);
+ void mark_used (HirId id);
+
+ bool is_variable_used (HirId id) const;
+
+ std::string as_string () const;
+
+private:
+ std::map<HirId, bool> is_used;
+};
+
+} // namespace Analysis
+} // namespace Rust
Rust Var(flag_assume_builtin_offset_of)
Define a built-in offset_of macro in the compiler and assume it is present
+frust-unused-check-2.0
+Rust Var(flag_unused_check_2_0)
+Use the new unused variable check instead of old one
+
; This comment is to ensure we retain the blank line above.
#include "rust-cfg-parser.h"
#include "rust-lint-scan-deadcode.h"
#include "rust-lint-unused-var.h"
+#include "rust-unused-var-checker.h"
#include "rust-readonly-check.h"
#include "rust-hir-dump.h"
#include "rust-ast-dump.h"
{
// lints
Analysis::ScanDeadcode::Scan (hir);
- Analysis::UnusedVariables::Lint (*ctx);
+
+ if (flag_unused_check_2_0)
+ Analysis::UnusedVarChecker ().go (hir);
+ else
+ Analysis::UnusedVariables::Lint (*ctx);
+
HIR::ReadonlyChecker ().go (hir);
// metadata
--- /dev/null
+// { dg-additional-options "-frust-unused-check-2.0" }
+static TEST: usize = 1;
+// { dg-warning "unused name" "" { target *-*-* } .-1 }
\ No newline at end of file
--- /dev/null
+// { dg-additional-options "-frust-unused-check-2.0" }
+#![feature(lang_items)]
+#[lang = "sized"]
+pub trait Sized {}
+
+pub fn test<T> (a: usize) -> () {
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+}