Merge remote-tracking branch 'upstream/master' into rustup

This commit is contained in:
Philipp Krones 2024-06-13 12:18:48 +02:00
commit cc63143bbf
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
213 changed files with 3146 additions and 1693 deletions

View file

@ -1,4 +1,4 @@
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Cast(expr, cast_ty) = init.kind
&& let TyKind::Path(ref qpath) = cast_ty.kind

View file

@ -1,12 +1,12 @@
if let ExprKind::Block(block, None) = expr.kind
&& block.stmts.len() == 3
&& let StmtKind::Local(local) = block.stmts[0].kind
&& let StmtKind::Let(local) = block.stmts[0].kind
&& let Some(init) = local.init
&& let ExprKind::Lit(ref lit) = init.kind
&& let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node
&& let PatKind::Binding(BindingMode::NONE, _, name, None) = local.pat.kind
&& name.as_str() == "x"
&& let StmtKind::Local(local1) = block.stmts[1].kind
&& let StmtKind::Let(local1) = block.stmts[1].kind
&& let Some(init1) = local1.init
&& let ExprKind::Lit(ref lit1) = init1.kind
&& let LitKind::Float(_, LitFloatType::Suffixed(FloatTy::F32)) = lit1.node
@ -22,7 +22,7 @@ if let ExprKind::Block(block, None) = expr.kind
}
if let ExprKind::Block(block, None) = expr.kind
&& block.stmts.len() == 1
&& let StmtKind::Local(local) = block.stmts[0].kind
&& let StmtKind::Let(local) = block.stmts[0].kind
&& let Some(init) = local.init
&& let ExprKind::Call(func, args) = init.kind
&& let ExprKind::Path(ref qpath) = func.kind

View file

@ -1,4 +1,4 @@
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Call(func, args) = init.kind
&& let ExprKind::Path(ref qpath) = func.kind

View file

@ -1,4 +1,4 @@
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::If(cond, then, Some(else_expr)) = init.kind
&& let ExprKind::DropTemps(expr) = cond.kind

View file

@ -1,4 +1,4 @@
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Call(func, args) = init.kind
&& let ExprKind::Path(ref qpath) = func.kind

View file

@ -12,7 +12,7 @@ if let Some(higher::ForLoop { pat: pat, arg: arg, body: body, .. }) = higher::Fo
&& let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node
&& let ExprKind::Block(block, None) = body.kind
&& block.stmts.len() == 1
&& let StmtKind::Local(local) = block.stmts[0].kind
&& let StmtKind::Let(local) = block.stmts[0].kind
&& let Some(init) = local.init
&& let ExprKind::Path(ref qpath1) = init.kind
&& match_qpath(qpath1, &["y"])

View file

@ -1,4 +1,4 @@
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Closure { capture_clause: CaptureBy::Ref, fn_decl: fn_decl, body: body_id, closure_kind: ClosureKind::Closure, .. } = init.kind
&& let FnRetTy::DefaultReturn(_) = fn_decl.output

View file

@ -1,4 +1,4 @@
if let StmtKind::Local(local) = stmt.kind
if let StmtKind::Let(local) = stmt.kind
&& let Some(init) = local.init
&& let ExprKind::Match(scrutinee, arms, MatchSource::Normal) = init.kind
&& let ExprKind::Lit(ref lit) = scrutinee.kind
@ -16,7 +16,7 @@ if let StmtKind::Local(local) = stmt.kind
&& arms[1].guard.is_none()
&& let ExprKind::Block(block, None) = arms[1].body.kind
&& block.stmts.len() == 1
&& let StmtKind::Local(local1) = block.stmts[0].kind
&& let StmtKind::Let(local1) = block.stmts[0].kind
&& let Some(init1) = local1.init
&& let ExprKind::Lit(ref lit4) = init1.kind
&& let LitKind::Int(3, LitIntType::Unsuffixed) = lit4.node

View file

@ -169,3 +169,16 @@ pub fn derive_ignored_unit_pattern(_: TokenStream) -> TokenStream {
}
}
}
#[proc_macro_derive(NonCanonicalClone)]
pub fn non_canonical_clone_derive(_: TokenStream) -> TokenStream {
quote! {
struct NonCanonicalClone;
impl Clone for NonCanonicalClone {
fn clone(&self) -> Self {
todo!()
}
}
impl Copy for NonCanonicalClone {}
}
}

View file

@ -58,7 +58,7 @@ fn group_with_span(delimiter: Delimiter, stream: TokenStream, span: Span) -> Gro
const ESCAPE_CHAR: char = '$';
/// Takes a single token followed by a sequence of tokens. Returns the sequence of tokens with their
/// span set to that of the first token. Tokens may be escaped with either `#ident` or `#(tokens)`.
/// span set to that of the first token. Tokens may be escaped with either `$ident` or `$(tokens)`.
#[proc_macro]
pub fn with_span(input: TokenStream) -> TokenStream {
let mut iter = input.into_iter();
@ -72,7 +72,7 @@ pub fn with_span(input: TokenStream) -> TokenStream {
}
/// Takes a sequence of tokens and return the tokens with the span set such that they appear to be
/// from an external macro. Tokens may be escaped with either `#ident` or `#(tokens)`.
/// from an external macro. Tokens may be escaped with either `$ident` or `$(tokens)`.
#[proc_macro]
pub fn external(input: TokenStream) -> TokenStream {
let mut res = TokenStream::new();
@ -84,7 +84,7 @@ pub fn external(input: TokenStream) -> TokenStream {
}
/// Copies all the tokens, replacing all their spans with the given span. Tokens can be escaped
/// either by `#ident` or `#(tokens)`.
/// either by `$ident` or `$(tokens)`.
fn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Result<()> {
while let Some(tt) = input.next() {
match tt {

View file

@ -117,4 +117,17 @@ mod issue_12016 {
}
}
fn in_closure() {
let v = vec![1, 2, 3];
if v.into_iter()
.filter(|x| {
let y = x + 1;
y > 3
})
.any(|x| x == 5)
{
println!("contains 4!");
}
}
fn main() {}

View file

@ -117,4 +117,17 @@ mod issue_12016 {
}
}
fn in_closure() {
let v = vec![1, 2, 3];
if v.into_iter()
.filter(|x| {
let y = x + 1;
y > 3
})
.any(|x| x == 5)
{
println!("contains 4!");
}
}
fn main() {}

View file

@ -1,89 +0,0 @@
#![warn(clippy::blocks_in_conditions)]
#![allow(
unused,
clippy::let_and_return,
clippy::needless_if,
clippy::unnecessary_literal_unwrap
)]
fn predicate<F: FnOnce(T) -> bool, T>(pfn: F, val: T) -> bool {
pfn(val)
}
fn pred_test() {
let v = 3;
let sky = "blue";
// This is a sneaky case, where the block isn't directly in the condition,
// but is actually inside a closure that the condition is using.
// The same principle applies -- add some extra expressions to make sure
// linter isn't confused by them.
if v == 3
&& sky == "blue"
&& predicate(
|x| {
//~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks
//~| NOTE: `-D clippy::blocks-in-conditions` implied by `-D warnings`
let target = 3;
x == target
},
v,
)
{}
if predicate(
|x| {
//~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; in
let target = 3;
x == target
},
v,
) {}
}
fn closure_without_block() {
if predicate(|x| x == 3, 6) {}
}
fn macro_in_closure() {
let option = Some(true);
if option.unwrap_or_else(|| unimplemented!()) {
unimplemented!()
}
}
fn closure(_: impl FnMut()) -> bool {
true
}
fn function_with_empty_closure() {
if closure(|| {}) {}
}
// issue #11814
fn match_with_pred() {
let v = 3;
match Some(predicate(
|x| {
//~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks
let target = 3;
x == target
},
v,
)) {
Some(true) => 1,
Some(false) => 2,
None => 3,
};
}
#[rustfmt::skip]
fn main() {
let mut range = 0..10;
range.all(|i| {i < 10} );
let v = vec![1, 2, 3];
if v.into_iter().any(|x| {x == 4}) {
println!("contains 4!");
}
}

View file

@ -1,39 +0,0 @@
error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
--> tests/ui/blocks_in_conditions_closure.rs:23:17
|
LL | |x| {
| _________________^
LL | |
LL | |
LL | | let target = 3;
LL | | x == target
LL | | },
| |_____________^
|
= note: `-D clippy::blocks-in-conditions` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]`
error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
--> tests/ui/blocks_in_conditions_closure.rs:34:13
|
LL | |x| {
| _____________^
LL | |
LL | | let target = 3;
LL | | x == target
LL | | },
| |_________^
error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
--> tests/ui/blocks_in_conditions_closure.rs:67:13
|
LL | |x| {
| _____________^
LL | |
LL | | let target = 3;
LL | | x == target
LL | | },
| |_________^
error: aborting due to 3 previous errors

View file

@ -1,29 +0,0 @@
#![warn(clippy::maybe_misused_cfg)]
fn main() {
#[cfg(feature = "not-really-a-feature")]
//~^ ERROR: 'feature' may be misspelled as 'features'
//~| NOTE: `-D clippy::maybe-misused-cfg` implied by `-D warnings`
let _ = 1 + 2;
#[cfg(all(feature = "right", feature = "wrong"))]
//~^ ERROR: 'feature' may be misspelled as 'features'
let _ = 1 + 2;
#[cfg(all(feature = "wrong1", any(feature = "right", feature = "wrong2", feature, features)))]
//~^ ERROR: 'feature' may be misspelled as 'features'
//~| ERROR: 'feature' may be misspelled as 'features'
let _ = 1 + 2;
#[cfg(test)]
//~^ ERROR: 'test' may be misspelled as 'tests'
let _ = 2;
#[cfg(test)]
//~^ ERROR: 'test' may be misspelled as 'Test'
let _ = 2;
#[cfg(all(test, test))]
//~^ ERROR: 'test' may be misspelled as 'tests'
//~| ERROR: 'test' may be misspelled as 'Test'
let _ = 2;
}

View file

@ -1,29 +0,0 @@
#![warn(clippy::maybe_misused_cfg)]
fn main() {
#[cfg(features = "not-really-a-feature")]
//~^ ERROR: 'feature' may be misspelled as 'features'
//~| NOTE: `-D clippy::maybe-misused-cfg` implied by `-D warnings`
let _ = 1 + 2;
#[cfg(all(feature = "right", features = "wrong"))]
//~^ ERROR: 'feature' may be misspelled as 'features'
let _ = 1 + 2;
#[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))]
//~^ ERROR: 'feature' may be misspelled as 'features'
//~| ERROR: 'feature' may be misspelled as 'features'
let _ = 1 + 2;
#[cfg(tests)]
//~^ ERROR: 'test' may be misspelled as 'tests'
let _ = 2;
#[cfg(Test)]
//~^ ERROR: 'test' may be misspelled as 'Test'
let _ = 2;
#[cfg(all(tests, Test))]
//~^ ERROR: 'test' may be misspelled as 'tests'
//~| ERROR: 'test' may be misspelled as 'Test'
let _ = 2;
}

View file

@ -1,53 +0,0 @@
error: 'feature' may be misspelled as 'features'
--> tests/ui/cfg_features.rs:4:11
|
LL | #[cfg(features = "not-really-a-feature")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "not-really-a-feature"`
|
= note: `-D clippy::maybe-misused-cfg` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::maybe_misused_cfg)]`
error: 'feature' may be misspelled as 'features'
--> tests/ui/cfg_features.rs:9:34
|
LL | #[cfg(all(feature = "right", features = "wrong"))]
| ^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "wrong"`
error: 'feature' may be misspelled as 'features'
--> tests/ui/cfg_features.rs:13:15
|
LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))]
| ^^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "wrong1"`
error: 'feature' may be misspelled as 'features'
--> tests/ui/cfg_features.rs:13:59
|
LL | #[cfg(all(features = "wrong1", any(feature = "right", features = "wrong2", feature, features)))]
| ^^^^^^^^^^^^^^^^^^^ help: did you mean: `feature = "wrong2"`
error: 'test' may be misspelled as 'tests'
--> tests/ui/cfg_features.rs:18:11
|
LL | #[cfg(tests)]
| ^^^^^ help: did you mean: `test`
error: 'test' may be misspelled as 'Test'
--> tests/ui/cfg_features.rs:21:11
|
LL | #[cfg(Test)]
| ^^^^ help: did you mean: `test`
error: 'test' may be misspelled as 'tests'
--> tests/ui/cfg_features.rs:25:15
|
LL | #[cfg(all(tests, Test))]
| ^^^^^ help: did you mean: `test`
error: 'test' may be misspelled as 'Test'
--> tests/ui/cfg_features.rs:25:22
|
LL | #[cfg(all(tests, Test))]
| ^^^^ help: did you mean: `test`
error: aborting due to 8 previous errors

View file

@ -1,5 +1,3 @@
const UNINIT: core::mem::MaybeUninit<core::cell::Cell<&'static ()>> = core::mem::MaybeUninit::uninit();
//~^ ERROR: a `const` item should never be interior mutable
//~| NOTE: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
fn main() {}

View file

@ -1,11 +1,10 @@
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/crashes/ice-9445.rs:1:1
|
LL | const UNINIT: core::mem::MaybeUninit<core::cell::Cell<&'static ()>> = core::mem::MaybeUninit::uninit();
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider making this `Sync` so that it can go in a static item or using a `thread_local`
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`

View file

@ -1,33 +0,0 @@
#![deny(clippy::mut_mut, clippy::zero_ptr)]
#![allow(dead_code)]
// FIXME: compiletest + extern crates doesn't work together. To make this test work, it would need
// the following three lines and the lazy_static crate.
//
// #[macro_use]
// extern crate lazy_static;
// use std::collections::HashMap;
/// ensure that we don't suggest `is_null` inside constants
/// FIXME: once const fn is stable, suggest these functions again in constants
const BAA: *const i32 = 0 as *const i32;
static mut BAR: *const i32 = BAA;
static mut FOO: *const i32 = 0 as *const i32;
#[allow(unused_variables, unused_mut)]
fn main() {
/*
lazy_static! {
static ref MUT_MAP : HashMap<usize, &'static str> = {
let mut m = HashMap::new();
m.insert(0, "zero");
m
};
static ref MUT_COUNT : usize = MUT_MAP.len();
}
assert_eq!(*MUT_COUNT, 1);
*/
// FIXME: don't lint in array length, requires `check_body`
//let _ = [""; (42.0 < f32::NAN) as usize];
}

View file

@ -1,87 +1,84 @@
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:12:1
|
LL | const UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(true));
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider making this `Sync` so that it can go in a static item or using a `thread_local`
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:23:1
|
LL | const UNFROZEN_VARIANT_FROM_FN: OptionalCell = unfrozen_variant();
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider making this `Sync` so that it can go in a static item or using a `thread_local`
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:45:1
|
LL | const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost {
| ^----
| |
| _make this a static item (maybe with lazy_static)
| |
LL | / const NESTED_UNFROZEN_VARIANT: NestedOutermost = NestedOutermost {
LL | |
LL | | outer: NestedOuter::NestedInner(NestedInner {
LL | | inner: NestedInnermost::Unfrozen(AtomicUsize::new(2)),
LL | | }),
LL | | };
| |__^
|
= help: consider making this a static item
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:60:5
|
LL | const TO_BE_UNFROZEN_VARIANT: OptionalCell;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:61:5
|
LL | const TO_BE_FROZEN_VARIANT: OptionalCell;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:64:5
|
LL | const DEFAULTED_ON_UNFROZEN_VARIANT: OptionalCell = OptionalCell::Unfrozen(Cell::new(false));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:90:5
|
LL | const TO_BE_UNFROZEN_VARIANT: Option<Self::ToBeUnfrozen> = Some(Self::ToBeUnfrozen::new(4));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:102:5
|
LL | const UNFROZEN_VARIANT: BothOfCellAndGeneric<T> = BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:105:5
|
LL | const GENERIC_VARIANT: BothOfCellAndGeneric<T> = BothOfCellAndGeneric::Generic(std::ptr::null());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:111:5
|
LL | const NO_ENUM: Cell<*const T> = Cell::new(std::ptr::null());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:118:5
|
LL | / const UNFROZEN_VARIANT: BothOfCellAndGeneric<Self::AssocType> =
LL | | BothOfCellAndGeneric::Unfrozen(Cell::new(std::ptr::null()));
| |____________________________________________________________________^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/enums.rs:120:5
|
LL | const GENERIC_VARIANT: BothOfCellAndGeneric<Self::AssocType> = BothOfCellAndGeneric::Generic(std::ptr::null());

View file

@ -1,31 +1,30 @@
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/others.rs:9:1
|
LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider making this a static item
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/others.rs:10:1
|
LL | const CELL: Cell<usize> = Cell::new(6);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider making this `Sync` so that it can go in a static item or using a `thread_local`
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/others.rs:11:1
|
LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider making this a static item
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/others.rs:16:9
|
LL | const $name: $ty = $e;
@ -36,7 +35,7 @@ LL | declare_const!(_ONCE: Once = Once::new());
|
= note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info)
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/others.rs:44:13
|
LL | const _BAZ: Cell<usize> = Cell::new(0);

View file

@ -1,4 +1,4 @@
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:16:5
|
LL | const ATOMIC: AtomicUsize;
@ -7,7 +7,7 @@ LL | const ATOMIC: AtomicUsize;
= note: `-D clippy::declare-interior-mutable-const` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:9:9
|
LL | const $name: $ty = $e;
@ -18,67 +18,67 @@ LL | declare_const!(ANOTHER_ATOMIC: AtomicUsize = Self::ATOMIC);
|
= note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info)
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:44:5
|
LL | const TO_BE_CONCRETE: AtomicUsize = AtomicUsize::new(11);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:69:5
|
LL | const TO_BE_UNFROZEN: Self::ToBeUnfrozen = AtomicUsize::new(13);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:70:5
|
LL | const WRAPPED_TO_BE_UNFROZEN: Wrapper<Self::ToBeUnfrozen> = Wrapper(AtomicUsize::new(14));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:89:5
|
LL | const BOUNDED: T::ToBeBounded;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:117:5
|
LL | const SELF: Self = AtomicUsize::new(17);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:118:5
|
LL | const WRAPPED_SELF: Option<Self> = Some(AtomicUsize::new(21));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:124:5
|
LL | const DIRECT: Cell<T>;
| ^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:125:5
|
LL | const INDIRECT: Cell<*const T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:129:5
|
LL | const DIRECT: Cell<T> = Cell::new(T::DEFAULT);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:141:5
|
LL | const ATOMIC: AtomicUsize = AtomicUsize::new(18);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: a `const` item should never be interior mutable
error: a `const` item should not be interior mutable
--> tests/ui/declare_interior_mutable_const/traits.rs:147:5
|
LL | const BOUNDED_ASSOC_TYPE: T::ToBeBounded = AtomicUsize::new(19);

View file

@ -18,5 +18,7 @@
#![warn(clippy::filter_map)]
#![warn(clippy::pub_enum_variant_names)]
#![warn(clippy::wrong_pub_self_convention)]
#![warn(clippy::maybe_misused_cfg)]
#![warn(clippy::mismatched_target_os)]
fn main() {}

View file

@ -97,5 +97,17 @@ error: lint `clippy::wrong_pub_self_convention` has been removed: set the `avoid
LL | #![warn(clippy::wrong_pub_self_convention)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 16 previous errors
error: lint `clippy::maybe_misused_cfg` has been removed: this lint has been replaced by `unexpected_cfgs`
--> tests/ui/deprecated.rs:21:9
|
LL | #![warn(clippy::maybe_misused_cfg)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: lint `clippy::mismatched_target_os` has been removed: this lint has been replaced by `unexpected_cfgs`
--> tests/ui/deprecated.rs:22:9
|
LL | #![warn(clippy::mismatched_target_os)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 18 previous errors

View file

@ -43,6 +43,10 @@ fn main() {
let b = *aref;
let _ = unsafe { *core::ptr::addr_of!(a) };
let _repeat = [0; 64];
// do NOT lint for array as sematic differences with/out `*&`.
let _arr = *&[0, 1, 2, 3, 4];
}
#[derive(Copy, Clone)]

View file

@ -43,6 +43,10 @@ fn main() {
let b = **&aref;
let _ = unsafe { *core::ptr::addr_of!(a) };
let _repeat = *&[0; 64];
// do NOT lint for array as sematic differences with/out `*&`.
let _arr = *&[0, 1, 2, 3, 4];
}
#[derive(Copy, Clone)]

View file

@ -50,7 +50,13 @@ LL | let b = **&aref;
| ^^^^^^ help: try: `aref`
error: immediately dereferencing a reference
--> tests/ui/deref_addrof.rs:53:17
--> tests/ui/deref_addrof.rs:47:19
|
LL | let _repeat = *&[0; 64];
| ^^^^^^^^^ help: try: `[0; 64]`
error: immediately dereferencing a reference
--> tests/ui/deref_addrof.rs:57:17
|
LL | inline!(*& $(@expr self))
| ^^^^^^^^^^^^^^^^ help: try: `$(@expr self)`
@ -58,12 +64,12 @@ LL | inline!(*& $(@expr self))
= note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
error: immediately dereferencing a reference
--> tests/ui/deref_addrof.rs:57:17
--> tests/ui/deref_addrof.rs:61:17
|
LL | inline!(*&mut $(@expr self))
| ^^^^^^^^^^^^^^^^^^^ help: try: `$(@expr self)`
|
= note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 10 previous errors
error: aborting due to 11 previous errors

View file

@ -1,7 +1,6 @@
#![allow(clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, dead_code)]
#![warn(clippy::expl_impl_clone_on_copy)]
#[derive(Copy)]
struct Qux;

View file

@ -1,5 +1,5 @@
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:8:1
--> tests/ui/derive.rs:7:1
|
LL | / impl Clone for Qux {
LL | |
@ -10,7 +10,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:8:1
--> tests/ui/derive.rs:7:1
|
LL | / impl Clone for Qux {
LL | |
@ -23,7 +23,7 @@ LL | | }
= help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]`
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:33:1
--> tests/ui/derive.rs:32:1
|
LL | / impl<'a> Clone for Lt<'a> {
LL | |
@ -34,7 +34,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:33:1
--> tests/ui/derive.rs:32:1
|
LL | / impl<'a> Clone for Lt<'a> {
LL | |
@ -45,7 +45,7 @@ LL | | }
| |_^
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:45:1
--> tests/ui/derive.rs:44:1
|
LL | / impl Clone for BigArray {
LL | |
@ -56,7 +56,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:45:1
--> tests/ui/derive.rs:44:1
|
LL | / impl Clone for BigArray {
LL | |
@ -67,7 +67,7 @@ LL | | }
| |_^
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:57:1
--> tests/ui/derive.rs:56:1
|
LL | / impl Clone for FnPtr {
LL | |
@ -78,7 +78,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:57:1
--> tests/ui/derive.rs:56:1
|
LL | / impl Clone for FnPtr {
LL | |
@ -89,7 +89,7 @@ LL | | }
| |_^
error: you are implementing `Clone` explicitly on a `Copy` type
--> tests/ui/derive.rs:78:1
--> tests/ui/derive.rs:77:1
|
LL | / impl<T: Clone> Clone for Generic2<T> {
LL | |
@ -100,7 +100,7 @@ LL | | }
| |_^
|
note: consider deriving `Clone` or removing `Copy`
--> tests/ui/derive.rs:78:1
--> tests/ui/derive.rs:77:1
|
LL | / impl<T: Clone> Clone for Generic2<T> {
LL | |

View file

@ -1,4 +1,4 @@
error: unsafe function's docs miss `# Safety` section
error: unsafe function's docs are missing a `# Safety` section
--> tests/ui/doc_unsafe.rs:9:1
|
LL | pub unsafe fn destroy_the_planet() {
@ -7,13 +7,13 @@ LL | pub unsafe fn destroy_the_planet() {
= note: `-D clippy::missing-safety-doc` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::missing_safety_doc)]`
error: unsafe function's docs miss `# Safety` section
error: unsafe function's docs are missing a `# Safety` section
--> tests/ui/doc_unsafe.rs:32:5
|
LL | pub unsafe fn republished() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsafe function's docs miss `# Safety` section
error: unsafe function's docs are missing a `# Safety` section
--> tests/ui/doc_unsafe.rs:40:5
|
LL | unsafe fn woefully_underdocumented(self);
@ -25,13 +25,13 @@ error: docs for unsafe trait missing `# Safety` section
LL | pub unsafe trait UnsafeTrait {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsafe function's docs miss `# Safety` section
error: unsafe function's docs are missing a `# Safety` section
--> tests/ui/doc_unsafe.rs:76:5
|
LL | pub unsafe fn more_undocumented_unsafe() -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: unsafe function's docs miss `# Safety` section
error: unsafe function's docs are missing a `# Safety` section
--> tests/ui/doc_unsafe.rs:92:9
|
LL | pub unsafe fn whee() {

View file

@ -5,6 +5,6 @@ fn main() {
-x;
-(-x);
--x;
//~^ ERROR: `--x` could be misinterpreted as pre-decrement by C programmers, is usuall
//~^ ERROR: `--x` could be misinterpreted as pre-decrement by C programmers, is usually
//~| NOTE: `-D clippy::double-neg` implied by `-D warnings`
}

View file

@ -471,3 +471,14 @@ mod issue_10854 {
}
}
}
mod issue_12853 {
fn f_by_value<F: Fn(u32)>(f: F) {
let x = Box::new(|| None.map(&f));
x();
}
fn f_by_ref<F: Fn(u32)>(f: &F) {
let x = Box::new(|| None.map(f));
x();
}
}

View file

@ -471,3 +471,14 @@ mod issue_10854 {
}
}
}
mod issue_12853 {
fn f_by_value<F: Fn(u32)>(f: F) {
let x = Box::new(|| None.map(|x| f(x)));
x();
}
fn f_by_ref<F: Fn(u32)>(f: &F) {
let x = Box::new(|| None.map(|x| f(x)));
x();
}
}

View file

@ -190,5 +190,17 @@ error: redundant closure
LL | test.map(|t| t.method())
| ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method`
error: aborting due to 31 previous errors
error: redundant closure
--> tests/ui/eta.rs:477:38
|
LL | let x = Box::new(|| None.map(|x| f(x)));
| ^^^^^^^^ help: replace the closure with the function itself: `&f`
error: redundant closure
--> tests/ui/eta.rs:481:38
|
LL | let x = Box::new(|| None.map(|x| f(x)));
| ^^^^^^^^ help: replace the closure with the function itself: `f`
error: aborting due to 33 previous errors

View file

@ -55,4 +55,19 @@ fn check_ln1p() {
let _ = (1.0 + x - 2.0).ln();
}
fn issue12881() {
pub trait MyLog {
fn log(&self) -> Self;
}
impl MyLog for f32 {
fn log(&self) -> Self {
4.
}
}
let x = 2.0;
x.log();
}
fn main() {}

View file

@ -55,4 +55,19 @@ fn check_ln1p() {
let _ = (1.0 + x - 2.0).ln();
}
fn issue12881() {
pub trait MyLog {
fn log(&self) -> Self;
}
impl MyLog for f32 {
fn log(&self) -> Self {
4.
}
}
let x = 2.0;
x.log();
}
fn main() {}

View file

@ -104,6 +104,7 @@ fn main() {
println!("{foo}{bar}", foo = "foo", bar = "bar");
println!("{foo}{bar}", bar = "bar", foo = "foo");
println!("{foo}{bar}", bar = "bar", foo = "foo");
println!("{}", my_other_macro!());
// negative tests
println!("error: something failed at {}", Somewhere.to_string());

View file

@ -104,6 +104,7 @@ fn main() {
println!("{foo}{bar}", foo = "foo", bar = "bar".to_string());
println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo");
println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
println!("{}", my_other_macro!().to_string());
// negative tests
println!("error: something failed at {}", Somewhere.to_string());

View file

@ -127,29 +127,35 @@ error: `to_string` applied to a type that implements `Display` in `println!` arg
LL | println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
--> tests/ui/format_args.rs:107:37
|
LL | println!("{}", my_other_macro!().to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `print!` args
--> tests/ui/format_args.rs:118:37
--> tests/ui/format_args.rs:119:37
|
LL | print!("{}", (Location::caller().to_string()));
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `print!` args
--> tests/ui/format_args.rs:119:39
--> tests/ui/format_args.rs:120:39
|
LL | print!("{}", ((Location::caller()).to_string()));
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `format!` args
--> tests/ui/format_args.rs:147:38
--> tests/ui/format_args.rs:148:38
|
LL | let x = format!("{} {}", a, b.to_string());
| ^^^^^^^^^^^^ help: remove this
error: `to_string` applied to a type that implements `Display` in `println!` args
--> tests/ui/format_args.rs:161:24
--> tests/ui/format_args.rs:162:24
|
LL | println!("{}", original[..10].to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]`
error: aborting due to 25 previous errors
error: aborting due to 26 previous errors

View file

@ -1,4 +1,5 @@
//@compile-flags: -Zdeduplicate-diagnostics=yes
//@aux-build: proc_macros.rs
#![warn(clippy::indexing_slicing)]
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
@ -11,6 +12,9 @@
clippy::useless_vec
)]
extern crate proc_macros;
use proc_macros::with_span;
const ARR: [i32; 2] = [1, 2];
const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
//~^ ERROR: indexing may panic
@ -22,6 +26,22 @@ const fn idx4() -> usize {
4
}
with_span!(
span
fn dont_lint_proc_macro_array() {
let x = [1, 2, 3, 4];
let index: usize = 1;
x[index];
x[10];
let x = vec![0; 5];
let index: usize = 1;
x[index];
x[10];
}
);
fn main() {
let x = [1, 2, 3, 4];
let index: usize = 1;

View file

@ -1,5 +1,5 @@
error: indexing may panic
--> tests/ui/indexing_slicing_index.rs:15:20
--> tests/ui/indexing_slicing_index.rs:19:20
|
LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
| ^^^^^^^^^^
@ -10,19 +10,19 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re
= help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
error[E0080]: evaluation of `main::{constant#3}` failed
--> tests/ui/indexing_slicing_index.rs:47:14
--> tests/ui/indexing_slicing_index.rs:67:14
|
LL | const { &ARR[idx4()] };
| ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
note: erroneous constant encountered
--> tests/ui/indexing_slicing_index.rs:47:5
--> tests/ui/indexing_slicing_index.rs:67:5
|
LL | const { &ARR[idx4()] };
| ^^^^^^^^^^^^^^^^^^^^^^
error: indexing may panic
--> tests/ui/indexing_slicing_index.rs:28:5
--> tests/ui/indexing_slicing_index.rs:48:5
|
LL | x[index];
| ^^^^^^^^
@ -30,7 +30,7 @@ LL | x[index];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: index is out of bounds
--> tests/ui/indexing_slicing_index.rs:31:5
--> tests/ui/indexing_slicing_index.rs:51:5
|
LL | x[4];
| ^^^^
@ -39,13 +39,13 @@ LL | x[4];
= help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
error: index is out of bounds
--> tests/ui/indexing_slicing_index.rs:33:5
--> tests/ui/indexing_slicing_index.rs:53:5
|
LL | x[1 << 3];
| ^^^^^^^^^
error: indexing may panic
--> tests/ui/indexing_slicing_index.rs:44:14
--> tests/ui/indexing_slicing_index.rs:64:14
|
LL | const { &ARR[idx()] };
| ^^^^^^^^^^
@ -54,7 +54,7 @@ LL | const { &ARR[idx()] };
= note: the suggestion might not be applicable in constant blocks
error: indexing may panic
--> tests/ui/indexing_slicing_index.rs:47:14
--> tests/ui/indexing_slicing_index.rs:67:14
|
LL | const { &ARR[idx4()] };
| ^^^^^^^^^^^
@ -63,13 +63,13 @@ LL | const { &ARR[idx4()] };
= note: the suggestion might not be applicable in constant blocks
error: index is out of bounds
--> tests/ui/indexing_slicing_index.rs:54:5
--> tests/ui/indexing_slicing_index.rs:74:5
|
LL | y[4];
| ^^^^
error: indexing may panic
--> tests/ui/indexing_slicing_index.rs:57:5
--> tests/ui/indexing_slicing_index.rs:77:5
|
LL | v[0];
| ^^^^
@ -77,7 +77,7 @@ LL | v[0];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
--> tests/ui/indexing_slicing_index.rs:59:5
--> tests/ui/indexing_slicing_index.rs:79:5
|
LL | v[10];
| ^^^^^
@ -85,7 +85,7 @@ LL | v[10];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
--> tests/ui/indexing_slicing_index.rs:61:5
--> tests/ui/indexing_slicing_index.rs:81:5
|
LL | v[1 << 3];
| ^^^^^^^^^
@ -93,13 +93,13 @@ LL | v[1 << 3];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: index is out of bounds
--> tests/ui/indexing_slicing_index.rs:69:5
--> tests/ui/indexing_slicing_index.rs:89:5
|
LL | x[N];
| ^^^^
error: indexing may panic
--> tests/ui/indexing_slicing_index.rs:72:5
--> tests/ui/indexing_slicing_index.rs:92:5
|
LL | v[N];
| ^^^^
@ -107,7 +107,7 @@ LL | v[N];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
--> tests/ui/indexing_slicing_index.rs:74:5
--> tests/ui/indexing_slicing_index.rs:94:5
|
LL | v[M];
| ^^^^
@ -115,7 +115,7 @@ LL | v[M];
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: index is out of bounds
--> tests/ui/indexing_slicing_index.rs:78:13
--> tests/ui/indexing_slicing_index.rs:98:13
|
LL | let _ = x[4];
| ^^^^

View file

@ -1,8 +1,111 @@
//@aux-build: proc_macros.rs
#![warn(clippy::indexing_slicing)]
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
// we want to avoid false positives.
#![warn(clippy::out_of_bounds_indexing)]
#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::useless_vec)]
#![allow(
clippy::no_effect,
clippy::unnecessary_operation,
clippy::useless_vec,
unused_must_use,
unused
)]
#![warn(clippy::indexing_slicing)]
extern crate proc_macros;
use proc_macros::with_span;
use std::ops::Index;
struct BoolMap<T> {
false_value: T,
true_value: T,
}
impl<T> Index<bool> for BoolMap<T> {
type Output = T;
fn index(&self, index: bool) -> &T {
if index { &self.true_value } else { &self.false_value }
}
}
struct BoolMapWithGet<T> {
false_value: T,
true_value: T,
}
impl<T> Index<bool> for BoolMapWithGet<T> {
type Output = T;
fn index(&self, index: bool) -> &Self::Output {
if index { &self.true_value } else { &self.false_value }
}
}
impl<T> BoolMapWithGet<T> {
fn get(&self, index: bool) -> Option<&T> {
if index {
Some(&self.true_value)
} else {
Some(&self.false_value)
}
}
}
struct S<T>(T);
impl S<i32> {
fn get() -> Option<i32> {
unimplemented!()
}
}
impl<T> Index<i32> for S<T> {
type Output = T;
fn index(&self, _index: i32) -> &Self::Output {
&self.0
}
}
struct Y<T>(T);
impl Y<i32> {
fn get<U>() -> Option<U> {
unimplemented!()
}
}
impl<T> Index<i32> for Y<T> {
type Output = T;
fn index(&self, _index: i32) -> &Self::Output {
&self.0
}
}
struct Z<T>(T);
impl<T> Z<T> {
fn get<T2>() -> T2 {
unimplemented!()
}
}
impl<T> Index<i32> for Z<T> {
type Output = T;
fn index(&self, _index: i32) -> &Self::Output {
&self.0
}
}
with_span!(
span
fn dont_lint_proc_macro() {
let x = [1, 2, 3, 4];
let index: usize = 1;
&x[index..];
&x[..10];
let x = vec![0; 5];
let index: usize = 1;
&x[index..];
&x[..10];
}
);
fn main() {
let x = [1, 2, 3, 4];
@ -51,4 +154,28 @@ fn main() {
//~^ ERROR: slicing may panic
&v[..]; // Ok, should not produce stderr.
let map = BoolMap {
false_value: 2,
true_value: 4,
};
map[true]; // Ok, because `get` does not exist (custom indexing)
let map_with_get = BoolMapWithGet {
false_value: 2,
true_value: 4,
};
// Lint on this, because `get` does exist with same signature
map_with_get[true];
let s = S::<i32>(1);
s[0];
let y = Y::<i32>(1);
y[0];
let z = Z::<i32>(1);
z[0];
}

View file

@ -1,5 +1,5 @@
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:12:6
--> tests/ui/indexing_slicing_slice.rs:115:6
|
LL | &x[index..];
| ^^^^^^^^^^
@ -9,7 +9,7 @@ LL | &x[index..];
= help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:14:6
--> tests/ui/indexing_slicing_slice.rs:117:6
|
LL | &x[..index];
| ^^^^^^^^^^
@ -17,7 +17,7 @@ LL | &x[..index];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:16:6
--> tests/ui/indexing_slicing_slice.rs:119:6
|
LL | &x[index_from..index_to];
| ^^^^^^^^^^^^^^^^^^^^^^^
@ -25,7 +25,7 @@ LL | &x[index_from..index_to];
= help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:18:6
--> tests/ui/indexing_slicing_slice.rs:121:6
|
LL | &x[index_from..][..index_to];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -33,7 +33,7 @@ LL | &x[index_from..][..index_to];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:18:6
--> tests/ui/indexing_slicing_slice.rs:121:6
|
LL | &x[index_from..][..index_to];
| ^^^^^^^^^^^^^^^
@ -41,7 +41,7 @@ LL | &x[index_from..][..index_to];
= help: consider using `.get(n..)` or .get_mut(n..)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:21:6
--> tests/ui/indexing_slicing_slice.rs:124:6
|
LL | &x[5..][..10];
| ^^^^^^^^^^^^
@ -49,7 +49,7 @@ LL | &x[5..][..10];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: range is out of bounds
--> tests/ui/indexing_slicing_slice.rs:21:8
--> tests/ui/indexing_slicing_slice.rs:124:8
|
LL | &x[5..][..10];
| ^
@ -58,7 +58,7 @@ LL | &x[5..][..10];
= help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:25:6
--> tests/ui/indexing_slicing_slice.rs:128:6
|
LL | &x[0..][..3];
| ^^^^^^^^^^^
@ -66,7 +66,7 @@ LL | &x[0..][..3];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:27:6
--> tests/ui/indexing_slicing_slice.rs:130:6
|
LL | &x[1..][..5];
| ^^^^^^^^^^^
@ -74,19 +74,19 @@ LL | &x[1..][..5];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: range is out of bounds
--> tests/ui/indexing_slicing_slice.rs:35:12
--> tests/ui/indexing_slicing_slice.rs:138:12
|
LL | &y[0..=4];
| ^
error: range is out of bounds
--> tests/ui/indexing_slicing_slice.rs:37:11
--> tests/ui/indexing_slicing_slice.rs:140:11
|
LL | &y[..=4];
| ^
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:43:6
--> tests/ui/indexing_slicing_slice.rs:146:6
|
LL | &v[10..100];
| ^^^^^^^^^^
@ -94,7 +94,7 @@ LL | &v[10..100];
= help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:45:6
--> tests/ui/indexing_slicing_slice.rs:148:6
|
LL | &x[10..][..100];
| ^^^^^^^^^^^^^^
@ -102,13 +102,13 @@ LL | &x[10..][..100];
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: range is out of bounds
--> tests/ui/indexing_slicing_slice.rs:45:8
--> tests/ui/indexing_slicing_slice.rs:148:8
|
LL | &x[10..][..100];
| ^^
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:48:6
--> tests/ui/indexing_slicing_slice.rs:151:6
|
LL | &v[10..];
| ^^^^^^^
@ -116,12 +116,36 @@ LL | &v[10..];
= help: consider using `.get(n..)` or .get_mut(n..)` instead
error: slicing may panic
--> tests/ui/indexing_slicing_slice.rs:50:6
--> tests/ui/indexing_slicing_slice.rs:153:6
|
LL | &v[..100];
| ^^^^^^^^
|
= help: consider using `.get(..n)`or `.get_mut(..n)` instead
error: aborting due to 16 previous errors
error: indexing may panic
--> tests/ui/indexing_slicing_slice.rs:171:5
|
LL | map_with_get[true];
| ^^^^^^^^^^^^^^^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
--> tests/ui/indexing_slicing_slice.rs:174:5
|
LL | s[0];
| ^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: indexing may panic
--> tests/ui/indexing_slicing_slice.rs:177:5
|
LL | y[0];
| ^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead
error: aborting due to 19 previous errors

View file

@ -137,7 +137,7 @@ fn can_break_both_inner_and_outer(cond: bool) {
}
fn break_wrong_loop(cond: bool) {
// 'inner has statement to break 'outer loop, but it was breaked early by a labeled child loop
// 'inner has statement to break 'outer loop, but it was broken out of early by a labeled child loop
'outer: loop {
loop {
//~^ ERROR: infinite loop detected

View file

@ -59,7 +59,7 @@ fn main() {
let _ = x;
}
// shouldnt fire
// shouldn't fire
for x in &vec {
let _ = x;
}

View file

@ -0,0 +1,49 @@
#![warn(clippy::manual_pattern_char_comparison)]
struct NotStr;
impl NotStr {
fn find(&self, _: impl FnMut(char) -> bool) {}
}
fn main() {
let sentence = "Hello, world!";
sentence.trim_end_matches(['.', ',', '!', '?']);
sentence.split(['\n', 'X']);
sentence.split(['\n', 'X']);
sentence.splitn(3, 'X');
sentence.splitn(3, |c: char| c.is_whitespace() || c == 'X');
let char_compare = 'X';
sentence.splitn(3, char_compare);
sentence.split(['\n', 'X', 'Y']);
sentence.splitn(3, 'X');
sentence.splitn(3, ['X', 'W']);
sentence.find('🎈');
let not_str = NotStr;
not_str.find(|c: char| c == 'X');
"".find(|c| c == 'a' || c > 'z');
let x = true;
"".find(|c| c == 'a' || x || c == 'b');
let d = 'd';
"".find(|c| c == 'a' || d == 'b');
"".find(|c| match c {
'a' | 'b' => true,
_ => c.is_ascii(),
});
"".find(|c| matches!(c, 'a' | 'b' if false));
"".find(|c| matches!(c, 'a' | '1'..'4'));
"".find(|c| c == 'a' || matches!(c, '1'..'4'));
macro_rules! m {
($e:expr) => {
$e == '?'
};
}
"".find(|c| m!(c));
}

View file

@ -0,0 +1,49 @@
#![warn(clippy::manual_pattern_char_comparison)]
struct NotStr;
impl NotStr {
fn find(&self, _: impl FnMut(char) -> bool) {}
}
fn main() {
let sentence = "Hello, world!";
sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?');
sentence.split(|c: char| c == '\n' || c == 'X');
sentence.split(|c| c == '\n' || c == 'X');
sentence.splitn(3, |c: char| c == 'X');
sentence.splitn(3, |c: char| c.is_whitespace() || c == 'X');
let char_compare = 'X';
sentence.splitn(3, |c: char| c == char_compare);
sentence.split(|c: char| matches!(c, '\n' | 'X' | 'Y'));
sentence.splitn(3, |c: char| matches!(c, 'X'));
sentence.splitn(3, |c: char| matches!(c, 'X' | 'W'));
sentence.find(|c| c == '🎈');
let not_str = NotStr;
not_str.find(|c: char| c == 'X');
"".find(|c| c == 'a' || c > 'z');
let x = true;
"".find(|c| c == 'a' || x || c == 'b');
let d = 'd';
"".find(|c| c == 'a' || d == 'b');
"".find(|c| match c {
'a' | 'b' => true,
_ => c.is_ascii(),
});
"".find(|c| matches!(c, 'a' | 'b' if false));
"".find(|c| matches!(c, 'a' | '1'..'4'));
"".find(|c| c == 'a' || matches!(c, '1'..'4'));
macro_rules! m {
($e:expr) => {
$e == '?'
};
}
"".find(|c| m!(c));
}

View file

@ -0,0 +1,59 @@
error: this manual char comparison can be written more succinctly
--> tests/ui/manual_pattern_char_comparison.rs:11:31
|
LL | sentence.trim_end_matches(|c: char| c == '.' || c == ',' || c == '!' || c == '?');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['.', ',', '!', '?']`
|
= note: `-D clippy::manual-pattern-char-comparison` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::manual_pattern_char_comparison)]`
error: this manual char comparison can be written more succinctly
--> tests/ui/manual_pattern_char_comparison.rs:12:20
|
LL | sentence.split(|c: char| c == '\n' || c == 'X');
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\n', 'X']`
error: this manual char comparison can be written more succinctly
--> tests/ui/manual_pattern_char_comparison.rs:13:20
|
LL | sentence.split(|c| c == '\n' || c == 'X');
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\n', 'X']`
error: this manual char comparison can be written more succinctly
--> tests/ui/manual_pattern_char_comparison.rs:14:24
|
LL | sentence.splitn(3, |c: char| c == 'X');
| ^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `'X'`
error: this manual char comparison can be written more succinctly
--> tests/ui/manual_pattern_char_comparison.rs:17:24
|
LL | sentence.splitn(3, |c: char| c == char_compare);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `char_compare`
error: this manual char comparison can be written more succinctly
--> tests/ui/manual_pattern_char_comparison.rs:18:20
|
LL | sentence.split(|c: char| matches!(c, '\n' | 'X' | 'Y'));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['\n', 'X', 'Y']`
error: this manual char comparison can be written more succinctly
--> tests/ui/manual_pattern_char_comparison.rs:19:24
|
LL | sentence.splitn(3, |c: char| matches!(c, 'X'));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using a `char`: `'X'`
error: this manual char comparison can be written more succinctly
--> tests/ui/manual_pattern_char_comparison.rs:20:24
|
LL | sentence.splitn(3, |c: char| matches!(c, 'X' | 'W'));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using an array of `char`: `['X', 'W']`
error: this manual char comparison can be written more succinctly
--> tests/ui/manual_pattern_char_comparison.rs:21:19
|
LL | sentence.find(|c| c == '🎈');
| ^^^^^^^^^^^^^ help: consider using a `char`: `'🎈'`
error: aborting due to 9 previous errors

View file

@ -26,6 +26,12 @@ fn main() {
Some(x) => x,
None => &[],
};
let x: Result<String, i64> = Ok(String::new());
x.unwrap_or_default();
let x: Result<String, i64> = Ok(String::new());
x.unwrap_or_default();
}
// Issue #12531

View file

@ -47,6 +47,21 @@ fn main() {
Some(x) => x,
None => &[],
};
let x: Result<String, i64> = Ok(String::new());
match x {
//~^ ERROR: match can be simplified with `.unwrap_or_default()`
Ok(v) => v,
Err(_) => String::new(),
};
let x: Result<String, i64> = Ok(String::new());
if let Ok(v) = x {
//~^ ERROR: if let can be simplified with `.unwrap_or_default()`
v
} else {
String::new()
};
}
// Issue #12531

View file

@ -53,7 +53,28 @@ LL | | };
| |_____^ help: replace it with: `x.unwrap_or_default()`
error: match can be simplified with `.unwrap_or_default()`
--> tests/ui/manual_unwrap_or_default.rs:56:20
--> tests/ui/manual_unwrap_or_default.rs:52:5
|
LL | / match x {
LL | |
LL | | Ok(v) => v,
LL | | Err(_) => String::new(),
LL | | };
| |_____^ help: replace it with: `x.unwrap_or_default()`
error: if let can be simplified with `.unwrap_or_default()`
--> tests/ui/manual_unwrap_or_default.rs:59:5
|
LL | / if let Ok(v) = x {
LL | |
LL | | v
LL | | } else {
LL | | String::new()
LL | | };
| |_____^ help: replace it with: `x.unwrap_or_default()`
error: match can be simplified with `.unwrap_or_default()`
--> tests/ui/manual_unwrap_or_default.rs:71:20
|
LL | Some(_) => match *b {
| ____________________^
@ -62,5 +83,5 @@ LL | | _ => 0,
LL | | },
| |_________^ help: replace it with: `(*b).unwrap_or_default()`
error: aborting due to 6 previous errors
error: aborting due to 8 previous errors

View file

@ -239,3 +239,20 @@ fn main() {
_ => false,
};
}
// issue #8919, fixed on https://github.com/rust-lang/rust/pull/97312
mod with_lifetime {
enum MaybeStaticStr<'a> {
Static(&'static str),
Borrowed(&'a str),
}
impl<'a> MaybeStaticStr<'a> {
fn get(&self) -> &'a str {
match *self {
MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s,
//~^ ERROR: this match arm has an identical body to another arm
}
}
}
}

View file

@ -262,3 +262,21 @@ fn main() {
_ => false,
};
}
// issue #8919, fixed on https://github.com/rust-lang/rust/pull/97312
mod with_lifetime {
enum MaybeStaticStr<'a> {
Static(&'static str),
Borrowed(&'a str),
}
impl<'a> MaybeStaticStr<'a> {
fn get(&self) -> &'a str {
match *self {
MaybeStaticStr::Static(s) => s,
MaybeStaticStr::Borrowed(s) => s,
//~^ ERROR: this match arm has an identical body to another arm
}
}
}
}

View file

@ -221,5 +221,21 @@ help: and remove this obsolete arm
LL - 0 => cfg!(not_enable),
|
error: aborting due to 13 previous errors
error: this match arm has an identical body to another arm
--> tests/ui/match_same_arms2.rs:277:17
|
LL | MaybeStaticStr::Borrowed(s) => s,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try changing either arm body
help: or try merging the arm patterns
|
LL | MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: and remove this obsolete arm
|
LL - MaybeStaticStr::Static(s) => s,
|
error: aborting due to 14 previous errors

View file

@ -1,25 +0,0 @@
#![warn(clippy::mismatched_target_os)]
#![allow(unused)]
#[cfg(target_os = "hermit")]
fn hermit() {}
#[cfg(target_os = "wasi")]
fn wasi() {}
#[cfg(target_os = "none")]
fn none() {}
// list with conditions
#[cfg(all(not(windows), target_os = "wasi"))]
fn list() {}
// windows is a valid target family, should be ignored
#[cfg(windows)]
fn windows() {}
// correct use, should be ignored
#[cfg(target_os = "hermit")]
fn correct() {}
fn main() {}

View file

@ -1,25 +0,0 @@
#![warn(clippy::mismatched_target_os)]
#![allow(unused)]
#[cfg(hermit)]
fn hermit() {}
#[cfg(wasi)]
fn wasi() {}
#[cfg(none)]
fn none() {}
// list with conditions
#[cfg(all(not(windows), wasi))]
fn list() {}
// windows is a valid target family, should be ignored
#[cfg(windows)]
fn windows() {}
// correct use, should be ignored
#[cfg(target_os = "hermit")]
fn correct() {}
fn main() {}

View file

@ -1,37 +0,0 @@
error: operating system used in target family position
--> tests/ui/mismatched_target_os_non_unix.rs:4:1
|
LL | #[cfg(hermit)]
| ^^^^^^------^^
| |
| help: try: `target_os = "hermit"`
|
= note: `-D clippy::mismatched-target-os` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::mismatched_target_os)]`
error: operating system used in target family position
--> tests/ui/mismatched_target_os_non_unix.rs:7:1
|
LL | #[cfg(wasi)]
| ^^^^^^----^^
| |
| help: try: `target_os = "wasi"`
error: operating system used in target family position
--> tests/ui/mismatched_target_os_non_unix.rs:10:1
|
LL | #[cfg(none)]
| ^^^^^^----^^
| |
| help: try: `target_os = "none"`
error: operating system used in target family position
--> tests/ui/mismatched_target_os_non_unix.rs:14:1
|
LL | #[cfg(all(not(windows), wasi))]
| ^^^^^^^^^^^^^^^^^^^^^^^^----^^^
| |
| help: try: `target_os = "wasi"`
error: aborting due to 4 previous errors

