Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve external preludes for modules inside blocks #17057

Closed
roife opened this issue Apr 13, 2024 · 4 comments 路 Fixed by #17251
Closed

Resolve external preludes for modules inside blocks #17057

roife opened this issue Apr 13, 2024 · 4 comments 路 Fixed by #17251
Labels
A-nameres name, path and module resolution C-bug Category: bug

Comments

@roife
Copy link
Contributor

roife commented Apr 13, 2024

The original issue was closed by the bot 馃槄, but we need to resolve this problem.

          Looks like we fail to resolve the extern prelude in local modules in block modules, it works fine if the `mod cs` is at the top-level (not nested inside a function or anything)
fn main() {
    mod f {
        use core as _;
    }
}
          here `core` does not resolve

Originally posted in #17032 (comment)

@roife
Copy link
Contributor Author

roife commented Apr 13, 2024

Sorry... I open the issue with reference in new issue, and am unable to add the bug label to this issue. 馃槼


I added self.inject_prelude(); in

fn seed_with_inner(&mut self, tree_id: TreeId) {
let item_tree = tree_id.item_tree(self.db);
let is_cfg_enabled = item_tree
.top_level_attrs(self.db, self.def_map.krate)
.cfg()
.map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false));
if is_cfg_enabled {
ModCollector {
def_collector: self,
macro_depth: 0,
module_id: DefMap::ROOT,
tree_id,
item_tree: &item_tree,
mod_dir: ModDir::root(),
}
.collect_in_top_module(item_tree.top_level_items());
}
}
, removed
if self.block.is_some() {
// Don't resolve extern prelude in block `DefMap`s, defer it to the crate def map so
// that blocks can properly shadow them
return PerNs::none();
}
and
if self.block.is_some() {
// Don't resolve extern prelude in block `DefMap`s.
return PerNs::none();
}

This resolves the issue, but I don't understand what "so that blocks can properly shadow them" means.

@Veykril Veykril added C-bug Category: bug A-nameres name, path and module resolution labels Apr 13, 2024
@Veykril
Copy link
Member

Veykril commented Apr 13, 2024

The shadowing is about stuff like

(assuming a core entry in the extern prelude)

fn f() {
   mod core {
       pub fn foo () {}
   }
   core::foo();
}

This should look into the local module, not the prelude.

@roife
Copy link
Contributor Author

roife commented Apr 13, 2024

It seems that it can be resolved correctly with the modifications above:

image

@Veykril
Copy link
Member

Veykril commented Apr 13, 2024

The problem with that approach might be that it fails for nsted block def maps

fn foo() {
    mod core { mod mem { fn drop<T>(_: T) {} } }
    {
        use self as _; // forces a block def map here
        core::mem::drop(0); // should resolve to the local item, not the prelude one
    }
}

@bors bors closed this as completed in d4da3f9 May 22, 2024
lnicola pushed a commit to lnicola/rust that referenced this issue May 26, 2024
fix: resolve extern prelude for local mods in block modules

fix rust-lang/rust-analyzer#17057, rust-lang/rust-analyzer#17032.

We should use `ModuleOrigin` to check if the current module is a pseudo-module introduced by blocks (where names might be shadowed), rather than checking `block_def_map`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-nameres name, path and module resolution C-bug Category: bug
Projects
None yet
2 participants