@@ -54,6 +54,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
54
54
use rustc_hir:: def_id:: { DefId , DefIdSet } ;
55
55
use rustc_hir:: Mutability ;
56
56
use rustc_middle:: middle:: stability;
57
+ use rustc_middle:: ty:: fast_reject:: { DeepRejectCtxt , TreatParams } ;
57
58
use rustc_middle:: ty:: TyCtxt ;
58
59
use rustc_span:: {
59
60
symbol:: { sym, Symbol } ,
@@ -62,6 +63,7 @@ use rustc_span::{
62
63
use serde:: ser:: { SerializeMap , SerializeSeq } ;
63
64
use serde:: { Serialize , Serializer } ;
64
65
66
+ use crate :: clean:: types:: TypeAliasItem ;
65
67
use crate :: clean:: { self , ItemId , RenderedLink , SelfTy } ;
66
68
use crate :: error:: Error ;
67
69
use crate :: formats:: cache:: Cache ;
@@ -1139,8 +1141,40 @@ fn render_assoc_items_inner(
1139
1141
info ! ( "Documenting associated items of {:?}" , containing_item. name) ;
1140
1142
let shared = Rc :: clone ( & cx. shared ) ;
1141
1143
let cache = & shared. cache ;
1142
- let Some ( v) = cache. impls . get ( & it) else { return } ;
1143
- let ( non_trait, traits) : ( Vec < _ > , _ ) = v. iter ( ) . partition ( |i| i. inner_impl ( ) . trait_ . is_none ( ) ) ;
1144
+ let tcx = cx. tcx ( ) ;
1145
+ let av = if let TypeAliasItem ( ait) = & * containing_item. kind &&
1146
+ let aliased_clean_type = ait. item_type . as_ref ( ) . unwrap_or ( & ait. type_ ) &&
1147
+ let Some ( aliased_type_defid) = aliased_clean_type. def_id ( cache) &&
1148
+ let Some ( mut av) = cache. impls . get ( & aliased_type_defid) . cloned ( ) &&
1149
+ let Some ( alias_def_id) = containing_item. item_id . as_def_id ( )
1150
+ {
1151
+ // This branch of the compiler compares types structually, but does
1152
+ // not check trait bounds. That's probably fine, since type aliases
1153
+ // don't normally constrain on them anyway.
1154
+ // https://github.com/rust-lang/rust/issues/21903
1155
+ //
1156
+ // FIXME(lazy_type_alias): Once the feature is complete or stable, rewrite this to use type unification.
1157
+ // Be aware of `tests/rustdoc/issue-112515-impl-ty-alias.rs` which might regress.
1158
+ let aliased_ty = tcx. type_of ( alias_def_id) . skip_binder ( ) ;
1159
+ let reject_cx = DeepRejectCtxt {
1160
+ treat_obligation_params : TreatParams :: AsCandidateKey ,
1161
+ } ;
1162
+ av. retain ( |impl_| {
1163
+ if let Some ( impl_def_id) = impl_. impl_item . item_id . as_def_id ( ) {
1164
+ reject_cx. types_may_unify ( aliased_ty, tcx. type_of ( impl_def_id) . skip_binder ( ) )
1165
+ } else {
1166
+ false
1167
+ }
1168
+ } ) ;
1169
+ av
1170
+ } else {
1171
+ Vec :: new ( )
1172
+ } ;
1173
+ let blank = Vec :: new ( ) ;
1174
+ let v = cache. impls . get ( & it) . unwrap_or ( & blank) ;
1175
+ let ( non_trait, traits) : ( Vec < _ > , _ ) =
1176
+ v. iter ( ) . chain ( & av[ ..] ) . partition ( |i| i. inner_impl ( ) . trait_ . is_none ( ) ) ;
1177
+ let mut saw_impls = FxHashSet :: default ( ) ;
1144
1178
if !non_trait. is_empty ( ) {
1145
1179
let mut tmp_buf = Buffer :: html ( ) ;
1146
1180
let ( render_mode, id, class_html) = match what {
@@ -1169,6 +1203,9 @@ fn render_assoc_items_inner(
1169
1203
} ;
1170
1204
let mut impls_buf = Buffer :: html ( ) ;
1171
1205
for i in & non_trait {
1206
+ if !saw_impls. insert ( i. def_id ( ) ) {
1207
+ continue ;
1208
+ }
1172
1209
render_impl (
1173
1210
& mut impls_buf,
1174
1211
cx,
@@ -1214,8 +1251,10 @@ fn render_assoc_items_inner(
1214
1251
1215
1252
let ( synthetic, concrete) : ( Vec < & Impl > , Vec < & Impl > ) =
1216
1253
traits. into_iter ( ) . partition ( |t| t. inner_impl ( ) . kind . is_auto ( ) ) ;
1217
- let ( blanket_impl, concrete) : ( Vec < & Impl > , _ ) =
1218
- concrete. into_iter ( ) . partition ( |t| t. inner_impl ( ) . kind . is_blanket ( ) ) ;
1254
+ let ( blanket_impl, concrete) : ( Vec < & Impl > , _ ) = concrete
1255
+ . into_iter ( )
1256
+ . filter ( |t| saw_impls. insert ( t. def_id ( ) ) )
1257
+ . partition ( |t| t. inner_impl ( ) . kind . is_blanket ( ) ) ;
1219
1258
1220
1259
render_all_impls ( w, cx, containing_item, & concrete, & synthetic, & blanket_impl) ;
1221
1260
}
0 commit comments