Skip to content

Commit 239f472

Browse files
committed
Don't mark #[target_feature] safe fns as unsafe in rustdoc JSON.
1 parent a84ab0c commit 239f472

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

src/librustdoc/json/conversions.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use rustc_abi::ExternAbi;
88
use rustc_ast::ast;
99
use rustc_attr_data_structures::{self as attrs, DeprecatedSince};
10+
use rustc_hir::HeaderSafety;
1011
use rustc_hir::def::CtorKind;
1112
use rustc_hir::def_id::DefId;
1213
use rustc_metadata::rendered_const;
@@ -383,10 +384,16 @@ impl FromClean<clean::Union> for Union {
383384

384385
impl FromClean<rustc_hir::FnHeader> for FunctionHeader {
385386
fn from_clean(header: &rustc_hir::FnHeader, renderer: &JsonRenderer<'_>) -> Self {
387+
// The type system's internal implementation details consider
388+
// safe functions with the `#[target_feature]` attribute as analogous to unsafe functions.
389+
// `header.is_unsafe()` returns `true` for them. But that's not the right decision
390+
// for rustdoc, so we specifically exclude that case.
391+
let is_unsafe =
392+
header.is_unsafe() && !matches!(header.safety, HeaderSafety::SafeTargetFeatures);
386393
FunctionHeader {
387394
is_async: header.is_async(),
388395
is_const: header.is_const(),
389-
is_unsafe: header.is_unsafe(),
396+
is_unsafe,
390397
abi: header.abi.into_json(renderer),
391398
}
392399
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,40 @@
11
//@ only-x86_64
22

33
//@ is "$.index[?(@.name=='test1')].attrs" '["#[target_feature(enable=\"avx\")]"]'
4+
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
45
#[target_feature(enable = "avx")]
56
pub fn test1() {}
67

78
//@ is "$.index[?(@.name=='test2')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]'
9+
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
810
#[target_feature(enable = "avx,avx2")]
911
pub fn test2() {}
1012

1113
//@ is "$.index[?(@.name=='test3')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]'
14+
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
1215
#[target_feature(enable = "avx", enable = "avx2")]
1316
pub fn test3() {}
1417

1518
//@ is "$.index[?(@.name=='test4')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\", enable=\"avx512f\")]"]'
19+
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
1620
#[target_feature(enable = "avx", enable = "avx2,avx512f")]
1721
pub fn test4() {}
22+
23+
//@ is "$.index[?(@.name=='test_unsafe_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
24+
//@ is "$.index[?(@.name=='test_unsafe_fn')].inner.function.header.is_unsafe" true
25+
#[target_feature(enable = "avx")]
26+
pub unsafe fn test_unsafe_fn() {}
27+
28+
pub struct Example;
29+
30+
impl Example {
31+
//@ is "$.index[?(@.name=='safe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
32+
//@ is "$.index[?(@.name=='safe_assoc_fn')].inner.function.header.is_unsafe" false
33+
#[target_feature(enable = "avx")]
34+
pub fn safe_assoc_fn() {}
35+
36+
//@ is "$.index[?(@.name=='unsafe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
37+
//@ is "$.index[?(@.name=='unsafe_assoc_fn')].inner.function.header.is_unsafe" true
38+
#[target_feature(enable = "avx")]
39+
pub unsafe fn unsafe_assoc_fn() {}
40+
}

0 commit comments

Comments
 (0)