Code change:
When running with the above code, the docs list the following items: <details<summaryDocs</summary </detailsI would expect to be listed as a reexport, not a struct. The way it is now, it looks like and are different types, which is not the case. If is made , everything looks as it's supposed to. label +T-rustdoc
It's the intended behaviour. Since the module is private, is inlining the item into .
Yes, but is public, so should it really be inlined a second time?
Ok sorry I misunderstood what you meant. No, it shouldn't be inlined a second time.

Related discussion:
text: BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params } } <del> /// This visitor is used to go through only the "top level" of a item and not enter any sub /// item while looking for a given `Ident` which is stored into `item` if found. struct OneLevelVisitor<'hir> { </del> <ins> /// Get DefId of of an item's user-visible parent. /// /// "User-visible" should account for re-exporting and inlining, which is why this function isn't /// just `tcx.parent(def_id)`. If the provided `path` has more than one path element, the `DefId` /// of the second-to-last will be given. /// /// ```text /// use crate::foo::Bar; ///            ^^^ DefId of this item will be returned /// ``` /// /// If the provided path has only one item, `tcx.parent(def_id)` will be returned instead. fn get_path_parent_def_id( tcx: TyCtxt<'_>, def_id: DefId, path: &hir::UsePath<'_>, ) -> Option<DefId> { if let [.., parent_segment, _] = &path.segments { match parent_segment.res { hir::def::Res::Def(_, parent_def_id) => Some(parent_def_id), _ if parent_segment.ident.name == kw::Crate => { // In case the "parent" is the crate, it'll give `Res::Err` so we need to // circumvent it this way. Some(tcx.parent(def_id)) } _ => None, } } else { // If the path doesn't have a parent, then the parent is the current module. Some(tcx.parent(def_id)) } } /// This visitor is used to find an HIR Item based on its `use` path. This doesn't use the ordinary /// name resolver because it does not walk all the way through a chain of re-exports. pub(crate) struct OneLevelVisitor<'hir> { </ins> map: rustc_middle::hir::map::Map<'hir>, <del> item: Option<&'hir hir::Item<'hir>>, </del> <ins> pub(crate) item: Option<&'hir hir::Item<'hir>>, </ins> looking_for: Ident, target_def_id: LocalDefId, } impl<'hir> OneLevelVisitor<'hir> { <del> fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self { </del> <ins> pub(crate) fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self { </ins> Self { map, item: None, looking_for: Ident::empty(), target_def_id } } <del> fn reset(&mut self, looking_for: Ident) { self.looking_for = looking_for; </del> <ins> pub(crate) fn find_target( &mut self, tcx: TyCtxt<'_>, def_id: DefId, path: &hir::UsePath<'_>, ) -> Option<&'hir hir::Item<'hir>> { let parent_def_id = get_path_parent_def_id(tcx, def_id, path)?; let parent = self.map.get_if_local(parent_def_id)?; // We get the `Ident` we will be looking for into `item`. self.looking_for = path.segments[path.segments.len() - 1].ident; // We reset the `item`. </ins> self.item = None; <ins> match parent { hir::Node::Item(parent_item) => { hir::intravisit::walk_item(self, parent_item); } hir::Node::Crate(m) => { hir::intravisit::walk_mod( self, m, tcx.local_def_id_to_hir_id(parent_def_id.as_local().unwrap()), ); } _ => return None, } self.item </ins> } }