Skip to content

Commit c24ac73

Browse files
Rollup merge of rust-lang#120039 - Nadrieril:remove-idx, r=compiler-errors
pat_analysis: Don't rely on contiguous `VariantId`s outside of rustc Today's pattern_analysis uses `BitSet` and `IndexVec` on the provided enum variant ids, which only makes sense if these ids count the variants from 0. In rust-analyzer, the variant ids are global interning ids, which would make `BitSet` and `IndexVec` ridiculously wasteful. In this PR I add some shims to use `FxHashSet`/`FxHashMap` instead outside of rustc. r? ``@compiler-errors``
2 parents b7b973f + 19d6f06 commit c24ac73

File tree

4 files changed

+49
-6
lines changed

4 files changed

+49
-6
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4355,6 +4355,7 @@ name = "rustc_pattern_analysis"
43554355
version = "0.0.0"
43564356
dependencies = [
43574357
"derivative",
4358+
"rustc-hash",
43584359
"rustc_apfloat",
43594360
"rustc_arena",
43604361
"rustc_data_structures",

compiler/rustc_pattern_analysis/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2021"
66
[dependencies]
77
# tidy-alphabetical-start
88
derivative = "2.2.0"
9+
rustc-hash = "1.1.0"
910
rustc_apfloat = "0.2.0"
1011
rustc_arena = { path = "../rustc_arena", optional = true }
1112
rustc_data_structures = { path = "../rustc_data_structures", optional = true }

compiler/rustc_pattern_analysis/src/constructor.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,13 @@ use std::iter::once;
155155
use smallvec::SmallVec;
156156

157157
use rustc_apfloat::ieee::{DoubleS, IeeeFloat, SingleS};
158-
use rustc_index::bit_set::{BitSet, GrowableBitSet};
159-
use rustc_index::IndexVec;
158+
use rustc_index::bit_set::GrowableBitSet;
160159

161160
use self::Constructor::*;
162161
use self::MaybeInfiniteInt::*;
163162
use self::SliceKind::*;
164163

164+
use crate::index;
165165
use crate::usefulness::PlaceCtxt;
166166
use crate::TypeCx;
167167

@@ -804,7 +804,10 @@ pub enum ConstructorSet<Cx: TypeCx> {
804804
Struct { empty: bool },
805805
/// This type has the following list of constructors. If `variants` is empty and
806806
/// `non_exhaustive` is false, don't use this; use `NoConstructors` instead.
807-
Variants { variants: IndexVec<Cx::VariantIdx, VariantVisibility>, non_exhaustive: bool },
807+
Variants {
808+
variants: index::IdxContainer<Cx::VariantIdx, VariantVisibility>,
809+
non_exhaustive: bool,
810+
},
808811
/// The type is `&T`.
809812
Ref,
810813
/// The type is a union.
@@ -904,7 +907,7 @@ impl<Cx: TypeCx> ConstructorSet<Cx> {
904907
}
905908
}
906909
ConstructorSet::Variants { variants, non_exhaustive } => {
907-
let mut seen_set: BitSet<_> = BitSet::new_empty(variants.len());
910+
let mut seen_set = index::IdxSet::new_empty(variants.len());
908911
for idx in seen.iter().map(|c| c.as_variant().unwrap()) {
909912
seen_set.insert(idx);
910913
}

compiler/rustc_pattern_analysis/src/lib.rs

+40-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,45 @@ rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
2121

2222
use std::fmt;
2323

24-
use rustc_index::Idx;
24+
#[cfg(feature = "rustc")]
25+
pub mod index {
26+
// Faster version when the indices of variants are `0..variants.len()`.
27+
pub use rustc_index::bit_set::BitSet as IdxSet;
28+
pub use rustc_index::Idx;
29+
pub use rustc_index::IndexVec as IdxContainer;
30+
}
31+
#[cfg(not(feature = "rustc"))]
32+
pub mod index {
33+
// Slower version when the indices of variants are something else.
34+
pub trait Idx: Copy + PartialEq + Eq + std::hash::Hash {}
35+
impl<T: Copy + PartialEq + Eq + std::hash::Hash> Idx for T {}
36+
37+
#[derive(Debug)]
38+
pub struct IdxContainer<K, V>(pub rustc_hash::FxHashMap<K, V>);
39+
impl<K: Idx, V> IdxContainer<K, V> {
40+
pub fn len(&self) -> usize {
41+
self.0.len()
42+
}
43+
pub fn iter_enumerated(&self) -> impl Iterator<Item = (K, &V)> {
44+
self.0.iter().map(|(k, v)| (*k, v))
45+
}
46+
}
47+
48+
#[derive(Debug)]
49+
pub struct IdxSet<T>(pub rustc_hash::FxHashSet<T>);
50+
impl<T: Idx> IdxSet<T> {
51+
pub fn new_empty(_len: usize) -> Self {
52+
Self(Default::default())
53+
}
54+
pub fn contains(&self, elem: T) -> bool {
55+
self.0.contains(&elem)
56+
}
57+
pub fn insert(&mut self, elem: T) {
58+
self.0.insert(elem);
59+
}
60+
}
61+
}
62+
2563
#[cfg(feature = "rustc")]
2664
use rustc_middle::ty::Ty;
2765
#[cfg(feature = "rustc")]
@@ -48,7 +86,7 @@ pub trait TypeCx: Sized + fmt::Debug {
4886
/// Errors that can abort analysis.
4987
type Error: fmt::Debug;
5088
/// The index of an enum variant.
51-
type VariantIdx: Clone + Idx;
89+
type VariantIdx: Clone + index::Idx + fmt::Debug;
5290
/// A string literal
5391
type StrLit: Clone + PartialEq + fmt::Debug;
5492
/// Extra data to store in a match arm.

0 commit comments

Comments
 (0)