@@ -259,6 +259,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
259
259
pub ( crate ) fn provide ( providers : & mut Providers ) {
260
260
* providers = Providers {
261
261
unsafety_check_result,
262
+ unsafe_derive_on_repr_packed,
262
263
..* providers
263
264
} ;
264
265
}
@@ -341,6 +342,27 @@ fn unsafety_check_result<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
341
342
}
342
343
}
343
344
345
+ fn unsafe_derive_on_repr_packed < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) {
346
+ let lint_node_id = match tcx. hir . as_local_node_id ( def_id) {
347
+ Some ( node_id) => node_id,
348
+ None => bug ! ( "checking unsafety for non-local def id {:?}" , def_id)
349
+ } ;
350
+
351
+ // FIXME: when we make this a hard error, this should have its
352
+ // own error code.
353
+ let message = if !tcx. generics_of ( def_id) . types . is_empty ( ) {
354
+ format ! ( "#[derive] can't be used on a #[repr(packed)] struct with \
355
+ type parameters (error E0133)")
356
+ } else {
357
+ format ! ( "#[derive] can't be used on a non-Copy #[repr(packed)] struct \
358
+ (error E0133)")
359
+ } ;
360
+ tcx. lint_node ( SAFE_PACKED_BORROWS ,
361
+ lint_node_id,
362
+ tcx. def_span ( def_id) ,
363
+ & message) ;
364
+ }
365
+
344
366
/// Return the NodeId for an enclosing scope that is also `unsafe`
345
367
fn is_enclosed ( tcx : TyCtxt ,
346
368
used_unsafe : & FxHashSet < ast:: NodeId > ,
@@ -402,7 +424,6 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
402
424
unsafe_blocks
403
425
} = tcx. unsafety_check_result ( def_id) ;
404
426
405
- let mut emitted_derive_error = false ;
406
427
for & UnsafetyViolation {
407
428
source_info, description, kind
408
429
} in violations. iter ( ) {
@@ -423,29 +444,15 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
423
444
block (error E0133)", description) ) ;
424
445
}
425
446
UnsafetyViolationKind :: BorrowPacked ( lint_node_id) => {
426
- if emitted_derive_error {
427
- continue
428
- }
429
-
430
- let message = if let Some ( impl_def_id) = builtin_derive_def_id ( tcx, def_id) {
431
- emitted_derive_error = true ;
432
- // FIXME: when we make this a hard error, this should have its
433
- // own error code.
434
- if !tcx. generics_of ( impl_def_id) . types . is_empty ( ) {
435
- format ! ( "#[derive] can't be used on a #[repr(packed)] struct with \
436
- type parameters (error E0133)")
437
- } else {
438
- format ! ( "#[derive] can't be used on a non-Copy #[repr(packed)] struct \
439
- (error E0133)")
440
- }
447
+ if let Some ( impl_def_id) = builtin_derive_def_id ( tcx, def_id) {
448
+ tcx. unsafe_derive_on_repr_packed ( impl_def_id) ;
441
449
} else {
442
- format ! ( "{} requires unsafe function or \
443
- block (error E0133)", description)
444
- } ;
445
- tcx. lint_node ( SAFE_PACKED_BORROWS ,
446
- lint_node_id,
447
- source_info. span ,
448
- & message) ;
450
+ tcx. lint_node ( SAFE_PACKED_BORROWS ,
451
+ lint_node_id,
452
+ source_info. span ,
453
+ & format ! ( "{} requires unsafe function or \
454
+ block (error E0133)", description) ) ;
455
+ }
449
456
}
450
457
}
451
458
}
0 commit comments