View file

@ -1,60 +0,0 @@
#![warn(clippy::mismatched_target_os)]
#![allow(unused)]
#[cfg(target_os = "linux")]
fn linux() {}
#[cfg(target_os = "freebsd")]
fn freebsd() {}
#[cfg(target_os = "dragonfly")]
fn dragonfly() {}
#[cfg(target_os = "openbsd")]
fn openbsd() {}
#[cfg(target_os = "netbsd")]
fn netbsd() {}
#[cfg(target_os = "macos")]
fn macos() {}
#[cfg(target_os = "ios")]
fn ios() {}
#[cfg(target_os = "android")]
fn android() {}
#[cfg(target_os = "emscripten")]
fn emscripten() {}
#[cfg(target_os = "fuchsia")]
fn fuchsia() {}
#[cfg(target_os = "haiku")]
fn haiku() {}
#[cfg(target_os = "illumos")]
fn illumos() {}
#[cfg(target_os = "l4re")]
fn l4re() {}
#[cfg(target_os = "redox")]
fn redox() {}
#[cfg(target_os = "solaris")]
fn solaris() {}
#[cfg(target_os = "vxworks")]
fn vxworks() {}
// list with conditions
#[cfg(all(not(any(target_os = "solaris", target_os = "linux")), target_os = "freebsd"))]
fn list() {}
// correct use, should be ignored
#[cfg(target_os = "freebsd")]
fn correct() {}
fn main() {}

