Skip to content

Commit cc0d140

Browse files
committed
Switch rustdoc from clean::Stability to rustc_attr::Stability
This gives greater type safety and is less work to maintain on the rustdoc end.
1 parent c38f001 commit cc0d140

File tree

5 files changed

+59
-59
lines changed

5 files changed

+59
-59
lines changed

compiler/rustc_attr/src/builtin.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_session::parse::{feature_err, ParseSess};
99
use rustc_session::Session;
1010
use rustc_span::hygiene::Transparency;
1111
use rustc_span::{symbol::sym, symbol::Symbol, Span};
12+
use std::cmp;
1213
use std::num::NonZeroU32;
1314
use version_check::Version;
1415

@@ -154,14 +155,27 @@ pub struct ConstStability {
154155
}
155156

156157
/// The available stability levels.
157-
#[derive(Encodable, Decodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
158+
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
158159
#[derive(HashStable_Generic)]
159160
pub enum StabilityLevel {
160161
// Reason for the current stability level and the relevant rust-lang issue
161162
Unstable { reason: Option<Symbol>, issue: Option<NonZeroU32>, is_soft: bool },
162163
Stable { since: Symbol },
163164
}
164165

166+
impl cmp::PartialOrd for StabilityLevel {
167+
// This only take into account stability, not any fields.
168+
// Therefore it is only `PartialOrd` and not `Ord`.
169+
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
170+
match (self, other) {
171+
(Self::Unstable { .. }, Self::Unstable { .. }) => Some(cmp::Ordering::Equal),
172+
(Self::Stable { .. }, Self::Stable { .. }) => Some(cmp::Ordering::Equal),
173+
(Self::Unstable { .. }, Self::Stable { .. }) => Some(cmp::Ordering::Less),
174+
(Self::Stable { .. }, Self::Unstable { .. }) => Some(cmp::Ordering::Greater),
175+
}
176+
}
177+
}
178+
165179
impl StabilityLevel {
166180
pub fn is_unstable(&self) -> bool {
167181
matches!(self, StabilityLevel::Unstable { .. })

src/librustdoc/clean/mod.rs

+4-20
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use rustc_index::vec::{Idx, IndexVec};
1919
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
2020
use rustc_middle::bug;
2121
use rustc_middle::middle::resolve_lifetime as rl;
22-
use rustc_middle::middle::stability;
2322
use rustc_middle::ty::fold::TypeFolder;
2423
use rustc_middle::ty::subst::{InternalSubsts, Subst};
2524
use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
@@ -274,7 +273,7 @@ impl Clean<Item> for doctree::Module<'_> {
274273
attrs,
275274
source: span.clean(cx),
276275
visibility: self.vis.clean(cx),
277-
stability: cx.stability(self.id).clean(cx),
276+
stability: cx.stability(self.id),
278277
deprecation: cx.deprecation(self.id).clean(cx),
279278
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
280279
inner: ModuleItem(Module { is_crate: self.is_crate, items }),
@@ -2397,24 +2396,9 @@ impl Clean<Item> for doctree::ProcMacro<'_> {
23972396
}
23982397
}
23992398

