diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 114 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model/src.rs | 37 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 52 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/test_db.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/coerce.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/expr.rs | 33 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/pat.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 44 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 6 |
16 files changed, 166 insertions, 227 deletions
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); |