Skip to content

Commit 1924f2d

Browse files
authored
Unrolled build for rust-lang#113241
Rollup merge of rust-lang#113241 - poliorcetics:85138-doc-object-safety, r=GuillaumeGomez rustdoc: Document lack of object safety on affected traits Closes rust-lang#85138 I saw the issue didn't have any recent activity, if there is another MR for it I missed it. I want the issue to move forward so here is my proposition. It takes some space just before the "Implementors" section and only if the trait is **not** object safe since it is the only case where special care must be taken in some cases and this has the benefit of avoiding generation of HTML in (I hope) the common case.
2 parents 9d83ac2 + a119158 commit 1924f2d

File tree

6 files changed

+61
-0
lines changed

6 files changed

+61
-0
lines changed

src/librustdoc/clean/types.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1455,6 +1455,9 @@ impl Trait {
14551455
pub(crate) fn unsafety(&self, tcx: TyCtxt<'_>) -> hir::Unsafety {
14561456
tcx.trait_def(self.def_id).unsafety
14571457
}
1458+
pub(crate) fn is_object_safe(&self, tcx: TyCtxt<'_>) -> bool {
1459+
tcx.check_is_object_safe(self.def_id)
1460+
}
14581461
}
14591462

14601463
#[derive(Clone, Debug)]

src/librustdoc/html/markdown.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,7 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
20242024
map.insert("required-associated-consts".into(), 1);
20252025
map.insert("required-methods".into(), 1);
20262026
map.insert("provided-methods".into(), 1);
2027+
map.insert("object-safety".into(), 1);
20272028
map.insert("implementors".into(), 1);
20282029
map.insert("synthetic-implementors".into(), 1);
20292030
map.insert("implementations-list".into(), 1);

src/librustdoc/html/render/print_item.rs

+15
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,21 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
954954
let cloned_shared = Rc::clone(&cx.shared);
955955
let cache = &cloned_shared.cache;
956956
let mut extern_crates = FxHashSet::default();
957+
958+
if !t.is_object_safe(cx.tcx()) {
959+
write_small_section_header(
960+
w,
961+
"object-safety",
962+
"Object Safety",
963+
&format!(
964+
"<div class=\"object-safety-info\">This trait is <b>not</b> \
965+
<a href=\"{base}/reference/items/traits.html#object-safety\">\
966+
object safe</a>.</div>",
967+
base = crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL
968+
),
969+
);
970+
}
971+
957972
if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
958973
// The DefId is for the first Type found with that name. The bool is
959974
// if any Types with the same name but different DefId have been found.

src/librustdoc/html/render/sidebar.rs

+8
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,14 @@ fn sidebar_trait<'a>(
218218
.map(|(id, title, items)| LinkBlock::new(Link::new(id, title), "", items))
219219
.collect();
220220
sidebar_assoc_items(cx, it, &mut blocks);
221+
222+
if !t.is_object_safe(cx.tcx()) {
223+
blocks.push(LinkBlock::forced(
224+
Link::new("object-safety", "Object Safety"),
225+
"object-safety-note",
226+
));
227+
}
228+
221229
blocks.push(LinkBlock::forced(Link::new("implementors", "Implementors"), "impl"));
222230
if t.is_auto(cx.tcx()) {
223231
blocks.push(LinkBlock::forced(

tests/rustdoc/sidebar-items.rs

+7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// @has - '//*[@class="sidebar-elems"]//section//a' 'Output'
1515
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-types"]' 'Provided Associated Types'
1616
// @has - '//*[@class="sidebar-elems"]//section//a' 'Extra'
17+
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' 'Object Safety'
1718
pub trait Foo {
1819
const FOO: usize;
1920
const BAR: u32 = 0;
@@ -24,6 +25,12 @@ pub trait Foo {
2425
fn bar() -> Self::Output;
2526
}
2627

28+
// @has foo/trait.Safe.html
29+
// @!has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' ''
30+
pub trait Safe {
31+
fn access(&self);
32+
}
33+
2734
// @has foo/struct.Bar.html
2835
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#fields"]' 'Fields'
2936
// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f"]' 'f'

tests/rustdoc/trait-object-safe.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#![crate_name = "foo"]
2+
3+
// @has 'foo/trait.Unsafe.html'
4+
// @has - '//*[@class="object-safety-info"]' 'This trait is not object safe.'
5+
// @has - '//*[@id="object-safety"]' 'Object Safety'
6+
pub trait Unsafe {
7+
fn foo() -> Self;
8+
}
9+
10+
// @has 'foo/trait.Unsafe2.html'
11+
// @has - '//*[@class="object-safety-info"]' 'This trait is not object safe.'
12+
// @has - '//*[@id="object-safety"]' 'Object Safety'
13+
pub trait Unsafe2<T> {
14+
fn foo(i: T);
15+
}
16+
17+
// @has 'foo/trait.Safe.html'
18+
// @!has - '//*[@class="object-safety-info"]' ''
19+
// @!has - '//*[@id="object-safety"]' ''
20+
pub trait Safe {
21+
fn foo(&self);
22+
}
23+
24+
// @has 'foo/struct.Foo.html'
25+
// @!has - '//*[@class="object-safety-info"]' ''
26+
// @!has - '//*[@id="object-safety"]' ''
27+
pub struct Foo;

0 commit comments

Comments
 (0)