@@ -8,7 +8,7 @@ use crate::errors::{
8
8
use crate :: require_same_types;
9
9
10
10
use hir:: def_id:: DefId ;
11
- use rustc_errors:: struct_span_err;
11
+ use rustc_errors:: { struct_span_err, DiagnosticMessage } ;
12
12
use rustc_hir as hir;
13
13
use rustc_middle:: traits:: { ObligationCause , ObligationCauseCode } ;
14
14
use rustc_middle:: ty:: { self , TyCtxt } ;
@@ -63,10 +63,66 @@ fn equate_intrinsic_type<'tcx>(
63
63
64
64
/// Returns the unsafety of the given intrinsic.
65
65
pub fn intrinsic_operation_unsafety ( tcx : TyCtxt < ' _ > , intrinsic_id : DefId ) -> hir:: Unsafety {
66
- match tcx. has_attr ( intrinsic_id, sym:: rustc_safe_intrinsic) {
66
+ let has_safe_attr = match tcx. has_attr ( intrinsic_id, sym:: rustc_safe_intrinsic) {
67
67
true => hir:: Unsafety :: Normal ,
68
68
false => hir:: Unsafety :: Unsafe ,
69
+ } ;
70
+ let is_in_list = match tcx. item_name ( intrinsic_id) {
71
+ // When adding a new intrinsic to this list,
72
+ // it's usually worth updating that intrinsic's documentation
73
+ // to note that it's safe to call, since
74
+ // safe extern fns are otherwise unprecedented.
75
+ sym:: abort
76
+ | sym:: assert_inhabited
77
+ | sym:: assert_zero_valid
78
+ | sym:: assert_uninit_valid
79
+ | sym:: size_of
80
+ | sym:: min_align_of
81
+ | sym:: needs_drop
82
+ | sym:: caller_location
83
+ | sym:: add_with_overflow
84
+ | sym:: sub_with_overflow
85
+ | sym:: mul_with_overflow
86
+ | sym:: wrapping_add
87
+ | sym:: wrapping_sub
88
+ | sym:: wrapping_mul
89
+ | sym:: saturating_add
90
+ | sym:: saturating_sub
91
+ | sym:: rotate_left
92
+ | sym:: rotate_right
93
+ | sym:: ctpop
94
+ | sym:: ctlz
95
+ | sym:: cttz
96
+ | sym:: bswap
97
+ | sym:: bitreverse
98
+ | sym:: discriminant_value
99
+ | sym:: type_id
100
+ | sym:: likely
101
+ | sym:: unlikely
102
+ | sym:: ptr_guaranteed_cmp
103
+ | sym:: minnumf32
104
+ | sym:: minnumf64
105
+ | sym:: maxnumf32
106
+ | sym:: rustc_peek
107
+ | sym:: maxnumf64
108
+ | sym:: type_name
109
+ | sym:: forget
110
+ | sym:: black_box
111
+ | sym:: variant_count
112
+ | sym:: ptr_mask => hir:: Unsafety :: Normal ,
113
+ _ => hir:: Unsafety :: Unsafe ,
114
+ } ;
115
+
116
+ if has_safe_attr != is_in_list {
117
+ tcx. sess . struct_span_err (
118
+ tcx. def_span ( intrinsic_id) ,
119
+ DiagnosticMessage :: Str ( format ! (
120
+ "intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`" ,
121
+ tcx. item_name( intrinsic_id)
122
+ ) ) ) . emit ( ) ;
69
123
}
124
+
125
+ is_in_list
70
126
}
71
127
72
128
/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
@@ -312,7 +368,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
312
368
(
313
369
1 ,
314
370
vec ! [
315
- tcx. mk_imm_ref( tcx. mk_region( ty:: ReLateBound ( ty:: INNERMOST , br) ) , param( 0 ) )
371
+ tcx. mk_imm_ref( tcx. mk_region( ty:: ReLateBound ( ty:: INNERMOST , br) ) , param( 0 ) ) ,
316
372
] ,
317
373
tcx. mk_projection ( discriminant_def_id, tcx. mk_substs ( [ param ( 0 ) . into ( ) ] . iter ( ) ) ) ,
318
374
)
0 commit comments