Rollup merge of #136923 - samueltardieu:push-vxxqvqwspssv, r=davidtwco

Lint `#[must_use]` attributes applied to methods in trait impls

The `#[must_use]` attribute has no effect when applied to methods in trait implementations. This PR adds it to the unused `#[must_use]` lint, and cleans the extra attributes in portable-simd and Clippy.
This commit is contained in:
Matthias Krüger 2025-02-19 21:16:11 +01:00 committed by GitHub
commit c29cc600fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 56 additions and 63 deletions

View File

@ -1431,37 +1431,48 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
/// Warns against some misuses of `#[must_use]`
fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) {
if !matches!(
if matches!(
target,
Target::Fn
| Target::Enum
| Target::Struct
| Target::Union
| Target::Method(_)
| Target::Method(MethodKind::Trait { body: false } | MethodKind::Inherent)
| Target::ForeignFn
// `impl Trait` in return position can trip
// `unused_must_use` if `Trait` is marked as
// `#[must_use]`
| Target::Trait
) {
let article = match target {
Target::ExternCrate
| Target::Enum
| Target::Impl
| Target::Expression
| Target::Arm
| Target::AssocConst
| Target::AssocTy => "an",
_ => "a",
};
self.tcx.emit_node_span_lint(
UNUSED_ATTRIBUTES,
hir_id,
attr.span,
errors::MustUseNoEffect { article, target },
);
return;
}
// `#[must_use]` can be applied to a trait method definition with a default body
if let Target::Method(MethodKind::Trait { body: true }) = target
&& let parent_def_id = self.tcx.hir().get_parent_item(hir_id).def_id
&& let containing_item = self.tcx.hir().expect_item(parent_def_id)
&& let hir::ItemKind::Trait(..) = containing_item.kind
{
return;
}
let article = match target {
Target::ExternCrate
| Target::Enum
| Target::Impl
| Target::Expression
| Target::Arm
| Target::AssocConst
| Target::AssocTy => "an",
_ => "a",
};
self.tcx.emit_node_span_lint(
UNUSED_ATTRIBUTES,
hir_id,
attr.span,
errors::MustUseNoEffect { article, target },
);
}
/// Checks if `#[must_not_suspend]` is applied to a struct, enum, union, or trait.

View File

@ -401,7 +401,6 @@ where
LaneCount<N>: SupportedLaneCount,
{
#[inline]
#[must_use = "method returns a defaulted mask with all elements set to false (0)"]
fn default() -> Self {
Self::splat(false)
}
@ -413,7 +412,6 @@ where
LaneCount<N>: SupportedLaneCount,
{
#[inline]
#[must_use = "method returns a new bool and does not mutate the original value"]
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
@ -425,7 +423,6 @@ where
LaneCount<N>: SupportedLaneCount,
{
#[inline]
#[must_use = "method returns a new Ordering and does not mutate the original value"]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.0.partial_cmp(&other.0)
}
@ -451,7 +448,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitand(self, rhs: Self) -> Self {
Self(self.0 & rhs.0)
}
@ -464,7 +460,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitand(self, rhs: bool) -> Self {
self & Self::splat(rhs)
}
@ -477,7 +472,6 @@ where
{
type Output = Mask<T, N>;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitand(self, rhs: Mask<T, N>) -> Mask<T, N> {
Mask::splat(self) & rhs
}
@ -490,7 +484,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitor(self, rhs: Self) -> Self {
Self(self.0 | rhs.0)
}
@ -503,7 +496,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitor(self, rhs: bool) -> Self {
self | Self::splat(rhs)
}
@ -516,7 +508,6 @@ where
{
type Output = Mask<T, N>;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitor(self, rhs: Mask<T, N>) -> Mask<T, N> {
Mask::splat(self) | rhs
}
@ -529,7 +520,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitxor(self, rhs: Self) -> Self::Output {
Self(self.0 ^ rhs.0)
}
@ -542,7 +532,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitxor(self, rhs: bool) -> Self::Output {
self ^ Self::splat(rhs)
}
@ -555,7 +544,6 @@ where
{
type Output = Mask<T, N>;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitxor(self, rhs: Mask<T, N>) -> Self::Output {
Mask::splat(self) ^ rhs
}
@ -568,7 +556,6 @@ where
{
type Output = Mask<T, N>;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn not(self) -> Self::Output {
Self(!self.0)
}

View File

@ -21,7 +21,6 @@ where
LaneCount<N>: SupportedLaneCount,
{
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn clone(&self) -> Self {
*self
}
@ -252,7 +251,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitand(self, rhs: Self) -> Self {
// Safety: `self` is an integer vector
unsafe { Self(core::intrinsics::simd::simd_and(self.0, rhs.0)) }
@ -266,7 +264,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitor(self, rhs: Self) -> Self {
// Safety: `self` is an integer vector
unsafe { Self(core::intrinsics::simd::simd_or(self.0, rhs.0)) }
@ -280,7 +277,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn bitxor(self, rhs: Self) -> Self {
// Safety: `self` is an integer vector
unsafe { Self(core::intrinsics::simd::simd_xor(self.0, rhs.0)) }
@ -294,7 +290,6 @@ where
{
type Output = Self;
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn not(self) -> Self::Output {
Self::splat(true) ^ self
}

View File

@ -135,7 +135,6 @@ macro_rules! for_base_types {
type Output = $out;
#[inline]
#[must_use = "operator returns a new vector without mutating the inputs"]
// TODO: only useful for int Div::div, but we hope that this
// will essentially always get inlined anyway.
#[track_caller]

View File

@ -18,7 +18,6 @@ macro_rules! deref_lhs {
type Output = Simd<T, N>;
#[inline]
#[must_use = "operator returns a new vector without mutating the inputs"]
fn $call(self, rhs: $simd) -> Self::Output {
(*self).$call(rhs)
}
@ -39,7 +38,6 @@ macro_rules! deref_rhs {
type Output = Simd<T, N>;
#[inline]
#[must_use = "operator returns a new vector without mutating the inputs"]
fn $call(self, rhs: &$simd) -> Self::Output {
self.$call(*rhs)
}
@ -71,7 +69,6 @@ macro_rules! deref_ops {
type Output = $simd;
#[inline]
#[must_use = "operator returns a new vector without mutating the inputs"]
fn $call(self, rhs: &'rhs $simd) -> Self::Output {
(*self).$call(*rhs)
}

View File

@ -11,7 +11,6 @@ macro_rules! neg {
type Output = Self;
#[inline]
#[must_use = "operator returns a new vector without mutating the input"]
fn neg(self) -> Self::Output {
// Safety: `self` is a signed vector
unsafe { core::intrinsics::simd::simd_neg(self) }
@ -46,7 +45,6 @@ macro_rules! not {
type Output = Self;
#[inline]
#[must_use = "operator returns a new vector without mutating the input"]
fn not(self) -> Self::Output {
self ^ (Simd::splat(!(0 as $scalar)))
}

View File

@ -371,7 +371,6 @@ macro_rules! impl_trait {
}
#[inline]
#[must_use = "method returns a new mask and does not mutate the original value"]
fn is_normal(self) -> Self::Mask {
!(self.abs().simd_eq(Self::splat(0.0)) | self.is_nan() | self.is_subnormal() | self.is_infinite())
}

View File

@ -94,7 +94,6 @@ impl Finiteness {
}
impl From<bool> for Finiteness {
#[must_use]
fn from(b: bool) -> Self {
if b { Infinite } else { Finite }
}

View File

@ -351,21 +351,18 @@ pub enum FullInt {
}
impl PartialEq for FullInt {
#[must_use]
fn eq(&self, other: &Self) -> bool {
self.cmp(other) == Ordering::Equal
}
}
impl PartialOrd for FullInt {
#[must_use]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for FullInt {
#[must_use]
fn cmp(&self, other: &Self) -> Ordering {
use FullInt::{S, U};

View File

@ -79,6 +79,11 @@ trait Use {
#[must_use] //~ ERROR `#[must_use]` has no effect
impl Use for () {
type AssocTy = ();
#[must_use] //~ ERROR `#[must_use]` has no effect
fn get_four(&self) -> usize {
4
}
}
#[must_use] //~ ERROR `#[must_use]` has no effect

View File

@ -76,43 +76,43 @@ LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a trait alias
--> $DIR/unused_attributes-must_use.rs:84:1
--> $DIR/unused_attributes-must_use.rs:89:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a macro def
--> $DIR/unused_attributes-must_use.rs:87:1
--> $DIR/unused_attributes-must_use.rs:92:1
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a statement
--> $DIR/unused_attributes-must_use.rs:95:5
--> $DIR/unused_attributes-must_use.rs:100:5
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a closure
--> $DIR/unused_attributes-must_use.rs:99:13
--> $DIR/unused_attributes-must_use.rs:104:13
|
LL | let x = #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an match arm
--> $DIR/unused_attributes-must_use.rs:121:9
--> $DIR/unused_attributes-must_use.rs:126:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a struct field
--> $DIR/unused_attributes-must_use.rs:129:28
--> $DIR/unused_attributes-must_use.rs:134:28
|
LL | let s = PatternField { #[must_use] foo: 123 };
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a pattern field
--> $DIR/unused_attributes-must_use.rs:130:24
--> $DIR/unused_attributes-must_use.rs:135:24
|
LL | let PatternField { #[must_use] foo } = s;
| ^^^^^^^^^^^
@ -129,6 +129,12 @@ error: `#[must_use]` has no effect when applied to an associated type
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a provided trait method
--> $DIR/unused_attributes-must_use.rs:83:5
|
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to a foreign static item
--> $DIR/unused_attributes-must_use.rs:50:5
|
@ -136,7 +142,7 @@ LL | #[must_use]
| ^^^^^^^^^^^
error: unused `X` that must be used
--> $DIR/unused_attributes-must_use.rs:103:5
--> $DIR/unused_attributes-must_use.rs:108:5
|
LL | X;
| ^
@ -152,7 +158,7 @@ LL | let _ = X;
| +++++++
error: unused `Y` that must be used
--> $DIR/unused_attributes-must_use.rs:104:5
--> $DIR/unused_attributes-must_use.rs:109:5
|
LL | Y::Z;
| ^^^^
@ -163,7 +169,7 @@ LL | let _ = Y::Z;
| +++++++
error: unused `U` that must be used
--> $DIR/unused_attributes-must_use.rs:105:5
--> $DIR/unused_attributes-must_use.rs:110:5
|
LL | U { unit: () };
| ^^^^^^^^^^^^^^
@ -174,7 +180,7 @@ LL | let _ = U { unit: () };
| +++++++
error: unused return value of `U::method` that must be used
--> $DIR/unused_attributes-must_use.rs:106:5
--> $DIR/unused_attributes-must_use.rs:111:5
|
LL | U::method();
| ^^^^^^^^^^^
@ -185,7 +191,7 @@ LL | let _ = U::method();
| +++++++
error: unused return value of `foo` that must be used
--> $DIR/unused_attributes-must_use.rs:107:5
--> $DIR/unused_attributes-must_use.rs:112:5
|
LL | foo();
| ^^^^^
@ -196,7 +202,7 @@ LL | let _ = foo();
| +++++++
error: unused return value of `foreign_foo` that must be used
--> $DIR/unused_attributes-must_use.rs:110:9
--> $DIR/unused_attributes-must_use.rs:115:9
|
LL | foreign_foo();
| ^^^^^^^^^^^^^
@ -207,7 +213,7 @@ LL | let _ = foreign_foo();
| +++++++
error: unused return value of `Use::get_four` that must be used
--> $DIR/unused_attributes-must_use.rs:118:5
--> $DIR/unused_attributes-must_use.rs:123:5
|
LL | ().get_four();
| ^^^^^^^^^^^^^
@ -217,5 +223,5 @@ help: use `let _ = ...` to ignore the resulting value
LL | let _ = ().get_four();
| +++++++
error: aborting due to 28 previous errors
error: aborting due to 29 previous errors