Handle structured stable attribute 'since' version in rustdoc
This commit is contained in:
parent
7b0e315ae6
commit
6933a671d3
@ -13,6 +13,7 @@
|
||||
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(
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
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 @@ pub(crate) fn stability_class(&self, tcx: TyCtxt<'_>) -> Option<String> {
|
||||
})
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -48,7 +48,7 @@
|
||||
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,
|
||||
|
@ -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() {}
|
||||
}
|
||||
|
@ -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() {}
|
||||
}
|
||||
|
@ -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() {}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user