Skip to content

Commit dc1c39b

Browse files
committed
rustdoc: decouple stability and const-stability
1 parent 256721e commit dc1c39b

File tree

3 files changed

+73
-37
lines changed

3 files changed

+73
-37
lines changed

src/librustdoc/html/render/mod.rs

+55-36
Original file line numberDiff line numberDiff line change
@@ -792,58 +792,77 @@ fn assoc_type(
792792
}
793793
}
794794

795+
/// Writes a span containing the versions at which an item became stable and/or const-stable. For
796+
/// example, if the item became stable at 1.0.0, and const-stable at 1.45.0, this function would
797+
/// write a span containing "1.0.0 (const: 1.45.0)".
798+
///
799+
/// Returns `true` if a stability annotation was rendered.
800+
///
801+
/// Stability and const-stability are considered separately. If the item is unstable, no version
802+
/// will be written. If the item is const-unstable, "const: unstable" will be appended to the
803+
/// span, with a link to the tracking issue if present. If an item's stability or const-stability
804+
/// version matches the version of its enclosing item, that version will be omitted.
805+
///
806+
/// Note that it is possible for an unstable function to be const-stable. In that case, the span
807+
/// will include the const-stable version, but no stable version will be emitted, as a natural
808+
/// consequence of the above rules.
795809
fn render_stability_since_raw(
796810
w: &mut Buffer,
797811
ver: Option<Symbol>,
798812
const_stability: Option<ConstStability>,
799813
containing_ver: Option<Symbol>,
800814
containing_const_ver: Option<Symbol>,
801815
) -> bool {
802-
let ver = ver.filter(|inner| !inner.is_empty());
816+
let stable_version = ver.filter(|inner| !inner.is_empty() && Some(*inner) != containing_ver);
803817

804-
match (ver, const_stability) {
805-
// stable and const stable
806-
(Some(v), Some(ConstStability { level: StabilityLevel::Stable { since }, .. }))
818+
let mut title = String::new();
819+
let mut stability = String::new();
820+
821+
if let Some(ver) = stable_version {
822+
stability.push_str(&ver.as_str());
823+
title.push_str(&format!("Stable since Rust version {}", ver));
824+
}
825+
826+
let const_title_and_stability = match const_stability {
827+
Some(ConstStability { level: StabilityLevel::Stable { since }, .. })
807828
if Some(since) != containing_const_ver =>
808829
{
809-
write!(
810-
w,
811-
"<span class=\"since\" title=\"Stable since Rust version {0}, const since {1}\">{0} (const: {1})</span>",
812-
v, since
813-
);
830+
Some((format!("const since {}", since), format!("const: {}", since)))
814831
}
815-
// stable and const unstable
816-
(
817-
Some(v),
818-
Some(ConstStability { level: StabilityLevel::Unstable { issue, .. }, feature, .. }),
819-
) => {
820-
write!(
821-
w,
822-
"<span class=\"since\" title=\"Stable since Rust version {0}, const unstable\">{0} (const: ",
823-
v
824-
);
825-
if let Some(n) = issue {
826-
write!(
827-
w,
828-
"<a href=\"https://github.com/rust-lang/rust/issues/{}\" title=\"Tracking issue for {}\">unstable</a>",
832+
Some(ConstStability { level: StabilityLevel::Unstable { issue, .. }, feature, .. }) => {
833+
let unstable = if let Some(n) = issue {
834+
format!(
835+
r#"<a href="https://github.com/rust-lang/rust/issues/{}" title="Tracking issue for {}">unstable</a>"#,
829836
n, feature
830-
);
837+
)
831838
} else {
832-
write!(w, "unstable");
833-
}
834-
write!(w, ")</span>");
839+
String::from("unstable")
840+
};
841+
842+
Some((String::from("const unstable"), format!("const: {}", unstable)))
835843
}
836-
// stable
837-
(Some(v), _) if ver != containing_ver => {
838-
write!(
839-
w,
840-
"<span class=\"since\" title=\"Stable since Rust version {0}\">{0}</span>",
841-
v
842-
);
844+
_ => None,
845+
};
846+
847+
if let Some((const_title, const_stability)) = const_title_and_stability {
848+
if !title.is_empty() {
849+
title.push_str(&format!(", {}", const_title));
850+
} else {
851+
title.push_str(&const_title);
852+
}
853+
854+
if !stability.is_empty() {
855+
stability.push_str(&format!(" ({})", const_stability));
856+
} else {
857+
stability.push_str(&const_stability);
843858
}
844-
_ => return false,
845859
}
846-
true
860+
861+
if !stability.is_empty() {
862+
write!(w, r#"<span class="since" title="{}">{}</span>"#, title, stability);
863+
}
864+
865+
!stability.is_empty()
847866
}
848867

849868
fn render_assoc_item(

src/test/rustdoc/const-display.rs

+17
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,20 @@ impl Foo {
6767
#[rustc_const_stable(feature = "rust1", since = "1.2.0")]
6868
pub const fn stable_impl() -> u32 { 42 }
6969
}
70+
71+
#[stable(feature = "rust1", since = "1.0.0")]
72+
pub struct Bar;
73+
74+
impl Bar {
75+
// Do not show non-const stabilities that are the same as the enclosing item.
76+
// @matches 'foo/struct.Bar.html' '//span[@class="since"]' '^const: 1.2.0$'
77+
#[stable(feature = "rust1", since = "1.0.0")]
78+
#[rustc_const_stable(feature = "rust1", since = "1.2.0")]
79+
pub const fn stable_impl() -> u32 { 42 }
80+
81+
// Show const-stability even for unstable functions.
82+
// @matches 'foo/struct.Bar.html' '//span[@class="since"]' '^const: 1.3.0$'
83+
#[unstable(feature = "foo2", issue = "none")]
84+
#[rustc_const_stable(feature = "rust1", since = "1.3.0")]
85+
pub const fn const_stable_unstable() -> u32 { 42 }
86+
}

src/test/rustdoc/deref-const-fn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub struct Bar;
1313

1414
impl Bar {
1515
// @has - '//*[@id="method.len"]' 'pub const fn len(&self) -> usize'
16-
// @has - '//*[@id="method.len"]//span[@class="since"]' '1.0.0 (const: 1.0.0)'
16+
// @has - '//*[@id="method.len"]//span[@class="since"]' 'const: 1.0.0'
1717
#[stable(feature = "rust1", since = "1.0.0")]
1818
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
1919
pub const fn len(&self) -> usize { 0 }

0 commit comments

Comments
 (0)