@@ -11,7 +11,7 @@ use super::objsequence::{
11
11
use super :: objstr;
12
12
use super :: objtype;
13
13
use num_bigint:: ToBigInt ;
14
- use num_traits:: { Signed , ToPrimitive } ;
14
+ use num_traits:: ToPrimitive ;
15
15
16
16
// set_item:
17
17
fn set_item (
@@ -277,19 +277,25 @@ fn list_insert(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
277
277
( element, None )
278
278
]
279
279
) ;
280
- if objint:: get_value ( insert_position) > std:: usize:: MAX . into ( ) {
281
- return Err (
282
- vm. new_overflow_error ( "Python int too large to convert to Rust usize" . to_string ( ) )
283
- ) ;
284
- }
285
- let mut vec = get_mut_elements ( list) ;
286
- let position = match objint:: get_value ( insert_position) {
287
- ref i if ( * i) . is_negative ( ) => {
288
- ( num_bigint:: BigInt :: from ( vec. len ( ) ) - i. abs ( ) ) . max ( 0 . into ( ) )
280
+ let int_position = match objint:: get_value ( insert_position) . to_i64 ( ) {
281
+ Some ( i) => i,
282
+ None => {
283
+ return Err (
284
+ vm. new_overflow_error ( "Python int too large to convert to Rust i64" . to_string ( ) )
285
+ ) ;
289
286
}
290
- i => i. min ( num_bigint:: BigInt :: from ( vec. len ( ) ) . into ( ) ) ,
291
287
} ;
292
- vec. insert ( position. to_usize ( ) . unwrap ( ) , element. clone ( ) ) ;
288
+ let mut vec = get_mut_elements ( list) ;
289
+ let vec_len = vec. len ( ) . to_i64 ( ) . unwrap ( ) ;
290
+ // This unbounded position can be < 0 or > vec.len()
291
+ let unbounded_position = if int_position < 0 {
292
+ vec_len + int_position
293
+ } else {
294
+ int_position
295
+ } ;
296
+ // Bound it by [0, vec.len()]
297
+ let position = unbounded_position. max ( 0 ) . min ( vec_len) . to_usize ( ) . unwrap ( ) ;
298
+ vec. insert ( position, element. clone ( ) ) ;
293
299
Ok ( vm. get_none ( ) )
294
300
}
295
301
0 commit comments