Overhaul UsePath.
`UsePath` contains a `SmallVec<[Res; 3]>`. This holds up to three `Res` results, one per namespace (type, value, or macro). `lower_import_res` takes a `PerNS<Option<Res<NodeId>>>` result and lowers it into the `SmallVec`. This is pretty weird. The input `PerNS` makes it clear which `Res` belongs to which namespace, but the `SmallVec` throws that information away. And code that operates on the `SmallVec` tends to use iteration (or even just grabbing the first entry!) without knowing which namespace the `Res` belongs to. Even weirder! Also, `SmallVec` is an overly flexible type to use here, because it can contain any number of elements (even though it's optimized for 3 in this case). This commit changes `UsePath` so it also contains a `PerNS<Option<Res<HirId>>>`. This type preserves more information and is more self-documenting. The commit also changes a lot of the use sites to access the result for a particular namespace. E.g. if you're looking up a trait, it will be in the `Res` for the type namespace if it's present; it's silly to look in the `Res` for the value namespace or macro namespace. Overall I find the new code much easier to understand. However, some use sites still iterate. These now use `present_items` because that filters out the `None` results. Also, `redundant_pub_crate.rs` gets a bigger change. A `UseKind:ListStem` item gets no `Res` results, which means the old `all` call in `is_not_macro_export` would succeed (because `all` succeeds on an empty iterator) and the `ListStem` would be ignored. This is what we want, but was more by luck than design. The new code detects `ListStem` explicitly. The commit generalizes the name of that function accordingly. Finally, the commit also removes the `use_path` arena, because `PerNS<Option<Res>>` impls `Copy` (unlike `SmallVec`) and it can be allocated in the arena shared by all `Copy` types.
This commit is contained in:
parent
176c34a946
commit
8747ccbcdf
23 changed files with 112 additions and 86 deletions
|
|
@ -1606,7 +1606,7 @@ fn first_non_private<'tcx>(
|
|||
&& let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(local_use_def_id)
|
||||
&& let hir::ItemKind::Use(path, hir::UseKind::Single(_)) = item.kind
|
||||
{
|
||||
for res in &path.res {
|
||||
for res in path.res.present_items() {
|
||||
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -3014,7 +3014,7 @@ fn clean_use_statement<'tcx>(
|
|||
) -> Vec<Item> {
|
||||
let mut items = Vec::new();
|
||||
let hir::UsePath { segments, ref res, span } = *path;
|
||||
for &res in res {
|
||||
for res in res.present_items() {
|
||||
let path = hir::Path { segments, res, span };
|
||||
items.append(&mut clean_use_statement_inner(import, name, &path, kind, cx, inlined_names));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -440,7 +440,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
hir::ItemKind::GlobalAsm { .. } => {}
|
||||
hir::ItemKind::Use(_, hir::UseKind::ListStem) => {}
|
||||
hir::ItemKind::Use(path, kind) => {
|
||||
for &res in &path.res {
|
||||
for res in path.res.present_items() {
|
||||
// Struct and variant constructors and proc macro stubs always show up alongside
|
||||
// their definitions, we've already processed them so just discard these.
|
||||
if should_ignore_res(res) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue