Switch rustdoc from `clean::Stability` to `rustc_attr::Stability`
This gives greater type safety and is less work to maintain on the rustdoc end.
This commit is contained in:
parent
c38f001db5
commit
cc0d140bae
|
@ -9,6 +9,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::cmp;
|
||||
use std::num::NonZeroU32;
|
||||
use version_check::Version;
|
||||
|
||||
|
@ -154,7 +155,7 @@ pub struct ConstStability {
|
|||
}
|
||||
|
||||
/// The available stability levels.
|
||||
#[derive(Encodable, Decodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
|
||||
#[derive(HashStable_Generic)]
|
||||
pub enum StabilityLevel {
|
||||
// Reason for the current stability level and the relevant rust-lang issue
|
||||
|
@ -162,6 +163,19 @@ pub enum StabilityLevel {
|
|||
Stable { since: Symbol },
|
||||
}
|
||||
|
||||
impl cmp::PartialOrd for StabilityLevel {
|
||||
// This only take into account stability, not any fields.
|
||||
// Therefore it is only `PartialOrd` and not `Ord`.
|
||||
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
|
||||
match (self, other) {
|
||||
(Self::Unstable { .. }, Self::Unstable { .. }) => Some(cmp::Ordering::Equal),
|
||||
(Self::Stable { .. }, Self::Stable { .. }) => Some(cmp::Ordering::Equal),
|
||||
(Self::Unstable { .. }, Self::Stable { .. }) => Some(cmp::Ordering::Less),
|
||||
(Self::Stable { .. }, Self::Unstable { .. }) => Some(cmp::Ordering::Greater),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StabilityLevel {
|
||||
pub fn is_unstable(&self) -> bool {
|
||||
matches!(self, StabilityLevel::Unstable { .. })
|
||||
|
|
|
@ -19,7 +19,6 @@ use rustc_index::vec::{Idx, IndexVec};
|
|||
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::middle::resolve_lifetime as rl;
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::fold::TypeFolder;
|
||||
use rustc_middle::ty::subst::{InternalSubsts, Subst};
|
||||
use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
|
||||
|
@ -274,7 +273,7 @@ impl Clean<Item> for doctree::Module<'_> {
|
|||
attrs,
|
||||
source: span.clean(cx),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: cx.stability(self.id).clean(cx),
|
||||
stability: cx.stability(self.id),
|
||||
deprecation: cx.deprecation(self.id).clean(cx),
|
||||
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
|
||||
inner: ModuleItem(Module { is_crate: self.is_crate, items }),
|
||||
|
@ -2397,24 +2396,9 @@ impl Clean<Item> for doctree::ProcMacro<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clean<Stability> for attr::Stability {
|
||||
fn clean(&self, _: &DocContext<'_>) -> Stability {
|
||||
Stability {
|
||||
level: stability::StabilityLevel::from_attr_level(&self.level),
|
||||
feature: self.feature.to_string(),
|
||||
since: match self.level {
|
||||
attr::Stable { ref since } => since.to_string(),
|
||||
_ => String::new(),
|
||||
},
|
||||
unstable_reason: match self.level {
|
||||
attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()),
|
||||
_ => None,
|
||||
},
|
||||
issue: match self.level {
|
||||
attr::Unstable { issue, .. } => issue,
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
impl Clean<attr::Stability> for attr::Stability {
|
||||
fn clean(&self, _: &DocContext<'_>) -> attr::Stability {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ use std::fmt;
|
|||
use std::hash::{Hash, Hasher};
|
||||
use std::iter::FromIterator;
|
||||
use std::lazy::SyncOnceCell as OnceCell;
|
||||
use std::num::NonZeroU32;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use std::{slice, vec};
|
||||
|
@ -13,6 +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_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
|
@ -20,11 +20,10 @@ use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
|||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::Mutability;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::{AssocKind, TyCtxt};
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::source_map::DUMMY_SP;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol, SymbolStr};
|
||||
use rustc_span::{self, FileName};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
@ -197,7 +196,7 @@ impl Item {
|
|||
self.stability.as_ref().and_then(|ref s| {
|
||||
let mut classes = Vec::with_capacity(2);
|
||||
|
||||
if s.level == stability::Unstable {
|
||||
if s.level.is_unstable() {
|
||||
classes.push("unstable");
|
||||
}
|
||||
|
||||
|
@ -210,8 +209,11 @@ impl Item {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn stable_since(&self) -> Option<&str> {
|
||||
self.stability.as_ref().map(|s| &s.since[..])
|
||||
pub fn stable_since(&self) -> Option<SymbolStr> {
|
||||
match self.stability?.level {
|
||||
StabilityLevel::Stable { since, .. } => Some(since.as_str()),
|
||||
StabilityLevel::Unstable { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_non_exhaustive(&self) -> bool {
|
||||
|
@ -1719,15 +1721,6 @@ pub struct ProcMacro {
|
|||
pub helpers: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Stability {
|
||||
pub level: stability::StabilityLevel,
|
||||
pub feature: String,
|
||||
pub since: String,
|
||||
pub unstable_reason: Option<String>,
|
||||
pub issue: Option<NonZeroU32>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Deprecation {
|
||||
pub since: Option<String>,
|
||||
|
|
|
@ -3,12 +3,13 @@ use crate::clean::blanket_impl::BlanketImplFinder;
|
|||
use crate::clean::{
|
||||
inline, Clean, Crate, Deprecation, ExternalCrate, FnDecl, FnRetTy, Generic, GenericArg,
|
||||
GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemEnum, Lifetime,
|
||||
MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Stability, Type,
|
||||
TypeBinding, TypeKind, Visibility, WherePredicate,
|
||||
MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Type, TypeBinding,
|
||||
TypeKind, Visibility, WherePredicate,
|
||||
};
|
||||
use crate::core::DocContext;
|
||||
|
||||
use itertools::Itertools;
|
||||
use rustc_attr::Stability;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
|
|
|
@ -49,6 +49,7 @@ use std::sync::Arc;
|
|||
|
||||
use itertools::Itertools;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_attr::StabilityLevel;
|
||||
use rustc_data_structures::flock;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_feature::UnstableFeatures;
|
||||
|
@ -1984,8 +1985,10 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
|
|||
let s1 = i1.stability.as_ref().map(|s| s.level);
|
||||
let s2 = i2.stability.as_ref().map(|s| s.level);
|
||||
match (s1, s2) {
|
||||
(Some(stability::Unstable), Some(stability::Stable)) => return Ordering::Greater,
|
||||
(Some(stability::Stable), Some(stability::Unstable)) => return Ordering::Less,
|
||||
(Some(a), Some(b)) => match a.partial_cmp(&b) {
|
||||
Some(Ordering::Equal) | None => {}
|
||||
Some(other) => return other,
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
let lhs = i1.name.as_ref().map_or("", |s| &**s);
|
||||
|
@ -2150,10 +2153,7 @@ fn stability_tags(item: &clean::Item) -> String {
|
|||
|
||||
// The "rustc_private" crates are permanently unstable so it makes no sense
|
||||
// to render "unstable" everywhere.
|
||||
if item
|
||||
.stability
|
||||
.as_ref()
|
||||
.map(|s| s.level == stability::Unstable && s.feature != "rustc_private")
|
||||
if item.stability.as_ref().map(|s| s.level.is_unstable() && s.feature != sym::rustc_private)
|
||||
== Some(true)
|
||||
{
|
||||
tags += &tag_html("unstable", "", "Experimental");
|
||||
|
@ -2204,16 +2204,17 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
|
|||
|
||||
// Render unstable items. But don't render "rustc_private" crates (internal compiler crates).
|
||||
// Those crates are permanently unstable so it makes no sense to render "unstable" everywhere.
|
||||
if let Some(stab) = item
|
||||
if let Some((StabilityLevel::Unstable { reason, issue, .. }, feature)) = item
|
||||
.stability
|
||||
.as_ref()
|
||||
.filter(|stab| stab.level == stability::Unstable && stab.feature != "rustc_private")
|
||||
.filter(|stab| stab.feature != sym::rustc_private)
|
||||
.map(|stab| (stab.level, stab.feature))
|
||||
{
|
||||
let mut message =
|
||||
"<span class='emoji'>🔬</span> This is a nightly-only experimental API.".to_owned();
|
||||
|
||||
let mut feature = format!("<code>{}</code>", Escape(&stab.feature));
|
||||
if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) {
|
||||
let mut feature = format!("<code>{}</code>", Escape(&feature.as_str()));
|
||||
if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, issue) {
|
||||
feature.push_str(&format!(
|
||||
" <a href=\"{url}{issue}\">#{issue}</a>",
|
||||
url = url,
|
||||
|
@ -2223,13 +2224,13 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
|
|||
|
||||
message.push_str(&format!(" ({})", feature));
|
||||
|
||||
if let Some(unstable_reason) = &stab.unstable_reason {
|
||||
if let Some(unstable_reason) = reason {
|
||||
let mut ids = cx.id_map.borrow_mut();
|
||||
message = format!(
|
||||
"<details><summary>{}</summary>{}</details>",
|
||||
message,
|
||||
MarkdownHtml(
|
||||
&unstable_reason,
|
||||
&unstable_reason.as_str(),
|
||||
&mut ids,
|
||||
error_codes,
|
||||
cx.shared.edition,
|
||||
|
@ -2355,7 +2356,7 @@ fn render_implementor(
|
|||
implementor,
|
||||
AssocItemLink::Anchor(None),
|
||||
RenderMode::Normal,
|
||||
implementor.impl_item.stable_since(),
|
||||
implementor.impl_item.stable_since().as_deref(),
|
||||
false,
|
||||
Some(use_absolute),
|
||||
false,
|
||||
|
@ -2384,7 +2385,7 @@ fn render_impls(
|
|||
i,
|
||||
assoc_link,
|
||||
RenderMode::Normal,
|
||||
containing_item.stable_since(),
|
||||
containing_item.stable_since().as_deref(),
|
||||
true,
|
||||
None,
|
||||
false,
|
||||
|
@ -2629,7 +2630,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
|
|||
&implementor,
|
||||
assoc_link,
|
||||
RenderMode::Normal,
|
||||
implementor.impl_item.stable_since(),
|
||||
implementor.impl_item.stable_since().as_deref(),
|
||||
false,
|
||||
None,
|
||||
true,
|
||||
|
@ -2780,7 +2781,11 @@ fn render_stability_since_raw(w: &mut Buffer, ver: Option<&str>, containing_ver:
|
|||
}
|
||||
|
||||
fn render_stability_since(w: &mut Buffer, item: &clean::Item, containing_item: &clean::Item) {
|
||||
render_stability_since_raw(w, item.stable_since(), containing_item.stable_since())
|
||||
render_stability_since_raw(
|
||||
w,
|
||||
item.stable_since().as_deref(),
|
||||
containing_item.stable_since().as_deref(),
|
||||
)
|
||||
}
|
||||
|
||||
fn render_assoc_item(
|
||||
|
@ -3324,7 +3329,7 @@ fn render_assoc_items(
|
|||
i,
|
||||
AssocItemLink::Anchor(None),
|
||||
render_mode,
|
||||
containing_item.stable_since(),
|
||||
containing_item.stable_since().as_deref(),
|
||||
true,
|
||||
None,
|
||||
false,
|
||||
|
@ -3564,8 +3569,11 @@ fn render_impl(
|
|||
);
|
||||
}
|
||||
write!(w, "<a href='#{}' class='anchor'></a>", id);
|
||||
let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]);
|
||||
render_stability_since_raw(w, since, outer_version);
|
||||
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);
|
||||
if let Some(l) = cx.src_href(&i.impl_item, cache) {
|
||||
write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>", l, "goto source code");
|
||||
}
|
||||
|
@ -3626,7 +3634,7 @@ 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(), outer_version);
|
||||
render_stability_since_raw(w, item.stable_since().as_deref(), outer_version);
|
||||
if let Some(l) = cx.src_href(item, cache) {
|
||||
write!(
|
||||
w,
|
||||
|
@ -3648,7 +3656,7 @@ 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(), outer_version);
|
||||
render_stability_since_raw(w, item.stable_since().as_deref(), outer_version);
|
||||
if let Some(l) = cx.src_href(item, cache) {
|
||||
write!(
|
||||
w,
|
||||
|
|
Loading…
Reference in New Issue