Don't mark #[target_feature] safe fns as unsafe in rustdoc JSON.

This commit is contained in:
Predrag Gruevski 2025-07-07 00:56:29 +00:00
parent a84ab0ce6c
commit 717041232a
2 changed files with 37 additions and 1 deletions

View file

@ -9,6 +9,7 @@ use rustc_ast::ast;
use rustc_attr_data_structures::{self as attrs, DeprecatedSince};
use rustc_hir::def::CtorKind;
use rustc_hir::def_id::DefId;
use rustc_hir::{HeaderSafety, Safety};
use rustc_metadata::rendered_const;
use rustc_middle::{bug, ty};
use rustc_span::{Pos, kw, sym};
@ -383,10 +384,22 @@ impl FromClean<clean::Union> for Union {
impl FromClean<rustc_hir::FnHeader> for FunctionHeader {
fn from_clean(header: &rustc_hir::FnHeader, renderer: &JsonRenderer<'_>) -> Self {
let is_unsafe = match header.safety {
HeaderSafety::SafeTargetFeatures => {
// The type system's internal implementation details consider
// safe functions with the `#[target_feature]` attribute to be analogous
// to unsafe functions: `header.is_unsafe()` returns `true` for them.
// For rustdoc, this isn't the right decision, so we explicitly return `false`.
// Context: https://github.com/rust-lang/rust/issues/142655
false
}
HeaderSafety::Normal(Safety::Safe) => false,
HeaderSafety::Normal(Safety::Unsafe) => true,
};
FunctionHeader {
is_async: header.is_async(),
is_const: header.is_const(),
is_unsafe: header.is_unsafe(),
is_unsafe,
abi: header.abi.into_json(renderer),
}
}

View file

@ -1,17 +1,40 @@
//@ only-x86_64
//@ is "$.index[?(@.name=='test1')].attrs" '["#[target_feature(enable=\"avx\")]"]'
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
#[target_feature(enable = "avx")]
pub fn test1() {}
//@ is "$.index[?(@.name=='test2')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]'
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
#[target_feature(enable = "avx,avx2")]
pub fn test2() {}
//@ is "$.index[?(@.name=='test3')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\")]"]'
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
#[target_feature(enable = "avx", enable = "avx2")]
pub fn test3() {}
//@ is "$.index[?(@.name=='test4')].attrs" '["#[target_feature(enable=\"avx\", enable=\"avx2\", enable=\"avx512f\")]"]'
//@ is "$.index[?(@.name=='test1')].inner.function.header.is_unsafe" false
#[target_feature(enable = "avx", enable = "avx2,avx512f")]
pub fn test4() {}
//@ is "$.index[?(@.name=='test_unsafe_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
//@ is "$.index[?(@.name=='test_unsafe_fn')].inner.function.header.is_unsafe" true
#[target_feature(enable = "avx")]
pub unsafe fn test_unsafe_fn() {}
pub struct Example;
impl Example {
//@ is "$.index[?(@.name=='safe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
//@ is "$.index[?(@.name=='safe_assoc_fn')].inner.function.header.is_unsafe" false
#[target_feature(enable = "avx")]
pub fn safe_assoc_fn() {}
//@ is "$.index[?(@.name=='unsafe_assoc_fn')].attrs" '["#[target_feature(enable=\"avx\")]"]'
//@ is "$.index[?(@.name=='unsafe_assoc_fn')].inner.function.header.is_unsafe" true
#[target_feature(enable = "avx")]
pub unsafe fn unsafe_assoc_fn() {}
}