diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-05-30 01:37:48 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2025-06-03 08:23:21 +1000 |
| commit | 8747ccbcdf54fe8227e10bc2584f3e9a2fee9103 (patch) | |
| tree | 3ca55070770fde8d544324c2910d46a441499a81 /src/tools/clippy/clippy_utils | |
| parent | 176c34a946df6b096cc2bce19c477fd49c0c9a09 (diff) | |
| download | rust-8747ccbcdf54fe8227e10bc2584f3e9a2fee9103.tar.gz rust-8747ccbcdf54fe8227e10bc2584f3e9a2fee9103.zip | |
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.
Diffstat (limited to 'src/tools/clippy/clippy_utils')
| -rw-r--r-- | src/tools/clippy/clippy_utils/src/paths.rs | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs index 9d7f3086b05..f37a609497e 100644 --- a/src/tools/clippy/clippy_utils/src/paths.rs +++ b/src/tools/clippy/clippy_utils/src/paths.rs @@ -306,10 +306,13 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n let item = tcx.hir_item(item_id); if let ItemKind::Use(path, UseKind::Single(ident)) = item.kind { if ident.name == name { - path.res - .iter() - .find(|res| ns.matches(res.ns())) - .and_then(Res::opt_def_id) + let opt_def_id = |ns: Option<Res>| ns.and_then(|res| res.opt_def_id()); + match ns { + PathNS::Type => opt_def_id(path.res.type_ns), + PathNS::Value => opt_def_id(path.res.value_ns), + PathNS::Macro => opt_def_id(path.res.macro_ns), + PathNS::Arbitrary => unreachable!(), + } } else { None } |
