diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index f578708b40cd3..939637d0e296f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -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", - }; + return; + } - self.tcx.emit_node_span_lint( - UNUSED_ATTRIBUTES, - hir_id, - attr.span, - errors::MustUseNoEffect { article, target }, - ); + // `#[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. diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs index b763a7c75a5a6..19d45f4d3b31a 100644 --- a/library/portable-simd/crates/core_simd/src/masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks.rs @@ -401,7 +401,6 @@ where LaneCount: 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: 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: SupportedLaneCount, { #[inline] - #[must_use = "method returns a new Ordering and does not mutate the original value"] fn partial_cmp(&self, other: &Self) -> Option { 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; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitand(self, rhs: Mask) -> Mask { 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; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitor(self, rhs: Mask) -> Mask { 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; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn bitxor(self, rhs: Mask) -> Self::Output { Mask::splat(self) ^ rhs } @@ -568,7 +556,6 @@ where { type Output = Mask; #[inline] - #[must_use = "method returns a new mask and does not mutate the original value"] fn not(self) -> Self::Output { Self(!self.0) } diff --git a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs index 2d01946b5747c..387b508c4b4ef 100644 --- a/library/portable-simd/crates/core_simd/src/masks/full_masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks/full_masks.rs @@ -21,7 +21,6 @@ where LaneCount: 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 } diff --git a/library/portable-simd/crates/core_simd/src/ops.rs b/library/portable-simd/crates/core_simd/src/ops.rs index d3bd14a340278..4ac64a253a3bd 100644 --- a/library/portable-simd/crates/core_simd/src/ops.rs +++ b/library/portable-simd/crates/core_simd/src/ops.rs @@ -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] diff --git a/library/portable-simd/crates/core_simd/src/ops/deref.rs b/library/portable-simd/crates/core_simd/src/ops/deref.rs index 0ff76cfba39bb..913cbbe977c46 100644 --- a/library/portable-simd/crates/core_simd/src/ops/deref.rs +++ b/library/portable-simd/crates/core_simd/src/ops/deref.rs @@ -18,7 +18,6 @@ macro_rules! deref_lhs { type Output = Simd; #[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; #[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) } diff --git a/library/portable-simd/crates/core_simd/src/ops/unary.rs b/library/portable-simd/crates/core_simd/src/ops/unary.rs index bdae96332a3ae..412a5b801171b 100644 --- a/library/portable-simd/crates/core_simd/src/ops/unary.rs +++ b/library/portable-simd/crates/core_simd/src/ops/unary.rs @@ -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))) } diff --git a/library/portable-simd/crates/core_simd/src/simd/num/float.rs b/library/portable-simd/crates/core_simd/src/simd/num/float.rs index 79954b937b397..db705dfe20221 100644 --- a/library/portable-simd/crates/core_simd/src/simd/num/float.rs +++ b/library/portable-simd/crates/core_simd/src/simd/num/float.rs @@ -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()) } diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs index d3aade31f14fc..7210f4b438db2 100644 --- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs +++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs @@ -94,7 +94,6 @@ impl Finiteness { } impl From for Finiteness { - #[must_use] fn from(b: bool) -> Self { if b { Infinite } else { Finite } } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index db82c458f703c..21909896c33eb 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -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 { Some(self.cmp(other)) } } impl Ord for FullInt { - #[must_use] fn cmp(&self, other: &Self) -> Ordering { use FullInt::{S, U}; diff --git a/tests/ui/lint/unused/unused_attributes-must_use.rs b/tests/ui/lint/unused/unused_attributes-must_use.rs index 51f868706b69b..860fc5046d103 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.rs +++ b/tests/ui/lint/unused/unused_attributes-must_use.rs @@ -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 diff --git a/tests/ui/lint/unused/unused_attributes-must_use.stderr b/tests/ui/lint/unused/unused_attributes-must_use.stderr index 9633767c44287..28fd8eeb8cbdc 100644 --- a/tests/ui/lint/unused/unused_attributes-must_use.stderr +++ b/tests/ui/lint/unused/unused_attributes-must_use.stderr @@ -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