2400-
impl Clean<Stability> for attr::Stability {
2401-
fn clean(&self, _: &DocContext<'_>) -> Stability {
2402-
Stability {
2403-
level: stability::StabilityLevel::from_attr_level(&self.level),
2404-
feature: self.feature.to_string(),
2405-
since: match self.level {
2406-
attr::Stable { ref since } => since.to_string(),
2407-
_ => String::new(),
2408-
},
2409-
unstable_reason: match self.level {
2410-
attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()),
2411-
_ => None,
2412-
},
2413-
issue: match self.level {
2414-
attr::Unstable { issue, .. } => issue,
2415-
_ => None,
2416-
},
2417-
}
2399+
impl Clean<attr::Stability> for attr::Stability {
2400+
fn clean(&self, _: &DocContext<'_>) -> attr::Stability {
2401+
self.clone()
24182402
}
24192403
}
24202404

src/librustdoc/clean/types.rs

+8-15
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use std::fmt;
44
use std::hash::{Hash, Hasher};
55
use std::iter::FromIterator;
66
use std::lazy::SyncOnceCell as OnceCell;
7-
use std::num::NonZeroU32;
87
use std::rc::Rc;
98
use std::sync::Arc;
109
use std::{slice, vec};
@@ -13,18 +12,18 @@ use rustc_ast::attr;
1312
use rustc_ast::util::comments::beautify_doc_string;
1413
use rustc_ast::{self as ast, AttrStyle};
1514
use rustc_ast::{FloatTy, IntTy, UintTy};
15+
use rustc_attr::{Stability, StabilityLevel};
1616
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1717
use rustc_hir as hir;
1818
use rustc_hir::def::Res;
1919
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
2020
use rustc_hir::lang_items::LangItem;
2121
use rustc_hir::Mutability;
2222
use rustc_index::vec::IndexVec;
23-
use rustc_middle::middle::stability;
2423
use rustc_middle::ty::{AssocKind, TyCtxt};
2524
use rustc_span::hygiene::MacroKind;
2625
use rustc_span::source_map::DUMMY_SP;
27-
use rustc_span::symbol::{kw, sym, Ident, Symbol};
26+
use rustc_span::symbol::{kw, sym, Ident, Symbol, SymbolStr};
2827
use rustc_span::{self, FileName};
2928
use rustc_target::abi::VariantIdx;
3029
use rustc_target::spec::abi::Abi;
@@ -197,7 +196,7 @@ impl Item {
197196
self.stability.as_ref().and_then(|ref s| {
198197
let mut classes = Vec::with_capacity(2);
199198

200-
if s.level == stability::Unstable {
199+
if s.level.is_unstable() {
201200
classes.push("unstable");
202201
}
203202

@@ -210,8 +209,11 @@ impl Item {
210209
})
211210
}
212211

213-
pub fn stable_since(&self) -> Option<&str> {
214-
self.stability.as_ref().map(|s| &s.since[..])
212+
pub fn stable_since(&self) -> Option<SymbolStr> {
213+
match self.stability?.level {
214+
StabilityLevel::Stable { since, .. } => Some(since.as_str()),
215+
StabilityLevel::Unstable { .. } => None,
216+
}
215217
}
216218

217219
pub fn is_non_exhaustive(&self) -> bool {
@@ -1719,15 +1721,6 @@ pub struct ProcMacro {
17191721
pub helpers: Vec<String>,
17201722
}
17211723

1722-
#[derive(Clone, Debug)]
1723-
pub struct Stability {
1724-
pub level: stability::StabilityLevel,
1725-
pub feature: String,
1726-
pub since: String,
1727-
pub unstable_reason: Option<String>,
1728-
pub issue: Option<NonZeroU32>,
1729-
}
1730-
17311724
#[derive(Clone, Debug)]
17321725
pub struct Deprecation {
17331726
pub since: Option<String>,

src/librustdoc/clean/utils.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ use crate::clean::blanket_impl::BlanketImplFinder;
33
use crate::clean::{
44
inline, Clean, Crate, Deprecation, ExternalCrate, FnDecl, FnRetTy, Generic, GenericArg,
55
GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemEnum, Lifetime,
6-
MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Stability, Type,
7-
TypeBinding, TypeKind, Visibility, WherePredicate,
6+
MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Type, TypeBinding,
7+
TypeKind, Visibility, WherePredicate,
88
};
99
use crate::core::DocContext;
1010

1111
use itertools::Itertools;
12+
use rustc_attr::Stability;
1213
use rustc_data_structures::fx::FxHashSet;
1314
use rustc_hir as hir;
1415
use rustc_hir::def::{DefKind, Res};

src/librustdoc/html/render/mod.rs

+29-21
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use std::sync::Arc;
4949

5050
use itertools::Itertools;
5151
use rustc_ast_pretty::pprust;
52+
use rustc_attr::StabilityLevel;
5253
use rustc_data_structures::flock;
5354
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5455
use rustc_feature::UnstableFeatures;
@@ -1984,8 +1985,10 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
19841985
let s1 = i1.stability.as_ref().map(|s| s.level);
19851986
let s2 = i2.stability.as_ref().map(|s| s.level);
19861987
match (s1, s2) {
1987-
(Some(stability::Unstable), Some(stability::Stable)) => return Ordering::Greater,
1988-
(Some(stability::Stable), Some(stability::Unstable)) => return Ordering::Less,
1988+
(Some(a), Some(b)) => match a.partial_cmp(&b) {
1989+
Some(Ordering::Equal) | None => {}
1990+
Some(other) => return other,
1991+
},
19891992
_ => {}
19901993
}
19911994
let lhs = i1.name.as_ref().map_or("", |s| &**s);
@@ -2150,10 +2153,7 @@ fn stability_tags(item: &clean::Item) -> String {
21502153

21512154
// The "rustc_private" crates are permanently unstable so it makes no sense
21522155
// to render "unstable" everywhere.
2153-
if item
2154-
.stability
2155-
.as_ref()
2156-
.map(|s| s.level == stability::Unstable && s.feature != "rustc_private")
2156+
if item.stability.as_ref().map(|s| s.level.is_unstable() && s.feature != sym::rustc_private)
21572157
== Some(true)
21582158
{
21592159
tags += &tag_html("unstable", "", "Experimental");
@@ -2204,16 +2204,17 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
22042204

22052205
// Render unstable items. But don't render "rustc_private" crates (internal compiler crates).
22062206
// Those crates are permanently unstable so it makes no sense to render "unstable" everywhere.
2207-
if let Some(stab) = item
2207+
if let Some((StabilityLevel::Unstable { reason, issue, .. }, feature)) = item
22082208
.stability
22092209
.as_ref()
2210-
.filter(|stab| stab.level == stability::Unstable && stab.feature != "rustc_private")
2210+
.filter(|stab| stab.feature != sym::rustc_private)
2211+
.map(|stab| (stab.level, stab.feature))
22112212
{
22122213
let mut message =
22132214
"<span class='emoji'>🔬</span> This is a nightly-only experimental API.".to_owned();
22142215

2215-
let mut feature = format!("<code>{}</code>", Escape(&stab.feature));
2216-
if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) {
2216+
let mut feature = format!("<code>{}</code>", Escape(&feature.as_str()));
2217+
if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, issue) {
22172218
feature.push_str(&format!(
22182219
"&nbsp;<a href=\"{url}{issue}\">#{issue}</a>",
22192220
url = url,
@@ -2223,13 +2224,13 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
22232224

22242225
message.push_str(&format!(" ({})", feature));
22252226

2226-
if let Some(unstable_reason) = &stab.unstable_reason {
2227+
if let Some(unstable_reason) = reason {
22272228
let mut ids = cx.id_map.borrow_mut();
22282229
message = format!(
22292230
"<details><summary>{}</summary>{}</details>",
22302231
message,
22312232
MarkdownHtml(
2232-
&unstable_reason,
2233+
&unstable_reason.as_str(),
22332234
&mut ids,
22342235
error_codes,
22352236
cx.shared.edition,
@@ -2355,7 +2356,7 @@ fn render_implementor(
23552356
implementor,
23562357
AssocItemLink::Anchor(None),
23572358
RenderMode::Normal,
2358-
implementor.impl_item.stable_since(),
2359+
implementor.impl_item.stable_since().as_deref(),
23592360
false,
23602361
Some(use_absolute),
23612362
false,
@@ -2384,7 +2385,7 @@ fn render_impls(
23842385
i,
23852386
assoc_link,
23862387
RenderMode::Normal,
2387-
containing_item.stable_since(),
2388+
containing_item.stable_since().as_deref(),
23882389
true,
23892390
None,
23902391
false,
@@ -2629,7 +2630,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait,
26292630
&implementor,
26302631
assoc_link,
26312632
RenderMode::Normal,
2632-
implementor.impl_item.stable_since(),
2633+
implementor.impl_item.stable_since().as_deref(),
26332634
false,
26342635
None,
26352636
true,
@@ -2780,7 +2781,11 @@ fn render_stability_since_raw(w: &mut Buffer, ver: Option<&str>, containing_ver:
27802781
}
27812782

27822783
fn render_stability_since(w: &mut Buffer, item: &clean::Item, containing_item: &clean::Item) {
2783-
render_stability_since_raw(w, item.stable_since(), containing_item.stable_since())
2784+
render_stability_since_raw(
2785+
w,
2786+
item.stable_since().as_deref(),
2787+
containing_item.stable_since().as_deref(),
2788+
)
27842789
}
27852790

27862791
fn render_assoc_item(
@@ -3324,7 +3329,7 @@ fn render_assoc_items(
33243329
i,
33253330
AssocItemLink::Anchor(None),
33263331
render_mode,
3327-
containing_item.stable_since(),
3332+
containing_item.stable_since().as_deref(),
33283333
true,
33293334
None,
33303335
false,
@@ -3564,8 +3569,11 @@ fn render_impl(
35643569
);
35653570
}
35663571
write!(w, "<a href='#{}' class='anchor'></a>", id);
3567-
let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]);
3568-
render_stability_since_raw(w, since, outer_version);
3572+
let since = i.impl_item.stability.as_ref().and_then(|s| match s.level {
3573+
StabilityLevel::Stable { since } => Some(since.as_str()),
3574+
StabilityLevel::Unstable { .. } => None,
3575+
});
3576+
render_stability_since_raw(w, since.as_deref(), outer_version);
35693577
if let Some(l) = cx.src_href(&i.impl_item, cache) {
35703578
write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>", l, "goto source code");
35713579
}
@@ -3626,7 +3634,7 @@ fn render_impl(
36263634
write!(w, "<code>");
36273635
render_assoc_item(w, item, link.anchor(&id), ItemType::Impl);
36283636
write!(w, "</code>");
3629-
render_stability_since_raw(w, item.stable_since(), outer_version);
3637+
render_stability_since_raw(w, item.stable_since().as_deref(), outer_version);
36303638
if let Some(l) = cx.src_href(item, cache) {
36313639
write!(
36323640
w,
@@ -3648,7 +3656,7 @@ fn render_impl(
36483656
write!(w, "<h4 id='{}' class=\"{}{}\"><code>", id, item_type, extra_class);
36493657
assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "");
36503658
write!(w, "</code>");
3651-
render_stability_since_raw(w, item.stable_since(), outer_version);
3659+
render_stability_since_raw(w, item.stable_since().as_deref(), outer_version);
36523660
if let Some(l) = cx.src_href(item, cache) {
36533661
write!(
36543662
w,

0 commit comments

Comments
 (0)