Skip to content

Commit 9f1aecd

Browse files
committed
rustdoc: assoc const bounds from supertraits
When documenting code with associated const equality bounds where the const is defined in a supertrait, `rustdoc` would panic with "called `Option::unwrap()` on a `None` value" because it only searched for the associated item in the immediate trait. This can be fixed by adding a recursive helper function that searched through the traits supertrait hierarchy to find the associated item.
1 parent db6bc0f commit 9f1aecd

File tree

3 files changed

+60
-5
lines changed

3 files changed

+60
-5
lines changed

src/librustdoc/clean/mod.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,6 +3147,31 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
31473147
})
31483148
}
31493149

3150+
fn find_assoc_item_in_trait<'tcx>(
3151+
tcx: TyCtxt<'tcx>,
3152+
trait_did: DefId,
3153+
ident: Ident,
3154+
assoc_tag: ty::AssocTag,
3155+
) -> Option<DefId> {
3156+
if let Some(item) =
3157+
tcx.associated_items(trait_did).find_by_ident_and_kind(tcx, ident, assoc_tag, trait_did)
3158+
{
3159+
return Some(item.def_id);
3160+
}
3161+
3162+
for (pred, _) in tcx.explicit_super_predicates_of(trait_did).iter_identity_copied() {
3163+
if let Some(trait_ref) = pred.as_trait_clause() {
3164+
if let Some(def_id) =
3165+
find_assoc_item_in_trait(tcx, trait_ref.def_id(), ident, assoc_tag)
3166+
{
3167+
return Some(def_id);
3168+
}
3169+
}
3170+
}
3171+
3172+
None
3173+
}
3174+
31503175
fn clean_assoc_item_constraint<'tcx>(
31513176
trait_did: DefId,
31523177
constraint: &hir::AssocItemConstraint<'tcx>,
@@ -3163,11 +3188,8 @@ fn clean_assoc_item_constraint<'tcx>(
31633188
hir::Term::Ty(_) => ty::AssocTag::Type,
31643189
hir::Term::Const(_) => ty::AssocTag::Const,
31653190
};
3166-
let assoc_item = cx
3167-
.tcx
3168-
.associated_items(trait_did)
3169-
.find_by_ident_and_kind(cx.tcx, constraint.ident, assoc_tag, trait_did)
3170-
.map(|item| item.def_id);
3191+
let assoc_item =
3192+
find_assoc_item_in_trait(cx.tcx, trait_did, constraint.ident, assoc_tag);
31713193
AssocItemConstraintKind::Equality { term: clean_hir_term(assoc_item, term, cx) }
31723194
}
31733195
hir::AssocItemConstraintKind::Bound { bounds } => AssocItemConstraintKind::Bound {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Regression test for issue #151511.
2+
// Ensure that rustdoc doesn't ICE when encountering assoc const eq bounds
3+
// where the assoc const comes from a supertrait.
4+
5+
#![feature(
6+
min_generic_const_args,
7+
adt_const_params,
8+
unsized_const_params,
9+
generic_const_parameter_types
10+
)]
11+
#![allow(incomplete_features)]
12+
13+
use std::marker::ConstParamTy_;
14+
15+
trait Trait: SuperTrait {}
16+
trait SuperTrait: SuperSuperTrait<i32> {}
17+
trait SuperSuperTrait<T: ConstParamTy_> {
18+
#[type_const]
19+
const K: T;
20+
}
21+
22+
fn take(_: impl Trait<K = 0>) {}
23+
//~^ ERROR anonymous constants referencing generics are not yet supported
24+
25+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: anonymous constants referencing generics are not yet supported
2+
--> $DIR/assoc-const-bounds-supertrait.rs:17:27
3+
|
4+
LL | fn take(_: impl Trait<K = 0>) {}
5+
| ^
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)