View file

@ -1,60 +0,0 @@
#![warn(clippy::mismatched_target_os)]
#![allow(unused)]
#[cfg(linux)]
fn linux() {}
#[cfg(freebsd)]
fn freebsd() {}
#[cfg(dragonfly)]
fn dragonfly() {}
#[cfg(openbsd)]
fn openbsd() {}
#[cfg(netbsd)]
fn netbsd() {}
#[cfg(macos)]
fn macos() {}
#[cfg(ios)]
fn ios() {}
#[cfg(android)]
fn android() {}
#[cfg(emscripten)]
fn emscripten() {}
#[cfg(fuchsia)]
fn fuchsia() {}
#[cfg(haiku)]
fn haiku() {}
#[cfg(illumos)]
fn illumos() {}
#[cfg(l4re)]
fn l4re() {}
#[cfg(redox)]
fn redox() {}
#[cfg(solaris)]
fn solaris() {}
#[cfg(vxworks)]
fn vxworks() {}
// list with conditions
#[cfg(all(not(any(solaris, linux)), freebsd))]
fn list() {}
// correct use, should be ignored
#[cfg(target_os = "freebsd")]
fn correct() {}
fn main() {}

View file

@ -1,184 +0,0 @@
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:4:1
|
LL | #[cfg(linux)]
| ^^^^^^-----^^
| |
| help: try: `target_os = "linux"`
|
= help: did you mean `unix`?
= note: `-D clippy::mismatched-target-os` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::mismatched_target_os)]`
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:7:1
|
LL | #[cfg(freebsd)]
| ^^^^^^-------^^
| |
| help: try: `target_os = "freebsd"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:10:1
|
LL | #[cfg(dragonfly)]
| ^^^^^^---------^^
| |
| help: try: `target_os = "dragonfly"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:13:1
|
LL | #[cfg(openbsd)]
| ^^^^^^-------^^
| |
| help: try: `target_os = "openbsd"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:16:1
|
LL | #[cfg(netbsd)]
| ^^^^^^------^^
| |
| help: try: `target_os = "netbsd"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:19:1
|
LL | #[cfg(macos)]
| ^^^^^^-----^^
| |
| help: try: `target_os = "macos"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:22:1
|
LL | #[cfg(ios)]
| ^^^^^^---^^
| |
| help: try: `target_os = "ios"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:25:1
|
LL | #[cfg(android)]
| ^^^^^^-------^^
| |
| help: try: `target_os = "android"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:28:1
|
LL | #[cfg(emscripten)]
| ^^^^^^----------^^
| |
| help: try: `target_os = "emscripten"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:31:1
|
LL | #[cfg(fuchsia)]
| ^^^^^^-------^^
| |
| help: try: `target_os = "fuchsia"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:34:1
|
LL | #[cfg(haiku)]
| ^^^^^^-----^^
| |
| help: try: `target_os = "haiku"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:37:1
|
LL | #[cfg(illumos)]
| ^^^^^^-------^^
| |
| help: try: `target_os = "illumos"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:40:1
|
LL | #[cfg(l4re)]
| ^^^^^^----^^
| |
| help: try: `target_os = "l4re"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:43:1
|
LL | #[cfg(redox)]
| ^^^^^^-----^^
| |
| help: try: `target_os = "redox"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:46:1
|
LL | #[cfg(solaris)]
| ^^^^^^-------^^
| |
| help: try: `target_os = "solaris"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:49:1
|
LL | #[cfg(vxworks)]
| ^^^^^^-------^^
| |
| help: try: `target_os = "vxworks"`
|
= help: did you mean `unix`?
error: operating system used in target family position
--> tests/ui/mismatched_target_os_unix.rs:53:1
|
LL | #[cfg(all(not(any(solaris, linux)), freebsd))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: did you mean `unix`?
help: try
|
LL | #[cfg(all(not(any(target_os = "solaris", linux)), freebsd))]
| ~~~~~~~~~~~~~~~~~~~~~
help: try
|
LL | #[cfg(all(not(any(solaris, target_os = "linux")), freebsd))]
| ~~~~~~~~~~~~~~~~~~~
help: try
|
LL | #[cfg(all(not(any(solaris, linux)), target_os = "freebsd"))]
| ~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 17 previous errors

View file

@ -141,3 +141,33 @@ mod msrv {
let _ = unsafe { bar.val };
}
}
mod issue12677 {
pub struct Wrapper {
pub strings: Vec<String>,
}
impl Wrapper {
#[must_use]
pub fn new(strings: Vec<String>) -> Self {
Self { strings }
}
#[must_use]
pub fn empty() -> Self {
Self { strings: Vec::new() }
}
}
pub struct Other {
pub text: String,
pub vec: Vec<String>,
}
impl Other {
pub fn new(text: String) -> Self {
let vec = Vec::new();
Self { text, vec }
}
}
}

View file

@ -130,5 +130,30 @@ LL | | let _ = unsafe { bar.val };
LL | | }
| |_____^
error: aborting due to 14 previous errors
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:152:9
|
LL | / pub fn new(strings: Vec<String>) -> Self {
LL | | Self { strings }
LL | | }
| |_________^
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:157:9
|
LL | / pub fn empty() -> Self {
LL | | Self { strings: Vec::new() }
LL | | }
| |_________^
error: this could be a `const fn`
--> tests/ui/missing_const_for_fn/could_be_const.rs:168:9
|
LL | / pub fn new(text: String) -> Self {
LL | | let vec = Vec::new();
LL | | Self { text, vec }
LL | | }
| |_________^
error: aborting due to 17 previous errors

View file

@ -4,6 +4,7 @@
use std::fmt;
use std::marker::PhantomData;
use std::ops::Deref;
use std::thread::LocalKey;
struct NamedStruct1Ignored {
data: u8,
@ -191,4 +192,21 @@ impl fmt::Debug for WithPD {
}
}
struct InClosure {
a: u8,
b: String,
}
impl fmt::Debug for InClosure {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_struct("InClosure");
d.field("a", &self.a);
let mut c = || {
d.field("b", &self.b);
};
c();
d.finish()
}
}
fn main() {}

View file

@ -1,5 +1,5 @@
error: manual `Debug` impl does not include all fields
--> tests/ui/missing_fields_in_debug.rs:13:1
--> tests/ui/missing_fields_in_debug.rs:14:1
|
LL | / impl fmt::Debug for NamedStruct1Ignored {
LL | |
@ -11,7 +11,7 @@ LL | | }
| |_^
|
note: this field is unused
--> tests/ui/missing_fields_in_debug.rs:10:5
--> tests/ui/missing_fields_in_debug.rs:11:5
|
LL | hidden: u32,
| ^^^^^^^^^^^
@ -21,7 +21,7 @@ LL | hidden: u32,
= help: to override `-D warnings` add `#[allow(clippy::missing_fields_in_debug)]`
error: manual `Debug` impl does not include all fields
--> tests/ui/missing_fields_in_debug.rs:32:1
--> tests/ui/missing_fields_in_debug.rs:33:1
|
LL | / impl fmt::Debug for NamedStructMultipleIgnored {
LL | |
@ -33,17 +33,17 @@ LL | | }
| |_^
|
note: this field is unused
--> tests/ui/missing_fields_in_debug.rs:26:5
--> tests/ui/missing_fields_in_debug.rs:27:5
|
LL | hidden: u32,
| ^^^^^^^^^^^
note: this field is unused
--> tests/ui/missing_fields_in_debug.rs:27:5
--> tests/ui/missing_fields_in_debug.rs:28:5
|
LL | hidden2: String,
| ^^^^^^^^^^^^^^^
note: this field is unused
--> tests/ui/missing_fields_in_debug.rs:29:5
--> tests/ui/missing_fields_in_debug.rs:30:5
|
LL | hidden4: ((((u8), u16), u32), u64),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -51,7 +51,7 @@ LL | hidden4: ((((u8), u16), u32), u64),
= help: consider calling `.finish_non_exhaustive()` if you intend to ignore fields
error: manual `Debug` impl does not include all fields
--> tests/ui/missing_fields_in_debug.rs:94:1
--> tests/ui/missing_fields_in_debug.rs:95:1
|
LL | / impl fmt::Debug for MultiExprDebugImpl {
LL | |
@ -63,7 +63,7 @@ LL | | }
| |_^
|
note: this field is unused
--> tests/ui/missing_fields_in_debug.rs:90:5
--> tests/ui/missing_fields_in_debug.rs:91:5
|
LL | b: String,
| ^^^^^^^^^

View file

@ -131,3 +131,15 @@ fn needless_bool_condition() -> bool {
foo()
}
fn issue12846() {
let a = true;
let b = false;
// parentheses are needed here
let _x = (a && b).then(|| todo!());
let _x = (a && b) as u8;
// parentheses are not needed here
let _x = a.then(|| todo!());
}

View file

@ -191,3 +191,15 @@ fn needless_bool_condition() -> bool {
foo()
}
fn issue12846() {
let a = true;
let b = false;
// parentheses are needed here
let _x = if a && b { true } else { false }.then(|| todo!());
let _x = if a && b { true } else { false } as u8;
// parentheses are not needed here
let _x = if a { true } else { false }.then(|| todo!());
}

View file

@ -191,5 +191,23 @@ error: this if-then-else expression returns a bool literal
LL | if unsafe { no(4) } & 1 != 0 { true } else { false }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(unsafe { no(4) } & 1 != 0)`
error: aborting due to 21 previous errors
error: this if-then-else expression returns a bool literal
--> tests/ui/needless_bool/fixable.rs:200:14
|
LL | let _x = if a && b { true } else { false }.then(|| todo!());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)`
error: this if-then-else expression returns a bool literal
--> tests/ui/needless_bool/fixable.rs:201:14
|
LL | let _x = if a && b { true } else { false } as u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `(a && b)`
error: this if-then-else expression returns a bool literal
--> tests/ui/needless_bool/fixable.rs:204:14
|
LL | let _x = if a { true } else { false }.then(|| todo!());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `a`
error: aborting due to 24 previous errors

View file

@ -0,0 +1,57 @@
#![warn(clippy::needless_character_iteration)]
#![allow(clippy::map_identity, clippy::unnecessary_operation)]
#[derive(Default)]
struct S {
field: &'static str,
}
impl S {
fn field(&self) -> &str {
self.field
}
}
fn magic(_: char) {}
fn main() {
"foo".is_ascii();
//~^ ERROR: checking if a string is ascii using iterators
!"foo".is_ascii();
//~^ ERROR: checking if a string is ascii using iterators
"foo".is_ascii();
//~^ ERROR: checking if a string is ascii using iterators
!"foo".is_ascii();
//~^ ERROR: checking if a string is ascii using iterators
let s = String::new();
s.is_ascii();
//~^ ERROR: checking if a string is ascii using iterators
!"foo".to_string().is_ascii();
//~^ ERROR: checking if a string is ascii using iterators
"foo".is_ascii();
!"foo".is_ascii();
S::default().field().is_ascii();
//~^ ERROR: checking if a string is ascii using iterators
// Should not lint!
"foo".chars().all(|c| {
let x = c;
magic(x);
x.is_ascii()
});
// Should not lint!
"foo".chars().all(|c| c.is_ascii() && c.is_alphabetic());
// Should not lint!
"foo".chars().map(|c| c).all(|c| !char::is_ascii(&c));
// Should not lint!
"foo".chars().all(|c| !c.is_ascii());
// Should not lint!
"foo".chars().any(|c| c.is_ascii());
}

View file

@ -0,0 +1,65 @@
#![warn(clippy::needless_character_iteration)]
#![allow(clippy::map_identity, clippy::unnecessary_operation)]
#[derive(Default)]
struct S {
field: &'static str,
}
impl S {
fn field(&self) -> &str {
self.field
}
}
fn magic(_: char) {}
fn main() {
"foo".chars().all(|c| c.is_ascii());
//~^ ERROR: checking if a string is ascii using iterators
"foo".chars().any(|c| !c.is_ascii());
//~^ ERROR: checking if a string is ascii using iterators
"foo".chars().all(|c| char::is_ascii(&c));
//~^ ERROR: checking if a string is ascii using iterators
"foo".chars().any(|c| !char::is_ascii(&c));
//~^ ERROR: checking if a string is ascii using iterators
let s = String::new();
s.chars().all(|c| c.is_ascii());
//~^ ERROR: checking if a string is ascii using iterators
"foo".to_string().chars().any(|c| !c.is_ascii());
//~^ ERROR: checking if a string is ascii using iterators
"foo".chars().all(|c| {
//~^ ERROR: checking if a string is ascii using iterators
let x = c;
x.is_ascii()
});
"foo".chars().any(|c| {
//~^ ERROR: checking if a string is ascii using iterators
let x = c;
!x.is_ascii()
});
S::default().field().chars().all(|x| x.is_ascii());
//~^ ERROR: checking if a string is ascii using iterators
// Should not lint!
"foo".chars().all(|c| {
let x = c;
magic(x);
x.is_ascii()
});
// Should not lint!
"foo".chars().all(|c| c.is_ascii() && c.is_alphabetic());
// Should not lint!
"foo".chars().map(|c| c).all(|c| !char::is_ascii(&c));
// Should not lint!
"foo".chars().all(|c| !c.is_ascii());
// Should not lint!
"foo".chars().any(|c| c.is_ascii());
}

View file

@ -0,0 +1,67 @@
error: checking if a string is ascii using iterators
--> tests/ui/needless_character_iteration.rs:18:5
|
LL | "foo".chars().all(|c| c.is_ascii());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"foo".is_ascii()`
|
= note: `-D clippy::needless-character-iteration` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::needless_character_iteration)]`
error: checking if a string is ascii using iterators
--> tests/ui/needless_character_iteration.rs:20:5
|
LL | "foo".chars().any(|c| !c.is_ascii());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".is_ascii()`
error: checking if a string is ascii using iterators
--> tests/ui/needless_character_iteration.rs:22:5
|
LL | "foo".chars().all(|c| char::is_ascii(&c));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"foo".is_ascii()`
error: checking if a string is ascii using iterators
--> tests/ui/needless_character_iteration.rs:24:5
|
LL | "foo".chars().any(|c| !char::is_ascii(&c));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".is_ascii()`
error: checking if a string is ascii using iterators
--> tests/ui/needless_character_iteration.rs:28:5
|
LL | s.chars().all(|c| c.is_ascii());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.is_ascii()`
error: checking if a string is ascii using iterators
--> tests/ui/needless_character_iteration.rs:30:5
|
LL | "foo".to_string().chars().any(|c| !c.is_ascii());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!"foo".to_string().is_ascii()`
error: checking if a string is ascii using iterators
--> tests/ui/needless_character_iteration.rs:33:5
|
LL | / "foo".chars().all(|c| {
LL | |
LL | | let x = c;
LL | | x.is_ascii()
LL | | });
| |______^ help: try: `"foo".is_ascii()`
error: checking if a string is ascii using iterators
--> tests/ui/needless_character_iteration.rs:38:5
|
LL | / "foo".chars().any(|c| {
LL | |
LL | | let x = c;
LL | | !x.is_ascii()
LL | | });
| |______^ help: try: `!"foo".is_ascii()`
error: checking if a string is ascii using iterators
--> tests/ui/needless_character_iteration.rs:44:5
|
LL | S::default().field().chars().all(|x| x.is_ascii());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `S::default().field().is_ascii()`
error: aborting due to 9 previous errors

View file

@ -10,7 +10,7 @@
/// unimplemented!();
/// }
/// ```
///
///
/// With an explicit return type it should lint too
/// ```edition2015
/// fn main() -> () {
@ -18,7 +18,7 @@
/// unimplemented!();
/// }
/// ```
///
///
/// This should, too.
/// ```rust
/// fn main() {
@ -26,7 +26,7 @@
/// unimplemented!();
/// }
/// ```
///
///
/// This one too.
/// ```no_run
/// // the fn is not always the first line

View file

@ -0,0 +1,116 @@
//@aux-build:proc_macros.rs
#![allow(unused, clippy::multiple_bound_locations)]
#![warn(clippy::needless_maybe_sized)]
extern crate proc_macros;
use proc_macros::external;
fn directly<T: Sized>(t: &T) {}
trait A: Sized {}
trait B: A {}
fn depth_1<T: A>(t: &T) {}
fn depth_2<T: B>(t: &T) {}
// We only need to show one
fn multiple_paths<T: A + B>(t: &T) {}
fn in_where<T>(t: &T)
where
T: Sized,
{
}
fn mixed_1<T: Sized>(t: &T)
{
}
fn mixed_2<T>(t: &T)
where
T: Sized,
{
}
fn mixed_3<T>(t: &T)
where
T: Sized,
{
}
struct Struct<T: Sized>(T);
impl<T: Sized> Struct<T> {
fn method<U: Sized>(&self) {}
}
enum Enum<T: Sized + 'static> {
Variant(&'static T),
}
union Union<'a, T: Sized> {
a: &'a T,
}
trait Trait<T: Sized> {
fn trait_method<U: Sized>() {}
type GAT<U: Sized>;
type Assoc: Sized + ?Sized; // False negative
}
trait SecondInTrait: Send + Sized {}
fn second_in_trait<T: SecondInTrait>() {}
fn impl_trait(_: &(impl Sized)) {}
trait GenericTrait<T>: Sized {}
fn in_generic_trait<T: GenericTrait<U>, U>() {}
mod larger_graph {
// C1 C2 Sized
// \ /\ /
// B1 B2
// \ /
// A1
trait C1 {}
trait C2 {}
trait B1: C1 + C2 {}
trait B2: C2 + Sized {}
trait A1: B1 + B2 {}
fn larger_graph<T: A1>() {}
}
// Should not lint
fn sized<T: Sized>() {}
fn maybe_sized<T: ?Sized>() {}
struct SeparateBounds<T: ?Sized>(T);
impl<T: Sized> SeparateBounds<T> {}
trait P {}
trait Q: P {}
fn ok_depth_1<T: P + ?Sized>() {}
fn ok_depth_2<T: Q + ?Sized>() {}
external! {
fn in_macro<T: Clone + ?Sized>(t: &T) {}
fn with_local_clone<T: $Clone + ?Sized>(t: &T) {}
}
#[derive(Clone)]
struct InDerive<T: ?Sized> {
t: T,
}
struct Refined<T: ?Sized>(T);
impl<T: Sized> Refined<T> {}
fn main() {}

View file

@ -0,0 +1,119 @@
//@aux-build:proc_macros.rs
#![allow(unused, clippy::multiple_bound_locations)]
#![warn(clippy::needless_maybe_sized)]
extern crate proc_macros;
use proc_macros::external;
fn directly<T: Sized + ?Sized>(t: &T) {}
trait A: Sized {}
trait B: A {}
fn depth_1<T: A + ?Sized>(t: &T) {}
fn depth_2<T: B + ?Sized>(t: &T) {}
// We only need to show one
fn multiple_paths<T: A + B + ?Sized>(t: &T) {}
fn in_where<T>(t: &T)
where
T: Sized + ?Sized,
{
}
fn mixed_1<T: Sized>(t: &T)
where
T: ?Sized,
{
}
fn mixed_2<T: ?Sized>(t: &T)
where
T: Sized,
{
}
fn mixed_3<T>(t: &T)
where
T: Sized,
T: ?Sized,
{
}
struct Struct<T: Sized + ?Sized>(T);
impl<T: Sized + ?Sized> Struct<T> {
fn method<U: Sized + ?Sized>(&self) {}
}
enum Enum<T: Sized + ?Sized + 'static> {
Variant(&'static T),
}
union Union<'a, T: Sized + ?Sized> {
a: &'a T,
}
trait Trait<T: Sized + ?Sized> {
fn trait_method<U: Sized + ?Sized>() {}
type GAT<U: Sized + ?Sized>;
type Assoc: Sized + ?Sized; // False negative
}
trait SecondInTrait: Send + Sized {}
fn second_in_trait<T: ?Sized + SecondInTrait>() {}
fn impl_trait(_: &(impl Sized + ?Sized)) {}
trait GenericTrait<T>: Sized {}
fn in_generic_trait<T: GenericTrait<U> + ?Sized, U>() {}
mod larger_graph {
// C1 C2 Sized
// \ /\ /
// B1 B2
// \ /
// A1
trait C1 {}
trait C2 {}
trait B1: C1 + C2 {}
trait B2: C2 + Sized {}
trait A1: B1 + B2 {}
fn larger_graph<T: A1 + ?Sized>() {}
}
// Should not lint
fn sized<T: Sized>() {}
fn maybe_sized<T: ?Sized>() {}
struct SeparateBounds<T: ?Sized>(T);
impl<T: Sized> SeparateBounds<T> {}
trait P {}
trait Q: P {}
fn ok_depth_1<T: P + ?Sized>() {}
fn ok_depth_2<T: Q + ?Sized>() {}
external! {
fn in_macro<T: Clone + ?Sized>(t: &T) {}
fn with_local_clone<T: $Clone + ?Sized>(t: &T) {}
}
#[derive(Clone)]
struct InDerive<T: ?Sized> {
t: T,
}
struct Refined<T: ?Sized>(T);
impl<T: Sized> Refined<T> {}
fn main() {}

View file

