Skip to content

Commit 7170412

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

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

src/librustdoc/json/conversions.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_ast::ast;
99
use rustc_attr_data_structures::{self as attrs, DeprecatedSince};
1010
use rustc_hir::def::CtorKind;
1111
use rustc_hir::def_id::DefId;
12+
use rustc_hir::{HeaderSafety, Safety};
1213
use rustc_metadata::rendered_const;
1314
use rustc_middle::{bug, ty};
1415
use rustc_span::{Pos, kw, sym};
@@ -383,10 +384,22 @@ 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+
let is_unsafe = match header.safety {
388+
HeaderSafety::SafeTargetFeatures => {
389+
// The type system's internal implementation details consider
390+
// safe functions with the `#[target_feature]` attribute to be analogous
391+
// to unsafe functions: `header.is_unsafe()` returns `true` for them.
392+
// For rustdoc, this isn't the right decision, so we explicitly return `false`.
393+
// Context: https://github.com/rust-lang/rust/issues/142655
394+
false
395+
}
396+
HeaderSafety::Normal(Safety::Safe) => false,
397+
HeaderSafety::Normal(Safety::Unsafe) => true,
398+
};
386399
FunctionHeader {
387400
is_async: header.is_async(),
388401
is_const: header.is_const(),
389-
is_unsafe: header.is_unsafe(),
402+
is_unsafe,
390403
abi: header.abi.into_json(renderer),
391404
}
392405
}
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)