From 51e22be682e4ed5864e36400cbbc10836ee52c7e Mon Sep 17 00:00:00 2001 From: "Alexis (Poliorcetics) Bourget" Date: Sat, 1 Jul 2023 19:13:00 +0200 Subject: [PATCH 1/3] feat: render Object Safety informations non-object safe traits --- src/librustdoc/clean/types.rs | 3 +++ src/librustdoc/html/render/print_item.rs | 14 ++++++++++++++ src/librustdoc/html/render/sidebar.rs | 8 ++++++++ 3 files changed, 25 insertions(+) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 455228d04efa7..b773977eb9ca9 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -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)] diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index fdf4556906172..4d518a3e20b9c 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -959,6 +959,20 @@ 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!("
This trait is not \ + \ + object safe.
", + 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. diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 4e8d88c55b64f..ba4aaaff5a749 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -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( From 40556b968ca044108d5f28d7a8810821c8be7d9d Mon Sep 17 00:00:00 2001 From: "Alexis (Poliorcetics) Bourget" Date: Sat, 8 Jul 2023 17:29:05 +0200 Subject: [PATCH 2/3] feat: Add 'object-safety' ID to init_id_map() in rustdoc --- src/librustdoc/html/markdown.rs | 1 + src/librustdoc/html/render/print_item.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index d24e6e5faf521..aa728c26afcf0 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -2024,6 +2024,7 @@ fn init_id_map() -> FxHashMap, 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); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 4d518a3e20b9c..c852f01f450a0 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -965,7 +965,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: w, "object-safety", "Object Safety", - &format!("
This trait is not \ + &format!( + "
This trait is not \ \ object safe.
", base = crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL From a119158eb39a5e251d0d309a261c11743b996ce0 Mon Sep 17 00:00:00 2001 From: "Alexis (Poliorcetics) Bourget" Date: Sat, 1 Jul 2023 19:13:26 +0200 Subject: [PATCH 3/3] tests: object-safety section in traits --- tests/rustdoc/sidebar-items.rs | 7 +++++++ tests/rustdoc/trait-object-safe.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 tests/rustdoc/trait-object-safe.rs diff --git a/tests/rustdoc/sidebar-items.rs b/tests/rustdoc/sidebar-items.rs index 6f7afa59bddc7..b746f6982644a 100644 --- a/tests/rustdoc/sidebar-items.rs +++ b/tests/rustdoc/sidebar-items.rs @@ -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; @@ -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' diff --git a/tests/rustdoc/trait-object-safe.rs b/tests/rustdoc/trait-object-safe.rs new file mode 100644 index 0000000000000..818843f75583f --- /dev/null +++ b/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 { + 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;