@@ -111,17 +111,43 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
111
111
// Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..]
112
112
if let ty:: Array ( _, s) = ty. sty {
113
113
let size: u128 = s. assert_usize ( cx. tcx ) . unwrap ( ) . into ( ) ;
114
- // Index is a constant range.
115
- if let Some ( ( start, end) ) = to_const_range ( cx, range, size) {
116
- if start > size || end > size {
117
- utils:: span_lint (
118
- cx,
119
- OUT_OF_BOUNDS_INDEXING ,
120
- expr. span ,
121
- "range is out of bounds" ,
122
- ) ;
123
- }
124
- return ;
114
+
115
+ match to_const_range ( cx, range, size) {
116
+ ( None , None ) => { } ,
117
+ ( Some ( start) , None ) => {
118
+ if start > size {
119
+ utils:: span_lint (
120
+ cx,
121
+ OUT_OF_BOUNDS_INDEXING ,
122
+ expr. span ,
123
+ "range is out of bounds" ,
124
+ ) ;
125
+ return ;
126
+ }
127
+ } ,
128
+ ( None , Some ( end) ) => {
129
+ if end > size {
130
+ utils:: span_lint (
131
+ cx,
132
+ OUT_OF_BOUNDS_INDEXING ,
133
+ expr. span ,
134
+ "range is out of bounds" ,
135
+ ) ;
136
+ return ;
137
+ }
138
+ } ,
139
+ ( Some ( start) , Some ( end) ) => {
140
+ if start > size || end > size {
141
+ utils:: span_lint (
142
+ cx,
143
+ OUT_OF_BOUNDS_INDEXING ,
144
+ expr. span ,
145
+ "range is out of bounds" ,
146
+ ) ;
147
+ }
148
+ // early return because both start and end are constant
149
+ return ;
150
+ } ,
125
151
}
126
152
}
127
153
@@ -161,34 +187,34 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
161
187
}
162
188
}
163
189
164
- /// Returns an option containing a tuple with the start and end (exclusive) of
165
- /// the range.
190
+ /// Returns a tuple of options with the start and end (exclusive) values of
191
+ /// the range. If the start or end is not constant, None is returned.
166
192
fn to_const_range < ' a , ' tcx > (
167
193
cx : & LateContext < ' a , ' tcx > ,
168
194
range : Range < ' _ > ,
169
195
array_size : u128 ,
170
- ) -> Option < ( u128 , u128 ) > {
196
+ ) -> ( Option < u128 > , Option < u128 > ) {
171
197
let s = range
172
198
. start
173
199
. map ( |expr| constant ( cx, cx. tables , expr) . map ( |( c, _) | c) ) ;
174
200
let start = match s {
175
- Some ( Some ( Constant :: Int ( x) ) ) => x ,
176
- Some ( _) => return None ,
177
- None => 0 ,
201
+ Some ( Some ( Constant :: Int ( x) ) ) => Some ( x ) ,
202
+ Some ( _) => None ,
203
+ None => Some ( 0 ) ,
178
204
} ;
179
205
180
206
let e = range
181
207
. end
182
208
. map ( |expr| constant ( cx, cx. tables , expr) . map ( |( c, _) | c) ) ;
183
209
let end = match e {
184
210
Some ( Some ( Constant :: Int ( x) ) ) => if range. limits == RangeLimits :: Closed {
185
- x + 1
211
+ Some ( x + 1 )
186
212
} else {
187
- x
213
+ Some ( x )
188
214
} ,
189
- Some ( _) => return None ,
190
- None => array_size,
215
+ Some ( _) => None ,
216
+ None => Some ( array_size) ,
191
217
} ;
192
218
193
- Some ( ( start, end) )
219
+ ( start, end)
194
220
}
0 commit comments