@@ -29,8 +29,6 @@ use clean::{
2929 self ,
3030 GetDefId ,
3131 ToSource ,
32- get_auto_traits_with_def_id,
33- get_blanket_impls_with_def_id,
3432} ;
3533
3634use super :: Clean ;
@@ -56,7 +54,7 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa
5654 let inner = match def {
5755 Def :: Trait ( did) => {
5856 record_extern_fqn ( cx, did, clean:: TypeKind :: Trait ) ;
59- ret. extend ( build_impls ( cx, did, false ) ) ;
57+ ret. extend ( build_impls ( cx, did) ) ;
6058 clean:: TraitItem ( build_external_trait ( cx, did) )
6159 }
6260 Def :: Fn ( did) => {
@@ -65,27 +63,27 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa
6563 }
6664 Def :: Struct ( did) => {
6765 record_extern_fqn ( cx, did, clean:: TypeKind :: Struct ) ;
68- ret. extend ( build_impls ( cx, did, true ) ) ;
66+ ret. extend ( build_impls ( cx, did) ) ;
6967 clean:: StructItem ( build_struct ( cx, did) )
7068 }
7169 Def :: Union ( did) => {
7270 record_extern_fqn ( cx, did, clean:: TypeKind :: Union ) ;
73- ret. extend ( build_impls ( cx, did, true ) ) ;
71+ ret. extend ( build_impls ( cx, did) ) ;
7472 clean:: UnionItem ( build_union ( cx, did) )
7573 }
7674 Def :: TyAlias ( did) => {
7775 record_extern_fqn ( cx, did, clean:: TypeKind :: Typedef ) ;
78- ret. extend ( build_impls ( cx, did, false ) ) ;
76+ ret. extend ( build_impls ( cx, did) ) ;
7977 clean:: TypedefItem ( build_type_alias ( cx, did) , false )
8078 }
8179 Def :: Enum ( did) => {
8280 record_extern_fqn ( cx, did, clean:: TypeKind :: Enum ) ;
83- ret. extend ( build_impls ( cx, did, true ) ) ;
81+ ret. extend ( build_impls ( cx, did) ) ;
8482 clean:: EnumItem ( build_enum ( cx, did) )
8583 }
8684 Def :: ForeignTy ( did) => {
8785 record_extern_fqn ( cx, did, clean:: TypeKind :: Foreign ) ;
88- ret. extend ( build_impls ( cx, did, false ) ) ;
86+ ret. extend ( build_impls ( cx, did) ) ;
8987 clean:: ForeignTypeItem
9088 }
9189 // Never inline enum variants but leave them shown as re-exports.
@@ -159,12 +157,11 @@ pub fn load_attrs(cx: &DocContext, did: DefId) -> clean::Attributes {
159157/// These names are used later on by HTML rendering to generate things like
160158/// source links back to the original item.
161159pub fn record_extern_fqn ( cx : & DocContext , did : DefId , kind : clean:: TypeKind ) {
160+ let mut crate_name = cx. tcx . crate_name ( did. krate ) . to_string ( ) ;
162161 if did. is_local ( ) {
163- debug ! ( "record_extern_fqn(did={:?}, kind+{:?}): def_id is local, aborting" , did, kind) ;
164- return ;
162+ crate_name = cx. crate_name . clone ( ) . unwrap_or ( crate_name) ;
165163 }
166164
167- let crate_name = cx. tcx . crate_name ( did. krate ) . to_string ( ) ;
168165 let relative = cx. tcx . def_path ( did) . data . into_iter ( ) . filter_map ( |elem| {
169166 // extern blocks have an empty name
170167 let s = elem. data . to_string ( ) ;
@@ -179,7 +176,12 @@ pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
179176 } else {
180177 once ( crate_name) . chain ( relative) . collect ( )
181178 } ;
182- cx. renderinfo . borrow_mut ( ) . external_paths . insert ( did, ( fqn, kind) ) ;
179+
180+ if did. is_local ( ) {
181+ cx. renderinfo . borrow_mut ( ) . exact_paths . insert ( did, fqn) ;
182+ } else {
183+ cx. renderinfo . borrow_mut ( ) . external_paths . insert ( did, ( fqn, kind) ) ;
184+ }
183185}
184186
185187pub fn build_external_trait ( cx : & DocContext , did : DefId ) -> clean:: Trait {
@@ -271,93 +273,14 @@ fn build_type_alias(cx: &DocContext, did: DefId) -> clean::Typedef {
271273 }
272274}
273275
274- pub fn build_impls ( cx : & DocContext , did : DefId , auto_traits : bool ) -> Vec < clean:: Item > {
276+ pub fn build_impls ( cx : & DocContext , did : DefId ) -> Vec < clean:: Item > {
275277 let tcx = cx. tcx ;
276278 let mut impls = Vec :: new ( ) ;
277279
278280 for & did in tcx. inherent_impls ( did) . iter ( ) {
279281 build_impl ( cx, did, & mut impls) ;
280282 }
281283
282- if auto_traits {
283- let auto_impls = get_auto_traits_with_def_id ( cx, did) ;
284- {
285- let mut renderinfo = cx. renderinfo . borrow_mut ( ) ;
286- let new_impls: Vec < clean:: Item > = auto_impls. into_iter ( )
287- . filter ( |i| renderinfo. inlined . insert ( i. def_id ) ) . collect ( ) ;
288-
289- impls. extend ( new_impls) ;
290- }
291- impls. extend ( get_blanket_impls_with_def_id ( cx, did) ) ;
292- }
293-
294- // If this is the first time we've inlined something from another crate, then
295- // we inline *all* impls from all the crates into this crate. Note that there's
296- // currently no way for us to filter this based on type, and we likely need
297- // many impls for a variety of reasons.
298- //
299- // Primarily, the impls will be used to populate the documentation for this
300- // type being inlined, but impls can also be used when generating
301- // documentation for primitives (no way to find those specifically).
302- if cx. populated_all_crate_impls . get ( ) {
303- return impls;
304- }
305-
306- cx. populated_all_crate_impls . set ( true ) ;
307-
308- for & cnum in tcx. crates ( ) . iter ( ) {
309- for did in tcx. all_trait_implementations ( cnum) . iter ( ) {
310- build_impl ( cx, * did, & mut impls) ;
311- }
312- }
313-
314- // Also try to inline primitive impls from other crates.
315- let lang_items = tcx. lang_items ( ) ;
316- let primitive_impls = [
317- lang_items. isize_impl ( ) ,
318- lang_items. i8_impl ( ) ,
319- lang_items. i16_impl ( ) ,
320- lang_items. i32_impl ( ) ,
321- lang_items. i64_impl ( ) ,
322- lang_items. i128_impl ( ) ,
323- lang_items. usize_impl ( ) ,
324- lang_items. u8_impl ( ) ,
325- lang_items. u16_impl ( ) ,
326- lang_items. u32_impl ( ) ,
327- lang_items. u64_impl ( ) ,
328- lang_items. u128_impl ( ) ,
329- lang_items. f32_impl ( ) ,
330- lang_items. f64_impl ( ) ,
331- lang_items. f32_runtime_impl ( ) ,
332- lang_items. f64_runtime_impl ( ) ,
333- lang_items. char_impl ( ) ,
334- lang_items. str_impl ( ) ,
335- lang_items. slice_impl ( ) ,
336- lang_items. slice_u8_impl ( ) ,
337- lang_items. str_alloc_impl ( ) ,
338- lang_items. slice_alloc_impl ( ) ,
339- lang_items. slice_u8_alloc_impl ( ) ,
340- lang_items. const_ptr_impl ( ) ,
341- lang_items. mut_ptr_impl ( ) ,
342- ] ;
343-
344- for def_id in primitive_impls. iter ( ) . filter_map ( |& def_id| def_id) {
345- if !def_id. is_local ( ) {
346- build_impl ( cx, def_id, & mut impls) ;
347-
348- let auto_impls = get_auto_traits_with_def_id ( cx, def_id) ;
349- let blanket_impls = get_blanket_impls_with_def_id ( cx, def_id) ;
350- let mut renderinfo = cx. renderinfo . borrow_mut ( ) ;
351-
352- let new_impls: Vec < clean:: Item > = auto_impls. into_iter ( )
353- . chain ( blanket_impls. into_iter ( ) )
354- . filter ( |i| renderinfo. inlined . insert ( i. def_id ) )
355- . collect ( ) ;
356-
357- impls. extend ( new_impls) ;
358- }
359- }
360-
361284 impls
362285}
363286
@@ -372,30 +295,60 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
372295
373296 // Only inline impl if the implemented trait is
374297 // reachable in rustdoc generated documentation
375- if let Some ( traitref) = associated_trait {
376- if !cx. access_levels . borrow ( ) . is_doc_reachable ( traitref. def_id ) {
377- return
298+ if !did. is_local ( ) {
299+ if let Some ( traitref) = associated_trait {
300+ if !cx. renderinfo . borrow ( ) . access_levels . is_doc_reachable ( traitref. def_id ) {
301+ return
302+ }
378303 }
379304 }
380305
381- let for_ = tcx. type_of ( did) . clean ( cx) ;
306+ let for_ = if let Some ( nodeid) = tcx. hir . as_local_node_id ( did) {
307+ match tcx. hir . expect_item ( nodeid) . node {
308+ hir:: ItemKind :: Impl ( .., ref t, _) => {
309+ t. clean ( cx)
310+ }
311+ _ => panic ! ( "did given to build_impl was not an impl" ) ,
312+ }
313+ } else {
314+ tcx. type_of ( did) . clean ( cx)
315+ } ;
382316
383317 // Only inline impl if the implementing type is
384318 // reachable in rustdoc generated documentation
385- if let Some ( did) = for_. def_id ( ) {
386- if !cx. access_levels . borrow ( ) . is_doc_reachable ( did) {
387- return
319+ if !did. is_local ( ) {
320+ if let Some ( did) = for_. def_id ( ) {
321+ if !cx. renderinfo . borrow ( ) . access_levels . is_doc_reachable ( did) {
322+ return
323+ }
388324 }
389325 }
390326
391327 let predicates = tcx. predicates_of ( did) ;
392- let trait_items = tcx. associated_items ( did) . filter_map ( |item| {
393- if associated_trait. is_some ( ) || item. vis == ty:: Visibility :: Public {
394- Some ( item. clean ( cx) )
395- } else {
396- None
328+ let ( trait_items, generics) = if let Some ( nodeid) = tcx. hir . as_local_node_id ( did) {
329+ match tcx. hir . expect_item ( nodeid) . node {
330+ hir:: ItemKind :: Impl ( .., ref gen, _, _, ref item_ids) => {
331+ (
332+ item_ids. iter ( )
333+ . map ( |ii| tcx. hir . impl_item ( ii. id ) . clean ( cx) )
334+ . collect :: < Vec < _ > > ( ) ,
335+ gen. clean ( cx) ,
336+ )
337+ }
338+ _ => panic ! ( "did given to build_impl was not an impl" ) ,
397339 }
398- } ) . collect :: < Vec < _ > > ( ) ;
340+ } else {
341+ (
342+ tcx. associated_items ( did) . filter_map ( |item| {
343+ if associated_trait. is_some ( ) || item. vis == ty:: Visibility :: Public {
344+ Some ( item. clean ( cx) )
345+ } else {
346+ None
347+ }
348+ } ) . collect :: < Vec < _ > > ( ) ,
349+ ( tcx. generics_of ( did) , & predicates) . clean ( cx) ,
350+ )
351+ } ;
399352 let polarity = tcx. impl_polarity ( did) ;
400353 let trait_ = associated_trait. clean ( cx) . map ( |bound| {
401354 match bound {
@@ -417,10 +370,12 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
417370 . collect ( )
418371 } ) . unwrap_or ( FxHashSet ( ) ) ;
419372
373+ debug ! ( "build_impl: impl {:?} for {:?}" , trait_. def_id( ) , for_. def_id( ) ) ;
374+
420375 ret. push ( clean:: Item {
421376 inner : clean:: ImplItem ( clean:: Impl {
422377 unsafety : hir:: Unsafety :: Normal ,
423- generics : ( tcx . generics_of ( did ) , & predicates ) . clean ( cx ) ,
378+ generics,
424379 provided_trait_methods : provided,
425380 trait_,
426381 for_,
@@ -465,7 +420,11 @@ fn build_module(cx: &DocContext, did: DefId, visited: &mut FxHashSet<DefId>) ->
465420}
466421
467422pub fn print_inlined_const ( cx : & DocContext , did : DefId ) -> String {
468- cx. tcx . rendered_const ( did)
423+ if let Some ( node_id) = cx. tcx . hir . as_local_node_id ( did) {
424+ cx. tcx . hir . node_to_pretty_string ( node_id)
425+ } else {
426+ cx. tcx . rendered_const ( did)
427+ }
469428}
470429
471430fn build_const ( cx : & DocContext , did : DefId ) -> clean:: Constant {
@@ -576,16 +535,27 @@ fn separate_supertrait_bounds(mut g: clean::Generics)
576535}
577536
578537pub fn record_extern_trait ( cx : & DocContext , did : DefId ) {
579- if cx. external_traits . borrow ( ) . contains_key ( & did) ||
580- cx. active_extern_traits . borrow ( ) . contains ( & did)
581- {
538+ if did. is_local ( ) {
582539 return ;
583540 }
584541
542+ {
543+ let external_traits = cx. external_traits . lock ( ) ;
544+ if external_traits. borrow ( ) . contains_key ( & did) ||
545+ cx. active_extern_traits . borrow ( ) . contains ( & did)
546+ {
547+ return ;
548+ }
549+ }
550+
585551 cx. active_extern_traits . borrow_mut ( ) . push ( did) ;
586552
553+ debug ! ( "record_extern_trait: {:?}" , did) ;
587554 let trait_ = build_external_trait ( cx, did) ;
588555
589- cx. external_traits . borrow_mut ( ) . insert ( did, trait_) ;
556+ {
557+ let external_traits = cx. external_traits . lock ( ) ;
558+ external_traits. borrow_mut ( ) . insert ( did, trait_) ;
559+ }
590560 cx. active_extern_traits . borrow_mut ( ) . remove_item ( & did) ;
591561}
0 commit comments