Handle structured stable attribute 'since' version in rustdoc

This commit is contained in:
David Tolnay 2023-10-24 16:35:43 -07:00
parent 7b0e315ae6
commit 6933a671d3
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
6 changed files with 49 additions and 29 deletions

View File

@ -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(

View File

@ -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,

View File

@ -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,

View File

@ -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() {}
}

View File

@ -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() {}
}

View File

@ -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() {}
}