mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-30 16:39:26 +00:00
Auto merge of #10885 - max-niederman:redundant_local, r=Centri3
new lint: `redundant_locals` This lint checks for code like the following: ```rs let x = 1; let x = x; ``` It checks (afaik) all cases where a binding is shadowed by its own value in the same block, including function parameters. This has no effect and is almost certainly accidental, so it's in the `correctness` category like `self_assignment`. This also lays the groundwork for a more generalized version of #5102. changelog: new lint: [`redundant_local`]
This commit is contained in:
commit
a44dcf80ef
13 changed files with 403 additions and 45 deletions
|
@ -5190,6 +5190,7 @@ Released 2018-09-13
|
||||||
[`redundant_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_else
|
[`redundant_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_else
|
||||||
[`redundant_feature_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_feature_names
|
[`redundant_feature_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_feature_names
|
||||||
[`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names
|
[`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names
|
||||||
|
[`redundant_locals`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_locals
|
||||||
[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern
|
[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern
|
||||||
[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching
|
[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching
|
||||||
[`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate
|
[`redundant_pub_crate`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pub_crate
|
||||||
|
|
|
@ -561,6 +561,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||||
crate::redundant_closure_call::REDUNDANT_CLOSURE_CALL_INFO,
|
crate::redundant_closure_call::REDUNDANT_CLOSURE_CALL_INFO,
|
||||||
crate::redundant_else::REDUNDANT_ELSE_INFO,
|
crate::redundant_else::REDUNDANT_ELSE_INFO,
|
||||||
crate::redundant_field_names::REDUNDANT_FIELD_NAMES_INFO,
|
crate::redundant_field_names::REDUNDANT_FIELD_NAMES_INFO,
|
||||||
|
crate::redundant_locals::REDUNDANT_LOCALS_INFO,
|
||||||
crate::redundant_pub_crate::REDUNDANT_PUB_CRATE_INFO,
|
crate::redundant_pub_crate::REDUNDANT_PUB_CRATE_INFO,
|
||||||
crate::redundant_slicing::DEREF_BY_SLICING_INFO,
|
crate::redundant_slicing::DEREF_BY_SLICING_INFO,
|
||||||
crate::redundant_slicing::REDUNDANT_SLICING_INFO,
|
crate::redundant_slicing::REDUNDANT_SLICING_INFO,
|
||||||
|
|
|
@ -275,6 +275,7 @@ mod redundant_clone;
|
||||||
mod redundant_closure_call;
|
mod redundant_closure_call;
|
||||||
mod redundant_else;
|
mod redundant_else;
|
||||||
mod redundant_field_names;
|
mod redundant_field_names;
|
||||||
|
mod redundant_locals;
|
||||||
mod redundant_pub_crate;
|
mod redundant_pub_crate;
|
||||||
mod redundant_slicing;
|
mod redundant_slicing;
|
||||||
mod redundant_static_lifetimes;
|
mod redundant_static_lifetimes;
|
||||||
|
@ -1091,6 +1092,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||||
absolute_paths_allowed_crates: absolute_paths_allowed_crates.clone(),
|
absolute_paths_allowed_crates: absolute_paths_allowed_crates.clone(),
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
store.register_late_pass(|_| Box::new(redundant_locals::RedundantLocals));
|
||||||
// add lints here, do not remove this comment, it's used in `new_lint`
|
// add lints here, do not remove this comment, it's used in `new_lint`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
103
clippy_lints/src/redundant_locals.rs
Normal file
103
clippy_lints/src/redundant_locals.rs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
use clippy_utils::diagnostics::span_lint_and_help;
|
||||||
|
use clippy_utils::is_from_proc_macro;
|
||||||
|
use clippy_utils::ty::needs_ordered_drop;
|
||||||
|
use rustc_hir::def::Res;
|
||||||
|
use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, HirId, Local, Node, Pat, PatKind, QPath};
|
||||||
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
|
use rustc_middle::lint::in_external_macro;
|
||||||
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::symbol::Ident;
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Checks for redundant redefinitions of local bindings.
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
/// Redundant redefinitions of local bindings do not change behavior and are likely to be unintended.
|
||||||
|
///
|
||||||
|
/// Note that although these bindings do not affect your code's meaning, they _may_ affect `rustc`'s stack allocation.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// let a = 0;
|
||||||
|
/// let a = a;
|
||||||
|
///
|
||||||
|
/// fn foo(b: i32) {
|
||||||
|
/// let b = b;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
/// Use instead:
|
||||||
|
/// ```rust
|
||||||
|
/// let a = 0;
|
||||||
|
/// // no redefinition with the same name
|
||||||
|
///
|
||||||
|
/// fn foo(b: i32) {
|
||||||
|
/// // no redefinition with the same name
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[clippy::version = "1.72.0"]
|
||||||
|
pub REDUNDANT_LOCALS,
|
||||||
|
correctness,
|
||||||
|
"redundant redefinition of a local binding"
|
||||||
|
}
|
||||||
|
declare_lint_pass!(RedundantLocals => [REDUNDANT_LOCALS]);
|
||||||
|
|
||||||
|
impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
|
||||||
|
fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
|
||||||
|
if_chain! {
|
||||||
|
// the pattern is a single by-value binding
|
||||||
|
if let PatKind::Binding(BindingAnnotation(ByRef::No, mutability), _, ident, None) = local.pat.kind;
|
||||||
|
// the binding is not type-ascribed
|
||||||
|
if local.ty.is_none();
|
||||||
|
// the expression is a resolved path
|
||||||
|
if let Some(expr) = local.init;
|
||||||
|
if let ExprKind::Path(qpath @ QPath::Resolved(None, path)) = expr.kind;
|
||||||
|
// the path is a single segment equal to the local's name
|
||||||
|
if let [last_segment] = path.segments;
|
||||||
|
if last_segment.ident == ident;
|
||||||
|
// resolve the path to its defining binding pattern
|
||||||
|
if let Res::Local(binding_id) = cx.qpath_res(&qpath, expr.hir_id);
|
||||||
|
if let Node::Pat(binding_pat) = cx.tcx.hir().get(binding_id);
|
||||||
|
// the previous binding has the same mutability
|
||||||
|
if find_binding(binding_pat, ident).unwrap().1 == mutability;
|
||||||
|
// the local does not affect the code's drop behavior
|
||||||
|
if !affects_drop_behavior(cx, binding_id, local.hir_id, expr);
|
||||||
|
// the local is user-controlled
|
||||||
|
if !in_external_macro(cx.sess(), local.span);
|
||||||
|
if !is_from_proc_macro(cx, expr);
|
||||||
|
then {
|
||||||
|
span_lint_and_help(
|
||||||
|
cx,
|
||||||
|
REDUNDANT_LOCALS,
|
||||||
|
vec![binding_pat.span, local.span],
|
||||||
|
"redundant redefinition of a binding",
|
||||||
|
None,
|
||||||
|
&format!("remove the redefinition of `{ident}`"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find the annotation of a binding introduced by a pattern, or `None` if it's not introduced.
|
||||||
|
fn find_binding(pat: &Pat<'_>, name: Ident) -> Option<BindingAnnotation> {
|
||||||
|
let mut ret = None;
|
||||||
|
|
||||||
|
pat.each_binding_or_first(&mut |annotation, _, _, ident| {
|
||||||
|
if ident == name {
|
||||||
|
ret = Some(annotation);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check if a rebinding of a local affects the code's drop behavior.
|
||||||
|
fn affects_drop_behavior<'tcx>(cx: &LateContext<'tcx>, bind: HirId, rebind: HirId, rebind_expr: &Expr<'tcx>) -> bool {
|
||||||
|
let hir = cx.tcx.hir();
|
||||||
|
|
||||||
|
// the rebinding is in a different scope than the original binding
|
||||||
|
// and the type of the binding cares about drop order
|
||||||
|
hir.get_enclosing_scope(bind) != hir.get_enclosing_scope(rebind)
|
||||||
|
&& needs_ordered_drop(cx, cx.typeck_results().expr_ty(rebind_expr))
|
||||||
|
}
|
|
@ -5,7 +5,8 @@
|
||||||
clippy::redundant_closure,
|
clippy::redundant_closure,
|
||||||
clippy::ref_option_ref,
|
clippy::ref_option_ref,
|
||||||
clippy::equatable_if_let,
|
clippy::equatable_if_let,
|
||||||
clippy::let_unit_value
|
clippy::let_unit_value,
|
||||||
|
clippy::redundant_locals
|
||||||
)]
|
)]
|
||||||
|
|
||||||
fn bad1(string: Option<&str>) -> (bool, &str) {
|
fn bad1(string: Option<&str>) -> (bool, &str) {
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
clippy::redundant_closure,
|
clippy::redundant_closure,
|
||||||
clippy::ref_option_ref,
|
clippy::ref_option_ref,
|
||||||
clippy::equatable_if_let,
|
clippy::equatable_if_let,
|
||||||
clippy::let_unit_value
|
clippy::let_unit_value,
|
||||||
|
clippy::redundant_locals
|
||||||
)]
|
)]
|
||||||
|
|
||||||
fn bad1(string: Option<&str>) -> (bool, &str) {
|
fn bad1(string: Option<&str>) -> (bool, &str) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:12:5
|
--> $DIR/option_if_let_else.rs:13:5
|
||||||
|
|
|
|
||||||
LL | / if let Some(x) = string {
|
LL | / if let Some(x) = string {
|
||||||
LL | | (true, x)
|
LL | | (true, x)
|
||||||
|
@ -11,19 +11,19 @@ LL | | }
|
||||||
= note: `-D clippy::option-if-let-else` implied by `-D warnings`
|
= note: `-D clippy::option-if-let-else` implied by `-D warnings`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:30:13
|
--> $DIR/option_if_let_else.rs:31:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(s) = *string { s.len() } else { 0 };
|
LL | let _ = if let Some(s) = *string { s.len() } else { 0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:31:13
|
--> $DIR/option_if_let_else.rs:32:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(s) = &num { s } else { &0 };
|
LL | let _ = if let Some(s) = &num { s } else { &0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:32:13
|
--> $DIR/option_if_let_else.rs:33:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(s) = &mut num {
|
LL | let _ = if let Some(s) = &mut num {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -43,13 +43,13 @@ LL ~ });
|
||||||
|
|
|
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:38:13
|
--> $DIR/option_if_let_else.rs:39:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(ref s) = num { s } else { &0 };
|
LL | let _ = if let Some(ref s) = num { s } else { &0 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:39:13
|
--> $DIR/option_if_let_else.rs:40:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(mut s) = num {
|
LL | let _ = if let Some(mut s) = num {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -69,7 +69,7 @@ LL ~ });
|
||||||
|
|
|
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:45:13
|
--> $DIR/option_if_let_else.rs:46:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(ref mut s) = num {
|
LL | let _ = if let Some(ref mut s) = num {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -89,7 +89,7 @@ LL ~ });
|
||||||
|
|
|
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:54:5
|
--> $DIR/option_if_let_else.rs:55:5
|
||||||
|
|
|
|
||||||
LL | / if let Some(x) = arg {
|
LL | / if let Some(x) = arg {
|
||||||
LL | | let y = x * x;
|
LL | | let y = x * x;
|
||||||
|
@ -108,7 +108,7 @@ LL + })
|
||||||
|
|
|
|
||||||
|
|
||||||
error: use Option::map_or_else instead of an if let/else
|
error: use Option::map_or_else instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:67:13
|
--> $DIR/option_if_let_else.rs:68:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(x) = arg {
|
LL | let _ = if let Some(x) = arg {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -120,7 +120,7 @@ LL | | };
|
||||||
| |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)`
|
| |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)`
|
||||||
|
|
||||||
error: use Option::map_or_else instead of an if let/else
|
error: use Option::map_or_else instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:76:13
|
--> $DIR/option_if_let_else.rs:77:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(x) = arg {
|
LL | let _ = if let Some(x) = arg {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -143,7 +143,7 @@ LL ~ }, |x| x * x * x * x);
|
||||||
|
|
|
|
||||||
|
|
||||||
error: use Option::map_or_else instead of an if let/else
|
error: use Option::map_or_else instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:109:13
|
--> $DIR/option_if_let_else.rs:110:13
|
||||||
|
|
|
|
||||||
LL | / if let Some(idx) = s.find('.') {
|
LL | / if let Some(idx) = s.find('.') {
|
||||||
LL | | vec![s[..idx].to_string(), s[idx..].to_string()]
|
LL | | vec![s[..idx].to_string(), s[idx..].to_string()]
|
||||||
|
@ -153,7 +153,7 @@ LL | | }
|
||||||
| |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])`
|
| |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])`
|
||||||
|
|
||||||
error: use Option::map_or_else instead of an if let/else
|
error: use Option::map_or_else instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:120:5
|
--> $DIR/option_if_let_else.rs:121:5
|
||||||
|
|
|
|
||||||
LL | / if let Ok(binding) = variable {
|
LL | / if let Ok(binding) = variable {
|
||||||
LL | | println!("Ok {binding}");
|
LL | | println!("Ok {binding}");
|
||||||
|
@ -172,13 +172,13 @@ LL + })
|
||||||
|
|
|
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:142:13
|
--> $DIR/option_if_let_else.rs:143:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(x) = optional { x + 2 } else { 5 };
|
LL | let _ = if let Some(x) = optional { x + 2 } else { 5 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:152:13
|
--> $DIR/option_if_let_else.rs:153:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(x) = Some(0) {
|
LL | let _ = if let Some(x) = Some(0) {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -200,13 +200,13 @@ LL ~ });
|
||||||
|
|
|
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:180:13
|
--> $DIR/option_if_let_else.rs:181:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
|
LL | let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:184:13
|
--> $DIR/option_if_let_else.rs:185:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Some(x) = Some(0) {
|
LL | let _ = if let Some(x) = Some(0) {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -226,7 +226,7 @@ LL ~ });
|
||||||
|
|
|
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:223:13
|
--> $DIR/option_if_let_else.rs:224:13
|
||||||
|
|
|
|
||||||
LL | let _ = match s {
|
LL | let _ = match s {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -236,7 +236,7 @@ LL | | };
|
||||||
| |_____^ help: try: `s.map_or(1, |string| string.len())`
|
| |_____^ help: try: `s.map_or(1, |string| string.len())`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:227:13
|
--> $DIR/option_if_let_else.rs:228:13
|
||||||
|
|
|
|
||||||
LL | let _ = match Some(10) {
|
LL | let _ = match Some(10) {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -246,7 +246,7 @@ LL | | };
|
||||||
| |_____^ help: try: `Some(10).map_or(5, |a| a + 1)`
|
| |_____^ help: try: `Some(10).map_or(5, |a| a + 1)`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:233:13
|
--> $DIR/option_if_let_else.rs:234:13
|
||||||
|
|
|
|
||||||
LL | let _ = match res {
|
LL | let _ = match res {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -256,7 +256,7 @@ LL | | };
|
||||||
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
|
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:237:13
|
--> $DIR/option_if_let_else.rs:238:13
|
||||||
|
|
|
|
||||||
LL | let _ = match res {
|
LL | let _ = match res {
|
||||||
| _____________^
|
| _____________^
|
||||||
|
@ -266,13 +266,13 @@ LL | | };
|
||||||
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
|
| |_____^ help: try: `res.map_or(1, |a| a + 1)`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:241:13
|
--> $DIR/option_if_let_else.rs:242:13
|
||||||
|
|
|
|
||||||
LL | let _ = if let Ok(a) = res { a + 1 } else { 5 };
|
LL | let _ = if let Ok(a) = res { a + 1 } else { 5 };
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `res.map_or(5, |a| a + 1)`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:258:9
|
--> $DIR/option_if_let_else.rs:259:9
|
||||||
|
|
|
|
||||||
LL | / match initial {
|
LL | / match initial {
|
||||||
LL | | Some(value) => do_something(value),
|
LL | | Some(value) => do_something(value),
|
||||||
|
@ -281,7 +281,7 @@ LL | | }
|
||||||
| |_________^ help: try: `initial.as_ref().map_or({}, |value| do_something(value))`
|
| |_________^ help: try: `initial.as_ref().map_or({}, |value| do_something(value))`
|
||||||
|
|
||||||
error: use Option::map_or instead of an if let/else
|
error: use Option::map_or instead of an if let/else
|
||||||
--> $DIR/option_if_let_else.rs:265:9
|
--> $DIR/option_if_let_else.rs:266:9
|
||||||
|
|
|
|
||||||
LL | / match initial {
|
LL | / match initial {
|
||||||
LL | | Some(value) => do_something2(value),
|
LL | | Some(value) => do_something2(value),
|
||||||
|
|
111
tests/ui/redundant_locals.rs
Normal file
111
tests/ui/redundant_locals.rs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
//@aux-build:proc_macros.rs:proc-macro
|
||||||
|
#![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)]
|
||||||
|
#![warn(clippy::redundant_locals)]
|
||||||
|
|
||||||
|
extern crate proc_macros;
|
||||||
|
use proc_macros::{external, with_span};
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
fn immutable() {
|
||||||
|
let x = 1;
|
||||||
|
let x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mutable() {
|
||||||
|
let mut x = 1;
|
||||||
|
let mut x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn upgraded_mutability() {
|
||||||
|
let x = 1;
|
||||||
|
let mut x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn downgraded_mutability() {
|
||||||
|
let mut x = 1;
|
||||||
|
let x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn coercion(par: &mut i32) {
|
||||||
|
let par: &i32 = par;
|
||||||
|
|
||||||
|
let x: &mut i32 = &mut 1;
|
||||||
|
let x: &i32 = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parameter(x: i32) {
|
||||||
|
let x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn many() {
|
||||||
|
let x = 1;
|
||||||
|
let x = x;
|
||||||
|
let x = x;
|
||||||
|
let x = x;
|
||||||
|
let x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn interleaved() {
|
||||||
|
let a = 1;
|
||||||
|
let b = 2;
|
||||||
|
let a = a;
|
||||||
|
let b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block() {
|
||||||
|
{
|
||||||
|
let x = 1;
|
||||||
|
let x = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn closure() {
|
||||||
|
|| {
|
||||||
|
let x = 1;
|
||||||
|
let x = x;
|
||||||
|
};
|
||||||
|
|x: i32| {
|
||||||
|
let x = x;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consequential_drop_order() {
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
let mutex = Mutex::new(1);
|
||||||
|
let guard = mutex.lock().unwrap();
|
||||||
|
|
||||||
|
{
|
||||||
|
let guard = guard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inconsequential_drop_order() {
|
||||||
|
let x = 1;
|
||||||
|
|
||||||
|
{
|
||||||
|
let x = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn macros() {
|
||||||
|
macro_rules! rebind {
|
||||||
|
($x:ident) => {
|
||||||
|
let $x = 1;
|
||||||
|
let $x = $x;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rebind!(x);
|
||||||
|
|
||||||
|
external! {
|
||||||
|
let x = 1;
|
||||||
|
let x = x;
|
||||||
|
}
|
||||||
|
with_span! {
|
||||||
|
span
|
||||||
|
let x = 1;
|
||||||
|
let x = x;
|
||||||
|
}
|
||||||
|
}
|
136
tests/ui/redundant_locals.stderr
Normal file
136
tests/ui/redundant_locals.stderr
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:11:9
|
||||||
|
|
|
||||||
|
LL | let x = 1;
|
||||||
|
| ^
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
= note: `-D clippy::redundant-locals` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:16:9
|
||||||
|
|
|
||||||
|
LL | let mut x = 1;
|
||||||
|
| ^^^^^
|
||||||
|
LL | let mut x = x;
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:37:14
|
||||||
|
|
|
||||||
|
LL | fn parameter(x: i32) {
|
||||||
|
| ^
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:42:9
|
||||||
|
|
|
||||||
|
LL | let x = 1;
|
||||||
|
| ^
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:43:9
|
||||||
|
|
|
||||||
|
LL | let x = x;
|
||||||
|
| ^
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:44:9
|
||||||
|
|
|
||||||
|
LL | let x = x;
|
||||||
|
| ^
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:45:9
|
||||||
|
|
|
||||||
|
LL | let x = x;
|
||||||
|
| ^
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:50:9
|
||||||
|
|
|
||||||
|
LL | let a = 1;
|
||||||
|
| ^
|
||||||
|
LL | let b = 2;
|
||||||
|
LL | let a = a;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `a`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:51:9
|
||||||
|
|
|
||||||
|
LL | let b = 2;
|
||||||
|
| ^
|
||||||
|
LL | let a = a;
|
||||||
|
LL | let b = b;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `b`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:58:13
|
||||||
|
|
|
||||||
|
LL | let x = 1;
|
||||||
|
| ^
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:65:13
|
||||||
|
|
|
||||||
|
LL | let x = 1;
|
||||||
|
| ^
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:68:6
|
||||||
|
|
|
||||||
|
LL | |x: i32| {
|
||||||
|
| ^
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: redundant redefinition of a binding
|
||||||
|
--> $DIR/redundant_locals.rs:85:9
|
||||||
|
|
|
||||||
|
LL | let x = 1;
|
||||||
|
| ^
|
||||||
|
...
|
||||||
|
LL | let x = x;
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: remove the redefinition of `x`
|
||||||
|
|
||||||
|
error: aborting due to 13 previous errors
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//@aux-build:proc_macro_derive.rs:proc-macro
|
//@aux-build:proc_macro_derive.rs:proc-macro
|
||||||
|
|
||||||
#![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)]
|
#![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)]
|
||||||
#![allow(clippy::let_unit_value, clippy::needless_if)]
|
#![allow(clippy::let_unit_value, clippy::needless_if, clippy::redundant_locals)]
|
||||||
|
|
||||||
extern crate proc_macro_derive;
|
extern crate proc_macro_derive;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
unused_assignments,
|
unused_assignments,
|
||||||
unused_variables,
|
unused_variables,
|
||||||
clippy::let_and_return,
|
clippy::let_and_return,
|
||||||
clippy::useless_vec
|
clippy::useless_vec,
|
||||||
|
clippy::redundant_locals
|
||||||
)]
|
)]
|
||||||
|
|
||||||
struct Foo(u32);
|
struct Foo(u32);
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
unused_assignments,
|
unused_assignments,
|
||||||
unused_variables,
|
unused_variables,
|
||||||
clippy::let_and_return,
|
clippy::let_and_return,
|
||||||
clippy::useless_vec
|
clippy::useless_vec,
|
||||||
|
clippy::redundant_locals
|
||||||
)]
|
)]
|
||||||
|
|
||||||
struct Foo(u32);
|
struct Foo(u32);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: this looks like you are swapping `bar.a` and `bar.b` manually
|
error: this looks like you are swapping `bar.a` and `bar.b` manually
|
||||||
--> $DIR/swap.rs:28:5
|
--> $DIR/swap.rs:29:5
|
||||||
|
|
|
|
||||||
LL | / let temp = bar.a;
|
LL | / let temp = bar.a;
|
||||||
LL | | bar.a = bar.b;
|
LL | | bar.a = bar.b;
|
||||||
|
@ -10,7 +10,7 @@ LL | | bar.b = temp;
|
||||||
= note: `-D clippy::manual-swap` implied by `-D warnings`
|
= note: `-D clippy::manual-swap` implied by `-D warnings`
|
||||||
|
|
||||||
error: this looks like you are swapping elements of `foo` manually
|
error: this looks like you are swapping elements of `foo` manually
|
||||||
--> $DIR/swap.rs:40:5
|
--> $DIR/swap.rs:41:5
|
||||||
|
|
|
|
||||||
LL | / let temp = foo[0];
|
LL | / let temp = foo[0];
|
||||||
LL | | foo[0] = foo[1];
|
LL | | foo[0] = foo[1];
|
||||||
|
@ -18,7 +18,7 @@ LL | | foo[1] = temp;
|
||||||
| |__________________^ help: try: `foo.swap(0, 1);`
|
| |__________________^ help: try: `foo.swap(0, 1);`
|
||||||
|
|
||||||
error: this looks like you are swapping elements of `foo` manually
|
error: this looks like you are swapping elements of `foo` manually
|
||||||
--> $DIR/swap.rs:49:5
|
--> $DIR/swap.rs:50:5
|
||||||
|
|
|
|
||||||
LL | / let temp = foo[0];
|
LL | / let temp = foo[0];
|
||||||
LL | | foo[0] = foo[1];
|
LL | | foo[0] = foo[1];
|
||||||
|
@ -26,7 +26,7 @@ LL | | foo[1] = temp;
|
||||||
| |__________________^ help: try: `foo.swap(0, 1);`
|
| |__________________^ help: try: `foo.swap(0, 1);`
|
||||||
|
|
||||||
error: this looks like you are swapping elements of `foo` manually
|
error: this looks like you are swapping elements of `foo` manually
|
||||||
--> $DIR/swap.rs:68:5
|
--> $DIR/swap.rs:69:5
|
||||||
|
|
|
|
||||||
LL | / let temp = foo[0];
|
LL | / let temp = foo[0];
|
||||||
LL | | foo[0] = foo[1];
|
LL | | foo[0] = foo[1];
|
||||||
|
@ -34,7 +34,7 @@ LL | | foo[1] = temp;
|
||||||
| |__________________^ help: try: `foo.swap(0, 1);`
|
| |__________________^ help: try: `foo.swap(0, 1);`
|
||||||
|
|
||||||
error: this looks like you are swapping `a` and `b` manually
|
error: this looks like you are swapping `a` and `b` manually
|
||||||
--> $DIR/swap.rs:79:5
|
--> $DIR/swap.rs:80:5
|
||||||
|
|
|
|
||||||
LL | / a ^= b;
|
LL | / a ^= b;
|
||||||
LL | | b ^= a;
|
LL | | b ^= a;
|
||||||
|
@ -42,7 +42,7 @@ LL | | a ^= b;
|
||||||
| |___________^ help: try: `std::mem::swap(&mut a, &mut b);`
|
| |___________^ help: try: `std::mem::swap(&mut a, &mut b);`
|
||||||
|
|
||||||
error: this looks like you are swapping `bar.a` and `bar.b` manually
|
error: this looks like you are swapping `bar.a` and `bar.b` manually
|
||||||
--> $DIR/swap.rs:87:5
|
--> $DIR/swap.rs:88:5
|
||||||
|
|
|
|
||||||
LL | / bar.a ^= bar.b;
|
LL | / bar.a ^= bar.b;
|
||||||
LL | | bar.b ^= bar.a;
|
LL | | bar.b ^= bar.a;
|
||||||
|
@ -50,7 +50,7 @@ LL | | bar.a ^= bar.b;
|
||||||
| |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);`
|
| |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);`
|
||||||
|
|
||||||
error: this looks like you are swapping elements of `foo` manually
|
error: this looks like you are swapping elements of `foo` manually
|
||||||
--> $DIR/swap.rs:95:5
|
--> $DIR/swap.rs:96:5
|
||||||
|
|
|
|
||||||
LL | / foo[0] ^= foo[1];
|
LL | / foo[0] ^= foo[1];
|
||||||
LL | | foo[1] ^= foo[0];
|
LL | | foo[1] ^= foo[0];
|
||||||
|
@ -58,7 +58,7 @@ LL | | foo[0] ^= foo[1];
|
||||||
| |_____________________^ help: try: `foo.swap(0, 1);`
|
| |_____________________^ help: try: `foo.swap(0, 1);`
|
||||||
|
|
||||||
error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually
|
error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually
|
||||||
--> $DIR/swap.rs:124:5
|
--> $DIR/swap.rs:125:5
|
||||||
|
|
|
|
||||||
LL | / let temp = foo[0][1];
|
LL | / let temp = foo[0][1];
|
||||||
LL | | foo[0][1] = bar[1][0];
|
LL | | foo[0][1] = bar[1][0];
|
||||||
|
@ -68,7 +68,7 @@ LL | | bar[1][0] = temp;
|
||||||
= note: or maybe you should use `std::mem::replace`?
|
= note: or maybe you should use `std::mem::replace`?
|
||||||
|
|
||||||
error: this looks like you are swapping `a` and `b` manually
|
error: this looks like you are swapping `a` and `b` manually
|
||||||
--> $DIR/swap.rs:138:7
|
--> $DIR/swap.rs:139:7
|
||||||
|
|
|
|
||||||
LL | ; let t = a;
|
LL | ; let t = a;
|
||||||
| _______^
|
| _______^
|
||||||
|
@ -79,7 +79,7 @@ LL | | b = t;
|
||||||
= note: or maybe you should use `std::mem::replace`?
|
= note: or maybe you should use `std::mem::replace`?
|
||||||
|
|
||||||
error: this looks like you are swapping `c.0` and `a` manually
|
error: this looks like you are swapping `c.0` and `a` manually
|
||||||
--> $DIR/swap.rs:147:7
|
--> $DIR/swap.rs:148:7
|
||||||
|
|
|
|
||||||
LL | ; let t = c.0;
|
LL | ; let t = c.0;
|
||||||
| _______^
|
| _______^
|
||||||
|
@ -90,7 +90,7 @@ LL | | a = t;
|
||||||
= note: or maybe you should use `std::mem::replace`?
|
= note: or maybe you should use `std::mem::replace`?
|
||||||
|
|
||||||
error: this looks like you are swapping `b` and `a` manually
|
error: this looks like you are swapping `b` and `a` manually
|
||||||
--> $DIR/swap.rs:173:5
|
--> $DIR/swap.rs:174:5
|
||||||
|
|
|
|
||||||
LL | / let t = b;
|
LL | / let t = b;
|
||||||
LL | | b = a;
|
LL | | b = a;
|
||||||
|
@ -100,7 +100,7 @@ LL | | a = t;
|
||||||
= note: or maybe you should use `std::mem::replace`?
|
= note: or maybe you should use `std::mem::replace`?
|
||||||
|
|
||||||
error: this looks like you are trying to swap `a` and `b`
|
error: this looks like you are trying to swap `a` and `b`
|
||||||
--> $DIR/swap.rs:135:5
|
--> $DIR/swap.rs:136:5
|
||||||
|
|
|
|
||||||
LL | / a = b;
|
LL | / a = b;
|
||||||
LL | | b = a;
|
LL | | b = a;
|
||||||
|
@ -110,7 +110,7 @@ LL | | b = a;
|
||||||
= note: `-D clippy::almost-swapped` implied by `-D warnings`
|
= note: `-D clippy::almost-swapped` implied by `-D warnings`
|
||||||
|
|
||||||
error: this looks like you are trying to swap `c.0` and `a`
|
error: this looks like you are trying to swap `c.0` and `a`
|
||||||
--> $DIR/swap.rs:144:5
|
--> $DIR/swap.rs:145:5
|
||||||
|
|
|
|
||||||
LL | / c.0 = a;
|
LL | / c.0 = a;
|
||||||
LL | | a = c.0;
|
LL | | a = c.0;
|
||||||
|
@ -119,7 +119,7 @@ LL | | a = c.0;
|
||||||
= note: or maybe you should use `std::mem::replace`?
|
= note: or maybe you should use `std::mem::replace`?
|
||||||
|
|
||||||
error: this looks like you are trying to swap `a` and `b`
|
error: this looks like you are trying to swap `a` and `b`
|
||||||
--> $DIR/swap.rs:151:5
|
--> $DIR/swap.rs:152:5
|
||||||
|
|
|
|
||||||
LL | / let a = b;
|
LL | / let a = b;
|
||||||
LL | | let b = a;
|
LL | | let b = a;
|
||||||
|
@ -128,7 +128,7 @@ LL | | let b = a;
|
||||||
= note: or maybe you should use `std::mem::replace`?
|
= note: or maybe you should use `std::mem::replace`?
|
||||||
|
|
||||||
error: this looks like you are trying to swap `d` and `c`
|
error: this looks like you are trying to swap `d` and `c`
|
||||||
--> $DIR/swap.rs:156:5
|
--> $DIR/swap.rs:157:5
|
||||||
|
|
|
|
||||||
LL | / d = c;
|
LL | / d = c;
|
||||||
LL | | c = d;
|
LL | | c = d;
|
||||||
|
@ -137,7 +137,7 @@ LL | | c = d;
|
||||||
= note: or maybe you should use `std::mem::replace`?
|
= note: or maybe you should use `std::mem::replace`?
|
||||||
|
|
||||||
error: this looks like you are trying to swap `a` and `b`
|
error: this looks like you are trying to swap `a` and `b`
|
||||||
--> $DIR/swap.rs:160:5
|
--> $DIR/swap.rs:161:5
|
||||||
|
|
|
|
||||||
LL | / let a = b;
|
LL | / let a = b;
|
||||||
LL | | b = a;
|
LL | | b = a;
|
||||||
|
@ -146,7 +146,7 @@ LL | | b = a;
|
||||||
= note: or maybe you should use `std::mem::replace`?
|
= note: or maybe you should use `std::mem::replace`?
|
||||||
|
|
||||||
error: this looks like you are swapping `s.0.x` and `s.0.y` manually
|
error: this looks like you are swapping `s.0.x` and `s.0.y` manually
|
||||||
--> $DIR/swap.rs:208:5
|
--> $DIR/swap.rs:209:5
|
||||||
|
|
|
|
||||||
LL | / let t = s.0.x;
|
LL | / let t = s.0.x;
|
||||||
LL | | s.0.x = s.0.y;
|
LL | | s.0.x = s.0.y;
|
||||||
|
|
Loading…
Reference in a new issue