From f72f15ca2861f8635f6240b083952f3bd3b78dee Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 1 Feb 2022 18:27:49 +0100 Subject: [PATCH] Use a slice in DefIdForest. --- compiler/rustc_middle/src/query/mod.rs | 3 +- .../src/ty/inhabitedness/def_id_forest.rs | 34 +++++++++---------- .../rustc_middle/src/ty/inhabitedness/mod.rs | 10 +++--- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b7ee5268f49..387db37f783 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1515,8 +1515,7 @@ rustc_queries! { /// check whether the forest is empty. query type_uninhabited_from( key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> - ) -> ty::inhabitedness::DefIdForest { - storage(ArenaCacheSelector<'tcx>) + ) -> ty::inhabitedness::DefIdForest<'tcx> { desc { "computing the inhabitedness of `{:?}`", key } remap_env_constness } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs b/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs index 55807874705..c4ad698ba76 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs @@ -3,7 +3,6 @@ use crate::ty::{DefId, DefIdTree}; use rustc_span::def_id::CRATE_DEF_ID; use smallvec::SmallVec; use std::mem; -use std::sync::Arc; 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 /// `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. -#[derive(Clone, HashStable, Debug)] -pub enum DefIdForest { +#[derive(Copy, Clone, HashStable, Debug)] +pub enum DefIdForest<'a> { Empty, Single(DefId), /// This variant is very rare. /// Invariant: >1 elements - /// We use `Arc` because this is used in the output of a query. - Multiple(Arc<[DefId]>), + Multiple(&'a [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)) } -impl<'tcx> DefIdForest { +impl<'tcx> DefIdForest<'tcx> { /// Creates an empty forest. - pub fn empty() -> DefIdForest { + pub fn empty() -> DefIdForest<'tcx> { DefIdForest::Empty } /// Creates a forest consisting of a single tree representing the entire /// crate. #[inline] - pub fn full() -> DefIdForest { + pub fn full() -> DefIdForest<'tcx> { DefIdForest::from_id(CRATE_DEF_ID.to_def_id()) } /// 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) } @@ -61,11 +59,11 @@ impl<'tcx> DefIdForest { } // Only allocates in the rare `Multiple` case. - fn from_slice(root_ids: &[DefId]) -> DefIdForest { - match root_ids { + fn from_vec(tcx: TyCtxt<'tcx>, root_ids: SmallVec<[DefId; 1]>) -> DefIdForest<'tcx> { + match &root_ids[..] { [] => Empty, [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. - pub fn intersection(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest + pub fn intersection(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest<'tcx> where - I: IntoIterator, + I: IntoIterator>, { let mut iter = iter.into_iter(); 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); next_ret.clear(); } - DefIdForest::from_slice(&ret) + DefIdForest::from_vec(tcx, ret) } /// Calculate the union of a collection of forests. - pub fn union(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest + pub fn union(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest<'tcx> where - I: IntoIterator, + I: IntoIterator>, { let mut 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); next_ret.clear(); } - DefIdForest::from_slice(&ret) + DefIdForest::from_vec(tcx, ret) } } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index ca053d704eb..14ddccbfd83 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -112,7 +112,7 @@ impl<'tcx> AdtDef { tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, - ) -> DefIdForest { + ) -> DefIdForest<'tcx> { // Non-exhaustive ADTs from other crates are always considered inhabited. if self.is_variant_list_non_exhaustive() && !self.did.is_local() { DefIdForest::empty() @@ -135,7 +135,7 @@ impl<'tcx> VariantDef { substs: SubstsRef<'tcx>, adt_kind: AdtKind, param_env: ty::ParamEnv<'tcx>, - ) -> DefIdForest { + ) -> DefIdForest<'tcx> { let is_enum = match adt_kind { // For now, `union`s are never considered uninhabited. // The precise semantics of inhabitedness with respect to unions is currently undecided. @@ -163,7 +163,7 @@ impl<'tcx> FieldDef { substs: SubstsRef<'tcx>, is_enum: bool, param_env: ty::ParamEnv<'tcx>, - ) -> DefIdForest { + ) -> DefIdForest<'tcx> { let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env); // FIXME(canndrew): Currently enum fields are (incorrectly) stored with // `Visibility::Invisible` so we need to override `self.vis` if we're @@ -190,7 +190,7 @@ impl<'tcx> TyS<'tcx> { &'tcx self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - ) -> DefIdForest { + ) -> DefIdForest<'tcx> { tcx.type_uninhabited_from(param_env.and(self)).clone() } } @@ -199,7 +199,7 @@ impl<'tcx> TyS<'tcx> { pub(crate) fn type_uninhabited_from<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, -) -> DefIdForest { +) -> DefIdForest<'tcx> { let ty = key.value; let param_env = key.param_env; match *ty.kind() {