@@ -373,6 +373,22 @@ fn report_unused_unsafe(tcx: TyCtxt, used_unsafe: &FxHashSet<ast::NodeId>, id: a
373
373
db. emit ( ) ;
374
374
}
375
375
376
+ fn builtin_derive_def_id < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) -> Option < DefId > {
377
+ debug ! ( "builtin_derive_def_id({:?})" , def_id) ;
378
+ if let Some ( impl_def_id) = tcx. impl_of_method ( def_id) {
379
+ if tcx. has_attr ( impl_def_id, "automatically_derived" ) {
380
+ debug ! ( "builtin_derive_def_id({:?}) - is {:?}" , def_id, impl_def_id) ;
381
+ Some ( impl_def_id)
382
+ } else {
383
+ debug ! ( "builtin_derive_def_id({:?}) - not automatically derived" , def_id) ;
384
+ None
385
+ }
386
+ } else {
387
+ debug ! ( "builtin_derive_def_id({:?}) - not a method" , def_id) ;
388
+ None
389
+ }
390
+ }
391
+
376
392
pub fn check_unsafety < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , def_id : DefId ) {
377
393
debug ! ( "check_unsafety({:?})" , def_id) ;
378
394
@@ -386,6 +402,7 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
386
402
unsafe_blocks
387
403
} = tcx. unsafety_check_result ( def_id) ;
388
404
405
+ let mut emitted_derive_error = false ;
389
406
for & UnsafetyViolation {
390
407
source_info, description, kind
391
408
} in violations. iter ( ) {
@@ -406,11 +423,29 @@ pub fn check_unsafety<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
406
423
block (error E0133)", description) ) ;
407
424
}
408
425
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
+ }
441
+ } else {
442
+ format ! ( "{} requires unsafe function or \
443
+ block (error E0133)", description)
444
+ } ;
409
445
tcx. lint_node ( SAFE_PACKED_BORROWS ,
410
446
lint_node_id,
411
447
source_info. span ,
412
- & format ! ( "{} requires unsafe function or \
413
- block (error E0133)", description) ) ;
448
+ & message) ;
414
449
}
415
450
}
416
451
}
0 commit comments