From 51ea7c12e70244dc89893888f3bfd6cead59d4c5 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Sun, 1 Dec 2024 21:37:18 +0000 Subject: [PATCH 1/2] rustdoc-json: Add tests for `static`s --- tests/rustdoc-json/statics/statics.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/rustdoc-json/statics/statics.rs diff --git a/tests/rustdoc-json/statics/statics.rs b/tests/rustdoc-json/statics/statics.rs new file mode 100644 index 000000000000..e3ed93699256 --- /dev/null +++ b/tests/rustdoc-json/statics/statics.rs @@ -0,0 +1,10 @@ +//@ is '$.index[*][?(@.name=="A")].inner.static.type.primitive' '"i32"' +//@ is '$.index[*][?(@.name=="A")].inner.static.is_mutable' false +//@ is '$.index[*][?(@.name=="A")].inner.static.expr' '"5"' +pub static A: i32 = 5; + +//@ is '$.index[*][?(@.name=="B")].inner.static.type.primitive' '"u32"' +//@ is '$.index[*][?(@.name=="B")].inner.static.is_mutable' true +// Expr value isn't gaurenteed, it'd be fine to change it. +//@ is '$.index[*][?(@.name=="B")].inner.static.expr' '"_"' +pub static mut B: u32 = 2 + 3; From f33dba028704d108497b8c06943b9bbc3d14c42b Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Sun, 1 Dec 2024 21:39:58 +0000 Subject: [PATCH 2/2] rustdoc-json: Include safety of `static`s --- src/librustdoc/json/conversions.rs | 29 +++++++++++--------- src/rustdoc-json-types/lib.rs | 18 ++++++++++++- tests/rustdoc-json/statics/extern.rs | 39 +++++++++++++++++++++++++++ tests/rustdoc-json/statics/statics.rs | 2 ++ 4 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 tests/rustdoc-json/statics/extern.rs diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 1c8303d4c208..bb967b7f163e 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -321,8 +321,8 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), renderer)), TyMethodItem(m) => ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)), ImplItem(i) => ItemEnum::Impl((*i).into_json(renderer)), - StaticItem(s) => ItemEnum::Static(s.into_json(renderer)), - ForeignStaticItem(s, _) => ItemEnum::Static(s.into_json(renderer)), + StaticItem(s) => ItemEnum::Static(convert_static(s, rustc_hir::Safety::Safe, renderer)), + ForeignStaticItem(s, safety) => ItemEnum::Static(convert_static(s, safety, renderer)), ForeignTypeItem => ItemEnum::ExternType, TypeAliasItem(t) => ItemEnum::TypeAlias(t.into_json(renderer)), // FIXME(generic_const_items): Add support for generic free consts @@ -831,17 +831,20 @@ impl FromClean> for TypeAlias { } } -impl FromClean for Static { - fn from_clean(stat: clean::Static, renderer: &JsonRenderer<'_>) -> Self { - let tcx = renderer.tcx; - Static { - type_: (*stat.type_).into_json(renderer), - is_mutable: stat.mutability == ast::Mutability::Mut, - expr: stat - .expr - .map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e))) - .unwrap_or_default(), - } +fn convert_static( + stat: clean::Static, + safety: rustc_hir::Safety, + renderer: &JsonRenderer<'_>, +) -> Static { + let tcx = renderer.tcx; + Static { + type_: (*stat.type_).into_json(renderer), + is_mutable: stat.mutability == ast::Mutability::Mut, + is_unsafe: safety == rustc_hir::Safety::Unsafe, + expr: stat + .expr + .map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e))) + .unwrap_or_default(), } } diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index f553a78d766e..84b33e3d8606 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -30,7 +30,7 @@ pub type FxHashMap = HashMap; // re-export for use in src/librustdoc /// This integer is incremented with every breaking change to the API, /// and is returned along with the JSON blob as [`Crate::format_version`]. /// Consuming code should assert that this value matches the format version(s) that it supports. -pub const FORMAT_VERSION: u32 = 36; +pub const FORMAT_VERSION: u32 = 37; /// The root of the emitted JSON blob. /// @@ -1238,6 +1238,22 @@ pub struct Static { /// /// It's not guaranteed that it'll match the actual source code for the initial value. pub expr: String, + + /// Is the static `unsafe`? + /// + /// This is only true if it's in an `extern` block, and not explicity marked + /// as `safe`. + /// + /// ```rust + /// unsafe extern { + /// static A: i32; // unsafe + /// safe static B: i32; // safe + /// } + /// + /// static C: i32 = 0; // safe + /// static mut D: i32 = 0; // safe + /// ``` + pub is_unsafe: bool, } /// A primitive type declaration. Declarations of this kind can only come from the core library. diff --git a/tests/rustdoc-json/statics/extern.rs b/tests/rustdoc-json/statics/extern.rs new file mode 100644 index 000000000000..d38fdf1cd1cd --- /dev/null +++ b/tests/rustdoc-json/statics/extern.rs @@ -0,0 +1,39 @@ +// ignore-tidy-linelength +//@ edition: 2021 + +extern "C" { + //@ is '$.index[*][?(@.name=="A")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="A")].inner.static.is_mutable' false + pub static A: i32; + //@ is '$.index[*][?(@.name=="B")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="B")].inner.static.is_mutable' true + pub static mut B: i32; + + // items in unadorned `extern` blocks cannot have safety qualifiers +} + +unsafe extern "C" { + //@ is '$.index[*][?(@.name=="C")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="C")].inner.static.is_mutable' false + pub static C: i32; + //@ is '$.index[*][?(@.name=="D")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="D")].inner.static.is_mutable' true + pub static mut D: i32; + + //@ is '$.index[*][?(@.name=="E")].inner.static.is_unsafe' false + //@ is '$.index[*][?(@.name=="E")].inner.static.is_mutable' false + pub safe static E: i32; + //@ is '$.index[*][?(@.name=="F")].inner.static.is_unsafe' false + //@ is '$.index[*][?(@.name=="F")].inner.static.is_mutable' true + pub safe static mut F: i32; + + //@ is '$.index[*][?(@.name=="G")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="G")].inner.static.is_mutable' false + pub unsafe static G: i32; + //@ is '$.index[*][?(@.name=="H")].inner.static.is_unsafe' true + //@ is '$.index[*][?(@.name=="H")].inner.static.is_mutable' true + pub unsafe static mut H: i32; +} + +//@ ismany '$.index[*][?(@.inner.static)].inner.static.expr' '""' '""' '""' '""' '""' '""' '""' '""' +//@ ismany '$.index[*][?(@.inner.static)].inner.static.type.primitive' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' diff --git a/tests/rustdoc-json/statics/statics.rs b/tests/rustdoc-json/statics/statics.rs index e3ed93699256..a8af23cc87dc 100644 --- a/tests/rustdoc-json/statics/statics.rs +++ b/tests/rustdoc-json/statics/statics.rs @@ -1,10 +1,12 @@ //@ is '$.index[*][?(@.name=="A")].inner.static.type.primitive' '"i32"' //@ is '$.index[*][?(@.name=="A")].inner.static.is_mutable' false //@ is '$.index[*][?(@.name=="A")].inner.static.expr' '"5"' +//@ is '$.index[*][?(@.name=="A")].inner.static.is_unsafe' false pub static A: i32 = 5; //@ is '$.index[*][?(@.name=="B")].inner.static.type.primitive' '"u32"' //@ is '$.index[*][?(@.name=="B")].inner.static.is_mutable' true // Expr value isn't gaurenteed, it'd be fine to change it. //@ is '$.index[*][?(@.name=="B")].inner.static.expr' '"_"' +//@ is '$.index[*][?(@.name=="B")].inner.static.is_unsafe' false pub static mut B: u32 = 2 + 3;