From bf8114cdf21225069ba98bf65b7ed95935ee144d Mon Sep 17 00:00:00 2001 From: binarycat Date: Mon, 14 Sep 2026 14:36:39 -0400 Subject: [PATCH 1/2] rustdoc: add disambiguators for identically named method in sidebar --- src/librustdoc/html/render/sidebar.rs | 46 ++++++++++++++++++--------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 6fa033f927c85..49dd3e523f6fb 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -6,7 +6,6 @@ use askama::Template; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefIdMap, DefIdSet}; -use rustc_middle::ty::TyCtxt; use tracing::debug; use super::{Context, ItemSection, impl_trait_key, item_ty_to_section}; @@ -454,13 +453,14 @@ fn sidebar_assoc_items<'a>( impl_, GetMethodsMode::AlsoCollectAssocFns { assoc_fns: &mut assoc_fns }, used_links_bor, - cx.tcx(), + cx, )); } // We want links' order to be reproducible so we don't use unstable sort. assoc_consts.sort(); assoc_types.sort(); - methods.sort(); + postprocess_method_list(&mut assoc_fns); + postprocess_method_list(&mut methods); } let mut blocks = vec![ @@ -564,13 +564,8 @@ fn sidebar_deref_methods<'a>( && real_target.is_doc_subtype_of(&i.inner_impl().for_, c) }) .flat_map(|i| { - get_methods( - i.inner_impl(), - GetMethodsMode::Deref { deref_mut }, - used_links, - cx.tcx(), - ) - .collect::>() + get_methods(i.inner_impl(), GetMethodsMode::Deref { deref_mut }, used_links, cx) + .collect::>() }) .collect::>(); if !ret.is_empty() { @@ -589,8 +584,8 @@ fn sidebar_deref_methods<'a>( print_path(impl_.inner_impl().trait_.as_ref().unwrap(), cx), print_type(real_target, cx), ); - // We want links' order to be reproducible so we don't use unstable sort. - ret.sort(); + + postprocess_method_list(&mut ret); out.push(LinkBlock::new(Link::new(id, title), "deref-methods", ret)); } } @@ -765,7 +760,7 @@ fn get_methods<'a>( i: &'a clean::Impl, mut mode: GetMethodsMode<'_, 'a>, used_links: &mut FxHashSet, - tcx: TyCtxt<'_>, + cx: &Context<'_>, ) -> impl Iterator> { i.items.iter().filter_map(move |item| { if let Some(ref name) = item.name @@ -774,12 +769,12 @@ fn get_methods<'a>( let mut build_link = || { Link::new( get_next_url(used_links, format!("{typ}.{name}", typ = ItemType::Method)), - name.as_str(), + format!("{} ({:#})", name.as_str(), print_type(&i.for_, cx)), ) }; match &mut mode { &mut GetMethodsMode::Deref { deref_mut } => { - if super::should_render_item(item, deref_mut, tcx) { + if super::should_render_item(item, deref_mut, cx.tcx()) { Some(build_link()) } else { None @@ -800,6 +795,27 @@ fn get_methods<'a>( }) } +fn postprocess_method_list(methods: &mut [Link<'_>]) { + // We want links' order to be reproducible so we don't use unstable sort. + methods.sort(); + let trunc_to = |dst: &mut Cow<'_, str>, len: usize| match dst { + Cow::Borrowed(s) => *s = &s[..len], + Cow::Owned(s) => s.truncate(len), + }; + fn get_short_name<'a>(itm: Option<&'a Link<'a>>) -> Option<&'a str> { + Some(itm?.name.split_once(' ')?.0) + } + for i in 0..methods.len() { + let short_name = get_short_name(methods.get(i)); + if get_short_name(methods.get(i.wrapping_sub(1))) != short_name + && short_name != get_short_name(methods.get(i + 1)) + { + let shortened_len = short_name.unwrap().len(); + trunc_to(&mut methods[i].name, shortened_len); + } + } +} + fn get_associated_constants<'a>( i: &'a clean::Impl, used_links: &mut FxHashSet, From 9bab94702cfb8d638f507dc8d79bbceef293c485 Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 18 Sep 2026 20:27:07 -0400 Subject: [PATCH 2/2] rustdoc: add test for new sidebar disambiguators --- tests/rustdoc-html/sidebar/sidebar-dupes.rs | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/rustdoc-html/sidebar/sidebar-dupes.rs diff --git a/tests/rustdoc-html/sidebar/sidebar-dupes.rs b/tests/rustdoc-html/sidebar/sidebar-dupes.rs new file mode 100644 index 0000000000000..ce521e150bc5e --- /dev/null +++ b/tests/rustdoc-html/sidebar/sidebar-dupes.rs @@ -0,0 +1,22 @@ +#![crate_name = "foo"] + +// Test to ensure identically named methods in the sidebar get a disambiguator + +//@ has foo/struct.C.html +pub struct A; +pub struct B; +pub struct C(T); + +impl C { + //@ matches - "//a[@href='#method.dupe']" "^dupe \(C\)$" + pub fn dupe(self) {} + //@ matches - "//a[@href='#method.uniq1']" "^uniq1$" + pub fn uniq1(self) {} +} + +impl C { + //@ matches - "//a[@href='#method.dupe-1']" "^dupe \(C\)$" + pub fn dupe(self) {} + //@ matches - "//a[@href='#method.uniq2']" "^uniq2$" + pub fn uniq2(self) {} +}