Skip to content

Commit 3cb521a

Browse files
committed
Auto merge of #126761 - GuillaumeGomez:unsafe_extern_blocks, r=spastorino
rustdoc: Add support for `missing_unsafe_on_extern` feature Follow-up of #124482. Not sure if the `safe` keyword is supposed to be displayed or not though? For now I didn't add it in the generated doc, only `unsafe` as usual. cc `@spastorino` r? `@fmease`
2 parents a0f01c3 + 630c3ad commit 3cb521a

File tree

7 files changed

+70
-28
lines changed

7 files changed

+70
-28
lines changed

src/librustdoc/clean/mod.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3077,23 +3077,20 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
30773077
let def_id = item.owner_id.to_def_id();
30783078
cx.with_param_env(def_id, |cx| {
30793079
let kind = match item.kind {
3080-
// FIXME(missing_unsafe_on_extern) handle safety of foreign fns.
3081-
// Safety was added as part of the implementation of unsafe extern blocks PR #124482
3082-
hir::ForeignItemKind::Fn(decl, names, generics, _) => {
3080+
hir::ForeignItemKind::Fn(decl, names, generics, safety) => {
30833081
let (generics, decl) = enter_impl_trait(cx, |cx| {
30843082
// NOTE: generics must be cleaned before args
30853083
let generics = clean_generics(generics, cx);
30863084
let args = clean_args_from_types_and_names(cx, decl.inputs, names);
30873085
let decl = clean_fn_decl_with_args(cx, decl, None, args);
30883086
(generics, decl)
30893087
});
3090-
ForeignFunctionItem(Box::new(Function { decl, generics }))
3091-
}
3092-
// FIXME(missing_unsafe_on_extern) handle safety of foreign statics.
3093-
// Safety was added as part of the implementation of unsafe extern blocks PR #124482
3094-
hir::ForeignItemKind::Static(ty, mutability, _) => {
3095-
ForeignStaticItem(Static { type_: clean_ty(ty, cx), mutability, expr: None })
3088+
ForeignFunctionItem(Box::new(Function { decl, generics }), safety)
30963089
}
3090+
hir::ForeignItemKind::Static(ty, mutability, safety) => ForeignStaticItem(
3091+
Static { type_: clean_ty(ty, cx), mutability, expr: None },
3092+
safety,
3093+
),
30973094
hir::ForeignItemKind::Type => ForeignTypeItem,
30983095
};
30993096

src/librustdoc/clean/types.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -639,14 +639,14 @@ impl Item {
639639
hir::FnHeader { safety: sig.safety(), abi: sig.abi(), constness, asyncness }
640640
}
641641
let header = match *self.kind {
642-
ItemKind::ForeignFunctionItem(_) => {
642+
ItemKind::ForeignFunctionItem(_, safety) => {
643643
let def_id = self.def_id().unwrap();
644644
let abi = tcx.fn_sig(def_id).skip_binder().abi();
645645
hir::FnHeader {
646646
safety: if abi == Abi::RustIntrinsic {
647647
intrinsic_operation_unsafety(tcx, def_id.expect_local())
648648
} else {
649-
hir::Safety::Unsafe
649+
safety
650650
},
651651
abi,
652652
constness: if tcx.is_const_fn(def_id)
@@ -842,9 +842,9 @@ pub(crate) enum ItemKind {
842842
StructFieldItem(Type),
843843
VariantItem(Variant),
844844
/// `fn`s from an extern block
845-
ForeignFunctionItem(Box<Function>),
845+
ForeignFunctionItem(Box<Function>, hir::Safety),
846846
/// `static`s from an extern block
847-
ForeignStaticItem(Static),
847+
ForeignStaticItem(Static, hir::Safety),
848848
/// `type`s from an extern block
849849
ForeignTypeItem,
850850
MacroItem(Macro),
@@ -893,8 +893,8 @@ impl ItemKind {
893893
| TyMethodItem(_)
894894
| MethodItem(_, _)
895895
| StructFieldItem(_)
896-
| ForeignFunctionItem(_)
897-
| ForeignStaticItem(_)
896+
| ForeignFunctionItem(_, _)
897+
| ForeignStaticItem(_, _)
898898
| ForeignTypeItem
899899
| MacroItem(_)
900900
| ProcMacroItem(_)
@@ -924,8 +924,8 @@ impl ItemKind {
924924
| StaticItem(_)
925925
| ConstantItem(_, _, _)
926926
| TraitAliasItem(_)
927-
| ForeignFunctionItem(_)
928-
| ForeignStaticItem(_)
927+
| ForeignFunctionItem(_, _)
928+
| ForeignStaticItem(_, _)
929929
| ForeignTypeItem
930930
| MacroItem(_)
931931
| ProcMacroItem(_)

src/librustdoc/fold.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ pub(crate) trait DocFolder: Sized {
8484
| TyMethodItem(_)
8585
| MethodItem(_, _)
8686
| StructFieldItem(_)
87-
| ForeignFunctionItem(_)
88-
| ForeignStaticItem(_)
87+
| ForeignFunctionItem(..)
88+
| ForeignStaticItem(..)
8989
| ForeignTypeItem
9090
| MacroItem(_)
9191
| ProcMacroItem(_)

src/librustdoc/html/render/print_item.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buf
254254

255255
match &*item.kind {
256256
clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items),
257-
clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => {
257+
clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f, _) => {
258258
item_function(buf, cx, item, f)
259259
}
260260
clean::TraitItem(ref t) => item_trait(buf, cx, item, t),
@@ -265,7 +265,8 @@ pub(super) fn print_item(cx: &mut Context<'_>, item: &clean::Item, buf: &mut Buf
265265
clean::MacroItem(ref m) => item_macro(buf, cx, item, m),
266266
clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m),
267267
clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
268-
clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) => item_static(buf, cx, item, i),
268+
clean::StaticItem(ref i) => item_static(buf, cx, item, i, None),
269+
clean::ForeignStaticItem(ref i, safety) => item_static(buf, cx, item, i, Some(*safety)),
269270
clean::ConstantItem(generics, ty, c) => item_constant(buf, cx, item, generics, ty, c),
270271
clean::ForeignTypeItem => item_foreign_type(buf, cx, item),
271272
clean::KeywordItem => item_keyword(buf, cx, item),
@@ -491,11 +492,14 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
491492
}
492493

493494
let unsafety_flag = match *myitem.kind {
494-
clean::FunctionItem(_) | clean::ForeignFunctionItem(_)
495+
clean::FunctionItem(_) | clean::ForeignFunctionItem(..)
495496
if myitem.fn_header(tcx).unwrap().safety == hir::Safety::Unsafe =>
496497
{
497498
"<sup title=\"unsafe function\">⚠</sup>"
498499
}
500+
clean::ForeignStaticItem(_, hir::Safety::Unsafe) => {
501+
"<sup title=\"unsafe static\">⚠</sup>"
502+
}
499503
_ => "",
500504
};
501505

@@ -1957,13 +1961,22 @@ fn item_fields(
19571961
}
19581962
}
19591963

1960-
fn item_static(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Static) {
1964+
fn item_static(
1965+
w: &mut impl fmt::Write,
1966+
cx: &mut Context<'_>,
1967+
it: &clean::Item,
1968+
s: &clean::Static,
1969+
safety: Option<hir::Safety>,
1970+
) {
19611971
wrap_item(w, |buffer| {
19621972
render_attributes_in_code(buffer, it, cx);
19631973
write!(
19641974
buffer,
1965-
"{vis}static {mutability}{name}: {typ}",
1975+
"{vis}{safe}static {mutability}{name}: {typ}",
19661976
vis = visibility_print_with_space(it, cx),
1977+
safe = safety
1978+
.map(|safe| if safe == hir::Safety::Unsafe { "unsafe " } else { "" })
1979+
.unwrap_or(""),
19671980
mutability = s.mutability.print_with_space(),
19681981
name = it.name.unwrap(),
19691982
typ = s.type_.print(cx)

src/librustdoc/json/conversions.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,14 +310,16 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
310310
EnumItem(e) => ItemEnum::Enum(e.into_tcx(tcx)),
311311
VariantItem(v) => ItemEnum::Variant(v.into_tcx(tcx)),
312312
FunctionItem(f) => ItemEnum::Function(from_function(f, true, header.unwrap(), tcx)),
313-
ForeignFunctionItem(f) => ItemEnum::Function(from_function(f, false, header.unwrap(), tcx)),
313+
ForeignFunctionItem(f, _) => {
314+
ItemEnum::Function(from_function(f, false, header.unwrap(), tcx))
315+
}
314316
TraitItem(t) => ItemEnum::Trait((*t).into_tcx(tcx)),
315317
TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)),
316318
MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), tcx)),
317319
TyMethodItem(m) => ItemEnum::Function(from_function(m, false, header.unwrap(), tcx)),
318320
ImplItem(i) => ItemEnum::Impl((*i).into_tcx(tcx)),
319321
StaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
320-
ForeignStaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
322+
ForeignStaticItem(s, _) => ItemEnum::Static(s.into_tcx(tcx)),
321323
ForeignTypeItem => ItemEnum::ForeignType,
322324
TypeAliasItem(t) => ItemEnum::TypeAlias(t.into_tcx(tcx)),
323325
OpaqueTyItem(t) => ItemEnum::OpaqueTy(t.into_tcx(tcx)),

src/librustdoc/visit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ pub(crate) trait DocVisitor: Sized {
3333
| TyMethodItem(_)
3434
| MethodItem(_, _)
3535
| StructFieldItem(_)
36-
| ForeignFunctionItem(_)
37-
| ForeignStaticItem(_)
36+
| ForeignFunctionItem(..)
37+
| ForeignStaticItem(..)
3838
| ForeignTypeItem
3939
| MacroItem(_)
4040
| ProcMacroItem(_)

tests/rustdoc/unsafe-extern-blocks.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Test to ensure the feature is working as expected.
2+
3+
#![feature(unsafe_extern_blocks)]
4+
#![crate_name = "foo"]
5+
6+
// @has 'foo/index.html'
7+
8+
// First we check that both the static and the function have a "sup" element
9+
// to tell they're unsafe.
10+
11+
// @count - '//ul[@class="item-table"]//sup[@title="unsafe static"]' 1
12+
// @has - '//ul[@class="item-table"]//sup[@title="unsafe static"]' '⚠'
13+
// @count - '//ul[@class="item-table"]//sup[@title="unsafe function"]' 1
14+
// @has - '//ul[@class="item-table"]//sup[@title="unsafe function"]' '⚠'
15+
16+
unsafe extern {
17+
// @has 'foo/static.FOO.html'
18+
// @has - '//pre[@class="rust item-decl"]' 'pub static FOO: i32'
19+
pub safe static FOO: i32;
20+
// @has 'foo/static.BAR.html'
21+
// @has - '//pre[@class="rust item-decl"]' 'pub unsafe static BAR: i32'
22+
pub static BAR: i32;
23+
24+
// @has 'foo/fn.foo.html'
25+
// @has - '//pre[@class="rust item-decl"]' 'pub extern "C" fn foo()'
26+
pub safe fn foo();
27+
// @has 'foo/fn.bar.html'
28+
// @has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn bar()'
29+
pub fn bar();
30+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy