Skip to content

Commit aeae353

Browse files
authored
Merge pull request #18843 from Veykril/push-usuzxtzsnrpt
fix: Handle newstyle `rustc_intrinsic` safety correctly
2 parents f475723 + 5ee1b0a commit aeae353

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

src/tools/rust-analyzer/crates/hir-ty/src/utils.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -270,25 +270,22 @@ pub fn is_fn_unsafe_to_call(db: &dyn HirDatabase, func: FunctionId) -> bool {
270270
return true;
271271
}
272272

273-
let is_intrinsic = db.attrs(func.into()).by_key(&sym::rustc_intrinsic).exists()
274-
|| data.abi.as_ref() == Some(&sym::rust_dash_intrinsic);
275-
276273
let loc = func.lookup(db.upcast());
277274
match loc.container {
278275
hir_def::ItemContainerId::ExternBlockId(block) => {
279-
if is_intrinsic || {
280-
let id = block.lookup(db.upcast()).id;
281-
id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic)
282-
} {
283-
// Intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
276+
let id = block.lookup(db.upcast()).id;
277+
let is_intrinsic_block =
278+
id.item_tree(db.upcast())[id.value].abi.as_ref() == Some(&sym::rust_dash_intrinsic);
279+
if is_intrinsic_block {
280+
// legacy intrinsics
281+
// extern "rust-intrinsic" intrinsics are unsafe unless they have the rustc_safe_intrinsic attribute
284282
!db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists()
285283
} else {
286284
// Function in an `extern` block are always unsafe to call, except when
287285
// it is marked as `safe`.
288286
!data.is_safe()
289287
}
290288
}
291-
_ if is_intrinsic => !db.attrs(func.into()).by_key(&sym::rustc_safe_intrinsic).exists(),
292289
_ => false,
293290
}
294291
}

src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,24 @@ fn main() {
237237
fn no_missing_unsafe_diagnostic_with_safe_intrinsic() {
238238
check_diagnostics(
239239
r#"
240+
#[rustc_intrinsic]
241+
pub fn bitreverse(x: u32) -> u32; // Safe intrinsic
242+
#[rustc_intrinsic]
243+
pub unsafe fn floorf32(x: f32) -> f32; // Unsafe intrinsic
244+
245+
fn main() {
246+
let _ = bitreverse(12);
247+
let _ = floorf32(12.0);
248+
//^^^^^^^^^^^^^^💡 error: call to unsafe function is unsafe and requires an unsafe function or block
249+
}
250+
"#,
251+
);
252+
}
253+
254+
#[test]
255+
fn no_missing_unsafe_diagnostic_with_legacy_safe_intrinsic() {
256+
check_diagnostics(
257+
r#"
240258
extern "rust-intrinsic" {
241259
#[rustc_safe_intrinsic]
242260
pub fn bitreverse(x: u32) -> u32; // Safe intrinsic

0 commit comments

Comments
 (0)