@@ -609,7 +609,10 @@ impl<'a, 'tcx> CastCheck<'tcx> {
609609 ( FnPtr , Ptr ( mt) ) => self . check_fptr_ptr_cast ( fcx, mt) ,
610610
611611 // prim -> prim
612- ( Int ( CEnum ) , Int ( _) ) => Ok ( CastKind :: EnumCast ) ,
612+ ( Int ( CEnum ) , Int ( _) ) => {
613+ self . cenum_impl_drop_lint ( fcx) ;
614+ Ok ( CastKind :: EnumCast )
615+ }
613616 ( Int ( Char ) | Int ( Bool ) , Int ( _) ) => Ok ( CastKind :: PrimIntCast ) ,
614617
615618 ( Int ( _) | Float , Int ( _) | Float ) => Ok ( CastKind :: NumericCast ) ,
@@ -706,11 +709,13 @@ impl<'a, 'tcx> CastCheck<'tcx> {
706709 // Coerce to a raw pointer so that we generate AddressOf in MIR.
707710 let array_ptr_type = fcx. tcx . mk_ptr ( m_expr) ;
708711 fcx. try_coerce ( self . expr , self . expr_ty , array_ptr_type, AllowTwoPhase :: No )
709- . unwrap_or_else ( |_| bug ! (
712+ . unwrap_or_else ( |_| {
713+ bug ! (
710714 "could not cast from reference to array to pointer to array ({:?} to {:?})" ,
711715 self . expr_ty,
712716 array_ptr_type,
713- ) ) ;
717+ )
718+ } ) ;
714719
715720 // this will report a type mismatch if needed
716721 fcx. demand_eqtype ( self . span , ety, m_cast. ty ) ;
@@ -740,6 +745,25 @@ impl<'a, 'tcx> CastCheck<'tcx> {
740745 Err ( err) => Err ( err) ,
741746 }
742747 }
748+
749+ fn cenum_impl_drop_lint ( & self , fcx : & FnCtxt < ' a , ' tcx > ) {
750+ if let ty:: Adt ( d, _) = self . expr_ty . kind {
751+ if d. has_dtor ( fcx. tcx ) {
752+ fcx. tcx . struct_span_lint_hir (
753+ lint:: builtin:: CENUM_IMPL_DROP_CAST ,
754+ self . expr . hir_id ,
755+ self . span ,
756+ |err| {
757+ err. build ( & format ! (
758+ "Cast `enum` implementing `Drop` `{}` to integer `{}`" ,
759+ self . expr_ty, self . cast_ty
760+ ) )
761+ . emit ( ) ;
762+ } ,
763+ ) ;
764+ }
765+ }
766+ }
743767}
744768
745769impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
0 commit comments