Remove final reference on fields and method calls in needless_borrow

This commit is contained in:
Jason Newcomb 2022-01-11 14:31:35 -05:00
parent 15c068ed0f
commit 9e9110e4f3
32 changed files with 484 additions and 362 deletions

View file

@ -981,7 +981,7 @@ Released 2021-03-25
[#6532](https://github.com/rust-lang/rust-clippy/pull/6532)
* [`single_match`] Suggest `if` over `if let` when possible
[#6574](https://github.com/rust-lang/rust-clippy/pull/6574)
* [`ref_in_deref`] Use parentheses correctly in suggestion
* `ref_in_deref` Use parentheses correctly in suggestion
[#6609](https://github.com/rust-lang/rust-clippy/pull/6609)
* [`stable_sort_primitive`] Clarify error message
[#6611](https://github.com/rust-lang/rust-clippy/pull/6611)

View file

@ -1,5 +1,6 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
use clippy_utils::sugg::has_enclosing_paren;
use clippy_utils::ty::peel_mid_ty_refs;
use clippy_utils::{get_parent_expr, get_parent_node, is_lint_allowed, path_to_local};
use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
@ -130,8 +131,6 @@ pub struct Dereferencing {
struct StateData {
/// Span of the top level expression
span: Span,
/// The required mutability
target_mut: Mutability,
}
enum State {
@ -140,9 +139,13 @@ enum State {
// The number of calls in a sequence which changed the referenced type
ty_changed_count: usize,
is_final_ufcs: bool,
/// The required mutability
target_mut: Mutability,
},
DerefedBorrow {
count: u32,
count: usize,
required_precedence: i8,
msg: &'static str,
},
}
@ -213,77 +216,98 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
1
},
is_final_ufcs: matches!(expr.kind, ExprKind::Call(..)),
},
StateData {
span: expr.span,
target_mut,
},
StateData { span: expr.span },
));
},
RefOp::AddrOf => {
// Find the number of times the borrow is auto-derefed.
let mut iter = find_adjustments(cx.tcx, typeck, expr).iter();
if let Some((i, adjust)) = iter.by_ref().enumerate().find_map(|(i, adjust)| {
if !matches!(adjust.kind, Adjust::Deref(_)) {
Some((i, Some(adjust)))
} else if !adjust.target.is_ref() {
// Include the current deref.
Some((i + 1, None))
} else {
None
}
}) {
if i > 1 {
// If the next adjustment is a mutable borrow, then check to see if the compiler will
// insert a re-borrow here. If not, leave an extra borrow here to avoid attempting to
// move the a mutable reference.
let (i, target_mut) = if let Some(&Adjust::Borrow(AutoBorrow::Ref(_, mutability))) =
adjust.or_else(|| iter.next()).map(|a| &a.kind)
{
if matches!(mutability, AutoBorrowMutability::Mut { .. })
&& !is_auto_reborrow_position(parent, expr.hir_id)
{
(i - 1, Mutability::Mut)
} else {
(i, mutability.into())
let mut deref_count = 0usize;
let next_adjust = loop {
match iter.next() {
Some(adjust) => {
if !matches!(adjust.kind, Adjust::Deref(_)) {
break Some(adjust);
} else if !adjust.target.is_ref() {
deref_count += 1;
break iter.next();
}
} else {
(
i,
iter.find_map(|adjust| match adjust.kind {
Adjust::Borrow(AutoBorrow::Ref(_, m)) => Some(m.into()),
_ => None,
})
// This default should never happen. Auto-deref always reborrows.
.unwrap_or(Mutability::Not),
)
};
deref_count += 1;
},
None => break None,
};
};
if i > 1 {
self.state = Some((
// Subtract one for the current borrow expression, and one to cover the last
// reference which can't be removed (it's either reborrowed, or needed for
// auto-deref to happen).
State::DerefedBorrow {
count:
// Truncation here would require more than a `u32::MAX` level reference. The compiler
// does not support this.
#[allow(clippy::cast_possible_truncation)]
{ i as u32 - 2 }
},
StateData {
span: expr.span,
target_mut,
},
));
}
// Determine the required number of references before any can be removed. In all cases the
// reference made by the current expression will be removed. After that there are four cases to
// handle.
//
// 1. Auto-borrow will trigger in the current position, so no further references are required.
// 2. Auto-deref ends at a reference, or the underlying type, so one extra needs to be left to
// handle the automatically inserted re-borrow.
// 3. Auto-deref hits a user-defined `Deref` impl, so at least one reference needs to exist to
// start auto-deref.
// 4. If the chain of non-user-defined derefs ends with a mutable re-borrow, and re-borrow
// adjustments will not be inserted automatically, then leave one further reference to avoid
// moving a mutable borrow.
// e.g.
// fn foo<T>(x: &mut Option<&mut T>, y: &mut T) {
// let x = match x {
// // Removing the borrow will cause `x` to be moved
// Some(x) => &mut *x,
// None => y
// };
// }
let deref_msg =
"this expression creates a reference which is immediately dereferenced by the compiler";
let borrow_msg = "this expression borrows a value the compiler would automatically borrow";
let (required_refs, required_precedence, msg) = if is_auto_borrow_position(parent, expr.hir_id)
{
(1, PREC_POSTFIX, if deref_count == 1 { borrow_msg } else { deref_msg })
} else if let Some(&Adjust::Borrow(AutoBorrow::Ref(_, mutability))) =
next_adjust.map(|a| &a.kind)
{
if matches!(mutability, AutoBorrowMutability::Mut { .. })
&& !is_auto_reborrow_position(parent)
{
(3, 0, deref_msg)
} else {
(2, 0, deref_msg)
}
} else {
(2, 0, deref_msg)
};
if deref_count >= required_refs {
self.state = Some((
State::DerefedBorrow {
// One of the required refs is for the current borrow expression, the remaining ones
// can't be removed without breaking the code. See earlier comment.
count: deref_count - required_refs,
required_precedence,
msg,
},
StateData { span: expr.span },
));
}
},
_ => (),
}
},
(Some((State::DerefMethod { ty_changed_count, .. }, data)), RefOp::Method(_)) => {
(
Some((
State::DerefMethod {
target_mut,
ty_changed_count,
..
},
data,
)),
RefOp::Method(_),
) => {
self.state = Some((
State::DerefMethod {
ty_changed_count: if deref_method_same_type(typeck.expr_ty(expr), typeck.expr_ty(sub_expr)) {
@ -292,12 +316,30 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing {
ty_changed_count + 1
},
is_final_ufcs: matches!(expr.kind, ExprKind::Call(..)),
target_mut,
},
data,
));
},
(Some((State::DerefedBorrow { count }, data)), RefOp::AddrOf) if count != 0 => {
self.state = Some((State::DerefedBorrow { count: count - 1 }, data));
(
Some((
State::DerefedBorrow {
count,
required_precedence,
msg,
},
data,
)),
RefOp::AddrOf,
) if count != 0 => {
self.state = Some((
State::DerefedBorrow {
count: count - 1,
required_precedence,
msg,
},
data,
));
},
(Some((state, data)), _) => report(cx, expr, state, data),
@ -475,18 +517,28 @@ fn is_linted_explicit_deref_position(parent: Option<Node<'_>>, child_id: HirId,
/// Checks if the given expression is in a position which can be auto-reborrowed.
/// Note: This is only correct assuming auto-deref is already occurring.
fn is_auto_reborrow_position(parent: Option<Node<'_>>, child_id: HirId) -> bool {
fn is_auto_reborrow_position(parent: Option<Node<'_>>) -> bool {
match parent {
Some(Node::Expr(parent)) => match parent.kind {
ExprKind::MethodCall(..) => true,
ExprKind::Call(callee, _) => callee.hir_id != child_id,
_ => false,
},
Some(Node::Expr(parent)) => matches!(parent.kind, ExprKind::MethodCall(..) | ExprKind::Call(..)),
Some(Node::Local(_)) => true,
_ => false,
}
}
/// Checks if the given expression is a position which can auto-borrow.
fn is_auto_borrow_position(parent: Option<Node<'_>>, child_id: HirId) -> bool {
if let Some(Node::Expr(parent)) = parent {
match parent.kind {
ExprKind::MethodCall(_, _, [self_arg, ..], _) => self_arg.hir_id == child_id,
ExprKind::Field(..) => true,
ExprKind::Call(f, _) => f.hir_id == child_id,
_ => false,
}
} else {
false
}
}
/// Adjustments are sometimes made in the parent block rather than the expression itself.
fn find_adjustments<'tcx>(
tcx: TyCtxt<'tcx>,
@ -535,6 +587,7 @@ fn report(cx: &LateContext<'_>, expr: &Expr<'_>, state: State, data: StateData)
State::DerefMethod {
ty_changed_count,
is_final_ufcs,
target_mut,
} => {
let mut app = Applicability::MachineApplicable;
let (expr_str, expr_is_macro_call) = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app);
@ -549,12 +602,12 @@ fn report(cx: &LateContext<'_>, expr: &Expr<'_>, state: State, data: StateData)
};
let addr_of_str = if ty_changed_count < ref_count {
// Check if a reborrow from &mut T -> &T is required.
if data.target_mut == Mutability::Not && matches!(ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
if target_mut == Mutability::Not && matches!(ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
"&*"
} else {
""
}
} else if data.target_mut == Mutability::Mut {
} else if target_mut == Mutability::Mut {
"&mut "
} else {
"&"
@ -570,7 +623,7 @@ fn report(cx: &LateContext<'_>, expr: &Expr<'_>, state: State, data: StateData)
cx,
EXPLICIT_DEREF_METHODS,
data.span,
match data.target_mut {
match target_mut {
Mutability::Not => "explicit `deref` method call",
Mutability::Mut => "explicit `deref_mut` method call",
},
@ -579,19 +632,24 @@ fn report(cx: &LateContext<'_>, expr: &Expr<'_>, state: State, data: StateData)
app,
);
},
State::DerefedBorrow { .. } => {
State::DerefedBorrow {
required_precedence,
msg,
..
} => {
let mut app = Applicability::MachineApplicable;
let snip = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app).0;
span_lint_and_sugg(
cx,
NEEDLESS_BORROW,
data.span,
&format!(
"this expression borrows a reference (`{}`) that is immediately dereferenced by the compiler",
cx.typeck_results().expr_ty(expr),
),
msg,
"change this to",
snip.into(),
if required_precedence > expr.precedence().order() && !has_enclosing_paren(&snip) {
format!("({})", snip)
} else {
snip.into()
},
app,
);
},

View file

@ -179,7 +179,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
)
.and_then(|snip| {
let i = snip.find("fn")?;
Some(item.span.lo() + BytePos((i + (&snip[i..]).find('(')?) as u32))
Some(item.span.lo() + BytePos((i + snip[i..].find('(')?) as u32))
})
.expect("failed to create span for type parameters");
Span::new(pos, pos, item.span.ctxt(), item.span.parent())

View file

@ -101,7 +101,7 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
// construct a replacement escape
// the maximum value is \077, or \x3f, so u8 is sufficient here
if let Ok(n) = u8::from_str_radix(&contents[from + 1..to], 8) {
write!(&mut suggest_1, "\\x{:02x}", n).unwrap();
write!(suggest_1, "\\x{:02x}", n).unwrap();
}
// append the null byte as \x00 and the following digits literally

View file

@ -388,7 +388,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String {
}
/// Return `true` if `sugg` is enclosed in parenthesis.
fn has_enclosing_paren(sugg: impl AsRef<str>) -> bool {
pub fn has_enclosing_paren(sugg: impl AsRef<str>) -> bool {
let mut chars = sugg.as_ref().chars();
if chars.next() == Some('(') {
let mut depth = 1;

View file

@ -1,3 +1,5 @@
#![allow(clippy::needless_borrow)]
#[deny(clippy::naive_bytecount)]
fn main() {
let x = vec![0_u8; 16];

View file

@ -1,23 +1,23 @@
error: you appear to be counting bytes the naive way
--> $DIR/bytecount.rs:5:13
--> $DIR/bytecount.rs:7:13
|
LL | let _ = x.iter().filter(|&&a| a == 0).count(); // naive byte count
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count(x, 0)`
|
note: the lint level is defined here
--> $DIR/bytecount.rs:1:8
--> $DIR/bytecount.rs:3:8
|
LL | #[deny(clippy::naive_bytecount)]
| ^^^^^^^^^^^^^^^^^^^^^^^
error: you appear to be counting bytes the naive way
--> $DIR/bytecount.rs:7:13
--> $DIR/bytecount.rs:9:13
|
LL | let _ = (&x[..]).iter().filter(|&a| *a == 0).count(); // naive byte count
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count((&x[..]), 0)`
error: you appear to be counting bytes the naive way
--> $DIR/bytecount.rs:19:13
--> $DIR/bytecount.rs:21:13
|
LL | let _ = x.iter().filter(|a| b + 1 == **a).count(); // naive byte count
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using the bytecount crate: `bytecount::count(x, b + 1)`

View file

@ -7,7 +7,8 @@
clippy::no_effect,
clippy::unnecessary_operation,
clippy::vec_init_then_push,
clippy::toplevel_ref_arg
clippy::toplevel_ref_arg,
clippy::needless_borrow
)]
use std::cell::RefCell;

View file

@ -7,7 +7,8 @@
clippy::no_effect,
clippy::unnecessary_operation,
clippy::vec_init_then_push,
clippy::toplevel_ref_arg
clippy::toplevel_ref_arg,
clippy::needless_borrow
)]
use std::cell::RefCell;

View file

@ -1,5 +1,5 @@
error: using `clone` on type `i32` which implements the `Copy` trait
--> $DIR/clone_on_copy.rs:24:5
--> $DIR/clone_on_copy.rs:25:5
|
LL | 42.clone();
| ^^^^^^^^^^ help: try removing the `clone` call: `42`
@ -7,43 +7,43 @@ LL | 42.clone();
= note: `-D clippy::clone-on-copy` implied by `-D warnings`
error: using `clone` on type `i32` which implements the `Copy` trait
--> $DIR/clone_on_copy.rs:28:5
--> $DIR/clone_on_copy.rs:29:5
|
LL | (&42).clone();
| ^^^^^^^^^^^^^ help: try dereferencing it: `*(&42)`
error: using `clone` on type `i32` which implements the `Copy` trait
--> $DIR/clone_on_copy.rs:31:5
--> $DIR/clone_on_copy.rs:32:5
|
LL | rc.borrow().clone();
| ^^^^^^^^^^^^^^^^^^^ help: try dereferencing it: `*rc.borrow()`
error: using `clone` on type `u32` which implements the `Copy` trait
--> $DIR/clone_on_copy.rs:34:5
--> $DIR/clone_on_copy.rs:35:5
|
LL | x.clone().rotate_left(1);
| ^^^^^^^^^ help: try removing the `clone` call: `x`
error: using `clone` on type `i32` which implements the `Copy` trait
--> $DIR/clone_on_copy.rs:48:5
--> $DIR/clone_on_copy.rs:49:5
|
LL | m!(42).clone();
| ^^^^^^^^^^^^^^ help: try removing the `clone` call: `m!(42)`
error: using `clone` on type `[u32; 2]` which implements the `Copy` trait
--> $DIR/clone_on_copy.rs:58:5
--> $DIR/clone_on_copy.rs:59:5
|
LL | x.clone()[0];
| ^^^^^^^^^ help: try dereferencing it: `(*x)`
error: using `clone` on type `char` which implements the `Copy` trait
--> $DIR/clone_on_copy.rs:68:14
--> $DIR/clone_on_copy.rs:69:14
|
LL | is_ascii('z'.clone());
| ^^^^^^^^^^^ help: try removing the `clone` call: `'z'`
error: using `clone` on type `i32` which implements the `Copy` trait
--> $DIR/clone_on_copy.rs:72:14
--> $DIR/clone_on_copy.rs:73:14
|
LL | vec.push(42.clone());
| ^^^^^^^^^^ help: try removing the `clone` call: `42`

View file

@ -1,5 +1,5 @@
// run-rustfix
#![allow(dead_code)]
#![allow(dead_code, clippy::needless_borrow)]
#![warn(clippy::duration_subsec)]
use std::time::Duration;

View file

@ -1,5 +1,5 @@
// run-rustfix
#![allow(dead_code)]
#![allow(dead_code, clippy::needless_borrow)]
#![warn(clippy::duration_subsec)]
use std::time::Duration;

View file

@ -5,13 +5,10 @@
clippy::no_effect,
clippy::redundant_closure_call,
clippy::needless_pass_by_value,
clippy::option_map_unit_fn
)]
#![warn(
clippy::redundant_closure,
clippy::redundant_closure_for_method_calls,
clippy::option_map_unit_fn,
clippy::needless_borrow
)]
#![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
use std::path::{Path, PathBuf};
@ -34,7 +31,7 @@ fn main() {
Some(1).map(closure_mac!()); // don't lint closure in macro expansion
let _: Option<Vec<u8>> = true.then(std::vec::Vec::new); // special case vec!
let d = Some(1u8).map(|a| foo(foo2(a))); //is adjusted?
all(&[1, 2, 3], &2, below); //is adjusted
all(&[1, 2, 3], &&2, below); //is adjusted
unsafe {
Some(1u8).map(|a| unsafe_fn(a)); // unsafe fn
}

View file

@ -5,13 +5,10 @@
clippy::no_effect,
clippy::redundant_closure_call,
clippy::needless_pass_by_value,
clippy::option_map_unit_fn
)]
#![warn(
clippy::redundant_closure,
clippy::redundant_closure_for_method_calls,
clippy::option_map_unit_fn,
clippy::needless_borrow
)]
#![warn(clippy::redundant_closure, clippy::redundant_closure_for_method_calls)]
use std::path::{Path, PathBuf};

View file

@ -1,5 +1,5 @@
error: redundant closure
--> $DIR/eta.rs:31:27
--> $DIR/eta.rs:28:27
|
LL | let a = Some(1u8).map(|a| foo(a));
| ^^^^^^^^^^ help: replace the closure with the function itself: `foo`
@ -7,45 +7,37 @@ LL | let a = Some(1u8).map(|a| foo(a));
= note: `-D clippy::redundant-closure` implied by `-D warnings`
error: redundant closure
--> $DIR/eta.rs:35:40
--> $DIR/eta.rs:32:40
|
LL | let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!
| ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new`
error: redundant closure
--> $DIR/eta.rs:36:35
--> $DIR/eta.rs:33:35
|
LL | let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
| ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2`
error: this expression borrows a reference (`&u8`) that is immediately dereferenced by the compiler
--> $DIR/eta.rs:37:21
|
LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
| ^^^ help: change this to: `&2`
|
= note: `-D clippy::needless-borrow` implied by `-D warnings`
error: redundant closure
--> $DIR/eta.rs:37:26
--> $DIR/eta.rs:34:26
|
LL | all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
| ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
error: redundant closure
--> $DIR/eta.rs:43:27
--> $DIR/eta.rs:40:27
|
LL | let e = Some(1u8).map(|a| divergent(a));
| ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `divergent`
error: redundant closure
--> $DIR/eta.rs:44:27
--> $DIR/eta.rs:41:27
|
LL | let e = Some(1u8).map(|a| generic(a));
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
error: redundant closure
--> $DIR/eta.rs:90:51
--> $DIR/eta.rs:87:51
|
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
| ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
@ -53,82 +45,82 @@ LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
= note: `-D clippy::redundant-closure-for-method-calls` implied by `-D warnings`
error: redundant closure
--> $DIR/eta.rs:91:51
--> $DIR/eta.rs:88:51
|
LL | let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
error: redundant closure
--> $DIR/eta.rs:93:42
--> $DIR/eta.rs:90:42
|
LL | let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
| ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
error: redundant closure
--> $DIR/eta.rs:97:29
--> $DIR/eta.rs:94:29
|
LL | let e = Some("str").map(|s| s.to_string());
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
error: redundant closure
--> $DIR/eta.rs:98:27
--> $DIR/eta.rs:95:27
|
LL | let e = Some('a').map(|s| s.to_uppercase());
| ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
error: redundant closure
--> $DIR/eta.rs:100:65
--> $DIR/eta.rs:97:65
|
LL | let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
error: redundant closure
--> $DIR/eta.rs:163:22
--> $DIR/eta.rs:160:22
|
LL | requires_fn_once(|| x());
| ^^^^^^ help: replace the closure with the function itself: `x`
error: redundant closure
--> $DIR/eta.rs:170:27
--> $DIR/eta.rs:167:27
|
LL | let a = Some(1u8).map(|a| foo_ptr(a));
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
error: redundant closure
--> $DIR/eta.rs:175:27
--> $DIR/eta.rs:172:27
|
LL | let a = Some(1u8).map(|a| closure(a));
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
error: redundant closure
--> $DIR/eta.rs:207:28
--> $DIR/eta.rs:204:28
|
LL | x.into_iter().for_each(|x| add_to_res(x));
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
error: redundant closure
--> $DIR/eta.rs:208:28
--> $DIR/eta.rs:205:28
|
LL | y.into_iter().for_each(|x| add_to_res(x));
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
error: redundant closure
--> $DIR/eta.rs:209:28
--> $DIR/eta.rs:206:28
|
LL | z.into_iter().for_each(|x| add_to_res(x));
| ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
error: redundant closure
--> $DIR/eta.rs:216:21
--> $DIR/eta.rs:213:21
|
LL | Some(1).map(|n| closure(n));
| ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
error: redundant closure
--> $DIR/eta.rs:235:21
--> $DIR/eta.rs:232:21
|
LL | map_str_to_path(|s| s.as_ref());
| ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::convert::AsRef::as_ref`
error: aborting due to 21 previous errors
error: aborting due to 20 previous errors

View file

@ -23,7 +23,12 @@ impl Unrelated {
clippy::iter_next_loop,
clippy::for_kv_map
)]
#[allow(clippy::linkedlist, clippy::unnecessary_mut_passed, clippy::similar_names)]
#[allow(
clippy::linkedlist,
clippy::unnecessary_mut_passed,
clippy::similar_names,
clippy::needless_borrow
)]
#[allow(unused_variables)]
fn main() {
let mut vec = vec![1, 2, 3, 4];

View file

@ -23,7 +23,12 @@ impl Unrelated {
clippy::iter_next_loop,
clippy::for_kv_map
)]
#[allow(clippy::linkedlist, clippy::unnecessary_mut_passed, clippy::similar_names)]
#[allow(
clippy::linkedlist,
clippy::unnecessary_mut_passed,
clippy::similar_names,
clippy::needless_borrow
)]
#[allow(unused_variables)]
fn main() {
let mut vec = vec![1, 2, 3, 4];

View file

@ -1,5 +1,5 @@
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:38:15
--> $DIR/for_loop_fixable.rs:43:15
|
LL | for _v in vec.iter() {}
| ^^^^^^^^^^ help: to write this more concisely, try: `&vec`
@ -7,13 +7,13 @@ LL | for _v in vec.iter() {}
= note: `-D clippy::explicit-iter-loop` implied by `-D warnings`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:40:15
--> $DIR/for_loop_fixable.rs:45:15
|
LL | for _v in vec.iter_mut() {}
| ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut vec`
error: it is more concise to loop over containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:43:15
--> $DIR/for_loop_fixable.rs:48:15
|
LL | for _v in out_vec.into_iter() {}
| ^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `out_vec`
@ -21,73 +21,73 @@ LL | for _v in out_vec.into_iter() {}
= note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:48:15
--> $DIR/for_loop_fixable.rs:53:15
|
LL | for _v in [1, 2, 3].iter() {}
| ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:52:15
--> $DIR/for_loop_fixable.rs:57:15
|
LL | for _v in [0; 32].iter() {}
| ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 32]`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:57:15
--> $DIR/for_loop_fixable.rs:62:15
|
LL | for _v in ll.iter() {}
| ^^^^^^^^^ help: to write this more concisely, try: `&ll`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:60:15
--> $DIR/for_loop_fixable.rs:65:15
|
LL | for _v in vd.iter() {}
| ^^^^^^^^^ help: to write this more concisely, try: `&vd`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:63:15
--> $DIR/for_loop_fixable.rs:68:15
|
LL | for _v in bh.iter() {}
| ^^^^^^^^^ help: to write this more concisely, try: `&bh`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:66:15
--> $DIR/for_loop_fixable.rs:71:15
|
LL | for _v in hm.iter() {}
| ^^^^^^^^^ help: to write this more concisely, try: `&hm`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:69:15
--> $DIR/for_loop_fixable.rs:74:15
|
LL | for _v in bt.iter() {}
| ^^^^^^^^^ help: to write this more concisely, try: `&bt`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:72:15
--> $DIR/for_loop_fixable.rs:77:15
|
LL | for _v in hs.iter() {}
| ^^^^^^^^^ help: to write this more concisely, try: `&hs`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:75:15
--> $DIR/for_loop_fixable.rs:80:15
|
LL | for _v in bs.iter() {}
| ^^^^^^^^^ help: to write this more concisely, try: `&bs`
error: it is more concise to loop over containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:250:18
--> $DIR/for_loop_fixable.rs:255:18
|
LL | for i in iterator.into_iter() {
| ^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `iterator`
error: it is more concise to loop over references to containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:270:18
--> $DIR/for_loop_fixable.rs:275:18
|
LL | for _ in t.into_iter() {}
| ^^^^^^^^^^^^^ help: to write this more concisely, try: `&t`
error: it is more concise to loop over containers instead of using explicit iteration methods
--> $DIR/for_loop_fixable.rs:272:18
--> $DIR/for_loop_fixable.rs:277:18
|
LL | for _ in r.into_iter() {}
| ^^^^^^^^^^^^^ help: to write this more concisely, try: `r`

View file

@ -62,6 +62,16 @@ fn main() {
};
*x = 5;
let s = String::new();
let _ = s.len();
let _ = s.capacity();
let _ = s.capacity();
let x = (1, 2);
let _ = x.0;
let x = &x as *const (i32, i32);
let _ = unsafe { (*x).0 };
}
#[allow(clippy::needless_borrowed_reference)]

View file

@ -62,6 +62,16 @@ fn main() {
};
*x = 5;
let s = String::new();
let _ = (&s).len();
let _ = (&s).capacity();
let _ = (&&s).capacity();
let x = (1, 2);
let _ = (&x).0;
let x = &x as *const (i32, i32);
let _ = unsafe { (&*x).0 };
}
#[allow(clippy::needless_borrowed_reference)]

View file

@ -1,4 +1,18 @@
error: this expression borrows a reference (`&i32`) that is immediately dereferenced by the compiler
error: creating a reference that is immediately dereferenced
--> $DIR/needless_borrow.rs:72:13
|
LL | let _ = (&x).0;
| ^^^^ help: try this: `x`
|
= note: `-D clippy::ref-in-deref` implied by `-D warnings`
error: creating a reference that is immediately dereferenced
--> $DIR/needless_borrow.rs:74:22
|
LL | let _ = unsafe { (&*x).0 };
| ^^^^^ help: try this: `(*x)`
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:9:15
|
LL | let _ = x(&&a); // warn
@ -6,83 +20,113 @@ LL | let _ = x(&&a); // warn
|
= note: `-D clippy::needless-borrow` implied by `-D warnings`
error: this expression borrows a reference (`&mut i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:13:13
|
LL | mut_ref(&mut &mut b); // warn
| ^^^^^^^^^^^ help: change this to: `&mut b`
error: this expression borrows a reference (`&i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:25:13
|
LL | &&a
| ^^^ help: change this to: `&a`
error: this expression borrows a reference (`&i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:27:15
|
LL | 46 => &&a,
| ^^^ help: change this to: `&a`
error: this expression borrows a reference (`&i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:33:27
|
LL | break &ref_a;
| ^^^^^^ help: change this to: `ref_a`
error: this expression borrows a reference (`&i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:40:15
|
LL | let _ = x(&&&a);
| ^^^^ help: change this to: `&a`
error: this expression borrows a reference (`&i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:41:15
|
LL | let _ = x(&mut &&a);
| ^^^^^^^^ help: change this to: `&a`
error: this expression borrows a reference (`&mut i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:42:15
|
LL | let _ = x(&&&mut b);
| ^^^^^^^^ help: change this to: `&mut b`
error: this expression borrows a reference (`&i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:43:15
|
LL | let _ = x(&&ref_a);
| ^^^^^^^ help: change this to: `ref_a`
error: this expression borrows a reference (`&mut i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:46:11
|
LL | x(&b);
| ^^ help: change this to: `b`
error: this expression borrows a reference (`&mut i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:53:13
|
LL | mut_ref(&mut x);
| ^^^^^^ help: change this to: `x`
error: this expression borrows a reference (`&mut i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:54:13
|
LL | mut_ref(&mut &mut x);
| ^^^^^^^^^^^ help: change this to: `x`
error: this expression borrows a reference (`&mut i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:55:23
|
LL | let y: &mut i32 = &mut x;
| ^^^^^^ help: change this to: `x`
error: this expression borrows a reference (`&mut i32`) that is immediately dereferenced by the compiler
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:56:23
|
LL | let y: &mut i32 = &mut &mut x;
| ^^^^^^^^^^^ help: change this to: `x`
error: aborting due to 14 previous errors
error: this expression borrows a value the compiler would automatically borrow
--> $DIR/needless_borrow.rs:67:13
|
LL | let _ = (&s).len();
| ^^^^ help: change this to: `s`
error: this expression borrows a value the compiler would automatically borrow
--> $DIR/needless_borrow.rs:68:13
|
LL | let _ = (&s).capacity();
| ^^^^ help: change this to: `s`
error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:69:13
|
LL | let _ = (&&s).capacity();
| ^^^^^ help: change this to: `s`
error: this expression borrows a value the compiler would automatically borrow
--> $DIR/needless_borrow.rs:72:13
|
LL | let _ = (&x).0;
| ^^^^ help: change this to: `x`
error: this expression borrows a value the compiler would automatically borrow
--> $DIR/needless_borrow.rs:74:22
|
LL | let _ = unsafe { (&*x).0 };
| ^^^^^ help: change this to: `(*x)`
error: aborting due to 21 previous errors

View file

@ -67,7 +67,7 @@ fn not_ok() {
foo_rslice(mrrrrrslice);
foo_rslice(mrrrrrslice);
}
#[allow(unused_parens, clippy::double_parens)]
#[allow(unused_parens, clippy::double_parens, clippy::needless_borrow)]
foo_rrrrmr((&&&&MoreRef));
generic_not_ok(mrslice);

View file

@ -67,7 +67,7 @@ fn not_ok() {
foo_rslice(mrrrrrslice.as_ref());
foo_rslice(mrrrrrslice);
}
#[allow(unused_parens, clippy::double_parens)]
#[allow(unused_parens, clippy::double_parens, clippy::needless_borrow)]
foo_rrrrmr((&&&&MoreRef).as_ref());
generic_not_ok(mrslice);

View file

@ -7,37 +7,37 @@ fn main() {
let mut v = Vec::new();
// these should be fine
write!(&mut v, "Hello");
writeln!(&mut v, "Hello");
write!(v, "Hello");
writeln!(v, "Hello");
let world = "world";
writeln!(&mut v, "Hello {}", world);
writeln!(&mut v, "Hello {world}", world = world);
writeln!(&mut v, "3 in hex is {:X}", 3);
writeln!(&mut v, "2 + 1 = {:.4}", 3);
writeln!(&mut v, "2 + 1 = {:5.4}", 3);
writeln!(&mut v, "Debug test {:?}", "hello, world");
writeln!(&mut v, "{0:8} {1:>8}", "hello", "world");
writeln!(&mut v, "{1:8} {0:>8}", "hello", "world");
writeln!(&mut v, "{foo:8} {bar:>8}", foo = "hello", bar = "world");
writeln!(&mut v, "{bar:8} {foo:>8}", foo = "hello", bar = "world");
writeln!(&mut v, "{number:>width$}", number = 1, width = 6);
writeln!(&mut v, "{number:>0width$}", number = 1, width = 6);
writeln!(&mut v, "{} of {:b} people know binary, the other half doesn't", 1, 2);
writeln!(&mut v, "10 / 4 is {}", 2.5);
writeln!(&mut v, "2 + 1 = {}", 3);
writeln!(v, "Hello {}", world);
writeln!(v, "Hello {world}", world = world);
writeln!(v, "3 in hex is {:X}", 3);
writeln!(v, "2 + 1 = {:.4}", 3);
writeln!(v, "2 + 1 = {:5.4}", 3);
writeln!(v, "Debug test {:?}", "hello, world");
writeln!(v, "{0:8} {1:>8}", "hello", "world");
writeln!(v, "{1:8} {0:>8}", "hello", "world");
writeln!(v, "{foo:8} {bar:>8}", foo = "hello", bar = "world");
writeln!(v, "{bar:8} {foo:>8}", foo = "hello", bar = "world");
writeln!(v, "{number:>width$}", number = 1, width = 6);
writeln!(v, "{number:>0width$}", number = 1, width = 6);
writeln!(v, "{} of {:b} people know binary, the other half doesn't", 1, 2);
writeln!(v, "10 / 4 is {}", 2.5);
writeln!(v, "2 + 1 = {}", 3);
// these should throw warnings
write!(&mut v, "Hello {}", "world");
writeln!(&mut v, "Hello {} {}", world, "world");
writeln!(&mut v, "Hello {}", "world");
write!(v, "Hello {}", "world");
writeln!(v, "Hello {} {}", world, "world");
writeln!(v, "Hello {}", "world");
// positional args don't change the fact
// that we're using a literal -- this should
// throw a warning
writeln!(&mut v, "{0} {1}", "hello", "world");
writeln!(&mut v, "{1} {0}", "hello", "world");
writeln!(v, "{0} {1}", "hello", "world");
writeln!(v, "{1} {0}", "hello", "world");
// named args shouldn't change anything either
writeln!(&mut v, "{foo} {bar}", foo = "hello", bar = "world");
writeln!(&mut v, "{bar} {foo}", foo = "hello", bar = "world");
writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
}

View file

@ -1,134 +1,134 @@
error: literal with an empty format string
--> $DIR/write_literal.rs:30:32
--> $DIR/write_literal.rs:30:27
|
LL | write!(&mut v, "Hello {}", "world");
| ^^^^^^^
LL | write!(v, "Hello {}", "world");
| ^^^^^^^
|
= note: `-D clippy::write-literal` implied by `-D warnings`
help: try this
|
LL - write!(&mut v, "Hello {}", "world");
LL + write!(&mut v, "Hello world");
LL - write!(v, "Hello {}", "world");
LL + write!(v, "Hello world");
|
error: literal with an empty format string
--> $DIR/write_literal.rs:31:44
--> $DIR/write_literal.rs:31:39
|
LL | writeln!(&mut v, "Hello {} {}", world, "world");
| ^^^^^^^
LL | writeln!(v, "Hello {} {}", world, "world");
| ^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "Hello {} {}", world, "world");
LL + writeln!(&mut v, "Hello {} world", world);
LL - writeln!(v, "Hello {} {}", world, "world");
LL + writeln!(v, "Hello {} world", world);
|
error: literal with an empty format string
--> $DIR/write_literal.rs:32:34
--> $DIR/write_literal.rs:32:29
|
LL | writeln!(&mut v, "Hello {}", "world");
| ^^^^^^^
LL | writeln!(v, "Hello {}", "world");
| ^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "Hello {}", "world");
LL + writeln!(&mut v, "Hello world");
LL - writeln!(v, "Hello {}", "world");
LL + writeln!(v, "Hello world");
|
error: literal with an empty format string
--> $DIR/write_literal.rs:37:33
--> $DIR/write_literal.rs:37:28
|
LL | writeln!(&mut v, "{0} {1}", "hello", "world");
| ^^^^^^^
LL | writeln!(v, "{0} {1}", "hello", "world");
| ^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "{0} {1}", "hello", "world");
LL + writeln!(&mut v, "hello {1}", "world");
LL - writeln!(v, "{0} {1}", "hello", "world");
LL + writeln!(v, "hello {1}", "world");
|
error: literal with an empty format string
--> $DIR/write_literal.rs:37:42
--> $DIR/write_literal.rs:37:37
|
LL | writeln!(&mut v, "{0} {1}", "hello", "world");
| ^^^^^^^
LL | writeln!(v, "{0} {1}", "hello", "world");
| ^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "{0} {1}", "hello", "world");
LL + writeln!(&mut v, "{0} world", "hello");
LL - writeln!(v, "{0} {1}", "hello", "world");
LL + writeln!(v, "{0} world", "hello");
|
error: literal with an empty format string
--> $DIR/write_literal.rs:38:33
--> $DIR/write_literal.rs:38:28
|
LL | writeln!(&mut v, "{1} {0}", "hello", "world");
| ^^^^^^^
LL | writeln!(v, "{1} {0}", "hello", "world");
| ^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "{1} {0}", "hello", "world");
LL + writeln!(&mut v, "{1} hello", "world");
LL - writeln!(v, "{1} {0}", "hello", "world");
LL + writeln!(v, "{1} hello", "world");
|
error: literal with an empty format string
--> $DIR/write_literal.rs:38:42
--> $DIR/write_literal.rs:38:37
|
LL | writeln!(&mut v, "{1} {0}", "hello", "world");
| ^^^^^^^
LL | writeln!(v, "{1} {0}", "hello", "world");
| ^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "{1} {0}", "hello", "world");
LL + writeln!(&mut v, "world {0}", "hello");
LL - writeln!(v, "{1} {0}", "hello", "world");
LL + writeln!(v, "world {0}", "hello");
|
error: literal with an empty format string
--> $DIR/write_literal.rs:41:37
--> $DIR/write_literal.rs:41:32
|
LL | writeln!(&mut v, "{foo} {bar}", foo = "hello", bar = "world");
| ^^^^^^^^^^^^^
LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
| ^^^^^^^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "{foo} {bar}", foo = "hello", bar = "world");
LL + writeln!(&mut v, "hello {bar}", bar = "world");
LL - writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
LL + writeln!(v, "hello {bar}", bar = "world");
|
error: literal with an empty format string
--> $DIR/write_literal.rs:41:52
--> $DIR/write_literal.rs:41:47
|
LL | writeln!(&mut v, "{foo} {bar}", foo = "hello", bar = "world");
| ^^^^^^^^^^^^^
LL | writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
| ^^^^^^^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "{foo} {bar}", foo = "hello", bar = "world");
LL + writeln!(&mut v, "{foo} world", foo = "hello");
LL - writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
LL + writeln!(v, "{foo} world", foo = "hello");
|
error: literal with an empty format string
--> $DIR/write_literal.rs:42:37
--> $DIR/write_literal.rs:42:32
|
LL | writeln!(&mut v, "{bar} {foo}", foo = "hello", bar = "world");
| ^^^^^^^^^^^^^
LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
| ^^^^^^^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "{bar} {foo}", foo = "hello", bar = "world");
LL + writeln!(&mut v, "{bar} hello", bar = "world");
LL - writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
LL + writeln!(v, "{bar} hello", bar = "world");
|
error: literal with an empty format string
--> $DIR/write_literal.rs:42:52
--> $DIR/write_literal.rs:42:47
|
LL | writeln!(&mut v, "{bar} {foo}", foo = "hello", bar = "world");
| ^^^^^^^^^^^^^
LL | writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
| ^^^^^^^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, "{bar} {foo}", foo = "hello", bar = "world");
LL + writeln!(&mut v, "world {foo}", foo = "hello");
LL - writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
LL + writeln!(v, "world {foo}", foo = "hello");
|
error: aborting due to 11 previous errors

View file

@ -6,20 +6,20 @@ use std::io::Write;
fn main() {
let mut v = Vec::new();
writeln!(&mut v, "{}", "{hello}");
writeln!(&mut v, r"{}", r"{hello}");
writeln!(&mut v, "{}", '\'');
writeln!(&mut v, "{}", '"');
writeln!(&mut v, r"{}", '"'); // don't lint
writeln!(&mut v, r"{}", '\'');
writeln!(v, "{}", "{hello}");
writeln!(v, r"{}", r"{hello}");
writeln!(v, "{}", '\'');
writeln!(v, "{}", '"');
writeln!(v, r"{}", '"'); // don't lint
writeln!(v, r"{}", '\'');
writeln!(
&mut v,
v,
"some {}",
"hello \
world!"
);
writeln!(
&mut v,
v,
"some {}\
{} \\ {}",
"1", "2", "3",

View file

@ -1,62 +1,62 @@
error: literal with an empty format string
--> $DIR/write_literal_2.rs:9:28
--> $DIR/write_literal_2.rs:9:23
|
LL | writeln!(&mut v, "{}", "{hello}");
| ^^^^^^^^^
LL | writeln!(v, "{}", "{hello}");
| ^^^^^^^^^
|
= note: `-D clippy::write-literal` implied by `-D warnings`
help: try this
|
LL - writeln!(&mut v, "{}", "{hello}");
LL + writeln!(&mut v, "{{hello}}");
LL - writeln!(v, "{}", "{hello}");
LL + writeln!(v, "{{hello}}");
|
error: literal with an empty format string
--> $DIR/write_literal_2.rs:10:29
--> $DIR/write_literal_2.rs:10:24
|
LL | writeln!(&mut v, r"{}", r"{hello}");
| ^^^^^^^^^^
LL | writeln!(v, r"{}", r"{hello}");
| ^^^^^^^^^^
|
help: try this
|
LL - writeln!(&mut v, r"{}", r"{hello}");
LL + writeln!(&mut v, r"{{hello}}");
LL - writeln!(v, r"{}", r"{hello}");
LL + writeln!(v, r"{{hello}}");
|
error: literal with an empty format string
--> $DIR/write_literal_2.rs:11:28
--> $DIR/write_literal_2.rs:11:23
|
LL | writeln!(&mut v, "{}", '/'');
| ^^^^
LL | writeln!(v, "{}", '/'');
| ^^^^
|
help: try this
|
LL - writeln!(&mut v, "{}", '/'');
LL + writeln!(&mut v, "'");
LL - writeln!(v, "{}", '/'');
LL + writeln!(v, "'");
|
error: literal with an empty format string
--> $DIR/write_literal_2.rs:12:28
--> $DIR/write_literal_2.rs:12:23
|
LL | writeln!(&mut v, "{}", '"');
| ^^^
LL | writeln!(v, "{}", '"');
| ^^^
|
help: try this
|
LL - writeln!(&mut v, "{}", '"');
LL + writeln!(&mut v, "/"");
LL - writeln!(v, "{}", '"');
LL + writeln!(v, "/"");
|
error: literal with an empty format string
--> $DIR/write_literal_2.rs:14:29
--> $DIR/write_literal_2.rs:14:24
|
LL | writeln!(&mut v, r"{}", '/'');
| ^^^^
LL | writeln!(v, r"{}", '/'');
| ^^^^
|
help: try this
|
LL - writeln!(&mut v, r"{}", '/'');
LL + writeln!(&mut v, r"'");
LL - writeln!(v, r"{}", '/'');
LL + writeln!(v, r"'");
|
error: literal with an empty format string

View file

@ -10,50 +10,50 @@ fn main() {
let mut v = Vec::new();
// These should fail
write!(&mut v, "Hello\n");
write!(&mut v, "Hello {}\n", "world");
write!(&mut v, "Hello {} {}\n", "world", "#2");
write!(&mut v, "{}\n", 1265);
write!(&mut v, "\n");
write!(v, "Hello\n");
write!(v, "Hello {}\n", "world");
write!(v, "Hello {} {}\n", "world", "#2");
write!(v, "{}\n", 1265);
write!(v, "\n");
// These should be fine
write!(&mut v, "");
write!(&mut v, "Hello");
writeln!(&mut v, "Hello");
writeln!(&mut v, "Hello\n");
writeln!(&mut v, "Hello {}\n", "world");
write!(&mut v, "Issue\n{}", 1265);
write!(&mut v, "{}", 1265);
write!(&mut v, "\n{}", 1275);
write!(&mut v, "\n\n");
write!(&mut v, "like eof\n\n");
write!(&mut v, "Hello {} {}\n\n", "world", "#2");
writeln!(&mut v, "\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126
writeln!(&mut v, "\nbla\n\n"); // #3126
write!(v, "");
write!(v, "Hello");
writeln!(v, "Hello");
writeln!(v, "Hello\n");
writeln!(v, "Hello {}\n", "world");
write!(v, "Issue\n{}", 1265);
write!(v, "{}", 1265);
write!(v, "\n{}", 1275);
write!(v, "\n\n");
write!(v, "like eof\n\n");
write!(v, "Hello {} {}\n\n", "world", "#2");
writeln!(v, "\ndon't\nwarn\nfor\nmultiple\nnewlines\n"); // #3126
writeln!(v, "\nbla\n\n"); // #3126
// Escaping
write!(&mut v, "\\n"); // #3514
write!(&mut v, "\\\n"); // should fail
write!(&mut v, "\\\\n");
write!(v, "\\n"); // #3514
write!(v, "\\\n"); // should fail
write!(v, "\\\\n");
// Raw strings
write!(&mut v, r"\n"); // #3778
write!(v, r"\n"); // #3778
// Literal newlines should also fail
write!(
&mut v,
v,
"
"
);
write!(
&mut v,
v,
r"
"
);
// Don't warn on CRLF (#4208)
write!(&mut v, "\r\n");
write!(&mut v, "foo\r\n");
write!(&mut v, "\\r\n"); //~ ERROR
write!(&mut v, "foo\rbar\n");
write!(v, "\r\n");
write!(v, "foo\r\n");
write!(v, "\\r\n"); //~ ERROR
write!(v, "foo\rbar\n");
}

View file

@ -1,81 +1,81 @@
error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:13:5
|
LL | write!(&mut v, "Hello/n");
| ^^^^^^^^^^^^^^^^^^^^^^^^^
LL | write!(v, "Hello/n");
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::write-with-newline` implied by `-D warnings`
help: use `writeln!()` instead
|
LL - write!(&mut v, "Hello/n");
LL + writeln!(&mut v, "Hello");
LL - write!(v, "Hello/n");
LL + writeln!(v, "Hello");
|
error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:14:5
|
LL | write!(&mut v, "Hello {}/n", "world");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | write!(v, "Hello {}/n", "world");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `writeln!()` instead
|
LL - write!(&mut v, "Hello {}/n", "world");
LL + writeln!(&mut v, "Hello {}", "world");
LL - write!(v, "Hello {}/n", "world");
LL + writeln!(v, "Hello {}", "world");
|
error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:15:5
|
LL | write!(&mut v, "Hello {} {}/n", "world", "#2");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | write!(v, "Hello {} {}/n", "world", "#2");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `writeln!()` instead
|
LL - write!(&mut v, "Hello {} {}/n", "world", "#2");
LL + writeln!(&mut v, "Hello {} {}", "world", "#2");
LL - write!(v, "Hello {} {}/n", "world", "#2");
LL + writeln!(v, "Hello {} {}", "world", "#2");
|
error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:16:5
|
LL | write!(&mut v, "{}/n", 1265);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | write!(v, "{}/n", 1265);
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `writeln!()` instead
|
LL - write!(&mut v, "{}/n", 1265);
LL + writeln!(&mut v, "{}", 1265);
LL - write!(v, "{}/n", 1265);
LL + writeln!(v, "{}", 1265);
|
error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:17:5
|
LL | write!(&mut v, "/n");
| ^^^^^^^^^^^^^^^^^^^^
LL | write!(v, "/n");
| ^^^^^^^^^^^^^^^
|
help: use `writeln!()` instead
|
LL - write!(&mut v, "/n");
LL + writeln!(&mut v);
LL - write!(v, "/n");
LL + writeln!(v);
|
error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:36:5
|
LL | write!(&mut v, "//n"); // should fail
| ^^^^^^^^^^^^^^^^^^^^^^
LL | write!(v, "//n"); // should fail
| ^^^^^^^^^^^^^^^^^
|
help: use `writeln!()` instead
|
LL - write!(&mut v, "//n"); // should fail
LL + writeln!(&mut v, "/"); // should fail
LL - write!(v, "//n"); // should fail
LL + writeln!(v, "/"); // should fail
|
error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:43:5
|
LL | / write!(
LL | | &mut v,
LL | | v,
LL | | "
LL | | "
LL | | );
@ -84,7 +84,7 @@ LL | | );
help: use `writeln!()` instead
|
LL ~ writeln!(
LL | &mut v,
LL | v,
LL ~ ""
|
@ -92,7 +92,7 @@ error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:48:5
|
LL | / write!(
LL | | &mut v,
LL | | v,
LL | | r"
LL | | "
LL | | );
@ -101,32 +101,32 @@ LL | | );
help: use `writeln!()` instead
|
LL ~ writeln!(
LL | &mut v,
LL | v,
LL ~ r""
|
error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:57:5
|
LL | write!(&mut v, "/r/n"); //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^
LL | write!(v, "/r/n"); //~ ERROR
| ^^^^^^^^^^^^^^^^^^
|
help: use `writeln!()` instead
|
LL - write!(&mut v, "/r/n"); //~ ERROR
LL + writeln!(&mut v, "/r"); //~ ERROR
LL - write!(v, "/r/n"); //~ ERROR
LL + writeln!(v, "/r"); //~ ERROR
|
error: using `write!()` with a format string that ends in a single newline
--> $DIR/write_with_newline.rs:58:5
|
LL | write!(&mut v, "foo/rbar/n");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | write!(v, "foo/rbar/n");
| ^^^^^^^^^^^^^^^^^^^^^^^
|
help: use `writeln!()` instead
|
LL - write!(&mut v, "foo/rbar/n");
LL + writeln!(&mut v, "foo/rbar");
LL - write!(v, "foo/rbar/n");
LL + writeln!(v, "foo/rbar");
|
error: aborting due to 10 previous errors

View file

@ -8,13 +8,13 @@ fn main() {
let mut v = Vec::new();
// These should fail
writeln!(&mut v);
writeln!(v);
let mut suggestion = Vec::new();
writeln!(&mut suggestion);
writeln!(suggestion);
// These should be fine
writeln!(&mut v);
writeln!(&mut v, " ");
write!(&mut v, "");
writeln!(v);
writeln!(v, " ");
write!(v, "");
}

View file

@ -8,13 +8,13 @@ fn main() {
let mut v = Vec::new();
// These should fail
writeln!(&mut v, "");
writeln!(v, "");
let mut suggestion = Vec::new();
writeln!(&mut suggestion, "");
writeln!(suggestion, "");
// These should be fine
writeln!(&mut v);
writeln!(&mut v, " ");
write!(&mut v, "");
writeln!(v);
writeln!(v, " ");
write!(v, "");
}

View file

@ -1,16 +1,16 @@
error: using `writeln!(&mut v, "")`
error: using `writeln!(v, "")`
--> $DIR/writeln_empty_string.rs:11:5
|
LL | writeln!(&mut v, "");
| ^^^^^^^^^^^^^^^^^^^^ help: replace it with: `writeln!(&mut v)`
LL | writeln!(v, "");
| ^^^^^^^^^^^^^^^ help: replace it with: `writeln!(v)`
|
= note: `-D clippy::writeln-empty-string` implied by `-D warnings`
error: using `writeln!(&mut suggestion, "")`
error: using `writeln!(suggestion, "")`
--> $DIR/writeln_empty_string.rs:14:5
|
LL | writeln!(&mut suggestion, "");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `writeln!(&mut suggestion)`
LL | writeln!(suggestion, "");
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `writeln!(suggestion)`
error: aborting due to 2 previous errors