Skip to content

Commit

Permalink
Move rustdoc::clean::utils::find_nearest_parent_module to TyCtxt
Browse files Browse the repository at this point in the history
`find_nearest_parent_module` was extracted from
`rustdoc::passes::collect_intra_doc_links` in rust-lang#80368.

We (me and Joshua Nelson) thought at the time that it should be in rustc
instead, and Joshua suggested it be a method on `TyCtxt`.
However, since rust-lang#80368 was fixing a significant regression that was about
to land on beta, we agreed that to be able to fix this quickly I should
leave the code in rustdoc.

This is a followup PR to move it to `TyCtxt`.
  • Loading branch information
camelid committed Jan 6, 2021
1 parent da305a2 commit 859a707
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 31 deletions.
27 changes: 27 additions & 0 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,33 @@ impl<'tcx> TyCtxt<'tcx> {
)
}

/// Find the nearest parent module of a [`DefId`].
/// This is different from [`TyCtxt::parent()`] because this returns
/// the nearest parent `mod`, whereas [`TyCtxt::parent()`] returns
/// the nearest module-like item (e.g., the enum that a variant belongs to).
///
/// Returns `def_id` if it's the crate root.
///
/// Note for users in rustdoc: **panics if the item it belongs to is fake**
/// (see `rustdoc::clean::types::Item::is_fake()`).
pub fn find_nearest_parent_module(self, def_id: DefId) -> Option<DefId> {
if def_id.is_top_level_module() {
// The crate root has no parent. Use it as the root instead.
Some(def_id)
} else {
let mut current = def_id;
// The immediate parent might not always be a module.
// Find the first parent which is.
while let Some(parent) = self.parent(current) {
if self.def_kind(parent) == DefKind::Mod {
return Some(parent);
}
current = parent;
}
None
}
}

pub fn metadata_encoding_version(self) -> Vec<u8> {
self.cstore.metadata_encoding_version().to_vec()
}
Expand Down
23 changes: 1 addition & 22 deletions src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::mir::interpret::ConstValue;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
use rustc_middle::ty::{self, DefIdTree, Ty};
use rustc_span::symbol::{kw, sym, Symbol};
use std::mem;

Expand Down Expand Up @@ -623,24 +623,3 @@ where
*cx.impl_trait_bounds.borrow_mut() = old_bounds;
r
}

/// Find the nearest parent module of a [`DefId`].
///
/// **Panics if the item it belongs to [is fake][Item::is_fake].**
crate fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
if def_id.is_top_level_module() {
// The crate root has no parent. Use it as the root instead.
Some(def_id)
} else {
let mut current = def_id;
// The immediate parent might not always be a module.
// Find the first parent which is.
while let Some(parent) = tcx.parent(current) {
if tcx.def_kind(parent) == DefKind::Mod {
return Some(parent);
}
current = parent;
}
None
}
}
6 changes: 3 additions & 3 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
use rustc_target::spec::abi::Abi;

use crate::clean::{self, utils::find_nearest_parent_module, PrimitiveType};
use crate::clean::{self, PrimitiveType};
use crate::formats::cache::cache;
use crate::formats::item_type::ItemType;
use crate::html::escape::Escape;
Expand Down Expand Up @@ -1100,7 +1100,7 @@ impl clean::Visibility {
// FIXME(camelid): This may not work correctly if `item_did` is a module.
// However, rustdoc currently never displays a module's
// visibility, so it shouldn't matter.
let parent_module = find_nearest_parent_module(tcx, item_did);
let parent_module = tcx.find_nearest_parent_module(item_did);

if vis_did.index == CRATE_DEF_INDEX {
write!(f, "pub(crate) ")
Expand All @@ -1109,7 +1109,7 @@ impl clean::Visibility {
// is the same as no visibility modifier
Ok(())
} else if parent_module
.map(|parent| find_nearest_parent_module(tcx, parent))
.map(|parent| tcx.find_nearest_parent_module(parent))
.flatten()
== Some(vis_did)
{
Expand Down
9 changes: 3 additions & 6 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use std::convert::{TryFrom, TryInto};
use std::mem;
use std::ops::Range;

use crate::clean::{self, utils::find_nearest_parent_module, Crate, Item, ItemLink, PrimitiveType};
use crate::clean::{self, Crate, Item, ItemLink, PrimitiveType};
use crate::core::DocContext;
use crate::fold::DocFolder;
use crate::html::markdown::{markdown_links, MarkdownLink};
Expand Down Expand Up @@ -832,11 +832,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
fn fold_item(&mut self, mut item: Item) -> Option<Item> {
use rustc_middle::ty::DefIdTree;

let parent_node = if item.is_fake() {
None
} else {
find_nearest_parent_module(self.cx.tcx, item.def_id)
};
let parent_node =
if item.is_fake() { None } else { self.cx.tcx.find_nearest_parent_module(item.def_id) };

if parent_node.is_some() {
trace!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id);
Expand Down

0 comments on commit 859a707

Please sign in to comment.