From f840fcb2f525c13809d6a736e434155edf075a06 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Thu, 19 Mar 2020 16:00:11 +0100
Subject: Simplify Arena to use a generic index

---
 crates/ra_arena/src/lib.rs                         | 101 +++++++++++++--------
 crates/ra_arena/src/map.rs                         |  32 +++----
 crates/ra_hir_def/src/adt.rs                       |  18 ++--
 crates/ra_hir_def/src/body.rs                      |   4 +-
 crates/ra_hir_def/src/body/lower.rs                |   6 +-
 crates/ra_hir_def/src/body/scope.rs                |   8 +-
 crates/ra_hir_def/src/expr.rs                      |  17 +---
 crates/ra_hir_def/src/generics.rs                  |   2 +-
 crates/ra_hir_def/src/lib.rs                       |  18 +---
 crates/ra_hir_def/src/nameres.rs                   |   4 +-
 crates/ra_hir_def/src/nameres/collector.rs         |   2 +-
 crates/ra_hir_def/src/nameres/raw.rs               |  88 +++++++++---------
 .../ra_hir_def/src/nameres/tests/mod_resolution.rs |   8 +-
 crates/ra_hir_def/src/trace.rs                     |  22 ++---
 crates/ra_hir_expand/src/ast_id_map.rs             |   8 +-
 crates/ra_project_model/src/cargo_workspace.rs     |  14 +--
 crates/ra_project_model/src/sysroot.rs             |   8 +-
 17 files changed, 175 insertions(+), 185 deletions(-)

(limited to 'crates')

diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs
index fc0f7c12f..ea98d5444 100644
--- a/crates/ra_arena/src/lib.rs
+++ b/crates/ra_arena/src/lib.rs
@@ -2,6 +2,7 @@
 
 use std::{
     fmt,
+    hash::{Hash, Hasher},
     iter::FromIterator,
     marker::PhantomData,
     ops::{Index, IndexMut},
@@ -36,86 +37,110 @@ impl fmt::Display for RawId {
     }
 }
 
-#[derive(Clone, PartialEq, Eq)]
-pub struct Arena<ID, T> {
-    data: Vec<T>,
-    _ty: PhantomData<ID>,
+pub struct Idx<T> {
+    raw: RawId,
+    _ty: PhantomData<fn() -> T>,
 }
 
-impl<ID: ArenaId, T: fmt::Debug> fmt::Debug for Arena<ID, T> {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        fmt.debug_struct("Arena").field("len", &self.len()).field("data", &self.data).finish()
+impl<T> Clone for Idx<T> {
+    fn clone(&self) -> Self {
+        *self
     }
 }
+impl<T> Copy for Idx<T> {}
 
-#[macro_export]
-macro_rules! impl_arena_id {
-    ($name:ident) => {
-        impl $crate::ArenaId for $name {
-            fn from_raw(raw: $crate::RawId) -> Self {
-                $name(raw)
-            }
-            fn into_raw(self) -> $crate::RawId {
-                self.0
-            }
+impl<T> PartialEq for Idx<T> {
+    fn eq(&self, other: &Idx<T>) -> bool {
+        self.raw == other.raw
+    }
+}
+impl<T> Eq for Idx<T> {}
+
+impl<T> Hash for Idx<T> {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.raw.hash(state)
+    }
+}
+
+impl<T> fmt::Debug for Idx<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut type_name = std::any::type_name::<T>();
+        if let Some(idx) = type_name.rfind(':') {
+            type_name = &type_name[idx + 1..]
         }
-    };
+        write!(f, "Idx::<{}>({})", type_name, self.raw)
+    }
 }
 
-pub trait ArenaId {
-    fn from_raw(raw: RawId) -> Self;
-    fn into_raw(self) -> RawId;
+impl<T> Idx<T> {
+    pub fn from_raw(raw: RawId) -> Self {
+        Idx { raw, _ty: PhantomData }
+    }
+    pub fn into_raw(self) -> RawId {
+        self.raw
+    }
+}
+
+#[derive(Clone, PartialEq, Eq)]
+pub struct Arena<T> {
+    data: Vec<T>,
 }
 
-impl<ID, T> Arena<ID, T> {
-    pub const fn new() -> Arena<ID, T> {
-        Arena { data: Vec::new(), _ty: PhantomData }
+impl<T: fmt::Debug> fmt::Debug for Arena<T> {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        fmt.debug_struct("Arena").field("len", &self.len()).field("data", &self.data).finish()
     }
 }
 
-impl<ID: ArenaId, T> Arena<ID, T> {
+impl<T> Arena<T> {
+    pub const fn new() -> Arena<T> {
+        Arena { data: Vec::new() }
+    }
+
     pub fn len(&self) -> usize {
         self.data.len()
     }
     pub fn is_empty(&self) -> bool {
         self.data.is_empty()
     }
-    pub fn alloc(&mut self, value: T) -> ID {
+    pub fn alloc(&mut self, value: T) -> Idx<T> {
         let id = RawId(self.data.len() as u32);
         self.data.push(value);
-        ID::from_raw(id)
+        Idx::from_raw(id)
     }
-    pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> + ExactSizeIterator + DoubleEndedIterator {
-        self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value))
+    pub fn iter(
+        &self,
+    ) -> impl Iterator<Item = (Idx<T>, &T)> + ExactSizeIterator + DoubleEndedIterator {
+        self.data.iter().enumerate().map(|(idx, value)| (Idx::from_raw(RawId(idx as u32)), value))
     }
 }
 
-impl<ID: ArenaId, T> Default for Arena<ID, T> {
-    fn default() -> Arena<ID, T> {
-        Arena { data: Vec::new(), _ty: PhantomData }
+impl<T> Default for Arena<T> {
+    fn default() -> Arena<T> {
+        Arena { data: Vec::new() }
     }
 }
 
-impl<ID: ArenaId, T> Index<ID> for Arena<ID, T> {
+impl<T> Index<Idx<T>> for Arena<T> {
     type Output = T;
-    fn index(&self, idx: ID) -> &T {
+    fn index(&self, idx: Idx<T>) -> &T {
         let idx = idx.into_raw().0 as usize;
         &self.data[idx]
     }
 }
 
-impl<ID: ArenaId, T> IndexMut<ID> for Arena<ID, T> {
-    fn index_mut(&mut self, idx: ID) -> &mut T {
+impl<T> IndexMut<Idx<T>> for Arena<T> {
+    fn index_mut(&mut self, idx: Idx<T>) -> &mut T {
         let idx = idx.into_raw().0 as usize;
         &mut self.data[idx]
     }
 }
 
-impl<ID: ArenaId, T> FromIterator<T> for Arena<ID, T> {
+impl<T> FromIterator<T> for Arena<T> {
     fn from_iter<I>(iter: I) -> Self
     where
         I: IntoIterator<Item = T>,
     {
-        Arena { data: Vec::from_iter(iter), _ty: PhantomData }
+        Arena { data: Vec::from_iter(iter) }
     }
 }
diff --git a/crates/ra_arena/src/map.rs b/crates/ra_arena/src/map.rs
index b73d4e365..5e764113d 100644
--- a/crates/ra_arena/src/map.rs
+++ b/crates/ra_arena/src/map.rs
@@ -2,17 +2,17 @@
 
 use std::marker::PhantomData;
 
-use super::ArenaId;
+use crate::Idx;
 
 /// A map from arena IDs to some other type. Space requirement is O(highest ID).
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct ArenaMap<ID, T> {
-    v: Vec<Option<T>>,
+pub struct ArenaMap<ID, V> {
+    v: Vec<Option<V>>,
     _ty: PhantomData<ID>,
 }
 
-impl<ID: ArenaId, T> ArenaMap<ID, T> {
-    pub fn insert(&mut self, id: ID, t: T) {
+impl<T, V> ArenaMap<Idx<T>, V> {
+    pub fn insert(&mut self, id: Idx<T>, t: V) {
         let idx = Self::to_idx(id);
         if self.v.capacity() <= idx {
             self.v.reserve(idx + 1 - self.v.capacity());
@@ -25,43 +25,43 @@ impl<ID: ArenaId, T> ArenaMap<ID, T> {
         self.v[idx] = Some(t);
     }
 
-    pub fn get(&self, id: ID) -> Option<&T> {
+    pub fn get(&self, id: Idx<T>) -> Option<&V> {
         self.v.get(Self::to_idx(id)).and_then(|it| it.as_ref())
     }
 
-    pub fn get_mut(&mut self, id: ID) -> Option<&mut T> {
+    pub fn get_mut(&mut self, id: Idx<T>) -> Option<&mut V> {
         self.v.get_mut(Self::to_idx(id)).and_then(|it| it.as_mut())
     }
 
-    pub fn values(&self) -> impl Iterator<Item = &T> {
+    pub fn values(&self) -> impl Iterator<Item = &V> {
         self.v.iter().filter_map(|o| o.as_ref())
     }
 
-    pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> {
+    pub fn values_mut(&mut self) -> impl Iterator<Item = &mut V> {
         self.v.iter_mut().filter_map(|o| o.as_mut())
     }
 
-    pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> {
+    pub fn iter(&self) -> impl Iterator<Item = (Idx<T>, &V)> {
         self.v.iter().enumerate().filter_map(|(idx, o)| Some((Self::from_idx(idx), o.as_ref()?)))
     }
 
-    fn to_idx(id: ID) -> usize {
+    fn to_idx(id: Idx<T>) -> usize {
         u32::from(id.into_raw()) as usize
     }
 
-    fn from_idx(idx: usize) -> ID {
-        ID::from_raw((idx as u32).into())
+    fn from_idx(idx: usize) -> Idx<T> {
+        Idx::from_raw((idx as u32).into())
     }
 }
 
-impl<ID: ArenaId, T> std::ops::Index<ID> for ArenaMap<ID, T> {
+impl<T, V> std::ops::Index<Idx<V>> for ArenaMap<Idx<V>, T> {
     type Output = T;
-    fn index(&self, id: ID) -> &T {
+    fn index(&self, id: Idx<V>) -> &T {
         self.v[Self::to_idx(id)].as_ref().unwrap()
     }
 }
 
-impl<ID, T> Default for ArenaMap<ID, T> {
+impl<T, V> Default for ArenaMap<Idx<V>, T> {
     fn default() -> Self {
         ArenaMap { v: Vec::new(), _ty: PhantomData }
     }
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index d55c49938..de07fc952 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -27,7 +27,7 @@ pub struct StructData {
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct EnumData {
     pub name: Name,
-    pub variants: Arena<LocalEnumVariantId, EnumVariantData>,
+    pub variants: Arena<EnumVariantData>,
 }
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -38,8 +38,8 @@ pub struct EnumVariantData {
 
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum VariantData {
-    Record(Arena<LocalStructFieldId, StructFieldData>),
-    Tuple(Arena<LocalStructFieldId, StructFieldData>),
+    Record(Arena<StructFieldData>),
+    Tuple(Arena<StructFieldData>),
     Unit,
 }
 
@@ -104,7 +104,7 @@ impl HasChildSource for EnumId {
 
 fn lower_enum(
     db: &dyn DefDatabase,
-    trace: &mut Trace<LocalEnumVariantId, EnumVariantData, ast::EnumVariant>,
+    trace: &mut Trace<EnumVariantData, ast::EnumVariant>,
     ast: &InFile<ast::EnumDef>,
 ) {
     for var in ast.value.variant_list().into_iter().flat_map(|it| it.variants()) {
@@ -128,8 +128,8 @@ impl VariantData {
         }
     }
 
-    pub fn fields(&self) -> &Arena<LocalStructFieldId, StructFieldData> {
-        const EMPTY: &Arena<LocalStructFieldId, StructFieldData> = &Arena::new();
+    pub fn fields(&self) -> &Arena<StructFieldData> {
+        const EMPTY: &Arena<StructFieldData> = &Arena::new();
         match &self {
             VariantData::Record(fields) | VariantData::Tuple(fields) => fields,
             _ => EMPTY,
@@ -183,11 +183,7 @@ pub enum StructKind {
 
 fn lower_struct(
     db: &dyn DefDatabase,
-    trace: &mut Trace<
-        LocalStructFieldId,
-        StructFieldData,
-        Either<ast::TupleFieldDef, ast::RecordFieldDef>,
-    >,
+    trace: &mut Trace<StructFieldData, Either<ast::TupleFieldDef, ast::RecordFieldDef>>,
     ast: &InFile<ast::StructKind>,
 ) -> StructKind {
     match &ast.value {
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 34561ee73..27a297e8b 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -121,8 +121,8 @@ pub(crate) struct Mark {
 /// The body of an item (function, const etc.).
 #[derive(Debug, Eq, PartialEq)]
 pub struct Body {
-    pub exprs: Arena<ExprId, Expr>,
-    pub pats: Arena<PatId, Pat>,
+    pub exprs: Arena<Expr>,
+    pub pats: Arena<Pat>,
     /// The patterns for the function's parameters. While the parameter types are
     /// part of the function signature, the patterns are not (they don't change
     /// the external type of the function).
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 6238de606..e8c58ed32 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -24,8 +24,8 @@ use crate::{
     builtin_type::{BuiltinFloat, BuiltinInt},
     db::DefDatabase,
     expr::{
-        ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp,
-        MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
+        dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal,
+        LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
     },
     item_scope::BuiltinShadowMode,
     path::GenericArgs,
@@ -51,7 +51,7 @@ pub(super) fn lower(
             exprs: Arena::default(),
             pats: Arena::default(),
             params: Vec::new(),
-            body_expr: ExprId::dummy(),
+            body_expr: dummy_expr_id(),
             item_scope: Default::default(),
         },
     }
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index 7c3db8869..4d489f692 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -2,7 +2,7 @@
 use std::sync::Arc;
 
 use hir_expand::name::Name;
-use ra_arena::{impl_arena_id, Arena, RawId};
+use ra_arena::{Arena, Idx};
 use rustc_hash::FxHashMap;
 
 use crate::{
@@ -12,13 +12,11 @@ use crate::{
     DefWithBodyId,
 };
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct ScopeId(RawId);
-impl_arena_id!(ScopeId);
+pub type ScopeId = Idx<ScopeData>;
 
 #[derive(Debug, PartialEq, Eq)]
 pub struct ExprScopes {
-    scopes: Arena<ScopeId, ScopeData>,
+    scopes: Arena<ScopeData>,
     scope_by_expr: FxHashMap<ExprId, ScopeId>,
 }
 
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index 66d004717..197bbe9bd 100644
--- a/crates/ra_hir_def/src/expr.rs
+++ b/crates/ra_hir_def/src/expr.rs
@@ -13,7 +13,7 @@
 //! See also a neighboring `body` module.
 
 use hir_expand::name::Name;
-use ra_arena::{impl_arena_id, RawId};
+use ra_arena::{Idx, RawId};
 use ra_syntax::ast::RangeOp;
 
 use crate::{
@@ -22,19 +22,12 @@ use crate::{
     type_ref::{Mutability, TypeRef},
 };
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct ExprId(RawId);
-impl_arena_id!(ExprId);
-
-impl ExprId {
-    pub fn dummy() -> ExprId {
-        ExprId((!0).into())
-    }
+pub type ExprId = Idx<Expr>;
+pub(crate) fn dummy_expr_id() -> ExprId {
+    ExprId::from_raw(RawId::from(!0))
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct PatId(RawId);
-impl_arena_id!(PatId);
+pub type PatId = Idx<Pat>;
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum Literal {
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index 24adc8153..b687ce2b2 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -43,7 +43,7 @@ pub enum TypeParamProvenance {
 /// Data about the generic parameters of a function, struct, impl, etc.
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct GenericParams {
-    pub types: Arena<LocalTypeParamId, TypeParamData>,
+    pub types: Arena<TypeParamData>,
     // lifetimes: Arena<LocalLifetimeParamId, LifetimeParamData>,
     pub where_predicates: Vec<WherePredicate>,
 }
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs
index d0f043ed0..516dd773e 100644
--- a/crates/ra_hir_def/src/lib.rs
+++ b/crates/ra_hir_def/src/lib.rs
@@ -50,7 +50,7 @@ use hir_expand::{
     ast_id_map::FileAstId, eager::expand_eager_macro, hygiene::Hygiene, AstId, HirFileId, InFile,
     MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
 };
-use ra_arena::{impl_arena_id, RawId};
+use ra_arena::Idx;
 use ra_db::{impl_intern_key, salsa, CrateId};
 use ra_syntax::{ast, AstNode};
 
@@ -64,9 +64,7 @@ pub struct ModuleId {
 }
 
 /// An ID of a module, **local** to a specific crate
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct LocalModuleId(RawId);
-impl_arena_id!(LocalModuleId);
+pub type LocalModuleId = Idx<nameres::ModuleData>;
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ItemLoc<N: AstNode> {
@@ -127,9 +125,7 @@ pub struct EnumVariantId {
     pub local_id: LocalEnumVariantId,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct LocalEnumVariantId(RawId);
-impl_arena_id!(LocalEnumVariantId);
+pub type LocalEnumVariantId = Idx<adt::EnumVariantData>;
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct StructFieldId {
@@ -137,9 +133,7 @@ pub struct StructFieldId {
     pub local_id: LocalStructFieldId,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct LocalStructFieldId(RawId);
-impl_arena_id!(LocalStructFieldId);
+pub type LocalStructFieldId = Idx<adt::StructFieldData>;
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct ConstId(salsa::InternId);
@@ -172,9 +166,7 @@ pub struct TypeParamId {
     pub local_id: LocalTypeParamId,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct LocalTypeParamId(RawId);
-impl_arena_id!(LocalTypeParamId);
+pub type LocalTypeParamId = Idx<generics::TypeParamData>;
 
 macro_rules! impl_froms {
     ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => {
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index be53313ee..40bdc34f5 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -77,7 +77,7 @@ use crate::{
 #[derive(Debug, PartialEq, Eq)]
 pub struct CrateDefMap {
     pub root: LocalModuleId,
-    pub modules: Arena<LocalModuleId, ModuleData>,
+    pub modules: Arena<ModuleData>,
     pub(crate) krate: CrateId,
     /// The prelude module for this crate. This either comes from an import
     /// marked with the `prelude_import` attribute, or (in the normal case) from
@@ -187,7 +187,7 @@ impl CrateDefMap {
         });
         let def_map = {
             let edition = db.crate_graph()[krate].edition;
-            let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default();
+            let mut modules: Arena<ModuleData> = Arena::default();
             let root = modules.alloc(ModuleData::default());
             CrateDefMap {
                 krate,
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 7a042e69f..5b292c250 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -966,7 +966,7 @@ mod tests {
 
         let def_map = {
             let edition = db.crate_graph()[krate].edition;
-            let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default();
+            let mut modules: Arena<ModuleData> = Arena::default();
             let root = modules.alloc(ModuleData::default());
             CrateDefMap {
                 krate,
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 0e4931f58..1631e87b8 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -12,7 +12,7 @@ use hir_expand::{
     hygiene::Hygiene,
     name::{AsName, Name},
 };
-use ra_arena::{impl_arena_id, Arena, RawId};
+use ra_arena::{Arena, Idx};
 use ra_prof::profile;
 use ra_syntax::{
     ast::{self, AttrsOwner, NameOwner, VisibilityOwner},
@@ -34,11 +34,11 @@ use crate::{
 /// on most edits.
 #[derive(Debug, Default, PartialEq, Eq)]
 pub struct RawItems {
-    modules: Arena<Module, ModuleData>,
-    imports: Arena<Import, ImportData>,
-    defs: Arena<Def, DefData>,
-    macros: Arena<Macro, MacroData>,
-    impls: Arena<Impl, ImplData>,
+    modules: Arena<ModuleData>,
+    imports: Arena<ImportData>,
+    defs: Arena<DefData>,
+    macros: Arena<MacroData>,
+    impls: Arena<ImplData>,
     /// items for top-level module
     items: Vec<RawItem>,
 }
@@ -68,9 +68,9 @@ impl RawItems {
     }
 }
 
-impl Index<Module> for RawItems {
+impl Index<Idx<ModuleData>> for RawItems {
     type Output = ModuleData;
-    fn index(&self, idx: Module) -> &ModuleData {
+    fn index(&self, idx: Idx<ModuleData>) -> &ModuleData {
         &self.modules[idx]
     }
 }
@@ -82,23 +82,23 @@ impl Index<Import> for RawItems {
     }
 }
 
-impl Index<Def> for RawItems {
+impl Index<Idx<DefData>> for RawItems {
     type Output = DefData;
-    fn index(&self, idx: Def) -> &DefData {
+    fn index(&self, idx: Idx<DefData>) -> &DefData {
         &self.defs[idx]
     }
 }
 
-impl Index<Macro> for RawItems {
+impl Index<Idx<MacroData>> for RawItems {
     type Output = MacroData;
-    fn index(&self, idx: Macro) -> &MacroData {
+    fn index(&self, idx: Idx<MacroData>) -> &MacroData {
         &self.macros[idx]
     }
 }
 
-impl Index<Impl> for RawItems {
+impl Index<Idx<ImplData>> for RawItems {
     type Output = ImplData;
-    fn index(&self, idx: Impl) -> &ImplData {
+    fn index(&self, idx: Idx<ImplData>) -> &ImplData {
         &self.impls[idx]
     }
 }
@@ -111,17 +111,13 @@ pub(super) struct RawItem {
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
 pub(super) enum RawItemKind {
-    Module(Module),
+    Module(Idx<ModuleData>),
     Import(Import),
-    Def(Def),
-    Macro(Macro),
-    Impl(Impl),
+    Def(Idx<DefData>),
+    Macro(Idx<MacroData>),
+    Impl(Idx<ImplData>),
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub(super) struct Module(RawId);
-impl_arena_id!(Module);
-
 #[derive(Debug, PartialEq, Eq)]
 pub(super) enum ModuleData {
     Declaration {
@@ -137,9 +133,7 @@ pub(super) enum ModuleData {
     },
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub(crate) struct Import(RawId);
-impl_arena_id!(Import);
+pub(crate) type Import = Idx<ImportData>;
 
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ImportData {
@@ -152,9 +146,7 @@ pub struct ImportData {
     pub(super) visibility: RawVisibility,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub(super) struct Def(RawId);
-impl_arena_id!(Def);
+// type Def = Idx<DefData>;
 
 #[derive(Debug, PartialEq, Eq)]
 pub(super) struct DefData {
@@ -190,10 +182,6 @@ impl DefKind {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub(super) struct Macro(RawId);
-impl_arena_id!(Macro);
-
 #[derive(Debug, PartialEq, Eq)]
 pub(super) struct MacroData {
     pub(super) ast_id: FileAstId<ast::MacroCall>,
@@ -203,10 +191,6 @@ pub(super) struct MacroData {
     pub(super) builtin: bool,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub(super) struct Impl(RawId);
-impl_arena_id!(Impl);
-
 #[derive(Debug, PartialEq, Eq)]
 pub(super) struct ImplData {
     pub(super) ast_id: FileAstId<ast::ImplDef>,
@@ -220,7 +204,11 @@ struct RawItemsCollector {
 }
 
 impl RawItemsCollector {
-    fn process_module(&mut self, current_module: Option<Module>, body: impl ast::ModuleItemOwner) {
+    fn process_module(
+        &mut self,
+        current_module: Option<Idx<ModuleData>>,
+        body: impl ast::ModuleItemOwner,
+    ) {
         for item_or_macro in body.items_with_macros() {
             match item_or_macro {
                 ast::ItemOrMacro::Macro(m) => self.add_macro(current_module, m),
@@ -229,7 +217,7 @@ impl RawItemsCollector {
         }
     }
 
-    fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) {
+    fn add_item(&mut self, current_module: Option<Idx<ModuleData>>, item: ast::ModuleItem) {
         let attrs = self.parse_attrs(&item);
         let visibility = RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene);
         let (kind, name) = match item {
@@ -285,7 +273,7 @@ impl RawItemsCollector {
         }
     }
 
-    fn add_module(&mut self, current_module: Option<Module>, module: ast::Module) {
+    fn add_module(&mut self, current_module: Option<Idx<ModuleData>>, module: ast::Module) {
         let name = match module.name() {
             Some(it) => it.as_name(),
             None => return,
@@ -315,7 +303,7 @@ impl RawItemsCollector {
         tested_by!(name_res_works_for_broken_modules);
     }
 
-    fn add_use_item(&mut self, current_module: Option<Module>, use_item: ast::UseItem) {
+    fn add_use_item(&mut self, current_module: Option<Idx<ModuleData>>, use_item: ast::UseItem) {
         // FIXME: cfg_attr
         let is_prelude = use_item.has_atom_attr("prelude_import");
         let attrs = self.parse_attrs(&use_item);
@@ -345,7 +333,7 @@ impl RawItemsCollector {
 
     fn add_extern_crate_item(
         &mut self,
-        current_module: Option<Module>,
+        current_module: Option<Idx<ModuleData>>,
         extern_crate: ast::ExternCrateItem,
     ) {
         if let Some(name_ref) = extern_crate.name_ref() {
@@ -371,7 +359,7 @@ impl RawItemsCollector {
         }
     }
 
-    fn add_macro(&mut self, current_module: Option<Module>, m: ast::MacroCall) {
+    fn add_macro(&mut self, current_module: Option<Idx<ModuleData>>, m: ast::MacroCall) {
         let attrs = self.parse_attrs(&m);
         let path = match m.path().and_then(|path| ModPath::from_src(path, &self.hygiene)) {
             Some(it) => it,
@@ -391,19 +379,29 @@ impl RawItemsCollector {
         self.push_item(current_module, attrs, RawItemKind::Macro(m));
     }
 
-    fn add_impl(&mut self, current_module: Option<Module>, imp: ast::ImplDef) {
+    fn add_impl(&mut self, current_module: Option<Idx<ModuleData>>, imp: ast::ImplDef) {
         let attrs = self.parse_attrs(&imp);
         let ast_id = self.source_ast_id_map.ast_id(&imp);
         let imp = self.raw_items.impls.alloc(ImplData { ast_id });
         self.push_item(current_module, attrs, RawItemKind::Impl(imp))
     }
 
-    fn push_import(&mut self, current_module: Option<Module>, attrs: Attrs, data: ImportData) {
+    fn push_import(
+        &mut self,
+        current_module: Option<Idx<ModuleData>>,
+        attrs: Attrs,
+        data: ImportData,
+    ) {
         let import = self.raw_items.imports.alloc(data);
         self.push_item(current_module, attrs, RawItemKind::Import(import))
     }
 
-    fn push_item(&mut self, current_module: Option<Module>, attrs: Attrs, kind: RawItemKind) {
+    fn push_item(
+        &mut self,
+        current_module: Option<Idx<ModuleData>>,
+        attrs: Attrs,
+        kind: RawItemKind,
+    ) {
         match current_module {
             Some(module) => match &mut self.raw_items.modules[module] {
                 ModuleData::Definition { items, .. } => items,
diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
index b502a4079..37fcdfb8c 100644
--- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
@@ -710,9 +710,7 @@ fn unresolved_module_diagnostics() {
         @r###"
     [
         UnresolvedModule {
-            module: LocalModuleId(
-                0,
-            ),
+            module: Idx::<ModuleData>(0),
             declaration: InFile {
                 file_id: HirFileId(
                     FileId(
@@ -722,9 +720,7 @@ fn unresolved_module_diagnostics() {
                     ),
                 ),
                 value: FileAstId {
-                    raw: ErasedFileAstId(
-                        1,
-                    ),
+                    raw: Idx::<SyntaxNodePtr>(1),
                     _ty: PhantomData,
                 },
             },
diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs
index 9769e88df..ced07577d 100644
--- a/crates/ra_hir_def/src/trace.rs
+++ b/crates/ra_hir_def/src/trace.rs
@@ -9,28 +9,28 @@
 //! absolute offsets. The `Trace` structure (inspired, at least in name, by
 //! Kotlin's `BindingTrace`) allows use the same code to compute both
 //! projections.
-use ra_arena::{map::ArenaMap, Arena, ArenaId, RawId};
+use ra_arena::{map::ArenaMap, Arena, Idx, RawId};
 
-pub(crate) struct Trace<ID: ArenaId, T, V> {
-    arena: Option<Arena<ID, T>>,
-    map: Option<ArenaMap<ID, V>>,
+pub(crate) struct Trace<T, V> {
+    arena: Option<Arena<T>>,
+    map: Option<ArenaMap<Idx<T>, V>>,
     len: u32,
 }
 
-impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> {
-    pub(crate) fn new_for_arena() -> Trace<ID, T, V> {
+impl<T, V> Trace<T, V> {
+    pub(crate) fn new_for_arena() -> Trace<T, V> {
         Trace { arena: Some(Arena::default()), map: None, len: 0 }
     }
 
-    pub(crate) fn new_for_map() -> Trace<ID, T, V> {
+    pub(crate) fn new_for_map() -> Trace<T, V> {
         Trace { arena: None, map: Some(ArenaMap::default()), len: 0 }
     }
 
-    pub(crate) fn alloc(&mut self, value: impl FnOnce() -> V, data: impl FnOnce() -> T) -> ID {
+    pub(crate) fn alloc(&mut self, value: impl FnOnce() -> V, data: impl FnOnce() -> T) -> Idx<T> {
         let id = if let Some(arena) = &mut self.arena {
             arena.alloc(data())
         } else {
-            let id = ID::from_raw(RawId::from(self.len));
+            let id = Idx::<T>::from_raw(RawId::from(self.len));
             self.len += 1;
             id
         };
@@ -41,11 +41,11 @@ impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> {
         id
     }
 
-    pub(crate) fn into_arena(mut self) -> Arena<ID, T> {
+    pub(crate) fn into_arena(mut self) -> Arena<T> {
         self.arena.take().unwrap()
     }
 
-    pub(crate) fn into_map(mut self) -> ArenaMap<ID, V> {
+    pub(crate) fn into_map(mut self) -> ArenaMap<Idx<T>, V> {
         self.map.take().unwrap()
     }
 }
diff --git a/crates/ra_hir_expand/src/ast_id_map.rs b/crates/ra_hir_expand/src/ast_id_map.rs
index a764bdf24..a6644d55f 100644
--- a/crates/ra_hir_expand/src/ast_id_map.rs
+++ b/crates/ra_hir_expand/src/ast_id_map.rs
@@ -10,7 +10,7 @@ use std::{
     marker::PhantomData,
 };
 
-use ra_arena::{impl_arena_id, Arena, RawId};
+use ra_arena::{Arena, Idx};
 use ra_syntax::{ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr};
 
 /// `AstId` points to an AST node in a specific file.
@@ -49,14 +49,12 @@ impl<N: AstNode> FileAstId<N> {
     }
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-struct ErasedFileAstId(RawId);
-impl_arena_id!(ErasedFileAstId);
+type ErasedFileAstId = Idx<SyntaxNodePtr>;
 
 /// Maps items' `SyntaxNode`s to `ErasedFileAstId`s and back.
 #[derive(Debug, PartialEq, Eq, Default)]
 pub struct AstIdMap {
-    arena: Arena<ErasedFileAstId, SyntaxNodePtr>,
+    arena: Arena<SyntaxNodePtr>,
 }
 
 impl AstIdMap {
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index 43dbd096a..c2857dbfc 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -7,7 +7,7 @@ use std::{
 
 use anyhow::{Context, Result};
 use cargo_metadata::{CargoOpt, Message, MetadataCommand, PackageId};
-use ra_arena::{impl_arena_id, Arena, RawId};
+use ra_arena::{Arena, Idx};
 use ra_cargo_watch::run_cargo;
 use ra_db::Edition;
 use rustc_hash::FxHashMap;
@@ -22,8 +22,8 @@ use serde::Deserialize;
 /// concepts.
 #[derive(Debug, Clone)]
 pub struct CargoWorkspace {
-    packages: Arena<Package, PackageData>,
-    targets: Arena<Target, TargetData>,
+    packages: Arena<PackageData>,
+    targets: Arena<TargetData>,
     workspace_root: PathBuf,
 }
 
@@ -69,13 +69,9 @@ impl Default for CargoFeatures {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub struct Package(RawId);
-impl_arena_id!(Package);
+pub type Package = Idx<PackageData>;
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub struct Target(RawId);
-impl_arena_id!(Target);
+pub type Target = Idx<TargetData>;
 
 #[derive(Debug, Clone)]
 pub struct PackageData {
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs
index 4ac4fa14d..55ff5ad80 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/ra_project_model/src/sysroot.rs
@@ -7,16 +7,14 @@ use std::{
     process::{Command, Output},
 };
 
-use ra_arena::{impl_arena_id, Arena, RawId};
+use ra_arena::{Arena, Idx};
 
 #[derive(Default, Debug, Clone)]
 pub struct Sysroot {
-    crates: Arena<SysrootCrate, SysrootCrateData>,
+    crates: Arena<SysrootCrateData>,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct SysrootCrate(RawId);
-impl_arena_id!(SysrootCrate);
+pub type SysrootCrate = Idx<SysrootCrateData>;
 
 #[derive(Debug, Clone)]
 pub struct SysrootCrateData {
-- 
cgit v1.2.3