diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index ff996b2a9254e..8feef9c259c13 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -124,6 +124,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                     visibility: Inherited,
                     def_id: self.cx.next_def_id(param_env_def_id.krate),
                     stability: None,
+                    const_stability: None,
                     deprecation: None,
                     kind: ImplItem(Impl {
                         unsafety: hir::Unsafety::Normal,
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 5721927d0ec8d..33b5e84c5e074 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -113,6 +113,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                     visibility: Inherited,
                     def_id: self.cx.next_def_id(impl_def_id.krate),
                     stability: None,
+                    const_stability: None,
                     deprecation: None,
                     kind: ImplItem(Impl {
                         unsafety: hir::Unsafety::Normal,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 61121c776f491..f3067360f0680 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -483,6 +483,7 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>)
                         def_id: DefId::local(CRATE_DEF_INDEX),
                         visibility: clean::Public,
                         stability: None,
+                        const_stability: None,
                         deprecation: None,
                         kind: clean::ImportItem(clean::Import::new_simple(
                             item.ident.to_string(),
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 9e8ce45292417..a9e433bf45842 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2189,6 +2189,7 @@ fn clean_extern_crate(
         def_id: crate_def_id,
         visibility: krate.vis.clean(cx),
         stability: None,
+        const_stability: None,
         deprecation: None,
         kind: ExternCrateItem(name.clean(cx), path),
     }]
@@ -2259,6 +2260,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
                         def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
                         visibility: self.vis.clean(cx),
                         stability: None,
+                        const_stability: None,
                         deprecation: None,
                         kind: ImportItem(Import::new_simple(
                             self.name.clean(cx),
@@ -2279,6 +2281,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
             def_id: DefId::local(CRATE_DEF_INDEX),
             visibility: self.vis.clean(cx),
             stability: None,
+            const_stability: None,
             deprecation: None,
             kind: ImportItem(inner),
         }]
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 2283b71a94fef..38d25d8d98e85 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -12,7 +12,7 @@ use rustc_ast::attr;
 use rustc_ast::util::comments::beautify_doc_string;
 use rustc_ast::{self as ast, AttrStyle};
 use rustc_ast::{FloatTy, IntTy, UintTy};
-use rustc_attr::{Stability, StabilityLevel};
+use rustc_attr::{ConstStability, Stability, StabilityLevel};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_feature::UnstableFeatures;
 use rustc_hir as hir;
@@ -87,6 +87,7 @@ crate struct Item {
     crate def_id: DefId,
     crate stability: Option<Stability>,
     crate deprecation: Option<Deprecation>,
+    crate const_stability: Option<ConstStability>,
 }
 
 impl fmt::Debug for Item {
@@ -155,6 +156,7 @@ impl Item {
             visibility: cx.tcx.visibility(def_id).clean(cx),
             stability: cx.tcx.lookup_stability(def_id).cloned(),
             deprecation: cx.tcx.lookup_deprecation(def_id).clean(cx),
+            const_stability: cx.tcx.lookup_const_stability(def_id).cloned(),
         }
     }
 
@@ -262,6 +264,13 @@ impl Item {
         }
     }
 
+    crate fn const_stable_since(&self) -> Option<SymbolStr> {
+        match self.const_stability?.level {
+            StabilityLevel::Stable { since, .. } => Some(since.as_str()),
+            StabilityLevel::Unstable { .. } => None,
+        }
+    }
+
     crate fn is_non_exhaustive(&self) -> bool {
         self.attrs.other_attrs.iter().any(|a| a.has_name(sym::non_exhaustive))
     }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index bbd4be88e6a8b..de620a35c80d7 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1692,13 +1692,13 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer, cache: &Cache)
     debug_assert!(!item.is_stripped());
     // Write the breadcrumb trail header for the top
     write!(buf, "<h1 class=\"fqn\"><span class=\"out-of-band\">");
-    if let Some(version) = item.stable_since() {
-        write!(
-            buf,
-            "<span class=\"since\" title=\"Stable since Rust version {0}\">{0}</span>",
-            version
-        );
-    }
+    render_stability_since_raw(
+        buf,
+        item.stable_since().as_deref(),
+        item.const_stable_since().as_deref(),
+        None,
+        None,
+    );
     write!(
         buf,
         "<span id=\"render-detail\">\
@@ -2476,6 +2476,7 @@ fn render_implementor(
         AssocItemLink::Anchor(None),
         RenderMode::Normal,
         implementor.impl_item.stable_since().as_deref(),
+        implementor.impl_item.const_stable_since().as_deref(),
         false,
         Some(use_absolute),
         false,
@@ -2506,6 +2507,7 @@ fn render_impls(
                 assoc_link,
                 RenderMode::Normal,
                 containing_item.stable_since().as_deref(),
+                containing_item.const_stable_since().as_deref(),
                 true,
                 None,
                 false,
@@ -2756,6 +2758,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
                     assoc_link,
                     RenderMode::Normal,
                     implementor.impl_item.stable_since().as_deref(),
+                    implementor.impl_item.const_stable_since().as_deref(),
                     false,
                     None,
                     true,
@@ -2898,10 +2901,40 @@ fn assoc_type(
     }
 }
 
-fn render_stability_since_raw(w: &mut Buffer, ver: Option<&str>, containing_ver: Option<&str>) {
+fn render_stability_since_raw(
+    w: &mut Buffer,
+    ver: Option<&str>,
+    const_ver: Option<&str>,
+    containing_ver: Option<&str>,
+    containing_const_ver: Option<&str>,
+) {
+    let ver = ver.and_then(|inner| if !inner.is_empty() { Some(inner) } else { None });
+
+    let const_ver = const_ver.and_then(|inner| if !inner.is_empty() { Some(inner) } else { None });
+
     if let Some(v) = ver {
-        if containing_ver != ver && !v.is_empty() {
-            write!(w, "<span class=\"since\" title=\"Stable since Rust version {0}\">{0}</span>", v)
+        if let Some(cv) = const_ver {
+            if const_ver != containing_const_ver {
+                write!(
+                    w,
+                    "<span class=\"since\" title=\"Stable since Rust version {0}, const since {1}\">{0} (const: {1})</span>",
+                    v, cv
+                );
+            } else if ver != containing_ver {
+                write!(
+                    w,
+                    "<span class=\"since\" title=\"Stable since Rust version {0}\">{0}</span>",
+                    v
+                );
+            }
+        } else {
+            if ver != containing_ver {
+                write!(
+                    w,
+                    "<span class=\"since\" title=\"Stable since Rust version {0}\">{0}</span>",
+                    v
+                );
+            }
         }
     }
 }
@@ -2910,7 +2943,9 @@ fn render_stability_since(w: &mut Buffer, item: &clean::Item, containing_item: &
     render_stability_since_raw(
         w,
         item.stable_since().as_deref(),
+        item.const_stable_since().as_deref(),
         containing_item.stable_since().as_deref(),
+        containing_item.const_stable_since().as_deref(),
     )
 }
 
@@ -3462,6 +3497,7 @@ fn render_assoc_items(
                 AssocItemLink::Anchor(None),
                 render_mode,
                 containing_item.stable_since().as_deref(),
+                containing_item.const_stable_since().as_deref(),
                 true,
                 None,
                 false,
@@ -3654,6 +3690,7 @@ fn render_impl(
     link: AssocItemLink<'_>,
     render_mode: RenderMode,
     outer_version: Option<&str>,
+    outer_const_version: Option<&str>,
     show_def_docs: bool,
     use_absolute: Option<bool>,
     is_on_foreign_type: bool,
@@ -3705,11 +3742,13 @@ fn render_impl(
             );
         }
         write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
-        let since = i.impl_item.stability.as_ref().and_then(|s| match s.level {
-            StabilityLevel::Stable { since } => Some(since.as_str()),
-            StabilityLevel::Unstable { .. } => None,
-        });
-        render_stability_since_raw(w, since.as_deref(), outer_version);
+        render_stability_since_raw(
+            w,
+            i.impl_item.stable_since().as_deref(),
+            i.impl_item.const_stable_since().as_deref(),
+            outer_version,
+            outer_const_version,
+        );
         write_srclink(cx, &i.impl_item, w, cache);
         write!(w, "</h3>");
 
@@ -3746,6 +3785,7 @@ fn render_impl(
         render_mode: RenderMode,
         is_default_item: bool,
         outer_version: Option<&str>,
+        outer_const_version: Option<&str>,
         trait_: Option<&clean::Trait>,
         show_def_docs: bool,
         cache: &Cache,
@@ -3775,7 +3815,13 @@ fn render_impl(
                     write!(w, "<code>");
                     render_assoc_item(w, item, link.anchor(&id), ItemType::Impl);
                     write!(w, "</code>");
-                    render_stability_since_raw(w, item.stable_since().as_deref(), outer_version);
+                    render_stability_since_raw(
+                        w,
+                        item.stable_since().as_deref(),
+                        item.const_stable_since().as_deref(),
+                        outer_version,
+                        outer_const_version,
+                    );
                     write_srclink(cx, item, w, cache);
                     write!(w, "</h4>");
                 }
@@ -3791,7 +3837,13 @@ fn render_impl(
                 write!(w, "<h4 id=\"{}\" class=\"{}{}\"><code>", id, item_type, extra_class);
                 assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "");
                 write!(w, "</code>");
-                render_stability_since_raw(w, item.stable_since().as_deref(), outer_version);
+                render_stability_since_raw(
+                    w,
+                    item.stable_since().as_deref(),
+                    item.const_stable_since().as_deref(),
+                    outer_version,
+                    outer_const_version,
+                );
                 write_srclink(cx, item, w, cache);
                 write!(w, "</h4>");
             }
@@ -3854,6 +3906,7 @@ fn render_impl(
             render_mode,
             false,
             outer_version,
+            outer_const_version,
             trait_,
             show_def_docs,
             cache,
@@ -3868,6 +3921,7 @@ fn render_impl(
         parent: &clean::Item,
         render_mode: RenderMode,
         outer_version: Option<&str>,
+        outer_const_version: Option<&str>,
         show_def_docs: bool,
         cache: &Cache,
     ) {
@@ -3888,6 +3942,7 @@ fn render_impl(
                 render_mode,
                 true,
                 outer_version,
+                outer_const_version,
                 None,
                 show_def_docs,
                 cache,
@@ -3909,6 +3964,7 @@ fn render_impl(
                 &i.impl_item,
                 render_mode,
                 outer_version,
+                outer_const_version,
                 show_def_docs,
                 cache,
             );
diff --git a/src/test/rustdoc/const-display.rs b/src/test/rustdoc/const-display.rs
index b3fbe377f0b96..11ba68a388fba 100644
--- a/src/test/rustdoc/const-display.rs
+++ b/src/test/rustdoc/const-display.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-linelength
+
 #![crate_name = "foo"]
 
 #![unstable(feature = "humans",
@@ -17,6 +19,7 @@ pub const unsafe fn foo() -> u32 { 42 }
 pub const fn foo2() -> u32 { 42 }
 
 // @has 'foo/fn.bar2.html' '//pre' 'pub const fn bar2() -> u32'
+// @has - //span '1.0.0 (const: 1.0.0)'
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 pub const fn bar2() -> u32 { 42 }
@@ -26,6 +29,7 @@ pub const fn bar2() -> u32 { 42 }
 pub const unsafe fn foo2_gated() -> u32 { 42 }
 
 // @has 'foo/fn.bar2_gated.html' '//pre' 'pub const unsafe fn bar2_gated() -> u32'
+// @has - '//span[@class="since"]' '1.0.0 (const: 1.0.0)'
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
 pub const unsafe fn bar2_gated() -> u32 { 42 }
@@ -40,4 +44,10 @@ impl Foo {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature="foo", issue = "none")]
     pub const unsafe fn gated() -> u32 { 42 }
+
+    // @has 'foo/struct.Foo.html' '//h4[@id="method.stable_impl"]/code' 'pub const fn stable_impl() -> u32'
+    // @has - '//span[@class="since"]' '1.0.0 (const: 1.2.0)'
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_stable(feature = "rust1", since = "1.2.0")]
+    pub const fn stable_impl() -> u32 { 42 }
 }