Skip to content

Commit 5733cfa

Browse files
committed
Lint unused parentheses around method receiver
1 parent a60d12c commit 5733cfa

6 files changed

Lines changed: 101 additions & 6 deletions

File tree

compiler/rustc_lint/src/unused.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,7 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements {
623623
enum UnusedDelimsCtx {
624624
FunctionArg,
625625
MethodArg,
626+
MethodReceiver,
626627
AssignedValue,
627628
AssignedValueLetElse,
628629
IfCond,
@@ -645,6 +646,7 @@ impl From<UnusedDelimsCtx> for &'static str {
645646
match ctx {
646647
UnusedDelimsCtx::FunctionArg => "function argument",
647648
UnusedDelimsCtx::MethodArg => "method argument",
649+
UnusedDelimsCtx::MethodReceiver => "method receiver",
648650
UnusedDelimsCtx::AssignedValue | UnusedDelimsCtx::AssignedValueLetElse => {
649651
"assigned value"
650652
}
@@ -710,6 +712,15 @@ trait UnusedDelimLint {
710712
}
711713
}
712714

715+
// For method receivers, only lint simple path expressions like `(x).method()`.
716+
// Keep parens for all other cases to avoid false positives with complex expressions
717+
// like `(1..10).sum()`, `(*ptr).method()`, `({ block }).method()`, etc.
718+
if ctx == UnusedDelimsCtx::MethodReceiver {
719+
if !matches!(inner.kind, ast::ExprKind::Path(..)) {
720+
return true;
721+
}
722+
}
723+
713724
// Check it's range in LetScrutineeExpr
714725
if let ast::ExprKind::Range(..) = inner.kind
715726
&& matches!(ctx, UnusedDelimsCtx::LetScrutineeExpr)
@@ -976,13 +987,15 @@ trait UnusedDelimLint {
976987
}
977988
// either function/method call, or something this lint doesn't care about
978989
ref call_or_other => {
979-
let (args_to_check, ctx) = match *call_or_other {
980-
Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg),
981-
MethodCall(ref call) => (&call.args[..], UnusedDelimsCtx::MethodArg),
990+
let (args_to_check, ctx, receiver) = match *call_or_other {
991+
Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg, None),
992+
MethodCall(ref call) => {
993+
(&call.args[..], UnusedDelimsCtx::MethodArg, Some(&call.receiver))
994+
}
982995
Closure(ref closure)
983996
if matches!(closure.fn_decl.output, FnRetTy::Default(_)) =>
984997
{
985-
(&[closure.body.clone()][..], UnusedDelimsCtx::ClosureBody)
998+
(&[closure.body.clone()][..], UnusedDelimsCtx::ClosureBody, None)
986999
}
9871000
// actual catch-all arm
9881001
_ => {
@@ -999,6 +1012,17 @@ trait UnusedDelimLint {
9991012
for arg in args_to_check {
10001013
self.check_unused_delims_expr(cx, arg, ctx, false, None, None, false);
10011014
}
1015+
if let Some(recv) = receiver {
1016+
self.check_unused_delims_expr(
1017+
cx,
1018+
recv,
1019+
UnusedDelimsCtx::MethodReceiver,
1020+
false,
1021+
None,
1022+
None,
1023+
false,
1024+
);
1025+
}
10021026
return;
10031027
}
10041028
};

library/compiler-builtins/libm/src/math/cbrt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ pub fn cbrt_round(x: f64, round: Round) -> FpResult<f64> {
194194
let mut cvt4: u64 = y1.to_bits();
195195
cvt4 = (cvt4 + (164 << 15)) & 0xffffffffffff0000u64;
196196

197-
if ((f64::from_bits(cvt4) - y1) - dy).abs() < hf64!("0x1p-60") || (zz).abs() == 1.0 {
197+
if ((f64::from_bits(cvt4) - y1) - dy).abs() < hf64!("0x1p-60") || zz.abs() == 1.0 {
198198
cvt3 = (cvt3 + (1u64 << 15)) & 0xffffffffffff0000u64;
199199
}
200200
}

library/core/src/ptr/const_ptr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl<T: PointeeSized> *const T {
2727
@capture { ptr: *const u8 } -> bool:
2828
// This use of `const_raw_ptr_comparison` has been explicitly blessed by t-lang.
2929
if const #[rustc_allow_const_fn_unstable(const_raw_ptr_comparison)] {
30-
match (ptr).guaranteed_eq(null_mut()) {
30+
match ptr.guaranteed_eq(null_mut()) {
3131
Some(res) => res,
3232
// To remain maximally conservative, we stop execution when we don't
3333
// know whether the pointer is null or not.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ run-rustfix
2+
3+
#![deny(unused_parens)]
4+
5+
struct Thing;
6+
impl Thing {
7+
fn method(self) {}
8+
}
9+
10+
fn main() {
11+
// Unnecessary parens - should warn
12+
let x = Thing;
13+
x.method(); //~ ERROR unnecessary parentheses around method receiver
14+
15+
// Necessary parens - should NOT warn
16+
let _ = (1..10).sum::<i32>(); // Range expression
17+
let _ = (1_i32 + 2).abs(); // Binary expression
18+
let _ = (-1_i32).abs(); // Unary expression
19+
let _ = (true as i32).abs(); // Cast expression
20+
let _ = (&42).clone(); // AddrOf expression
21+
let _ = (&mut 42).clone(); // AddrOf mut expression
22+
23+
// Block expressions - should NOT warn
24+
let _ = ({ 1_i32 }).abs(); // Block expression
25+
let _ = (unsafe { std::mem::zeroed::<i32>() }).abs(); // Unsafe block expression
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ run-rustfix
2+
3+
#![deny(unused_parens)]
4+
5+
struct Thing;
6+
impl Thing {
7+
fn method(self) {}
8+
}
9+
10+
fn main() {
11+
// Unnecessary parens - should warn
12+
let x = Thing;
13+
(x).method(); //~ ERROR unnecessary parentheses around method receiver
14+
15+
// Necessary parens - should NOT warn
16+
let _ = (1..10).sum::<i32>(); // Range expression
17+
let _ = (1_i32 + 2).abs(); // Binary expression
18+
let _ = (-1_i32).abs(); // Unary expression
19+
let _ = (true as i32).abs(); // Cast expression
20+
let _ = (&42).clone(); // AddrOf expression
21+
let _ = (&mut 42).clone(); // AddrOf mut expression
22+
23+
// Block expressions - should NOT warn
24+
let _ = ({ 1_i32 }).abs(); // Block expression
25+
let _ = (unsafe { std::mem::zeroed::<i32>() }).abs(); // Unsafe block expression
26+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error: unnecessary parentheses around method receiver
2+
--> $DIR/unused-parens-method-receiver-issue-151985.rs:13:5
3+
|
4+
LL | (x).method();
5+
| ^ ^
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/unused-parens-method-receiver-issue-151985.rs:3:9
9+
|
10+
LL | #![deny(unused_parens)]
11+
| ^^^^^^^^^^^^^
12+
help: remove these parentheses
13+
|
14+
LL - (x).method();
15+
LL + x.method();
16+
|
17+
18+
error: aborting due to 1 previous error
19+

0 commit comments

Comments
 (0)