@@ -12,6 +12,7 @@ use rustc_span::def_id::{DefId, LocalDefId};
12
12
use rustc_span:: symbol:: Symbol ;
13
13
use rustc_span:: Span ;
14
14
15
+ use std:: borrow:: Cow ;
15
16
use std:: ops:: Bound ;
16
17
17
18
struct UnsafetyVisitor < ' a , ' tcx > {
@@ -70,7 +71,6 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
70
71
}
71
72
72
73
fn requires_unsafe ( & mut self , span : Span , kind : UnsafeOpKind ) {
73
- let ( description, note) = kind. description_and_note ( ) ;
74
74
let unsafe_op_in_unsafe_fn_allowed = self . unsafe_op_in_unsafe_fn_allowed ( ) ;
75
75
match self . safety_context {
76
76
SafetyContext :: BuiltinUnsafeBlock => { }
@@ -82,6 +82,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
82
82
}
83
83
SafetyContext :: UnsafeFn if unsafe_op_in_unsafe_fn_allowed => { }
84
84
SafetyContext :: UnsafeFn => {
85
+ let ( description, note) = kind. description_and_note ( self . tcx ) ;
85
86
// unsafe_op_in_unsafe_fn is disallowed
86
87
self . tcx . struct_span_lint_hir (
87
88
UNSAFE_OP_IN_UNSAFE_FN ,
@@ -99,6 +100,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
99
100
)
100
101
}
101
102
SafetyContext :: Safe => {
103
+ let ( description, note) = kind. description_and_note ( self . tcx ) ;
102
104
let fn_sugg = if unsafe_op_in_unsafe_fn_allowed { " function or" } else { "" } ;
103
105
struct_span_err ! (
104
106
self . tcx. sess,
@@ -350,7 +352,12 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
350
352
}
351
353
ExprKind :: Call { fun, ty : _, args : _, from_hir_call : _, fn_span : _ } => {
352
354
if self . thir [ fun] . ty . fn_sig ( self . tcx ) . unsafety ( ) == hir:: Unsafety :: Unsafe {
353
- self . requires_unsafe ( expr. span , CallToUnsafeFunction ) ;
355
+ let func_id = if let ty:: FnDef ( func_id, _) = self . thir [ fun] . ty . kind ( ) {
356
+ Some ( * func_id)
357
+ } else {
358
+ None
359
+ } ;
360
+ self . requires_unsafe ( expr. span , CallToUnsafeFunction ( func_id) ) ;
354
361
} else if let & ty:: FnDef ( func_did, _) = self . thir [ fun] . ty . kind ( ) {
355
362
// If the called function has target features the calling function hasn't,
356
363
// the call requires `unsafe`. Don't check this on wasm
@@ -364,7 +371,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
364
371
. iter ( )
365
372
. all ( |feature| self . body_target_features . contains ( feature) )
366
373
{
367
- self . requires_unsafe ( expr. span , CallToFunctionWith ) ;
374
+ self . requires_unsafe ( expr. span , CallToFunctionWith ( func_did ) ) ;
368
375
}
369
376
}
370
377
}
@@ -523,7 +530,7 @@ impl BodyUnsafety {
523
530
524
531
#[ derive( Clone , Copy , PartialEq ) ]
525
532
enum UnsafeOpKind {
526
- CallToUnsafeFunction ,
533
+ CallToUnsafeFunction ( Option < DefId > ) ,
527
534
UseOfInlineAssembly ,
528
535
InitializingTypeWith ,
529
536
UseOfMutableStatic ,
@@ -533,64 +540,71 @@ enum UnsafeOpKind {
533
540
AccessToUnionField ,
534
541
MutationOfLayoutConstrainedField ,
535
542
BorrowOfLayoutConstrainedField ,
536
- CallToFunctionWith ,
543
+ CallToFunctionWith ( DefId ) ,
537
544
}
538
545
539
546
use UnsafeOpKind :: * ;
540
547
541
548
impl UnsafeOpKind {
542
- pub fn description_and_note ( & self ) -> ( & ' static str , & ' static str ) {
549
+ pub fn description_and_note ( & self , tcx : TyCtxt < ' _ > ) -> ( Cow < ' static , str > , & ' static str ) {
543
550
match self {
544
- CallToUnsafeFunction => (
545
- "call to unsafe function" ,
551
+ CallToUnsafeFunction ( did) => (
552
+ if let Some ( did) = did {
553
+ Cow :: from ( format ! ( "call to unsafe function `{}`" , tcx. def_path_str( * did) ) )
554
+ } else {
555
+ Cow :: Borrowed ( "call to unsafe function" )
556
+ } ,
546
557
"consult the function's documentation for information on how to avoid undefined \
547
558
behavior",
548
559
) ,
549
560
UseOfInlineAssembly => (
550
- "use of inline assembly" ,
561
+ Cow :: Borrowed ( "use of inline assembly" ) ,
551
562
"inline assembly is entirely unchecked and can cause undefined behavior" ,
552
563
) ,
553
564
InitializingTypeWith => (
554
- "initializing type with `rustc_layout_scalar_valid_range` attr" ,
565
+ Cow :: Borrowed ( "initializing type with `rustc_layout_scalar_valid_range` attr" ) ,
555
566
"initializing a layout restricted type's field with a value outside the valid \
556
567
range is undefined behavior",
557
568
) ,
558
569
UseOfMutableStatic => (
559
- "use of mutable static" ,
570
+ Cow :: Borrowed ( "use of mutable static" ) ,
560
571
"mutable statics can be mutated by multiple threads: aliasing violations or data \
561
572
races will cause undefined behavior",
562
573
) ,
563
574
UseOfExternStatic => (
564
- "use of extern static" ,
575
+ Cow :: Borrowed ( "use of extern static" ) ,
565
576
"extern statics are not controlled by the Rust type system: invalid data, \
566
577
aliasing violations or data races will cause undefined behavior",
567
578
) ,
568
579
DerefOfRawPointer => (
569
- "dereference of raw pointer" ,
580
+ Cow :: Borrowed ( "dereference of raw pointer" ) ,
570
581
"raw pointers may be null, dangling or unaligned; they can violate aliasing rules \
571
582
and cause data races: all of these are undefined behavior",
572
583
) ,
573
584
AssignToDroppingUnionField => (
574
- "assignment to union field that might need dropping" ,
585
+ Cow :: Borrowed ( "assignment to union field that might need dropping" ) ,
575
586
"the previous content of the field will be dropped, which causes undefined \
576
587
behavior if the field was not properly initialized",
577
588
) ,
578
589
AccessToUnionField => (
579
- "access to union field" ,
590
+ Cow :: Borrowed ( "access to union field" ) ,
580
591
"the field may not be properly initialized: using uninitialized data will cause \
581
592
undefined behavior",
582
593
) ,
583
594
MutationOfLayoutConstrainedField => (
584
- "mutation of layout constrained field" ,
595
+ Cow :: Borrowed ( "mutation of layout constrained field" ) ,
585
596
"mutating layout constrained fields cannot statically be checked for valid values" ,
586
597
) ,
587
598
BorrowOfLayoutConstrainedField => (
588
- "borrow of layout constrained field with interior mutability" ,
599
+ Cow :: Borrowed ( "borrow of layout constrained field with interior mutability" ) ,
589
600
"references to fields of layout constrained fields lose the constraints. Coupled \
590
601
with interior mutability, the field can be changed to invalid values",
591
602
) ,
592
- CallToFunctionWith => (
593
- "call to function with `#[target_feature]`" ,
603
+ CallToFunctionWith ( did) => (
604
+ Cow :: from ( format ! (
605
+ "call to function `{}` with `#[target_feature]`" ,
606
+ tcx. def_path_str( * did)
607
+ ) ) ,
594
608
"can only be called if the required target features are available" ,
595
609
) ,
596
610
}
0 commit comments