mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 05:08:52 +00:00
fix: Handle newstyle rustc_intrinsic
safety correctly
This commit is contained in:
parent
6725e046df
commit
e462ee79e4
2 changed files with 24 additions and 9 deletions
|
@ -270,17 +270,15 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_intrinsic = db.attrs(func.into()).by_key(&sym::rustc_intrinsic).exists()
|
|
||||||
|| data.abi.as_ref() == Some(&sym::rust_dash_intrinsic);
|
|
||||||
|
|
||||||
let loc = func.lookup(db.upcast());
|
let loc = func.lookup(db.upcast());
|
||||||
match loc.container {
|
match loc.container {
|
||||||
hir_def::ItemContainerId::ExternBlockId(block) => {
|
hir_def::ItemContainerId::ExternBlockId(block) => {
|
||||||
if is_intrinsic || {
|
|
||||||
let id = block.lookup(db.upcast()).id;
|
let id = block.lookup(db.upcast()).id;
|
||||||
id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic)
|
let is_intrinsic_block =
|
||||||
} {
|
id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic);
|
||||||
// Intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
|
if is_intrinsic_block {
|
||||||
|
// legacy intrinsics
|
||||||
|
// extern "rust-intrinsic" intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
|
||||||
!db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists()
|
!db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists()
|
||||||
} else {
|
} else {
|
||||||
// Function in an `extern` block are always unsafe to call, except when
|
// Function in an `extern` block are always unsafe to call, except when
|
||||||
|
@ -288,7 +286,6 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
|
||||||
!data.is_safe()
|
!data.is_safe()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ if is_intrinsic => !db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists(),
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -237,6 +237,24 @@ fn main() {
|
||||||
fn no_missing_unsafe_diagnostic_with_safe_intrinsic() {
|
fn no_missing_unsafe_diagnostic_with_safe_intrinsic() {
|
||||||
check_diagnostics(
|
check_diagnostics(
|
||||||
r#"
|
r#"
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
|
||||||
|
#[rustc_intrinsic]
|
||||||
|
pub unsafe fn floorf32(x: f32) -> f32; // Unsafe intrinsic
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = bitreverse(12);
|
||||||
|
let _ = floorf32(12.0);
|
||||||
|
//^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_missing_unsafe_diagnostic_with_legacy_safe_intrinsic() {
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
extern "rust-intrinsic" {
|
extern "rust-intrinsic" {
|
||||||
#[rustc_safe_intrinsic]
|
#[rustc_safe_intrinsic]
|
||||||
pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
|
pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
|
||||||
|
|
Loading…
Reference in a new issue