@@ -9,7 +9,7 @@ use rustc_errors::{Applicability, Diag};
99use rustc_hir:: def:: { DefKind , Res } ;
1010use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
1111use rustc_lint:: LateContext ;
12- use rustc_middle:: ty:: { self , FloatTy , Ty } ;
12+ use rustc_middle:: ty:: { self , Ty } ;
1313use rustc_span:: Span ;
1414
1515use super :: { CAST_ENUM_TRUNCATION , CAST_POSSIBLE_TRUNCATION , utils} ;
@@ -91,14 +91,15 @@ pub(super) fn check(
9191 cast_to : Ty < ' _ > ,
9292 cast_to_span : Span ,
9393) {
94- let msg = match ( cast_from. kind ( ) , utils :: int_ty_to_nbits ( cx . tcx , cast_to) ) {
95- ( ty:: Int ( _) | ty:: Uint ( _) , Some ( to_nbits ) ) => {
94+ let msg = match ( cast_from. kind ( ) , cast_to. is_integral ( ) ) {
95+ ( ty:: Int ( _) | ty:: Uint ( _) , true ) => {
9696 let from_nbits = apply_reductions (
9797 cx,
98- utils:: int_ty_to_nbits ( cx . tcx , cast_from ) . unwrap ( ) ,
98+ utils:: int_ty_to_nbits ( cast_from , cx . tcx ) ,
9999 cast_expr,
100100 cast_from. is_signed ( ) ,
101101 ) ;
102+ let to_nbits = utils:: int_ty_to_nbits ( cast_to, cx. tcx ) ;
102103
103104 let ( should_lint, suffix) = match ( is_isize_or_usize ( cast_from) , is_isize_or_usize ( cast_to) ) {
104105 ( true , true ) | ( false , false ) => ( to_nbits < from_nbits, "" ) ,
@@ -120,7 +121,7 @@ pub(super) fn check(
120121 format ! ( "casting `{cast_from}` to `{cast_to}` may truncate the value{suffix}" , )
121122 } ,
122123
123- ( ty:: Adt ( def, _) , Some ( to_nbits ) ) if def. is_enum ( ) => {
124+ ( ty:: Adt ( def, _) , true ) if def. is_enum ( ) => {
124125 let ( from_nbits, variant) = if let ExprKind :: Path ( p) = & cast_expr. kind
125126 && let Res :: Def ( DefKind :: Ctor ( ..) , id) = cx. qpath_res ( p, cast_expr. hir_id )
126127 {
@@ -131,6 +132,7 @@ pub(super) fn check(
131132 } else {
132133 ( utils:: enum_ty_to_nbits ( * def, cx. tcx ) , None )
133134 } ;
135+ let to_nbits = utils:: int_ty_to_nbits ( cast_to, cx. tcx ) ;
134136
135137 let cast_from_ptr_size = def. repr ( ) . int . is_none_or ( |ty| matches ! ( ty, IntegerType :: Pointer ( _) , ) ) ;
136138 let suffix = match ( cast_from_ptr_size, is_isize_or_usize ( cast_to) ) {
@@ -155,12 +157,18 @@ pub(super) fn check(
155157 format ! ( "casting `{cast_from}` to `{cast_to}` may truncate the value{suffix}" )
156158 } ,
157159
158- ( ty:: Float ( _) , Some ( _ ) ) => {
160+ ( ty:: Float ( _) , true ) => {
159161 format ! ( "casting `{cast_from}` to `{cast_to}` may truncate the value" )
160162 } ,
161163
162- ( ty:: Float ( FloatTy :: F64 ) , None ) if matches ! ( cast_to. kind( ) , & ty:: Float ( FloatTy :: F32 ) ) => {
163- "casting `f64` to `f32` may truncate the value" . to_string ( )
164+ ( ty:: Float ( _) , false ) => {
165+ let from_nbits = utils:: float_ty_to_nbits ( cast_from) ;
166+ let to_nbits = utils:: float_ty_to_nbits ( cast_to) ;
167+ if from_nbits > to_nbits {
168+ format ! ( "casting `f{from_nbits}` to `f{to_nbits}` may truncate the value" )
169+ } else {
170+ return ;
171+ }
164172 } ,
165173
166174 _ => return ,
0 commit comments