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/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<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);
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index fdf4556906172..c852f01f450a0 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -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()) {
+        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.
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(
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<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;