@@ -116,29 +116,49 @@ fn main() {
116116 i64:: MAX as u64 ;
117117 i128:: MAX as u128 ;
118118
119- ( -1i8 ) . abs ( ) as u8 ;
120- ( -1i16 ) . abs ( ) as u16 ;
121- ( -1i32 ) . abs ( ) as u32 ;
119+ ( -1i8 ) . saturating_abs ( ) as u8 ;
120+ // abs() can return a negative value in release builds
121+ ( i8:: MIN ) . abs ( ) as u8 ;
122+ //~^ ERROR: casting `i8` to `u8` may lose the sign of the value
123+ ( -1i16 ) . saturating_abs ( ) as u16 ;
124+ ( -1i32 ) . saturating_abs ( ) as u32 ;
122125 ( -1i64 ) . abs ( ) as u64 ;
123126 ( -1isize ) . abs ( ) as usize ;
124127
125128 ( -1i8 ) . checked_abs ( ) . unwrap ( ) as u8 ;
129+ ( i8:: MIN ) . checked_abs ( ) . unwrap ( ) as u8 ;
126130 ( -1i16 ) . checked_abs ( ) . unwrap ( ) as u16 ;
127131 ( -1i32 ) . checked_abs ( ) . unwrap ( ) as u32 ;
128- ( -1i64 ) . checked_abs ( ) . unwrap ( ) as u64 ;
129- ( -1isize ) . checked_abs ( ) . unwrap ( ) as usize ;
132+ // SAFETY: -1 is a small number which will always return Some
133+ ( unsafe { ( -1i64 ) . checked_abs ( ) . unwrap_unchecked ( ) } ) as u64 ;
134+ ( -1isize ) . checked_abs ( ) . expect ( "-1 is a small number" ) as usize ;
135+
136+ ( -1i8 ) . isqrt ( ) as u8 ;
137+ ( i8:: MIN ) . isqrt ( ) as u8 ;
138+ ( -1i16 ) . isqrt ( ) as u16 ;
139+ ( -1i32 ) . isqrt ( ) as u32 ;
140+ ( -1i64 ) . isqrt ( ) as u64 ;
141+ ( -1isize ) . isqrt ( ) as usize ;
142+
143+ ( -1i8 ) . checked_isqrt ( ) . unwrap ( ) as u8 ;
144+ ( i8:: MIN ) . checked_isqrt ( ) . unwrap ( ) as u8 ;
145+ ( -1i16 ) . checked_isqrt ( ) . unwrap ( ) as u16 ;
146+ ( -1i32 ) . checked_isqrt ( ) . unwrap ( ) as u32 ;
147+ // SAFETY: -1 is a small number which will always return Some
148+ ( unsafe { ( -1i64 ) . checked_isqrt ( ) . unwrap_unchecked ( ) } ) as u64 ;
149+ ( -1isize ) . checked_isqrt ( ) . expect ( "-1 is a small number" ) as usize ;
130150
131151 ( -1i8 ) . rem_euclid ( 1i8 ) as u8 ;
132- ( -1i8 ) . rem_euclid ( 1i8 ) as u16 ;
133- ( -1i16 ) . rem_euclid ( 1i16 ) as u16 ;
152+ ( -1i8 ) . wrapping_rem_euclid ( 1i8 ) . unwrap ( ) as u16 ;
153+ ( -1i16 ) . rem_euclid ( 1i16 ) . unwrap ( ) as u16 ;
134154 ( -1i16 ) . rem_euclid ( 1i16 ) as u32 ;
135155 ( -1i32 ) . rem_euclid ( 1i32 ) as u32 ;
136156 ( -1i32 ) . rem_euclid ( 1i32 ) as u64 ;
137157 ( -1i64 ) . rem_euclid ( 1i64 ) as u64 ;
138158 ( -1i64 ) . rem_euclid ( 1i64 ) as u128 ;
139159 ( -1isize ) . rem_euclid ( 1isize ) as usize ;
140160 ( 1i8 ) . rem_euclid ( -1i8 ) as u8 ;
141- ( 1i8 ) . rem_euclid ( -1i8 ) as u16 ;
161+ ( 1i8 ) . wrapping_rem_euclid ( -1i8 ) as u16 ;
142162 ( 1i16 ) . rem_euclid ( -1i16 ) as u16 ;
143163 ( 1i16 ) . rem_euclid ( -1i16 ) as u32 ;
144164 ( 1i32 ) . rem_euclid ( -1i32 ) as u32 ;
@@ -371,14 +391,25 @@ fn issue11642() {
371391 let x = x as i32 ;
372392 ( x * x) as u32 ;
373393 x. pow ( 2 ) as u32 ;
374- ( -2_i32 ) . pow ( 2 ) as u32
394+ ( -2_i32 ) . saturating_pow ( 2 ) as u32
375395 }
376396
377397 let _a = |x : i32 | -> u32 { ( x * x * x * x) as u32 } ;
378398
399+ ( 2_i32 ) . checked_pow ( 3 ) . unwrap ( ) as u32 ;
379400 ( -2_i32 ) . pow ( 3 ) as u32 ;
380401 //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
381402
403+ ( 2_i32 % 1 ) as u32 ;
404+ ( 2_i32 % -1 ) as u32 ;
405+ ( -2_i32 % 1 ) as u32 ;
406+ //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
407+ ( -2_i32 % -1 ) as u32 ;
408+ //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
409+ ( 2_i32 >> 1 ) as u32 ;
410+ ( -2_i32 >> 1 ) as u32 ;
411+ //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
412+
382413 let x: i32 = 10 ;
383414 ( x * x) as u32 ;
384415 ( x * x * x) as u32 ;
@@ -387,12 +418,22 @@ fn issue11642() {
387418 let y: i16 = -2 ;
388419 ( y * y * y * y * -2 ) as u16 ;
389420 //~^ ERROR: casting `i16` to `u16` may lose the sign of the value
390- ( y * y * y * y * 2 ) as u16 ;
391- ( y * y * y * 2 ) as u16 ;
421+ ( y * y * y / y * 2 ) as u16 ;
422+ ( y * y / y * 2 ) as u16 ;
392423 //~^ ERROR: casting `i16` to `u16` may lose the sign of the value
393- ( y * y * y * -2 ) as u16 ;
424+ ( y / y * y * -2 ) as u16 ;
394425 //~^ ERROR: casting `i16` to `u16` may lose the sign of the value
395426
427+ ( y + y + y + -2 ) as u16 ;
428+ //~^ ERROR: casting `i16` to `u16` may lose the sign of the value
429+ ( y + y + y + 2 ) as u16 ;
430+ //~^ ERROR: casting `i16` to `u16` may lose the sign of the value
431+
432+ let z: i16 = 2 ;
433+ ( z + -2 ) as u16 ;
434+ //~^ ERROR: casting `i16` to `u16` may lose the sign of the value
435+ ( z + z + 2 ) as u16 ;
436+
396437 fn foo ( a : i32 , b : i32 , c : i32 ) -> u32 {
397438 ( a * a * b * b * c * c) as u32 ;
398439 ( a * b * c) as u32 ;
@@ -409,8 +450,9 @@ fn issue11642() {
409450 //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
410451 ( a / b + b * c) as u32 ;
411452 //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
412- a. pow ( 3 ) as u32 ;
453+ a. saturating_pow ( 3 ) as u32 ;
413454 //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
414455 ( a. abs ( ) * b. pow ( 2 ) / c. abs ( ) ) as u32
456+ //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
415457 }
416458}
0 commit comments