Skip to content

Track partial_res_map per owner#159760

Open
oli-obk wants to merge 3 commits into
rust-lang:mainfrom
oli-obk:partial_res_map
Open

Track partial_res_map per owner#159760
oli-obk wants to merge 3 commits into
rust-lang:mainfrom
oli-obk:partial_res_map

Conversation

@oli-obk

@oli-obk oli-obk commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

cc rust-lang/rust-project-goals#620

r? @petrochenkov

Except for imports, everything using the partial_res_map in ast lowering works per-owner already. So, as a way to land this without a major refactoring, we turn all resolutions of path segments in use trees other than the first into Res::Err, which works just fine except for this one clippy lint.

Some background:

use statements are expanded from ast -> hir by flattening trees, so

use foo::bar::{baz, boo::{a, b}};

is turned into

use foo::bar::baz;
use foo::bar::boo::a;
use foo::bar::boo::b;

but the foo::bar part is only resolved in the first expanded import and the boo is only resolved in the second one (the one ending in a). On main the way this works out is that we ast->hir lower each of those paths for every expanded import by looking up the resolution again.

So when we start having per-owner maps, the second and third expanded import can't access the entry for foo anymore, as it's only available in the first map.

As discussed in #t-compiler > partial_res_map vs per-owner tables @ 💬, reworking the representation of use statements is entirely on the table. So I'm planning to just flatten the entire tree as we do today, but only have one owner (ItemKind::Use) and everything else just lives within that.

cc @bushrat011899 as a recent contributor to the clippy lint.

rustdoc and stability checking are unaffected, as the former uses import_res_map, and the latter still correctly reports on path segments via the first expansion of a use tree.

oli-obk added 3 commits July 23, 2026 08:48
still keep around the global map for within the resolver, but only forward the per-owner maps to ast lowering
They are not used anywhere, as we use the import_map everywhere for the actual resolutions. The import_map stores the resolution of the last segment of an import, the previous segments' resolution are only used within the resolver itself.
@rustbot

rustbot commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

clippy is developed in its own repository. If possible, consider making this change to rust-lang/rust-clippy instead.

cc @rust-lang/clippy

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 23, 2026
@bushrat011899

Copy link
Copy Markdown
Contributor

Interesting! I'm still getting my head around how the compiler works, so I'm not super confident I can say what the impact of this PR would be on the viability of this lint. But I do want to highlight I have an open PR for a total rewrite anyway to work directly with the use items instead of just the paths, since there was already issues with how multi imports were being handled. That PR is here. I'm not sure if that makes things better or worse, but I'd be happy to try and make my PR work with yours once it's merged.

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job aarch64-gnu-llvm-21-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
To only update this specific test, also pass `--test-args internal-lints/non_glob_import_of_type_ir_inherent.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/aarch64-unknown-linux-gnu/stage2" "--target=aarch64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/aarch64-unknown-linux-gnu/test/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent" "-A" "unused" "-W" "unused_attributes" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Crpath" "-Cdebuginfo=0" "-Z" "unstable-options"
stdout: none
--- stderr -------------------------------
error: non-glob import of `rustc_type_ir::inherent`
##[error]  --> /checkout/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs:16:9
   |
LL |     use rustc_type_ir::inherent::Predicate; //~ ERROR non-glob import of `rustc_type_ir::inherent`
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^---------
   |                                  |
   |                                  help: try using a glob import instead: `*`
   |
note: the lint level is defined here
---

error: non-glob import of `rustc_type_ir::inherent`
##[error]  --> /checkout/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs:20:9
   |
LL |     use rustc_type_ir::inherent::ParamEnv as _; //~ ERROR non-glob import of `rustc_type_ir::inherent`
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^-------------
   |                                  |
   |                                  help: try using a glob import instead: `*`

error: non-glob import of `rustc_type_ir::inherent`
##[error]  --> /checkout/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs:24:9
   |
LL |     use rustc_type_ir::inherent; //~ ERROR non-glob import of `rustc_type_ir::inherent`
   |         ^^^^^^^^^^^^^^^^^^^^^^^- help: try using a glob import instead: `::*`

error: non-glob import of `rustc_type_ir::inherent`
##[error]  --> /checkout/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs:25:9
   |
LL |     use rustc_type_ir::inherent as inh; //~ ERROR non-glob import of `rustc_type_ir::inherent`
   |         ^^^^^^^^^^^^^^^^^^^^^^^------- help: try using a glob import instead: `::*`

error: non-glob import of `rustc_type_ir::inherent`
##[error]  --> /checkout/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs:26:25
   |
LL |     use rustc_type_ir::{inherent as _}; //~ ERROR non-glob import of `rustc_type_ir::inherent`
   |                         ^^^^^^^^----- help: try using a glob import instead: `::*`

error: non-glob import of `rustc_type_ir::inherent`
##[error]  --> /checkout/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs:33:35
   |
LL |     use rustc_type_ir::inherent::{self}; //~ ERROR non-glob import of `rustc_type_ir::inherent`
   |                                   ^^^^ help: try using a glob import instead: `*`

error: non-glob import of `rustc_type_ir::inherent`
##[error]  --> /checkout/tests/ui-fulldeps/internal-lints/non_glob_import_of_type_ir_inherent.rs:34:35
   |
LL |     use rustc_type_ir::inherent::{self as innate}; //~ ERROR non-glob import of `rustc_type_ir::inherent`
   |                                   ^^^^----------
   |                                   |
   |                                   help: try using a glob import instead: `*`

error: aborting due to 8 previous errors

@Jarcho

Jarcho commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

The clippy lint only needs each segment to have a resolution the first time it appears. Are the HirIds of the shared path segments identical? If not we can always use the span which would only break with some pretty horrendous macros.

So I'm planning to just flatten the entire tree as we do today, but only have one owner (ItemKind::Use) and everything else just lives within that.

You mean to put the whole use foo::{bar, baz} under a single item instead of multiple like it currently is? That would be much nicer to deal with for the lints in question.

@oli-obk

oli-obk commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

The hir ids are different. Only the node ids are shared. But as you saw, even a rustc internal lint is having this problem. So I will have to see if I can get the information preserved in some manner

@petrochenkov

Copy link
Copy Markdown
Contributor

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jul 23, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Jul 23, 2026
Track `partial_res_map` per owner
@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 23, 2026
@rust-bors

rust-bors Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 30ec28b (30ec28bd9d7faa57972a041a14355b364ade29ff)
Base parent: 390279b (390279b302ca98ae270f434100ae3730531d1246)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (30ec28b): comparison URL.

Overall result: ❌ regressions - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@bors rollup=never rustc-perf
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.5% [0.2%, 1.2%] 160
Regressions ❌
(secondary)
0.5% [0.1%, 1.1%] 77
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.5% [0.2%, 1.2%] 160

Max RSS (memory usage)

Results (primary 1.8%, secondary 0.7%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
1.8% [0.4%, 4.4%] 48
Regressions ❌
(secondary)
2.2% [0.8%, 6.3%] 18
Improvements ✅
(primary)
-0.5% [-0.5%, -0.5%] 1
Improvements ✅
(secondary)
-3.2% [-6.5%, -0.5%] 7
All ❌✅ (primary) 1.8% [-0.5%, 4.4%] 49

Cycles

Results (primary -2.4%, secondary 2.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.9% [2.0%, 4.0%] 7
Improvements ✅
(primary)
-2.4% [-2.4%, -2.4%] 1
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) -2.4% [-2.4%, -2.4%] 1

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: 486.724s -> 489.686s (0.61%)
Artifact size: 387.61 MiB -> 389.76 MiB (0.56%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

perf-regression Performance regression. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants