[gccrs COMMIT] gccrs: add double negations lint
[email protected] Thu, 6 Aug 2026 14:37:27 +0000
| Newsgroups | gmane.comp.gcc.rust,gmane.comp.gcc.patches |
|---|---|
| Message-ID | <[email protected]> |
From: Lucas Ly Ba <[email protected]> Warn on a double arithmetic negation such as `- -x`, which is likely a mistake (Rust has no `--` operator). gcc/rust/ChangeLog: * checks/lints/unused/rust-unused-checker.cc (UnusedChecker::visit): New. * checks/lints/unused/rust-unused-checker.h (UnusedChecker::visit): New. gcc/testsuite/ChangeLog: * rust/compile/double-negations_0.rs: New test. Signed-off-by: Lucas Ly Ba <[email protected]> --- This change was merged into the gccrs repository and is posted here for upstream visibility and potential drive-by review, as requested by GCC release managers. Each commit email contains a link to its details on github from where you can find the Pull-Request and associated discussions. Commit on github: https://github.com/Rust-GCC/gccrs/commit/d273e1b6a25261b49983fc58471da3245b96928f The commit has NOT been mentioned in any issue. The commit has been mentioned in the following pull-request(s): - https://github.com/Rust-GCC/gccrs/pull/4643 .../lints/unused/rust-unused-checker.cc | 31 +++++++++++++++++++ .../checks/lints/unused/rust-unused-checker.h | 1 + .../rust/compile/double-negations_0.rs | 17 ++++++++++ 3 files changed, 49 insertions(+) create mode 100644 gcc/testsuite/rust/compile/double-negations_0.rs diff --git a/gcc/rust/checks/lints/unused/rust-unused-checker.cc b/gcc/rust/checks/lints/unused/rust-unused-checker.cc index 553a2f71e..1c128f519 100644 --- a/gcc/rust/checks/lints/unused/rust-unused-checker.cc +++ b/gcc/rust/checks/lints/unused/rust-unused-checker.cc @@ -378,5 +378,36 @@ UnusedChecker::visit (HIR::BorrowExpr &expr) walk (expr); } +namespace { +// Probe whether an expression is itself an arithmetic negation, without +// recursing (so it only inspects the node it is dispatched on). Used to detect +// `- -x` for the double_negations lint, since gccrs builds with -fno-rtti and +// HIR has no down-cast helper. +class NegationProbe : public HIR::HIRFullVisitorBase +{ +public: + bool is_negation = false; + using HIR::HIRFullVisitorBase::visit; + void visit (HIR::NegationExpr &expr) override + { + is_negation = expr.get_expr_type () == HIR::NegationExpr::ExprType::NEGATE; + } +}; +} // namespace + +void +UnusedChecker::visit (HIR::NegationExpr &expr) +{ + if (expr.get_expr_type () == HIR::NegationExpr::ExprType::NEGATE) + { + NegationProbe probe; + expr.get_expr ().accept_vis (probe); + if (probe.is_negation) + rust_warning_at (expr.get_locus (), OPT_Wunused, + "use of a double negation"); + } + walk (expr); +} + } // namespace Analysis } // namespace Rust diff --git a/gcc/rust/checks/lints/unused/rust-unused-checker.h b/gcc/rust/checks/lints/unused/rust-unused-checker.h index 161f59b8a..659087a57 100644 --- a/gcc/rust/checks/lints/unused/rust-unused-checker.h +++ b/gcc/rust/checks/lints/unused/rust-unused-checker.h @@ -53,6 +53,7 @@ private: virtual void visit (HIR::ExternBlock &block) override; virtual void visit (HIR::LetStmt &stmt) override; virtual void visit (HIR::BorrowExpr &expr) override; + virtual void visit (HIR::NegationExpr &expr) override; virtual void visit_loop_label (HIR::LoopLabel &label) override; }; } // namespace Analysis diff --git a/gcc/testsuite/rust/compile/double-negations_0.rs b/gcc/testsuite/rust/compile/double-negations_0.rs new file mode 100644 index 000000000..47854e963 --- /dev/null +++ b/gcc/testsuite/rust/compile/double-negations_0.rs @@ -0,0 +1,17 @@ +// { dg-additional-options "-frust-unused-check-2.0" } +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "neg"] +pub trait Neg { + type Output; + fn neg(self) -> Self::Output; +} + +pub fn f(x: i32) -> i32 { + - -x +// { dg-warning "double negation" "" { target *-*-* } .-1 } +} base-commit: 840bac99462208bc849a44fd36bb36cf04f711a5 -- 2.54.0