From cc0d140baecbe6b38496f1d869de0698e639c7df Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 11 Oct 2020 09:55:17 -0400 Subject: [PATCH] Switch rustdoc from `clean::Stability` to `rustc_attr::Stability` This gives greater type safety and is less work to maintain on the rustdoc end. --- compiler/rustc_attr/src/builtin.rs | 16 +++++++++- src/librustdoc/clean/mod.rs | 24 +++----------- src/librustdoc/clean/types.rs | 23 +++++--------- src/librustdoc/clean/utils.rs | 5 +-- src/librustdoc/html/render/mod.rs | 50 +++++++++++++++++------------- 5 files changed, 59 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 325af56f3cd..5268d3f0ab0 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -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 { + 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 { .. }) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 501891da573..bb1ee7f2615 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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 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 for doctree::ProcMacro<'_> { } } -impl Clean 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 for attr::Stability { + fn clean(&self, _: &DocContext<'_>) -> attr::Stability { + self.clone() } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 1e07f8e2eac..f347ba10e18 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -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 { + 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, } -#[derive(Clone, Debug)] -pub struct Stability { - pub level: stability::StabilityLevel, - pub feature: String, - pub since: String, - pub unstable_reason: Option, - pub issue: Option, -} - #[derive(Clone, Debug)] pub struct Deprecation { pub since: Option, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 913342e2715..25ba6e49bd5 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -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}; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 76334f0213d..36db5557b52 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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 { // 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 = "🔬 This is a nightly-only experimental API.".to_owned(); - let mut feature = format!("{}", Escape(&stab.feature)); - if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) { + let mut feature = format!("{}", Escape(&feature.as_str())); + if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, issue) { feature.push_str(&format!( " #{issue}", url = url, @@ -2223,13 +2224,13 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec { 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!( "
{}{}
", 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, "", 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, "[src]", l, "goto source code"); } @@ -3626,7 +3634,7 @@ fn render_impl( write!(w, ""); render_assoc_item(w, item, link.anchor(&id), ItemType::Impl); write!(w, ""); - 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, "

", id, item_type, extra_class); assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), ""); write!(w, ""); - 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,