@@ -8,7 +8,7 @@ use crate::errors::{
88use crate :: require_same_types;
99
1010use hir:: def_id:: DefId ;
11- use rustc_errors:: struct_span_err;
11+ use rustc_errors:: { struct_span_err, DiagnosticMessage } ;
1212use rustc_hir as hir;
1313use rustc_middle:: traits:: { ObligationCause , ObligationCauseCode } ;
1414use rustc_middle:: ty:: { self , TyCtxt } ;
@@ -63,10 +63,66 @@ fn equate_intrinsic_type<'tcx>(
6363
6464/// Returns the unsafety of the given intrinsic.
6565pub 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) {
6767 true => hir:: Unsafety :: Normal ,
6868 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 ( ) ;
69123 }
124+
125+ is_in_list
70126}
71127
72128/// 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<'_>) {
312368 (
313369 1 ,
314370 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 ) ) ,
316372 ] ,
317373 tcx. mk_projection ( discriminant_def_id, tcx. mk_substs ( [ param ( 0 ) . into ( ) ] . iter ( ) ) ) ,
318374 )
0 commit comments