]> git.lizzy.rs Git - rust.git/blob - tests/ui/index_refutable_slice/if_let_slice_binding.rs
Auto merge of #8374 - Alexendoo:bless-revisions, r=camsteffen
[rust.git] / tests / ui / index_refutable_slice / if_let_slice_binding.rs
1 #![deny(clippy::index_refutable_slice)]
2
3 enum SomeEnum<T> {
4     One(T),
5     Two(T),
6     Three(T),
7     Four(T),
8 }
9
10 fn lintable_examples() {
11     // Try with reference
12     let slice: Option<&[u32]> = Some(&[1, 2, 3]);
13     if let Some(slice) = slice {
14         println!("{}", slice[0]);
15     }
16
17     // Try with copy
18     let slice: Option<[u32; 3]> = Some([1, 2, 3]);
19     if let Some(slice) = slice {
20         println!("{}", slice[0]);
21     }
22
23     // Try with long slice and small indices
24     let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]);
25     if let Some(slice) = slice {
26         println!("{}", slice[2]);
27         println!("{}", slice[0]);
28     }
29
30     // Multiple bindings
31     let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]);
32     if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped {
33         println!("{}", slice[0]);
34     }
35
36     // Two lintable slices in one if let
37     let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]);
38     let b_wrapped: Option<[u32; 2]> = Some([4, 6]);
39     if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
40         println!("{} -> {}", a[2], b[1]);
41     }
42
43     // This requires the slice values to be borrowed as the slice values can only be
44     // borrowed and `String` doesn't implement copy
45     let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
46     if let Some(ref slice) = slice {
47         println!("{:?}", slice[1]);
48     }
49     println!("{:?}", slice);
50
51     // This should not suggest using the `ref` keyword as the scrutinee is already
52     // a reference
53     let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
54     if let Some(slice) = &slice {
55         println!("{:?}", slice[0]);
56     }
57     println!("{:?}", slice);
58 }
59
60 fn slice_index_above_limit() {
61     let slice: Option<&[u32]> = Some(&[1, 2, 3]);
62
63     if let Some(slice) = slice {
64         // Would cause a panic, IDK
65         println!("{}", slice[7]);
66     }
67 }
68
69 fn slice_is_used() {
70     let slice: Option<&[u32]> = Some(&[1, 2, 3]);
71     if let Some(slice) = slice {
72         println!("{:?}", slice.len());
73     }
74
75     let slice: Option<&[u32]> = Some(&[1, 2, 3]);
76     if let Some(slice) = slice {
77         println!("{:?}", slice.to_vec());
78     }
79
80     let opt: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
81     if let Some(slice) = opt {
82         if !slice.is_empty() {
83             println!("first: {}", slice[0]);
84         }
85     }
86 }
87
88 /// The slice is used by an external function and should therefore not be linted
89 fn check_slice_as_arg() {
90     fn is_interesting<T>(slice: &[T; 2]) -> bool {
91         !slice.is_empty()
92     }
93
94     let slice_wrapped: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
95     if let Some(slice) = &slice_wrapped {
96         if is_interesting(slice) {
97             println!("This is interesting {}", slice[0]);
98         }
99     }
100     println!("{:?}", slice_wrapped);
101 }
102
103 fn check_slice_in_struct() {
104     #[derive(Debug)]
105     struct Wrapper<'a> {
106         inner: Option<&'a [String]>,
107         is_awesome: bool,
108     }
109
110     impl<'a> Wrapper<'a> {
111         fn is_super_awesome(&self) -> bool {
112             self.is_awesome
113         }
114     }
115
116     let inner = &[String::from("New"), String::from("World")];
117     let wrap = Wrapper {
118         inner: Some(inner),
119         is_awesome: true,
120     };
121
122     // Test 1: Field access
123     if let Some(slice) = wrap.inner {
124         if wrap.is_awesome {
125             println!("This is awesome! {}", slice[0]);
126         }
127     }
128
129     // Test 2: function access
130     if let Some(slice) = wrap.inner {
131         if wrap.is_super_awesome() {
132             println!("This is super awesome! {}", slice[0]);
133         }
134     }
135     println!("Complete wrap: {:?}", wrap);
136 }
137
138 /// This would be a nice additional feature to have in the future, but adding it
139 /// now would make the PR too large. This is therefore only a test that we don't
140 /// lint cases we can't make a reasonable suggestion for
141 fn mutable_slice_index() {
142     // Mut access
143     let mut slice: Option<[String; 1]> = Some([String::from("Penguin")]);
144     if let Some(ref mut slice) = slice {
145         slice[0] = String::from("Mr. Penguin");
146     }
147     println!("Use after modification: {:?}", slice);
148
149     // Mut access on reference
150     let mut slice: Option<[String; 1]> = Some([String::from("Cat")]);
151     if let Some(slice) = &mut slice {
152         slice[0] = String::from("Lord Meow Meow");
153     }
154     println!("Use after modification: {:?}", slice);
155 }
156
157 /// The lint will ignore bindings with sub patterns as it would be hard
158 /// to build correct suggestions for these instances :)
159 fn binding_with_sub_pattern() {
160     let slice: Option<&[u32]> = Some(&[1, 2, 3]);
161     if let Some(slice @ [_, _, _]) = slice {
162         println!("{:?}", slice[2]);
163     }
164 }
165
166 fn main() {}