@@ -21,6 +21,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
21
21
/// `unsafe` block, and whether it has been used.
22
22
safety_context : SafetyContext ,
23
23
body_unsafety : BodyUnsafety ,
24
+ is_const : bool ,
24
25
}
25
26
26
27
impl < ' tcx > UnsafetyVisitor < ' _ , ' tcx > {
@@ -166,6 +167,16 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
166
167
( Bound :: Unbounded , Bound :: Unbounded ) => { }
167
168
_ => self . requires_unsafe ( expr. span , InitializingTypeWith ) ,
168
169
} ,
170
+ ExprKind :: Cast { source } => {
171
+ let source = & self . thir [ source] ;
172
+ if self . tcx . features ( ) . const_raw_ptr_to_usize_cast
173
+ && self . is_const
174
+ && ( source. ty . is_unsafe_ptr ( ) || source. ty . is_fn_ptr ( ) )
175
+ && expr. ty . is_integral ( )
176
+ {
177
+ self . requires_unsafe ( expr. span , CastOfPointerToInt ) ;
178
+ }
179
+ }
169
180
_ => { }
170
181
}
171
182
@@ -209,7 +220,6 @@ enum UnsafeOpKind {
209
220
CallToUnsafeFunction ,
210
221
UseOfInlineAssembly ,
211
222
InitializingTypeWith ,
212
- #[ allow( dead_code) ] // FIXME
213
223
CastOfPointerToInt ,
214
224
#[ allow( dead_code) ] // FIXME
215
225
UseOfMutableStatic ,
@@ -299,6 +309,7 @@ pub fn check_unsafety<'tcx>(
299
309
tcx : TyCtxt < ' tcx > ,
300
310
thir : & Thir < ' tcx > ,
301
311
expr : ExprId ,
312
+ def_id : LocalDefId ,
302
313
hir_id : hir:: HirId ,
303
314
) {
304
315
let body_unsafety = tcx. hir ( ) . fn_sig_by_hir_id ( hir_id) . map_or ( BodyUnsafety :: Safe , |fn_sig| {
@@ -310,8 +321,13 @@ pub fn check_unsafety<'tcx>(
310
321
} ) ;
311
322
let safety_context =
312
323
if body_unsafety. is_unsafe ( ) { SafetyContext :: UnsafeFn } else { SafetyContext :: Safe } ;
324
+ let is_const = match tcx. hir ( ) . body_owner_kind ( hir_id) {
325
+ hir:: BodyOwnerKind :: Closure => false ,
326
+ hir:: BodyOwnerKind :: Fn => tcx. is_const_fn_raw ( def_id. to_def_id ( ) ) ,
327
+ hir:: BodyOwnerKind :: Const | hir:: BodyOwnerKind :: Static ( _) => true ,
328
+ } ;
313
329
let mut visitor =
314
- UnsafetyVisitor { tcx, thir, safety_context, hir_context : hir_id, body_unsafety } ;
330
+ UnsafetyVisitor { tcx, thir, safety_context, hir_context : hir_id, body_unsafety, is_const } ;
315
331
visitor. visit_expr ( & thir[ expr] ) ;
316
332
}
317
333
@@ -323,7 +339,7 @@ crate fn thir_check_unsafety_inner<'tcx>(
323
339
let body_id = tcx. hir ( ) . body_owned_by ( hir_id) ;
324
340
let body = tcx. hir ( ) . body ( body_id) ;
325
341
let ( thir, expr) = cx:: build_thir ( tcx, def, & body. value ) ;
326
- check_unsafety ( tcx, & thir, expr, hir_id) ;
342
+ check_unsafety ( tcx, & thir, expr, def . did , hir_id) ;
327
343
}
328
344
329
345
crate fn thir_check_unsafety < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : LocalDefId ) {
0 commit comments