rustc: Parameterize ty::Visibility over used ID

It allows using `LocalDefId` instead of `DefId` when possible, and also encode cheaper `Visibility<DefIndex>` into metadata.
This commit is contained in:
Vadim Petrochenkov
2022-08-28 00:10:06 +03:00
parent 0568b0a3de
commit d8d3b83e3a
24 changed files with 170 additions and 127 deletions

View File

@@ -259,11 +259,11 @@ impl fmt::Display for ImplPolarity {
}
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)]
pub enum Visibility {
pub enum Visibility<Id = LocalDefId> {
/// Visible everywhere (including in other crates).
Public,
/// Visible only in the given crate-local module.
Restricted(DefId),
Restricted(Id),
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
@@ -354,28 +354,45 @@ impl<'tcx> DefIdTree for TyCtxt<'tcx> {
}
}
impl Visibility {
/// Returns `true` if an item with this visibility is accessible from the given block.
pub fn is_accessible_from<T: DefIdTree>(self, module: DefId, tree: T) -> bool {
let restriction = match self {
// Public items are visible everywhere.
Visibility::Public => return true,
// Restricted items are visible in an arbitrary local module.
Visibility::Restricted(other) if other.krate != module.krate => return false,
Visibility::Restricted(module) => module,
};
impl<Id> Visibility<Id> {
pub fn is_public(self) -> bool {
matches!(self, Visibility::Public)
}
tree.is_descendant_of(module, restriction)
pub fn map_id<OutId>(self, f: impl FnOnce(Id) -> OutId) -> Visibility<OutId> {
match self {
Visibility::Public => Visibility::Public,
Visibility::Restricted(id) => Visibility::Restricted(f(id)),
}
}
}
impl<Id: Into<DefId>> Visibility<Id> {
pub fn to_def_id(self) -> Visibility<DefId> {
self.map_id(Into::into)
}
/// Returns `true` if an item with this visibility is accessible from the given module.
pub fn is_accessible_from(self, module: impl Into<DefId>, tree: impl DefIdTree) -> bool {
match self {
// Public items are visible everywhere.
Visibility::Public => true,
Visibility::Restricted(id) => tree.is_descendant_of(module.into(), id.into()),
}
}
/// Returns `true` if this visibility is at least as accessible as the given visibility
pub fn is_at_least<T: DefIdTree>(self, vis: Visibility, tree: T) -> bool {
let vis_restriction = match vis {
Visibility::Public => return self == Visibility::Public,
Visibility::Restricted(module) => module,
};
pub fn is_at_least(self, vis: Visibility<impl Into<DefId>>, tree: impl DefIdTree) -> bool {
match vis {
Visibility::Public => self.is_public(),
Visibility::Restricted(id) => self.is_accessible_from(id, tree),
}
}
}
self.is_accessible_from(vis_restriction, tree)
impl Visibility<DefId> {
pub fn expect_local(self) -> Visibility {
self.map_id(|id| id.expect_local())
}
// Returns `true` if this item is visible anywhere in the local crate.
@@ -385,10 +402,6 @@ impl Visibility {
Visibility::Restricted(def_id) => def_id.is_local(),
}
}
pub fn is_public(self) -> bool {
matches!(self, Visibility::Public)
}
}
/// The crate variances map is computed during typeck and contains the
@@ -1790,7 +1803,7 @@ pub enum VariantDiscr {
pub struct FieldDef {
pub did: DefId,
pub name: Symbol,
pub vis: Visibility,
pub vis: Visibility<DefId>,
}
impl PartialEq for FieldDef {