Skip to content

Commit 1ba03c6

Browse files
bors[bot]matklad
andauthored
Merge #3656
3656: Simplify arenas r=matklad a=matklad At the moment, Arena is paranetrized by two types: index and data. The original motivation was to allow index to be defined in the downstream crate, so that you can add inherent impls to the index. However, it seems like we've never actually used that capability, so perhaps we should switch to a generic Index impl? This PR tries this out, switching only `raw.rs` and parts of `hir_def`. wdyt? Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
2 parents 988f1dd + f840fcb commit 1ba03c6

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)