Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,13 @@ impl UnusedDelimLint for UnusedParens {
}

impl UnusedParens {
fn pin_ergonomics_rustfix_allowed(cx: &EarlyContext<'_>) -> bool {
// FIXME(pin_ergonomics): Once `pin_ergonomics` is stabilized,
// remove this feature gate and allow the pinned-pattern rustfix
// suggestion unconditionally.
cx.builder.features().pin_ergonomics()
}

fn check_unused_parens_pat(
&self,
cx: &EarlyContext<'_>,
Expand All @@ -636,7 +643,7 @@ impl UnusedParens {
avoid_mut: bool,
keep_space: (bool, bool),
) {
use ast::{BindingMode, PatKind};
use ast::{BindingMode, ByRef, Mutability, PatKind, Pinnedness};

if let PatKind::Paren(inner) = &value.kind {
match inner.kind {
Expand All @@ -649,8 +656,15 @@ impl UnusedParens {
PatKind::Guard(..) => return,
// Avoid `p0 | .. | pn` if we should.
PatKind::Or(..) if avoid_or => return,
// Avoid `mut x` and `mut x @ p` if we should:
PatKind::Ident(BindingMode::MUT, ..) if avoid_mut => {
// Avoid bindings that start with `mut`, like `mut x`, `mut x @ p`,
// and `mut ref pin const x`, if we should.
PatKind::Ident(BindingMode(_, Mutability::Mut), ..) if avoid_mut => {
return;
}
PatKind::Ref(_, Pinnedness::Pinned, _)
| PatKind::Ident(BindingMode(ByRef::Yes(Pinnedness::Pinned, _), _), ..)
if !Self::pin_ergonomics_rustfix_allowed(cx) =>
{
return;
}
// Otherwise proceed with linting.
Expand Down Expand Up @@ -756,8 +770,8 @@ impl EarlyLintPass for UnusedParens {
}

fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
use ast::Mutability;
use ast::PatKind::*;
use ast::{Mutability, Pinnedness};
let keep_space = (false, false);
match &p.kind {
// Do not lint on `(..)` as that will result in the other arms being useless.
Expand All @@ -775,9 +789,22 @@ impl EarlyLintPass for UnusedParens {
// Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
Ident(.., Some(p)) | Box(p) | Deref(p) | Guard(p, _) => self.check_unused_parens_pat(cx, p, true, false, keep_space),
// Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
// This only applies to plain shared reference patterns. In `&pin const (mut x)`,
// `pin const` is consumed before parsing the subpattern, so removing the
// parentheses preserves `mut x` as a binding pattern.
// Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
// FIXME(pin_ergonomics): check pinned patterns
Ref(p, _, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Not, keep_space),
Ref(p, pinned, m) => {
if *pinned == Pinnedness::Pinned && !Self::pin_ergonomics_rustfix_allowed(cx) {
return;
}
self.check_unused_parens_pat(
cx,
p,
true,
*pinned == Pinnedness::Not && *m == Mutability::Not,
keep_space,
);
}
}
}

Expand Down
56 changes: 56 additions & 0 deletions tests/ui/lint/unused-parens-pinned-reference-patterns.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//@ run-rustfix
//@ check-pass
//@ normalize-stderr: "warning: 9 warnings emitted\n\n" -> "warning: 9 warnings emitted\n"
#![feature(pin_ergonomics, mut_ref)]
#![allow(dead_code)]
#![warn(unused_parens)]

fn pinned_reference_patterns(
pin_const: &pin const i32,
pin_mut: &pin mut i32,
nested_pin_const: &pin const &pin const i32,
) {
let &pin const _x = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin const mut _x = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin const mut _x @ _ = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin mut mut _x = pin_mut;
//~^ WARN unnecessary parentheses around pattern

let &pin const &pin const _x = nested_pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin const ref pin const _x = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin mut ref pin mut _x = pin_mut;
//~^ WARN unnecessary parentheses around pattern

let &pin const mut ref pin const _x = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin mut mut ref pin mut _x = pin_mut;
//~^ WARN unnecessary parentheses around pattern
}

fn pinned_or_patterns_are_still_ambiguous(pin_const: &pin const i32) {
match pin_const {
&pin const (0 | 1) => {}
_ => {}
}
}

fn plain_shared_reference_patterns_still_need_parens(shared: &i32) {
let &(mut _x) = shared;

let &(mut ref _x) = shared;

let &(mut ref pin const _x) = shared;
}

fn main() {}
56 changes: 56 additions & 0 deletions tests/ui/lint/unused-parens-pinned-reference-patterns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//@ run-rustfix
//@ check-pass
//@ normalize-stderr: "warning: 9 warnings emitted\n\n" -> "warning: 9 warnings emitted\n"
#![feature(pin_ergonomics, mut_ref)]
#![allow(dead_code)]
#![warn(unused_parens)]

fn pinned_reference_patterns(
pin_const: &pin const i32,
pin_mut: &pin mut i32,
nested_pin_const: &pin const &pin const i32,
) {
let &pin const (_x) = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin const (mut _x) = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin const (mut _x @ _) = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin mut (mut _x) = pin_mut;
//~^ WARN unnecessary parentheses around pattern

let &pin const (&pin const _x) = nested_pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin const (ref pin const _x) = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin mut (ref pin mut _x) = pin_mut;
//~^ WARN unnecessary parentheses around pattern

let &pin const (mut ref pin const _x) = pin_const;
//~^ WARN unnecessary parentheses around pattern

let &pin mut (mut ref pin mut _x) = pin_mut;
//~^ WARN unnecessary parentheses around pattern
}

fn pinned_or_patterns_are_still_ambiguous(pin_const: &pin const i32) {
match pin_const {
&pin const (0 | 1) => {}
_ => {}
}
}

fn plain_shared_reference_patterns_still_need_parens(shared: &i32) {
let &(mut _x) = shared;

let &(mut ref _x) = shared;

let &(mut ref pin const _x) = shared;
}

fn main() {}
114 changes: 114 additions & 0 deletions tests/ui/lint/unused-parens-pinned-reference-patterns.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
warning: unnecessary parentheses around pattern
--> $DIR/unused-parens-pinned-reference-patterns.rs:13:20
|
LL | let &pin const (_x) = pin_const;
| ^ ^
|
note: the lint level is defined here
--> $DIR/unused-parens-pinned-reference-patterns.rs:6:9
|
LL | #![warn(unused_parens)]
| ^^^^^^^^^^^^^
help: remove these parentheses
|
LL - let &pin const (_x) = pin_const;
LL + let &pin const _x = pin_const;
|

warning: unnecessary parentheses around pattern
--> $DIR/unused-parens-pinned-reference-patterns.rs:16:20
|
LL | let &pin const (mut _x) = pin_const;
| ^ ^
|
help: remove these parentheses
|
LL - let &pin const (mut _x) = pin_const;
LL + let &pin const mut _x = pin_const;
|

warning: unnecessary parentheses around pattern
--> $DIR/unused-parens-pinned-reference-patterns.rs:19:20
|
LL | let &pin const (mut _x @ _) = pin_const;
| ^ ^
|
help: remove these parentheses
|
LL - let &pin const (mut _x @ _) = pin_const;
LL + let &pin const mut _x @ _ = pin_const;
|

warning: unnecessary parentheses around pattern
--> $DIR/unused-parens-pinned-reference-patterns.rs:22:18
|
LL | let &pin mut (mut _x) = pin_mut;
| ^ ^
|
help: remove these parentheses
|
LL - let &pin mut (mut _x) = pin_mut;
LL + let &pin mut mut _x = pin_mut;
|

warning: unnecessary parentheses around pattern
--> $DIR/unused-parens-pinned-reference-patterns.rs:25:20
|
LL | let &pin const (&pin const _x) = nested_pin_const;
| ^ ^
|
help: remove these parentheses
|
LL - let &pin const (&pin const _x) = nested_pin_const;
LL + let &pin const &pin const _x = nested_pin_const;
|

warning: unnecessary parentheses around pattern
--> $DIR/unused-parens-pinned-reference-patterns.rs:28:20
|
LL | let &pin const (ref pin const _x) = pin_const;
| ^ ^
|
help: remove these parentheses
|
LL - let &pin const (ref pin const _x) = pin_const;
LL + let &pin const ref pin const _x = pin_const;
|

warning: unnecessary parentheses around pattern
--> $DIR/unused-parens-pinned-reference-patterns.rs:31:18
|
LL | let &pin mut (ref pin mut _x) = pin_mut;
| ^ ^
|
help: remove these parentheses
|
LL - let &pin mut (ref pin mut _x) = pin_mut;
LL + let &pin mut ref pin mut _x = pin_mut;
|

warning: unnecessary parentheses around pattern
--> $DIR/unused-parens-pinned-reference-patterns.rs:34:20
|
LL | let &pin const (mut ref pin const _x) = pin_const;
| ^ ^
|
help: remove these parentheses
|
LL - let &pin const (mut ref pin const _x) = pin_const;
LL + let &pin const mut ref pin const _x = pin_const;
|

warning: unnecessary parentheses around pattern
--> $DIR/unused-parens-pinned-reference-patterns.rs:37:18
|
LL | let &pin mut (mut ref pin mut _x) = pin_mut;
| ^ ^
|
help: remove these parentheses
|
LL - let &pin mut (mut ref pin mut _x) = pin_mut;
LL + let &pin mut mut ref pin mut _x = pin_mut;
|

warning: 9 warnings emitted
Loading