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:
Joshua Nelson 2020-10-11 09:55:17 -04:00
parent c38f001db5
commit cc0d140bae
5 changed files with 59 additions and 59 deletions

View File

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

View File

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

View File

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

View File

@ -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};

View File

@ -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!(
"&nbsp;<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,