Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustdoc: Document lack of object safety on affected traits #113241

Merged
merged 3 commits into from Nov 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/librustdoc/clean/types.rs
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
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
Expand Up @@ -959,6 +959,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()) {
poliorcetics marked this conversation as resolved.
Show resolved Hide resolved
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
),
poliorcetics marked this conversation as resolved.
Show resolved Hide resolved
);
}

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
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()) {
GuillaumeGomez marked this conversation as resolved.
Show resolved Hide resolved
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
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
@@ -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;