-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove @no-rustfix for if_let_slice_binding and slice_indexing_in_macro
- Loading branch information
1 parent
d983222
commit c78a1f4
Showing
6 changed files
with
217 additions
and
15 deletions.
There are no files selected for viewing
177 changes: 177 additions & 0 deletions
177
tests/ui/index_refutable_slice/if_let_slice_binding.fixed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
#![deny(clippy::index_refutable_slice)] | ||
#![allow(clippy::uninlined_format_args, clippy::needless_lifetimes)] | ||
|
||
enum SomeEnum<T> { | ||
One(T), | ||
Two(T), | ||
Three(T), | ||
Four(T), | ||
} | ||
|
||
fn lintable_examples() { | ||
// Try with reference | ||
let slice: Option<&[u32]> = Some(&[1, 2, 3]); | ||
if let Some([slice_0, ..]) = slice { | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
println!("{}", slice_0); | ||
} | ||
|
||
// Try with copy | ||
let slice: Option<[u32; 3]> = Some([1, 2, 3]); | ||
if let Some([slice_0, ..]) = slice { | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
println!("{}", slice_0); | ||
} | ||
|
||
// Try with long slice and small indices | ||
let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]); | ||
if let Some([slice_0, _, slice_2, ..]) = slice { | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
println!("{}", slice_2); | ||
println!("{}", slice_0); | ||
} | ||
|
||
// Multiple bindings | ||
let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]); | ||
if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped { | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
println!("{}", slice_0); | ||
} | ||
|
||
// Two lintable slices in one if let | ||
let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]); | ||
let b_wrapped: Option<[u32; 2]> = Some([4, 6]); | ||
if let (SomeEnum::Three([_, _, a_2, ..]), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) { | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
//~| ERROR: this binding can be a slice pattern to avoid indexing | ||
println!("{} -> {}", a_2, b_1); | ||
} | ||
|
||
// This requires the slice values to be borrowed as the slice values can only be | ||
// borrowed and `String` doesn't implement copy | ||
let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); | ||
if let Some([_, ref slice_1, ..]) = slice { | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
println!("{:?}", slice_1); | ||
} | ||
println!("{:?}", slice); | ||
|
||
// This should not suggest using the `ref` keyword as the scrutinee is already | ||
// a reference | ||
let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]); | ||
if let Some([slice_0, ..]) = &slice { | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
println!("{:?}", slice_0); | ||
} | ||
println!("{:?}", slice); | ||
} | ||
|
||
fn slice_index_above_limit() { | ||
let slice: Option<&[u32]> = Some(&[1, 2, 3]); | ||
|
||
if let Some(slice) = slice { | ||
// Would cause a panic, IDK | ||
println!("{}", slice[7]); | ||
} | ||
} | ||
|
||
fn slice_is_used() { | ||
let slice: Option<&[u32]> = Some(&[1, 2, 3]); | ||
if let Some(slice) = slice { | ||
println!("{:?}", slice.len()); | ||
} | ||
|
||
let slice: Option<&[u32]> = Some(&[1, 2, 3]); | ||
if let Some(slice) = slice { | ||
println!("{:?}", slice.to_vec()); | ||
} | ||
|
||
let opt: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]); | ||
if let Some(slice) = opt { | ||
if !slice.is_empty() { | ||
println!("first: {}", slice[0]); | ||
} | ||
} | ||
} | ||
|
||
/// The slice is used by an external function and should therefore not be linted | ||
fn check_slice_as_arg() { | ||
fn is_interesting<T>(slice: &[T; 2]) -> bool { | ||
!slice.is_empty() | ||
} | ||
|
||
let slice_wrapped: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]); | ||
if let Some(slice) = &slice_wrapped { | ||
if is_interesting(slice) { | ||
println!("This is interesting {}", slice[0]); | ||
} | ||
} | ||
println!("{:?}", slice_wrapped); | ||
} | ||
|
||
fn check_slice_in_struct() { | ||
#[derive(Debug)] | ||
struct Wrapper<'a> { | ||
inner: Option<&'a [String]>, | ||
is_awesome: bool, | ||
} | ||
|
||
impl<'a> Wrapper<'a> { | ||
fn is_super_awesome(&self) -> bool { | ||
self.is_awesome | ||
} | ||
} | ||
|
||
let inner = &[String::from("New"), String::from("World")]; | ||
let wrap = Wrapper { | ||
inner: Some(inner), | ||
is_awesome: true, | ||
}; | ||
|
||
// Test 1: Field access | ||
if let Some([slice_0, ..]) = wrap.inner { | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
if wrap.is_awesome { | ||
println!("This is awesome! {}", slice_0); | ||
} | ||
} | ||
|
||
// Test 2: function access | ||
if let Some([slice_0, ..]) = wrap.inner { | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
if wrap.is_super_awesome() { | ||
println!("This is super awesome! {}", slice_0); | ||
} | ||
} | ||
println!("Complete wrap: {:?}", wrap); | ||
} | ||
|
||
/// This would be a nice additional feature to have in the future, but adding it | ||
/// now would make the PR too large. This is therefore only a test that we don't | ||
/// lint cases we can't make a reasonable suggestion for | ||
fn mutable_slice_index() { | ||
// Mut access | ||
let mut slice: Option<[String; 1]> = Some([String::from("Penguin")]); | ||
if let Some(ref mut slice) = slice { | ||
slice[0] = String::from("Mr. Penguin"); | ||
} | ||
println!("Use after modification: {:?}", slice); | ||
|
||
// Mut access on reference | ||
let mut slice: Option<[String; 1]> = Some([String::from("Cat")]); | ||
if let Some(slice) = &mut slice { | ||
slice[0] = String::from("Lord Meow Meow"); | ||
} | ||
println!("Use after modification: {:?}", slice); | ||
} | ||
|
||
/// The lint will ignore bindings with sub patterns as it would be hard | ||
/// to build correct suggestions for these instances :) | ||
fn binding_with_sub_pattern() { | ||
let slice: Option<&[u32]> = Some(&[1, 2, 3]); | ||
if let Some(slice @ [_, _, _]) = slice { | ||
println!("{:?}", slice[2]); | ||
} | ||
} | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#![deny(clippy::index_refutable_slice)] | ||
|
||
extern crate if_chain; | ||
use if_chain::if_chain; | ||
|
||
macro_rules! if_let_slice_macro { | ||
() => { | ||
// This would normally be linted | ||
let slice: Option<&[u32]> = Some(&[1, 2, 3]); | ||
if let Some(slice) = slice { | ||
println!("{}", slice[0]); | ||
} | ||
}; | ||
} | ||
|
||
fn main() { | ||
// Don't lint this | ||
if_let_slice_macro!(); | ||
|
||
// Do lint this | ||
if_chain! { | ||
let slice: Option<&[u32]> = Some(&[1, 2, 3]); | ||
if let Some([slice_0, ..]) = slice; | ||
//~^ ERROR: this binding can be a slice pattern to avoid indexing | ||
then { | ||
println!("{}", slice_0); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters