Skip to content

Commit d882b21

Browse files
committed
rustdoc: add impl items from aliased type into sidebar
1 parent ffc48e3 commit d882b21

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

src/librustdoc/html/render/sidebar.rs

+40-5
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ use std::{borrow::Cow, rc::Rc};
33
use askama::Template;
44
use rustc_data_structures::fx::FxHashSet;
55
use rustc_hir::{def::CtorKind, def_id::DefIdSet};
6+
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
67
use rustc_middle::ty::{self, TyCtxt};
78

89
use crate::{
910
clean,
11+
clean::types::TypeAliasItem,
1012
formats::{item_type::ItemType, Impl},
1113
html::{format::Buffer, markdown::IdMap},
1214
};
@@ -279,10 +281,43 @@ fn sidebar_assoc_items<'a>(
279281
) {
280282
let did = it.item_id.expect_def_id();
281283
let cache = cx.cache();
284+
let tcx = cx.tcx();
285+
let mut v: Vec<&Impl> =
286+
cache.impls.get(&did).map(Vec::as_slice).unwrap_or(&[]).iter().collect();
287+
if let TypeAliasItem(ait) = &*it.kind &&
288+
let aliased_clean_type = ait.item_type.as_ref().unwrap_or(&ait.type_) &&
289+
let Some(aliased_type_defid) = aliased_clean_type.def_id(cache) &&
290+
let Some(av) = cache.impls.get(&aliased_type_defid) &&
291+
let Some(alias_def_id) = it.item_id.as_def_id()
292+
{
293+
// This branch of the compiler compares types structually, but does
294+
// not check trait bounds. That's probably fine, since type aliases
295+
// don't normally constrain on them anyway.
296+
// https://github.com/rust-lang/rust/issues/21903
297+
//
298+
// FIXME(lazy_type_alias): Once the feature is complete or stable, rewrite this to use type unification.
299+
// Be aware of `tests/rustdoc/issue-112515-impl-ty-alias.rs` which might regress.
300+
let aliased_ty = tcx.type_of(alias_def_id).skip_binder();
301+
let reject_cx = DeepRejectCtxt {
302+
treat_obligation_params: TreatParams::AsCandidateKey,
303+
};
304+
v.extend(av.iter().filter(|impl_| {
305+
if let Some(impl_def_id) = impl_.impl_item.item_id.as_def_id() {
306+
reject_cx.types_may_unify(aliased_ty, tcx.type_of(impl_def_id).skip_binder())
307+
} else {
308+
false
309+
}
310+
}));
311+
}
312+
let v = {
313+
let mut saw_impls = FxHashSet::default();
314+
v.retain(|i| saw_impls.insert(i.def_id()));
315+
v.as_slice()
316+
};
282317

283318
let mut assoc_consts = Vec::new();
284319
let mut methods = Vec::new();
285-
if let Some(v) = cache.impls.get(&did) {
320+
if !v.is_empty() {
286321
let mut used_links = FxHashSet::default();
287322
let mut id_map = IdMap::new();
288323

@@ -318,7 +353,7 @@ fn sidebar_assoc_items<'a>(
318353
cx,
319354
&mut deref_methods,
320355
impl_,
321-
v,
356+
v.iter().copied(),
322357
&mut derefs,
323358
&mut used_links,
324359
);
@@ -348,7 +383,7 @@ fn sidebar_deref_methods<'a>(
348383
cx: &'a Context<'_>,
349384
out: &mut Vec<LinkBlock<'a>>,
350385
impl_: &Impl,
351-
v: &[Impl],
386+
v: impl Iterator<Item = &'a Impl>,
352387
derefs: &mut DefIdSet,
353388
used_links: &mut FxHashSet<String>,
354389
) {
@@ -373,7 +408,7 @@ fn sidebar_deref_methods<'a>(
373408
// Avoid infinite cycles
374409
return;
375410
}
376-
let deref_mut = v.iter().any(|i| i.trait_did() == cx.tcx().lang_items().deref_mut_trait());
411+
let deref_mut = { v }.any(|i| i.trait_did() == cx.tcx().lang_items().deref_mut_trait());
377412
let inner_impl = target
378413
.def_id(c)
379414
.or_else(|| {
@@ -424,7 +459,7 @@ fn sidebar_deref_methods<'a>(
424459
cx,
425460
out,
426461
target_deref_impl,
427-
target_impls,
462+
target_impls.iter(),
428463
derefs,
429464
used_links,
430465
);

tests/rustdoc/issue-32077-type-alias-impls.rs

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ impl Bar for GenericStruct<u32> {}
2929
// @!has - '//h3' 'impl Bar for GenericStruct<u32> {}'
3030
// Same goes for the `Deref` impl.
3131
// @!has - '//h2' 'Methods from Deref<Target = u32>'
32+
// @count - '//nav[@class="sidebar"]//a' 'on_alias' 1
33+
// @count - '//nav[@class="sidebar"]//a' 'on_gen' 1
34+
// @count - '//nav[@class="sidebar"]//a' 'Foo' 1
35+
// @!has - '//nav[@class="sidebar"]//a' 'Bar'
36+
// @!has - '//nav[@class="sidebar"]//a' 'on_u32'
3237
pub type TypedefStruct = GenericStruct<u8>;
3338

3439
impl TypedefStruct {

0 commit comments

Comments
 (0)