Skip to content

Commit f840fcb

Browse files
committed
Simplify Arena to use a generic index
1 parent 988f1dd commit f840fcb

File tree

17 files changed

+175
-185
lines changed

17 files changed

+175
-185
lines changed

crates/ra_arena/src/lib.rs

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use std::{
44
fmt,
5+
hash::{Hash, Hasher},
56
iter::FromIterator,
67
marker::PhantomData,
78
ops::{Index, IndexMut},
@@ -36,86 +37,110 @@ impl fmt::Display for RawId {
3637
}
3738
}
3839

39-
#[derive(Clone, PartialEq, Eq)]
40-
pub struct Arena<ID, T> {
41-
data: Vec<T>,
42-
_ty: PhantomData<ID>,
40+
pub struct Idx<T> {
41+
raw: RawId,
42+
_ty: PhantomData<fn() -> T>,
4343
}
4444

45-
impl<ID: ArenaId, T: fmt::Debug> fmt::Debug for Arena<ID, T> {
46-
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
47-
fmt.debug_struct("Arena").field("len", &self.len()).field("data", &self.data).finish()
45+
impl<T> Clone for Idx<T> {
46+
fn clone(&self) -> Self {
47+
*self
4848
}
4949
}
50+
impl<T> Copy for Idx<T> {}
5051

51-
#[macro_export]
52-
macro_rules! impl_arena_id {
53-
($name:ident) => {
54-
impl $crate::ArenaId for $name {
55-
fn from_raw(raw: $crate::RawId) -> Self {
56-
$name(raw)
57-
}
58-
fn into_raw(self) -> $crate::RawId {
59-
self.0
60-
}
52+
impl<T> PartialEq for Idx<T> {
53+
fn eq(&self, other: &Idx<T>) -> bool {
54+
self.raw == other.raw
55+
}
56+
}
57+
impl<T> Eq for Idx<T> {}
58+
59+
impl<T> Hash for Idx<T> {
60+
fn hash<H: Hasher>(&self, state: &mut H) {
61+
self.raw.hash(state)
62+
}
63+
}
64+
65+
impl<T> fmt::Debug for Idx<T> {
66+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67+
let mut type_name = std::any::type_name::<T>();
68+
if let Some(idx) = type_name.rfind(':') {
69+
type_name = &type_name[idx + 1..]
6170
}
62-
};
71+
write!(f, "Idx::<{}>({})", type_name, self.raw)
72+
}
6373
}
6474

65-
pub trait ArenaId {
66-
fn from_raw(raw: RawId) -> Self;
67-
fn into_raw(self) -> RawId;
75+
impl<T> Idx<T> {
76+
pub fn from_raw(raw: RawId) -> Self {
77+
Idx { raw, _ty: PhantomData }
78+
}
79+
pub fn into_raw(self) -> RawId {
80+
self.raw
81+
}
82+
}
83+
84+
#[derive(Clone, PartialEq, Eq)]
85+
pub struct Arena<T> {
86+
data: Vec<T>,
6887
}
6988

70-
impl<ID, T> Arena<ID, T> {
71-
pub const fn new() -> Arena<ID, T> {
72-
Arena { data: Vec::new(), _ty: PhantomData }
89+
impl<T: fmt::Debug> fmt::Debug for Arena<T> {
90+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
91+
fmt.debug_struct("Arena").field("len", &self.len()).field("data", &self.data).finish()
7392
}
7493
}
7594

76-
impl<ID: ArenaId, T> Arena<ID, T> {
95+
impl<T> Arena<T> {
96+
pub const fn new() -> Arena<T> {
97+
Arena { data: Vec::new() }
98+
}
99+
77100
pub fn len(&self) -> usize {
78101
self.data.len()
79102
}
80103
pub fn is_empty(&self) -> bool {
81104
self.data.is_empty()
82105
}
83-
pub fn alloc(&mut self, value: T) -> ID {
106+
pub fn alloc(&mut self, value: T) -> Idx<T> {
84107
let id = RawId(self.data.len() as u32);
85108
self.data.push(value);
86-
ID::from_raw(id)
109+
Idx::from_raw(id)
87110
}
88-
pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> + ExactSizeIterator + DoubleEndedIterator {
89-
self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value))
111+
pub fn iter(
112+
&self,
113+
) -> impl Iterator<Item = (Idx<T>, &T)> + ExactSizeIterator + DoubleEndedIterator {
114+
self.data.iter().enumerate().map(|(idx, value)| (Idx::from_raw(RawId(idx as u32)), value))
90115
}
91116
}
92117

93-
impl<ID: ArenaId, T> Default for Arena<ID, T> {
94-
fn default() -> Arena<ID, T> {
95-
Arena { data: Vec::new(), _ty: PhantomData }
118+
impl<T> Default for Arena<T> {
119+
fn default() -> Arena<T> {
120+
Arena { data: Vec::new() }
96121
}
97122
}
98123

99-
impl<ID: ArenaId, T> Index<ID> for Arena<ID, T> {
124+
impl<T> Index<Idx<T>> for Arena<T> {
100125
type Output = T;
101-
fn index(&self, idx: ID) -> &T {
126+
fn index(&self, idx: Idx<T>) -> &T {
102127
let idx = idx.into_raw().0 as usize;
103128
&self.data[idx]
104129
}
105130
}
106131

107-
impl<ID: ArenaId, T> IndexMut<ID> for Arena<ID, T> {
108-
fn index_mut(&mut self, idx: ID) -> &mut T {
132+
impl<T> IndexMut<Idx<T>> for Arena<T> {
133+
fn index_mut(&mut self, idx: Idx<T>) -> &mut T {
109134
let idx = idx.into_raw().0 as usize;
110135
&mut self.data[idx]
111136
}
112137
}
113138

114-
impl<ID: ArenaId, T> FromIterator<T> for Arena<ID, T> {
139+
impl<T> FromIterator<T> for Arena<T> {
115140
fn from_iter<I>(iter: I) -> Self
116141
where
117142
I: IntoIterator<Item = T>,
118143
{
119-
Arena { data: Vec::from_iter(iter), _ty: PhantomData }
144+
Arena { data: Vec::from_iter(iter) }
120145
}
121146
}

crates/ra_arena/src/map.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
33
use std::marker::PhantomData;
44

5-
use super::ArenaId;
5+
use crate::Idx;
66

77
/// A map from arena IDs to some other type. Space requirement is O(highest ID).
88
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
9-
pub struct ArenaMap<ID, T> {
10-
v: Vec<Option<T>>,
9+
pub struct ArenaMap<ID, V> {
10+
v: Vec<Option<V>>,
1111
_ty: PhantomData<ID>,
1212
}
1313

14-
impl<ID: ArenaId, T> ArenaMap<ID, T> {
15-
pub fn insert(&mut self, id: ID, t: T) {
14+
impl<T, V> ArenaMap<Idx<T>, V> {
15+
pub fn insert(&mut self, id: Idx<T>, t: V) {
1616
let idx = Self::to_idx(id);
1717
if self.v.capacity() <= idx {
1818
self.v.reserve(idx + 1 - self.v.capacity());
@@ -25,43 +25,43 @@ impl<ID: ArenaId, T> ArenaMap<ID, T> {
2525
self.v[idx] = Some(t);
2626
}
2727

28-
pub fn get(&self, id: ID) -> Option<&T> {
28+
pub fn get(&self, id: Idx<T>) -> Option<&V> {
2929
self.v.get(Self::to_idx(id)).and_then(|it| it.as_ref())
3030
}
3131

32-
pub fn get_mut(&mut self, id: ID) -> Option<&mut T> {
32+
pub fn get_mut(&mut self, id: Idx<T>) -> Option<&mut V> {
3333
self.v.get_mut(Self::to_idx(id)).and_then(|it| it.as_mut())
3434
}
3535

36-
pub fn values(&self) -> impl Iterator<Item = &T> {
36+
pub fn values(&self) -> impl Iterator<Item = &V> {
3737
self.v.iter().filter_map(|o| o.as_ref())
3838
}
3939

40-
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> {
40+
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
4141
self.v.iter_mut().filter_map(|o| o.as_mut())
4242
}
4343

44-
pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> {
44+
pub fn iter(&self) -> impl Iterator<Item = (Idx<T>, &V)> {
4545
self.v.iter().enumerate().filter_map(|(idx, o)| Some((Self::from_idx(idx), o.as_ref()?)))
4646
}
4747

48-
fn to_idx(id: ID) -> usize {
48+
fn to_idx(id: Idx<T>) -> usize {
4949
u32::from(id.into_raw()) as usize
5050
}
5151

52-
fn from_idx(idx: usize) -> ID {
53-
ID::from_raw((idx as u32).into())
52+
fn from_idx(idx: usize) -> Idx<T> {
53+
Idx::from_raw((idx as u32).into())
5454
}
5555
}
5656

57-
impl<ID: ArenaId, T> std::ops::Index<ID> for ArenaMap<ID, T> {
57+
impl<T, V> std::ops::Index<Idx<V>> for ArenaMap<Idx<V>, T> {
5858
type Output = T;
59-
fn index(&self, id: ID) -> &T {
59+
fn index(&self, id: Idx<V>) -> &T {
6060
self.v[Self::to_idx(id)].as_ref().unwrap()
6161
}
6262
}
6363

64-
impl<ID, T> Default for ArenaMap<ID, T> {
64+
impl<T, V> Default for ArenaMap<Idx<V>, T> {
6565
fn default() -> Self {
6666
ArenaMap { v: Vec::new(), _ty: PhantomData }
6767
}

crates/ra_hir_def/src/adt.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub struct StructData {
2727
#[derive(Debug, Clone, PartialEq, Eq)]
2828
pub struct EnumData {
2929
pub name: Name,
30-
pub variants: Arena<LocalEnumVariantId, EnumVariantData>,
30+
pub variants: Arena<EnumVariantData>,
3131
}
3232

3333
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -38,8 +38,8 @@ pub struct EnumVariantData {
3838

3939
#[derive(Debug, Clone, PartialEq, Eq)]
4040
pub enum VariantData {
41-
Record(Arena<LocalStructFieldId, StructFieldData>),
42-
Tuple(Arena<LocalStructFieldId, StructFieldData>),
41+
Record(Arena<StructFieldData>),
42+
Tuple(Arena<StructFieldData>),
4343
Unit,
4444
}
4545

@@ -104,7 +104,7 @@ impl HasChildSource for EnumId {
104104

105105
fn lower_enum(
106106
db: &dyn DefDatabase,
107-
trace: &mut Trace<LocalEnumVariantId, EnumVariantData, ast::EnumVariant>,
107+
trace: &mut Trace<EnumVariantData, ast::EnumVariant>,
108108
ast: &InFile<ast::EnumDef>,
109109
) {
110110
for var in ast.value.variant_list().into_iter().flat_map(|it| it.variants()) {
@@ -128,8 +128,8 @@ impl VariantData {
128128
}
129129
}
130130

131-
pub fn fields(&self) -> &Arena<LocalStructFieldId, StructFieldData> {
132-
const EMPTY: &Arena<LocalStructFieldId, StructFieldData> = &Arena::new();
131+
pub fn fields(&self) -> &Arena<StructFieldData> {
132+
const EMPTY: &Arena<StructFieldData> = &Arena::new();
133133
match &self {
134134
VariantData::Record(fields) | VariantData::Tuple(fields) => fields,
135135
_ => EMPTY,
@@ -183,11 +183,7 @@ pub enum StructKind {
183183

184184
fn lower_struct(
185185
db: &dyn DefDatabase,
186-
trace: &mut Trace<
187-
LocalStructFieldId,
188-
StructFieldData,
189-
Either<ast::TupleFieldDef, ast::RecordFieldDef>,
190-
>,
186+
trace: &mut Trace<StructFieldData, Either<ast::TupleFieldDef, ast::RecordFieldDef>>,
191187
ast: &InFile<ast::StructKind>,
192188
) -> StructKind {
193189
match &ast.value {

crates/ra_hir_def/src/body.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ pub(crate) struct Mark {
121121
/// The body of an item (function, const etc.).
122122
#[derive(Debug, Eq, PartialEq)]
123123
pub struct Body {
124-
pub exprs: Arena<ExprId, Expr>,
125-
pub pats: Arena<PatId, Pat>,
124+
pub exprs: Arena<Expr>,
125+
pub pats: Arena<Pat>,
126126
/// The patterns for the function's parameters. While the parameter types are
127127
/// part of the function signature, the patterns are not (they don't change
128128
/// the external type of the function).

crates/ra_hir_def/src/body/lower.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use crate::{
2424
builtin_type::{BuiltinFloat, BuiltinInt},
2525
db::DefDatabase,
2626
expr::{
27-
ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp,
28-
MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
27+
dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal,
28+
LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
2929
},
3030
item_scope::BuiltinShadowMode,
3131
path::GenericArgs,
@@ -51,7 +51,7 @@ pub(super) fn lower(
5151
exprs: Arena::default(),
5252
pats: Arena::default(),
5353
params: Vec::new(),
54-
body_expr: ExprId::dummy(),
54+
body_expr: dummy_expr_id(),
5555
item_scope: Default::default(),
5656
},
5757
}

crates/ra_hir_def/src/body/scope.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use std::sync::Arc;
33

44
use hir_expand::name::Name;
5-
use ra_arena::{impl_arena_id, Arena, RawId};
5+
use ra_arena::{Arena, Idx};
66
use rustc_hash::FxHashMap;
77

88
use crate::{
@@ -12,13 +12,11 @@ use crate::{
1212
DefWithBodyId,
1313
};
1414

15-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16-
pub struct ScopeId(RawId);
17-
impl_arena_id!(ScopeId);
15+
pub type ScopeId = Idx<ScopeData>;
1816

1917
#[derive(Debug, PartialEq, Eq)]
2018
pub struct ExprScopes {
21-
scopes: Arena<ScopeId, ScopeData>,
19+
scopes: Arena<ScopeData>,
2220
scope_by_expr: FxHashMap<ExprId, ScopeId>,
2321
}
2422

crates/ra_hir_def/src/expr.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//! See also a neighboring `body` module.
1414
1515
use hir_expand::name::Name;
16-
use ra_arena::{impl_arena_id, RawId};
16+
use ra_arena::{Idx, RawId};
1717
use ra_syntax::ast::RangeOp;
1818

1919
use crate::{
@@ -22,19 +22,12 @@ use crate::{
2222
type_ref::{Mutability, TypeRef},
2323
};
2424

25-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
26-
pub struct ExprId(RawId);
27-
impl_arena_id!(ExprId);
28-
29-
impl ExprId {
30-
pub fn dummy() -> ExprId {
31-
ExprId((!0).into())
32-
}
25+
pub type ExprId = Idx<Expr>;
26+
pub(crate) fn dummy_expr_id() -> ExprId {
27+
ExprId::from_raw(RawId::from(!0))
3328
}
3429

35-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
36-
pub struct PatId(RawId);
37-
impl_arena_id!(PatId);
30+
pub type PatId = Idx<Pat>;
3831

3932
#[derive(Debug, Clone, Eq, PartialEq)]
4033
pub enum Literal {

crates/ra_hir_def/src/generics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub enum TypeParamProvenance {
4343
/// Data about the generic parameters of a function, struct, impl, etc.
4444
#[derive(Clone, PartialEq, Eq, Debug)]
4545
pub struct GenericParams {
46-
pub types: Arena<LocalTypeParamId, TypeParamData>,
46+
pub types: Arena<TypeParamData>,
4747
// lifetimes: Arena<LocalLifetimeParamId, LifetimeParamData>,
4848
pub where_predicates: Vec<WherePredicate>,
4949
}

0 commit comments

Comments
 (0)