@ -0,0 +1,353 @@
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:9:24
|
LL | fn directly<T: Sized + ?Sized>(t: &T) {}
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:9:16
|
LL | fn directly<T: Sized + ?Sized>(t: &T) {}
| ^^^^^
= note: `-D clippy::needless-maybe-sized` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::needless_maybe_sized)]`
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn directly<T: Sized + ?Sized>(t: &T) {}
LL + fn directly<T: Sized>(t: &T) {}
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:14:19
|
LL | fn depth_1<T: A + ?Sized>(t: &T) {}
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:14:15
|
LL | fn depth_1<T: A + ?Sized>(t: &T) {}
| ^
= note: ...because `A` has the bound `Sized`
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn depth_1<T: A + ?Sized>(t: &T) {}
LL + fn depth_1<T: A>(t: &T) {}
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:15:19
|
LL | fn depth_2<T: B + ?Sized>(t: &T) {}
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:15:15
|
LL | fn depth_2<T: B + ?Sized>(t: &T) {}
| ^
= note: ...because `B` has the bound `A`
= note: ...because `A` has the bound `Sized`
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn depth_2<T: B + ?Sized>(t: &T) {}
LL + fn depth_2<T: B>(t: &T) {}
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:18:30
|
LL | fn multiple_paths<T: A + B + ?Sized>(t: &T) {}
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:18:22
|
LL | fn multiple_paths<T: A + B + ?Sized>(t: &T) {}
| ^
= note: ...because `A` has the bound `Sized`
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn multiple_paths<T: A + B + ?Sized>(t: &T) {}
LL + fn multiple_paths<T: A + B>(t: &T) {}
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:22:16
|
LL | T: Sized + ?Sized,
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:22:8
|
LL | T: Sized + ?Sized,
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - T: Sized + ?Sized,
LL + T: Sized,
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:28:8
|
LL | T: ?Sized,
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:26:15
|
LL | fn mixed_1<T: Sized>(t: &T)
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - where
LL - T: ?Sized,
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:32:15
|
LL | fn mixed_2<T: ?Sized>(t: &T)
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:34:8
|
LL | T: Sized,
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn mixed_2<T: ?Sized>(t: &T)
LL + fn mixed_2<T>(t: &T)
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:41:8
|
LL | T: ?Sized,
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:40:8
|
LL | T: Sized,
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - T: Sized,
LL - T: ?Sized,
LL + T: Sized,
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:45:26
|
LL | struct Struct<T: Sized + ?Sized>(T);
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:45:18
|
LL | struct Struct<T: Sized + ?Sized>(T);
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - struct Struct<T: Sized + ?Sized>(T);
LL + struct Struct<T: Sized>(T);
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:47:17
|
LL | impl<T: Sized + ?Sized> Struct<T> {
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:47:9
|
LL | impl<T: Sized + ?Sized> Struct<T> {
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - impl<T: Sized + ?Sized> Struct<T> {
LL + impl<T: Sized> Struct<T> {
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:48:26
|
LL | fn method<U: Sized + ?Sized>(&self) {}
| ^^^^^^
|
note: `U` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:48:18
|
LL | fn method<U: Sized + ?Sized>(&self) {}
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn method<U: Sized + ?Sized>(&self) {}
LL + fn method<U: Sized>(&self) {}
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:51:22
|
LL | enum Enum<T: Sized + ?Sized + 'static> {
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:51:14
|
LL | enum Enum<T: Sized + ?Sized + 'static> {
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - enum Enum<T: Sized + ?Sized + 'static> {
LL + enum Enum<T: Sized + 'static> {
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:55:28
|
LL | union Union<'a, T: Sized + ?Sized> {
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:55:20
|
LL | union Union<'a, T: Sized + ?Sized> {
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - union Union<'a, T: Sized + ?Sized> {
LL + union Union<'a, T: Sized> {
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:59:24
|
LL | trait Trait<T: Sized + ?Sized> {
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:59:16
|
LL | trait Trait<T: Sized + ?Sized> {
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - trait Trait<T: Sized + ?Sized> {
LL + trait Trait<T: Sized> {
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:60:32
|
LL | fn trait_method<U: Sized + ?Sized>() {}
| ^^^^^^
|
note: `U` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:60:24
|
LL | fn trait_method<U: Sized + ?Sized>() {}
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn trait_method<U: Sized + ?Sized>() {}
LL + fn trait_method<U: Sized>() {}
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:62:25
|
LL | type GAT<U: Sized + ?Sized>;
| ^^^^^^
|
note: `U` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:62:17
|
LL | type GAT<U: Sized + ?Sized>;
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - type GAT<U: Sized + ?Sized>;
LL + type GAT<U: Sized>;
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:68:23
|
LL | fn second_in_trait<T: ?Sized + SecondInTrait>() {}
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:68:32
|
LL | fn second_in_trait<T: ?Sized + SecondInTrait>() {}
| ^^^^^^^^^^^^^
= note: ...because `SecondInTrait` has the bound `Sized`
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn second_in_trait<T: ?Sized + SecondInTrait>() {}
LL + fn second_in_trait<T: SecondInTrait>() {}
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:70:33
|
LL | fn impl_trait(_: &(impl Sized + ?Sized)) {}
| ^^^^^^
|
note: `impl Sized + ?Sized` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:70:25
|
LL | fn impl_trait(_: &(impl Sized + ?Sized)) {}
| ^^^^^
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn impl_trait(_: &(impl Sized + ?Sized)) {}
LL + fn impl_trait(_: &(impl Sized)) {}
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:73:42
|
LL | fn in_generic_trait<T: GenericTrait<U> + ?Sized, U>() {}
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:73:24
|
LL | fn in_generic_trait<T: GenericTrait<U> + ?Sized, U>() {}
| ^^^^^^^^^^^^^^^
= note: ...because `GenericTrait` has the bound `Sized`
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn in_generic_trait<T: GenericTrait<U> + ?Sized, U>() {}
LL + fn in_generic_trait<T: GenericTrait<U>, U>() {}
|
error: `?Sized` bound is ignored because of a `Sized` requirement
--> tests/ui/needless_maybe_sized.rs:88:29
|
LL | fn larger_graph<T: A1 + ?Sized>() {}
| ^^^^^^
|
note: `T` cannot be unsized because of the bound
--> tests/ui/needless_maybe_sized.rs:88:24
|
LL | fn larger_graph<T: A1 + ?Sized>() {}
| ^^
= note: ...because `A1` has the bound `B2`
= note: ...because `B2` has the bound `Sized`
help: change the bounds that require `Sized`, or remove the `?Sized` bound
|
LL - fn larger_graph<T: A1 + ?Sized>() {}
LL + fn larger_graph<T: A1>() {}
|
error: aborting due to 20 previous errors

View file

@ -1,7 +1,11 @@
//@aux-build:proc_macro_derive.rs
#![allow(clippy::clone_on_copy, unused)]
#![allow(clippy::assigning_clones)]
#![no_main]
extern crate proc_macros;
use proc_macros::with_span;
// lint
struct A(u32);
@ -95,3 +99,19 @@ impl<A: Copy> Clone for Uwu<A> {
}
impl<A: std::fmt::Debug + Copy + Clone> Copy for Uwu<A> {}
// should skip proc macros, see https://github.com/rust-lang/rust-clippy/issues/12788
#[derive(proc_macro_derive::NonCanonicalClone)]
pub struct G;
with_span!(
span
#[derive(Copy)]
struct H;
impl Clone for H {
fn clone(&self) -> Self {
todo!()
}
}
);

View file

@ -1,7 +1,11 @@
//@aux-build:proc_macro_derive.rs
#![allow(clippy::clone_on_copy, unused)]
#![allow(clippy::assigning_clones)]
#![no_main]
extern crate proc_macros;
use proc_macros::with_span;
// lint
struct A(u32);
@ -105,3 +109,19 @@ impl<A: Copy> Clone for Uwu<A> {
}
impl<A: std::fmt::Debug + Copy + Clone> Copy for Uwu<A> {}
// should skip proc macros, see https://github.com/rust-lang/rust-clippy/issues/12788
#[derive(proc_macro_derive::NonCanonicalClone)]
pub struct G;
with_span!(
span
#[derive(Copy)]
struct H;
impl Clone for H {
fn clone(&self) -> Self {
todo!()
}
}
);

View file

@ -1,5 +1,5 @@
error: non-canonical implementation of `clone` on a `Copy` type
--> tests/ui/non_canonical_clone_impl.rs:10:29
--> tests/ui/non_canonical_clone_impl.rs:14:29
|
LL | fn clone(&self) -> Self {
| _____________________________^
@ -11,7 +11,7 @@ LL | | }
= help: to override `-D warnings` add `#[allow(clippy::non_canonical_clone_impl)]`
error: unnecessary implementation of `clone_from` on a `Copy` type
--> tests/ui/non_canonical_clone_impl.rs:14:5
--> tests/ui/non_canonical_clone_impl.rs:18:5
|
LL | / fn clone_from(&mut self, source: &Self) {
LL | | source.clone();
@ -20,7 +20,7 @@ LL | | }
| |_____^ help: remove it
error: non-canonical implementation of `clone` on a `Copy` type
--> tests/ui/non_canonical_clone_impl.rs:81:29
--> tests/ui/non_canonical_clone_impl.rs:85:29
|
LL | fn clone(&self) -> Self {
| _____________________________^
@ -29,7 +29,7 @@ LL | | }
| |_____^ help: change this to: `{ *self }`
error: unnecessary implementation of `clone_from` on a `Copy` type
--> tests/ui/non_canonical_clone_impl.rs:85:5
--> tests/ui/non_canonical_clone_impl.rs:89:5
|
LL | / fn clone_from(&mut self, source: &Self) {
LL | | source.clone();

View file

@ -1,5 +1,3 @@
//@compile-flags: -Zdeduplicate-diagnostics=yes
#![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)]
#![warn(clippy::nonminimal_bool)]

View file

@ -1,5 +1,3 @@
//@compile-flags: -Zdeduplicate-diagnostics=yes
#![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)]
#![warn(clippy::nonminimal_bool)]

View file

@ -1,5 +1,5 @@
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:10:13
--> tests/ui/nonminimal_bool_methods.rs:8:13
|
LL | let _ = !a.is_some();
| ^^^^^^^^^^^^ help: try: `a.is_none()`
@ -8,91 +8,91 @@ LL | let _ = !a.is_some();
= help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:12:13
--> tests/ui/nonminimal_bool_methods.rs:10:13
|
LL | let _ = !a.is_none();
| ^^^^^^^^^^^^ help: try: `a.is_some()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:14:13
--> tests/ui/nonminimal_bool_methods.rs:12:13
|
LL | let _ = !b.is_err();
| ^^^^^^^^^^^ help: try: `b.is_ok()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:16:13
--> tests/ui/nonminimal_bool_methods.rs:14:13
|
LL | let _ = !b.is_ok();
| ^^^^^^^^^^ help: try: `b.is_err()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:18:13
--> tests/ui/nonminimal_bool_methods.rs:16:13
|
LL | let _ = !(a.is_some() && !c);
| ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() || c`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:19:13
--> tests/ui/nonminimal_bool_methods.rs:17:13
|
LL | let _ = !(a.is_some() || !c);
| ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() && c`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:20:26
--> tests/ui/nonminimal_bool_methods.rs:18:26
|
LL | let _ = !(!c ^ c) || !a.is_some();
| ^^^^^^^^^^^^ help: try: `a.is_none()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:21:25
--> tests/ui/nonminimal_bool_methods.rs:19:25
|
LL | let _ = (!c ^ c) || !a.is_some();
| ^^^^^^^^^^^^ help: try: `a.is_none()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:22:23
--> tests/ui/nonminimal_bool_methods.rs:20:23
|
LL | let _ = !c ^ c || !a.is_some();
| ^^^^^^^^^^^^ help: try: `a.is_none()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:94:8
--> tests/ui/nonminimal_bool_methods.rs:92:8
|
LL | if !res.is_ok() {}
| ^^^^^^^^^^^^ help: try: `res.is_err()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:95:8
--> tests/ui/nonminimal_bool_methods.rs:93:8
|
LL | if !res.is_err() {}
| ^^^^^^^^^^^^^ help: try: `res.is_ok()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:98:8
--> tests/ui/nonminimal_bool_methods.rs:96:8
|
LL | if !res.is_some() {}
| ^^^^^^^^^^^^^^ help: try: `res.is_none()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:99:8
--> tests/ui/nonminimal_bool_methods.rs:97:8
|
LL | if !res.is_none() {}
| ^^^^^^^^^^^^^^ help: try: `res.is_some()`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:115:8
--> tests/ui/nonminimal_bool_methods.rs:113:8
|
LL | if !(a as u64 >= b) {}
| ^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:116:8
--> tests/ui/nonminimal_bool_methods.rs:114:8
|
LL | if !((a as u64) >= b) {}
| ^^^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b`
error: this boolean expression can be simplified
--> tests/ui/nonminimal_bool_methods.rs:117:8
--> tests/ui/nonminimal_bool_methods.rs:115:8
|
LL | if !(a as u64 <= b) {}
| ^^^^^^^^^^^^^^^^ help: try: `a as u64 > b`

View file

@ -311,4 +311,11 @@ mod lazy {
}
}
fn host_effect() {
// #12877 - make sure we don't ICE in type_certainty
use std::ops::Add;
Add::<i32>::add(1, 1).add(i32::MIN);
}
fn main() {}

View file

@ -311,4 +311,11 @@ mod lazy {
}
}
fn host_effect() {
// #12877 - make sure we don't ICE in type_certainty
use std::ops::Add;
Add::<i32>::add(1, 1).add(i32::MIN);
}
fn main() {}

View file

@ -37,3 +37,13 @@ fn check_expect() {
#[expect(clippy::overly_complex_bool_expr)]
let _ = a < b && a >= b;
}
#[allow(clippy::never_loop)]
fn check_never_type() {
loop {
_ = (break) || true;
}
loop {
_ = (return) || true;
}
}

View file

@ -37,3 +37,13 @@ fn check_expect() {
#[expect(clippy::overly_complex_bool_expr)]
let _ = a < b && a >= b;
}
#[allow(clippy::never_loop)]
fn check_never_type() {
loop {
_ = (break) || true;
}
loop {
_ = (return) || true;
}
}

View file

@ -56,6 +56,11 @@ fn function_result_with_panic() -> Result<bool, String> // should emit lint
panic!("error");
}
fn in_closure() -> Result<bool, String> {
let c = || panic!();
c()
}
fn todo() {
println!("something");
}

View file

@ -34,5 +34,21 @@ note: return Err() instead of panicking
LL | panic!("error");
| ^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error: used `panic!()` or assertion in a function that returns `Result`
--> tests/ui/panic_in_result_fn.rs:59:1
|
LL | / fn in_closure() -> Result<bool, String> {
LL | | let c = || panic!();
LL | | c()
LL | | }
| |_^
|
= help: `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing
note: return Err() instead of panicking
--> tests/ui/panic_in_result_fn.rs:60:16
|
LL | let c = || panic!();
| ^^^^^^^^
error: aborting due to 3 previous errors

View file

@ -1,5 +1,6 @@
//@aux-build:option_helpers.rs
#![warn(clippy::search_is_some)]
#![allow(clippy::manual_pattern_char_comparison)]
#![allow(clippy::useless_vec)]
#![allow(dead_code)]
extern crate option_helpers;

View file

@ -1,5 +1,5 @@
error: called `is_some()` after searching an `Iterator` with `find`
--> tests/ui/search_is_some.rs:15:13
--> tests/ui/search_is_some.rs:16:13
|
LL | let _ = v.iter().find(|&x| {
| _____________^
@ -13,7 +13,7 @@ LL | | ).is_some();
= help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
error: called `is_some()` after searching an `Iterator` with `position`
--> tests/ui/search_is_some.rs:21:13
--> tests/ui/search_is_some.rs:22:13
|
LL | let _ = v.iter().position(|&x| {
| _____________^
@ -25,7 +25,7 @@ LL | | ).is_some();
= help: this is more succinctly expressed by calling `any()`
error: called `is_some()` after searching an `Iterator` with `rposition`
--> tests/ui/search_is_some.rs:27:13
--> tests/ui/search_is_some.rs:28:13
|
LL | let _ = v.iter().rposition(|&x| {
| _____________^
@ -37,13 +37,13 @@ LL | | ).is_some();
= help: this is more succinctly expressed by calling `any()`
error: called `is_some()` after searching an `Iterator` with `find`
--> tests/ui/search_is_some.rs:42:20
--> tests/ui/search_is_some.rs:43:20
|
LL | let _ = (0..1).find(some_closure).is_some();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(some_closure)`
error: called `is_none()` after searching an `Iterator` with `find`
--> tests/ui/search_is_some.rs:52:13
--> tests/ui/search_is_some.rs:53:13
|
LL | let _ = v.iter().find(|&x| {
| _____________^
@ -55,7 +55,7 @@ LL | | ).is_none();
= help: this is more succinctly expressed by calling `any()` with negation
error: called `is_none()` after searching an `Iterator` with `position`
--> tests/ui/search_is_some.rs:58:13
--> tests/ui/search_is_some.rs:59:13
|
LL | let _ = v.iter().position(|&x| {
| _____________^
@ -67,7 +67,7 @@ LL | | ).is_none();
= help: this is more succinctly expressed by calling `any()` with negation
error: called `is_none()` after searching an `Iterator` with `rposition`
--> tests/ui/search_is_some.rs:64:13
--> tests/ui/search_is_some.rs:65:13
|
LL | let _ = v.iter().rposition(|&x| {
| _____________^
@ -79,7 +79,7 @@ LL | | ).is_none();
= help: this is more succinctly expressed by calling `any()` with negation
error: called `is_none()` after searching an `Iterator` with `find`
--> tests/ui/search_is_some.rs:79:13
--> tests/ui/search_is_some.rs:80:13
|
LL | let _ = (0..1).find(some_closure).is_none();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(some_closure)`

View file

@ -21,6 +21,12 @@ fn main() {
string.push('\u{0052}');
string.push('a');
let c_ref = &'a';
string.push(*c_ref);
let c = 'a';
string.push(c);
string.push('a');
get_string!().push('ö');
// `insert_str` tests
@ -41,5 +47,9 @@ fn main() {
string.insert(Y, '"');
string.insert(Y, '\'');
string.insert(0, *c_ref);
string.insert(0, c);
string.insert(0, 'a');
get_string!().insert(1, '?');
}

View file

@ -21,6 +21,12 @@ fn main() {
string.push_str("\u{0052}");
string.push_str(r##"a"##);
let c_ref = &'a';
string.push_str(&c_ref.to_string());
let c = 'a';
string.push_str(&c.to_string());
string.push_str(&'a'.to_string());
get_string!().push_str("ö");
// `insert_str` tests
@ -41,5 +47,9 @@ fn main() {
string.insert_str(Y, r##"""##);
string.insert_str(Y, r##"'"##);
string.insert_str(0, &c_ref.to_string());
string.insert_str(0, &c.to_string());
string.insert_str(0, &'a'.to_string());
get_string!().insert_str(1, "?");
}

View file

@ -31,65 +31,101 @@ error: calling `push_str()` using a single-character string literal
LL | string.push_str(r##"a"##);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `string.push('a')`
error: calling `push_str()` using a single-character converted to string
--> tests/ui/single_char_add_str.rs:25:5
|
LL | string.push_str(&c_ref.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push(*c_ref)`
error: calling `push_str()` using a single-character converted to string
--> tests/ui/single_char_add_str.rs:27:5
|
LL | string.push_str(&c.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push(c)`
error: calling `push_str()` using a single-character converted to string
--> tests/ui/single_char_add_str.rs:28:5
|
LL | string.push_str(&'a'.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` without `to_string()`: `string.push('a')`
error: calling `push_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:24:5
--> tests/ui/single_char_add_str.rs:30:5
|
LL | get_string!().push_str("ö");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `push` with a character literal: `get_string!().push('ö')`
error: calling `insert_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:29:5
--> tests/ui/single_char_add_str.rs:35:5
|
LL | string.insert_str(0, "R");
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, 'R')`
error: calling `insert_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:30:5
--> tests/ui/single_char_add_str.rs:36:5
|
LL | string.insert_str(1, "'");
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(1, '\'')`
error: calling `insert_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:35:5
--> tests/ui/single_char_add_str.rs:41:5
|
LL | string.insert_str(0, "\x52");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\x52')`
error: calling `insert_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:36:5
--> tests/ui/single_char_add_str.rs:42:5
|
LL | string.insert_str(0, "\u{0052}");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(0, '\u{0052}')`
error: calling `insert_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:38:5
--> tests/ui/single_char_add_str.rs:44:5
|
LL | string.insert_str(x, r##"a"##);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(x, 'a')`
error: calling `insert_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:40:5
--> tests/ui/single_char_add_str.rs:46:5
|
LL | string.insert_str(Y, r##"a"##);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, 'a')`
error: calling `insert_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:41:5
--> tests/ui/single_char_add_str.rs:47:5
|
LL | string.insert_str(Y, r##"""##);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '"')`
error: calling `insert_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:42:5
--> tests/ui/single_char_add_str.rs:48:5
|
LL | string.insert_str(Y, r##"'"##);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `string.insert(Y, '\'')`
error: calling `insert_str()` using a single-character converted to string
--> tests/ui/single_char_add_str.rs:50:5
|
LL | string.insert_str(0, &c_ref.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, *c_ref)`
error: calling `insert_str()` using a single-character converted to string
--> tests/ui/single_char_add_str.rs:51:5
|
LL | string.insert_str(0, &c.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, c)`
error: calling `insert_str()` using a single-character converted to string
--> tests/ui/single_char_add_str.rs:52:5
|
LL | string.insert_str(0, &'a'.to_string());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` without `to_string()`: `string.insert(0, 'a')`
error: calling `insert_str()` using a single-character string literal
--> tests/ui/single_char_add_str.rs:44:5
--> tests/ui/single_char_add_str.rs:54:5
|
LL | get_string!().insert_str(1, "?");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `insert` with a character literal: `get_string!().insert(1, '?')`
error: aborting due to 15 previous errors
error: aborting due to 21 previous errors

View file

@ -0,0 +1,9 @@
#![warn(clippy::str_to_string)]
fn main() {
let hello = "hello world".to_owned();
//~^ ERROR: `to_string()` called on a `&str`
let msg = &hello[..];
msg.to_owned();
//~^ ERROR: `to_string()` called on a `&str`
}

View file

@ -2,9 +2,8 @@ error: `to_string()` called on a `&str`
--> tests/ui/str_to_string.rs:4:17
|
LL | let hello = "hello world".to_string();
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"hello world".to_owned()`
|
= help: consider using `.to_owned()`
= note: `-D clippy::str-to-string` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::str_to_string)]`
@ -12,9 +11,7 @@ error: `to_string()` called on a `&str`
--> tests/ui/str_to_string.rs:7:5
|
LL | msg.to_string();
| ^^^^^^^^^^^^^^^
|
= help: consider using `.to_owned()`
| ^^^^^^^^^^^^^^^ help: try: `msg.to_owned()`
error: aborting due to 2 previous errors

View file

@ -1,5 +1,4 @@
#![warn(clippy::temporary_assignment)]
#![allow(const_item_mutation)]
use std::ops::{Deref, DerefMut};

View file

@ -1,5 +1,5 @@
error: assignment to temporary
--> tests/ui/temporary_assignment.rs:48:5
--> tests/ui/temporary_assignment.rs:47:5
|
LL | Struct { field: 0 }.field = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | Struct { field: 0 }.field = 1;
= help: to override `-D warnings` add `#[allow(clippy::temporary_assignment)]`
error: assignment to temporary
--> tests/ui/temporary_assignment.rs:51:5
--> tests/ui/temporary_assignment.rs:50:5
|
LL | / MultiStruct {
LL | |
@ -19,13 +19,13 @@ LL | | .field = 1;
| |______________^
error: assignment to temporary
--> tests/ui/temporary_assignment.rs:57:5
--> tests/ui/temporary_assignment.rs:56:5
|
LL | ArrayStruct { array: [0] }.array[0] = 1;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: assignment to temporary
--> tests/ui/temporary_assignment.rs:59:5
--> tests/ui/temporary_assignment.rs:58:5
|
LL | (0, 0).0 = 1;
| ^^^^^^^^^^^^

View file

@ -0,0 +1,8 @@
//@compile-flags: -C incremental=target/debug/test/incr
// see https://github.com/rust-lang/rust-clippy/issues/10969
fn main() {
let s = "Hello, world!";
println!("{}", s);
}

View file

@ -0,0 +1,8 @@
//@compile-flags: -C incremental=target/debug/test/incr
// see https://github.com/rust-lang/rust-clippy/issues/10969
fn main() {
let s = "Hello, world!";
println!("{}", s.to_string());
}

View file

@ -0,0 +1,11 @@
error: `to_string` applied to a type that implements `Display` in `println!` args
--> tests/ui/to_string_in_format_args_incremental.rs:7:21
|
LL | println!("{}", s.to_string());
| ^^^^^^^^^^^^ help: remove this
|
= note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::to_string_in_format_args)]`
error: aborting due to 1 previous error

View file

@ -1,5 +1,9 @@
#![deny(clippy::type_repetition_in_bounds)]
#![allow(clippy::extra_unused_type_parameters, clippy::multiple_bound_locations)]
#![allow(
clippy::extra_unused_type_parameters,
clippy::multiple_bound_locations,
clippy::needless_maybe_sized
)]
use serde::Deserialize;
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};

Some files were not shown because too many files have changed in this diff Show more