about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_attr/src/builtin.rs7
-rw-r--r--src/librustdoc/clean/types.rs6
-rw-r--r--src/librustdoc/html/render/mod.rs31
-rw-r--r--tests/rustdoc/html-no-source.rs12
-rw-r--r--tests/rustdoc/source-version-separator.rs10
-rw-r--r--tests/rustdoc/version-separator-without-source.rs12
6 files changed, 49 insertions, 29 deletions
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 7081e285d68..a31b683b1af 100644
--- a/compiler/rustc_attr/src/builtin.rs
+++ b/compiler/rustc_attr/src/builtin.rs
@@ -13,6 +13,7 @@ use rustc_session::parse::{feature_err, ParseSess};
 use rustc_session::Session;
 use rustc_span::hygiene::Transparency;
 use rustc_span::{symbol::sym, symbol::Symbol, Span};
+use std::fmt::{self, Display};
 use std::num::NonZeroU32;
 
 use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
@@ -590,6 +591,12 @@ fn parse_version(s: &str, allow_appendix: bool) -> Option<Version> {
     Some(Version { major, minor, patch })
 }
 
+impl Display for Version {
+    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)
+    }
+}
+
 /// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
 /// evaluate individual items.
 pub fn eval_condition(
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 6a7410144fd..449aac4cfc8 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -12,7 +12,7 @@ use thin_vec::ThinVec;
 
 use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
-use rustc_attr::{ConstStability, Deprecation, Stability, StabilityLevel};
+use rustc_attr::{ConstStability, Deprecation, Since, Stability, StabilityLevel};
 use rustc_const_eval::const_eval::is_unstable_const_fn;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
@@ -585,14 +585,14 @@ impl Item {
         })
     }
 
-    pub(crate) fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
+    pub(crate) fn stable_since(&self, tcx: TyCtxt<'_>) -> Option<Since> {
         match self.stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since),
             StabilityLevel::Unstable { .. } => None,
         }
     }
 
