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:
@@ -2,6 +2,7 @@ use crate::ty;
|
||||
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_span::def_id::DefId;
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::Span;
|
||||
|
||||
@@ -18,7 +19,7 @@ pub struct ModChild {
|
||||
/// Local variables cannot be exported, so this `Res` doesn't need the ID parameter.
|
||||
pub res: Res<!>,
|
||||
/// Visibility of the item.
|
||||
pub vis: ty::Visibility,
|
||||
pub vis: ty::Visibility<DefId>,
|
||||
/// Span of the item.
|
||||
pub span: Span,
|
||||
/// A proper `macro_rules` item (not a reexport).
|
||||
|
||||
@@ -1607,7 +1607,7 @@ rustc_queries! {
|
||||
desc { "looking up late bound vars" }
|
||||
}
|
||||
|
||||
query visibility(def_id: DefId) -> ty::Visibility {
|
||||
query visibility(def_id: DefId) -> ty::Visibility<DefId> {
|
||||
desc { |tcx| "computing visibility of `{}`", tcx.def_path_str(def_id) }
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ impl AssocItem {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility {
|
||||
pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility<DefId> {
|
||||
tcx.visibility(self.def_id)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ use crate::ty::{
|
||||
FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List,
|
||||
ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region,
|
||||
RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy,
|
||||
Visibility,
|
||||
};
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
@@ -1728,6 +1729,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
.chain(self.crates(()).iter().copied())
|
||||
.flat_map(move |cnum| self.traits_in_crate(cnum).iter().copied())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
|
||||
self.visibility(def_id.to_def_id()).expect_local()
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait implemented for all `X<'a>` types that can be safely and
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::def_id::{DefId, DefIndex};
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
|
||||
use crate::middle::exported_symbols::ExportedSymbol;
|
||||
@@ -60,7 +60,7 @@ trivially_parameterized_over_tcx! {
|
||||
ty::ImplPolarity,
|
||||
ty::ReprOptions,
|
||||
ty::TraitDef,
|
||||
ty::Visibility,
|
||||
ty::Visibility<DefIndex>,
|
||||
ty::adjustment::CoerceUnsizedInfo,
|
||||
ty::fast_reject::SimplifiedTypeGen<DefId>,
|
||||
rustc_ast::Attribute,
|
||||
|
||||
Reference in New Issue
Block a user