Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 5 additions & 24 deletions compiler/rustc_resolve/src/effective_visibilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,10 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
// is the maximum value among visibilities of bindings corresponding to that def id.
for (binding, eff_vis) in visitor.import_effective_visibilities.iter() {
let NameBindingKind::Import { import, .. } = binding.kind else { unreachable!() };
if !binding.is_ambiguity_recursive() {
if let Some(node_id) = import.id() {
r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx)
}
} else if binding.ambiguity.is_some() && eff_vis.is_public_at_level(Level::Reexported) {
if let Some(node_id) = import.id() {
r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx)
}
if binding.ambiguity.is_some() && eff_vis.is_public_at_level(Level::Reexported) {
exported_ambiguities.insert(*binding);
}
}
Expand All @@ -121,31 +120,13 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> {
// Set the given effective visibility level to `Level::Direct` and
// sets the rest of the `use` chain to `Level::Reexported` until
// we hit the actual exported item.
//
// If the binding is ambiguous, put the root ambiguity binding and all reexports
// leading to it into the table. They are used by the `ambiguous_glob_reexports`
// lint. For all bindings added to the table this way `is_ambiguity` returns true.
let is_ambiguity =
|binding: NameBinding<'ra>, warn: bool| binding.ambiguity.is_some() && !warn;
let mut parent_id = ParentId::Def(module_id);
let mut warn_ambiguity = binding.warn_ambiguity;
while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
self.update_import(binding, parent_id);

if is_ambiguity(binding, warn_ambiguity) {
// Stop at the root ambiguity, further bindings in the chain should not
// be reexported because the root ambiguity blocks any access to them.
// (Those further bindings are most likely not ambiguities themselves.)
break;
}

parent_id = ParentId::Import(binding);
binding = nested_binding;
warn_ambiguity |= nested_binding.warn_ambiguity;
}
if !is_ambiguity(binding, warn_ambiguity)
&& let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local())
{
if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
self.update_def(def_id, binding.vis.expect_local(), parent_id);
}
}
Expand Down
4 changes: 3 additions & 1 deletion tests/rustdoc-json/reexport/glob_collision.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Regression test for https://github.com/rust-lang/rust/issues/100973
// Update: the rules has changed after #147984, one of the colliding items is now available
// from other crates under a deprecation lint.

//@ set m1 = "$.index[?(@.name == 'm1' && @.inner.module)].id"
//@ is "$.index[?(@.name == 'm1')].inner.module.items" []
//@ is "$.index[?(@.name == 'm1')].inner.module.items" [0]
//@ is "$.index[?(@.name == 'm1')].inner.module.is_stripped" true
mod m1 {
pub fn f() {}
Expand Down
12 changes: 7 additions & 5 deletions tests/rustdoc/glob-shadowing.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//@ has 'glob_shadowing/index.html'
//@ count - '//dt' 6
//@ !has - '//dd' 'sub1::describe'
//@ count - '//dt' 7
//@ !has - '//dd' 'sub1::describe1'
//@ has - '//dd' 'sub2::describe'

//@ !has - '//dd' 'sub1::describe2'
//@ has - '//dd' 'sub1::describe2'

//@ !has - '//dd' 'sub1::prelude'
//@ has - '//dd' 'mod::prelude'
Expand All @@ -18,7 +18,7 @@

mod sub1 {
// this should be shadowed by sub2::describe
/// sub1::describe
/// sub1::describe1
pub fn describe() -> &'static str {
"sub1::describe"
}
Expand All @@ -33,7 +33,9 @@ mod sub1 {
pub struct Foo;

// this should be shadowed,
// because both sub1::describe2 and sub3::describe2 are from glob reexport
// because both sub1::describe2 and sub3::describe2 are from glob reexport,
// but it is still usable from other crates under the `ambiguous_glob_imports` lint,
// so it is reachable and documented
/// sub1::describe2
pub fn describe2() -> &'static str {
"sub1::describe2"
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/imports/ambiguous-reachable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//@ build-pass
//@ aux-crate: ambiguous_reachable_extern=ambiguous-reachable-extern.rs

#![allow(ambiguous_glob_imports)]

fn main() {
ambiguous_reachable_extern::generic::<u8>();
}
21 changes: 21 additions & 0 deletions tests/ui/imports/ambiguous-reachable.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Future incompatibility report: Future breakage diagnostic:
warning: `generic` is ambiguous
--> $DIR/ambiguous-reachable.rs:7:33
|
LL | ambiguous_reachable_extern::generic::<u8>();
| ^^^^^^^ ambiguous name
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #114095 <https://github.com/rust-lang/rust/issues/114095>
= note: ambiguous because of multiple glob imports of a name in the same module
note: `generic` could refer to the function defined here
--> $DIR/auxiliary/ambiguous-reachable-extern.rs:13:9
|
LL | pub use m1::*;
| ^^
note: `generic` could also refer to the function defined here
--> $DIR/auxiliary/ambiguous-reachable-extern.rs:14:9
|
LL | pub use m2::*;
| ^^

14 changes: 14 additions & 0 deletions tests/ui/imports/auxiliary/ambiguous-reachable-extern.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
mod m1 {
pub fn generic<T>() {
let x = 10;
let y = 11;
println!("hello {x} world {:?}", y);
}
}

mod m2 {
pub fn generic() {}
}

pub use m1::*;
pub use m2::*;
Loading