Simplify Arena to use a generic index
This commit is contained in:
parent
988f1dda6b
commit
f840fcb2f5
@ -2,6 +2,7 @@
|
||||
|
||||
use std::{
|
||||
fmt,
|
||||
hash::{Hash, Hasher},
|
||||
iter::FromIterator,
|
||||
marker::PhantomData,
|
||||
ops::{Index, IndexMut},
|
||||
@ -36,86 +37,110 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
#[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> {
|
||||
impl<T> Clone for Idx<T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
impl<T> Copy for Idx<T> {}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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<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()
|
||||
}
|
||||
}
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub trait ArenaId {
|
||||
fn from_raw(raw: RawId) -> Self;
|
||||
fn into_raw(self) -> RawId;
|
||||
}
|
||||
|
||||
impl<ID, T> Arena<ID, T> {
|
||||
pub const fn new() -> Arena<ID, T> {
|
||||
Arena { data: Vec::new(), _ty: PhantomData }
|
||||
impl<T> Arena<T> {
|
||||
pub const fn new() -> Arena<T> {
|
||||
Arena { data: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<ID: ArenaId, T> Arena<ID, T> {
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
@ -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 @@ pub fn insert(&mut self, id: ID, t: 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 }
|
||||
}
|
||||
|
@ -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 @@ fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<Self::ChildId, S
|
||||
|
||||
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 @@ fn new(db: &dyn DefDatabase, flavor: InFile<ast::StructKind>) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -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).
|
||||
|
@ -24,8 +24,8 @@
|
||||
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(),
|
||||
},
|
||||
}
|
||||
|
@ -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 @@
|
||||
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>,
|
||||
}
|
||||
|
||||
|
@ -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 @@
|
||||
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 {
|
||||
|
@ -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>,
|
||||
}
|
||||
|
@ -50,7 +50,7 @@
|
||||
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),*))?),*) => {
|
||||
|
@ -77,7 +77,7 @@
|
||||
#[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 @@ pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<C
|
||||
});
|
||||
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,
|
||||
|
@ -966,7 +966,7 @@ fn do_resolve(code: &str) -> 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,
|
||||
|
@ -12,7 +12,7 @@
|
||||
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 @@
|
||||
/// 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 @@ pub(super) fn items(&self) -> &[RawItem] {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn index(&self, idx: Import) -> &ImportData {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ pub fn ast_id(&self) -> FileAstId<ast::ModuleItem> {
|
||||
}
|
||||
}
|
||||
|
||||
#[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 @@ fn process_module(&mut self, current_module: Option<Module>, body: impl ast::Mod
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn add_module(&mut self, current_module: Option<Module>, module: ast::Module) {
|
||||
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 @@ fn add_use_item(&mut self, current_module: Option<Module>, use_item: ast::UseIte
|
||||
|
||||
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 @@ fn add_extern_crate_item(
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn add_macro(&mut self, current_module: Option<Module>, m: ast::MacroCall) {
|
||||
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,
|
||||
|
@ -710,9 +710,7 @@ mod baz {}
|
||||
@r###"
|
||||
[
|
||||
UnresolvedModule {
|
||||
module: LocalModuleId(
|
||||
0,
|
||||
),
|
||||
module: Idx::<ModuleData>(0),
|
||||
declaration: InFile {
|
||||
file_id: HirFileId(
|
||||
FileId(
|
||||
@ -722,9 +720,7 @@ mod baz {}
|
||||
),
|
||||
),
|
||||
value: FileAstId {
|
||||
raw: ErasedFileAstId(
|
||||
1,
|
||||
),
|
||||
raw: Idx::<SyntaxNodePtr>(1),
|
||||
_ty: PhantomData,
|
||||
},
|
||||
},
|
||||
|
@ -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 @@ pub(crate) fn alloc(&mut self, value: impl FnOnce() -> V, data: impl FnOnce() ->
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
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 @@ pub fn upcast<M: AstNode>(self) -> FileAstId<M>
|
||||
}
|
||||
}
|
||||
|
||||
#[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 {
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
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 @@
|
||||
/// 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 @@ fn default() -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
#[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 {
|
||||
|
@ -7,16 +7,14 @@
|
||||
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 {
|
||||
|
Loading…
Reference in New Issue
Block a user