-    pub(crate) fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<Symbol> {
+    pub(crate) fn const_stable_since(&self, tcx: TyCtxt<'_>) -> Option<Since> {
         match self.const_stability(tcx)?.level {
             StabilityLevel::Stable { since, .. } => Some(since),
             StabilityLevel::Unstable { .. } => None,
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 89e29d8b59b..1aad014c571 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -48,7 +48,7 @@ use std::str;
 use std::string::ToString;
 
 use askama::Template;
-use rustc_attr::{ConstStability, Deprecation, StabilityLevel};
+use rustc_attr::{rust_version_symbol, ConstStability, Deprecation, Since, StabilityLevel};
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::{DefId, DefIdSet};
@@ -911,13 +911,17 @@ fn assoc_method(
 /// consequence of the above rules.
 fn render_stability_since_raw_with_extra(
     w: &mut Buffer,
-    ver: Option<Symbol>,
+    ver: Option<Since>,
     const_stability: Option<ConstStability>,
-    containing_ver: Option<Symbol>,
-    containing_const_ver: Option<Symbol>,
+    containing_ver: Option<Since>,
+    containing_const_ver: Option<Since>,
     extra_class: &str,
 ) -> bool {
-    let stable_version = ver.filter(|inner| !inner.is_empty() && Some(*inner) != containing_ver);
+    let stable_version = if ver != containing_ver && let Some(ver) = &ver {
+        since_to_string(ver)
+    } else {
+        None
+    };
 
     let mut title = String::new();
     let mut stability = String::new();
@@ -931,7 +935,8 @@ fn render_stability_since_raw_with_extra(
         Some(ConstStability { level: StabilityLevel::Stable { since, .. }, .. })
             if Some(since) != containing_const_ver =>
         {
-            Some((format!("const since {since}"), format!("const: {since}")))
+            since_to_string(&since)
+                .map(|since| (format!("const since {since}"), format!("const: {since}")))
         }
         Some(ConstStability { level: StabilityLevel::Unstable { issue, .. }, feature, .. }) => {
             let unstable = if let Some(n) = issue {
@@ -971,13 +976,21 @@ fn render_stability_since_raw_with_extra(
     !stability.is_empty()
 }
 
+fn since_to_string(since: &Since) -> Option<String> {
+    match since {
+        Since::Version(since) => Some(since.to_string()),
+        Since::Current => Some(rust_version_symbol().to_string()),
+        Since::Err => None,
+    }
+}
+
 #[inline]
 fn render_stability_since_raw(
     w: &mut Buffer,
-    ver: Option<Symbol>,
+    ver: Option<Since>,
     const_stability: Option<ConstStability>,
-    containing_ver: Option<Symbol>,
-    containing_const_ver: Option<Symbol>,
+    containing_ver: Option<Since>,
+    containing_const_ver: Option<Since>,
 ) -> bool {
     render_stability_since_raw_with_extra(
         w,
diff --git a/tests/rustdoc/html-no-source.rs b/tests/rustdoc/html-no-source.rs
index 25615a73c3f..b91aa41207a 100644
--- a/tests/rustdoc/html-no-source.rs
+++ b/tests/rustdoc/html-no-source.rs
@@ -11,20 +11,20 @@
 // @files 'src/foo' '[]'
 
 // @has foo/fn.foo.html
-// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · '
-// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · '
+// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · source · '
 #[stable(feature = "bar", since = "1.0")]
 pub fn foo() {}
 
 // @has foo/struct.Bar.html
-// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · '
-// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · '
+// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · source · '
 #[stable(feature = "bar", since = "1.0")]
 pub struct Bar;
 
 impl Bar {
-    // @has - '//*[@id="method.bar"]/*[@class="since rightside"]' '2.0'
-    // @!has - '//*[@id="method.bar"]/*[@class="rightside"]' '2.0 ·'
+    // @has - '//*[@id="method.bar"]/*[@class="since rightside"]' '2.0.0'
+    // @!has - '//*[@id="method.bar"]/*[@class="rightside"]' '2.0.0 ·'
     #[stable(feature = "foobar", since = "2.0")]
     pub fn bar() {}
 }
diff --git a/tests/rustdoc/source-version-separator.rs b/tests/rustdoc/source-version-separator.rs
index 14580373b3b..7256f731573 100644
--- a/tests/rustdoc/source-version-separator.rs
+++ b/tests/rustdoc/source-version-separator.rs
@@ -3,23 +3,23 @@
 #![feature(staged_api)]
 
 // @has foo/trait.Bar.html
-// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · source · '
 #[stable(feature = "bar", since = "1.0")]
 pub trait Bar {
-    // @has - '//*[@id="tymethod.foo"]/*[@class="rightside"]' '3.0 · source'
+    // @has - '//*[@id="tymethod.foo"]/*[@class="rightside"]' '3.0.0 · source'
     #[stable(feature = "foobar", since = "3.0")]
     fn foo();
 }
 
-// @has - '//div[@id="implementors-list"]//*[@class="rightside"]' '4.0 · source'
+// @has - '//div[@id="implementors-list"]//*[@class="rightside"]' '4.0.0 · source'
 
 // @has foo/struct.Foo.html
-// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · source · '
 #[stable(feature = "baz", since = "1.0")]
 pub struct Foo;
 
 impl Foo {
-    // @has - '//*[@id="method.foofoo"]/*[@class="rightside"]' '3.0 · source'
+    // @has - '//*[@id="method.foofoo"]/*[@class="rightside"]' '3.0.0 · source'
     #[stable(feature = "foobar", since = "3.0")]
     pub fn foofoo() {}
 }
diff --git a/tests/rustdoc/version-separator-without-source.rs b/tests/rustdoc/version-separator-without-source.rs
index 04ea46a7f3a..4a855b7bb29 100644
--- a/tests/rustdoc/version-separator-without-source.rs
+++ b/tests/rustdoc/version-separator-without-source.rs
@@ -4,20 +4,20 @@
 #![crate_name = "foo"]
 
 // @has foo/fn.foo.html
-// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · '
-// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · '
+// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · source · '
 #[stable(feature = "bar", since = "1.0")]
 pub fn foo() {}
 
 // @has foo/struct.Bar.html
-// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · '
-// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0 · source · '
+// @has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · '
+// @!has - '//div[@class="main-heading"]/*[@class="out-of-band"]' '1.0.0 · source · '
 #[stable(feature = "bar", since = "1.0")]
 pub struct Bar;
 
 impl Bar {
-    // @has - '//*[@id="method.bar"]/*[@class="since rightside"]' '2.0'
-    // @!has - '//*[@id="method.bar"]/*[@class="rightside"]' '2.0 ·'
+    // @has - '//*[@id="method.bar"]/*[@class="since rightside"]' '2.0.0'
+    // @!has - '//*[@id="method.bar"]/*[@class="rightside"]' '2.0.0 ·'
     #[stable(feature = "foobar", since = "2.0")]
     pub fn bar() {}
 }