Skip to content

Commit 682fe41

Browse files
committed
resolve: Partially convert ambiguous_glob_imports lint into a hard error
1 parent 21ff67d commit 682fe41

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+188
-819
lines changed

compiler/rustc_codegen_gcc/build_system/src/test.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -826,8 +826,6 @@ fn valid_ui_error_pattern_test(file: &str) -> bool {
826826
"type-alias-impl-trait/auxiliary/cross_crate_ice.rs",
827827
"type-alias-impl-trait/auxiliary/cross_crate_ice2.rs",
828828
"macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs",
829-
"imports/ambiguous-1.rs",
830-
"imports/ambiguous-4-extern.rs",
831829
"entry-point/auxiliary/bad_main_functions.rs",
832830
]
833831
.iter()

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4438,7 +4438,7 @@ declare_lint! {
44384438
///
44394439
/// ### Example
44404440
///
4441-
/// ```rust,compile_fail
4441+
/// ```rust,ignore (needs extern crate)
44424442
/// #![deny(ambiguous_glob_imports)]
44434443
/// pub fn foo() -> u32 {
44444444
/// use sub::*;
@@ -4454,8 +4454,6 @@ declare_lint! {
44544454
/// }
44554455
/// ```
44564456
///
4457-
/// {{produces}}
4458-
///
44594457
/// ### Explanation
44604458
///
44614459
/// Previous versions of Rust compile it successfully because it

compiler/rustc_resolve/src/build_reduced_graph.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
5353
ns: Namespace,
5454
binding: NameBinding<'ra>,
5555
) {
56-
if let Err(old_binding) = self.try_define_local(parent, ident, ns, binding, false) {
56+
if let Err(old_binding) = self.try_define_local(parent, ident, ns, binding) {
5757
self.report_conflict(parent, ident, ns, old_binding, binding);
5858
}
5959
}
@@ -82,13 +82,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
8282
vis: Visibility<DefId>,
8383
span: Span,
8484
expansion: LocalExpnId,
85-
ambiguity: Option<(NameBinding<'ra>, AmbiguityKind)>,
85+
ambiguity: Option<(NameBinding<'ra>, AmbiguityKind, bool)>,
8686
) {
8787
let binding = self.arenas.alloc_name_binding(NameBindingData {
8888
kind: NameBindingKind::Res(res),
8989
ambiguity,
90-
// External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment.
91-
warn_ambiguity: true,
9290
vis,
9391
span,
9492
expansion,
@@ -288,7 +286,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
288286
AmbigModChildKind::GlobVsGlob => AmbiguityKind::GlobVsGlob,
289287
AmbigModChildKind::GlobVsExpanded => AmbiguityKind::GlobVsExpanded,
290288
};
291-
(self.arenas.new_res_binding(res, vis, span, expansion), ambig_kind)
289+
// External ambiguities always report the `AMBIGUOUS_GLOB_IMPORTS` lint at the moment.
290+
(self.arenas.new_res_binding(res, vis, span, expansion), ambig_kind, true)
292291
});
293292

294293
// Record primary definitions.

compiler/rustc_resolve/src/diagnostics.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
19951995
}
19961996
}
19971997

1998+
pub(crate) fn remove_same_import(
1999+
b1: NameBinding<'ra>,
2000+
b2: NameBinding<'ra>,
2001+
) -> (NameBinding<'ra>, NameBinding<'ra>) {
2002+
if let NameBindingKind::Import { import: import1, binding: b1_next } = b1.kind
2003+
&& let NameBindingKind::Import { import: import2, binding: b2_next } = b2.kind
2004+
&& import1 == import2
2005+
&& b1.ambiguity == b2.ambiguity
2006+
{
2007+
assert!(b1.ambiguity.is_none());
2008+
assert_eq!(b1.expansion, b2.expansion);
2009+
assert_eq!(b1.span, b2.span);
2010+
assert_eq!(b1.vis, b2.vis);
2011+
Self::remove_same_import(b1_next, b2_next)
2012+
} else {
2013+
(b1, b2)
2014+
}
2015+
}
2016+
19982017
fn ambiguity_diagnostic(&self, ambiguity_error: &AmbiguityError<'ra>) -> errors::Ambiguity {
19992018
let AmbiguityError { kind, ident, b1, b2, misc1, misc2, .. } = *ambiguity_error;
20002019
let extern_prelude_ambiguity = || {
@@ -2003,6 +2022,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
20032022
&& entry.flag_binding.as_ref().and_then(|pb| pb.get().0.binding()) == Some(b2)
20042023
})
20052024
};
2025+
let (b1, b2) = Self::remove_same_import(b1, b2);
20062026
let (b1, b2, misc1, misc2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() {
20072027
// We have to print the span-less alternative first, otherwise formatting looks bad.
20082028
(b2, b1, misc2, misc1, true)

compiler/rustc_resolve/src/effective_visibilities.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -125,27 +125,13 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
125125
// If the binding is ambiguous, put the root ambiguity binding and all reexports
126126
// leading to it into the table. They are used by the `ambiguous_glob_reexports`
127127
// lint. For all bindings added to the table this way `is_ambiguity` returns true.
128-
let is_ambiguity =
129-
|binding: NameBinding<'ra>, warn: bool| binding.ambiguity.is_some() && !warn;
130128
let mut parent_id = ParentId::Def(module_id);
131-
let mut warn_ambiguity = binding.warn_ambiguity;
132129
while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
133130
self.update_import(binding, parent_id);
134-
135-
if is_ambiguity(binding, warn_ambiguity) {
136-
// Stop at the root ambiguity, further bindings in the chain should not
137-
// be reexported because the root ambiguity blocks any access to them.
138-
// (Those further bindings are most likely not ambiguities themselves.)
139-
break;
140-
}
141-
142131
parent_id = ParentId::Import(binding);
143132
binding = nested_binding;
144-
warn_ambiguity |= nested_binding.warn_ambiguity;
145133
}
146-
if !is_ambiguity(binding, warn_ambiguity)
147-
&& let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local())
148-
{
134+
if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
149135
self.update_def(def_id, binding.vis.expect_local(), parent_id);
150136
}
151137
}

