Skip to content

Commit f33dba0

Browse files
committed
rustdoc-json: Include safety of statics
1 parent 51ea7c1 commit f33dba0

File tree

4 files changed

+74
-14
lines changed

4 files changed

+74
-14
lines changed

src/librustdoc/json/conversions.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,8 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum {
321321
MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), renderer)),
322322
TyMethodItem(m) => ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)),
323323
ImplItem(i) => ItemEnum::Impl((*i).into_json(renderer)),
324-
StaticItem(s) => ItemEnum::Static(s.into_json(renderer)),
325-
ForeignStaticItem(s, _) => ItemEnum::Static(s.into_json(renderer)),
324+
StaticItem(s) => ItemEnum::Static(convert_static(s, rustc_hir::Safety::Safe, renderer)),
325+
ForeignStaticItem(s, safety) => ItemEnum::Static(convert_static(s, safety, renderer)),
326326
ForeignTypeItem => ItemEnum::ExternType,
327327
TypeAliasItem(t) => ItemEnum::TypeAlias(t.into_json(renderer)),
328328
// FIXME(generic_const_items): Add support for generic free consts
@@ -831,17 +831,20 @@ impl FromClean<Box<clean::TypeAlias>> for TypeAlias {
831831
}
832832
}
833833

834-
impl FromClean<clean::Static> for Static {
835-
fn from_clean(stat: clean::Static, renderer: &JsonRenderer<'_>) -> Self {
836-
let tcx = renderer.tcx;
837-
Static {
838-
type_: (*stat.type_).into_json(renderer),
839-
is_mutable: stat.mutability == ast::Mutability::Mut,
840-
expr: stat
841-
.expr
842-
.map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e)))
843-
.unwrap_or_default(),
844-
}
834+
fn convert_static(
835+
stat: clean::Static,
836+
safety: rustc_hir::Safety,
837+
renderer: &JsonRenderer<'_>,
838+
) -> Static {
839+
let tcx = renderer.tcx;
840+
Static {
841+
type_: (*stat.type_).into_json(renderer),
842+
is_mutable: stat.mutability == ast::Mutability::Mut,
843+
is_unsafe: safety == rustc_hir::Safety::Unsafe,
844+
expr: stat
845+
.expr
846+
.map(|e| rendered_const(tcx, tcx.hir().body(e), tcx.hir().body_owner_def_id(e)))
847+
.unwrap_or_default(),
845848
}
846849
}
847850

src/rustdoc-json-types/lib.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
3030
/// This integer is incremented with every breaking change to the API,
3131
/// and is returned along with the JSON blob as [`Crate::format_version`].
3232
/// Consuming code should assert that this value matches the format version(s) that it supports.
33-
pub const FORMAT_VERSION: u32 = 36;
33+
pub const FORMAT_VERSION: u32 = 37;
3434

3535
/// The root of the emitted JSON blob.
3636
///
@@ -1238,6 +1238,22 @@ pub struct Static {
12381238
///
12391239
/// It's not guaranteed that it'll match the actual source code for the initial value.
12401240
pub expr: String,
1241+
1242+
/// Is the static `unsafe`?
1243+
///
1244+
/// This is only true if it's in an `extern` block, and not explicity marked
1245+
/// as `safe`.
1246+
///
1247+
/// ```rust
1248+
/// unsafe extern {
1249+
/// static A: i32; // unsafe
1250+
/// safe static B: i32; // safe
1251+
/// }
1252+
///
1253+
/// static C: i32 = 0; // safe
1254+
/// static mut D: i32 = 0; // safe
1255+
/// ```
1256+
pub is_unsafe: bool,
12411257
}
12421258

12431259
/// A primitive type declaration. Declarations of this kind can only come from the core library.

tests/rustdoc-json/statics/extern.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// ignore-tidy-linelength
2+
//@ edition: 2021
3+
4+
extern "C" {
5+
//@ is '$.index[*][?(@.name=="A")].inner.static.is_unsafe' true
6+
//@ is '$.index[*][?(@.name=="A")].inner.static.is_mutable' false
7+
pub static A: i32;
8+
//@ is '$.index[*][?(@.name=="B")].inner.static.is_unsafe' true
9+
//@ is '$.index[*][?(@.name=="B")].inner.static.is_mutable' true
10+
pub static mut B: i32;
11+
12+
// items in unadorned `extern` blocks cannot have safety qualifiers
13+
}
14+
15+
unsafe extern "C" {
16+
//@ is '$.index[*][?(@.name=="C")].inner.static.is_unsafe' true
17+
//@ is '$.index[*][?(@.name=="C")].inner.static.is_mutable' false
18+
pub static C: i32;
19+
//@ is '$.index[*][?(@.name=="D")].inner.static.is_unsafe' true
20+
//@ is '$.index[*][?(@.name=="D")].inner.static.is_mutable' true
21+
pub static mut D: i32;
22+
23+
//@ is '$.index[*][?(@.name=="E")].inner.static.is_unsafe' false
24+
//@ is '$.index[*][?(@.name=="E")].inner.static.is_mutable' false
25+
pub safe static E: i32;
26+
//@ is '$.index[*][?(@.name=="F")].inner.static.is_unsafe' false
27+
//@ is '$.index[*][?(@.name=="F")].inner.static.is_mutable' true
28+
pub safe static mut F: i32;
29+
30+
//@ is '$.index[*][?(@.name=="G")].inner.static.is_unsafe' true
31+
//@ is '$.index[*][?(@.name=="G")].inner.static.is_mutable' false
32+
pub unsafe static G: i32;
33+
//@ is '$.index[*][?(@.name=="H")].inner.static.is_unsafe' true
34+
//@ is '$.index[*][?(@.name=="H")].inner.static.is_mutable' true
35+
pub unsafe static mut H: i32;
36+
}
37+
38+
//@ ismany '$.index[*][?(@.inner.static)].inner.static.expr' '""' '""' '""' '""' '""' '""' '""' '""'
39+
//@ ismany '$.index[*][?(@.inner.static)].inner.static.type.primitive' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"'

tests/rustdoc-json/statics/statics.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
//@ is '$.index[*][?(@.name=="A")].inner.static.type.primitive' '"i32"'
22
//@ is '$.index[*][?(@.name=="A")].inner.static.is_mutable' false
33
//@ is '$.index[*][?(@.name=="A")].inner.static.expr' '"5"'
4+
//@ is '$.index[*][?(@.name=="A")].inner.static.is_unsafe' false
45
pub static A: i32 = 5;
56

67
//@ is '$.index[*][?(@.name=="B")].inner.static.type.primitive' '"u32"'
78
//@ is '$.index[*][?(@.name=="B")].inner.static.is_mutable' true
89
// Expr value isn't gaurenteed, it'd be fine to change it.
910
//@ is '$.index[*][?(@.name=="B")].inner.static.expr' '"_"'
11+
//@ is '$.index[*][?(@.name=="B")].inner.static.is_unsafe' false
1012
pub static mut B: u32 = 2 + 3;

0 commit comments

Comments
 (0)