Skip to content

Commit 88df8fd

Browse files
authored
Rollup merge of #151091 - hide-deprecated-items, r=lolbinarycat
Add new "hide deprecated items" setting in rustdoc This PR adds a new JS setting which allows the JS to hide deprecated items. This is especially useful for crates like `std` which accumulates deprecated items but never removes them. Nicely enough, the "deprecation" information was already in the search index, meaning I didn't need to change anything there. Before this PR, it was only used to make the deprecated items rank lower. Well now it's also used to generate an extra CSS class, allowing the JS setting to work. This is taking over #149551. This feature got approved by the rustdoc team in the [meeting of december](https://rust-lang.zulipchat.com/#narrow/channel/393423-t-rustdoc.2Fmeetings/topic/2025-12-08/near/562553156). You can give it a try [here](https://rustdoc.crud.net/imperio/hide-deprecated-items/foo/index.html). r? @lolbinarycat
2 parents 1262ff9 + aef8112 commit 88df8fd

File tree

17 files changed

+293
-81
lines changed

17 files changed

+293
-81
lines changed

src/librustdoc/clean/auto_trait.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ fn synthesize_auto_trait_impl<'tcx>(
126126
items: Vec::new(),
127127
polarity,
128128
kind: clean::ImplKind::Auto,
129+
is_deprecated: false,
129130
})),
130131
item_id: clean::ItemId::Auto { trait_: trait_def_id, for_: item_def_id },
131132
cfg: None,

src/librustdoc/clean/blanket_impl.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ pub(crate) fn synthesize_blanket_impls(
117117
None,
118118
None,
119119
))),
120+
is_deprecated: tcx
121+
.lookup_deprecation(impl_def_id)
122+
.is_some_and(|deprecation| deprecation.is_in_effect()),
120123
})),
121124
cfg: None,
122125
inline_stmt_id: None,

src/librustdoc/clean/inline.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,9 @@ pub(crate) fn build_impl(
645645
} else {
646646
ImplKind::Normal
647647
},
648+
is_deprecated: tcx
649+
.lookup_deprecation(did)
650+
.is_some_and(|deprecation| deprecation.is_in_effect()),
648651
})),
649652
merged_attrs,
650653
cfg,

src/librustdoc/clean/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2904,6 +2904,9 @@ fn clean_impl<'tcx>(
29042904
)),
29052905
_ => None,
29062906
});
2907+
let is_deprecated = tcx
2908+
.lookup_deprecation(def_id.to_def_id())
2909+
.is_some_and(|deprecation| deprecation.is_in_effect());
29072910
let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
29082911
let kind = ImplItem(Box::new(Impl {
29092912
safety: match impl_.of_trait {
@@ -2924,6 +2927,7 @@ fn clean_impl<'tcx>(
29242927
} else {
29252928
ImplKind::Normal
29262929
},
2930+
is_deprecated,
29272931
}));
29282932
Item::from_def_id_and_parts(def_id.to_def_id(), None, kind, cx)
29292933
};

src/librustdoc/clean/types.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,10 @@ impl Item {
427427
})
428428
}
429429

430+
pub(crate) fn is_deprecated(&self, tcx: TyCtxt<'_>) -> bool {
431+
self.deprecation(tcx).is_some_and(|deprecation| deprecation.is_in_effect())
432+
}
433+
430434
pub(crate) fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
431435
self.item_id.as_def_id().map(|did| inner_docs(tcx.get_all_attrs(did))).unwrap_or(false)
432436
}
@@ -1270,6 +1274,9 @@ impl Trait {
12701274
pub(crate) fn is_dyn_compatible(&self, tcx: TyCtxt<'_>) -> bool {
12711275
tcx.is_dyn_compatible(self.def_id)
12721276
}
1277+
pub(crate) fn is_deprecated(&self, tcx: TyCtxt<'_>) -> bool {
1278+
tcx.lookup_deprecation(self.def_id).is_some_and(|deprecation| deprecation.is_in_effect())
1279+
}
12731280
}
12741281

12751282
#[derive(Clone, Debug)]
@@ -2254,6 +2261,7 @@ pub(crate) struct Impl {
22542261
pub(crate) items: Vec<Item>,
22552262
pub(crate) polarity: ty::ImplPolarity,
22562263
pub(crate) kind: ImplKind,
2264+
pub(crate) is_deprecated: bool,
22572265
}
22582266

22592267
impl Impl {

src/librustdoc/formats/cache.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
593593
cache,
594594
);
595595
let aliases = item.attrs.get_doc_aliases();
596-
let deprecation = item.deprecation(tcx);
596+
let is_deprecated = item.is_deprecated(tcx);
597597
let index_item = IndexItem {
598598
ty: item.type_(),
599599
defid: Some(defid),
@@ -608,7 +608,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
608608
impl_id,
609609
search_type,
610610
aliases,
611-
deprecation,
611+
is_deprecated,
612612
};
613613

614614
cache.search_index.push(index_item);

src/librustdoc/html/render/mod.rs

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ pub(crate) struct IndexItem {
141141
pub(crate) impl_id: Option<DefId>,
142142
pub(crate) search_type: Option<IndexItemFunctionType>,
143143
pub(crate) aliases: Box<[Symbol]>,
144-
pub(crate) deprecation: Option<Deprecation>,
144+
pub(crate) is_deprecated: bool,
145145
}
146146

147147
/// A type used for the search index.
@@ -1791,12 +1791,14 @@ fn render_impl(
17911791
let mut info_buffer = String::new();
17921792
let mut short_documented = true;
17931793

1794+
let mut trait_item_deprecated = false;
17941795
if render_method_item {
17951796
if !is_default_item {
17961797
if let Some(t) = trait_ {
17971798
// The trait item may have been stripped so we might not
17981799
// find any documentation or stability for it.
17991800
if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
1801+
trait_item_deprecated = it.is_deprecated(cx.tcx());
18001802
// We need the stability of the item from the trait
18011803
// because impls can't have a stability.
18021804
if !item.doc_value().is_empty() {
@@ -1836,10 +1838,20 @@ fn render_impl(
18361838
Either::Right(boring)
18371839
};
18381840

1841+
let mut deprecation_class = if trait_item_deprecated || item.is_deprecated(cx.tcx()) {
1842+
" deprecated"
1843+
} else {
1844+
""
1845+
};
1846+
18391847
let toggled = !doc_buffer.is_empty();
18401848
if toggled {
18411849
let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
1842-
write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>")?;
1850+
write!(
1851+
w,
1852+
"<details class=\"toggle{method_toggle_class}{deprecation_class}\" open><summary>"
1853+
)?;
1854+
deprecation_class = "";
18431855
}
18441856
match &item.kind {
18451857
clean::MethodItem(..) | clean::RequiredMethodItem(_) => {
@@ -1856,7 +1868,7 @@ fn render_impl(
18561868
.map(|item| format!("{}.{name}", item.type_()));
18571869
write!(
18581870
w,
1859-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1871+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
18601872
{}",
18611873
render_rightside(cx, item, render_mode)
18621874
)?;
@@ -1882,7 +1894,7 @@ fn render_impl(
18821894
let id = cx.derive_id(&source_id);
18831895
write!(
18841896
w,
1885-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1897+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
18861898
{}",
18871899
render_rightside(cx, item, render_mode)
18881900
)?;
@@ -1909,7 +1921,7 @@ fn render_impl(
19091921
let id = cx.derive_id(&source_id);
19101922
write!(
19111923
w,
1912-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1924+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
19131925
{}",
19141926
render_rightside(cx, item, render_mode),
19151927
)?;
@@ -1941,7 +1953,7 @@ fn render_impl(
19411953
let id = cx.derive_id(&source_id);
19421954
write!(
19431955
w,
1944-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1956+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
19451957
{}",
19461958
render_rightside(cx, item, render_mode),
19471959
)?;
@@ -1968,7 +1980,7 @@ fn render_impl(
19681980
let id = cx.derive_id(&source_id);
19691981
write!(
19701982
w,
1971-
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
1983+
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
19721984
{}",
19731985
render_rightside(cx, item, render_mode),
19741986
)?;
@@ -2140,11 +2152,18 @@ fn render_impl(
21402152
}
21412153
if render_mode == RenderMode::Normal {
21422154
let toggled = !(impl_items.is_empty() && default_impl_items.is_empty());
2155+
let deprecation_attr = if impl_.is_deprecated
2156+
|| trait_.is_some_and(|trait_| trait_.is_deprecated(cx.tcx()))
2157+
{
2158+
" deprecated"
2159+
} else {
2160+
""
2161+
};
21432162
if toggled {
21442163
close_tags.push("</details>");
21452164
write!(
21462165
w,
2147-
"<details class=\"toggle implementors-toggle\"{}>\
2166+
"<details class=\"toggle implementors-toggle{deprecation_attr}\"{}>\
21482167
<summary>",
21492168
if rendering_params.toggle_open_by_default { " open" } else { "" }
21502169
)?;

src/librustdoc/html/render/print_item.rs

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ fn toggle_close(mut w: impl fmt::Write) {
217217
}
218218

219219
fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> impl fmt::Display {
220+
fn deprecation_class_attr(is_deprecated: bool) -> &'static str {
221+
if is_deprecated { " class=\"deprecated\"" } else { "" }
222+
}
223+
220224
fmt::from_fn(|w| {
221225
write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?;
222226

@@ -370,11 +374,18 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
370374
write!(w, "</code></dt>")?
371375
}
372376
clean::ImportItem(ref import) => {
373-
let stab_tags =
374-
import.source.did.map_or_else(String::new, |import_def_id| {
375-
print_extra_info_tags(tcx, myitem, item, Some(import_def_id))
376-
.to_string()
377-
});
377+
let (stab_tags, deprecation) = match import.source.did {
378+
Some(import_def_id) => {
379+
let stab_tags =
380+
print_extra_info_tags(tcx, myitem, item, Some(import_def_id))
381+
.to_string();
382+
let deprecation = tcx
383+
.lookup_deprecation(import_def_id)
384+
.is_some_and(|deprecation| deprecation.is_in_effect());
385+
(stab_tags, deprecation)
386+
}
387+
None => (String::new(), item.is_deprecated(tcx)),
388+
};
378389
let id = match import.kind {
379390
clean::ImportKind::Simple(s) => {
380391
format!(" id=\"{}\"", cx.derive_id(format!("reexport.{s}")))
@@ -383,8 +394,8 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
383394
};
384395
write!(
385396
w,
386-
"<dt{id}>\
387-
<code>"
397+
"<dt{id}{deprecation_attr}><code>",
398+
deprecation_attr = deprecation_class_attr(deprecation)
388399
)?;
389400
render_attributes_in_code(w, myitem, "", cx)?;
390401
write!(
@@ -396,9 +407,7 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
396407
)?;
397408
}
398409
_ => {
399-
if myitem.name.is_none() {
400-
continue;
401-
}
410+
let Some(item_name) = myitem.name else { continue };
402411

403412
let unsafety_flag = match myitem.kind {
404413
clean::FunctionItem(_) | clean::ForeignFunctionItem(..)
@@ -431,9 +440,10 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
431440
.into_string();
432441
let (docs_before, docs_after) =
433442
if docs.is_empty() { ("", "") } else { ("<dd>", "</dd>") };
443+
let deprecation_attr = deprecation_class_attr(myitem.is_deprecated(tcx));
434444
write!(
435445
w,
436-
"<dt>\
446+
"<dt{deprecation_attr}>\
437447
<a class=\"{class}\" href=\"{href}\" title=\"{title1} {title2}\">\
438448
{name}\
439449
</a>\
@@ -442,12 +452,12 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
442452
{stab_tags}\
443453
</dt>\
444454
{docs_before}{docs}{docs_after}",
445-
name = EscapeBodyTextWithWbr(myitem.name.unwrap().as_str()),
455+
name = EscapeBodyTextWithWbr(item_name.as_str()),
446456
visibility_and_hidden = visibility_and_hidden,
447457
stab_tags = print_extra_info_tags(tcx, myitem, item, None),
448458
class = type_,
449459
unsafety_flag = unsafety_flag,
450-
href = print_item_path(type_, myitem.name.unwrap().as_str()),
460+
href = print_item_path(type_, item_name.as_str()),
451461
title1 = myitem.type_(),
452462
title2 = full_path(cx, myitem),
453463
)?;
@@ -778,15 +788,24 @@ fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt:
778788

779789
let content = document_full(m, cx, HeadingOffset::H5).to_string();
780790

791+
let mut deprecation_class =
792+
if m.is_deprecated(cx.tcx()) { " deprecated" } else { "" };
793+
781794
let toggled = !content.is_empty();
782795
if toggled {
783796
let method_toggle_class =
784797
if item_type.is_method() { " method-toggle" } else { "" };
785-
write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>")?;
798+
write!(
799+
w,
800+
"<details \
801+
class=\"toggle{method_toggle_class}{deprecation_class}\" \
802+
open><summary>"
803+
)?;
804+
deprecation_class = "";
786805
}
787806
write!(
788807
w,
789-
"<section id=\"{id}\" class=\"method\">\
808+
"<section id=\"{id}\" class=\"method{deprecation_class}\">\
790809
{}\
791810
<h4 class=\"code-header\">{}</h4></section>",
792811
render_rightside(cx, m, RenderMode::Normal),

src/librustdoc/html/render/search_index.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,7 +1282,7 @@ pub(crate) fn build_index(
12821282
cache,
12831283
),
12841284
aliases: item.attrs.get_doc_aliases(),
1285-
deprecation: item.deprecation(tcx),
1285+
is_deprecated: item.is_deprecated(tcx),
12861286
});
12871287
}
12881288
}
@@ -1519,7 +1519,7 @@ pub(crate) fn build_index(
15191519
trait_parent: item.trait_parent_idx,
15201520
module_path,
15211521
exact_module_path,
1522-
deprecated: item.deprecation.is_some(),
1522+
deprecated: item.is_deprecated,
15231523
associated_item_disambiguator: if let Some(impl_id) = item.impl_id
15241524
&& let Some(parent_idx) = item.parent_idx
15251525
&& associated_item_duplicates

src/librustdoc/html/static/css/rustdoc.css

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\
6464
<path d="M3,5h16M3,11h16M3,17h16" stroke-width="2.75"/></svg>');
6565
}
6666

67-
:root.sans-serif {
67+
:root.sans-serif-fonts {
6868
--font-family: "Fira Sans", sans-serif;
6969
--font-family-code: "Fira Mono", monospace;
7070
}
@@ -2642,6 +2642,15 @@ However, it's not needed with smaller screen width because the doc/code block is
26422642
}
26432643
}
26442644

2645+
/* Items on module pages */
2646+
.hide-deprecated-items dt.deprecated,
2647+
.hide-deprecated-items dt.deprecated + dd,
2648+
/* Items on item pages */
2649+
.hide-deprecated-items .deprecated,
2650+
.hide-deprecated-items .deprecated + .item-info {
2651+
display: none;
2652+
}
2653+
26452654
/*
26462655
WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
26472656
If you update this line, then you also need to update the line with the same warning

0 commit comments

Comments
 (0)