diff options
38 files changed, 324 insertions, 358 deletions
diff --git a/crates/ra_arena/src/lib.rs b/crates/ra_arena/src/lib.rs index 3ec8d3b60..fc0f7c12f 100644 --- a/crates/ra_arena/src/lib.rs +++ b/crates/ra_arena/src/lib.rs | |||
@@ -37,7 +37,7 @@ impl fmt::Display for RawId { | |||
37 | } | 37 | } |
38 | 38 | ||
39 | #[derive(Clone, PartialEq, Eq)] | 39 | #[derive(Clone, PartialEq, Eq)] |
40 | pub struct Arena<ID: ArenaId, T> { | 40 | pub struct Arena<ID, T> { |
41 | data: Vec<T>, | 41 | data: Vec<T>, |
42 | _ty: PhantomData<ID>, | 42 | _ty: PhantomData<ID>, |
43 | } | 43 | } |
@@ -67,6 +67,12 @@ pub trait ArenaId { | |||
67 | fn into_raw(self) -> RawId; | 67 | fn into_raw(self) -> RawId; |
68 | } | 68 | } |
69 | 69 | ||
70 | impl<ID, T> Arena<ID, T> { | ||
71 | pub const fn new() -> Arena<ID, T> { | ||
72 | Arena { data: Vec::new(), _ty: PhantomData } | ||
73 | } | ||
74 | } | ||
75 | |||
70 | impl<ID: ArenaId, T> Arena<ID, T> { | 76 | impl<ID: ArenaId, T> Arena<ID, T> { |
71 | pub fn len(&self) -> usize { | 77 | pub fn len(&self) -> usize { |
72 | self.data.len() | 78 | self.data.len() |
@@ -79,7 +85,7 @@ impl<ID: ArenaId, T> Arena<ID, T> { | |||
79 | self.data.push(value); | 85 | self.data.push(value); |
80 | ID::from_raw(id) | 86 | ID::from_raw(id) |
81 | } | 87 | } |
82 | pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> + ExactSizeIterator { | 88 | pub fn iter(&self) -> impl Iterator<Item = (ID, &T)> + ExactSizeIterator + DoubleEndedIterator { |
83 | self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) | 89 | self.data.iter().enumerate().map(|(idx, value)| (ID::from_raw(RawId(idx as u32)), value)) |
84 | } | 90 | } |
85 | } | 91 | } |
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index 9cd21e4b6..c4eb28245 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; | 3 | use std::{collections::HashSet, fmt::Write, path::Path, time::Instant}; |
4 | 4 | ||
5 | use ra_db::SourceDatabaseExt; | 5 | use ra_db::SourceDatabaseExt; |
6 | use ra_hir::{AssocItem, Crate, HasBodySource, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; | 6 | use ra_hir::{AssocItem, Crate, HasSource, HirDisplay, ModuleDef, Ty, TypeWalk}; |
7 | use ra_syntax::AstNode; | 7 | use ra_syntax::AstNode; |
8 | 8 | ||
9 | use crate::{Result, Verbosity}; | 9 | use crate::{Result, Verbosity}; |
@@ -109,7 +109,7 @@ pub fn run( | |||
109 | } | 109 | } |
110 | let body = f.body(db); | 110 | let body = f.body(db); |
111 | let inference_result = f.infer(db); | 111 | let inference_result = f.infer(db); |
112 | for (expr_id, _) in body.exprs() { | 112 | for (expr_id, _) in body.exprs.iter() { |
113 | let ty = &inference_result[expr_id]; | 113 | let ty = &inference_result[expr_id]; |
114 | num_exprs += 1; | 114 | num_exprs += 1; |
115 | if let Ty::Unknown = ty { | 115 | if let Ty::Unknown = ty { |
@@ -128,15 +128,16 @@ pub fn run( | |||
128 | if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { | 128 | if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr_id) { |
129 | num_type_mismatches += 1; | 129 | num_type_mismatches += 1; |
130 | if verbosity.is_verbose() { | 130 | if verbosity.is_verbose() { |
131 | let src = f.expr_source(db, expr_id); | 131 | let src = f.body_source_map(db).expr_syntax(expr_id); |
132 | if let Some(src) = src { | 132 | if let Some(src) = src { |
133 | // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly | 133 | // FIXME: it might be nice to have a function (on Analysis?) that goes from Source<T> -> (LineCol, LineCol) directly |
134 | let original_file = src.file_id.original_file(db); | 134 | let original_file = src.file_id.original_file(db); |
135 | let path = db.file_relative_path(original_file); | 135 | let path = db.file_relative_path(original_file); |
136 | let line_index = host.analysis().file_line_index(original_file).unwrap(); | 136 | let line_index = host.analysis().file_line_index(original_file).unwrap(); |
137 | let text_range = src | 137 | let text_range = src.value.either( |
138 | .value | 138 | |it| it.syntax_node_ptr().range(), |
139 | .either(|it| it.syntax().text_range(), |it| it.syntax().text_range()); | 139 | |it| it.syntax_node_ptr().range(), |
140 | ); | ||
140 | let (start, end) = ( | 141 | let (start, end) = ( |
141 | line_index.line_col(text_range.start()), | 142 | line_index.line_col(text_range.start()), |
142 | line_index.line_col(text_range.end()), | 143 | line_index.line_col(text_range.end()), |
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index b3e2ff1c2..3f44a50c4 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -6,7 +6,6 @@ use std::sync::Arc; | |||
6 | 6 | ||
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | adt::VariantData, | 8 | adt::VariantData, |
9 | body::scope::ExprScopes, | ||
10 | builtin_type::BuiltinType, | 9 | builtin_type::BuiltinType, |
11 | docs::Documentation, | 10 | docs::Documentation, |
12 | per_ns::PerNs, | 11 | per_ns::PerNs, |
@@ -28,7 +27,7 @@ use crate::{ | |||
28 | db::{DefDatabase, HirDatabase}, | 27 | db::{DefDatabase, HirDatabase}, |
29 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, | 28 | expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, |
30 | ty::{InferenceResult, Namespace, TraitRef}, | 29 | ty::{InferenceResult, Namespace, TraitRef}, |
31 | Either, HasSource, Name, Source, Ty, | 30 | Either, Name, Source, Ty, |
32 | }; | 31 | }; |
33 | 32 | ||
34 | /// hir::Crate describes a single crate. It's the main interface with which | 33 | /// hir::Crate describes a single crate. It's the main interface with which |
@@ -62,7 +61,7 @@ impl Crate { | |||
62 | } | 61 | } |
63 | 62 | ||
64 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { | 63 | pub fn root_module(self, db: &impl DefDatabase) -> Option<Module> { |
65 | let module_id = db.crate_def_map(self.crate_id).root(); | 64 | let module_id = db.crate_def_map(self.crate_id).root; |
66 | Some(Module::new(self, module_id)) | 65 | Some(Module::new(self, module_id)) |
67 | } | 66 | } |
68 | 67 | ||
@@ -195,7 +194,7 @@ impl Module { | |||
195 | /// in the module tree of any target in `Cargo.toml`. | 194 | /// in the module tree of any target in `Cargo.toml`. |
196 | pub fn crate_root(self, db: &impl DefDatabase) -> Module { | 195 | pub fn crate_root(self, db: &impl DefDatabase) -> Module { |
197 | let def_map = db.crate_def_map(self.id.krate); | 196 | let def_map = db.crate_def_map(self.id.krate); |
198 | self.with_module_id(def_map.root()) | 197 | self.with_module_id(def_map.root) |
199 | } | 198 | } |
200 | 199 | ||
201 | /// Finds a child module with the specified name. | 200 | /// Finds a child module with the specified name. |
@@ -302,11 +301,11 @@ pub enum FieldSource { | |||
302 | 301 | ||
303 | impl StructField { | 302 | impl StructField { |
304 | pub fn name(&self, db: &impl HirDatabase) -> Name { | 303 | pub fn name(&self, db: &impl HirDatabase) -> Name { |
305 | self.parent.variant_data(db).fields().unwrap()[self.id].name.clone() | 304 | self.parent.variant_data(db).fields()[self.id].name.clone() |
306 | } | 305 | } |
307 | 306 | ||
308 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { | 307 | pub fn ty(&self, db: &impl HirDatabase) -> Ty { |
309 | db.type_for_field(*self) | 308 | db.field_types(self.parent.into())[self.id].clone() |
310 | } | 309 | } |
311 | 310 | ||
312 | pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { | 311 | pub fn parent_def(&self, _db: &impl HirDatabase) -> VariantDef { |
@@ -336,8 +335,7 @@ impl Struct { | |||
336 | db.struct_data(self.id.into()) | 335 | db.struct_data(self.id.into()) |
337 | .variant_data | 336 | .variant_data |
338 | .fields() | 337 | .fields() |
339 | .into_iter() | 338 | .iter() |
340 | .flat_map(|it| it.iter()) | ||
341 | .map(|(id, _)| StructField { parent: self.into(), id }) | 339 | .map(|(id, _)| StructField { parent: self.into(), id }) |
342 | .collect() | 340 | .collect() |
343 | } | 341 | } |
@@ -346,8 +344,7 @@ impl Struct { | |||
346 | db.struct_data(self.id.into()) | 344 | db.struct_data(self.id.into()) |
347 | .variant_data | 345 | .variant_data |
348 | .fields() | 346 | .fields() |
349 | .into_iter() | 347 | .iter() |
350 | .flat_map(|it| it.iter()) | ||
351 | .find(|(_id, data)| data.name == *name) | 348 | .find(|(_id, data)| data.name == *name) |
352 | .map(|(id, _)| StructField { parent: self.into(), id }) | 349 | .map(|(id, _)| StructField { parent: self.into(), id }) |
353 | } | 350 | } |
@@ -444,8 +441,7 @@ impl EnumVariant { | |||
444 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { | 441 | pub fn fields(self, db: &impl HirDatabase) -> Vec<StructField> { |
445 | self.variant_data(db) | 442 | self.variant_data(db) |
446 | .fields() | 443 | .fields() |
447 | .into_iter() | 444 | .iter() |
448 | .flat_map(|it| it.iter()) | ||
449 | .map(|(id, _)| StructField { parent: self.into(), id }) | 445 | .map(|(id, _)| StructField { parent: self.into(), id }) |
450 | .collect() | 446 | .collect() |
451 | } | 447 | } |
@@ -453,8 +449,7 @@ impl EnumVariant { | |||
453 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | 449 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { |
454 | self.variant_data(db) | 450 | self.variant_data(db) |
455 | .fields() | 451 | .fields() |
456 | .into_iter() | 452 | .iter() |
457 | .flat_map(|it| it.iter()) | ||
458 | .find(|(_id, data)| data.name == *name) | 453 | .find(|(_id, data)| data.name == *name) |
459 | .map(|(id, _)| StructField { parent: self.into(), id }) | 454 | .map(|(id, _)| StructField { parent: self.into(), id }) |
460 | } | 455 | } |
@@ -510,7 +505,7 @@ impl VariantDef { | |||
510 | } | 505 | } |
511 | } | 506 | } |
512 | 507 | ||
513 | pub fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | 508 | pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { |
514 | match self { | 509 | match self { |
515 | VariantDef::Struct(it) => it.field(db, name), | 510 | VariantDef::Struct(it) => it.field(db, name), |
516 | VariantDef::EnumVariant(it) => it.field(db, name), | 511 | VariantDef::EnumVariant(it) => it.field(db, name), |
@@ -560,52 +555,6 @@ impl DefWithBody { | |||
560 | } | 555 | } |
561 | } | 556 | } |
562 | 557 | ||
563 | pub trait HasBody: Copy { | ||
564 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>; | ||
565 | fn body(self, db: &impl HirDatabase) -> Arc<Body>; | ||
566 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>; | ||
567 | fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes>; | ||
568 | } | ||
569 | |||
570 | impl<T> HasBody for T | ||
571 | where | ||
572 | T: Into<DefWithBody> + Copy + HasSource, | ||
573 | { | ||
574 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
575 | db.infer(self.into()) | ||
576 | } | ||
577 | |||
578 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
579 | self.into().body(db) | ||
580 | } | ||
581 | |||
582 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
583 | self.into().body_source_map(db) | ||
584 | } | ||
585 | |||
586 | fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> { | ||
587 | self.into().expr_scopes(db) | ||
588 | } | ||
589 | } | ||
590 | |||
591 | impl HasBody for DefWithBody { | ||
592 | fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | ||
593 | db.infer(self) | ||
594 | } | ||
595 | |||
596 | fn body(self, db: &impl HirDatabase) -> Arc<Body> { | ||
597 | db.body(self.into()) | ||
598 | } | ||
599 | |||
600 | fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | ||
601 | db.body_with_source_map(self.into()).1 | ||
602 | } | ||
603 | |||
604 | fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> { | ||
605 | db.expr_scopes(self.into()) | ||
606 | } | ||
607 | } | ||
608 | |||
609 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 558 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
610 | pub struct Function { | 559 | pub struct Function { |
611 | pub(crate) id: FunctionId, | 560 | pub(crate) id: FunctionId, |
@@ -632,7 +581,7 @@ impl Function { | |||
632 | db.function_data(self.id).params.clone() | 581 | db.function_data(self.id).params.clone() |
633 | } | 582 | } |
634 | 583 | ||
635 | pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { | 584 | pub fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> { |
636 | db.body_with_source_map(self.id.into()).1 | 585 | db.body_with_source_map(self.id.into()).1 |
637 | } | 586 | } |
638 | 587 | ||
@@ -966,7 +915,7 @@ pub struct Local { | |||
966 | 915 | ||
967 | impl Local { | 916 | impl Local { |
968 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { | 917 | pub fn name(self, db: &impl HirDatabase) -> Option<Name> { |
969 | let body = self.parent.body(db); | 918 | let body = db.body(self.parent.into()); |
970 | match &body[self.pat_id] { | 919 | match &body[self.pat_id] { |
971 | Pat::Bind { name, .. } => Some(name.clone()), | 920 | Pat::Bind { name, .. } => Some(name.clone()), |
972 | _ => None, | 921 | _ => None, |
@@ -978,7 +927,7 @@ impl Local { | |||
978 | } | 927 | } |
979 | 928 | ||
980 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { | 929 | pub fn is_mut(self, db: &impl HirDatabase) -> bool { |
981 | let body = self.parent.body(db); | 930 | let body = db.body(self.parent.into()); |
982 | match &body[self.pat_id] { | 931 | match &body[self.pat_id] { |
983 | Pat::Bind { mode, .. } => match mode { | 932 | Pat::Bind { mode, .. } => match mode { |
984 | BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, | 933 | BindingAnnotation::Mutable | BindingAnnotation::RefMut => true, |
@@ -1002,7 +951,7 @@ impl Local { | |||
1002 | } | 951 | } |
1003 | 952 | ||
1004 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { | 953 | pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> { |
1005 | let source_map = self.parent.body_source_map(db); | 954 | let (_body, source_map) = db.body_with_source_map(self.parent.into()); |
1006 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... | 955 | let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm... |
1007 | let root = src.file_syntax(db); | 956 | let root = src.file_syntax(db); |
1008 | src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) | 957 | src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root))) |
@@ -1020,6 +969,41 @@ pub struct ImplBlock { | |||
1020 | pub(crate) id: ImplId, | 969 | pub(crate) id: ImplId, |
1021 | } | 970 | } |
1022 | 971 | ||
972 | impl ImplBlock { | ||
973 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | ||
974 | db.impl_data(self.id).target_trait.clone() | ||
975 | } | ||
976 | |||
977 | pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { | ||
978 | db.impl_data(self.id).target_type.clone() | ||
979 | } | ||
980 | |||
981 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { | ||
982 | Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db)) | ||
983 | } | ||
984 | |||
985 | pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { | ||
986 | let target_ty = self.target_ty(db); | ||
987 | TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty)) | ||
988 | } | ||
989 | |||
990 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | ||
991 | db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect() | ||
992 | } | ||
993 | |||
994 | pub fn is_negative(&self, db: &impl DefDatabase) -> bool { | ||
995 | db.impl_data(self.id).is_negative | ||
996 | } | ||
997 | |||
998 | pub fn module(&self, db: &impl DefDatabase) -> Module { | ||
999 | self.id.module(db).into() | ||
1000 | } | ||
1001 | |||
1002 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { | ||
1003 | Crate { crate_id: self.module(db).id.krate } | ||
1004 | } | ||
1005 | } | ||
1006 | |||
1023 | /// For IDE only | 1007 | /// For IDE only |
1024 | pub enum ScopeDef { | 1008 | pub enum ScopeDef { |
1025 | ModuleDef(ModuleDef), | 1009 | ModuleDef(ModuleDef), |
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs index b9d21bdd7..a4e317c20 100644 --- a/crates/ra_hir/src/code_model/src.rs +++ b/crates/ra_hir/src/code_model/src.rs | |||
@@ -2,12 +2,11 @@ | |||
2 | 2 | ||
3 | use hir_def::{AstItemDef, HasChildSource, HasSource as _, Lookup, VariantId}; | 3 | use hir_def::{AstItemDef, HasChildSource, HasSource as _, Lookup, VariantId}; |
4 | use hir_expand::either::Either; | 4 | use hir_expand::either::Either; |
5 | use ra_syntax::ast::{self, AstNode}; | 5 | use ra_syntax::ast; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | db::{DefDatabase, HirDatabase}, | 8 | db::DefDatabase, Const, Enum, EnumVariant, FieldSource, Function, ImplBlock, Import, MacroDef, |
9 | Const, Enum, EnumVariant, FieldSource, Function, HasBody, Import, MacroDef, Module, | 9 | Module, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, |
10 | ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, | ||
11 | }; | 10 | }; |
12 | 11 | ||
13 | pub use hir_expand::Source; | 12 | pub use hir_expand::Source; |
@@ -109,6 +108,12 @@ impl HasSource for MacroDef { | |||
109 | Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } | 108 | Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } |
110 | } | 109 | } |
111 | } | 110 | } |
111 | impl HasSource for ImplBlock { | ||
112 | type Ast = ast::ImplBlock; | ||
113 | fn source(self, db: &impl DefDatabase) -> Source<ast::ImplBlock> { | ||
114 | self.id.source(db) | ||
115 | } | ||
116 | } | ||
112 | impl HasSource for Import { | 117 | impl HasSource for Import { |
113 | type Ast = Either<ast::UseTree, ast::ExternCrateItem>; | 118 | type Ast = Either<ast::UseTree, ast::ExternCrateItem>; |
114 | 119 | ||
@@ -121,27 +126,3 @@ impl HasSource for Import { | |||
121 | src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root))) | 126 | src.with_value(ptr.map(|it| it.to_node(&root), |it| it.to_node(&root))) |
122 | } | 127 | } |
123 | } | 128 | } |
124 | |||
125 | pub trait HasBodySource: HasBody + HasSource | ||
126 | where | ||
127 | Self::Ast: AstNode, | ||
128 | { | ||
129 | fn expr_source( | ||
130 | self, | ||
131 | db: &impl HirDatabase, | ||
132 | expr_id: crate::expr::ExprId, | ||
133 | ) -> Option<Source<Either<ast::Expr, ast::RecordField>>> { | ||
134 | let source_map = self.body_source_map(db); | ||
135 | let source_ptr = source_map.expr_syntax(expr_id)?; | ||
136 | let root = source_ptr.file_syntax(db); | ||
137 | let source = source_ptr.map(|ast| ast.map(|it| it.to_node(&root), |it| it.to_node(&root))); | ||
138 | Some(source) | ||
139 | } | ||
140 | } | ||
141 | |||
142 | impl<T> HasBodySource for T | ||
143 | where | ||
144 | T: HasBody + HasSource, | ||
145 | T::Ast: AstNode, | ||
146 | { | ||
147 | } | ||
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index a9dab2d25..5084bbacf 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use ra_arena::map::ArenaMap; | ||
5 | use ra_db::salsa; | 6 | use ra_db::salsa; |
6 | 7 | ||
7 | use crate::{ | 8 | use crate::{ |
@@ -11,15 +12,19 @@ use crate::{ | |||
11 | CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, | 12 | CallableDef, FnSig, GenericPredicate, InferenceResult, Namespace, Substs, Ty, TypableDef, |
12 | TypeCtor, | 13 | TypeCtor, |
13 | }, | 14 | }, |
14 | Crate, DefWithBody, GenericDef, ImplBlock, StructField, Trait, | 15 | Crate, DefWithBody, GenericDef, ImplBlock, Trait, |
15 | }; | 16 | }; |
16 | 17 | ||
17 | pub use hir_def::db::{ | 18 | pub use hir_def::{ |
18 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, | 19 | db::{ |
19 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, | 20 | BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, |
20 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, | 21 | DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, |
21 | LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, RawItemsWithSourceMapQuery, | 22 | FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, |
22 | StaticDataQuery, StructDataQuery, TraitDataQuery, TypeAliasDataQuery, | 23 | InternDatabaseStorage, LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, |
24 | RawItemsWithSourceMapQuery, StaticDataQuery, StructDataQuery, TraitDataQuery, | ||
25 | TypeAliasDataQuery, | ||
26 | }, | ||
27 | LocalStructFieldId, VariantId, | ||
23 | }; | 28 | }; |
24 | pub use hir_expand::db::{ | 29 | pub use hir_expand::db::{ |
25 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, | 30 | AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, |
@@ -35,8 +40,8 @@ pub trait HirDatabase: DefDatabase { | |||
35 | #[salsa::invoke(crate::ty::type_for_def)] | 40 | #[salsa::invoke(crate::ty::type_for_def)] |
36 | fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; | 41 | fn type_for_def(&self, def: TypableDef, ns: Namespace) -> Ty; |
37 | 42 | ||
38 | #[salsa::invoke(crate::ty::type_for_field)] | 43 | #[salsa::invoke(crate::ty::field_types_query)] |
39 | fn type_for_field(&self, field: StructField) -> Ty; | 44 | fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>; |
40 | 45 | ||
41 | #[salsa::invoke(crate::ty::callable_item_sig)] | 46 | #[salsa::invoke(crate::ty::callable_item_sig)] |
42 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; | 47 | fn callable_item_signature(&self, def: CallableDef) -> FnSig; |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 6b703d8b4..43fedde7a 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -44,15 +44,15 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
44 | pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { | 44 | pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { |
45 | let body = self.func.body(db); | 45 | let body = self.func.body(db); |
46 | 46 | ||
47 | for e in body.exprs() { | 47 | for e in body.exprs.iter() { |
48 | if let (id, Expr::RecordLit { path, fields, spread }) = e { | 48 | if let (id, Expr::RecordLit { path, fields, spread }) = e { |
49 | self.validate_record_literal(id, path, fields, *spread, db); | 49 | self.validate_record_literal(id, path, fields, *spread, db); |
50 | } | 50 | } |
51 | } | 51 | } |
52 | 52 | ||
53 | let body_expr = &body[body.body_expr()]; | 53 | let body_expr = &body[body.body_expr]; |
54 | if let Expr::Block { statements: _, tail: Some(t) } = body_expr { | 54 | if let Expr::Block { statements: _, tail: Some(t) } = body_expr { |
55 | self.validate_results_in_tail_expr(body.body_expr(), *t, db); | 55 | self.validate_results_in_tail_expr(body.body_expr, *t, db); |
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index f506bba70..1e7c22774 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -9,9 +9,9 @@ use ra_syntax::{ | |||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::{AstDatabase, DefDatabase, HirDatabase}, | 11 | db::{AstDatabase, DefDatabase, HirDatabase}, |
12 | AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, | 12 | AssocItem, Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock, |
13 | ImplBlock, Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, | 13 | Local, MacroDef, Module, ModuleDef, ModuleSource, Source, Static, Struct, StructField, Trait, |
14 | StructField, Trait, TypeAlias, Union, VariantDef, | 14 | TypeAlias, Union, VariantDef, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | pub trait FromSource: Sized { | 17 | pub trait FromSource: Sized { |
@@ -200,8 +200,7 @@ impl FromSource for StructField { | |||
200 | variant_def | 200 | variant_def |
201 | .variant_data(db) | 201 | .variant_data(db) |
202 | .fields() | 202 | .fields() |
203 | .into_iter() | 203 | .iter() |
204 | .flat_map(|it| it.iter()) | ||
205 | .map(|(id, _)| StructField { parent: variant_def, id }) | 204 | .map(|(id, _)| StructField { parent: variant_def, id }) |
206 | .find(|f| f.source(db) == src) | 205 | .find(|f| f.source(db) == src) |
207 | } | 206 | } |
@@ -221,7 +220,7 @@ impl Local { | |||
221 | }; | 220 | }; |
222 | Some(res) | 221 | Some(res) |
223 | })?; | 222 | })?; |
224 | let source_map = parent.body_source_map(db); | 223 | let (_body, source_map) = db.body_with_source_map(parent.into()); |
225 | let src = src.map(ast::Pat::from); | 224 | let src = src.map(ast::Pat::from); |
226 | let pat_id = source_map.node_pat(src.as_ref())?; | 225 | let pat_id = source_map.node_pat(src.as_ref())?; |
227 | Some(Local { parent, pat_id }) | 226 | Some(Local { parent, pat_id }) |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs deleted file mode 100644 index 334eeebac..000000000 --- a/crates/ra_hir/src/impl_block.rs +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use hir_def::{resolver::HasResolver, type_ref::TypeRef, AstItemDef}; | ||
4 | use ra_syntax::ast; | ||
5 | |||
6 | use crate::{ | ||
7 | db::{AstDatabase, DefDatabase, HirDatabase}, | ||
8 | ty::Ty, | ||
9 | AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, | ||
10 | }; | ||
11 | |||
12 | impl HasSource for ImplBlock { | ||
13 | type Ast = ast::ImplBlock; | ||
14 | fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ImplBlock> { | ||
15 | self.id.source(db) | ||
16 | } | ||
17 | } | ||
18 | |||
19 | impl ImplBlock { | ||
20 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | ||
21 | db.impl_data(self.id).target_trait.clone() | ||
22 | } | ||
23 | |||
24 | pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { | ||
25 | db.impl_data(self.id).target_type.clone() | ||
26 | } | ||
27 | |||
28 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { | ||
29 | Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db)) | ||
30 | } | ||
31 | |||
32 | pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option<TraitRef> { | ||
33 | let target_ty = self.target_ty(db); | ||
34 | TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty)) | ||
35 | } | ||
36 | |||
37 | pub fn items(&self, db: &impl DefDatabase) -> Vec<AssocItem> { | ||
38 | db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect() | ||
39 | } | ||
40 | |||
41 | pub fn is_negative(&self, db: &impl DefDatabase) -> bool { | ||
42 | db.impl_data(self.id).is_negative | ||
43 | } | ||
44 | |||
45 | pub fn module(&self, db: &impl DefDatabase) -> Module { | ||
46 | self.id.module(db).into() | ||
47 | } | ||
48 | |||
49 | pub fn krate(&self, db: &impl DefDatabase) -> Crate { | ||
50 | Crate { crate_id: self.module(db).id.krate } | ||
51 | } | ||
52 | } | ||
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 8c589c728..843ce6a88 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -32,7 +32,6 @@ pub mod db; | |||
32 | pub mod source_binder; | 32 | pub mod source_binder; |
33 | 33 | ||
34 | mod ty; | 34 | mod ty; |
35 | mod impl_block; | ||
36 | mod expr; | 35 | mod expr; |
37 | pub mod diagnostics; | 36 | pub mod diagnostics; |
38 | mod util; | 37 | mod util; |
@@ -49,11 +48,10 @@ mod marks; | |||
49 | 48 | ||
50 | pub use crate::{ | 49 | pub use crate::{ |
51 | code_model::{ | 50 | code_model::{ |
52 | src::{HasBodySource, HasSource}, | 51 | src::HasSource, Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, |
53 | Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, DefWithBody, Docs, Enum, | 52 | DefWithBody, Docs, Enum, EnumVariant, FieldSource, Function, GenericDef, GenericParam, |
54 | EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasAttrs, HasBody, ImplBlock, | 53 | HasAttrs, ImplBlock, Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, |
55 | Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, | 54 | Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, |
56 | StructField, Trait, TypeAlias, Union, VariantDef, | ||
57 | }, | 55 | }, |
58 | expr::ExprScopes, | 56 | expr::ExprScopes, |
59 | from_source::FromSource, | 57 | from_source::FromSource, |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index cfc4bd326..31390bb7f 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -28,8 +28,7 @@ use crate::{ | |||
28 | expr::{BodySourceMap, ExprScopes, ScopeId}, | 28 | expr::{BodySourceMap, ExprScopes, ScopeId}, |
29 | ty::method_resolution::{self, implements_trait}, | 29 | ty::method_resolution::{self, implements_trait}, |
30 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, | 30 | Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, |
31 | GenericParam, HasBody, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, | 31 | GenericParam, Local, MacroDef, Name, Path, ScopeDef, Static, Struct, Trait, Ty, TypeAlias, |
32 | TypeAlias, | ||
33 | }; | 32 | }; |
34 | 33 | ||
35 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { | 34 | fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option<Resolver> { |
@@ -155,8 +154,8 @@ impl SourceAnalyzer { | |||
155 | ) -> SourceAnalyzer { | 154 | ) -> SourceAnalyzer { |
156 | let def_with_body = def_with_body_from_child_node(db, node); | 155 | let def_with_body = def_with_body_from_child_node(db, node); |
157 | if let Some(def) = def_with_body { | 156 | if let Some(def) = def_with_body { |
158 | let source_map = def.body_source_map(db); | 157 | let (_body, source_map) = db.body_with_source_map(def.into()); |
159 | let scopes = def.expr_scopes(db); | 158 | let scopes = db.expr_scopes(def.into()); |
160 | let scope = match offset { | 159 | let scope = match offset { |
161 | None => scope_for(&scopes, &source_map, node), | 160 | None => scope_for(&scopes, &source_map, node), |
162 | Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), | 161 | Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), |
@@ -166,7 +165,7 @@ impl SourceAnalyzer { | |||
166 | resolver, | 165 | resolver, |
167 | body_owner: Some(def), | 166 | body_owner: Some(def), |
168 | body_source_map: Some(source_map), | 167 | body_source_map: Some(source_map), |
169 | infer: Some(def.infer(db)), | 168 | infer: Some(db.infer(def)), |
170 | scopes: Some(scopes), | 169 | scopes: Some(scopes), |
171 | file_id: node.file_id, | 170 | file_id: node.file_id, |
172 | } | 171 | } |
@@ -216,6 +215,11 @@ impl SourceAnalyzer { | |||
216 | self.infer.as_ref()?.field_resolution(expr_id) | 215 | self.infer.as_ref()?.field_resolution(expr_id) |
217 | } | 216 | } |
218 | 217 | ||
218 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { | ||
219 | let expr_id = self.expr_id(&field.expr()?)?; | ||
220 | self.infer.as_ref()?.record_field_resolution(expr_id) | ||
221 | } | ||
222 | |||
219 | pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { | 223 | pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { |
220 | let expr_id = self.expr_id(&record_lit.clone().into())?; | 224 | let expr_id = self.expr_id(&record_lit.clone().into())?; |
221 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) | 225 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) |
diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir/src/test_db.rs index 03c7ac155..efee2f658 100644 --- a/crates/ra_hir/src/test_db.rs +++ b/crates/ra_hir/src/test_db.rs | |||
@@ -80,7 +80,7 @@ impl TestDB { | |||
80 | let crate_graph = self.crate_graph(); | 80 | let crate_graph = self.crate_graph(); |
81 | for krate in crate_graph.iter().next() { | 81 | for krate in crate_graph.iter().next() { |
82 | let crate_def_map = self.crate_def_map(krate); | 82 | let crate_def_map = self.crate_def_map(krate); |
83 | for module_id in crate_def_map.modules() { | 83 | for (module_id, _) in crate_def_map.modules.iter() { |
84 | let module_id = ModuleId { krate, module_id }; | 84 | let module_id = ModuleId { krate, module_id }; |
85 | let module = crate::Module::from(module_id); | 85 | let module = crate::Module::from(module_id); |
86 | module.diagnostics( | 86 | module.diagnostics( |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 309bd2727..f62316c1f 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -30,8 +30,9 @@ pub(crate) use autoderef::autoderef; | |||
30 | pub(crate) use infer::{infer_query, InferTy, InferenceResult}; | 30 | pub(crate) use infer::{infer_query, InferTy, InferenceResult}; |
31 | pub use lower::CallableDef; | 31 | pub use lower::CallableDef; |
32 | pub(crate) use lower::{ | 32 | pub(crate) use lower::{ |
33 | callable_item_sig, generic_defaults_query, generic_predicates_for_param_query, | 33 | callable_item_sig, field_types_query, generic_defaults_query, |
34 | generic_predicates_query, type_for_def, type_for_field, Namespace, TypableDef, | 34 | generic_predicates_for_param_query, generic_predicates_query, type_for_def, Namespace, |
35 | TypableDef, | ||
35 | }; | 36 | }; |
36 | pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 37 | pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; |
37 | 38 | ||
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 471bdc387..ddc7d262a 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -44,8 +44,7 @@ use crate::{ | |||
44 | db::HirDatabase, | 44 | db::HirDatabase, |
45 | expr::{BindingAnnotation, Body, ExprId, PatId}, | 45 | expr::{BindingAnnotation, Body, ExprId, PatId}, |
46 | ty::infer::diagnostics::InferenceDiagnostic, | 46 | ty::infer::diagnostics::InferenceDiagnostic, |
47 | Adt, AssocItem, DefWithBody, FloatTy, Function, HasBody, IntTy, Path, StructField, Trait, | 47 | Adt, AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, Trait, VariantDef, |
48 | VariantDef, | ||
49 | }; | 48 | }; |
50 | 49 | ||
51 | macro_rules! ty_app { | 50 | macro_rules! ty_app { |
@@ -126,6 +125,8 @@ pub struct InferenceResult { | |||
126 | method_resolutions: FxHashMap<ExprId, Function>, | 125 | method_resolutions: FxHashMap<ExprId, Function>, |
127 | /// For each field access expr, records the field it resolves to. | 126 | /// For each field access expr, records the field it resolves to. |
128 | field_resolutions: FxHashMap<ExprId, StructField>, | 127 | field_resolutions: FxHashMap<ExprId, StructField>, |
128 | /// For each field in record literal, records the field it resolves to. | ||
129 | record_field_resolutions: FxHashMap<ExprId, StructField>, | ||
129 | /// For each struct literal, records the variant it resolves to. | 130 | /// For each struct literal, records the variant it resolves to. |
130 | variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>, | 131 | variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>, |
131 | /// For each associated item record what it resolves to | 132 | /// For each associated item record what it resolves to |
@@ -143,6 +144,9 @@ impl InferenceResult { | |||
143 | pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { | 144 | pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { |
144 | self.field_resolutions.get(&expr).copied() | 145 | self.field_resolutions.get(&expr).copied() |
145 | } | 146 | } |
147 | pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructField> { | ||
148 | self.record_field_resolutions.get(&expr).copied() | ||
149 | } | ||
146 | pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> { | 150 | pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> { |
147 | self.variant_resolutions.get(&id.into()).copied() | 151 | self.variant_resolutions.get(&id.into()).copied() |
148 | } | 152 | } |
@@ -216,7 +220,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
216 | coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), | 220 | coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver), |
217 | db, | 221 | db, |
218 | owner, | 222 | owner, |
219 | body: owner.body(db), | 223 | body: db.body(owner.into()), |
220 | resolver, | 224 | resolver, |
221 | } | 225 | } |
222 | } | 226 | } |
@@ -565,7 +569,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
565 | 569 | ||
566 | fn collect_fn(&mut self, data: &FunctionData) { | 570 | fn collect_fn(&mut self, data: &FunctionData) { |
567 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 571 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
568 | for (type_ref, pat) in data.params.iter().zip(body.params()) { | 572 | for (type_ref, pat) in data.params.iter().zip(body.params.iter()) { |
569 | let ty = self.make_ty(type_ref); | 573 | let ty = self.make_ty(type_ref); |
570 | 574 | ||
571 | self.infer_pat(*pat, &ty, BindingMode::default()); | 575 | self.infer_pat(*pat, &ty, BindingMode::default()); |
@@ -574,7 +578,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
574 | } | 578 | } |
575 | 579 | ||
576 | fn infer_body(&mut self) { | 580 | fn infer_body(&mut self) { |
577 | self.infer_expr(self.body.body_expr(), &Expectation::has_type(self.return_ty.clone())); | 581 | self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); |
578 | } | 582 | } |
579 | 583 | ||
580 | fn resolve_into_iter_item(&self) -> Option<TypeAlias> { | 584 | fn resolve_into_iter_item(&self) -> Option<TypeAlias> { |
diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 4ea038d99..54765da35 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs | |||
@@ -245,14 +245,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
245 | ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), | 245 | ty_app!(TypeCtor::Adt(Adt::Struct(struct1)), st1), |
246 | ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), | 246 | ty_app!(TypeCtor::Adt(Adt::Struct(struct2)), st2), |
247 | ) if struct1 == struct2 => { | 247 | ) if struct1 == struct2 => { |
248 | let fields = struct1.fields(self.db); | 248 | let field_tys = self.db.field_types(struct1.id.into()); |
249 | let (last_field, prev_fields) = fields.split_last()?; | 249 | let struct_data = self.db.struct_data(struct1.id.0); |
250 | |||
251 | let mut fields = struct_data.variant_data.fields().iter(); | ||
252 | let (last_field_id, _data) = fields.next_back()?; | ||
250 | 253 | ||
251 | // Get the generic parameter involved in the last field. | 254 | // Get the generic parameter involved in the last field. |
252 | let unsize_generic_index = { | 255 | let unsize_generic_index = { |
253 | let mut index = None; | 256 | let mut index = None; |
254 | let mut multiple_param = false; | 257 | let mut multiple_param = false; |
255 | last_field.ty(self.db).walk(&mut |ty| match ty { | 258 | field_tys[last_field_id].walk(&mut |ty| match ty { |
256 | &Ty::Param { idx, .. } => { | 259 | &Ty::Param { idx, .. } => { |
257 | if index.is_none() { | 260 | if index.is_none() { |
258 | index = Some(idx); | 261 | index = Some(idx); |
@@ -271,8 +274,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
271 | 274 | ||
272 | // Check other fields do not involve it. | 275 | // Check other fields do not involve it. |
273 | let mut multiple_used = false; | 276 | let mut multiple_used = false; |
274 | prev_fields.iter().for_each(|field| { | 277 | fields.for_each(|(field_id, _data)| { |
275 | field.ty(self.db).walk(&mut |ty| match ty { | 278 | field_tys[field_id].walk(&mut |ty| match ty { |
276 | &Ty::Param { idx, .. } if idx == unsize_generic_index => { | 279 | &Ty::Param { idx, .. } if idx == unsize_generic_index => { |
277 | multiple_used = true | 280 | multiple_used = true |
278 | } | 281 | } |
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 20a7e9352..663ff9435 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs | |||
@@ -214,19 +214,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
214 | self.unify(&ty, &expected.ty); | 214 | self.unify(&ty, &expected.ty); |
215 | 215 | ||
216 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 216 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
217 | let field_types = | ||
218 | def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default(); | ||
217 | for (field_idx, field) in fields.iter().enumerate() { | 219 | for (field_idx, field) in fields.iter().enumerate() { |
218 | let field_ty = def_id | 220 | let field_def = def_id.and_then(|it| match it.field(self.db, &field.name) { |
219 | .and_then(|it| match it.field(self.db, &field.name) { | 221 | Some(field) => Some(field), |
220 | Some(field) => Some(field), | 222 | None => { |
221 | None => { | 223 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { |
222 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { | 224 | expr: tgt_expr, |
223 | expr: tgt_expr, | 225 | field: field_idx, |
224 | field: field_idx, | 226 | }); |
225 | }); | 227 | None |
226 | None | 228 | } |
227 | } | 229 | }); |
228 | }) | 230 | if let Some(field_def) = field_def { |
229 | .map_or(Ty::Unknown, |field| field.ty(self.db)) | 231 | self.result.record_field_resolutions.insert(field.expr, field_def); |
232 | } | ||
233 | let field_ty = field_def | ||
234 | .map_or(Ty::Unknown, |it| field_types[it.id].clone()) | ||
230 | .subst(&substs); | 235 | .subst(&substs); |
231 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); | 236 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
232 | } | 237 | } |
@@ -250,7 +255,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
250 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), | 255 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), |
251 | TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { | 256 | TypeCtor::Adt(Adt::Struct(s)) => s.field(self.db, name).map(|field| { |
252 | self.write_field_resolution(tgt_expr, field); | 257 | self.write_field_resolution(tgt_expr, field); |
253 | field.ty(self.db).subst(&a_ty.parameters) | 258 | self.db.field_types(s.id.into())[field.id] |
259 | .clone() | ||
260 | .subst(&a_ty.parameters) | ||
254 | }), | 261 | }), |
255 | _ => None, | 262 | _ => None, |
256 | }, | 263 | }, |
diff --git a/crates/ra_hir/src/ty/infer/pat.rs b/crates/ra_hir/src/ty/infer/pat.rs index c125ddfbc..641d61e87 100644 --- a/crates/ra_hir/src/ty/infer/pat.rs +++ b/crates/ra_hir/src/ty/infer/pat.rs | |||
@@ -27,10 +27,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
27 | 27 | ||
28 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 28 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
29 | 29 | ||
30 | let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); | ||
30 | for (i, &subpat) in subpats.iter().enumerate() { | 31 | for (i, &subpat) in subpats.iter().enumerate() { |
31 | let expected_ty = def | 32 | let expected_ty = def |
32 | .and_then(|d| d.field(self.db, &Name::new_tuple_field(i))) | 33 | .and_then(|d| d.field(self.db, &Name::new_tuple_field(i))) |
33 | .map_or(Ty::Unknown, |field| field.ty(self.db)) | 34 | .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) |
34 | .subst(&substs); | 35 | .subst(&substs); |
35 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 36 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
36 | self.infer_pat(subpat, &expected_ty, default_bm); | 37 | self.infer_pat(subpat, &expected_ty, default_bm); |
@@ -56,10 +57,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
56 | 57 | ||
57 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 58 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
58 | 59 | ||
60 | let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); | ||
59 | for subpat in subpats { | 61 | for subpat in subpats { |
60 | let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); | 62 | let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); |
61 | let expected_ty = | 63 | let expected_ty = matching_field |
62 | matching_field.map_or(Ty::Unknown, |field| field.ty(self.db)).subst(&substs); | 64 | .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) |
65 | .subst(&substs); | ||
63 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 66 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
64 | self.infer_pat(subpat.pat, &expected_ty, default_bm); | 67 | self.infer_pat(subpat.pat, &expected_ty, default_bm); |
65 | } | 68 | } |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 2272510e8..a39beb2a0 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -14,8 +14,9 @@ use hir_def::{ | |||
14 | path::{GenericArg, PathSegment}, | 14 | path::{GenericArg, PathSegment}, |
15 | resolver::{HasResolver, Resolver, TypeNs}, | 15 | resolver::{HasResolver, Resolver, TypeNs}, |
16 | type_ref::{TypeBound, TypeRef}, | 16 | type_ref::{TypeBound, TypeRef}, |
17 | AdtId, GenericDefId, | 17 | AdtId, GenericDefId, LocalStructFieldId, VariantId, |
18 | }; | 18 | }; |
19 | use ra_arena::map::ArenaMap; | ||
19 | 20 | ||
20 | use super::{ | 21 | use super::{ |
21 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 22 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, |
@@ -29,7 +30,7 @@ use crate::{ | |||
29 | }, | 30 | }, |
30 | util::make_mut_slice, | 31 | util::make_mut_slice, |
31 | Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, | 32 | Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, |
32 | StructField, Trait, TypeAlias, Union, VariantDef, | 33 | Trait, TypeAlias, Union, |
33 | }; | 34 | }; |
34 | 35 | ||
35 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of | 36 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of |
@@ -549,16 +550,23 @@ pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSi | |||
549 | } | 550 | } |
550 | } | 551 | } |
551 | 552 | ||
552 | /// Build the type of a specific field of a struct or enum variant. | 553 | /// Build the type of all specific fields of a struct or enum variant. |
553 | pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | 554 | pub(crate) fn field_types_query( |
554 | let parent_def = field.parent_def(db); | 555 | db: &impl HirDatabase, |
555 | let resolver = match parent_def { | 556 | variant_id: VariantId, |
556 | VariantDef::Struct(it) => it.id.resolver(db), | 557 | ) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { |
557 | VariantDef::EnumVariant(it) => it.parent.id.resolver(db), | 558 | let (resolver, var_data) = match variant_id { |
559 | VariantId::StructId(it) => (it.resolver(db), db.struct_data(it.0).variant_data.clone()), | ||
560 | VariantId::EnumVariantId(it) => ( | ||
561 | it.parent.resolver(db), | ||
562 | db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), | ||
563 | ), | ||
558 | }; | 564 | }; |
559 | let var_data = parent_def.variant_data(db); | 565 | let mut res = ArenaMap::default(); |
560 | let type_ref = &var_data.fields().unwrap()[field.id].type_ref; | 566 | for (field_id, field_data) in var_data.fields().iter() { |
561 | Ty::from_hir(db, &resolver, type_ref) | 567 | res.insert(field_id, Ty::from_hir(db, &resolver, &field_data.type_ref)) |
568 | } | ||
569 | Arc::new(res) | ||
562 | } | 570 | } |
563 | 571 | ||
564 | /// This query exists only to be used when resolving short-hand associated types | 572 | /// This query exists only to be used when resolving short-hand associated types |
@@ -696,10 +704,7 @@ impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> { | |||
696 | 704 | ||
697 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | 705 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { |
698 | let struct_data = db.struct_data(def.id.into()); | 706 | let struct_data = db.struct_data(def.id.into()); |
699 | let fields = match struct_data.variant_data.fields() { | 707 | let fields = struct_data.variant_data.fields(); |
700 | Some(fields) => fields, | ||
701 | None => panic!("fn_sig_for_struct_constructor called on unit struct"), | ||
702 | }; | ||
703 | let resolver = def.id.resolver(db); | 708 | let resolver = def.id.resolver(db); |
704 | let params = fields | 709 | let params = fields |
705 | .iter() | 710 | .iter() |
@@ -712,7 +717,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { | |||
712 | /// Build the type of a tuple struct constructor. | 717 | /// Build the type of a tuple struct constructor. |
713 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | 718 | fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { |
714 | let struct_data = db.struct_data(def.id.into()); | 719 | let struct_data = db.struct_data(def.id.into()); |
715 | if struct_data.variant_data.fields().is_none() { | 720 | if struct_data.variant_data.is_unit() { |
716 | return type_for_adt(db, def); // Unit struct | 721 | return type_for_adt(db, def); // Unit struct |
717 | } | 722 | } |
718 | let generics = db.generic_params(def.id.into()); | 723 | let generics = db.generic_params(def.id.into()); |
@@ -722,10 +727,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { | |||
722 | 727 | ||
723 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { | 728 | fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> FnSig { |
724 | let var_data = def.variant_data(db); | 729 | let var_data = def.variant_data(db); |
725 | let fields = match var_data.fields() { | 730 | let fields = var_data.fields(); |
726 | Some(fields) => fields, | ||
727 | None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), | ||
728 | }; | ||
729 | let resolver = def.parent.id.resolver(db); | 731 | let resolver = def.parent.id.resolver(db); |
730 | let params = fields | 732 | let params = fields |
731 | .iter() | 733 | .iter() |
@@ -740,7 +742,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) | |||
740 | /// Build the type of a tuple enum variant constructor. | 742 | /// Build the type of a tuple enum variant constructor. |
741 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { | 743 | fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> Ty { |
742 | let var_data = def.variant_data(db); | 744 | let var_data = def.variant_data(db); |
743 | if var_data.fields().is_none() { | 745 | if var_data.is_unit() { |
744 | return type_for_adt(db, def.parent_enum(db)); // Unit variant | 746 | return type_for_adt(db, def.parent_enum(db)); // Unit variant |
745 | } | 747 | } |
746 | let generics = db.generic_params(def.parent_enum(db).id.into()); | 748 | let generics = db.generic_params(def.parent_enum(db).id.into()); |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 9efdc53c4..1a93e5e50 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -19,7 +19,7 @@ use crate::{ | |||
19 | db::HirDatabase, | 19 | db::HirDatabase, |
20 | ty::display::HirDisplay, | 20 | ty::display::HirDisplay, |
21 | ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, | 21 | ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, |
22 | Crate, GenericDef, HasBody, ImplBlock, Trait, TypeAlias, | 22 | Crate, GenericDef, ImplBlock, Trait, TypeAlias, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | /// This represents a trait whose name we could not resolve. | 25 | /// This represents a trait whose name we could not resolve. |
@@ -715,7 +715,7 @@ fn closure_fn_trait_impl_datum( | |||
715 | let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; | 715 | let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; |
716 | fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?; | 716 | fn_once_trait.associated_type_by_name(db, &name::OUTPUT_TYPE)?; |
717 | 717 | ||
718 | let num_args: u16 = match &data.def.body(db)[data.expr] { | 718 | let num_args: u16 = match &db.body(data.def.into())[data.expr] { |
719 | crate::expr::Expr::Lambda { args, .. } => args.len() as u16, | 719 | crate::expr::Expr::Lambda { args, .. } => args.len() as u16, |
720 | _ => { | 720 | _ => { |
721 | log::warn!("closure for closure type {:?} not found", data); | 721 | log::warn!("closure for closure type {:?} not found", data); |
@@ -805,7 +805,7 @@ fn closure_fn_trait_output_assoc_ty_value( | |||
805 | ) -> Arc<AssociatedTyValue<ChalkIr>> { | 805 | ) -> Arc<AssociatedTyValue<ChalkIr>> { |
806 | let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db); | 806 | let impl_id = Impl::ClosureFnTraitImpl(data.clone()).to_chalk(db); |
807 | 807 | ||
808 | let num_args: u16 = match &data.def.body(db)[data.expr] { | 808 | let num_args: u16 = match &db.body(data.def.into())[data.expr] { |
809 | crate::expr::Expr::Lambda { args, .. } => args.len() as u16, | 809 | crate::expr::Expr::Lambda { args, .. } => args.len() as u16, |
810 | _ => { | 810 | _ => { |
811 | log::warn!("closure for closure type {:?} not found", data); | 811 | log::warn!("closure for closure type {:?} not found", data); |
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 20e9a1eb5..c9f30923e 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -95,7 +95,7 @@ fn lower_enum( | |||
95 | name: var.name().map(|it| it.as_name()), | 95 | name: var.name().map(|it| it.as_name()), |
96 | variant_data: Arc::new(VariantData::new(var.kind())), | 96 | variant_data: Arc::new(VariantData::new(var.kind())), |
97 | }, | 97 | }, |
98 | ) | 98 | ); |
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
@@ -109,10 +109,18 @@ impl VariantData { | |||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | pub fn fields(&self) -> Option<&Arena<LocalStructFieldId, StructFieldData>> { | 112 | pub fn fields(&self) -> &Arena<LocalStructFieldId, StructFieldData> { |
113 | const EMPTY: &Arena<LocalStructFieldId, StructFieldData> = &Arena::new(); | ||
113 | match &self { | 114 | match &self { |
114 | VariantData::Record(fields) | VariantData::Tuple(fields) => Some(fields), | 115 | VariantData::Record(fields) | VariantData::Tuple(fields) => fields, |
115 | _ => None, | 116 | _ => EMPTY, |
117 | } | ||
118 | } | ||
119 | |||
120 | pub fn is_unit(&self) -> bool { | ||
121 | match self { | ||
122 | VariantData::Unit => true, | ||
123 | _ => false, | ||
116 | } | 124 | } |
117 | } | 125 | } |
118 | } | 126 | } |
@@ -160,7 +168,7 @@ fn lower_struct( | |||
160 | name: Name::new_tuple_field(i), | 168 | name: Name::new_tuple_field(i), |
161 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), | 169 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), |
162 | }, | 170 | }, |
163 | ) | 171 | ); |
164 | } | 172 | } |
165 | StructKind::Tuple | 173 | StructKind::Tuple |
166 | } | 174 | } |
@@ -172,7 +180,7 @@ fn lower_struct( | |||
172 | name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), | 180 | name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), |
173 | type_ref: TypeRef::from_ast_opt(fd.ascribed_type()), | 181 | type_ref: TypeRef::from_ast_opt(fd.ascribed_type()), |
174 | }, | 182 | }, |
175 | ) | 183 | ); |
176 | } | 184 | } |
177 | StructKind::Record | 185 | StructKind::Record |
178 | } | 186 | } |
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index c06997cf1..d77ccb272 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! Defines `Body`: a lowered representation of bodies of functions, statics and |
2 | //! consts. | ||
2 | mod lower; | 3 | mod lower; |
3 | pub mod scope; | 4 | pub mod scope; |
4 | 5 | ||
@@ -20,7 +21,7 @@ use crate::{ | |||
20 | DefWithBodyId, HasModule, HasSource, Lookup, ModuleId, | 21 | DefWithBodyId, HasModule, HasSource, Lookup, ModuleId, |
21 | }; | 22 | }; |
22 | 23 | ||
23 | pub struct Expander { | 24 | struct Expander { |
24 | crate_def_map: Arc<CrateDefMap>, | 25 | crate_def_map: Arc<CrateDefMap>, |
25 | current_file_id: HirFileId, | 26 | current_file_id: HirFileId, |
26 | hygiene: Hygiene, | 27 | hygiene: Hygiene, |
@@ -28,7 +29,7 @@ pub struct Expander { | |||
28 | } | 29 | } |
29 | 30 | ||
30 | impl Expander { | 31 | impl Expander { |
31 | pub fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { | 32 | fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { |
32 | let crate_def_map = db.crate_def_map(module.krate); | 33 | let crate_def_map = db.crate_def_map(module.krate); |
33 | let hygiene = Hygiene::new(db, current_file_id); | 34 | let hygiene = Hygiene::new(db, current_file_id); |
34 | Expander { crate_def_map, current_file_id, hygiene, module } | 35 | Expander { crate_def_map, current_file_id, hygiene, module } |
@@ -101,17 +102,17 @@ impl Drop for Mark { | |||
101 | /// The body of an item (function, const etc.). | 102 | /// The body of an item (function, const etc.). |
102 | #[derive(Debug, Eq, PartialEq)] | 103 | #[derive(Debug, Eq, PartialEq)] |
103 | pub struct Body { | 104 | pub struct Body { |
104 | exprs: Arena<ExprId, Expr>, | 105 | pub exprs: Arena<ExprId, Expr>, |
105 | pats: Arena<PatId, Pat>, | 106 | pub pats: Arena<PatId, Pat>, |
106 | /// The patterns for the function's parameters. While the parameter types are | 107 | /// The patterns for the function's parameters. While the parameter types are |
107 | /// part of the function signature, the patterns are not (they don't change | 108 | /// part of the function signature, the patterns are not (they don't change |
108 | /// the external type of the function). | 109 | /// the external type of the function). |
109 | /// | 110 | /// |
110 | /// If this `Body` is for the body of a constant, this will just be | 111 | /// If this `Body` is for the body of a constant, this will just be |
111 | /// empty. | 112 | /// empty. |
112 | params: Vec<PatId>, | 113 | pub params: Vec<PatId>, |
113 | /// The `ExprId` of the actual body expression. | 114 | /// The `ExprId` of the actual body expression. |
114 | body_expr: ExprId, | 115 | pub body_expr: ExprId, |
115 | } | 116 | } |
116 | 117 | ||
117 | pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; | 118 | pub type ExprPtr = Either<AstPtr<ast::Expr>, AstPtr<ast::RecordField>>; |
@@ -182,22 +183,6 @@ impl Body { | |||
182 | ) -> (Body, BodySourceMap) { | 183 | ) -> (Body, BodySourceMap) { |
183 | lower::lower(db, expander, params, body) | 184 | lower::lower(db, expander, params, body) |
184 | } | 185 | } |
185 | |||
186 | pub fn params(&self) -> &[PatId] { | ||
187 | &self.params | ||
188 | } | ||
189 | |||
190 | pub fn body_expr(&self) -> ExprId { | ||
191 | self.body_expr | ||
192 | } | ||
193 | |||
194 | pub fn exprs(&self) -> impl Iterator<Item = (ExprId, &Expr)> { | ||
195 | self.exprs.iter() | ||
196 | } | ||
197 | |||
198 | pub fn pats(&self) -> impl Iterator<Item = (PatId, &Pat)> { | ||
199 | self.pats.iter() | ||
200 | } | ||
201 | } | 186 | } |
202 | 187 | ||
203 | impl Index<ExprId> for Body { | 188 | impl Index<ExprId> for Body { |
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f4640dfa4..331736cb2 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -1,4 +1,5 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` |
2 | //! representation. | ||
2 | 3 | ||
3 | use hir_expand::{ | 4 | use hir_expand::{ |
4 | either::Either, | 5 | either::Either, |
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index 20d707bc4..625aa39dd 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! Name resolution for expressions. |
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use hir_expand::name::Name; | 4 | use hir_expand::name::Name; |
@@ -54,8 +54,8 @@ impl ExprScopes { | |||
54 | let mut scopes = | 54 | let mut scopes = |
55 | ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() }; | 55 | ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() }; |
56 | let root = scopes.root_scope(); | 56 | let root = scopes.root_scope(); |
57 | scopes.add_params_bindings(body, root, body.params()); | 57 | scopes.add_params_bindings(body, root, &body.params); |
58 | compute_expr_scopes(body.body_expr(), body, &mut scopes, root); | 58 | compute_expr_scopes(body.body_expr, body, &mut scopes, root); |
59 | scopes | 59 | scopes |
60 | } | 60 | } |
61 | 61 | ||
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs index 3b9fb0328..f15c23db9 100644 --- a/crates/ra_hir_def/src/lang_item.rs +++ b/crates/ra_hir_def/src/lang_item.rs | |||
@@ -39,8 +39,9 @@ impl LangItems { | |||
39 | let crate_def_map = db.crate_def_map(krate); | 39 | let crate_def_map = db.crate_def_map(krate); |
40 | 40 | ||
41 | crate_def_map | 41 | crate_def_map |
42 | .modules() | 42 | .modules |
43 | .filter_map(|module_id| db.module_lang_items(ModuleId { krate, module_id })) | 43 | .iter() |
44 | .filter_map(|(module_id, _)| db.module_lang_items(ModuleId { krate, module_id })) | ||
44 | .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v)))); | 45 | .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v)))); |
45 | 46 | ||
46 | Arc::new(lang_items) | 47 | Arc::new(lang_items) |
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index f63c3dd64..8e8c2d749 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -192,12 +192,6 @@ pub struct LocalEnumVariantId(RawId); | |||
192 | impl_arena_id!(LocalEnumVariantId); | 192 | impl_arena_id!(LocalEnumVariantId); |
193 | 193 | ||
194 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 194 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
195 | pub enum VariantId { | ||
196 | EnumVariantId(EnumVariantId), | ||
197 | StructId(StructId), | ||
198 | } | ||
199 | |||
200 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
201 | pub struct StructFieldId { | 195 | pub struct StructFieldId { |
202 | pub parent: VariantId, | 196 | pub parent: VariantId, |
203 | pub local_id: LocalStructFieldId, | 197 | pub local_id: LocalStructFieldId, |
@@ -437,6 +431,13 @@ impl_froms!( | |||
437 | ImplId | 431 | ImplId |
438 | ); | 432 | ); |
439 | 433 | ||
434 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
435 | pub enum VariantId { | ||
436 | EnumVariantId(EnumVariantId), | ||
437 | StructId(StructId), | ||
438 | } | ||
439 | impl_froms!(VariantId: EnumVariantId, StructId); | ||
440 | |||
440 | trait Intern { | 441 | trait Intern { |
441 | type ID; | 442 | type ID; |
442 | fn intern(self, db: &impl db::DefDatabase) -> Self::ID; | 443 | fn intern(self, db: &impl db::DefDatabase) -> Self::ID; |
@@ -481,6 +482,16 @@ impl HasModule for ConstLoc { | |||
481 | } | 482 | } |
482 | } | 483 | } |
483 | 484 | ||
485 | impl HasModule for AdtId { | ||
486 | fn module(&self, db: &impl db::DefDatabase) -> ModuleId { | ||
487 | match self { | ||
488 | AdtId::StructId(it) => it.0.module(db), | ||
489 | AdtId::UnionId(it) => it.0.module(db), | ||
490 | AdtId::EnumId(it) => it.module(db), | ||
491 | } | ||
492 | } | ||
493 | } | ||
494 | |||
484 | impl HasModule for StaticLoc { | 495 | impl HasModule for StaticLoc { |
485 | fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { | 496 | fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { |
486 | self.container | 497 | self.container |
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 5919771b0..2359386c2 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -80,16 +80,16 @@ use crate::{ | |||
80 | /// Contains all top-level defs from a macro-expanded crate | 80 | /// Contains all top-level defs from a macro-expanded crate |
81 | #[derive(Debug, PartialEq, Eq)] | 81 | #[derive(Debug, PartialEq, Eq)] |
82 | pub struct CrateDefMap { | 82 | pub struct CrateDefMap { |
83 | krate: CrateId, | 83 | pub root: LocalModuleId, |
84 | edition: Edition, | 84 | pub modules: Arena<LocalModuleId, ModuleData>, |
85 | pub(crate) krate: CrateId, | ||
85 | /// The prelude module for this crate. This either comes from an import | 86 | /// The prelude module for this crate. This either comes from an import |
86 | /// marked with the `prelude_import` attribute, or (in the normal case) from | 87 | /// marked with the `prelude_import` attribute, or (in the normal case) from |
87 | /// a dependency (`std` or `core`). | 88 | /// a dependency (`std` or `core`). |
88 | prelude: Option<ModuleId>, | 89 | pub(crate) prelude: Option<ModuleId>, |
89 | extern_prelude: FxHashMap<Name, ModuleDefId>, | 90 | pub(crate) extern_prelude: FxHashMap<Name, ModuleDefId>, |
90 | root: LocalModuleId, | ||
91 | modules: Arena<LocalModuleId, ModuleData>, | ||
92 | 91 | ||
92 | edition: Edition, | ||
93 | diagnostics: Vec<DefDiagnostic>, | 93 | diagnostics: Vec<DefDiagnostic>, |
94 | } | 94 | } |
95 | 95 | ||
@@ -229,22 +229,6 @@ impl CrateDefMap { | |||
229 | Arc::new(def_map) | 229 | Arc::new(def_map) |
230 | } | 230 | } |
231 | 231 | ||
232 | pub fn krate(&self) -> CrateId { | ||
233 | self.krate | ||
234 | } | ||
235 | |||
236 | pub fn root(&self) -> LocalModuleId { | ||
237 | self.root | ||
238 | } | ||
239 | |||
240 | pub fn prelude(&self) -> Option<ModuleId> { | ||
241 | self.prelude | ||
242 | } | ||
243 | |||
244 | pub fn extern_prelude(&self) -> &FxHashMap<Name, ModuleDefId> { | ||
245 | &self.extern_prelude | ||
246 | } | ||
247 | |||
248 | pub fn add_diagnostics( | 232 | pub fn add_diagnostics( |
249 | &self, | 233 | &self, |
250 | db: &impl DefDatabase, | 234 | db: &impl DefDatabase, |
@@ -254,10 +238,6 @@ impl CrateDefMap { | |||
254 | self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) | 238 | self.diagnostics.iter().for_each(|it| it.add_to(db, module, sink)) |
255 | } | 239 | } |
256 | 240 | ||
257 | pub fn modules(&self) -> impl Iterator<Item = LocalModuleId> + '_ { | ||
258 | self.modules.iter().map(|(id, _data)| id) | ||
259 | } | ||
260 | |||
261 | pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = LocalModuleId> + '_ { | 241 | pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator<Item = LocalModuleId> + '_ { |
262 | self.modules | 242 | self.modules |
263 | .iter() | 243 | .iter() |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index df01a20e1..41becf8df 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -1,4 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! The core of the module-level name resolution algorithm. |
2 | //! | ||
3 | //! `DefCollector::collect` contains the fixed-point iteration loop which | ||
4 | //! resolves imports and expands macros. | ||
2 | 5 | ||
3 | use hir_expand::{ | 6 | use hir_expand::{ |
4 | builtin_macro::find_builtin_macro, | 7 | builtin_macro::find_builtin_macro, |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 2ec84f2cc..401af031c 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -22,7 +22,8 @@ use ra_syntax::{ | |||
22 | use test_utils::tested_by; | 22 | use test_utils::tested_by; |
23 | 23 | ||
24 | use crate::{ | 24 | use crate::{ |
25 | attr::Attrs, db::DefDatabase, path::Path, FileAstId, HirFileId, LocalImportId, Source, | 25 | attr::Attrs, db::DefDatabase, path::Path, trace::Trace, FileAstId, HirFileId, LocalImportId, |
26 | Source, | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | /// `RawItems` is a set of top-level items in a file (except for impls). | 29 | /// `RawItems` is a set of top-level items in a file (except for impls). |
@@ -48,10 +49,6 @@ pub struct ImportSourceMap { | |||
48 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; | 49 | type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>; |
49 | 50 | ||
50 | impl ImportSourceMap { | 51 | impl ImportSourceMap { |
51 | fn insert(&mut self, import: LocalImportId, ptr: ImportSourcePtr) { | ||
52 | self.map.insert(import, ptr) | ||
53 | } | ||
54 | |||
55 | pub fn get(&self, import: LocalImportId) -> ImportSourcePtr { | 52 | pub fn get(&self, import: LocalImportId) -> ImportSourcePtr { |
56 | self.map[import].clone() | 53 | self.map[import].clone() |
57 | } | 54 | } |
@@ -72,7 +69,7 @@ impl RawItems { | |||
72 | let mut collector = RawItemsCollector { | 69 | let mut collector = RawItemsCollector { |
73 | raw_items: RawItems::default(), | 70 | raw_items: RawItems::default(), |
74 | source_ast_id_map: db.ast_id_map(file_id), | 71 | source_ast_id_map: db.ast_id_map(file_id), |
75 | source_map: ImportSourceMap::default(), | 72 | imports: Trace::new(), |
76 | file_id, | 73 | file_id, |
77 | hygiene: Hygiene::new(db, file_id), | 74 | hygiene: Hygiene::new(db, file_id), |
78 | }; | 75 | }; |
@@ -83,7 +80,11 @@ impl RawItems { | |||
83 | collector.process_module(None, item_list); | 80 | collector.process_module(None, item_list); |
84 | } | 81 | } |
85 | } | 82 | } |
86 | (Arc::new(collector.raw_items), Arc::new(collector.source_map)) | 83 | let mut raw_items = collector.raw_items; |
84 | let (arena, map) = collector.imports.into_arena_and_map(); | ||
85 | raw_items.imports = arena; | ||
86 | let source_map = ImportSourceMap { map }; | ||
87 | (Arc::new(raw_items), Arc::new(source_map)) | ||
87 | } | 88 | } |
88 | 89 | ||
89 | pub(super) fn items(&self) -> &[RawItem] { | 90 | pub(super) fn items(&self) -> &[RawItem] { |
@@ -207,8 +208,8 @@ pub(super) struct ImplData { | |||
207 | 208 | ||
208 | struct RawItemsCollector { | 209 | struct RawItemsCollector { |
209 | raw_items: RawItems, | 210 | raw_items: RawItems, |
211 | imports: Trace<LocalImportId, ImportData, ImportSourcePtr>, | ||
210 | source_ast_id_map: Arc<AstIdMap>, | 212 | source_ast_id_map: Arc<AstIdMap>, |
211 | source_map: ImportSourceMap, | ||
212 | file_id: HirFileId, | 213 | file_id: HirFileId, |
213 | hygiene: Hygiene, | 214 | hygiene: Hygiene, |
214 | } | 215 | } |
@@ -392,8 +393,7 @@ impl RawItemsCollector { | |||
392 | data: ImportData, | 393 | data: ImportData, |
393 | source: ImportSourcePtr, | 394 | source: ImportSourcePtr, |
394 | ) { | 395 | ) { |
395 | let import = self.raw_items.imports.alloc(data); | 396 | let import = self.imports.alloc(|| source, || data); |
396 | self.source_map.insert(import, source); | ||
397 | self.push_item(current_module, attrs, RawItemKind::Import(import)) | 397 | self.push_item(current_module, attrs, RawItemKind::Import(import)) |
398 | } | 398 | } |
399 | 399 | ||
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index f0b86af7c..f502f1cb3 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs | |||
@@ -25,7 +25,7 @@ fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> { | |||
25 | 25 | ||
26 | fn render_crate_def_map(map: &CrateDefMap) -> String { | 26 | fn render_crate_def_map(map: &CrateDefMap) -> String { |
27 | let mut buf = String::new(); | 27 | let mut buf = String::new(); |
28 | go(&mut buf, map, "\ncrate", map.root()); | 28 | go(&mut buf, map, "\ncrate", map.root); |
29 | return buf.trim().to_string(); | 29 | return buf.trim().to_string(); |
30 | 30 | ||
31 | fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: LocalModuleId) { | 31 | fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: LocalModuleId) { |
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 7b2723d57..0e606fd0e 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs | |||
@@ -195,7 +195,7 @@ impl Path { | |||
195 | } | 195 | } |
196 | 196 | ||
197 | /// Converts an `ast::NameRef` into a single-identifier `Path`. | 197 | /// Converts an `ast::NameRef` into a single-identifier `Path`. |
198 | pub fn from_name_ref(name_ref: &ast::NameRef) -> Path { | 198 | pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path { |
199 | name_ref.as_name().into() | 199 | name_ref.as_name().into() |
200 | } | 200 | } |
201 | 201 | ||
diff --git a/crates/ra_hir_def/src/per_ns.rs b/crates/ra_hir_def/src/per_ns.rs index 06ef6c9fc..00e866bf9 100644 --- a/crates/ra_hir_def/src/per_ns.rs +++ b/crates/ra_hir_def/src/per_ns.rs | |||
@@ -1,4 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! In rust, it is possible to have a value, a type and a macro with the same |
2 | //! name without conflicts. | ||
3 | //! | ||
4 | //! `PerNs` (per namespace) captures this. | ||
2 | 5 | ||
3 | use hir_expand::MacroDefId; | 6 | use hir_expand::MacroDefId; |
4 | 7 | ||
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 7182b8a4d..95b3c926d 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs | |||
@@ -18,8 +18,8 @@ use crate::{ | |||
18 | path::{Path, PathKind}, | 18 | path::{Path, PathKind}, |
19 | per_ns::PerNs, | 19 | per_ns::PerNs, |
20 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, | 20 | AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, |
21 | GenericDefId, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, | 21 | GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, |
22 | TraitId, TypeAliasId, | 22 | StructId, TraitId, TypeAliasId, |
23 | }; | 23 | }; |
24 | 24 | ||
25 | #[derive(Debug, Clone, Default)] | 25 | #[derive(Debug, Clone, Default)] |
@@ -29,20 +29,20 @@ pub struct Resolver { | |||
29 | 29 | ||
30 | // FIXME how to store these best | 30 | // FIXME how to store these best |
31 | #[derive(Debug, Clone)] | 31 | #[derive(Debug, Clone)] |
32 | pub(crate) struct ModuleItemMap { | 32 | struct ModuleItemMap { |
33 | crate_def_map: Arc<CrateDefMap>, | 33 | crate_def_map: Arc<CrateDefMap>, |
34 | module_id: LocalModuleId, | 34 | module_id: LocalModuleId, |
35 | } | 35 | } |
36 | 36 | ||
37 | #[derive(Debug, Clone)] | 37 | #[derive(Debug, Clone)] |
38 | pub(crate) struct ExprScope { | 38 | struct ExprScope { |
39 | owner: DefWithBodyId, | 39 | owner: DefWithBodyId, |
40 | expr_scopes: Arc<ExprScopes>, | 40 | expr_scopes: Arc<ExprScopes>, |
41 | scope_id: ScopeId, | 41 | scope_id: ScopeId, |
42 | } | 42 | } |
43 | 43 | ||
44 | #[derive(Debug, Clone)] | 44 | #[derive(Debug, Clone)] |
45 | pub(crate) enum Scope { | 45 | enum Scope { |
46 | /// All the items and imported names of a module | 46 | /// All the items and imported names of a module |
47 | ModuleScope(ModuleItemMap), | 47 | ModuleScope(ModuleItemMap), |
48 | /// Brings the generic parameters of an item into scope | 48 | /// Brings the generic parameters of an item into scope |
@@ -321,7 +321,7 @@ impl Resolver { | |||
321 | let mut traits = FxHashSet::default(); | 321 | let mut traits = FxHashSet::default(); |
322 | for scope in &self.scopes { | 322 | for scope in &self.scopes { |
323 | if let Scope::ModuleScope(m) = scope { | 323 | if let Scope::ModuleScope(m) = scope { |
324 | if let Some(prelude) = m.crate_def_map.prelude() { | 324 | if let Some(prelude) = m.crate_def_map.prelude { |
325 | let prelude_def_map = db.crate_def_map(prelude.krate); | 325 | let prelude_def_map = db.crate_def_map(prelude.krate); |
326 | traits.extend(prelude_def_map[prelude.module_id].scope.traits()); | 326 | traits.extend(prelude_def_map[prelude.module_id].scope.traits()); |
327 | } | 327 | } |
@@ -340,7 +340,7 @@ impl Resolver { | |||
340 | } | 340 | } |
341 | 341 | ||
342 | pub fn krate(&self) -> Option<CrateId> { | 342 | pub fn krate(&self) -> Option<CrateId> { |
343 | self.module().map(|t| t.0.krate()) | 343 | self.module().map(|t| t.0.krate) |
344 | } | 344 | } |
345 | 345 | ||
346 | pub fn where_predicates_in_scope<'a>( | 346 | pub fn where_predicates_in_scope<'a>( |
@@ -395,10 +395,10 @@ impl Scope { | |||
395 | m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { | 395 | m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { |
396 | f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); | 396 | f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); |
397 | }); | 397 | }); |
398 | m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| { | 398 | m.crate_def_map.extern_prelude.iter().for_each(|(name, &def)| { |
399 | f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into()))); | 399 | f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into()))); |
400 | }); | 400 | }); |
401 | if let Some(prelude) = m.crate_def_map.prelude() { | 401 | if let Some(prelude) = m.crate_def_map.prelude { |
402 | let prelude_def_map = db.crate_def_map(prelude.krate); | 402 | let prelude_def_map = db.crate_def_map(prelude.krate); |
403 | prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { | 403 | prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { |
404 | f(name.clone(), ScopeDef::PerNs(res.def)); | 404 | f(name.clone(), ScopeDef::PerNs(res.def)); |
@@ -503,13 +503,7 @@ impl HasResolver for TraitId { | |||
503 | impl<T: Into<AdtId>> HasResolver for T { | 503 | impl<T: Into<AdtId>> HasResolver for T { |
504 | fn resolver(self, db: &impl DefDatabase) -> Resolver { | 504 | fn resolver(self, db: &impl DefDatabase) -> Resolver { |
505 | let def = self.into(); | 505 | let def = self.into(); |
506 | let module = match def { | 506 | def.module(db) |
507 | AdtId::StructId(it) => it.0.module(db), | ||
508 | AdtId::UnionId(it) => it.0.module(db), | ||
509 | AdtId::EnumId(it) => it.module(db), | ||
510 | }; | ||
511 | |||
512 | module | ||
513 | .resolver(db) | 507 | .resolver(db) |
514 | .push_generic_params_scope(db, def.into()) | 508 | .push_generic_params_scope(db, def.into()) |
515 | .push_scope(Scope::AdtScope(def)) | 509 | .push_scope(Scope::AdtScope(def)) |
diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs index fc26f5a48..2bcd707bc 100644 --- a/crates/ra_hir_def/src/trace.rs +++ b/crates/ra_hir_def/src/trace.rs | |||
@@ -12,38 +12,48 @@ | |||
12 | use ra_arena::{map::ArenaMap, Arena, ArenaId, RawId}; | 12 | use ra_arena::{map::ArenaMap, Arena, ArenaId, RawId}; |
13 | 13 | ||
14 | pub(crate) struct Trace<ID: ArenaId, T, V> { | 14 | pub(crate) struct Trace<ID: ArenaId, T, V> { |
15 | for_arena: bool, | 15 | arena: Option<Arena<ID, T>>, |
16 | arena: Arena<ID, T>, | 16 | map: Option<ArenaMap<ID, V>>, |
17 | map: ArenaMap<ID, V>, | ||
18 | len: u32, | 17 | len: u32, |
19 | } | 18 | } |
20 | 19 | ||
21 | impl<ID: ra_arena::ArenaId, T, V> Trace<ID, T, V> { | 20 | impl<ID: ra_arena::ArenaId + Copy, T, V> Trace<ID, T, V> { |
21 | pub(crate) fn new() -> Trace<ID, T, V> { | ||
22 | Trace { arena: Some(Arena::default()), map: Some(ArenaMap::default()), len: 0 } | ||
23 | } | ||
24 | |||
22 | pub(crate) fn new_for_arena() -> Trace<ID, T, V> { | 25 | pub(crate) fn new_for_arena() -> Trace<ID, T, V> { |
23 | Trace { for_arena: true, arena: Arena::default(), map: ArenaMap::default(), len: 0 } | 26 | Trace { arena: Some(Arena::default()), map: None, len: 0 } |
24 | } | 27 | } |
25 | 28 | ||
26 | pub(crate) fn new_for_map() -> Trace<ID, T, V> { | 29 | pub(crate) fn new_for_map() -> Trace<ID, T, V> { |
27 | Trace { for_arena: false, arena: Arena::default(), map: ArenaMap::default(), len: 0 } | 30 | Trace { arena: None, map: Some(ArenaMap::default()), len: 0 } |
28 | } | 31 | } |
29 | 32 | ||
30 | pub(crate) fn alloc(&mut self, value: impl Fn() -> V, data: impl Fn() -> T) { | 33 | pub(crate) fn alloc(&mut self, value: impl FnOnce() -> V, data: impl FnOnce() -> T) -> ID { |
31 | if self.for_arena { | 34 | let id = if let Some(arena) = &mut self.arena { |
32 | self.arena.alloc(data()); | 35 | arena.alloc(data()) |
33 | } else { | 36 | } else { |
34 | let id = ID::from_raw(RawId::from(self.len)); | 37 | let id = ID::from_raw(RawId::from(self.len)); |
35 | self.len += 1; | 38 | self.len += 1; |
36 | self.map.insert(id, value()); | 39 | id |
40 | }; | ||
41 | |||
42 | if let Some(map) = &mut self.map { | ||
43 | map.insert(id, value()); | ||
37 | } | 44 | } |
45 | id | ||
46 | } | ||
47 | |||
48 | pub(crate) fn into_arena(mut self) -> Arena<ID, T> { | ||
49 | self.arena.take().unwrap() | ||
38 | } | 50 | } |
39 | 51 | ||
40 | pub(crate) fn into_arena(self) -> Arena<ID, T> { | 52 | pub(crate) fn into_map(mut self) -> ArenaMap<ID, V> { |
41 | assert!(self.for_arena); | 53 | self.map.take().unwrap() |
42 | self.arena | ||
43 | } | 54 | } |
44 | 55 | ||
45 | pub(crate) fn into_map(self) -> ArenaMap<ID, V> { | 56 | pub(crate) fn into_arena_and_map(mut self) -> (Arena<ID, T>, ArenaMap<ID, V>) { |
46 | assert!(!self.for_arena); | 57 | (self.arena.take().unwrap(), self.map.take().unwrap()) |
47 | self.map | ||
48 | } | 58 | } |
49 | } | 59 | } |
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 8a05b287f..0f692460d 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs | |||
@@ -324,7 +324,7 @@ impl RootDatabase { | |||
324 | hir::db::ExprScopesQuery | 324 | hir::db::ExprScopesQuery |
325 | hir::db::InferQuery | 325 | hir::db::InferQuery |
326 | hir::db::TypeForDefQuery | 326 | hir::db::TypeForDefQuery |
327 | hir::db::TypeForFieldQuery | 327 | hir::db::FieldTypesQuery |
328 | hir::db::CallableItemSignatureQuery | 328 | hir::db::CallableItemSignatureQuery |
329 | hir::db::GenericPredicatesQuery | 329 | hir::db::GenericPredicatesQuery |
330 | hir::db::GenericDefaultsQuery | 330 | hir::db::GenericDefaultsQuery |
diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs index 4a4b030f8..cab06dea9 100644 --- a/crates/ra_ide_api/src/references/classify.rs +++ b/crates/ra_ide_api/src/references/classify.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! Functions that are used to classify an element from its definition or reference. | 1 | //! Functions that are used to classify an element from its definition or reference. |
2 | 2 | ||
3 | use hir::{FromSource, Module, ModuleSource, Path, PathResolution, Source, SourceAnalyzer}; | 3 | use hir::{FromSource, Module, ModuleSource, PathResolution, Source, SourceAnalyzer}; |
4 | use ra_prof::profile; | 4 | use ra_prof::profile; |
5 | use ra_syntax::{ast, match_ast, AstNode}; | 5 | use ra_syntax::{ast, match_ast, AstNode}; |
6 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
@@ -140,12 +140,8 @@ pub(crate) fn classify_name_ref( | |||
140 | 140 | ||
141 | if let Some(record_field) = ast::RecordField::cast(parent.clone()) { | 141 | if let Some(record_field) = ast::RecordField::cast(parent.clone()) { |
142 | tested_by!(goto_definition_works_for_record_fields); | 142 | tested_by!(goto_definition_works_for_record_fields); |
143 | if let Some(record_lit) = record_field.syntax().ancestors().find_map(ast::RecordLit::cast) { | 143 | if let Some(field_def) = analyzer.resolve_record_field(&record_field) { |
144 | let variant_def = analyzer.resolve_record_literal(&record_lit)?; | 144 | return Some(from_struct_field(db, field_def)); |
145 | let hir_path = Path::from_name_ref(name_ref.value); | ||
146 | let hir_name = hir_path.as_ident()?; | ||
147 | let field = variant_def.field(db, hir_name)?; | ||
148 | return Some(from_struct_field(db, field)); | ||
149 | } | 145 | } |
150 | } | 146 | } |
151 | 147 | ||
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index c128e608d..351997dcd 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs | |||
@@ -54,11 +54,13 @@ struct TargetData { | |||
54 | name: String, | 54 | name: String, |
55 | root: PathBuf, | 55 | root: PathBuf, |
56 | kind: TargetKind, | 56 | kind: TargetKind, |
57 | is_proc_macro: bool, | ||
57 | } | 58 | } |
58 | 59 | ||
59 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 60 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
60 | pub enum TargetKind { | 61 | pub enum TargetKind { |
61 | Bin, | 62 | Bin, |
63 | /// Any kind of Cargo lib crate-type (dylib, rlib, proc-macro, ...). | ||
62 | Lib, | 64 | Lib, |
63 | Example, | 65 | Example, |
64 | Test, | 66 | Test, |
@@ -74,6 +76,7 @@ impl TargetKind { | |||
74 | "test" => TargetKind::Test, | 76 | "test" => TargetKind::Test, |
75 | "bench" => TargetKind::Bench, | 77 | "bench" => TargetKind::Bench, |
76 | "example" => TargetKind::Example, | 78 | "example" => TargetKind::Example, |
79 | "proc-macro" => TargetKind::Lib, | ||
77 | _ if kind.contains("lib") => TargetKind::Lib, | 80 | _ if kind.contains("lib") => TargetKind::Lib, |
78 | _ => continue, | 81 | _ => continue, |
79 | }; | 82 | }; |
@@ -123,6 +126,9 @@ impl Target { | |||
123 | pub fn kind(self, ws: &CargoWorkspace) -> TargetKind { | 126 | pub fn kind(self, ws: &CargoWorkspace) -> TargetKind { |
124 | ws.targets[self].kind | 127 | ws.targets[self].kind |
125 | } | 128 | } |
129 | pub fn is_proc_macro(self, ws: &CargoWorkspace) -> bool { | ||
130 | ws.targets[self].is_proc_macro | ||
131 | } | ||
126 | } | 132 | } |
127 | 133 | ||
128 | impl CargoWorkspace { | 134 | impl CargoWorkspace { |
@@ -155,11 +161,13 @@ impl CargoWorkspace { | |||
155 | let pkg_data = &mut packages[pkg]; | 161 | let pkg_data = &mut packages[pkg]; |
156 | pkg_by_id.insert(id, pkg); | 162 | pkg_by_id.insert(id, pkg); |
157 | for meta_tgt in meta_pkg.targets { | 163 | for meta_tgt in meta_pkg.targets { |
164 | let is_proc_macro = meta_tgt.kind.as_slice() == &["proc-macro"]; | ||
158 | let tgt = targets.alloc(TargetData { | 165 | let tgt = targets.alloc(TargetData { |
159 | pkg, | 166 | pkg, |
160 | name: meta_tgt.name, | 167 | name: meta_tgt.name, |
161 | root: meta_tgt.src_path.clone(), | 168 | root: meta_tgt.src_path.clone(), |
162 | kind: TargetKind::new(meta_tgt.kind.as_slice()), | 169 | kind: TargetKind::new(meta_tgt.kind.as_slice()), |
170 | is_proc_macro, | ||
163 | }); | 171 | }); |
164 | pkg_data.targets.push(tgt); | 172 | pkg_data.targets.push(tgt); |
165 | } | 173 | } |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 638ca2f8b..55ff4d6ef 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -211,6 +211,8 @@ impl ProjectWorkspace { | |||
211 | let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied()); | 211 | let libcore = sysroot.core().and_then(|it| sysroot_crates.get(&it).copied()); |
212 | let liballoc = sysroot.alloc().and_then(|it| sysroot_crates.get(&it).copied()); | 212 | let liballoc = sysroot.alloc().and_then(|it| sysroot_crates.get(&it).copied()); |
213 | let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); | 213 | let libstd = sysroot.std().and_then(|it| sysroot_crates.get(&it).copied()); |
214 | let libproc_macro = | ||
215 | sysroot.proc_macro().and_then(|it| sysroot_crates.get(&it).copied()); | ||
214 | 216 | ||
215 | let mut pkg_to_lib_crate = FxHashMap::default(); | 217 | let mut pkg_to_lib_crate = FxHashMap::default(); |
216 | let mut pkg_crates = FxHashMap::default(); | 218 | let mut pkg_crates = FxHashMap::default(); |
@@ -237,6 +239,21 @@ impl ProjectWorkspace { | |||
237 | lib_tgt = Some(crate_id); | 239 | lib_tgt = Some(crate_id); |
238 | pkg_to_lib_crate.insert(pkg, crate_id); | 240 | pkg_to_lib_crate.insert(pkg, crate_id); |
239 | } | 241 | } |
242 | if tgt.is_proc_macro(&cargo) { | ||
243 | if let Some(proc_macro) = libproc_macro { | ||
244 | if let Err(_) = crate_graph.add_dep( | ||
245 | crate_id, | ||
246 | "proc_macro".into(), | ||
247 | proc_macro, | ||
248 | ) { | ||
249 | log::error!( | ||
250 | "cyclic dependency on proc_macro for {}", | ||
251 | pkg.name(&cargo) | ||
252 | ) | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | |||
240 | pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); | 257 | pkg_crates.entry(pkg).or_insert_with(Vec::new).push(crate_id); |
241 | } | 258 | } |
242 | } | 259 | } |
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs index bec9439d7..10ca391b6 100644 --- a/crates/ra_project_model/src/sysroot.rs +++ b/crates/ra_project_model/src/sysroot.rs | |||
@@ -39,6 +39,10 @@ impl Sysroot { | |||
39 | self.by_name("std") | 39 | self.by_name("std") |
40 | } | 40 | } |
41 | 41 | ||
42 | pub fn proc_macro(&self) -> Option<SysrootCrate> { | ||
43 | self.by_name("proc_macro") | ||
44 | } | ||
45 | |||
42 | pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a { | 46 | pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIterator + 'a { |
43 | self.crates.iter().map(|(id, _data)| id) | 47 | self.crates.iter().map(|(id, _data)| id) |
44 | } | 48 | } |
@@ -74,7 +78,7 @@ impl Sysroot { | |||
74 | } | 78 | } |
75 | } | 79 | } |
76 | if let Some(alloc) = sysroot.by_name("alloc") { | 80 | if let Some(alloc) = sysroot.by_name("alloc") { |
77 | if let Some(core) = sysroot.by_name("core") { | 81 | if let Some(core) = sysroot.core() { |
78 | sysroot.crates[alloc].deps.push(core); | 82 | sysroot.crates[alloc].deps.push(core); |
79 | } | 83 | } |
80 | } | 84 | } |
diff --git a/xtask/tests/tidy-tests/docs.rs b/xtask/tests/tidy-tests/docs.rs index 141219860..fae871285 100644 --- a/xtask/tests/tidy-tests/docs.rs +++ b/xtask/tests/tidy-tests/docs.rs | |||
@@ -74,7 +74,6 @@ fn no_docs_comments() { | |||
74 | "ra_db", | 74 | "ra_db", |
75 | "ra_hir", | 75 | "ra_hir", |
76 | "ra_hir_expand", | 76 | "ra_hir_expand", |
77 | "ra_hir_def", | ||
78 | "ra_ide_api", | 77 | "ra_ide_api", |
79 | "ra_lsp_server", | 78 | "ra_lsp_server", |
80 | "ra_mbe", | 79 | "ra_mbe", |