Skip to content

Commit 613e9cd

Browse files
committed
Auto merge of rust-lang#136816 - yotamofek:pr/notable-traits-button-cleanup, r=<try>
Optimize `notable_trait_buttons` ~Small cleanup. Use `Iterator::any` instead of `for` loop with `predicate = true;`. I think this makes the code more readable... and also has the additional benefit of short-circuiting the iterator when a notable trait is found (a `break` statement was missing in the `for` loop version, I think). Probably won't be significant enough to show on perf results, though.~ Three commits, each attempting to optimize `notable_trait_buttons` by a little bit.
2 parents 69482e8 + afdf48d commit 613e9cd

File tree

3 files changed

+47
-46
lines changed

3 files changed

+47
-46
lines changed

src/librustdoc/html/render/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
55
use std::sync::mpsc::{Receiver, channel};
66

77
use rinja::Template;
8-
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
8+
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
99
use rustc_hir::def_id::{DefIdMap, LOCAL_CRATE};
1010
use rustc_middle::ty::TyCtxt;
1111
use rustc_session::Session;
@@ -60,7 +60,7 @@ pub(crate) struct Context<'tcx> {
6060
/// [#82381]: https://github.com/rust-lang/rust/issues/82381
6161
pub(crate) shared: SharedContext<'tcx>,
6262
/// Collection of all types with notable traits referenced in the current module.
63-
pub(crate) types_with_notable_traits: RefCell<FxIndexSet<clean::Type>>,
63+
pub(crate) types_with_notable_traits: RefCell<FxHashSet<clean::Type>>,
6464
/// Contains information that needs to be saved and reset after rendering an item which is
6565
/// not a module.
6666
pub(crate) info: ContextInfo,
@@ -579,7 +579,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
579579
id_map: RefCell::new(id_map),
580580
deref_id_map: Default::default(),
581581
shared: scx,
582-
types_with_notable_traits: RefCell::new(FxIndexSet::default()),
582+
types_with_notable_traits: RefCell::default(),
583583
info: ContextInfo::new(include_sources),
584584
};
585585

src/librustdoc/html/render/mod.rs

+43-42
Original file line numberDiff line numberDiff line change
@@ -1432,56 +1432,57 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
14321432
}
14331433

14341434
pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Option<String> {
1435-
let mut has_notable_trait = false;
1436-
14371435
if ty.is_unit() {
14381436
// Very common fast path.
14391437
return None;
14401438
}
14411439

1442-
let did = ty.def_id(cx.cache())?;
1440+
let has_notable_trait = || {
1441+
let Some(did) = ty.def_id(cx.cache()) else {
1442+
return false;
1443+
};
14431444

1444-
// Box has pass-through impls for Read, Write, Iterator, and Future when the
1445-
// boxed type implements one of those. We don't want to treat every Box return
1446-
// as being notably an Iterator (etc), though, so we exempt it. Pin has the same
1447-
// issue, with a pass-through impl for Future.
1448-
if Some(did) == cx.tcx().lang_items().owned_box()
1449-
|| Some(did) == cx.tcx().lang_items().pin_type()
1450-
{
1451-
return None;
1452-
}
1445+
// Box has pass-through impls for Read, Write, Iterator, and Future when the
1446+
// boxed type implements one of those. We don't want to treat every Box return
1447+
// as being notably an Iterator (etc), though, so we exempt it. Pin has the same
1448+
// issue, with a pass-through impl for Future.
1449+
if Some(did) == cx.tcx().lang_items().owned_box()
1450+
|| Some(did) == cx.tcx().lang_items().pin_type()
1451+
{
1452+
return false;
1453+
}
14531454

1454-
if let Some(impls) = cx.cache().impls.get(&did) {
1455-
for i in impls {
1456-
let impl_ = i.inner_impl();
1457-
if impl_.polarity != ty::ImplPolarity::Positive {
1458-
continue;
1459-
}
1455+
let Some(impls) = cx.cache().impls.get(&did) else {
1456+
return false;
1457+
};
14601458

1461-
if !ty.is_doc_subtype_of(&impl_.for_, cx.cache()) {
1462-
// Two different types might have the same did,
1463-
// without actually being the same.
1464-
continue;
1465-
}
1466-
if let Some(trait_) = &impl_.trait_ {
1467-
let trait_did = trait_.def_id();
1459+
impls
1460+
.iter()
1461+
.map(Impl::inner_impl)
1462+
.filter(|impl_| {
1463+
impl_.polarity == ty::ImplPolarity::Positive
1464+
// Two different types might have the same did,
1465+
// without actually being the same.
1466+
&& ty.is_doc_subtype_of(&impl_.for_, cx.cache())
1467+
})
1468+
.filter_map(|impl_| impl_.trait_.as_ref())
1469+
.filter_map(|trait_| cx.cache().traits.get(&trait_.def_id()))
1470+
.any(|t| t.is_notable_trait(cx.tcx()))
1471+
};
14681472

1469-
if cx.cache().traits.get(&trait_did).is_some_and(|t| t.is_notable_trait(cx.tcx())) {
1470-
has_notable_trait = true;
1471-
}
1472-
}
1473+
let mut types_with_notable_traits = cx.types_with_notable_traits.borrow_mut();
1474+
if !types_with_notable_traits.contains(ty) {
1475+
if has_notable_trait() {
1476+
types_with_notable_traits.insert(ty.clone());
1477+
} else {
1478+
return None;
14731479
}
14741480
}
14751481

1476-
if has_notable_trait {
1477-
cx.types_with_notable_traits.borrow_mut().insert(ty.clone());
1478-
Some(format!(
1479-
" <a href=\"#\" class=\"tooltip\" data-notable-ty=\"{ty}\">ⓘ</a>",
1480-
ty = Escape(&format!("{:#}", ty.print(cx))),
1481-
))
1482-
} else {
1483-
None
1484-
}
1482+
Some(format!(
1483+
" <a href=\"#\" class=\"tooltip\" data-notable-ty=\"{ty}\">ⓘ</a>",
1484+
ty = Escape(&format!("{:#}", ty.print(cx))),
1485+
))
14851486
}
14861487

14871488
fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
@@ -1544,10 +1545,10 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
15441545
(format!("{:#}", ty.print(cx)), out.into_inner())
15451546
}
15461547

1547-
pub(crate) fn notable_traits_json<'a>(
1548-
tys: impl Iterator<Item = &'a clean::Type>,
1549-
cx: &Context<'_>,
1550-
) -> String {
1548+
pub(crate) fn notable_traits_json(tys: &FxHashSet<clean::Type>, cx: &Context<'_>) -> String {
1549+
#[expect(rustc::potential_query_instability, reason = "items are sorted by name")]
1550+
let tys = tys.iter();
1551+
15511552
let mut mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect();
15521553
mp.sort_by(|(name1, _html1), (name2, _html2)| name1.cmp(name2));
15531554
struct NotableTraitsMap(Vec<(String, String)>);

src/librustdoc/html/render/print_item.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer)
281281
write!(
282282
buf,
283283
r#"<script type="text/json" id="notable-traits-data">{}</script>"#,
284-
notable_traits_json(types_with_notable_traits.iter(), cx)
284+
notable_traits_json(&types_with_notable_traits, cx)
285285
);
286286
types_with_notable_traits.clear();
287287
}

0 commit comments

Comments
 (0)