Auto merge of #103158 - Bryanskiy:resolve_perf, r=petrochenkov
Perf improvements for effective visibility calculating related to https://github.com/rust-lang/rust/pull/102026 r? `@petrochenkov`
This commit is contained in:
commit
a5406feb1c
@ -69,21 +69,7 @@ impl EffectiveVisibility {
|
|||||||
self.get(tag).is_public()
|
self.get(tag).is_public()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, vis: Visibility, tag: AccessLevel, tree: impl DefIdTree) -> bool {
|
pub fn from_vis(vis: Visibility) -> EffectiveVisibility {
|
||||||
let mut changed = false;
|
|
||||||
for level in AccessLevel::all_levels() {
|
|
||||||
if level <= tag {
|
|
||||||
let current_effective_vis = self.get_mut(level);
|
|
||||||
if *current_effective_vis != vis && vis.is_at_least(*current_effective_vis, tree) {
|
|
||||||
changed = true;
|
|
||||||
*current_effective_vis = vis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
changed
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_vis(vis: Visibility) -> EffectiveVisibility {
|
|
||||||
EffectiveVisibility {
|
EffectiveVisibility {
|
||||||
public: vis,
|
public: vis,
|
||||||
exported: vis,
|
exported: vis,
|
||||||
@ -173,33 +159,49 @@ impl<Id: Hash + Eq + Copy + Into<DefId>> AccessLevels<Id> {
|
|||||||
parent_id: Id,
|
parent_id: Id,
|
||||||
tag: AccessLevel,
|
tag: AccessLevel,
|
||||||
tree: impl DefIdTree,
|
tree: impl DefIdTree,
|
||||||
) -> Result<bool, ()> {
|
) -> bool {
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
let mut current_effective_vis = self
|
let mut current_effective_vis = self.get_effective_vis(id).copied().unwrap_or_else(|| {
|
||||||
.get_effective_vis(id)
|
if id.into().is_crate_root() {
|
||||||
.copied()
|
EffectiveVisibility::from_vis(Visibility::Public)
|
||||||
.unwrap_or_else(|| EffectiveVisibility::from_vis(default_vis()));
|
} else {
|
||||||
|
EffectiveVisibility::from_vis(default_vis())
|
||||||
|
}
|
||||||
|
});
|
||||||
if let Some(inherited_effective_vis) = self.get_effective_vis(parent_id) {
|
if let Some(inherited_effective_vis) = self.get_effective_vis(parent_id) {
|
||||||
|
let mut inherited_effective_vis_at_prev_level = *inherited_effective_vis.get(tag);
|
||||||
|
let mut calculated_effective_vis = inherited_effective_vis_at_prev_level;
|
||||||
for level in AccessLevel::all_levels() {
|
for level in AccessLevel::all_levels() {
|
||||||
if tag >= level {
|
if tag >= level {
|
||||||
let inherited_effective_vis_at_level = *inherited_effective_vis.get(level);
|
let inherited_effective_vis_at_level = *inherited_effective_vis.get(level);
|
||||||
let calculated_effective_vis =
|
let current_effective_vis_at_level = current_effective_vis.get_mut(level);
|
||||||
if nominal_vis.is_at_least(inherited_effective_vis_at_level, tree) {
|
// effective visibility for id shouldn't be recalculated if
|
||||||
inherited_effective_vis_at_level
|
// inherited from parent_id effective visibility isn't changed at next level
|
||||||
} else {
|
if !(inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level
|
||||||
nominal_vis
|
&& tag != level)
|
||||||
};
|
{
|
||||||
changed |= current_effective_vis.update(calculated_effective_vis, level, tree);
|
calculated_effective_vis =
|
||||||
|
if nominal_vis.is_at_least(inherited_effective_vis_at_level, tree) {
|
||||||
|
inherited_effective_vis_at_level
|
||||||
|
} else {
|
||||||
|
nominal_vis
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// effective visibility can't be decreased at next update call for the
|
||||||
|
// same id
|
||||||
|
if *current_effective_vis_at_level != calculated_effective_vis
|
||||||
|
&& calculated_effective_vis
|
||||||
|
.is_at_least(*current_effective_vis_at_level, tree)
|
||||||
|
{
|
||||||
|
changed = true;
|
||||||
|
*current_effective_vis_at_level = calculated_effective_vis;
|
||||||
|
}
|
||||||
|
inherited_effective_vis_at_prev_level = inherited_effective_vis_at_level;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if !id.into().is_crate_root() {
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
changed |= current_effective_vis.update(Visibility::Public, AccessLevel::Public, tree);
|
|
||||||
}
|
}
|
||||||
self.map.insert(id, current_effective_vis);
|
self.map.insert(id, current_effective_vis);
|
||||||
Ok(changed)
|
changed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,9 +922,9 @@ pub struct TestReachabilityVisitor<'tcx, 'a> {
|
|||||||
impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
|
impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
|
||||||
fn access_level_diagnostic(&mut self, def_id: LocalDefId) {
|
fn access_level_diagnostic(&mut self, def_id: LocalDefId) {
|
||||||
if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_effective_visibility) {
|
if self.tcx.has_attr(def_id.to_def_id(), sym::rustc_effective_visibility) {
|
||||||
|
let mut error_msg = String::new();
|
||||||
|
let span = self.tcx.def_span(def_id.to_def_id());
|
||||||
if let Some(effective_vis) = self.access_levels.get_effective_vis(def_id) {
|
if let Some(effective_vis) = self.access_levels.get_effective_vis(def_id) {
|
||||||
let mut error_msg = String::new();
|
|
||||||
let span = self.tcx.def_span(def_id.to_def_id());
|
|
||||||
for level in AccessLevel::all_levels() {
|
for level in AccessLevel::all_levels() {
|
||||||
let vis_str = match effective_vis.get(level) {
|
let vis_str = match effective_vis.get(level) {
|
||||||
ty::Visibility::Restricted(restricted_id) => {
|
ty::Visibility::Restricted(restricted_id) => {
|
||||||
@ -943,8 +943,10 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
|
|||||||
}
|
}
|
||||||
error_msg.push_str(&format!("{:?}: {}", level, vis_str));
|
error_msg.push_str(&format!("{:?}: {}", level, vis_str));
|
||||||
}
|
}
|
||||||
self.tcx.sess.emit_err(ReportEffectiveVisibility { span, descr: error_msg });
|
} else {
|
||||||
|
error_msg.push_str("not in the table");
|
||||||
}
|
}
|
||||||
|
self.tcx.sess.emit_err(ReportEffectiveVisibility { span, descr: error_msg });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,10 +96,18 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
|
|||||||
parent_id: LocalDefId,
|
parent_id: LocalDefId,
|
||||||
tag: AccessLevel,
|
tag: AccessLevel,
|
||||||
) {
|
) {
|
||||||
|
let module_id = self
|
||||||
|
.r
|
||||||
|
.get_nearest_non_block_module(def_id.to_def_id())
|
||||||
|
.nearest_parent_mod()
|
||||||
|
.expect_local();
|
||||||
|
if nominal_vis == Visibility::Restricted(module_id)
|
||||||
|
|| self.r.visibilities[&parent_id] == Visibility::Restricted(module_id)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
let mut access_levels = std::mem::take(&mut self.r.access_levels);
|
let mut access_levels = std::mem::take(&mut self.r.access_levels);
|
||||||
let module_id =
|
self.changed |= access_levels.update(
|
||||||
self.r.get_nearest_non_block_module(def_id.to_def_id()).def_id().expect_local();
|
|
||||||
let res = access_levels.update(
|
|
||||||
def_id,
|
def_id,
|
||||||
nominal_vis,
|
nominal_vis,
|
||||||
|| Visibility::Restricted(module_id),
|
|| Visibility::Restricted(module_id),
|
||||||
@ -107,14 +115,6 @@ impl<'r, 'a> AccessLevelsVisitor<'r, 'a> {
|
|||||||
tag,
|
tag,
|
||||||
&*self.r,
|
&*self.r,
|
||||||
);
|
);
|
||||||
if let Ok(changed) = res {
|
|
||||||
self.changed |= changed;
|
|
||||||
} else {
|
|
||||||
self.r.session.delay_span_bug(
|
|
||||||
self.r.opt_span(def_id.to_def_id()).unwrap(),
|
|
||||||
"Can't update effective visibility",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
self.r.access_levels = access_levels;
|
self.r.access_levels = access_levels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,12 +17,12 @@ mod outer { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(c
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_effective_visibility]
|
#[rustc_effective_visibility]
|
||||||
struct PrivStruct; //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
|
struct PrivStruct; //~ ERROR not in the table
|
||||||
|
|
||||||
#[rustc_effective_visibility]
|
#[rustc_effective_visibility]
|
||||||
pub union PubUnion { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
|
pub union PubUnion { //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
|
||||||
#[rustc_effective_visibility]
|
#[rustc_effective_visibility]
|
||||||
a: u8, //~ ERROR Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
|
a: u8, //~ ERROR not in the table
|
||||||
#[rustc_effective_visibility]
|
#[rustc_effective_visibility]
|
||||||
pub b: u8, //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
|
pub b: u8, //~ ERROR Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
|
||||||
}
|
}
|
||||||
@ -38,13 +38,13 @@ mod outer { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(c
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_effective_visibility]
|
#[rustc_effective_visibility]
|
||||||
macro_rules! none_macro { //~ Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
|
macro_rules! none_macro { //~ ERROR Public: pub(crate), Exported: pub(crate), Reachable: pub(crate), ReachableFromImplTrait: pub(crate)
|
||||||
() => {};
|
() => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[rustc_effective_visibility]
|
#[rustc_effective_visibility]
|
||||||
macro_rules! public_macro { //~ Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
|
macro_rules! public_macro { //~ ERROR Public: pub, Exported: pub, Reachable: pub, ReachableFromImplTrait: pub
|
||||||
() => {};
|
() => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait
|
|||||||
LL | pub trait PubTrait {
|
LL | pub trait PubTrait {
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
|
error: not in the table
|
||||||
--> $DIR/access_levels.rs:20:9
|
--> $DIR/access_levels.rs:20:9
|
||||||
|
|
|
|
||||||
LL | struct PrivStruct;
|
LL | struct PrivStruct;
|
||||||
@ -34,7 +34,7 @@ error: Public: pub(crate), Exported: pub, Reachable: pub, ReachableFromImplTrait
|
|||||||
LL | pub union PubUnion {
|
LL | pub union PubUnion {
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: Public: pub(self), Exported: pub(self), Reachable: pub(self), ReachableFromImplTrait: pub(self)
|
error: not in the table
|
||||||
--> $DIR/access_levels.rs:25:13
|
--> $DIR/access_levels.rs:25:13
|
||||||
|
|
|
|
||||||
LL | a: u8,
|
LL | a: u8,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user