@@ -15,7 +15,7 @@ use rustc_span::hygiene::MacroKind;
1515use rustc_span:: symbol:: { sym, Symbol } ;
1616use rustc_span:: Span ;
1717
18- use crate :: clean:: { self , GetDefId , ToSource , TypeKind } ;
18+ use crate :: clean:: { self , Attributes , GetDefId , ToSource , TypeKind } ;
1919use crate :: core:: DocContext ;
2020use crate :: doctree;
2121
@@ -35,8 +35,11 @@ type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>;
3535///
3636/// The returned value is `None` if the definition could not be inlined,
3737/// and `Some` of a vector of items if it was successfully expanded.
38+ ///
39+ /// `parent_module` refers to the parent of the *re-export*, not the original item.
3840pub fn try_inline (
3941 cx : & DocContext < ' _ > ,
42+ parent_module : DefId ,
4043 res : Res ,
4144 name : Symbol ,
4245 attrs : Option < Attrs < ' _ > > ,
@@ -48,12 +51,13 @@ pub fn try_inline(
4851 }
4952 let mut ret = Vec :: new ( ) ;
5053
54+ debug ! ( "attrs={:?}" , attrs) ;
5155 let attrs_clone = attrs;
5256
5357 let inner = match res {
5458 Res :: Def ( DefKind :: Trait , did) => {
5559 record_extern_fqn ( cx, did, clean:: TypeKind :: Trait ) ;
56- ret. extend ( build_impls ( cx, did, attrs) ) ;
60+ ret. extend ( build_impls ( cx, Some ( parent_module ) , did, attrs) ) ;
5761 clean:: TraitItem ( build_external_trait ( cx, did) )
5862 }
5963 Res :: Def ( DefKind :: Fn , did) => {
@@ -62,27 +66,27 @@ pub fn try_inline(
6266 }
6367 Res :: Def ( DefKind :: Struct , did) => {
6468 record_extern_fqn ( cx, did, clean:: TypeKind :: Struct ) ;
65- ret. extend ( build_impls ( cx, did, attrs) ) ;
69+ ret. extend ( build_impls ( cx, Some ( parent_module ) , did, attrs) ) ;
6670 clean:: StructItem ( build_struct ( cx, did) )
6771 }
6872 Res :: Def ( DefKind :: Union , did) => {
6973 record_extern_fqn ( cx, did, clean:: TypeKind :: Union ) ;
70- ret. extend ( build_impls ( cx, did, attrs) ) ;
74+ ret. extend ( build_impls ( cx, Some ( parent_module ) , did, attrs) ) ;
7175 clean:: UnionItem ( build_union ( cx, did) )
7276 }
7377 Res :: Def ( DefKind :: TyAlias , did) => {
7478 record_extern_fqn ( cx, did, clean:: TypeKind :: Typedef ) ;
75- ret. extend ( build_impls ( cx, did, attrs) ) ;
79+ ret. extend ( build_impls ( cx, Some ( parent_module ) , did, attrs) ) ;
7680 clean:: TypedefItem ( build_type_alias ( cx, did) , false )
7781 }
7882 Res :: Def ( DefKind :: Enum , did) => {
7983 record_extern_fqn ( cx, did, clean:: TypeKind :: Enum ) ;
80- ret. extend ( build_impls ( cx, did, attrs) ) ;
84+ ret. extend ( build_impls ( cx, Some ( parent_module ) , did, attrs) ) ;
8185 clean:: EnumItem ( build_enum ( cx, did) )
8286 }
8387 Res :: Def ( DefKind :: ForeignTy , did) => {
8488 record_extern_fqn ( cx, did, clean:: TypeKind :: Foreign ) ;
85- ret. extend ( build_impls ( cx, did, attrs) ) ;
89+ ret. extend ( build_impls ( cx, Some ( parent_module ) , did, attrs) ) ;
8690 clean:: ForeignTypeItem
8791 }
8892 // Never inline enum variants but leave them shown as re-exports.
@@ -117,7 +121,7 @@ pub fn try_inline(
117121 } ;
118122
119123 let target_attrs = load_attrs ( cx, did) ;
120- let attrs = merge_attrs ( cx, target_attrs, attrs_clone) ;
124+ let attrs = merge_attrs ( cx, Some ( parent_module ) , target_attrs, attrs_clone) ;
121125
122126 cx. renderinfo . borrow_mut ( ) . inlined . insert ( did) ;
123127 ret. push ( clean:: Item {
@@ -291,40 +295,52 @@ pub fn build_ty(cx: &DocContext<'_>, did: DefId) -> Option<clean::Type> {
291295}
292296
293297/// Builds all inherent implementations of an ADT (struct/union/enum) or Trait item/path/reexport.
294- pub fn build_impls ( cx : & DocContext < ' _ > , did : DefId , attrs : Option < Attrs < ' _ > > ) -> Vec < clean:: Item > {
298+ pub fn build_impls (
299+ cx : & DocContext < ' _ > ,
300+ parent_module : Option < DefId > ,
301+ did : DefId ,
302+ attrs : Option < Attrs < ' _ > > ,
303+ ) -> Vec < clean:: Item > {
295304 let tcx = cx. tcx ;
296305 let mut impls = Vec :: new ( ) ;
297306
298307 // for each implementation of an item represented by `did`, build the clean::Item for that impl
299308 for & did in tcx. inherent_impls ( did) . iter ( ) {
300- build_impl ( cx, did, attrs, & mut impls) ;
309+ build_impl ( cx, parent_module , did, attrs, & mut impls) ;
301310 }
302311
303312 impls
304313}
305314
315+ /// `parent_module` refers to the parent of the re-export, not the original item
306316fn merge_attrs (
307317 cx : & DocContext < ' _ > ,
308- attrs : Attrs < ' _ > ,
309- other_attrs : Option < Attrs < ' _ > > ,
318+ parent_module : Option < DefId > ,
319+ old_attrs : Attrs < ' _ > ,
320+ new_attrs : Option < Attrs < ' _ > > ,
310321) -> clean:: Attributes {
311322 // NOTE: If we have additional attributes (from a re-export),
312323 // always insert them first. This ensure that re-export
313324 // doc comments show up before the original doc comments
314325 // when we render them.
315- let merged_attrs = if let Some ( inner) = other_attrs {
316- let mut both = inner. to_vec ( ) ;
317- both. extend_from_slice ( attrs) ;
318- both
326+ if let Some ( inner) = new_attrs {
327+ if let Some ( new_id) = parent_module {
328+ let diag = cx. sess ( ) . diagnostic ( ) ;
329+ Attributes :: from_ast ( diag, old_attrs, Some ( ( inner, new_id) ) )
330+ } else {
331+ let mut both = inner. to_vec ( ) ;
332+ both. extend_from_slice ( old_attrs) ;
333+ both. clean ( cx)
334+ }
319335 } else {
320- attrs. to_vec ( )
321- } ;
322- merged_attrs. clean ( cx)
336+ old_attrs. clean ( cx)
337+ }
323338}
324339
325340/// Builds a specific implementation of a type. The `did` could be a type method or trait method.
326341pub fn build_impl (
327342 cx : & DocContext < ' _ > ,
343+ parent_module : impl Into < Option < DefId > > ,
328344 did : DefId ,
329345 attrs : Option < Attrs < ' _ > > ,
330346 ret : & mut Vec < clean:: Item > ,
@@ -333,7 +349,8 @@ pub fn build_impl(
333349 return ;
334350 }
335351
336- let attrs = merge_attrs ( cx, load_attrs ( cx, did) , attrs) ;
352+ let attrs = merge_attrs ( cx, parent_module. into ( ) , load_attrs ( cx, did) , attrs) ;
353+ debug ! ( "merged_attrs={:?}" , attrs) ;
337354
338355 let tcx = cx. tcx ;
339356 let associated_trait = tcx. impl_trait_ref ( did) ;
@@ -499,7 +516,9 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>)
499516 } ,
500517 ) ) ,
501518 } ) ;
502- } else if let Some ( i) = try_inline ( cx, item. res , item. ident . name , None , visited) {
519+ } else if let Some ( i) =
520+ try_inline ( cx, did, item. res , item. ident . name , None , visited)
521+ {
503522 items. extend ( i)
504523 }
505524 }
0 commit comments