aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock13
-rw-r--r--crates/ra_arena/Cargo.toml5
-rw-r--r--crates/ra_arena/src/lib.rs97
-rw-r--r--crates/ra_hir/Cargo.toml2
-rw-r--r--crates/ra_hir/src/arena.rs66
-rw-r--r--crates/ra_hir/src/function/scope.rs12
-rw-r--r--crates/ra_hir/src/ids.rs12
-rw-r--r--crates/ra_hir/src/lib.rs1
-rw-r--r--crates/ra_hir/src/module.rs17
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs4
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs5
-rw-r--r--crates/ra_lsp_server/src/server_world.rs32
-rw-r--r--crates/ra_vfs/Cargo.toml1
-rw-r--r--crates/ra_vfs/src/arena.rs53
-rw-r--r--crates/ra_vfs/src/lib.rs34
15 files changed, 167 insertions, 187 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5f35f2872..b06058688 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -371,11 +371,6 @@ version = "1.1.0"
371source = "registry+https://github.com/rust-lang/crates.io-index" 371source = "registry+https://github.com/rust-lang/crates.io-index"
372 372
373[[package]] 373[[package]]
374name = "id-arena"
375version = "2.0.0"
376source = "registry+https://github.com/rust-lang/crates.io-index"
377
378[[package]]
379name = "idna" 374name = "idna"
380version = "0.1.5" 375version = "0.1.5"
381source = "registry+https://github.com/rust-lang/crates.io-index" 376source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -684,6 +679,10 @@ dependencies = [
684] 679]
685 680
686[[package]] 681[[package]]
682name = "ra_arena"
683version = "0.1.0"
684
685[[package]]
687name = "ra_cli" 686name = "ra_cli"
688version = "0.1.0" 687version = "0.1.0"
689dependencies = [ 688dependencies = [
@@ -729,9 +728,9 @@ dependencies = [
729 "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 728 "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
730 "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 729 "ena 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
731 "flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", 730 "flexi_logger 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
732 "id-arena 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
733 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 731 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
734 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 732 "parking_lot 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
733 "ra_arena 0.1.0",
735 "ra_db 0.1.0", 734 "ra_db 0.1.0",
736 "ra_editor 0.1.0", 735 "ra_editor 0.1.0",
737 "ra_syntax 0.1.0", 736 "ra_syntax 0.1.0",
@@ -808,6 +807,7 @@ version = "0.1.0"
808dependencies = [ 807dependencies = [
809 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 808 "crossbeam-channel 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
810 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 809 "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
810 "ra_arena 0.1.0",
811 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 811 "relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
812 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 812 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
813 "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 813 "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1529,7 +1529,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1529"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" 1529"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
1530"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 1530"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
1531"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" 1531"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
1532"checksum id-arena 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3a7250033feafee46a1cecd2c2616a64aec1d064f38c9ae2bdd297728542843e"
1533"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 1532"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
1534"checksum im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9c7f9bb8aee47fc16d535a705f7867a9fc83bb822e5e1043bb98e77ffeed3c" 1533"checksum im 12.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ae9c7f9bb8aee47fc16d535a705f7867a9fc83bb822e5e1043bb98e77ffeed3c"
1535"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" 1534"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
diff --git a/crates/ra_arena/Cargo.toml b/crates/ra_arena/Cargo.toml
new file mode 100644
index 000000000..9594e2d0f
--- /dev/null
+++ b/crates/ra_arena/Cargo.toml
@@ -0,0 +1,5 @@
1[package]
2edition = "2018"
3name = "ra_arena"
4version = "0.1.0"
5authors = ["Aleksey Kladov <[email protected]>"]
diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs
new file mode 100644
index 000000000..a5eeb4118
--- /dev/null
+++ b/crates/ra_arena/src/lib.rs
@@ -0,0 +1,97 @@
1//! Yet another index-based arena.
2
3use std::{
4 fmt,
5 marker::PhantomData,
6 ops::{Index, IndexMut},
7};
8
9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct RawId(u32);
11
12impl From<RawId> for u32 {
13 fn from(raw: RawId) -> u32 {
14 raw.0
15 }
16}
17
18impl From<u32> for RawId {
19 fn from(id: u32) -> RawId {
20 RawId(id)
21 }
22}
23
24impl fmt::Debug for RawId {
25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26 self.0.fmt(f)
27 }
28}
29
30impl fmt::Display for RawId {
31 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
32 self.0.fmt(f)
33 }
34}
35
36#[derive(Clone, Debug, PartialEq, Eq)]
37pub struct Arena<ID: ArenaId, T> {
38 data: Vec<T>,
39 _ty: PhantomData<ID>,
40}
41
42#[macro_export]
43macro_rules! impl_arena_id {
44 ($name:ident) => {
45 impl $crate::ArenaId for $name {
46 fn from_raw(raw: $crate::RawId) -> Self {
47 $name(raw)
48 }
49 fn into_raw(self) -> $crate::RawId {
50 self.0
51 }
52 }
53 };
54}
55
56pub trait ArenaId {
57 fn from_raw(raw: RawId) -> Self;
58 fn into_raw(self) -> RawId;
59}
60
61impl<ID: ArenaId, T> Arena<ID, T> {
62 pub fn alloc(&mut self, value: T) -> ID {
63 let id = RawId(self.data.len() as u32);
64 self.data.push(value);
65 ID::from_raw(id)
66 }
67 pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> {
68 self.data
69 .iter()
70 .enumerate()
71 .map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value))
72 }
73}
74
75impl<ID: ArenaId, T> Default for Arena<ID, T> {
76 fn default() -> Arena<ID, T> {
77 Arena {
78 data: Vec::new(),
79 _ty: PhantomData,
80 }
81 }
82}
83
84impl<ID: ArenaId, T> Index<ID> for Arena<ID, T> {
85 type Output = T;
86 fn index(&self, idx: ID) -> &T {
87 let idx = idx.into_raw().0 as usize;
88 &self.data[idx]
89 }
90}
91
92impl<ID: ArenaId, T> IndexMut<ID> for Arena<ID, T> {
93 fn index_mut(&mut self, idx: ID) -> &mut T {
94 let idx = idx.into_raw().0 as usize;
95 &mut self.data[idx]
96 }
97}
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml
index c3fbd327d..8c0cf4b86 100644
--- a/crates/ra_hir/Cargo.toml
+++ b/crates/ra_hir/Cargo.toml
@@ -11,9 +11,9 @@ relative-path = "0.4.0"
11salsa = "0.9.0" 11salsa = "0.9.0"
12rustc-hash = "1.0" 12rustc-hash = "1.0"
13parking_lot = "0.7.0" 13parking_lot = "0.7.0"
14id-arena = "2.0"
15ena = "0.11" 14ena = "0.11"
16ra_syntax = { path = "../ra_syntax" } 15ra_syntax = { path = "../ra_syntax" }
16ra_arena = { path = "../ra_arena" }
17ra_editor = { path = "../ra_editor" } 17ra_editor = { path = "../ra_editor" }
18ra_db = { path = "../ra_db" } 18ra_db = { path = "../ra_db" }
19test_utils = { path = "../test_utils" } 19test_utils = { path = "../test_utils" }
diff --git a/crates/ra_hir/src/arena.rs b/crates/ra_hir/src/arena.rs
deleted file mode 100644
index d4f9d9cb9..000000000
--- a/crates/ra_hir/src/arena.rs
+++ /dev/null
@@ -1,66 +0,0 @@
1//! A simple id-based arena, similar to https://github.com/fitzgen/id-arena.
2//! We use our own version for more compact id's and to allow inherent impls
3//! on Ids.
4
5use std::{
6 fmt,
7 hash::{Hash, Hasher},
8 marker::PhantomData,
9};
10
11pub struct Id<T> {
12 idx: u32,
13 _ty: PhantomData<fn() -> T>,
14}
15
16impl<T> fmt::Debug for Id<T> {
17 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18 f.debug_tuple("Id").field(&self.idx).finish()
19 }
20}
21impl<T> Copy for Id<T> {}
22impl<T> Clone for Id<T> {
23 fn clone(&self) -> Id<T> {
24 *self
25 }
26}
27
28impl<T> PartialEq for Id<T> {
29 fn eq(&self, other: &Id<T>) -> bool {
30 self.idx == other.idx
31 }
32}
33
34impl<T> Eq for Id<T> {}
35
36impl<T> Hash for Id<T> {
37 fn hash<H: Hasher>(&self, h: &mut H) {
38 self.idx.hash(h);
39 }
40}
41
42#[derive(Debug, PartialEq, Eq)]
43pub(crate) struct ArenaBehavior<T> {
44 _ty: PhantomData<T>,
45}
46
47impl<T> id_arena::ArenaBehavior for ArenaBehavior<T> {
48 type Id = Id<T>;
49 fn new_arena_id() -> u32 {
50 0
51 }
52 fn new_id(_arena_id: u32, index: usize) -> Id<T> {
53 Id {
54 idx: index as u32,
55 _ty: PhantomData,
56 }
57 }
58 fn index(id: Id<T>) -> usize {
59 id.idx as usize
60 }
61 fn arena_id(_id: Id<T>) -> u32 {
62 0
63 }
64}
65
66pub(crate) type Arena<T> = id_arena::Arena<T, ArenaBehavior<T>>;
diff --git a/crates/ra_hir/src/function/scope.rs b/crates/ra_hir/src/function/scope.rs
index 3e4cfad0c..42bfe4f32 100644
--- a/crates/ra_hir/src/function/scope.rs
+++ b/crates/ra_hir/src/function/scope.rs
@@ -5,19 +5,19 @@ use ra_syntax::{
5 algo::generate, 5 algo::generate,
6 ast::{self, ArgListOwner, LoopBodyOwner, NameOwner}, 6 ast::{self, ArgListOwner, LoopBodyOwner, NameOwner},
7}; 7};
8use ra_arena::{Arena, RawId, impl_arena_id};
8use ra_db::LocalSyntaxPtr; 9use ra_db::LocalSyntaxPtr;
9 10
10use crate::{ 11use crate::{Name, AsName};
11 arena::{Arena, Id},
12 Name, AsName,
13};
14 12
15pub(crate) type ScopeId = Id<ScopeData>; 13#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
14pub struct ScopeId(RawId);
15impl_arena_id!(ScopeId);
16 16
17#[derive(Debug, PartialEq, Eq)] 17#[derive(Debug, PartialEq, Eq)]
18pub struct FnScopes { 18pub struct FnScopes {
19 pub self_param: Option<LocalSyntaxPtr>, 19 pub self_param: Option<LocalSyntaxPtr>,
20 scopes: Arena<ScopeData>, 20 scopes: Arena<ScopeId, ScopeData>,
21 scope_for: FxHashMap<LocalSyntaxPtr, ScopeId>, 21 scope_for: FxHashMap<LocalSyntaxPtr, ScopeId>,
22} 22}
23 23
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 4c7ebe3ea..66adacc7d 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -1,10 +1,8 @@
1use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId}; 1use ra_db::{SourceRootId, LocationIntener, Cancelable, FileId};
2use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast}; 2use ra_syntax::{SourceFileNode, SyntaxKind, SyntaxNode, SyntaxNodeRef, SourceFile, AstNode, ast};
3use ra_arena::{Arena, RawId, impl_arena_id};
3 4
4use crate::{ 5use crate::{HirDatabase, PerNs, ModuleId, Module, Def, Function, Struct, Enum};
5 HirDatabase, PerNs, ModuleId, Module, Def, Function, Struct, Enum,
6 arena::{Arena, Id},
7};
8 6
9/// hir makes a heavy use of ids: integer (u32) handlers to various things. You 7/// hir makes a heavy use of ids: integer (u32) handlers to various things. You
10/// can think of id as a pointer (but without a lifetime) or a file descriptor 8/// can think of id as a pointer (but without a lifetime) or a file descriptor
@@ -206,7 +204,9 @@ impl DefKind {
206 204
207/// Identifier of item within a specific file. This is stable over reparses, so 205/// Identifier of item within a specific file. This is stable over reparses, so
208/// it's OK to use it as a salsa key/value. 206/// it's OK to use it as a salsa key/value.
209pub(crate) type SourceFileItemId = Id<SyntaxNode>; 207#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
208pub struct SourceFileItemId(RawId);
209impl_arena_id!(SourceFileItemId);
210 210
211#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 211#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
212pub struct SourceItemId { 212pub struct SourceItemId {
@@ -219,7 +219,7 @@ pub struct SourceItemId {
219#[derive(Debug, PartialEq, Eq)] 219#[derive(Debug, PartialEq, Eq)]
220pub struct SourceFileItems { 220pub struct SourceFileItems {
221 file_id: HirFileId, 221 file_id: HirFileId,
222 arena: Arena<SyntaxNode>, 222 arena: Arena<SourceFileItemId, SyntaxNode>,
223} 223}
224 224
225impl SourceFileItems { 225impl SourceFileItems {
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 8ee52a466..344b543b6 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -19,7 +19,6 @@ pub mod db;
19mod mock; 19mod mock;
20mod query_definitions; 20mod query_definitions;
21mod path; 21mod path;
22mod arena;
23pub mod source_binder; 22pub mod source_binder;
24 23
25mod ids; 24mod ids;
diff --git a/crates/ra_hir/src/module.rs b/crates/ra_hir/src/module.rs
index a53b69d20..c70dc54dd 100644
--- a/crates/ra_hir/src/module.rs
+++ b/crates/ra_hir/src/module.rs
@@ -9,6 +9,7 @@ use ra_syntax::{
9 ast::{self, AstNode, NameOwner}, 9 ast::{self, AstNode, NameOwner},
10 SyntaxNode, 10 SyntaxNode,
11}; 11};
12use ra_arena::{Arena, RawId, impl_arena_id};
12use ra_db::{SourceRootId, FileId, Cancelable}; 13use ra_db::{SourceRootId, FileId, Cancelable};
13use relative_path::RelativePathBuf; 14use relative_path::RelativePathBuf;
14 15
@@ -16,7 +17,6 @@ use crate::{
16 Def, DefKind, DefLoc, DefId, 17 Def, DefKind, DefLoc, DefId,
17 Name, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate, 18 Name, Path, PathKind, HirDatabase, SourceItemId, SourceFileItemId, Crate,
18 HirFileId, 19 HirFileId,
19 arena::{Arena, Id},
20}; 20};
21 21
22pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs}; 22pub use self::nameres::{ModuleScope, Resolution, Namespace, PerNs};
@@ -173,6 +173,14 @@ impl Module {
173 } 173 }
174} 174}
175 175
176#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
177pub struct ModuleId(RawId);
178impl_arena_id!(ModuleId);
179
180#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
181pub struct LinkId(RawId);
182impl_arena_id!(LinkId);
183
176/// Physically, rust source is organized as a set of files, but logically it is 184/// Physically, rust source is organized as a set of files, but logically it is
177/// organized as a tree of modules. Usually, a single file corresponds to a 185/// organized as a tree of modules. Usually, a single file corresponds to a
178/// single module, but it is not nessary the case. 186/// single module, but it is not nessary the case.
@@ -182,8 +190,8 @@ impl Module {
182/// always have one parent). 190/// always have one parent).
183#[derive(Default, Debug, PartialEq, Eq)] 191#[derive(Default, Debug, PartialEq, Eq)]
184pub struct ModuleTree { 192pub struct ModuleTree {
185 mods: Arena<ModuleData>, 193 mods: Arena<ModuleId, ModuleData>,
186 links: Arena<LinkData>, 194 links: Arena<LinkId, LinkData>,
187} 195}
188 196
189impl ModuleTree { 197impl ModuleTree {
@@ -210,9 +218,6 @@ pub(crate) enum ModuleSourceNode {
210 Module(ast::ModuleNode), 218 Module(ast::ModuleNode),
211} 219}
212 220
213pub type ModuleId = Id<ModuleData>;
214type LinkId = Id<LinkData>;
215
216#[derive(Clone, Debug, Hash, PartialEq, Eq)] 221#[derive(Clone, Debug, Hash, PartialEq, Eq)]
217pub enum Problem { 222pub enum Problem {
218 UnresolvedModule { 223 UnresolvedModule {
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 06dd373c0..60d9671de 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -350,7 +350,7 @@ fn on_notification(
350 .write() 350 .write()
351 .add_file_overlay(&path, params.text_document.text) 351 .add_file_overlay(&path, params.text_document.text)
352 { 352 {
353 subs.add_sub(FileId(file_id.0)); 353 subs.add_sub(FileId(file_id.0.into()));
354 } 354 }
355 return Ok(()); 355 return Ok(());
356 } 356 }
@@ -379,7 +379,7 @@ fn on_notification(
379 .to_file_path() 379 .to_file_path()
380 .map_err(|()| format_err!("invalid uri: {}", uri))?; 380 .map_err(|()| format_err!("invalid uri: {}", uri))?;
381 if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { 381 if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) {
382 subs.remove_sub(FileId(file_id.0)); 382 subs.remove_sub(FileId(file_id.0.into()));
383 } 383 }
384 let params = req::PublishDiagnosticsParams { 384 let params = req::PublishDiagnosticsParams {
385 uri, 385 uri,
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index b5792f3b8..4e895a9a9 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -337,7 +337,10 @@ pub fn handle_runnables(
337 None => return Ok(None), 337 None => return Ok(None),
338 }; 338 };
339 let file_id = world.analysis().crate_root(crate_id)?; 339 let file_id = world.analysis().crate_root(crate_id)?;
340 let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0)); 340 let path = world
341 .vfs
342 .read()
343 .file2path(ra_vfs::VfsFile(file_id.0.into()));
341 let res = world.workspaces.iter().find_map(|ws| { 344 let res = world.workspaces.iter().find_map(|ws| {
342 let tgt = ws.target_by_root(&path)?; 345 let tgt = ws.target_by_root(&path)?;
343 let res = CargoTargetSpec { 346 let res = CargoTargetSpec {
diff --git a/crates/ra_lsp_server/src/server_world.rs b/crates/ra_lsp_server/src/server_world.rs
index c183c25af..ebf2b15cc 100644
--- a/crates/ra_lsp_server/src/server_world.rs
+++ b/crates/ra_lsp_server/src/server_world.rs
@@ -49,7 +49,7 @@ impl ServerWorldState {
49 let (mut vfs, roots) = Vfs::new(roots); 49 let (mut vfs, roots) = Vfs::new(roots);
50 for r in roots { 50 for r in roots {
51 let is_local = vfs.root2path(r).starts_with(&root); 51 let is_local = vfs.root2path(r).starts_with(&root);
52 change.add_root(SourceRootId(r.0), is_local); 52 change.add_root(SourceRootId(r.0.into()), is_local);
53 } 53 }
54 54
55 let mut crate_graph = CrateGraph::default(); 55 let mut crate_graph = CrateGraph::default();
@@ -60,7 +60,7 @@ impl ServerWorldState {
60 for tgt in pkg.targets(ws) { 60 for tgt in pkg.targets(ws) {
61 let root = tgt.root(ws); 61 let root = tgt.root(ws);
62 if let Some(file_id) = vfs.load(root) { 62 if let Some(file_id) = vfs.load(root) {
63 let file_id = FileId(file_id.0); 63 let file_id = FileId(file_id.0.into());
64 let crate_id = crate_graph.add_crate_root(file_id); 64 let crate_id = crate_graph.add_crate_root(file_id);
65 if tgt.kind(ws) == TargetKind::Lib { 65 if tgt.kind(ws) == TargetKind::Lib {
66 pkg_to_lib_crate.insert(pkg, crate_id); 66 pkg_to_lib_crate.insert(pkg, crate_id);
@@ -113,14 +113,19 @@ impl ServerWorldState {
113 if root_path.starts_with(&self.root) { 113 if root_path.starts_with(&self.root) {
114 self.roots_to_scan -= 1; 114 self.roots_to_scan -= 1;
115 for (file, path, text) in files { 115 for (file, path, text) in files {
116 change.add_file(SourceRootId(root.0), FileId(file.0), path, text); 116 change.add_file(
117 SourceRootId(root.0.into()),
118 FileId(file.0.into()),
119 path,
120 text,
121 );
117 } 122 }
118 } else { 123 } else {
119 let files = files 124 let files = files
120 .into_iter() 125 .into_iter()
121 .map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text)) 126 .map(|(vfsfile, path, text)| (FileId(vfsfile.0.into()), path, text))
122 .collect(); 127 .collect();
123 libs.push((SourceRootId(root.0), files)); 128 libs.push((SourceRootId(root.0.into()), files));
124 } 129 }
125 } 130 }
126 VfsChange::AddFile { 131 VfsChange::AddFile {
@@ -129,13 +134,18 @@ impl ServerWorldState {
129 path, 134 path,
130 text, 135 text,
131 } => { 136 } => {
132 change.add_file(SourceRootId(root.0), FileId(file.0), path, text); 137 change.add_file(
138 SourceRootId(root.0.into()),
139 FileId(file.0.into()),
140 path,
141 text,
142 );
133 } 143 }
134 VfsChange::RemoveFile { root, file, path } => { 144 VfsChange::RemoveFile { root, file, path } => {
135 change.remove_file(SourceRootId(root.0), FileId(file.0), path) 145 change.remove_file(SourceRootId(root.0.into()), FileId(file.0.into()), path)
136 } 146 }
137 VfsChange::ChangeFile { file, text } => { 147 VfsChange::ChangeFile { file, text } => {
138 change.change_file(FileId(file.0), text); 148 change.change_file(FileId(file.0.into()), text);
139 } 149 }
140 } 150 }
141 } 151 }
@@ -173,18 +183,18 @@ impl ServerWorld {
173 .read() 183 .read()
174 .path2file(&path) 184 .path2file(&path)
175 .ok_or_else(|| format_err!("unknown file: {}", path.display()))?; 185 .ok_or_else(|| format_err!("unknown file: {}", path.display()))?;
176 Ok(FileId(file.0)) 186 Ok(FileId(file.0.into()))
177 } 187 }
178 188
179 pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> { 189 pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> {
180 let path = self.vfs.read().file2path(VfsFile(id.0)); 190 let path = self.vfs.read().file2path(VfsFile(id.0.into()));
181 let url = Url::from_file_path(&path) 191 let url = Url::from_file_path(&path)
182 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; 192 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?;
183 Ok(url) 193 Ok(url)
184 } 194 }
185 195
186 pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { 196 pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> {
187 let base = self.vfs.read().root2path(VfsRoot(root.0)); 197 let base = self.vfs.read().root2path(VfsRoot(root.0.into()));
188 let path = path.to_path(base); 198 let path = path.to_path(base);
189 let url = Url::from_file_path(&path) 199 let url = Url::from_file_path(&path)
190 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; 200 .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?;
diff --git a/crates/ra_vfs/Cargo.toml b/crates/ra_vfs/Cargo.toml
index 7c170cdfc..e637063c9 100644
--- a/crates/ra_vfs/Cargo.toml
+++ b/crates/ra_vfs/Cargo.toml
@@ -12,6 +12,7 @@ crossbeam-channel = "0.3.5"
12log = "0.4.6" 12log = "0.4.6"
13 13
14thread_worker = { path = "../thread_worker" } 14thread_worker = { path = "../thread_worker" }
15ra_arena = { path = "../ra_arena" }
15 16
16[dev-dependencies] 17[dev-dependencies]
17tempfile = "3" 18tempfile = "3"
diff --git a/crates/ra_vfs/src/arena.rs b/crates/ra_vfs/src/arena.rs
deleted file mode 100644
index 6b42ae26d..000000000
--- a/crates/ra_vfs/src/arena.rs
+++ /dev/null
@@ -1,53 +0,0 @@
1use std::{
2 marker::PhantomData,
3 ops::{Index, IndexMut},
4};
5
6#[derive(Clone, Debug)]
7pub(crate) struct Arena<ID: ArenaId, T> {
8 data: Vec<T>,
9 _ty: PhantomData<ID>,
10}
11
12pub(crate) trait ArenaId {
13 fn from_u32(id: u32) -> Self;
14 fn to_u32(self) -> u32;
15}
16
17impl<ID: ArenaId, T> Arena<ID, T> {
18 pub fn alloc(&mut self, value: T) -> ID {
19 let id = self.data.len() as u32;
20 self.data.push(value);
21 ID::from_u32(id)
22 }
23 pub fn iter<'a>(&'a self) -> impl Iterator<Item = (ID, &'a T)> {
24 self.data
25 .iter()
26 .enumerate()
27 .map(|(idx, value)| (ID::from_u32(idx as u32), value))
28 }
29}
30
31impl<ID: ArenaId, T> Default for Arena<ID, T> {
32 fn default() -> Arena<ID, T> {
33 Arena {
34 data: Vec::new(),
35 _ty: PhantomData,
36 }
37 }
38}
39
40impl<ID: ArenaId, T> Index<ID> for Arena<ID, T> {
41 type Output = T;
42 fn index(&self, idx: ID) -> &T {
43 let idx = idx.to_u32() as usize;
44 &self.data[idx]
45 }
46}
47
48impl<ID: ArenaId, T> IndexMut<ID> for Arena<ID, T> {
49 fn index_mut(&mut self, idx: ID) -> &mut T {
50 let idx = idx.to_u32() as usize;
51 &mut self.data[idx]
52 }
53}
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs
index 5bbc3e993..cdea18d73 100644
--- a/crates/ra_vfs/src/lib.rs
+++ b/crates/ra_vfs/src/lib.rs
@@ -13,7 +13,6 @@
13//! VFS is based on a concept of roots: a set of directories on the file system 13//! VFS is based on a concept of roots: a set of directories on the file system
14//! which are watched for changes. Typically, there will be a root for each 14//! which are watched for changes. Typically, there will be a root for each
15//! Cargo package. 15//! Cargo package.
16mod arena;
17mod io; 16mod io;
18 17
19use std::{ 18use std::{
@@ -32,10 +31,7 @@ use relative_path::RelativePathBuf;
32use crossbeam_channel::Receiver; 31use crossbeam_channel::Receiver;
33use walkdir::DirEntry; 32use walkdir::DirEntry;
34use thread_worker::WorkerHandle; 33use thread_worker::WorkerHandle;
35 34use ra_arena::{Arena, RawId, impl_arena_id};
36use crate::{
37 arena::{ArenaId, Arena},
38};
39 35
40pub use crate::io::TaskResult as VfsTask; 36pub use crate::io::TaskResult as VfsTask;
41 37
@@ -68,29 +64,13 @@ fn has_rs_extension(p: &Path) -> bool {
68 p.extension() == Some(OsStr::new("rs")) 64 p.extension() == Some(OsStr::new("rs"))
69} 65}
70 66
71#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 67#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
72pub struct VfsRoot(pub u32); 68pub struct VfsRoot(pub RawId);
73 69impl_arena_id!(VfsRoot);
74impl ArenaId for VfsRoot {
75 fn from_u32(idx: u32) -> VfsRoot {
76 VfsRoot(idx)
77 }
78 fn to_u32(self) -> u32 {
79 self.0
80 }
81}
82
83#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
84pub struct VfsFile(pub u32);
85 70
86impl ArenaId for VfsFile { 71#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
87 fn from_u32(idx: u32) -> VfsFile { 72pub struct VfsFile(pub RawId);
88 VfsFile(idx) 73impl_arena_id!(VfsFile);
89 }
90 fn to_u32(self) -> u32 {
91 self.0
92 }
93}
94 74
95struct VfsFileData { 75struct VfsFileData {
96 root: VfsRoot, 76 root: VfsRoot,