@@ -807,11 +807,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
807
807
808
808
// ptr -> *
809
809
( Ptr ( m_e) , Ptr ( m_c) ) => self . check_ptr_ptr_cast ( fcx, m_e, m_c) , // ptr-ptr-cast
810
- ( Ptr ( m_expr) , Int ( _) ) => self . check_ptr_addr_cast ( fcx, m_expr) , // ptr-addr-cast
811
- ( FnPtr , Int ( _) ) => Ok ( CastKind :: FnPtrAddrCast ) ,
812
810
813
- // * -> ptr
814
- ( Int ( _) , Ptr ( mt) ) => self . check_addr_ptr_cast ( fcx, mt) , // addr-ptr-cast
811
+ // ptr-addr-cast
812
+ ( Ptr ( m_expr) , Int ( _) ) => {
813
+ self . fuzzy_provenance_ptr2int_lint ( fcx, t_from) ;
814
+ self . check_ptr_addr_cast ( fcx, m_expr)
815
+ }
816
+ ( FnPtr , Int ( _) ) => {
817
+ self . fuzzy_provenance_ptr2int_lint ( fcx, t_from) ;
818
+ Ok ( CastKind :: FnPtrAddrCast )
819
+ }
820
+ // addr-ptr-cast
821
+ ( Int ( _) , Ptr ( mt) ) => {
822
+ self . fuzzy_provenance_int2ptr_lint ( fcx) ;
823
+ self . check_addr_ptr_cast ( fcx, mt)
824
+ }
825
+ // fn-ptr-cast
815
826
( FnPtr , Ptr ( mt) ) => self . check_fptr_ptr_cast ( fcx, mt) ,
816
827
817
828
// prim -> prim
@@ -934,6 +945,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
934
945
fcx : & FnCtxt < ' a , ' tcx > ,
935
946
m_cast : TypeAndMut < ' tcx > ,
936
947
) -> Result < CastKind , CastError > {
948
+ self . fuzzy_provenance_int2ptr_lint ( fcx) ;
937
949
// ptr-addr cast. pointer must be thin.
938
950
match fcx. pointer_kind ( m_cast. ty , self . span ) ? {
939
951
None => Err ( CastError :: UnknownCastPtrKind ) ,
@@ -973,6 +985,50 @@ impl<'a, 'tcx> CastCheck<'tcx> {
973
985
}
974
986
}
975
987
}
988
+
989
+ fn fuzzy_provenance_ptr2int_lint ( & self , fcx : & FnCtxt < ' a , ' tcx > , t_from : CastTy < ' tcx > ) {
990
+ fcx. tcx . struct_span_lint_hir (
991
+ lint:: builtin:: FUZZY_PROVENANCE_CASTS ,
992
+ self . expr . hir_id ,
993
+ self . span ,
994
+ |err| {
995
+ let mut err = err. build ( & format ! (
996
+ "strict provenance disallows casting pointer `{}` to integer `{}`" ,
997
+ self . expr_ty, self . cast_ty
998
+ ) ) ;
999
+
1000
+ if let CastTy :: FnPtr = t_from {
1001
+ err. help (
1002
+ "use `(... as *const u8).addr()` to obtain \
1003
+ the address of a function pointer",
1004
+ ) ;
1005
+ } else {
1006
+ err. help ( "use `.addr()` to obtain the address of a pointer" ) ;
1007
+ }
1008
+
1009
+ err. emit ( ) ;
1010
+ } ,
1011
+ ) ;
1012
+ }
1013
+
1014
+ fn fuzzy_provenance_int2ptr_lint ( & self , fcx : & FnCtxt < ' a , ' tcx > ) {
1015
+ fcx. tcx . struct_span_lint_hir (
1016
+ lint:: builtin:: FUZZY_PROVENANCE_CASTS ,
1017
+ self . expr . hir_id ,
1018
+ self . span ,
1019
+ |err| {
1020
+ err. build ( & format ! (
1021
+ "strict provenance disallows casting integer `{}` to pointer `{}`" ,
1022
+ self . expr_ty, self . cast_ty
1023
+ ) )
1024
+ . help (
1025
+ "use `.with_addr(...)` to adjust a valid pointer \
1026
+ in the same allocation, to this address",
1027
+ )
1028
+ . emit ( ) ;
1029
+ } ,
1030
+ ) ;
1031
+ }
976
1032
}
977
1033
978
1034
impl < ' a , ' tcx > FnCtxt < ' a , ' tcx > {
0 commit comments