diff options
| author | Matthias Krüger <476013+matthiaskrgr@users.noreply.github.com> | 2025-07-08 19:29:38 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-08 19:29:38 +0200 |
| commit | cbf7f80d5c65fd73169b8999513e1b934b84976c (patch) | |
| tree | 84a0e7a989b4bb97c0bf667176a5dbaf0ae98df6 | |
| parent | bc9b313cb5d784e88c5e7d272b46ac385970bd51 (diff) | |
| parent | 717041232ae0ae0ae445a2a302510aab3375ea47 (diff) | |
| download | rust-cbf7f80d5c65fd73169b8999513e1b934b84976c.tar.gz rust-cbf7f80d5c65fd73169b8999513e1b934b84976c.zip | |
Rollup merge of #143555 - obi1kenobi:pg/target-feature-not-unsafe-rustdoc-json, r=aDotInTheVoid
Don't mark `#[target_feature]` safe fns as unsafe in rustdoc JSON. Fixes https://github.com/rust-lang/rust/issues/142655 by explicitly checking whether functions are safe but using `#[target_feature]`, instead of relying on the `FnHeader::is_unsafe()` method which considers such functions unsafe. I don't believe this merits a bump of the rustdoc JSON `FORMAT_VERSION` constant, since the format is unchanged and this is just a small bugfix. r? aDotInTheVoid
| -rw-r--r-- | src/librustdoc/json/conversions.rs | 15 | ||||
| -rw-r--r-- | tests/rustdoc-json/attrs/target_feature.rs | 23 |
2 files changed, 37 insertions, 1 deletions
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index abf3f3fcedd..e7163bead92 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -7,6 +7,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}; @@ -381,10 +382,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), } } diff --git a/tests/rustdoc-json/attrs/target_feature.rs b/tests/rustdoc-json/attrs/target_feature.rs index ee2b3235f72..80262d8e332 100644 --- a/tests/rustdoc-json/attrs/target_feature.rs +++ b/tests/rustdoc-json/attrs/target_feature.rs @@ -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() {} +} |
