Skip to content

Commit

Permalink
Rollup merge of #113241 - poliorcetics:85138-doc-object-safety, r=Gui…
Browse files Browse the repository at this point in the history
…llaumeGomez

rustdoc: Document lack of object safety on affected traits

Closes #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.
  • Loading branch information
matthiaskrgr authored Oct 31, 2023
2 parents d7d9f15 + a119158 commit 51b275b
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,9 @@ impl Trait {
pub(crate) fn unsafety(&self, tcx: TyCtxt<'_>) -> hir::Unsafety {
tcx.trait_def(self.def_id).unsafety
}
pub(crate) fn is_object_safe(&self, tcx: TyCtxt<'_>) -> bool {
tcx.check_is_object_safe(self.def_id)
}
}

#[derive(Clone, Debug)]
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2024,6 +2024,7 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
map.insert("required-associated-consts".into(), 1);
map.insert("required-methods".into(), 1);
map.insert("provided-methods".into(), 1);
map.insert("object-safety".into(), 1);
map.insert("implementors".into(), 1);
map.insert("synthetic-implementors".into(), 1);
map.insert("implementations-list".into(), 1);
Expand Down
15 changes: 15 additions & 0 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,21 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
let cloned_shared = Rc::clone(&cx.shared);
let cache = &cloned_shared.cache;
let mut extern_crates = FxHashSet::default();

if !t.is_object_safe(cx.tcx()) {
write_small_section_header(
w,
"object-safety",
"Object Safety",
&format!(
"<div class=\"object-safety-info\">This trait is <b>not</b> \
<a href=\"{base}/reference/items/traits.html#object-safety\">\
object safe</a>.</div>",
base = crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL
),
);
}

if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) {
// The DefId is for the first Type found with that name. The bool is
// if any Types with the same name but different DefId have been found.
Expand Down
8 changes: 8 additions & 0 deletions src/librustdoc/html/render/sidebar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,14 @@ fn sidebar_trait<'a>(
.map(|(id, title, items)| LinkBlock::new(Link::new(id, title), "", items))
.collect();
sidebar_assoc_items(cx, it, &mut blocks);

if !t.is_object_safe(cx.tcx()) {
blocks.push(LinkBlock::forced(
Link::new("object-safety", "Object Safety"),
"object-safety-note",
));
}

blocks.push(LinkBlock::forced(Link::new("implementors", "Implementors"), "impl"));
if t.is_auto(cx.tcx()) {
blocks.push(LinkBlock::forced(
Expand Down
7 changes: 7 additions & 0 deletions tests/rustdoc/sidebar-items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// @has - '//*[@class="sidebar-elems"]//section//a' 'Output'
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-types"]' 'Provided Associated Types'
// @has - '//*[@class="sidebar-elems"]//section//a' 'Extra'
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' 'Object Safety'
pub trait Foo {
const FOO: usize;
const BAR: u32 = 0;
Expand All @@ -24,6 +25,12 @@ pub trait Foo {
fn bar() -> Self::Output;
}

// @has foo/trait.Safe.html
// @!has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' ''
pub trait Safe {
fn access(&self);
}

// @has foo/struct.Bar.html
// @has - '//div[@class="sidebar-elems"]//h3/a[@href="#fields"]' 'Fields'
// @has - '//*[@class="sidebar-elems"]//section//a[@href="#structfield.f"]' 'f'
Expand Down
27 changes: 27 additions & 0 deletions tests/rustdoc/trait-object-safe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#![crate_name = "foo"]

// @has 'foo/trait.Unsafe.html'
// @has - '//*[@class="object-safety-info"]' 'This trait is not object safe.'
// @has - '//*[@id="object-safety"]' 'Object Safety'
pub trait Unsafe {
fn foo() -> Self;
}

// @has 'foo/trait.Unsafe2.html'
// @has - '//*[@class="object-safety-info"]' 'This trait is not object safe.'
// @has - '//*[@id="object-safety"]' 'Object Safety'
pub trait Unsafe2<T> {
fn foo(i: T);
}

// @has 'foo/trait.Safe.html'
// @!has - '//*[@class="object-safety-info"]' ''
// @!has - '//*[@id="object-safety"]' ''
pub trait Safe {
fn foo(&self);
}

// @has 'foo/struct.Foo.html'
// @!has - '//*[@class="object-safety-info"]' ''
// @!has - '//*[@id="object-safety"]' ''
pub struct Foo;

0 comments on commit 51b275b

Please sign in to comment.