attributes: Add #[rustc_safe_intrinsic] builtin

This commit is contained in:
Arthur Cohen 2022-08-17 13:43:59 +02:00
parent 57ee5cf5a9
commit 0ab2c91a2d
9 changed files with 24 additions and 51 deletions

View file

@ -7,6 +7,7 @@ use crate::errors::{
};
use crate::require_same_types;
use hir::def_id::DefId;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
@ -61,51 +62,10 @@ fn equate_intrinsic_type<'tcx>(
}
/// Returns the unsafety of the given intrinsic.
pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
match intrinsic {
// 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
// safe extern fns are otherwise unprecedented.
sym::abort
| sym::assert_inhabited
| sym::assert_zero_valid
| sym::assert_uninit_valid
| sym::size_of
| sym::min_align_of
| sym::needs_drop
| sym::caller_location
| sym::add_with_overflow
| sym::sub_with_overflow
| sym::mul_with_overflow
| sym::wrapping_add
| sym::wrapping_sub
| sym::wrapping_mul
| sym::saturating_add
| sym::saturating_sub
| sym::rotate_left
| sym::rotate_right
| sym::ctpop
| sym::ctlz
| sym::cttz
| sym::bswap
| sym::bitreverse
| sym::discriminant_value
| sym::type_id
| sym::likely
| sym::unlikely
| sym::ptr_guaranteed_cmp
| sym::minnumf32
| sym::minnumf64
| sym::maxnumf32
| sym::rustc_peek
| sym::maxnumf64
| sym::type_name
| sym::forget
| sym::black_box
| sym::variant_count
| sym::ptr_mask => hir::Unsafety::Normal,
_ => hir::Unsafety::Unsafe,
pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir::Unsafety {
match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
true => hir::Unsafety::Normal,
false => hir::Unsafety::Unsafe,
}
}
@ -113,7 +73,8 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
/// 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.def_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(
@ -160,7 +121,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),
@ -351,7 +312,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
(
1,
vec![
tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0)),
tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0))
],
tcx.mk_projection(discriminant_def_id, tcx.mk_substs([param(0).into()].iter())),
)

View file

@ -2544,7 +2544,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
abi: abi::Abi,
) -> ty::PolyFnSig<'tcx> {
let unsafety = if abi == abi::Abi::RustIntrinsic {
intrinsic_operation_unsafety(tcx.item_name(def_id))
intrinsic_operation_unsafety(tcx, def_id)
} else {
hir::Unsafety::Unsafe
};