fix: resolve extern prelude for local mods in block modules · rust-lang/rust@ea2a16c

@@ -18,7 +18,9 @@ use crate::{

1818

db::DefDatabase,

1919

item_scope::{ImportOrExternCrate, BUILTIN_SCOPE},

2020

item_tree::Fields,

21-

nameres::{sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs},

21+

nameres::{

22+

sub_namespace_match, BlockInfo, BuiltinShadowMode, DefMap, MacroSubNs, ModuleOrigin,

23+

},

2224

path::{ModPath, PathKind},

2325

per_ns::PerNs,

2426

visibility::{RawVisibility, Visibility},

@@ -221,7 +223,7 @@ impl DefMap {

221223

None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),

222224

};

223225

tracing::debug!("resolving {:?} in crate root (+ extern prelude)", segment);

224-

self.resolve_name_in_crate_root_or_extern_prelude(db, segment)

226+

self.resolve_name_in_crate_root_or_extern_prelude(db, original_module, segment)

225227

}

226228

PathKind::Plain => {

227229

let (_, segment) = match segments.next() {

@@ -470,9 +472,9 @@ impl DefMap {

470472

};

471473472474

let extern_prelude = || {

473-

if self.block.is_some() {

474-

// Don't resolve extern prelude in block `DefMap`s, defer it to the crate def map so

475-

// that blocks can properly shadow them

475+

if matches!(self[module].origin, ModuleOrigin::BlockExpr { .. }) {

476+

// Don't resolve extern prelude in pseudo-modules of blocks, because

477+

// they might been shadowed by local names.

476478

return PerNs::none();

477479

}

478480

self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, extern_crate)| {

@@ -505,6 +507,7 @@ impl DefMap {

505507

fn resolve_name_in_crate_root_or_extern_prelude(

506508

&self,

507509

db: &dyn DefDatabase,

510+

module: LocalModuleId,

508511

name: &Name,

509512

) -> PerNs {

510513

let from_crate_root = match self.block {

@@ -515,8 +518,8 @@ impl DefMap {

515518

None => self[Self::ROOT].scope.get(name),

516519

};

517520

let from_extern_prelude = || {

518-

if self.block.is_some() {

519-

// Don't resolve extern prelude in block `DefMap`s.

521+

if matches!(self[module].origin, ModuleOrigin::BlockExpr { .. }) {

522+

// Don't resolve extern prelude in pseudo-module of a block.

520523

return PerNs::none();

521524

}

522525

self.data.extern_prelude.get(name).copied().map_or(