@@ -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 ;
@@ -1131,13 +1133,13 @@ pub(crate) fn render_all_impls(
1131
1133
fn render_assoc_items < ' a , ' cx : ' a > (
1132
1134
cx : & ' a mut Context < ' cx > ,
1133
1135
containing_item : & ' a clean:: Item ,
1134
- did : DefId ,
1136
+ it : DefId ,
1135
1137
what : AssocItemRender < ' a > ,
1136
1138
) -> impl fmt:: Display + ' a + Captures < ' cx > {
1137
1139
let mut derefs = DefIdSet :: default ( ) ;
1138
- derefs. insert ( did ) ;
1140
+ derefs. insert ( it ) ;
1139
1141
display_fn ( move |f| {
1140
- render_assoc_items_inner ( f, cx, containing_item, did , what, & mut derefs) ;
1142
+ render_assoc_items_inner ( f, cx, containing_item, it , what, & mut derefs) ;
1141
1143
Ok ( ( ) )
1142
1144
} )
1143
1145
}
@@ -1146,16 +1148,46 @@ fn render_assoc_items_inner(
1146
1148
mut w : & mut dyn fmt:: Write ,
1147
1149
cx : & mut Context < ' _ > ,
1148
1150
containing_item : & clean:: Item ,
1149
- did : DefId ,
1151
+ it : DefId ,
1150
1152
what : AssocItemRender < ' _ > ,
1151
1153
derefs : & mut DefIdSet ,
1152
1154
) {
1153
1155
info ! ( "Documenting associated items of {:?}" , containing_item. name) ;
1154
1156
let shared = Rc :: clone ( & cx. shared ) ;
1155
- let v = shared. all_impls_for_item ( containing_item, did) ;
1156
- let v = v. as_slice ( ) ;
1157
- let ( non_trait, traits) : ( Vec < & Impl > , _ ) =
1158
- v. iter ( ) . partition ( |i| i. inner_impl ( ) . trait_ . is_none ( ) ) ;
1157
+ let cache = & shared. cache ;
1158
+ let tcx = cx. tcx ( ) ;
1159
+ let av = if let TypeAliasItem ( ait) = & * containing_item. kind &&
1160
+ let aliased_clean_type = ait. item_type . as_ref ( ) . unwrap_or ( & ait. type_ ) &&
1161
+ let Some ( aliased_type_defid) = aliased_clean_type. def_id ( cache) &&
1162
+ let Some ( mut av) = cache. impls . get ( & aliased_type_defid) . cloned ( ) &&
1163
+ let Some ( alias_def_id) = containing_item. item_id . as_def_id ( )
1164
+ {
1165
+ // This branch of the compiler compares types structually, but does
1166
+ // not check trait bounds. That's probably fine, since type aliases
1167
+ // don't normally constrain on them anyway.
1168
+ // https://github.com/rust-lang/rust/issues/21903
1169
+ //
1170
+ // FIXME(lazy_type_alias): Once the feature is complete or stable, rewrite this to use type unification.
1171
+ // Be aware of `tests/rustdoc/issue-112515-impl-ty-alias.rs` which might regress.
1172
+ let aliased_ty = tcx. type_of ( alias_def_id) . skip_binder ( ) ;
1173
+ let reject_cx = DeepRejectCtxt {
1174
+ treat_obligation_params : TreatParams :: AsCandidateKey ,
1175
+ } ;
1176
+ av. retain ( |impl_| {
1177
+ if let Some ( impl_def_id) = impl_. impl_item . item_id . as_def_id ( ) {
1178
+ reject_cx. types_may_unify ( aliased_ty, tcx. type_of ( impl_def_id) . skip_binder ( ) )
1179
+ } else {
1180
+ false
1181
+ }
1182
+ } ) ;
1183
+ av
1184
+ } else {
1185
+ Vec :: new ( )
1186
+ } ;
1187
+ let blank = Vec :: new ( ) ;
1188
+ let v = cache. impls . get ( & it) . unwrap_or ( & blank) ;
1189
+ let ( non_trait, traits) : ( Vec < _ > , _ ) =
1190
+ v. iter ( ) . chain ( & av[ ..] ) . partition ( |i| i. inner_impl ( ) . trait_ . is_none ( ) ) ;
1159
1191
let mut saw_impls = FxHashSet :: default ( ) ;
1160
1192
if !non_trait. is_empty ( ) {
1161
1193
let mut tmp_buf = Buffer :: html ( ) ;
0 commit comments