diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 51d9a4641cd52..8ed5e1abd5056 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -623,6 +623,7 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements { enum UnusedDelimsCtx { FunctionArg, MethodArg, + MethodReceiver, AssignedValue, AssignedValueLetElse, IfCond, @@ -645,6 +646,7 @@ impl From for &'static str { match ctx { UnusedDelimsCtx::FunctionArg => "function argument", UnusedDelimsCtx::MethodArg => "method argument", + UnusedDelimsCtx::MethodReceiver => "method receiver", UnusedDelimsCtx::AssignedValue | UnusedDelimsCtx::AssignedValueLetElse => { "assigned value" } @@ -710,6 +712,16 @@ trait UnusedDelimLint { } } + // For method receivers, only lint simple path expressions like `(x).method()`. + // Keep parens for all other cases to avoid false positives with complex expressions + // like `(1..10).sum()`, `(*ptr).method()`, `({ block }).method()`, etc. + // Only lint simple variable names like `(x).method()` + if ctx == UnusedDelimsCtx::MethodReceiver { + if !matches!(inner.kind, ast::ExprKind::Path(None, _)) { + return true; + } + } + // Check it's range in LetScrutineeExpr if let ast::ExprKind::Range(..) = inner.kind && matches!(ctx, UnusedDelimsCtx::LetScrutineeExpr) @@ -976,13 +988,15 @@ trait UnusedDelimLint { } // either function/method call, or something this lint doesn't care about ref call_or_other => { - let (args_to_check, ctx) = match *call_or_other { - Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg), - MethodCall(ref call) => (&call.args[..], UnusedDelimsCtx::MethodArg), + let (args_to_check, ctx, receiver) = match *call_or_other { + Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg, None), + MethodCall(ref call) => { + (&call.args[..], UnusedDelimsCtx::MethodArg, Some(&call.receiver)) + } Closure(ref closure) if matches!(closure.fn_decl.output, FnRetTy::Default(_)) => { - (&[closure.body.clone()][..], UnusedDelimsCtx::ClosureBody) + (&[closure.body.clone()][..], UnusedDelimsCtx::ClosureBody, None) } // actual catch-all arm _ => { @@ -999,6 +1013,17 @@ trait UnusedDelimLint { for arg in args_to_check { self.check_unused_delims_expr(cx, arg, ctx, false, None, None, false); } + if let Some(recv) = receiver { + self.check_unused_delims_expr( + cx, + recv, + UnusedDelimsCtx::MethodReceiver, + false, + None, + None, + false, + ); + } return; } }; @@ -1584,6 +1609,7 @@ impl UnusedDelimLint for UnusedBraces { if let [stmt] = inner.stmts.as_slice() && let ast::StmtKind::Expr(ref expr) = stmt.kind && !Self::is_expr_delims_necessary(expr, ctx, followed_by_block) + && ctx != UnusedDelimsCtx::MethodReceiver && (ctx != UnusedDelimsCtx::AnonConst || (matches!(expr.kind, ast::ExprKind::Lit(_)) && !expr.span.from_expansion())) diff --git a/library/compiler-builtins/libm/src/math/cbrt.rs b/library/compiler-builtins/libm/src/math/cbrt.rs index e905e15f13fbe..1bd3d8ea819a0 100644 --- a/library/compiler-builtins/libm/src/math/cbrt.rs +++ b/library/compiler-builtins/libm/src/math/cbrt.rs @@ -194,7 +194,7 @@ pub fn cbrt_round(x: f64, round: Round) -> FpResult { let mut cvt4: u64 = y1.to_bits(); cvt4 = (cvt4 + (164 << 15)) & 0xffffffffffff0000u64; - if ((f64::from_bits(cvt4) - y1) - dy).abs() < hf64!("0x1p-60") || (zz).abs() == 1.0 { + if ((f64::from_bits(cvt4) - y1) - dy).abs() < hf64!("0x1p-60") || zz.abs() == 1.0 { cvt3 = (cvt3 + (1u64 << 15)) & 0xffffffffffff0000u64; } } diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 2566d1471ab7f..cdc302fba4eca 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -27,7 +27,7 @@ impl *const T { @capture { ptr: *const u8 } -> bool: // This use of `const_raw_ptr_comparison` has been explicitly blessed by t-lang. if const #[rustc_allow_const_fn_unstable(const_raw_ptr_comparison)] { - match (ptr).guaranteed_eq(null_mut()) { + match ptr.guaranteed_eq(null_mut()) { Some(res) => res, // To remain maximally conservative, we stop execution when we don't // know whether the pointer is null or not. diff --git a/library/coretests/tests/floats/mod.rs b/library/coretests/tests/floats/mod.rs index 06fc3c96eafc8..b09535b02129d 100644 --- a/library/coretests/tests/floats/mod.rs +++ b/library/coretests/tests/floats/mod.rs @@ -770,13 +770,13 @@ float_test! { assert_biteq!((-Float::MAX).midpoint(Float::MIN_POSITIVE), -Float::MAX / 2.); assert_biteq!(Float::MAX.midpoint(-Float::MIN_POSITIVE), Float::MAX / 2.); assert_biteq!((-Float::MAX).midpoint(-Float::MIN_POSITIVE), -Float::MAX / 2.); - assert_biteq!((Float::MIN_POSITIVE).midpoint(Float::MAX), Float::MAX / 2.); - assert_biteq!((Float::MIN_POSITIVE).midpoint(-Float::MAX), -Float::MAX / 2.); + assert_biteq!(Float::MIN_POSITIVE.midpoint(Float::MAX), Float::MAX / 2.); + assert_biteq!(Float::MIN_POSITIVE.midpoint(-Float::MAX), -Float::MAX / 2.); assert_biteq!((-Float::MIN_POSITIVE).midpoint(Float::MAX), Float::MAX / 2.); assert_biteq!((-Float::MIN_POSITIVE).midpoint(-Float::MAX), -Float::MAX / 2.); assert_biteq!(Float::MAX.midpoint(Float::MAX), Float::MAX); assert_biteq!( - (Float::MIN_POSITIVE).midpoint(Float::MIN_POSITIVE), + Float::MIN_POSITIVE.midpoint(Float::MIN_POSITIVE), Float::MIN_POSITIVE ); assert_biteq!( @@ -1175,7 +1175,7 @@ float_test! { assert_biteq!((-Float::MAX_SUBNORMAL).next_down(), -Float::MIN_POSITIVE_NORMAL); assert_biteq!((-Float::TINY).next_down(), -Float::TINY_UP); assert_biteq!((-Float::ZERO).next_down(), -Float::TINY); - assert_biteq!((Float::ZERO).next_down(), -Float::TINY); + assert_biteq!(Float::ZERO.next_down(), -Float::TINY); assert_biteq!(Float::TINY.next_down(), Float::ZERO); assert_biteq!(Float::TINY_UP.next_down(), Float::TINY); assert_biteq!(Float::MIN_POSITIVE_NORMAL.next_down(), Float::MAX_SUBNORMAL); diff --git a/library/coretests/tests/time.rs b/library/coretests/tests/time.rs index ff80ff680943f..37d85ef10c714 100644 --- a/library/coretests/tests/time.rs +++ b/library/coretests/tests/time.rs @@ -264,8 +264,8 @@ fn div_duration_f32() { // These tests demonstrate it doesn't panic with extreme values. // Accuracy of the computed value is not a huge concern, we know floats don't work well // at these extremes. - assert!((Duration::MAX).div_duration_f32(Duration::NANOSECOND) > 10.0f32.powf(28.0)); - assert!((Duration::NANOSECOND).div_duration_f32(Duration::MAX) < 0.1); + assert!(Duration::MAX.div_duration_f32(Duration::NANOSECOND) > 10.0f32.powf(28.0)); + assert!(Duration::NANOSECOND.div_duration_f32(Duration::MAX) < 0.1); } #[test] @@ -277,8 +277,8 @@ fn div_duration_f64() { // These tests demonstrate it doesn't panic with extreme values. // Accuracy of the computed value is not a huge concern, we know floats don't work well // at these extremes. - assert!((Duration::MAX).div_duration_f64(Duration::NANOSECOND) > 10.0f64.powf(28.0)); - assert!((Duration::NANOSECOND).div_duration_f64(Duration::MAX) < 0.1); + assert!(Duration::MAX.div_duration_f64(Duration::NANOSECOND) > 10.0f64.powf(28.0)); + assert!(Duration::NANOSECOND.div_duration_f64(Duration::MAX) < 0.1); } #[test] diff --git a/src/tools/miri/tests/pass/u128.rs b/src/tools/miri/tests/pass/u128.rs index 6def529dbe7c3..60b1cf556bcce 100644 --- a/src/tools/miri/tests/pass/u128.rs +++ b/src/tools/miri/tests/pass/u128.rs @@ -57,8 +57,8 @@ fn main() { // common traits assert_eq!(x, b(x.clone())); // overflow checks - assert_eq!((z).checked_mul(z), Some(0x734C_C2F2_A521)); - assert_eq!((k).checked_mul(k), None); + assert_eq!(z.checked_mul(z), Some(0x734C_C2F2_A521)); + assert_eq!(k.checked_mul(k), None); let l: u128 = b(u128::MAX - 10); let o: u128 = b(17); assert_eq!(l.checked_add(b(11)), None); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs index 5bc2446fdd2dd..c04999f698e75 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval.rs @@ -96,7 +96,7 @@ pub fn intern_const_ref<'a>( BuiltinUint::U16 => Box::new((i as u16).to_le_bytes()), BuiltinUint::U32 => Box::new((i as u32).to_le_bytes()), BuiltinUint::U64 => Box::new((i as u64).to_le_bytes()), - BuiltinUint::U128 => Box::new((i).to_le_bytes()), + BuiltinUint::U128 => Box::new(i.to_le_bytes()), BuiltinUint::Usize => Box::new((i as usize).to_le_bytes()), }, _ => return Const::new(interner, rustc_type_ir::ConstKind::Error(ErrorGuaranteed)), @@ -136,7 +136,7 @@ pub fn intern_const_ref<'a>( BuiltinInt::I16 => Box::new((i as i16).to_le_bytes()), BuiltinInt::I32 => Box::new((i as i32).to_le_bytes()), BuiltinInt::I64 => Box::new((i as i64).to_le_bytes()), - BuiltinInt::I128 => Box::new((i).to_le_bytes()), + BuiltinInt::I128 => Box::new(i.to_le_bytes()), BuiltinInt::Isize => Box::new((i as isize).to_le_bytes()), }, _ => return Const::new(interner, rustc_type_ir::ConstKind::Error(ErrorGuaranteed)), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs index a8aacbff16fa8..65d4c9678120d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/lower/pattern_matching.rs @@ -336,7 +336,7 @@ impl<'db> MirLowerCtx<'_, 'db> { id, mode, next_place, - (slice).into(), + slice.into(), current, current_else, )?; diff --git a/src/tools/test-float-parse/src/validate.rs b/src/tools/test-float-parse/src/validate.rs index 40dda274e3b86..1ddda63bb0fa6 100644 --- a/src/tools/test-float-parse/src/validate.rs +++ b/src/tools/test-float-parse/src/validate.rs @@ -71,7 +71,7 @@ impl Constants { let neg_inf_cutoff = -&inf_cutoff; let powers_of_two: BTreeMap = - (POWERS_OF_TWO_RANGE).map(|n| (n, two.pow(n))).collect(); + POWERS_OF_TWO_RANGE.map(|n| (n, two.pow(n))).collect(); let mut half_ulp = powers_of_two.clone(); half_ulp.iter_mut().for_each(|(_k, v)| *v = &*v / two_int); diff --git a/tests/ui/lint/unused-parens-method-receiver-issue-151985.fixed b/tests/ui/lint/unused-parens-method-receiver-issue-151985.fixed new file mode 100644 index 0000000000000..7a5c438f9cc8d --- /dev/null +++ b/tests/ui/lint/unused-parens-method-receiver-issue-151985.fixed @@ -0,0 +1,26 @@ +//@ run-rustfix + +#![deny(unused_parens)] + +struct Thing; +impl Thing { + fn method(self) {} +} + +fn main() { + // Unnecessary parens - should warn + let x = Thing; + x.method(); //~ ERROR unnecessary parentheses around method receiver + + // Necessary parens - should NOT warn + let _ = (1..10).sum::(); // Range expression + let _ = (1_i32 + 2).abs(); // Binary expression + let _ = (-1_i32).abs(); // Unary expression + let _ = (true as i32).abs(); // Cast expression + let _ = (&42).clone(); // AddrOf expression + let _ = (&mut 42).clone(); // AddrOf mut expression + + // Block expressions - should NOT warn + let _ = ({ 1_i32 }).abs(); // Block expression + let _ = (unsafe { std::mem::zeroed::() }).abs(); // Unsafe block expression +} diff --git a/tests/ui/lint/unused-parens-method-receiver-issue-151985.rs b/tests/ui/lint/unused-parens-method-receiver-issue-151985.rs new file mode 100644 index 0000000000000..cc8a431bee190 --- /dev/null +++ b/tests/ui/lint/unused-parens-method-receiver-issue-151985.rs @@ -0,0 +1,29 @@ +//@ run-rustfix + +#![deny(unused_parens)] + +struct Thing; +impl Thing { + fn method(self) {} +} + +fn main() { + // Unnecessary parens - should warn + let x = Thing; + (x).method(); //~ ERROR unnecessary parentheses around method receiver + + // Necessary parens - should NOT warn + let _ = (1..10).sum::(); // Range expression + let _ = (1_i32 + 2).abs(); // Binary expression + let _ = (-1_i32).abs(); // Unary expression + let _ = (true as i32).abs(); // Cast expression + let _ = (&42).clone(); // AddrOf expression + let _ = (&mut 42).clone(); // AddrOf mut expression + + // Block expressions - should NOT warn + let _ = ({ 1_i32 }).abs(); // Block expression + let _ = (unsafe { std::mem::zeroed::() }).abs(); // Unsafe block expression + + // lint for path with multiple segments + let _ = (Float::MIN_POSITIVE).midpoint(-Float::MAX); +} diff --git a/tests/ui/lint/unused-parens-method-receiver-issue-151985.stderr b/tests/ui/lint/unused-parens-method-receiver-issue-151985.stderr new file mode 100644 index 0000000000000..c986a4bc94d6c --- /dev/null +++ b/tests/ui/lint/unused-parens-method-receiver-issue-151985.stderr @@ -0,0 +1,19 @@ +error: unnecessary parentheses around method receiver + --> $DIR/unused-parens-method-receiver-issue-151985.rs:13:5 + | +LL | (x).method(); + | ^ ^ + | +note: the lint level is defined here + --> $DIR/unused-parens-method-receiver-issue-151985.rs:3:9 + | +LL | #![deny(unused_parens)] + | ^^^^^^^^^^^^^ +help: remove these parentheses + | +LL - (x).method(); +LL + x.method(); + | + +error: aborting due to 1 previous error +