Skip to content
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

pattern analysis: Require enum indices to be contiguous #123242

Merged
merged 1 commit into from Mar 31, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 4 additions & 7 deletions compiler/rustc_pattern_analysis/src/constructor.rs
Expand Up @@ -155,13 +155,13 @@ use std::iter::once;
use smallvec::SmallVec;

use rustc_apfloat::ieee::{DoubleS, IeeeFloat, SingleS};
use rustc_index::bit_set::GrowableBitSet;
use rustc_index::bit_set::{BitSet, GrowableBitSet};
use rustc_index::IndexVec;

use self::Constructor::*;
use self::MaybeInfiniteInt::*;
use self::SliceKind::*;

use crate::index;
use crate::PatCx;

/// Whether we have seen a constructor in the column or not.
Expand Down Expand Up @@ -920,10 +920,7 @@ pub enum ConstructorSet<Cx: PatCx> {
Struct { empty: bool },
/// This type has the following list of constructors. If `variants` is empty and
/// `non_exhaustive` is false, don't use this; use `NoConstructors` instead.
Variants {
variants: index::IdxContainer<Cx::VariantIdx, VariantVisibility>,
non_exhaustive: bool,
},
Variants { variants: IndexVec<Cx::VariantIdx, VariantVisibility>, non_exhaustive: bool },
/// The type is `&T`.
Ref,
/// The type is a union.
Expand Down Expand Up @@ -1025,7 +1022,7 @@ impl<Cx: PatCx> ConstructorSet<Cx> {
}
}
ConstructorSet::Variants { variants, non_exhaustive } => {
let mut seen_set = index::IdxSet::new_empty(variants.len());
let mut seen_set = BitSet::new_empty(variants.len());
for idx in seen.iter().filter_map(|c| c.as_variant()) {
seen_set.insert(idx);
}
Expand Down
49 changes: 4 additions & 45 deletions compiler/rustc_pattern_analysis/src/lib.rs
Expand Up @@ -25,50 +25,9 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

use std::fmt;

#[cfg(feature = "rustc")]
pub mod index {
// Faster version when the indices of variants are `0..variants.len()`.
pub use rustc_index::bit_set::BitSet as IdxSet;
pub use rustc_index::Idx;
pub use rustc_index::IndexVec as IdxContainer;
}
#[cfg(not(feature = "rustc"))]
pub mod index {
// Slower version when the indices of variants are something else.
pub trait Idx: Copy + PartialEq + Eq + std::hash::Hash {}
impl<T: Copy + PartialEq + Eq + std::hash::Hash> Idx for T {}

#[derive(Debug)]
pub struct IdxContainer<K, V>(pub rustc_hash::FxHashMap<K, V>);
impl<K: Idx, V> IdxContainer<K, V> {
pub fn len(&self) -> usize {
self.0.len()
}
pub fn iter_enumerated(&self) -> impl Iterator<Item = (K, &V)> {
self.0.iter().map(|(k, v)| (*k, v))
}
}

impl<V> FromIterator<V> for IdxContainer<usize, V> {
fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
Self(iter.into_iter().enumerate().collect())
}
}

#[derive(Debug)]
pub struct IdxSet<T>(pub rustc_hash::FxHashSet<T>);
impl<T: Idx> IdxSet<T> {
pub fn new_empty(_len: usize) -> Self {
Self(Default::default())
}
pub fn contains(&self, elem: T) -> bool {
self.0.contains(&elem)
}
pub fn insert(&mut self, elem: T) {
self.0.insert(elem);
}
}
}
// Re-exports to avoid rustc_index version issues.
pub use rustc_index::Idx;
pub use rustc_index::IndexVec;

#[cfg(feature = "rustc")]
use rustc_middle::ty::Ty;
Expand Down Expand Up @@ -96,7 +55,7 @@ pub trait PatCx: Sized + fmt::Debug {
/// Errors that can abort analysis.
type Error: fmt::Debug;
/// The index of an enum variant.
type VariantIdx: Clone + index::Idx + fmt::Debug;
type VariantIdx: Clone + Idx + fmt::Debug;
/// A string literal
type StrLit: Clone + PartialEq + fmt::Debug;
/// Extra data to store in a match arm.
Expand Down