Skip to content

Commit eb628e8

Browse files
authored
Rollup merge of #102109 - petrochenkov:addids, r=oli-obk
resolve: Set effective visibilities for imports more precisely Instead of setting them for all primary and additional IDs of the import, only set them for the binding's true ID.
2 parents bf167e0 + 4ddff03 commit eb628e8

File tree

4 files changed

+75
-12
lines changed

4 files changed

+75
-12
lines changed

compiler/rustc_resolve/src/access_levels.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::imports::ImportKind;
21
use crate::NameBinding;
32
use crate::NameBindingKind;
43
use crate::Resolver;
@@ -54,15 +53,11 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
5453
// sets the rest of the `use` chain to `AccessLevel::Exported` until
5554
// we hit the actual exported item.
5655
let set_import_binding_access_level =
57-
|this: &mut Self, mut binding: &NameBinding<'a>, mut access_level| {
56+
|this: &mut Self, mut binding: &NameBinding<'a>, mut access_level, ns| {
5857
while let NameBindingKind::Import { binding: nested_binding, import, .. } =
5958
binding.kind
6059
{
61-
this.set_access_level(import.id, access_level);
62-
if let ImportKind::Single { additional_ids, .. } = import.kind {
63-
this.set_access_level(additional_ids.0, access_level);
64-
this.set_access_level(additional_ids.1, access_level);
65-
}
60+
this.set_access_level(this.r.import_id_for_ns(import, ns), access_level);
6661

6762
access_level = Some(AccessLevel::Exported);
6863
binding = nested_binding;
@@ -72,11 +67,11 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
7267
let module = self.r.get_module(module_id.to_def_id()).unwrap();
7368
let resolutions = self.r.resolutions(module);
7469

75-
for (.., name_resolution) in resolutions.borrow().iter() {
70+
for (key, name_resolution) in resolutions.borrow().iter() {
7671
if let Some(binding) = name_resolution.borrow().binding() && binding.vis.is_public() && !binding.is_ambiguity() {
7772
let access_level = match binding.is_import() {
7873
true => {
79-
set_import_binding_access_level(self, binding, module_level);
74+
set_import_binding_access_level(self, binding, module_level, key.ns);
8075
Some(AccessLevel::Exported)
8176
},
8277
false => module_level,

compiler/rustc_resolve/src/imports.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::diagnostics::Suggestion;
44
use crate::Determinacy::{self, *};
5-
use crate::Namespace::{MacroNS, TypeNS};
5+
use crate::Namespace::{self, *};
66
use crate::{module_to_string, names_to_string};
77
use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
88
use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
@@ -371,6 +371,31 @@ impl<'a> Resolver<'a> {
371371
self.used_imports.insert(import.id);
372372
}
373373
}
374+
375+
/// Take primary and additional node IDs from an import and select one that corresponds to the
376+
/// given namespace. The logic must match the corresponding logic from `fn lower_use_tree` that
377+
/// assigns resolutons to IDs.
378+
pub(crate) fn import_id_for_ns(&self, import: &Import<'_>, ns: Namespace) -> NodeId {
379+
if let ImportKind::Single { additional_ids: (id1, id2), .. } = import.kind {
380+
if let Some(resolutions) = self.import_res_map.get(&import.id) {
381+
assert!(resolutions[ns].is_some(), "incorrectly finalized import");
382+
return match ns {
383+
TypeNS => import.id,
384+
ValueNS => match resolutions.type_ns {
385+
Some(_) => id1,
386+
None => import.id,
387+
},
388+
MacroNS => match (resolutions.type_ns, resolutions.value_ns) {
389+
(Some(_), Some(_)) => id2,
390+
(Some(_), None) | (None, Some(_)) => id1,
391+
(None, None) => import.id,
392+
},
393+
};
394+
}
395+
}
396+
397+
import.id
398+
}
374399
}
375400

376401
/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved

src/test/ui/privacy/access_levels.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,21 @@ mod outer { //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(sel
5555
}
5656
}
5757

58-
pub use outer::inner1;
58+
#[rustc_effective_visibility]
59+
pub use outer::inner1; //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
5960

6061
pub fn foo() -> outer::ReachableStruct { outer::ReachableStruct {a: 0} }
6162

63+
mod half_public_import {
64+
#[rustc_effective_visibility]
65+
pub type HalfPublicImport = u8; //~ ERROR Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
66+
#[rustc_effective_visibility]
67+
#[allow(non_upper_case_globals)]
68+
pub(crate) const HalfPublicImport: u8 = 0; //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
69+
}
70+
71+
#[rustc_effective_visibility]
72+
pub use half_public_import::HalfPublicImport; //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
73+
//~^ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
74+
6275
fn main() {}

src/test/ui/privacy/access_levels.stderr

+31-1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,36 @@ error: Public: pub(self), Exported: pub(self), Reachable: pub, ReachableFromImpl
8888
LL | pub a: u8,
8989
| ^^^^^^^^^
9090

91+
error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
92+
--> $DIR/access_levels.rs:59:9
93+
|
94+
LL | pub use outer::inner1;
95+
| ^^^^^^^^^^^^^
96+
97+
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
98+
--> $DIR/access_levels.rs:65:5
99+
|
100+
LL | pub type HalfPublicImport = u8;
101+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
102+
103+
error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
104+
--> $DIR/access_levels.rs:68:5
105+
|
106+
LL | pub(crate) const HalfPublicImport: u8 = 0;
107+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
108+
109+
error: Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
110+
--> $DIR/access_levels.rs:72:9
111+
|
112+
LL | pub use half_public_import::HalfPublicImport;
113+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
114+
115+
error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
116+
--> $DIR/access_levels.rs:72:9
117+
|
118+
LL | pub use half_public_import::HalfPublicImport;
119+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120+
91121
error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
92122
--> $DIR/access_levels.rs:14:13
93123
|
@@ -100,5 +130,5 @@ error: Public: pub(self), Exported: pub, Reachable: pub, ReachableFromImplTrait:
100130
LL | type B;
101131
| ^^^^^^
102132

103-
error: aborting due to 17 previous errors
133+
error: aborting due to 22 previous errors
104134

0 commit comments

Comments
 (0)