summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir_analysis/src/check/intrinsic.rs
diff options
context:
space:
mode:
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),