https://gcc.gnu.org/g:f9eb87556d10353a8ca678c4c570772a6f2df043
commit r17-3093-gf9eb87556d10353a8ca678c4c570772a6f2df043 Author: Lucas Ly Ba <[email protected]> Date: Sat Jun 27 23:12:31 2026 +0200 gccrs: add dyn drop lint Warn on a trait object that carries a `Drop` bound, as values are dropped automatically and the bound has no effect. gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): Warn on a trait object with a `Drop` bound. * rust-lang.cc (grs_langhook_init_options_struct): Enable warn_unused. gcc/testsuite/ChangeLog: * rust/compile/dyn-drop_0.rs: New test. Signed-off-by: Lucas Ly Ba <[email protected]> Diff: --- gcc/rust/rust-lang.cc | 2 ++ gcc/rust/typecheck/rust-hir-type-check-type.cc | 10 ++++++++++ gcc/testsuite/rust/compile/dyn-drop_0.rs | 14 ++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc index dde3ef204ce0..dc39bc053d0e 100644 --- a/gcc/rust/rust-lang.cc +++ b/gcc/rust/rust-lang.cc @@ -136,6 +136,8 @@ grs_langhook_init_options_struct (struct gcc_options *opts) /* We need to warn on unused variables by default */ opts->x_warn_unused_variable = 1; + /* Experimental lints under -frust-unused-check-2.0 warn by default */ + opts->x_warn_unused = 1; /* For const variables too */ opts->x_warn_unused_const_variable = 1; /* And finally unused result for #[must_use] */ diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 634d04988616..c6fbb2ae1bd7 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -655,6 +655,16 @@ TypeCheckType::visit (HIR::TraitObjectType &type) specified_bounds.push_back (std::move (predicate)); } + // The dyn_drop lint: a trait object with a `Drop` bound is pointless, as + // values are dropped automatically regardless of the bound. + if (flag_unused_check_2_0) + if (auto drop = mappings.lookup_lang_item (LangItem::Kind::DROP)) + for (auto &bound : specified_bounds) + if (bound.get_id () == drop.value ()) + rust_warning_at (type.get_locus (), OPT_Wunused, + "this trait object has a %<Drop%> bound, which has " + "no effect"); + RustIdent ident{CanonicalPath::create_empty (), type.get_locus ()}; translated = new TyTy::DynamicObjectType (type.get_mappings ().get_hirid (), ident, diff --git a/gcc/testsuite/rust/compile/dyn-drop_0.rs b/gcc/testsuite/rust/compile/dyn-drop_0.rs new file mode 100644 index 000000000000..07bc30d7b2a2 --- /dev/null +++ b/gcc/testsuite/rust/compile/dyn-drop_0.rs @@ -0,0 +1,14 @@ +// { dg-additional-options "-frust-unused-check-2.0" } +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +pub trait Sized {} + +#[lang = "drop"] +pub trait Drop { + fn drop(&mut self); +} + +pub fn f(_x: &dyn Drop) {} +// { dg-warning "trait object has a .Drop. bound" "" { target *-*-* } .-1 }
