@@ -3,10 +3,12 @@ use std::{borrow::Cow, rc::Rc};
3
3
use askama:: Template ;
4
4
use rustc_data_structures:: fx:: FxHashSet ;
5
5
use rustc_hir:: { def:: CtorKind , def_id:: DefIdSet } ;
6
+ use rustc_middle:: ty:: fast_reject:: { DeepRejectCtxt , TreatParams } ;
6
7
use rustc_middle:: ty:: { self , TyCtxt } ;
7
8
8
9
use crate :: {
9
10
clean,
11
+ clean:: types:: TypeAliasItem ,
10
12
formats:: { item_type:: ItemType , Impl } ,
11
13
html:: { format:: Buffer , markdown:: IdMap } ,
12
14
} ;
@@ -279,10 +281,43 @@ fn sidebar_assoc_items<'a>(
279
281
) {
280
282
let did = it. item_id . expect_def_id ( ) ;
281
283
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
+ } ;
282
317
283
318
let mut assoc_consts = Vec :: new ( ) ;
284
319
let mut methods = Vec :: new ( ) ;
285
- if let Some ( v ) = cache . impls . get ( & did ) {
320
+ if !v . is_empty ( ) {
286
321
let mut used_links = FxHashSet :: default ( ) ;
287
322
let mut id_map = IdMap :: new ( ) ;
288
323
@@ -318,7 +353,7 @@ fn sidebar_assoc_items<'a>(
318
353
cx,
319
354
& mut deref_methods,
320
355
impl_,
321
- v,
356
+ v. iter ( ) . copied ( ) ,
322
357
& mut derefs,
323
358
& mut used_links,
324
359
) ;
@@ -348,7 +383,7 @@ fn sidebar_deref_methods<'a>(
348
383
cx : & ' a Context < ' _ > ,
349
384
out : & mut Vec < LinkBlock < ' a > > ,
350
385
impl_ : & Impl ,
351
- v : & [ Impl ] ,
386
+ v : impl Iterator < Item = & ' a Impl > ,
352
387
derefs : & mut DefIdSet ,
353
388
used_links : & mut FxHashSet < String > ,
354
389
) {
@@ -373,7 +408,7 @@ fn sidebar_deref_methods<'a>(
373
408
// Avoid infinite cycles
374
409
return ;
375
410
}
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 ( ) ) ;
377
412
let inner_impl = target
378
413
. def_id ( c)
379
414
. or_else ( || {
@@ -424,7 +459,7 @@ fn sidebar_deref_methods<'a>(
424
459
cx,
425
460
out,
426
461
target_deref_impl,
427
- target_impls,
462
+ target_impls. iter ( ) ,
428
463
derefs,
429
464
used_links,
430
465
) ;
0 commit comments