diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_hir_analysis/src/check/intrinsic.rs (renamed from compiler/rustc_typeck/src/check/intrinsic.rs) | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index c7425ff78..609095c9c 100644 --- a/compiler/rustc_typeck/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -7,10 +7,10 @@ use crate::errors::{ }; use crate::require_same_types; -use rustc_errors::struct_span_err; +use hir::def_id::DefId; +use rustc_errors::{struct_span_err, DiagnosticMessage}; use rustc_hir as hir; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; -use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_target::spec::abi::Abi; @@ -26,7 +26,7 @@ fn equate_intrinsic_type<'tcx>( ) { let (own_counts, span) = match &it.kind { hir::ForeignItemKind::Fn(.., generics) => { - let own_counts = tcx.generics_of(it.def_id.to_def_id()).own_counts(); + let own_counts = tcx.generics_of(it.owner_id.to_def_id()).own_counts(); (own_counts, generics.span) } _ => { @@ -57,13 +57,17 @@ fn equate_intrinsic_type<'tcx>( { let fty = tcx.mk_fn_ptr(sig); let cause = ObligationCause::new(it.span, it.hir_id(), ObligationCauseCode::IntrinsicType); - require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.def_id)), fty); + require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(it.owner_id)), fty); } } /// Returns the unsafety of the given intrinsic. -pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety { - match intrinsic { +pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir::Unsafety { + let has_safe_attr = match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) { + true => hir::Unsafety::Normal, + false => hir::Unsafety::Unsafe, + }; + let is_in_list = match tcx.item_name(intrinsic_id) { // When adding a new intrinsic to this list, // it's usually worth updating that intrinsic's documentation // to note that it's safe to call, since @@ -107,14 +111,26 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety { | sym::variant_count | sym::ptr_mask => hir::Unsafety::Normal, _ => hir::Unsafety::Unsafe, + }; + + if has_safe_attr != is_in_list { + tcx.sess.struct_span_err( + tcx.def_span(intrinsic_id), + DiagnosticMessage::Str(format!( + "intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`", + tcx.item_name(intrinsic_id) + ))).emit(); } + + is_in_list } /// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`, /// and in `library/core/src/intrinsics.rs`. pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n))); - let intrinsic_name = tcx.item_name(it.def_id.to_def_id()); + let intrinsic_id = it.owner_id.to_def_id(); + let intrinsic_name = tcx.item_name(intrinsic_id); let name_str = intrinsic_name.as_str(); let bound_vars = tcx.mk_bound_variable_kinds( @@ -161,7 +177,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }; (n_tps, 0, inputs, output, hir::Unsafety::Unsafe) } else { - let unsafety = intrinsic_operation_unsafety(intrinsic_name); + let unsafety = intrinsic_operation_unsafety(tcx, intrinsic_id); let (n_tps, inputs, output) = match intrinsic_name { sym::abort => (0, Vec::new(), tcx.types.never), sym::unreachable => (0, Vec::new(), tcx.types.never), |