Use a slice in DefIdForest.
This commit is contained in:
parent
6c2ee885e6
commit
f72f15ca28
3 changed files with 22 additions and 25 deletions
|
@ -1515,8 +1515,7 @@ rustc_queries! {
|
||||||
/// check whether the forest is empty.
|
/// check whether the forest is empty.
|
||||||
query type_uninhabited_from(
|
query type_uninhabited_from(
|
||||||
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
|
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
|
||||||
) -> ty::inhabitedness::DefIdForest {
|
) -> ty::inhabitedness::DefIdForest<'tcx> {
|
||||||
storage(ArenaCacheSelector<'tcx>)
|
|
||||||
desc { "computing the inhabitedness of `{:?}`", key }
|
desc { "computing the inhabitedness of `{:?}`", key }
|
||||||
remap_env_constness
|
remap_env_constness
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ use crate::ty::{DefId, DefIdTree};
|
||||||
use rustc_span::def_id::CRATE_DEF_ID;
|
use rustc_span::def_id::CRATE_DEF_ID;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use DefIdForest::*;
|
use DefIdForest::*;
|
||||||
|
|
||||||
|
@ -18,14 +17,13 @@ use DefIdForest::*;
|
||||||
/// We store the minimal set of `DefId`s required to represent the whole set. If A and B are
|
/// We store the minimal set of `DefId`s required to represent the whole set. If A and B are
|
||||||
/// `DefId`s in the `DefIdForest`, and A is a parent of B, then only A will be stored. When this is
|
/// `DefId`s in the `DefIdForest`, and A is a parent of B, then only A will be stored. When this is
|
||||||
/// used with `type_uninhabited_from`, there will very rarely be more than one `DefId` stored.
|
/// used with `type_uninhabited_from`, there will very rarely be more than one `DefId` stored.
|
||||||
#[derive(Clone, HashStable, Debug)]
|
#[derive(Copy, Clone, HashStable, Debug)]
|
||||||
pub enum DefIdForest {
|
pub enum DefIdForest<'a> {
|
||||||
Empty,
|
Empty,
|
||||||
Single(DefId),
|
Single(DefId),
|
||||||
/// This variant is very rare.
|
/// This variant is very rare.
|
||||||
/// Invariant: >1 elements
|
/// Invariant: >1 elements
|
||||||
/// We use `Arc` because this is used in the output of a query.
|
Multiple(&'a [DefId]),
|
||||||
Multiple(Arc<[DefId]>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tests whether a slice of roots contains a given DefId.
|
/// Tests whether a slice of roots contains a given DefId.
|
||||||
|
@ -34,21 +32,21 @@ fn slice_contains<'tcx>(tcx: TyCtxt<'tcx>, slice: &[DefId], id: DefId) -> bool {
|
||||||
slice.iter().any(|root_id| tcx.is_descendant_of(id, *root_id))
|
slice.iter().any(|root_id| tcx.is_descendant_of(id, *root_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> DefIdForest {
|
impl<'tcx> DefIdForest<'tcx> {
|
||||||
/// Creates an empty forest.
|
/// Creates an empty forest.
|
||||||
pub fn empty() -> DefIdForest {
|
pub fn empty() -> DefIdForest<'tcx> {
|
||||||
DefIdForest::Empty
|
DefIdForest::Empty
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a forest consisting of a single tree representing the entire
|
/// Creates a forest consisting of a single tree representing the entire
|
||||||
/// crate.
|
/// crate.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn full() -> DefIdForest {
|
pub fn full() -> DefIdForest<'tcx> {
|
||||||
DefIdForest::from_id(CRATE_DEF_ID.to_def_id())
|
DefIdForest::from_id(CRATE_DEF_ID.to_def_id())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a forest containing a `DefId` and all its descendants.
|
/// Creates a forest containing a `DefId` and all its descendants.
|
||||||
pub fn from_id(id: DefId) -> DefIdForest {
|
pub fn from_id(id: DefId) -> DefIdForest<'tcx> {
|
||||||
DefIdForest::Single(id)
|
DefIdForest::Single(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,11 +59,11 @@ impl<'tcx> DefIdForest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only allocates in the rare `Multiple` case.
|
// Only allocates in the rare `Multiple` case.
|
||||||
fn from_slice(root_ids: &[DefId]) -> DefIdForest {
|
fn from_vec(tcx: TyCtxt<'tcx>, root_ids: SmallVec<[DefId; 1]>) -> DefIdForest<'tcx> {
|
||||||
match root_ids {
|
match &root_ids[..] {
|
||||||
[] => Empty,
|
[] => Empty,
|
||||||
[id] => Single(*id),
|
[id] => Single(*id),
|
||||||
_ => DefIdForest::Multiple(root_ids.into()),
|
_ => DefIdForest::Multiple(tcx.arena.alloc_from_iter(root_ids)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,9 +86,9 @@ impl<'tcx> DefIdForest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the intersection of a collection of forests.
|
/// Calculate the intersection of a collection of forests.
|
||||||
pub fn intersection<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest
|
pub fn intersection<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest<'tcx>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = DefIdForest>,
|
I: IntoIterator<Item = DefIdForest<'tcx>>,
|
||||||
{
|
{
|
||||||
let mut iter = iter.into_iter();
|
let mut iter = iter.into_iter();
|
||||||
let mut ret: SmallVec<[_; 1]> = if let Some(first) = iter.next() {
|
let mut ret: SmallVec<[_; 1]> = if let Some(first) = iter.next() {
|
||||||
|
@ -114,13 +112,13 @@ impl<'tcx> DefIdForest {
|
||||||
mem::swap(&mut next_ret, &mut ret);
|
mem::swap(&mut next_ret, &mut ret);
|
||||||
next_ret.clear();
|
next_ret.clear();
|
||||||
}
|
}
|
||||||
DefIdForest::from_slice(&ret)
|
DefIdForest::from_vec(tcx, ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the union of a collection of forests.
|
/// Calculate the union of a collection of forests.
|
||||||
pub fn union<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest
|
pub fn union<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest<'tcx>
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = DefIdForest>,
|
I: IntoIterator<Item = DefIdForest<'tcx>>,
|
||||||
{
|
{
|
||||||
let mut ret: SmallVec<[_; 1]> = SmallVec::new();
|
let mut ret: SmallVec<[_; 1]> = SmallVec::new();
|
||||||
let mut next_ret: SmallVec<[_; 1]> = SmallVec::new();
|
let mut next_ret: SmallVec<[_; 1]> = SmallVec::new();
|
||||||
|
@ -142,6 +140,6 @@ impl<'tcx> DefIdForest {
|
||||||
mem::swap(&mut next_ret, &mut ret);
|
mem::swap(&mut next_ret, &mut ret);
|
||||||
next_ret.clear();
|
next_ret.clear();
|
||||||
}
|
}
|
||||||
DefIdForest::from_slice(&ret)
|
DefIdForest::from_vec(tcx, ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ impl<'tcx> AdtDef {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
substs: SubstsRef<'tcx>,
|
substs: SubstsRef<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> DefIdForest {
|
) -> DefIdForest<'tcx> {
|
||||||
// Non-exhaustive ADTs from other crates are always considered inhabited.
|
// Non-exhaustive ADTs from other crates are always considered inhabited.
|
||||||
if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
|
if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
|
||||||
DefIdForest::empty()
|
DefIdForest::empty()
|
||||||
|
@ -135,7 +135,7 @@ impl<'tcx> VariantDef {
|
||||||
substs: SubstsRef<'tcx>,
|
substs: SubstsRef<'tcx>,
|
||||||
adt_kind: AdtKind,
|
adt_kind: AdtKind,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> DefIdForest {
|
) -> DefIdForest<'tcx> {
|
||||||
let is_enum = match adt_kind {
|
let is_enum = match adt_kind {
|
||||||
// For now, `union`s are never considered uninhabited.
|
// For now, `union`s are never considered uninhabited.
|
||||||
// The precise semantics of inhabitedness with respect to unions is currently undecided.
|
// The precise semantics of inhabitedness with respect to unions is currently undecided.
|
||||||
|
@ -163,7 +163,7 @@ impl<'tcx> FieldDef {
|
||||||
substs: SubstsRef<'tcx>,
|
substs: SubstsRef<'tcx>,
|
||||||
is_enum: bool,
|
is_enum: bool,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> DefIdForest {
|
) -> DefIdForest<'tcx> {
|
||||||
let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env);
|
let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env);
|
||||||
// FIXME(canndrew): Currently enum fields are (incorrectly) stored with
|
// FIXME(canndrew): Currently enum fields are (incorrectly) stored with
|
||||||
// `Visibility::Invisible` so we need to override `self.vis` if we're
|
// `Visibility::Invisible` so we need to override `self.vis` if we're
|
||||||
|
@ -190,7 +190,7 @@ impl<'tcx> TyS<'tcx> {
|
||||||
&'tcx self,
|
&'tcx self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> DefIdForest {
|
) -> DefIdForest<'tcx> {
|
||||||
tcx.type_uninhabited_from(param_env.and(self)).clone()
|
tcx.type_uninhabited_from(param_env.and(self)).clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ impl<'tcx> TyS<'tcx> {
|
||||||
pub(crate) fn type_uninhabited_from<'tcx>(
|
pub(crate) fn type_uninhabited_from<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
|
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
|
||||||
) -> DefIdForest {
|
) -> DefIdForest<'tcx> {
|
||||||
let ty = key.value;
|
let ty = key.value;
|
||||||
let param_env = key.param_env;
|
let param_env = key.param_env;
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue