Skip to content

fix: update import resolutions after macro expansion - #22934

Open
dhl wants to merge 1 commit into
rust-lang:masterfrom
blueshift-gg:fix/import-resolution-after-macro-expansion
Open

fix: update import resolutions after macro expansion#22934
dhl wants to merge 1 commit into
rust-lang:masterfrom
blueshift-gg:fix/import-resolution-after-macro-expansion

Conversation

@dhl

@dhl dhl commented Jul 27, 2026

Copy link
Copy Markdown

When a macro expansion adds a definition that shadows a glob-imported name, use super::fn imports in submodules would not resolve to the new definition.

This had two causes: the import re-resolution compared only namespace occupancy, missing def changes that didn't affect which namespaces were populated; and the scope update would only overwrite entries that originated from glob imports, missing re-resolutions of the same import to a different def.

The re-resolution now makes full resolved definition comparison, and the scope update allows overwriting an entry that carries the same import source.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 27, 2026
@dhl
dhl marked this pull request as draft July 27, 2026 19:04
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 27, 2026
@ChayimFriedman2

Copy link
Copy Markdown
Contributor

This seems like a duplicate of #22886, and what I said there applies here too:

Without looking at the code yet, name resolution in Rust is an extremely complicated process (and we definitely don't have extensive enough testing for it). Unfortunately, I don't think we can allow a (non-trivial) patch to it to be written by AI by someone that does not know it and the r-a codebase well enough - it's just too easy to miss something.

@dhl
dhl force-pushed the fix/import-resolution-after-macro-expansion branch 2 times, most recently from f23155b to 9c41114 Compare July 27, 2026 23:59
When a macro expansion adds a definition that shadows a glob-imported
name, `use super::fn` imports in submodules would not resolve to the
new definition.

This had two causes: the import re-resolution compared only namespace
occupancy, missing def changes that didn't affect which namespaces
were populated; and the scope update would only overwrite entries that
originated from glob imports, missing re-resolutions of the same import
to a different def.

The re-resolution now makes full resolved definition comparison, and
the scope update allows overwriting an entry that carries the same
import source.
@dhl
dhl force-pushed the fix/import-resolution-after-macro-expansion branch from 9c41114 to 8d68bba Compare July 28, 2026 00:02
@dhl
dhl marked this pull request as ready for review July 28, 2026 18:09
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jul 28, 2026
@dhl

dhl commented Jul 28, 2026

Copy link
Copy Markdown
Author

@ChayimFriedman2 Thanks for the note.

I understand the caution around name resolution. The resolution code is nuanced and under-tested, which is exactly why I had spent several days tracing through the collector and item_scope paths and doing case analysis before opening this.

This PR is related to but not a duplicate of #22886; my fix is a superset of theirs, as they did not address the namespaces availability check issue. Indeed, the macro expansion bug that my fix addresses is still reproducible against #22886, but my fix also covers their bug.

// still reproducible against #22886 

mod other {
    pub fn foo(z: u8) -> u8 { z }
}

use other::*;

// the glob version DOES get shadowed properly if the
// pass-through macro was removed
#[shadow::shadow]
pub fn foo(a: u8, b: u8) -> u8 { a + b }

pub fn call_direct() {
    foo(1, 2); //works
}

pub mod via_use_import {
    use super::foo;

    pub fn call() {
        foo(1, 2);  // ← E0107: expected 1 argument, found 2
    }
}

pub mod via_path_call {
    pub fn call() {
        super::foo(1, 2);  // works
    }
}

The root causes of the bugs boil down to 2 issues in the current resolution process:

  1. re-resolution only compared namespace occupancy (which is what the availability check did), so a change of definition that did not alter occupancy did not trigger the update;

  2. the scope update refused to overwrite an entry unless it originated from a glob, even when the import source was the same.

I deliberately kept the change narrow, allowing just enough additional resolutions updates to cover the above 2 cases, to limit the impact to the rest of the name resolution process.

Happy to walk through the analysis or add further tests if that would help.

I would appreciate it if someone could look at the actual code before this is closed.

@ChayimFriedman2

Copy link
Copy Markdown
Contributor

Do you use AI to author your GitHub comments? This is explicitly forbidden by our AI policy, and also makes me suspect the fix itself was also AI-authored. They at least disclosed their AI usage.

@dhl

dhl commented Jul 28, 2026

Copy link
Copy Markdown
Author

I don't. My team are contributors to rustc as well, and we are aware of the policies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants