Skip to content

Commit 743dc68

Browse files
committed
resolve: Preserve ambiguous glob reexports in crate metadata
So in cross-crate scenarios they can work in the same way as in crate-local scenarios.
1 parent 20f1c04 commit 743dc68

36 files changed

+858
-103
lines changed

compiler/rustc_metadata/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#![feature(min_specialization)]
1010
#![feature(never_type)]
1111
#![feature(proc_macro_internals)]
12+
#![feature(result_option_map_or_default)]
1213
#![feature(trusted_len)]
1314
// tidy-alphabetical-end
1415

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,21 @@ impl<'a> CrateMetadataRef<'a> {
13081308
}
13091309
}
13101310

1311+
fn get_ambig_module_children(
1312+
self,
1313+
id: DefIndex,
1314+
sess: &Session,
1315+
) -> impl Iterator<Item = AmbigModChild> {
1316+
gen move {
1317+
let children = self.root.tables.ambig_module_children.get(self, id);
1318+
if !children.is_default() {
1319+
for child in children.decode((self, sess)) {
1320+
yield child;
1321+
}
1322+
}
1323+
}
1324+
}
1325+
13111326
fn is_ctfe_mir_available(self, id: DefIndex) -> bool {
13121327
self.root.tables.mir_for_ctfe.get(self, id).is_some()
13131328
}

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
88
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
99
use rustc_middle::arena::ArenaAllocatable;
1010
use rustc_middle::bug;
11-
use rustc_middle::metadata::ModChild;
11+
use rustc_middle::metadata::{AmbigModChild, ModChild};
1212
use rustc_middle::middle::exported_symbols::ExportedSymbol;
1313
use rustc_middle::middle::stability::DeprecationEntry;
1414
use rustc_middle::query::{ExternProviders, LocalCrate};
@@ -584,6 +584,14 @@ impl CStore {
584584
self.get_crate_data(def_id.krate).get_expn_that_defined(def_id.index, sess)
585585
}
586586

587+
pub fn ambig_module_children_untracked(
588+
&self,
589+
def_id: DefId,
590+
sess: &Session,
591+
) -> impl Iterator<Item = AmbigModChild> {
592+
self.get_crate_data(def_id.krate).get_ambig_module_children(def_id.index, sess)
593+
}
594+
587595
/// Only public-facing way to traverse all the definitions in a non-local crate.
588596
/// Critically useful for this third-party project: <https://github.com/hacspec/hacspec>.
589597
/// See <https://github.com/rust-lang/rust/pull/85889> for context.

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
17261726

17271727
record_defaulted_array!(self.tables.module_children_reexports[def_id] <-
17281728
module_children.iter().filter(|child| !child.reexport_chain.is_empty()));
1729+
1730+
let ambig_module_children = tcx
1731+
.resolutions(())
1732+
.ambig_module_children
1733+
.get(&local_def_id)
1734+
.map_or_default(|v| &v[..]);
1735+
record_defaulted_array!(self.tables.ambig_module_children[def_id] <-
1736+
ambig_module_children);
17291737
}
17301738
}
17311739

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_index::bit_set::DenseBitSet;
2121
use rustc_macros::{
2222
Decodable, Encodable, MetadataDecodable, MetadataEncodable, TyDecodable, TyEncodable,
2323
};
24-
use rustc_middle::metadata::ModChild;
24+
use rustc_middle::metadata::{AmbigModChild, ModChild};
2525
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
2626
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
2727
use rustc_middle::middle::deduced_param_attrs::DeducedParamAttrs;
@@ -399,6 +399,7 @@ define_tables! {
399399
// That's why the encoded list needs to contain `ModChild` structures describing all the names
400400
// individually instead of `DefId`s.
401401
module_children_reexports: Table<DefIndex, LazyArray<ModChild>>,
402+
ambig_module_children: Table<DefIndex, LazyArray<AmbigModChild>>,
402403
cross_crate_inlinable: Table<DefIndex, bool>,
403404

404405
- optional:

compiler/rustc_metadata/src/rmeta/parameterized.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ trivially_parameterized_over_tcx! {
9494
rustc_hir::def_id::DefIndex,
9595
rustc_hir::definitions::DefKey,
9696
rustc_index::bit_set::DenseBitSet<u32>,
97+
rustc_middle::metadata::AmbigModChild,
9798
rustc_middle::metadata::ModChild,
9899
rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs,
99100
rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile,

compiler/rustc_middle/src/metadata.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,17 @@ pub struct ModChild {
4444
/// Empty if the module child is a proper item.
4545
pub reexport_chain: SmallVec<[Reexport; 2]>,
4646
}
47+
48+
#[derive(Debug, TyEncodable, TyDecodable, HashStable)]
49+
pub enum AmbigModChildKind {
50+
GlobVsGlob,
51+
GlobVsExpanded,
52+
}
53+
54+
/// Same as `ModChild`, however, it includes ambiguity error.
55+
#[derive(Debug, TyEncodable, TyDecodable, HashStable)]
56+
pub struct AmbigModChild {
57+
pub main: ModChild,
58+
pub second: ModChild,
59+
pub kind: AmbigModChildKind,
60+
}

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub use self::typeck_results::{
109109
Rust2024IncompatiblePatInfo, TypeckResults, UserType, UserTypeAnnotationIndex, UserTypeKind,
110110
};
111111
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
112-
use crate::metadata::ModChild;
112+
use crate::metadata::{AmbigModChild, ModChild};
113113
use crate::middle::privacy::EffectiveVisibilities;
114114
use crate::mir::{Body, CoroutineLayout, CoroutineSavedLocal, SourceInfo};
115115
use crate::query::{IntoQueryParam, Providers};
@@ -174,6 +174,7 @@ pub struct ResolverGlobalCtxt {
174174
pub extern_crate_map: UnordMap<LocalDefId, CrateNum>,
175175
pub maybe_unused_trait_imports: FxIndexSet<LocalDefId>,
176176
pub module_children: LocalDefIdMap<Vec<ModChild>>,
177+
pub ambig_module_children: LocalDefIdMap<Vec<AmbigModChild>>,
177178
pub glob_map: FxIndexMap<LocalDefId, FxIndexSet<Symbol>>,
178179
pub main_def: Option<MainDefinition>,
179180
pub trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 83 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_hir::def::{self, *};
2222
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
2323
use rustc_index::bit_set::DenseBitSet;
2424
use rustc_metadata::creader::LoadedMacro;
25-
use rustc_middle::metadata::ModChild;
25+
use rustc_middle::metadata::{AmbigModChildKind, ModChild, Reexport};
2626
use rustc_middle::ty::{Feed, Visibility};
2727
use rustc_middle::{bug, span_bug};
2828
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
@@ -36,9 +36,9 @@ use crate::imports::{ImportData, ImportKind};
3636
use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
3737
use crate::ref_mut::CmCell;
3838
use crate::{
39-
BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind, ModuleOrUniformRoot,
40-
NameBinding, ParentScope, PathResult, ResolutionError, Resolver, Segment, Used,
41-
VisResolutionError, errors,
39+
AmbiguityKind, BindingKey, ExternPreludeEntry, Finalize, MacroData, Module, ModuleKind,
40+
ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult,
41+
ResolutionError, Resolver, Segment, Used, VisResolutionError, errors,
4242
};
4343

4444
type Res = def::Res<NodeId>;
@@ -81,9 +81,18 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
8181
res: Res,
8282
vis: Visibility<DefId>,
8383
span: Span,
84-
expn_id: LocalExpnId,
84+
expansion: LocalExpnId,
85+
ambiguity: Option<(NameBinding<'ra>, AmbiguityKind)>,
8586
) {
86-
let binding = self.arenas.new_res_binding(res, vis, span, expn_id);
87+
let binding = self.arenas.alloc_name_binding(NameBindingData {
88+
kind: NameBindingKind::Res(res),
89+
ambiguity,
90+
// External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment.
91+
warn_ambiguity: true,
92+
vis,
93+
span,
94+
expansion,
95+
});
8796
// Even if underscore names cannot be looked up, we still need to add them to modules,
8897
// because they can be fetched by glob imports from those modules, and bring traits
8998
// into scope both directly and through glob imports.
@@ -232,9 +241,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
232241
}
233242

234243
pub(crate) fn build_reduced_graph_external(&self, module: Module<'ra>) {
235-
for (i, child) in self.tcx.module_children(module.def_id()).into_iter().enumerate() {
236-
let parent_scope = ParentScope::module(module, self.arenas);
237-
self.build_reduced_graph_for_external_crate_res(child, parent_scope, i)
244+
let def_id = module.def_id();
245+
let children = self.tcx.module_children(def_id);
246+
let parent_scope = ParentScope::module(module, self.arenas);
247+
for (i, child) in children.iter().enumerate() {
248+
self.build_reduced_graph_for_external_crate_res(child, parent_scope, i, None)
249+
}
250+
for (i, child) in
251+
self.cstore().ambig_module_children_untracked(def_id, self.tcx.sess).enumerate()
252+
{
253+
self.build_reduced_graph_for_external_crate_res(
254+
&child.main,
255+
parent_scope,
256+
children.len() + i,
257+
Some((&child.second, child.kind)),
258+
)
238259
}
239260
}
240261

@@ -244,17 +265,31 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
244265
child: &ModChild,
245266
parent_scope: ParentScope<'ra>,
246267
child_index: usize,
268+
ambig_child: Option<(&ModChild, AmbigModChildKind)>,
247269
) {
248270
let parent = parent_scope.module;
271+
let child_span = |this: &Self, reexport_chain: &[Reexport], res: def::Res<_>| {
272+
this.def_span(
273+
reexport_chain
274+
.first()
275+
.and_then(|reexport| reexport.id())
276+
.unwrap_or_else(|| res.def_id()),
277+
)
278+
};
249279
let ModChild { ident, res, vis, ref reexport_chain } = *child;
250-
let span = self.def_span(
251-
reexport_chain
252-
.first()
253-
.and_then(|reexport| reexport.id())
254-
.unwrap_or_else(|| res.def_id()),
255-
);
280+
let span = child_span(self, reexport_chain, res);
256281
let res = res.expect_non_local();
257282
let expansion = parent_scope.expansion;
283+
let ambig = ambig_child.map(|(ambig_child, ambig_kind)| {
284+
let ModChild { ident: _, res, vis, ref reexport_chain } = *ambig_child;
285+
let span = child_span(self, reexport_chain, res);
286+
let res = res.expect_non_local();
287+
let ambig_kind = match ambig_kind {
288+
AmbigModChildKind::GlobVsGlob => AmbiguityKind::GlobVsGlob,
289+
AmbigModChildKind::GlobVsExpanded => AmbiguityKind::GlobVsExpanded,
290+
};
291+
(self.arenas.new_res_binding(res, vis, span, expansion), ambig_kind)
292+
});
258293
// Record primary definitions.
259294
match res {
260295
Res::Def(
@@ -272,9 +307,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
272307
_,
273308
)
274309
| Res::PrimTy(..)
275-
| Res::ToolMod => {
276-
self.define_extern(parent, ident, TypeNS, child_index, res, vis, span, expansion)
277-
}
310+
| Res::ToolMod => self.define_extern(
311+
parent,
312+
ident,
313+
TypeNS,
314+
child_index,
315+
res,
316+
vis,
317+
span,
318+
expansion,
319+
ambig,
320+
),
278321
Res::Def(
279322
DefKind::Fn
280323
| DefKind::AssocFn
@@ -283,10 +326,28 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
283326
| DefKind::AssocConst
284327
| DefKind::Ctor(..),
285328
_,
286-
) => self.define_extern(parent, ident, ValueNS, child_index, res, vis, span, expansion),
287-
Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => {
288-
self.define_extern(parent, ident, MacroNS, child_index, res, vis, span, expansion)
289-
}
329+
) => self.define_extern(
330+
parent,
331+
ident,
332+
ValueNS,
333+
child_index,
334+
res,
335+
vis,
336+
span,
337+
expansion,
338+
ambig,
339+
),
340+
Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => self.define_extern(
341+
parent,
342+
ident,
343+
MacroNS,
344+
child_index,
345+
res,
346+
vis,
347+
span,
348+
expansion,
349+
ambig,
350+
),
290351
Res::Def(
291352
DefKind::TyParam
292353
| DefKind::ConstParam

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
145145
for ambiguity_error in &self.ambiguity_errors {
146146
let diag = self.ambiguity_diagnostics(ambiguity_error);
147147
if ambiguity_error.warning {
148-
let NameBindingKind::Import { import, .. } = ambiguity_error.b1.0.kind else {
149-
unreachable!()
148+
let node_id = match ambiguity_error.b1.0.kind {
149+
NameBindingKind::Import { import, .. } => import.root_id,
150+
NameBindingKind::Res(_) => CRATE_NODE_ID,
150151
};
151152
self.lint_buffer.buffer_lint(
152153
AMBIGUOUS_GLOB_IMPORTS,
153-
import.root_id,
154+
node_id,
154155
ambiguity_error.ident.span,
155156
BuiltinLintDiag::AmbiguousGlobImports { diag },
156157
);

0 commit comments

Comments
 (0)