@@ -111,17 +111,43 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
111111 // Ranged indexes, i.e. &x[n..m], &x[n..], &x[..n] and &x[..]
112112 if let ty:: Array ( _, s) = ty. sty {
113113 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+ } ,
125151 }
126152 }
127153
@@ -161,34 +187,34 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IndexingSlicing {
161187 }
162188}
163189
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.
166192fn to_const_range < ' a , ' tcx > (
167193 cx : & LateContext < ' a , ' tcx > ,
168194 range : Range < ' _ > ,
169195 array_size : u128 ,
170- ) -> Option < ( u128 , u128 ) > {
196+ ) -> ( Option < u128 > , Option < u128 > ) {
171197 let s = range
172198 . start
173199 . map ( |expr| constant ( cx, cx. tables , expr) . map ( |( c, _) | c) ) ;
174200 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 ) ,
178204 } ;
179205
180206 let e = range
181207 . end
182208 . map ( |expr| constant ( cx, cx. tables , expr) . map ( |( c, _) | c) ) ;
183209 let end = match e {
184210 Some ( Some ( Constant :: Int ( x) ) ) => if range. limits == RangeLimits :: Closed {
185- x + 1
211+ Some ( x + 1 )
186212 } else {
187- x
213+ Some ( x )
188214 } ,
189- Some ( _) => return None ,
190- None => array_size,
215+ Some ( _) => None ,
216+ None => Some ( array_size) ,
191217 } ;
192218
193- Some ( ( start, end) )
219+ ( start, end)
194220}
0 commit comments