compiler/rustc_resolve/src/imports.rs

Lines changed: 34 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
325325
self.arenas.alloc_name_binding(NameBindingData {
326326
kind: NameBindingKind::Import { binding, import },
327327
ambiguity: None,
328-
warn_ambiguity: false,
329328
span: import.span,
330329
vis,
331330
expansion: import.parent_scope.expansion,
@@ -339,7 +338,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
339338
ident: Ident,
340339
ns: Namespace,
341340
binding: NameBinding<'ra>,
342-
warn_ambiguity: bool,
343341
) -> Result<(), NameBinding<'ra>> {
344342
let res = binding.res();
345343
self.check_reserved_macro_name(ident, res);
@@ -351,7 +349,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
351349
module.underscore_disambiguator.update_unchecked(|d| d + 1);
352350
module.underscore_disambiguator.get()
353351
});
354-
self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| {
352+
self.update_local_resolution(module, key, |this, resolution| {
355353
if let Some(old_binding) = resolution.best_binding() {
356354
if res == Res::Err && old_binding.res() != Res::Err {
357355
// Do not override real bindings with `Res::Err`s from error recovery.
@@ -360,30 +358,35 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
360358
match (old_binding.is_glob_import(), binding.is_glob_import()) {
361359
(true, true) => {
362360
let (glob_binding, old_glob_binding) = (binding, old_binding);
363-
// FIXME: remove `!binding.is_ambiguity_recursive()` after delete the warning ambiguity.
364-
if !binding.is_ambiguity_recursive()
365-
&& let NameBindingKind::Import { import: old_import, .. } =
366-
old_glob_binding.kind
367-
&& let NameBindingKind::Import { import, .. } = glob_binding.kind
368-
&& old_import == import
369-
{
370-
// When imported from the same glob-import statement, we should replace
371-
// `old_glob_binding` with `glob_binding`, regardless of whether
372-
// they have the same resolution or not.
361+
assert_ne!(glob_binding, old_glob_binding);
362+
363+
// There's a specific situation that is currently processed here instead of
364+
// using determinacy elsewhere.
365+
// Same glob import first fetches a glob binding from its target module,
366+
// and then fetches a more expanded non-glob binding from the same module.
367+
// In that case the non-glob binding should overwrite ("shadow") the glob
368+
// binding without any errors.
369+
let (deep_binding, old_deep_binding) =
370+
Self::remove_same_import(glob_binding, old_glob_binding);
371+
if deep_binding != binding && !deep_binding.is_glob_import() {
372+
assert_ne!(old_deep_binding, old_binding);
373+
assert_ne!(old_deep_binding, deep_binding);
374+
assert!(old_deep_binding.is_glob_import());
375+
assert!(old_deep_binding.ambiguity.is_none());
376+
assert!(deep_binding.ambiguity.is_none());
373377
resolution.glob_binding = Some(glob_binding);
374378
} else if res != old_glob_binding.res() {
375379
resolution.glob_binding = Some(this.new_ambiguity_binding(
376380
AmbiguityKind::GlobVsGlob,
377381
old_glob_binding,
378382
glob_binding,
379-
warn_ambiguity,
383+
false,
380384
));
381-
} else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
385+
} else if !old_glob_binding.vis.is_at_least(glob_binding.vis, this.tcx)
386+
|| glob_binding.is_ambiguity_recursive()
387+
{
382388
// We are glob-importing the same item but with greater visibility.
383389
resolution.glob_binding = Some(glob_binding);
384-
} else if binding.is_ambiguity_recursive() {
385-
resolution.glob_binding =
386-
Some(this.new_warn_ambiguity_binding(glob_binding));
387390
}
388391
}
389392
(old_glob @ true, false) | (old_glob @ false, true) => {
@@ -412,7 +415,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
412415
glob_binding,
413416
false,
414417
));
415-
} else if !old_glob_binding.vis.is_at_least(binding.vis, this.tcx) {
418+
} else if !old_glob_binding.vis.is_at_least(glob_binding.vis, this.tcx)
419+
|| glob_binding.is_ambiguity_recursive()
420+
{
421+
// We are glob-importing the same item but with greater visibility.
416422
resolution.glob_binding = Some(glob_binding);
417423
}
418424
} else {
@@ -440,33 +446,22 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
440446
ambiguity_kind: AmbiguityKind,
441447
primary_binding: NameBinding<'ra>,
442448
secondary_binding: NameBinding<'ra>,
443-
warn_ambiguity: bool,
449+
warning: bool,
444450
) -> NameBinding<'ra> {
445-
let ambiguity = Some((secondary_binding, ambiguity_kind));
446-
let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding };
451+
let ambiguity = Some((secondary_binding, ambiguity_kind, warning));
452+
let data = NameBindingData { ambiguity, ..*primary_binding };
447453
self.arenas.alloc_name_binding(data)
448454
}
449455

450-
fn new_warn_ambiguity_binding(&self, binding: NameBinding<'ra>) -> NameBinding<'ra> {
451-
assert!(binding.is_ambiguity_recursive());
452-
self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding })
453-
}
454-
455456
// Use `f` to mutate the resolution of the name in the module.
456457
// If the resolution becomes a success, define it in the module's glob importers.
457-
fn update_local_resolution<T, F>(
458-
&mut self,
459-
module: Module<'ra>,
460-
key: BindingKey,
461-
warn_ambiguity: bool,
462-
f: F,
463-
) -> T
458+
fn update_local_resolution<T, F>(&mut self, module: Module<'ra>, key: BindingKey, f: F) -> T
464459
where
465460
F: FnOnce(&Resolver<'ra, 'tcx>, &mut NameResolution<'ra>) -> T,
466461
{
467462
// Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
468463
// during which the resolution might end up getting re-defined via a glob cycle.
469-
let (binding, t, warn_ambiguity) = {
464+
let (binding, t) = {
470465
let resolution = &mut *self.resolution_or_default(module, key).borrow_mut_unchecked();
471466
let old_binding = resolution.binding();
472467

@@ -475,7 +470,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
475470
if let Some(binding) = resolution.binding()
476471
&& old_binding != Some(binding)
477472
{
478-
(binding, t, warn_ambiguity || old_binding.is_some())
473+
(binding, t)
479474
} else {
480475
return t;
481476
}
@@ -500,7 +495,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
500495
ident.0,
501496
key.ns,
502497
imported_binding,
503-
warn_ambiguity,
504498
);
505499
}
506500
}
@@ -521,11 +515,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
521515
let dummy_binding = self.import(dummy_binding, import);
522516
self.per_ns(|this, ns| {
523517
let module = import.parent_scope.module;
524-
let _ = this.try_define_local(module, target, ns, dummy_binding, false);
518+
let _ = this.try_define_local(module, target, ns, dummy_binding);
525519
// Don't remove underscores from `single_imports`, they were never added.
526520
if target.name != kw::Underscore {
527521
let key = BindingKey::new(target, ns);
528-
this.update_local_resolution(module, key, false, |_, resolution| {
522+
this.update_local_resolution(module, key, |_, resolution| {
529523
resolution.single_imports.swap_remove(&import);
530524
})
531525
}
@@ -658,7 +652,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
658652
let Some(binding) = resolution.best_binding() else { continue };
659653

660654
if let NameBindingKind::Import { import, .. } = binding.kind
661-
&& let Some((amb_binding, _)) = binding.ambiguity
655+
&& let Some((amb_binding, ..)) = binding.ambiguity
662656
&& binding.res() != Res::Err
663657
&& exported_ambiguities.contains(&binding)
664658
{
@@ -917,7 +911,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
917911
this.get_mut_unchecked().update_local_resolution(
918912
parent,
919913
key,
920-
false,
921914
|_, resolution| {
922915
resolution.single_imports.swap_remove(&import);
923916
},
@@ -1523,16 +1516,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
15231516
};
15241517
if self.is_accessible_from(binding.vis, scope) {
15251518
let imported_binding = self.import(binding, import);
1526-
let warn_ambiguity = self
1527-
.resolution(import.parent_scope.module, key)
1528-
.and_then(|r| r.binding())
1529-
.is_some_and(|binding| binding.warn_ambiguity_recursive());
15301519
let _ = self.try_define_local(
15311520
import.parent_scope.module,
15321521
key.ident.0,
15331522
key.ns,
15341523
imported_binding,
1535-
warn_ambiguity,
15361524
);
15371525
}
15381526
}

0 commit comments

Comments
 (0)