From 6586c37beca21869f698ef2de10d1df7be7e7879 Mon Sep 17 00:00:00 2001 From: Andreas Jonson Date: Wed, 23 Sep 2020 08:09:16 +0200 Subject: [PATCH] Move MiniSet to data_structures remove the need for T to be copy from MiniSet as was done for MiniMap --- Cargo.lock | 2 - compiler/rustc_data_structures/src/lib.rs | 1 + .../rustc_data_structures/src/mini_set.rs | 41 +++++++++++++++++ compiler/rustc_infer/Cargo.toml | 1 - .../rustc_infer/src/infer/outlives/verify.rs | 2 +- compiler/rustc_middle/Cargo.toml | 1 - compiler/rustc_middle/src/ty/outlives.rs | 2 +- compiler/rustc_middle/src/ty/print/mod.rs | 2 +- compiler/rustc_middle/src/ty/walk.rs | 44 +------------------ 9 files changed, 46 insertions(+), 50 deletions(-) create mode 100644 compiler/rustc_data_structures/src/mini_set.rs diff --git a/Cargo.lock b/Cargo.lock index 68288916e6d..26a9e64b85a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3638,7 +3638,6 @@ dependencies = [ name = "rustc_infer" version = "0.0.0" dependencies = [ - "arrayvec", "rustc_ast", "rustc_data_structures", "rustc_errors", @@ -3778,7 +3777,6 @@ dependencies = [ name = "rustc_middle" version = "0.0.0" dependencies = [ - "arrayvec", "bitflags", "chalk-ir", "measureme", diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 1f977805f5e..5990e94ab7e 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -102,6 +102,7 @@ pub mod work_queue; pub use atomic_ref::AtomicRef; pub mod frozen; pub mod mini_map; +pub mod mini_set; pub mod tagged_ptr; pub mod temp_dir; pub mod unhash; diff --git a/compiler/rustc_data_structures/src/mini_set.rs b/compiler/rustc_data_structures/src/mini_set.rs new file mode 100644 index 00000000000..9d45af723de --- /dev/null +++ b/compiler/rustc_data_structures/src/mini_set.rs @@ -0,0 +1,41 @@ +use crate::fx::FxHashSet; +use arrayvec::ArrayVec; +use std::hash::Hash; +/// Small-storage-optimized implementation of a set. +/// +/// Stores elements in a small array up to a certain length +/// and switches to `HashSet` when that length is exceeded. +pub enum MiniSet { + Array(ArrayVec<[T; 8]>), + Set(FxHashSet), +} + +impl MiniSet { + /// Creates an empty `MiniSet`. + pub fn new() -> Self { + MiniSet::Array(ArrayVec::new()) + } + + /// Adds a value to the set. + /// + /// If the set did not have this value present, true is returned. + /// + /// If the set did have this value present, false is returned. + pub fn insert(&mut self, elem: T) -> bool { + match self { + MiniSet::Array(array) => { + if array.iter().any(|e| *e == elem) { + false + } else { + if let Err(error) = array.try_push(elem) { + let mut set: FxHashSet = array.drain(..).collect(); + set.insert(error.element()); + *self = MiniSet::Set(set); + } + true + } + } + MiniSet::Set(set) => set.insert(elem), + } + } +} diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index a8c1a370cef..5dba4106c94 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -21,5 +21,4 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.0", features = ["union", "may_dangle"] } -arrayvec = { version = "0.5.1", default-features = false } rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs index e06bfb59580..21b0836563f 100644 --- a/compiler/rustc_infer/src/infer/outlives/verify.rs +++ b/compiler/rustc_infer/src/infer/outlives/verify.rs @@ -1,9 +1,9 @@ use crate::infer::outlives::env::RegionBoundPairs; use crate::infer::{GenericKind, VerifyBound}; use rustc_data_structures::captures::Captures; +use rustc_data_structures::mini_set::MiniSet; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; -use rustc_middle::ty::walk::MiniSet; use rustc_middle::ty::{self, Ty, TyCtxt}; /// The `TypeOutlives` struct has the job of "lowering" a `T: 'a` diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 1d84ddad7f5..a5a860a38b3 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -28,6 +28,5 @@ rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } chalk-ir = "0.21.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } -arrayvec = { version = "0.5.1", default-features = false } measureme = "0.7.1" rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_middle/src/ty/outlives.rs b/compiler/rustc_middle/src/ty/outlives.rs index 01649f44c88..ca992d36e95 100644 --- a/compiler/rustc_middle/src/ty/outlives.rs +++ b/compiler/rustc_middle/src/ty/outlives.rs @@ -3,8 +3,8 @@ // RFC for reference. use crate::ty::subst::{GenericArg, GenericArgKind}; -use crate::ty::walk::MiniSet; use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc_data_structures::mini_set::MiniSet; use smallvec::SmallVec; #[derive(Debug)] diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index f315292dab5..225ea2399fb 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -2,9 +2,9 @@ use crate::ty::subst::{GenericArg, Subst}; use crate::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::mini_set::MiniSet; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; -use rustc_middle::ty::walk::MiniSet; // `pretty` is a separate module only for organization. mod pretty; diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 7afa6e6cc05..80ade7dda4c 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -3,50 +3,8 @@ use crate::ty; use crate::ty::subst::{GenericArg, GenericArgKind}; -use arrayvec::ArrayVec; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::mini_set::MiniSet; use smallvec::{self, SmallVec}; -use std::hash::Hash; - -/// Small-storage-optimized implementation of a set -/// made specifically for walking type tree. -/// -/// Stores elements in a small array up to a certain length -/// and switches to `HashSet` when that length is exceeded. -pub enum MiniSet { - Array(ArrayVec<[T; 8]>), - Set(FxHashSet), -} - -impl MiniSet { - /// Creates an empty `MiniSet`. - pub fn new() -> Self { - MiniSet::Array(ArrayVec::new()) - } - - /// Adds a value to the set. - /// - /// If the set did not have this value present, true is returned. - /// - /// If the set did have this value present, false is returned. - pub fn insert(&mut self, elem: T) -> bool { - match self { - MiniSet::Array(array) => { - if array.iter().any(|e| *e == elem) { - false - } else { - if array.try_push(elem).is_err() { - let mut set: FxHashSet = array.iter().copied().collect(); - set.insert(elem); - *self = MiniSet::Set(set); - } - true - } - } - MiniSet::Set(set) => set.insert(elem), - } - } -} // The TypeWalker's stack is hot enough that it's worth going to some effort to // avoid heap allocations.