diff options
-rw-r--r-- | crates/ra_arena/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_arena/src/map.rs | 70 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 24 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 8 |
5 files changed, 97 insertions, 25 deletions
diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs index a5eeb4118..040977dc4 100644 --- a/crates/ra_arena/src/lib.rs +++ b/crates/ra_arena/src/lib.rs | |||
@@ -6,6 +6,8 @@ use std::{ | |||
6 | ops::{Index, IndexMut}, | 6 | ops::{Index, IndexMut}, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | pub mod map; | ||
10 | |||
9 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 11 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
10 | pub struct RawId(u32); | 12 | pub struct RawId(u32); |
11 | 13 | ||
diff --git a/crates/ra_arena/src/map.rs b/crates/ra_arena/src/map.rs new file mode 100644 index 000000000..2f09d677f --- /dev/null +++ b/crates/ra_arena/src/map.rs | |||
@@ -0,0 +1,70 @@ | |||
1 | //! A map from arena IDs to some other type. Space requirement is O(highest ID). | ||
2 | |||
3 | use std::marker::PhantomData; | ||
4 | |||
5 | use super::ArenaId; | ||
6 | |||
7 | /// A map from arena IDs to some other type. Space requirement is O(highest ID). | ||
8 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
9 | pub struct ArenaMap<ID, T> { | ||
10 | v: Vec<Option<T>>, | ||
11 | _ty: PhantomData<ID>, | ||
12 | } | ||
13 | |||
14 | impl<ID: ArenaId, T> ArenaMap<ID, T> { | ||
15 | pub fn insert(&mut self, id: ID, t: T) { | ||
16 | let idx = Self::to_idx(id); | ||
17 | if self.v.capacity() <= idx { | ||
18 | self.v.reserve(idx + 1 - self.v.capacity()); | ||
19 | } | ||
20 | if self.v.len() <= idx { | ||
21 | while self.v.len() <= idx { | ||
22 | self.v.push(None); | ||
23 | } | ||
24 | } | ||
25 | self.v[idx] = Some(t); | ||
26 | } | ||
27 | |||
28 | pub fn get(&self, id: ID) -> Option<&T> { | ||
29 | self.v.get(Self::to_idx(id)).and_then(|it| it.as_ref()) | ||
30 | } | ||
31 | |||
32 | pub fn values(&self) -> impl Iterator<Item = &T> { | ||
33 | self.v.iter().filter_map(|o| o.as_ref()) | ||
34 | } | ||
35 | |||
36 | pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> { | ||
37 | self.v.iter_mut().filter_map(|o| o.as_mut()) | ||
38 | } | ||
39 | |||
40 | pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> { | ||
41 | self.v | ||
42 | .iter() | ||
43 | .enumerate() | ||
44 | .filter_map(|(idx, o)| Some((Self::from_idx(idx), o.as_ref()?))) | ||
45 | } | ||
46 | |||
47 | fn to_idx(id: ID) -> usize { | ||
48 | u32::from(id.into_raw()) as usize | ||
49 | } | ||
50 | |||
51 | fn from_idx(idx: usize) -> ID { | ||
52 | ID::from_raw((idx as u32).into()) | ||
53 | } | ||
54 | } | ||
55 | |||
56 | impl<ID: ArenaId, T> std::ops::Index<ID> for ArenaMap<ID, T> { | ||
57 | type Output = T; | ||
58 | fn index(&self, id: ID) -> &T { | ||
59 | self.v[Self::to_idx(id)].as_ref().unwrap() | ||
60 | } | ||
61 | } | ||
62 | |||
63 | impl<ID, T> Default for ArenaMap<ID, T> { | ||
64 | fn default() -> Self { | ||
65 | ArenaMap { | ||
66 | v: Vec::new(), | ||
67 | _ty: PhantomData, | ||
68 | } | ||
69 | } | ||
70 | } | ||
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index c87d76735..69144e94f 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -3,7 +3,7 @@ use std::sync::Arc; | |||
3 | 3 | ||
4 | use rustc_hash::FxHashMap; | 4 | use rustc_hash::FxHashMap; |
5 | 5 | ||
6 | use ra_arena::{Arena, RawId, impl_arena_id}; | 6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
7 | use ra_db::{LocalSyntaxPtr, Cancelable}; | 7 | use ra_db::{LocalSyntaxPtr, Cancelable}; |
8 | use ra_syntax::{SyntaxNodeRef, ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner}}; | 8 | use ra_syntax::{SyntaxNodeRef, ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner}}; |
9 | 9 | ||
@@ -39,9 +39,9 @@ pub struct Body { | |||
39 | pub struct BodySyntaxMapping { | 39 | pub struct BodySyntaxMapping { |
40 | body: Arc<Body>, | 40 | body: Arc<Body>, |
41 | expr_syntax_mapping: FxHashMap<LocalSyntaxPtr, ExprId>, | 41 | expr_syntax_mapping: FxHashMap<LocalSyntaxPtr, ExprId>, |
42 | expr_syntax_mapping_back: FxHashMap<ExprId, LocalSyntaxPtr>, | 42 | expr_syntax_mapping_back: ArenaMap<ExprId, LocalSyntaxPtr>, |
43 | pat_syntax_mapping: FxHashMap<LocalSyntaxPtr, PatId>, | 43 | pat_syntax_mapping: FxHashMap<LocalSyntaxPtr, PatId>, |
44 | pat_syntax_mapping_back: FxHashMap<PatId, LocalSyntaxPtr>, | 44 | pat_syntax_mapping_back: ArenaMap<PatId, LocalSyntaxPtr>, |
45 | } | 45 | } |
46 | 46 | ||
47 | impl Body { | 47 | impl Body { |
@@ -72,7 +72,7 @@ impl Index<PatId> for Body { | |||
72 | 72 | ||
73 | impl BodySyntaxMapping { | 73 | impl BodySyntaxMapping { |
74 | pub fn expr_syntax(&self, expr: ExprId) -> Option<LocalSyntaxPtr> { | 74 | pub fn expr_syntax(&self, expr: ExprId) -> Option<LocalSyntaxPtr> { |
75 | self.expr_syntax_mapping_back.get(&expr).cloned() | 75 | self.expr_syntax_mapping_back.get(expr).cloned() |
76 | } | 76 | } |
77 | pub fn syntax_expr(&self, ptr: LocalSyntaxPtr) -> Option<ExprId> { | 77 | pub fn syntax_expr(&self, ptr: LocalSyntaxPtr) -> Option<ExprId> { |
78 | self.expr_syntax_mapping.get(&ptr).cloned() | 78 | self.expr_syntax_mapping.get(&ptr).cloned() |
@@ -83,7 +83,7 @@ impl BodySyntaxMapping { | |||
83 | .cloned() | 83 | .cloned() |
84 | } | 84 | } |
85 | pub fn pat_syntax(&self, pat: PatId) -> Option<LocalSyntaxPtr> { | 85 | pub fn pat_syntax(&self, pat: PatId) -> Option<LocalSyntaxPtr> { |
86 | self.pat_syntax_mapping_back.get(&pat).cloned() | 86 | self.pat_syntax_mapping_back.get(pat).cloned() |
87 | } | 87 | } |
88 | pub fn syntax_pat(&self, ptr: LocalSyntaxPtr) -> Option<PatId> { | 88 | pub fn syntax_pat(&self, ptr: LocalSyntaxPtr) -> Option<PatId> { |
89 | self.pat_syntax_mapping.get(&ptr).cloned() | 89 | self.pat_syntax_mapping.get(&ptr).cloned() |
@@ -334,9 +334,9 @@ struct ExprCollector { | |||
334 | exprs: Arena<ExprId, Expr>, | 334 | exprs: Arena<ExprId, Expr>, |
335 | pats: Arena<PatId, Pat>, | 335 | pats: Arena<PatId, Pat>, |
336 | expr_syntax_mapping: FxHashMap<LocalSyntaxPtr, ExprId>, | 336 | expr_syntax_mapping: FxHashMap<LocalSyntaxPtr, ExprId>, |
337 | expr_syntax_mapping_back: FxHashMap<ExprId, LocalSyntaxPtr>, | 337 | expr_syntax_mapping_back: ArenaMap<ExprId, LocalSyntaxPtr>, |
338 | pat_syntax_mapping: FxHashMap<LocalSyntaxPtr, PatId>, | 338 | pat_syntax_mapping: FxHashMap<LocalSyntaxPtr, PatId>, |
339 | pat_syntax_mapping_back: FxHashMap<PatId, LocalSyntaxPtr>, | 339 | pat_syntax_mapping_back: ArenaMap<PatId, LocalSyntaxPtr>, |
340 | } | 340 | } |
341 | 341 | ||
342 | impl ExprCollector { | 342 | impl ExprCollector { |
@@ -345,9 +345,9 @@ impl ExprCollector { | |||
345 | exprs: Arena::default(), | 345 | exprs: Arena::default(), |
346 | pats: Arena::default(), | 346 | pats: Arena::default(), |
347 | expr_syntax_mapping: FxHashMap::default(), | 347 | expr_syntax_mapping: FxHashMap::default(), |
348 | expr_syntax_mapping_back: FxHashMap::default(), | 348 | expr_syntax_mapping_back: ArenaMap::default(), |
349 | pat_syntax_mapping: FxHashMap::default(), | 349 | pat_syntax_mapping: FxHashMap::default(), |
350 | pat_syntax_mapping_back: FxHashMap::default(), | 350 | pat_syntax_mapping_back: ArenaMap::default(), |
351 | } | 351 | } |
352 | } | 352 | } |
353 | 353 | ||
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 6bdfdd7b4..d57990cd2 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -22,8 +22,8 @@ use std::sync::Arc; | |||
22 | use std::{fmt, mem}; | 22 | use std::{fmt, mem}; |
23 | 23 | ||
24 | use log; | 24 | use log; |
25 | use rustc_hash::FxHashMap; | ||
26 | use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError}; | 25 | use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError}; |
26 | use ra_arena::map::ArenaMap; | ||
27 | 27 | ||
28 | use ra_db::Cancelable; | 28 | use ra_db::Cancelable; |
29 | 29 | ||
@@ -470,15 +470,15 @@ pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) | |||
470 | /// The result of type inference: A mapping from expressions and patterns to types. | 470 | /// The result of type inference: A mapping from expressions and patterns to types. |
471 | #[derive(Clone, PartialEq, Eq, Debug)] | 471 | #[derive(Clone, PartialEq, Eq, Debug)] |
472 | pub struct InferenceResult { | 472 | pub struct InferenceResult { |
473 | type_of_expr: FxHashMap<ExprId, Ty>, | 473 | type_of_expr: ArenaMap<ExprId, Ty>, |
474 | type_of_pat: FxHashMap<PatId, Ty>, | 474 | type_of_pat: ArenaMap<PatId, Ty>, |
475 | } | 475 | } |
476 | 476 | ||
477 | impl Index<ExprId> for InferenceResult { | 477 | impl Index<ExprId> for InferenceResult { |
478 | type Output = Ty; | 478 | type Output = Ty; |
479 | 479 | ||
480 | fn index(&self, expr: ExprId) -> &Ty { | 480 | fn index(&self, expr: ExprId) -> &Ty { |
481 | self.type_of_expr.get(&expr).unwrap_or(&Ty::Unknown) | 481 | self.type_of_expr.get(expr).unwrap_or(&Ty::Unknown) |
482 | } | 482 | } |
483 | } | 483 | } |
484 | 484 | ||
@@ -486,7 +486,7 @@ impl Index<PatId> for InferenceResult { | |||
486 | type Output = Ty; | 486 | type Output = Ty; |
487 | 487 | ||
488 | fn index(&self, pat: PatId) -> &Ty { | 488 | fn index(&self, pat: PatId) -> &Ty { |
489 | self.type_of_pat.get(&pat).unwrap_or(&Ty::Unknown) | 489 | self.type_of_pat.get(pat).unwrap_or(&Ty::Unknown) |
490 | } | 490 | } |
491 | } | 491 | } |
492 | 492 | ||
@@ -499,8 +499,8 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
499 | module: Module, | 499 | module: Module, |
500 | impl_block: Option<ImplBlock>, | 500 | impl_block: Option<ImplBlock>, |
501 | var_unification_table: InPlaceUnificationTable<TypeVarId>, | 501 | var_unification_table: InPlaceUnificationTable<TypeVarId>, |
502 | type_of_expr: FxHashMap<ExprId, Ty>, | 502 | type_of_expr: ArenaMap<ExprId, Ty>, |
503 | type_of_pat: FxHashMap<PatId, Ty>, | 503 | type_of_pat: ArenaMap<PatId, Ty>, |
504 | /// The return type of the function being inferred. | 504 | /// The return type of the function being inferred. |
505 | return_ty: Ty, | 505 | return_ty: Ty, |
506 | } | 506 | } |
@@ -528,8 +528,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
528 | impl_block: Option<ImplBlock>, | 528 | impl_block: Option<ImplBlock>, |
529 | ) -> Self { | 529 | ) -> Self { |
530 | InferenceContext { | 530 | InferenceContext { |
531 | type_of_expr: FxHashMap::default(), | 531 | type_of_expr: ArenaMap::default(), |
532 | type_of_pat: FxHashMap::default(), | 532 | type_of_pat: ArenaMap::default(), |
533 | var_unification_table: InPlaceUnificationTable::new(), | 533 | var_unification_table: InPlaceUnificationTable::new(), |
534 | return_ty: Ty::Unknown, // set in collect_fn_signature | 534 | return_ty: Ty::Unknown, // set in collect_fn_signature |
535 | db, | 535 | db, |
@@ -541,12 +541,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
541 | } | 541 | } |
542 | 542 | ||
543 | fn resolve_all(mut self) -> InferenceResult { | 543 | fn resolve_all(mut self) -> InferenceResult { |
544 | let mut expr_types = mem::replace(&mut self.type_of_expr, FxHashMap::default()); | 544 | let mut expr_types = mem::replace(&mut self.type_of_expr, ArenaMap::default()); |
545 | for ty in expr_types.values_mut() { | 545 | for ty in expr_types.values_mut() { |
546 | let resolved = self.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); | 546 | let resolved = self.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); |
547 | *ty = resolved; | 547 | *ty = resolved; |
548 | } | 548 | } |
549 | let mut pat_types = mem::replace(&mut self.type_of_pat, FxHashMap::default()); | 549 | let mut pat_types = mem::replace(&mut self.type_of_pat, ArenaMap::default()); |
550 | for ty in pat_types.values_mut() { | 550 | for ty in pat_types.values_mut() { |
551 | let resolved = self.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); | 551 | let resolved = self.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); |
552 | *ty = resolved; | 552 | *ty = resolved; |
@@ -666,7 +666,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
666 | // resolve locally | 666 | // resolve locally |
667 | let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); | 667 | let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); |
668 | if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { | 668 | if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { |
669 | let ty = ctry!(self.type_of_pat.get(&scope_entry.pat())); | 669 | let ty = ctry!(self.type_of_pat.get(scope_entry.pat())); |
670 | let ty = self.resolve_ty_as_possible(ty.clone()); | 670 | let ty = self.resolve_ty_as_possible(ty.clone()); |
671 | return Ok(Some(ty)); | 671 | return Ok(Some(ty)); |
672 | }; | 672 | }; |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 20fb783b8..030a20f1b 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -195,16 +195,16 @@ fn infer(content: &str) -> String { | |||
195 | let inference_result = func.infer(&db).unwrap(); | 195 | let inference_result = func.infer(&db).unwrap(); |
196 | let body_syntax_mapping = func.body_syntax_mapping(&db).unwrap(); | 196 | let body_syntax_mapping = func.body_syntax_mapping(&db).unwrap(); |
197 | let mut types = Vec::new(); | 197 | let mut types = Vec::new(); |
198 | for (pat, ty) in &inference_result.type_of_pat { | 198 | for (pat, ty) in inference_result.type_of_pat.iter() { |
199 | let syntax_ptr = if let Some(sp) = body_syntax_mapping.pat_syntax(*pat) { | 199 | let syntax_ptr = if let Some(sp) = body_syntax_mapping.pat_syntax(pat) { |
200 | sp | 200 | sp |
201 | } else { | 201 | } else { |
202 | continue; | 202 | continue; |
203 | }; | 203 | }; |
204 | types.push((syntax_ptr, ty)); | 204 | types.push((syntax_ptr, ty)); |
205 | } | 205 | } |
206 | for (expr, ty) in &inference_result.type_of_expr { | 206 | for (expr, ty) in inference_result.type_of_expr.iter() { |
207 | let syntax_ptr = if let Some(sp) = body_syntax_mapping.expr_syntax(*expr) { | 207 | let syntax_ptr = if let Some(sp) = body_syntax_mapping.expr_syntax(expr) { |
208 | sp | 208 | sp |
209 | } else { | 209 | } else { |
210 | continue; | 210 | continue; |