mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
Use rustc_safe_intrinsic
attribute to check for intrinsic safety
Instead of maintaining a list that is poorly kept in sync we can just use the attribute.
This commit is contained in:
parent
3033c3ddbf
commit
72afcf2cad
3 changed files with 14 additions and 48 deletions
|
@ -350,6 +350,7 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||||
),
|
),
|
||||||
ungated!(rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
|
ungated!(rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
|
||||||
ungated!(rustc_const_stable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
|
ungated!(rustc_const_stable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
|
||||||
|
ungated!(rustc_safe_intrinsic, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
|
||||||
gated!(
|
gated!(
|
||||||
allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), DuplicatesOk,
|
allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), DuplicatesOk,
|
||||||
"allow_internal_unstable side-steps feature gating and stability checks",
|
"allow_internal_unstable side-steps feature gating and stability checks",
|
||||||
|
|
|
@ -17,7 +17,7 @@ use hir_def::{
|
||||||
ConstParamId, FunctionId, GenericDefId, ItemContainerId, Lookup, TraitId, TypeAliasId,
|
ConstParamId, FunctionId, GenericDefId, ItemContainerId, Lookup, TraitId, TypeAliasId,
|
||||||
TypeOrConstParamId, TypeParamId,
|
TypeOrConstParamId, TypeParamId,
|
||||||
};
|
};
|
||||||
use hir_expand::name::{known, Name};
|
use hir_expand::name::Name;
|
||||||
use itertools::Either;
|
use itertools::Either;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
|
@ -335,54 +335,18 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
|
||||||
// Function in an `extern` block are always unsafe to call, except when it has
|
// Function in an `extern` block are always unsafe to call, except when it has
|
||||||
// `"rust-intrinsic"` ABI there are a few exceptions.
|
// `"rust-intrinsic"` ABI there are a few exceptions.
|
||||||
let id = block.lookup(db.upcast()).id;
|
let id = block.lookup(db.upcast()).id;
|
||||||
!matches!(
|
|
||||||
id.item_tree(db.upcast())[id.value].abi.as_deref(),
|
let is_intrinsic =
|
||||||
Some("rust-intrinsic") if !is_intrinsic_fn_unsafe(&data.name)
|
id.item_tree(db.upcast())[id.value].abi.as_deref() == Some("rust-intrinsic");
|
||||||
)
|
|
||||||
|
if is_intrinsic {
|
||||||
|
// Intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
|
||||||
|
!data.attrs.by_key("rustc_safe_intrinsic").exists()
|
||||||
|
} else {
|
||||||
|
// Extern items are always unsafe
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the given intrinsic is unsafe to call, or false otherwise.
|
|
||||||
fn is_intrinsic_fn_unsafe(name: &Name) -> bool {
|
|
||||||
// Should be kept in sync with https://github.com/rust-lang/rust/blob/532d2b14c05f9bc20b2d27cbb5f4550d28343a36/compiler/rustc_typeck/src/check/intrinsic.rs#L72-L106
|
|
||||||
![
|
|
||||||
known::abort,
|
|
||||||
known::add_with_overflow,
|
|
||||||
known::bitreverse,
|
|
||||||
known::black_box,
|
|
||||||
known::bswap,
|
|
||||||
known::caller_location,
|
|
||||||
known::ctlz,
|
|
||||||
known::ctpop,
|
|
||||||
known::cttz,
|
|
||||||
known::discriminant_value,
|
|
||||||
known::forget,
|
|
||||||
known::likely,
|
|
||||||
known::maxnumf32,
|
|
||||||
known::maxnumf64,
|
|
||||||
known::min_align_of,
|
|
||||||
known::minnumf32,
|
|
||||||
known::minnumf64,
|
|
||||||
known::mul_with_overflow,
|
|
||||||
known::needs_drop,
|
|
||||||
known::ptr_guaranteed_eq,
|
|
||||||
known::ptr_guaranteed_ne,
|
|
||||||
known::rotate_left,
|
|
||||||
known::rotate_right,
|
|
||||||
known::rustc_peek,
|
|
||||||
known::saturating_add,
|
|
||||||
known::saturating_sub,
|
|
||||||
known::size_of,
|
|
||||||
known::sub_with_overflow,
|
|
||||||
known::type_id,
|
|
||||||
known::type_name,
|
|
||||||
known::unlikely,
|
|
||||||
known::variant_count,
|
|
||||||
known::wrapping_add,
|
|
||||||
known::wrapping_mul,
|
|
||||||
known::wrapping_sub,
|
|
||||||
]
|
|
||||||
.contains(name)
|
|
||||||
}
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ fn main() {
|
||||||
check_diagnostics(
|
check_diagnostics(
|
||||||
r#"
|
r#"
|
||||||
extern "rust-intrinsic" {
|
extern "rust-intrinsic" {
|
||||||
|
#[rustc_safe_intrinsic]
|
||||||
pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
|
pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
|
||||||
pub fn floorf32(x: f32) -> f32; // Unsafe intrinsic
|
pub fn floorf32(x: f32) -> f32; // Unsafe intrinsic
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue