Skip to content

Move MiniSet to data_structures #77028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3638,7 +3638,6 @@ dependencies = [
name = "rustc_infer"
version = "0.0.0"
dependencies = [
"arrayvec",
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
Expand Down Expand Up @@ -3778,7 +3777,6 @@ dependencies = [
name = "rustc_middle"
version = "0.0.0"
dependencies = [
"arrayvec",
"bitflags",
"chalk-ir",
"measureme",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
41 changes: 41 additions & 0 deletions compiler/rustc_data_structures/src/mini_set.rs
Original file line number Diff line number Diff line change
@@ -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<T> {
Array(ArrayVec<[T; 8]>),
Set(FxHashSet<T>),
}

impl<T: Eq + Hash> MiniSet<T> {
/// 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<T> = array.drain(..).collect();
set.insert(error.element());
*self = MiniSet::Set(set);
}
true
}
}
MiniSet::Set(set) => set.insert(elem),
}
}
}
1 change: 0 additions & 1 deletion compiler/rustc_infer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/outlives/verify.rs
Original file line number Diff line number Diff line change
@@ -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`
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_middle/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/outlives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/print/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
44 changes: 1 addition & 43 deletions compiler/rustc_middle/src/ty/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> {
Array(ArrayVec<[T; 8]>),
Set(FxHashSet<T>),
}

impl<T: Eq + Hash + Copy> MiniSet<T> {
/// 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<T> = 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.
Expand Down