diff options
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/from_id.rs | 60 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 91 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/expr.rs | 42 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/pat.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 55 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/op.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/utils.rs | 14 |
12 files changed, 131 insertions, 219 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 54da937ea..52ad4e5d1 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -534,14 +534,6 @@ impl VariantDef { | |||
534 | } | 534 | } |
535 | } | 535 | } |
536 | 536 | ||
537 | pub(crate) fn field(self, db: &impl HirDatabase, name: &Name) -> Option<StructField> { | ||
538 | match self { | ||
539 | VariantDef::Struct(it) => it.field(db, name), | ||
540 | VariantDef::Union(it) => it.field(db, name), | ||
541 | VariantDef::EnumVariant(it) => it.field(db, name), | ||
542 | } | ||
543 | } | ||
544 | |||
545 | pub fn module(self, db: &impl HirDatabase) -> Module { | 537 | pub fn module(self, db: &impl HirDatabase) -> Module { |
546 | match self { | 538 | match self { |
547 | VariantDef::Struct(it) => it.module(db), | 539 | VariantDef::Struct(it) => it.module(db), |
@@ -618,7 +610,7 @@ impl Function { | |||
618 | } | 610 | } |
619 | 611 | ||
620 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 612 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
621 | db.infer(self.into()) | 613 | db.infer(self.id.into()) |
622 | } | 614 | } |
623 | 615 | ||
624 | /// The containing impl block, if this is a method. | 616 | /// The containing impl block, if this is a method. |
@@ -647,7 +639,7 @@ impl Function { | |||
647 | 639 | ||
648 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { | 640 | pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { |
649 | let infer = self.infer(db); | 641 | let infer = self.infer(db); |
650 | infer.add_diagnostics(db, self, sink); | 642 | infer.add_diagnostics(db, self.id, sink); |
651 | let mut validator = ExprValidator::new(self, infer, sink); | 643 | let mut validator = ExprValidator::new(self, infer, sink); |
652 | validator.validate_body(db); | 644 | validator.validate_body(db); |
653 | } | 645 | } |
@@ -672,7 +664,7 @@ impl Const { | |||
672 | } | 664 | } |
673 | 665 | ||
674 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 666 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
675 | db.infer(self.into()) | 667 | db.infer(self.id.into()) |
676 | } | 668 | } |
677 | 669 | ||
678 | /// The containing impl block, if this is a type alias. | 670 | /// The containing impl block, if this is a type alias. |
@@ -715,7 +707,7 @@ impl Static { | |||
715 | } | 707 | } |
716 | 708 | ||
717 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { | 709 | pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { |
718 | db.infer(self.into()) | 710 | db.infer(self.id.into()) |
719 | } | 711 | } |
720 | } | 712 | } |
721 | 713 | ||
@@ -908,9 +900,9 @@ impl Local { | |||
908 | } | 900 | } |
909 | 901 | ||
910 | pub fn ty(self, db: &impl HirDatabase) -> Type { | 902 | pub fn ty(self, db: &impl HirDatabase) -> Type { |
911 | let infer = db.infer(self.parent); | ||
912 | let ty = infer[self.pat_id].clone(); | ||
913 | let def = DefWithBodyId::from(self.parent); | 903 | let def = DefWithBodyId::from(self.parent); |
904 | let infer = db.infer(def); | ||
905 | let ty = infer[self.pat_id].clone(); | ||
914 | let resolver = def.resolver(db); | 906 | let resolver = def.resolver(db); |
915 | let krate = def.module(db).krate; | 907 | let krate = def.module(db).krate; |
916 | let environment = TraitEnvironment::lower(db, &resolver); | 908 | let environment = TraitEnvironment::lower(db, &resolver); |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index a5bfef91f..e192c8f47 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -2,18 +2,15 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId}; | 5 | use hir_def::{DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId}; |
6 | use ra_arena::map::ArenaMap; | 6 | use ra_arena::map::ArenaMap; |
7 | use ra_db::{salsa, CrateId}; | 7 | use ra_db::{salsa, CrateId}; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::ty::{ |
10 | ty::{ | 10 | method_resolution::CrateImplBlocks, |
11 | method_resolution::CrateImplBlocks, | 11 | traits::{AssocTyValue, Impl}, |
12 | traits::{AssocTyValue, Impl}, | 12 | CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, |
13 | CallableDef, FnSig, GenericPredicate, InferenceResult, Substs, Ty, TyDefId, TypeCtor, | 13 | ValueTyDefId, |
14 | ValueTyDefId, | ||
15 | }, | ||
16 | DefWithBody, | ||
17 | }; | 14 | }; |
18 | 15 | ||
19 | pub use hir_def::db::{ | 16 | pub use hir_def::db::{ |
@@ -32,7 +29,7 @@ pub use hir_expand::db::{ | |||
32 | #[salsa::requires(salsa::Database)] | 29 | #[salsa::requires(salsa::Database)] |
33 | pub trait HirDatabase: DefDatabase { | 30 | pub trait HirDatabase: DefDatabase { |
34 | #[salsa::invoke(crate::ty::infer_query)] | 31 | #[salsa::invoke(crate::ty::infer_query)] |
35 | fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; | 32 | fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>; |
36 | 33 | ||
37 | #[salsa::invoke(crate::ty::ty_query)] | 34 | #[salsa::invoke(crate::ty::ty_query)] |
38 | fn ty(&self, def: TyDefId) -> Ty; | 35 | fn ty(&self, def: TyDefId) -> Ty; |
diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 38daa5e59..e96a18d12 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs | |||
@@ -4,13 +4,13 @@ | |||
4 | //! are splitting the hir. | 4 | //! are splitting the hir. |
5 | 5 | ||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | AdtId, AssocItemId, AttrDefId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, | 7 | AdtId, AssocItemId, AttrDefId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId, |
8 | GenericDefId, ModuleDefId, StaticId, StructFieldId, StructId, TypeAliasId, UnionId, VariantId, | 8 | StructFieldId, VariantId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | ty::TypableDef, Adt, AssocItem, AttrDef, Const, Crate, DefWithBody, EnumVariant, Function, | 12 | Adt, AssocItem, AttrDef, Crate, DefWithBody, EnumVariant, GenericDef, ModuleDef, StructField, |
13 | GenericDef, ModuleDef, Static, StructField, TypeAlias, VariantDef, | 13 | VariantDef, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | impl From<ra_db::CrateId> for Crate { | 16 | impl From<ra_db::CrateId> for Crate { |
@@ -137,58 +137,6 @@ impl From<GenericDef> for GenericDefId { | |||
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | impl From<AdtId> for TypableDef { | ||
141 | fn from(id: AdtId) -> Self { | ||
142 | Adt::from(id).into() | ||
143 | } | ||
144 | } | ||
145 | |||
146 | impl From<StructId> for TypableDef { | ||
147 | fn from(id: StructId) -> Self { | ||
148 | AdtId::StructId(id).into() | ||
149 | } | ||
150 | } | ||
151 | |||
152 | impl From<UnionId> for TypableDef { | ||
153 | fn from(id: UnionId) -> Self { | ||
154 | AdtId::UnionId(id).into() | ||
155 | } | ||
156 | } | ||
157 | |||
158 | impl From<EnumId> for TypableDef { | ||
159 | fn from(id: EnumId) -> Self { | ||
160 | AdtId::EnumId(id).into() | ||
161 | } | ||
162 | } | ||
163 | |||
164 | impl From<EnumVariantId> for TypableDef { | ||
165 | fn from(id: EnumVariantId) -> Self { | ||
166 | EnumVariant::from(id).into() | ||
167 | } | ||
168 | } | ||
169 | |||
170 | impl From<TypeAliasId> for TypableDef { | ||
171 | fn from(id: TypeAliasId) -> Self { | ||
172 | TypeAlias::from(id).into() | ||
173 | } | ||
174 | } | ||
175 | |||
176 | impl From<FunctionId> for TypableDef { | ||
177 | fn from(id: FunctionId) -> Self { | ||
178 | Function::from(id).into() | ||
179 | } | ||
180 | } | ||
181 | impl From<ConstId> for TypableDef { | ||
182 | fn from(id: ConstId) -> Self { | ||
183 | Const::from(id).into() | ||
184 | } | ||
185 | } | ||
186 | impl From<StaticId> for TypableDef { | ||
187 | fn from(id: StaticId) -> Self { | ||
188 | Static::from(id).into() | ||
189 | } | ||
190 | } | ||
191 | |||
192 | impl From<Adt> for GenericDefId { | 140 | impl From<Adt> for GenericDefId { |
193 | fn from(id: Adt) -> Self { | 141 | fn from(id: Adt) -> Self { |
194 | match id { | 142 | match id { |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index b9d3a1713..05f5bca57 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -168,7 +168,7 @@ impl SourceAnalyzer { | |||
168 | resolver, | 168 | resolver, |
169 | body_owner: Some(def), | 169 | body_owner: Some(def), |
170 | body_source_map: Some(source_map), | 170 | body_source_map: Some(source_map), |
171 | infer: Some(db.infer(def)), | 171 | infer: Some(db.infer(def.into())), |
172 | scopes: Some(scopes), | 172 | scopes: Some(scopes), |
173 | file_id: node.file_id, | 173 | file_id: node.file_id, |
174 | } | 174 | } |
@@ -214,27 +214,27 @@ impl SourceAnalyzer { | |||
214 | 214 | ||
215 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { | 215 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { |
216 | let expr_id = self.expr_id(&call.clone().into())?; | 216 | let expr_id = self.expr_id(&call.clone().into())?; |
217 | self.infer.as_ref()?.method_resolution(expr_id) | 217 | self.infer.as_ref()?.method_resolution(expr_id).map(Function::from) |
218 | } | 218 | } |
219 | 219 | ||
220 | pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> { | 220 | pub fn resolve_field(&self, field: &ast::FieldExpr) -> Option<crate::StructField> { |
221 | let expr_id = self.expr_id(&field.clone().into())?; | 221 | let expr_id = self.expr_id(&field.clone().into())?; |
222 | self.infer.as_ref()?.field_resolution(expr_id) | 222 | self.infer.as_ref()?.field_resolution(expr_id).map(|it| it.into()) |
223 | } | 223 | } |
224 | 224 | ||
225 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { | 225 | pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<crate::StructField> { |
226 | let expr_id = self.expr_id(&field.expr()?)?; | 226 | let expr_id = self.expr_id(&field.expr()?)?; |
227 | self.infer.as_ref()?.record_field_resolution(expr_id) | 227 | self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) |
228 | } | 228 | } |
229 | 229 | ||
230 | pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { | 230 | pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<crate::VariantDef> { |
231 | let expr_id = self.expr_id(&record_lit.clone().into())?; | 231 | let expr_id = self.expr_id(&record_lit.clone().into())?; |
232 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id) | 232 | self.infer.as_ref()?.variant_resolution_for_expr(expr_id).map(|it| it.into()) |
233 | } | 233 | } |
234 | 234 | ||
235 | pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option<crate::VariantDef> { | 235 | pub fn resolve_record_pattern(&self, record_pat: &ast::RecordPat) -> Option<crate::VariantDef> { |
236 | let pat_id = self.pat_id(&record_pat.clone().into())?; | 236 | let pat_id = self.pat_id(&record_pat.clone().into())?; |
237 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id) | 237 | self.infer.as_ref()?.variant_resolution_for_pat(pat_id).map(|it| it.into()) |
238 | } | 238 | } |
239 | 239 | ||
240 | pub fn resolve_macro_call( | 240 | pub fn resolve_macro_call( |
@@ -297,13 +297,13 @@ impl SourceAnalyzer { | |||
297 | if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { | 297 | if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { |
298 | let expr_id = self.expr_id(&path_expr.into())?; | 298 | let expr_id = self.expr_id(&path_expr.into())?; |
299 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { | 299 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_expr(expr_id) { |
300 | return Some(PathResolution::AssocItem(assoc)); | 300 | return Some(PathResolution::AssocItem(assoc.into())); |
301 | } | 301 | } |
302 | } | 302 | } |
303 | if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { | 303 | if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { |
304 | let pat_id = self.pat_id(&path_pat.into())?; | 304 | let pat_id = self.pat_id(&path_pat.into())?; |
305 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { | 305 | if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) { |
306 | return Some(PathResolution::AssocItem(assoc)); | 306 | return Some(PathResolution::AssocItem(assoc.into())); |
307 | } | 307 | } |
308 | } | 308 | } |
309 | // This must be a normal source file rather than macro file. | 309 | // This must be a normal source file rather than macro file. |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index a26776b26..e4ba8afa6 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -38,7 +38,7 @@ pub use lower::CallableDef; | |||
38 | pub(crate) use lower::{ | 38 | pub(crate) use lower::{ |
39 | callable_item_sig, field_types_query, generic_defaults_query, | 39 | callable_item_sig, field_types_query, generic_defaults_query, |
40 | generic_predicates_for_param_query, generic_predicates_query, ty_query, value_ty_query, | 40 | generic_predicates_for_param_query, generic_predicates_query, ty_query, value_ty_query, |
41 | TyDefId, TypableDef, ValueTyDefId, | 41 | TyDefId, ValueTyDefId, |
42 | }; | 42 | }; |
43 | pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 43 | pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; |
44 | 44 | ||
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index db9a8c9d1..59e4e5f36 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -22,11 +22,13 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; | |||
22 | use rustc_hash::FxHashMap; | 22 | use rustc_hash::FxHashMap; |
23 | 23 | ||
24 | use hir_def::{ | 24 | use hir_def::{ |
25 | body::Body, | ||
25 | data::{ConstData, FunctionData}, | 26 | data::{ConstData, FunctionData}, |
26 | path::known, | 27 | expr::{BindingAnnotation, ExprId, PatId}, |
28 | path::{known, Path}, | ||
27 | resolver::{HasResolver, Resolver, TypeNs}, | 29 | resolver::{HasResolver, Resolver, TypeNs}, |
28 | type_ref::{Mutability, TypeRef}, | 30 | type_ref::{Mutability, TypeRef}, |
29 | AdtId, AssocItemId, DefWithBodyId, | 31 | AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId, |
30 | }; | 32 | }; |
31 | use hir_expand::{diagnostics::DiagnosticSink, name}; | 33 | use hir_expand::{diagnostics::DiagnosticSink, name}; |
32 | use ra_arena::map::ArenaMap; | 34 | use ra_arena::map::ArenaMap; |
@@ -34,17 +36,12 @@ use ra_prof::profile; | |||
34 | use test_utils::tested_by; | 36 | use test_utils::tested_by; |
35 | 37 | ||
36 | use super::{ | 38 | use super::{ |
39 | primitive::{FloatTy, IntTy}, | ||
37 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 40 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, |
38 | ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, | 41 | ApplicationTy, InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, |
39 | TypeWalk, Uncertain, | 42 | TypeWalk, Uncertain, |
40 | }; | 43 | }; |
41 | use crate::{ | 44 | use crate::{db::HirDatabase, ty::infer::diagnostics::InferenceDiagnostic}; |
42 | code_model::TypeAlias, | ||
43 | db::HirDatabase, | ||
44 | expr::{BindingAnnotation, Body, ExprId, PatId}, | ||
45 | ty::infer::diagnostics::InferenceDiagnostic, | ||
46 | AssocItem, DefWithBody, FloatTy, Function, IntTy, Path, StructField, VariantDef, | ||
47 | }; | ||
48 | 45 | ||
49 | macro_rules! ty_app { | 46 | macro_rules! ty_app { |
50 | ($ctor:pat, $param:pat) => { | 47 | ($ctor:pat, $param:pat) => { |
@@ -62,15 +59,15 @@ mod pat; | |||
62 | mod coerce; | 59 | mod coerce; |
63 | 60 | ||
64 | /// The entry point of type inference. | 61 | /// The entry point of type inference. |
65 | pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { | 62 | pub fn infer_query(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> { |
66 | let _p = profile("infer_query"); | 63 | let _p = profile("infer_query"); |
67 | let resolver = DefWithBodyId::from(def).resolver(db); | 64 | let resolver = def.resolver(db); |
68 | let mut ctx = InferenceContext::new(db, def, resolver); | 65 | let mut ctx = InferenceContext::new(db, def, resolver); |
69 | 66 | ||
70 | match &def { | 67 | match def { |
71 | DefWithBody::Const(c) => ctx.collect_const(&db.const_data(c.id)), | 68 | DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)), |
72 | DefWithBody::Function(f) => ctx.collect_fn(&db.function_data(f.id)), | 69 | DefWithBodyId::FunctionId(f) => ctx.collect_fn(&db.function_data(f)), |
73 | DefWithBody::Static(s) => ctx.collect_const(&db.static_data(s.id)), | 70 | DefWithBodyId::StaticId(s) => ctx.collect_const(&db.static_data(s)), |
74 | } | 71 | } |
75 | 72 | ||
76 | ctx.infer_body(); | 73 | ctx.infer_body(); |
@@ -121,15 +118,15 @@ pub struct TypeMismatch { | |||
121 | #[derive(Clone, PartialEq, Eq, Debug, Default)] | 118 | #[derive(Clone, PartialEq, Eq, Debug, Default)] |
122 | pub struct InferenceResult { | 119 | pub struct InferenceResult { |
123 | /// For each method call expr, records the function it resolves to. | 120 | /// For each method call expr, records the function it resolves to. |
124 | method_resolutions: FxHashMap<ExprId, Function>, | 121 | method_resolutions: FxHashMap<ExprId, FunctionId>, |
125 | /// For each field access expr, records the field it resolves to. | 122 | /// For each field access expr, records the field it resolves to. |
126 | field_resolutions: FxHashMap<ExprId, StructField>, | 123 | field_resolutions: FxHashMap<ExprId, StructFieldId>, |
127 | /// For each field in record literal, records the field it resolves to. | 124 | /// For each field in record literal, records the field it resolves to. |
128 | record_field_resolutions: FxHashMap<ExprId, StructField>, | 125 | record_field_resolutions: FxHashMap<ExprId, StructFieldId>, |
129 | /// For each struct literal, records the variant it resolves to. | 126 | /// For each struct literal, records the variant it resolves to. |
130 | variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>, | 127 | variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, |
131 | /// For each associated item record what it resolves to | 128 | /// For each associated item record what it resolves to |
132 | assoc_resolutions: FxHashMap<ExprOrPatId, AssocItem>, | 129 | assoc_resolutions: FxHashMap<ExprOrPatId, AssocItemId>, |
133 | diagnostics: Vec<InferenceDiagnostic>, | 130 | diagnostics: Vec<InferenceDiagnostic>, |
134 | pub(super) type_of_expr: ArenaMap<ExprId, Ty>, | 131 | pub(super) type_of_expr: ArenaMap<ExprId, Ty>, |
135 | pub(super) type_of_pat: ArenaMap<PatId, Ty>, | 132 | pub(super) type_of_pat: ArenaMap<PatId, Ty>, |
@@ -137,25 +134,25 @@ pub struct InferenceResult { | |||
137 | } | 134 | } |
138 | 135 | ||
139 | impl InferenceResult { | 136 | impl InferenceResult { |
140 | pub fn method_resolution(&self, expr: ExprId) -> Option<Function> { | 137 | pub fn method_resolution(&self, expr: ExprId) -> Option<FunctionId> { |
141 | self.method_resolutions.get(&expr).copied() | 138 | self.method_resolutions.get(&expr).copied() |
142 | } | 139 | } |
143 | pub fn field_resolution(&self, expr: ExprId) -> Option<StructField> { | 140 | pub fn field_resolution(&self, expr: ExprId) -> Option<StructFieldId> { |
144 | self.field_resolutions.get(&expr).copied() | 141 | self.field_resolutions.get(&expr).copied() |
145 | } | 142 | } |
146 | pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructField> { | 143 | pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructFieldId> { |
147 | self.record_field_resolutions.get(&expr).copied() | 144 | self.record_field_resolutions.get(&expr).copied() |
148 | } | 145 | } |
149 | pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantDef> { | 146 | pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> { |
150 | self.variant_resolutions.get(&id.into()).copied() | 147 | self.variant_resolutions.get(&id.into()).copied() |
151 | } | 148 | } |
152 | pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantDef> { | 149 | pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> { |
153 | self.variant_resolutions.get(&id.into()).copied() | 150 | self.variant_resolutions.get(&id.into()).copied() |
154 | } | 151 | } |
155 | pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<AssocItem> { | 152 | pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<AssocItemId> { |
156 | self.assoc_resolutions.get(&id.into()).copied() | 153 | self.assoc_resolutions.get(&id.into()).copied() |
157 | } | 154 | } |
158 | pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<AssocItem> { | 155 | pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<AssocItemId> { |
159 | self.assoc_resolutions.get(&id.into()).copied() | 156 | self.assoc_resolutions.get(&id.into()).copied() |
160 | } | 157 | } |
161 | pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { | 158 | pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { |
@@ -164,7 +161,7 @@ impl InferenceResult { | |||
164 | pub(crate) fn add_diagnostics( | 161 | pub(crate) fn add_diagnostics( |
165 | &self, | 162 | &self, |
166 | db: &impl HirDatabase, | 163 | db: &impl HirDatabase, |
167 | owner: Function, | 164 | owner: FunctionId, |
168 | sink: &mut DiagnosticSink, | 165 | sink: &mut DiagnosticSink, |
169 | ) { | 166 | ) { |
170 | self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink)) | 167 | self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink)) |
@@ -191,7 +188,7 @@ impl Index<PatId> for InferenceResult { | |||
191 | #[derive(Clone, Debug)] | 188 | #[derive(Clone, Debug)] |
192 | struct InferenceContext<'a, D: HirDatabase> { | 189 | struct InferenceContext<'a, D: HirDatabase> { |
193 | db: &'a D, | 190 | db: &'a D, |
194 | owner: DefWithBody, | 191 | owner: DefWithBodyId, |
195 | body: Arc<Body>, | 192 | body: Arc<Body>, |
196 | resolver: Resolver, | 193 | resolver: Resolver, |
197 | var_unification_table: InPlaceUnificationTable<TypeVarId>, | 194 | var_unification_table: InPlaceUnificationTable<TypeVarId>, |
@@ -209,7 +206,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
209 | } | 206 | } |
210 | 207 | ||
211 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 208 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
212 | fn new(db: &'a D, owner: DefWithBody, resolver: Resolver) -> Self { | 209 | fn new(db: &'a D, owner: DefWithBodyId, resolver: Resolver) -> Self { |
213 | InferenceContext { | 210 | InferenceContext { |
214 | result: InferenceResult::default(), | 211 | result: InferenceResult::default(), |
215 | var_unification_table: InPlaceUnificationTable::new(), | 212 | var_unification_table: InPlaceUnificationTable::new(), |
@@ -243,15 +240,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
243 | self.result.type_of_expr.insert(expr, ty); | 240 | self.result.type_of_expr.insert(expr, ty); |
244 | } | 241 | } |
245 | 242 | ||
246 | fn write_method_resolution(&mut self, expr: ExprId, func: Function) { | 243 | fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId) { |
247 | self.result.method_resolutions.insert(expr, func); | 244 | self.result.method_resolutions.insert(expr, func); |
248 | } | 245 | } |
249 | 246 | ||
250 | fn write_field_resolution(&mut self, expr: ExprId, field: StructField) { | 247 | fn write_field_resolution(&mut self, expr: ExprId, field: StructFieldId) { |
251 | self.result.field_resolutions.insert(expr, field); | 248 | self.result.field_resolutions.insert(expr, field); |
252 | } | 249 | } |
253 | 250 | ||
254 | fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantDef) { | 251 | fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) { |
255 | self.result.variant_resolutions.insert(id, variant); | 252 | self.result.variant_resolutions.insert(id, variant); |
256 | } | 253 | } |
257 | 254 | ||
@@ -514,7 +511,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
514 | }) | 511 | }) |
515 | } | 512 | } |
516 | 513 | ||
517 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) { | 514 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { |
518 | let path = match path { | 515 | let path = match path { |
519 | Some(path) => path, | 516 | Some(path) => path, |
520 | None => return (Ty::Unknown, None), | 517 | None => return (Ty::Unknown, None), |
@@ -527,13 +524,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
527 | let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); | 524 | let substs = Ty::substs_from_path(self.db, resolver, path, strukt.into()); |
528 | let ty = self.db.ty(strukt.into()); | 525 | let ty = self.db.ty(strukt.into()); |
529 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | 526 | let ty = self.insert_type_vars(ty.apply_substs(substs)); |
530 | (ty, Some(VariantDef::Struct(strukt.into()))) | 527 | (ty, Some(strukt.into())) |
531 | } | 528 | } |
532 | Some(TypeNs::EnumVariantId(var)) => { | 529 | Some(TypeNs::EnumVariantId(var)) => { |
533 | let substs = Ty::substs_from_path(self.db, resolver, path, var.into()); | 530 | let substs = Ty::substs_from_path(self.db, resolver, path, var.into()); |
534 | let ty = self.db.ty(var.parent.into()); | 531 | let ty = self.db.ty(var.parent.into()); |
535 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | 532 | let ty = self.insert_type_vars(ty.apply_substs(substs)); |
536 | (ty, Some(VariantDef::EnumVariant(var.into()))) | 533 | (ty, Some(var.into())) |
537 | } | 534 | } |
538 | Some(_) | None => (Ty::Unknown, None), | 535 | Some(_) | None => (Ty::Unknown, None), |
539 | } | 536 | } |
@@ -557,22 +554,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
557 | self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); | 554 | self.infer_expr(self.body.body_expr, &Expectation::has_type(self.return_ty.clone())); |
558 | } | 555 | } |
559 | 556 | ||
560 | fn resolve_into_iter_item(&self) -> Option<TypeAlias> { | 557 | fn resolve_into_iter_item(&self) -> Option<TypeAliasId> { |
561 | let path = known::std_iter_into_iterator(); | 558 | let path = known::std_iter_into_iterator(); |
562 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | 559 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; |
563 | self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE).map(TypeAlias::from) | 560 | self.db.trait_data(trait_).associated_type_by_name(&name::ITEM_TYPE) |
564 | } | 561 | } |
565 | 562 | ||
566 | fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { | 563 | fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> { |
567 | let path = known::std_ops_try(); | 564 | let path = known::std_ops_try(); |
568 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | 565 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; |
569 | self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE).map(TypeAlias::from) | 566 | self.db.trait_data(trait_).associated_type_by_name(&name::OK_TYPE) |
570 | } | 567 | } |
571 | 568 | ||
572 | fn resolve_future_future_output(&self) -> Option<TypeAlias> { | 569 | fn resolve_future_future_output(&self) -> Option<TypeAliasId> { |
573 | let path = known::std_future_future(); | 570 | let path = known::std_future_future(); |
574 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | 571 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; |
575 | self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE).map(TypeAlias::from) | 572 | self.db.trait_data(trait_).associated_type_by_name(&name::OUTPUT_TYPE) |
576 | } | 573 | } |
577 | 574 | ||
578 | fn resolve_boxed_box(&self) -> Option<AdtId> { | 575 | fn resolve_boxed_box(&self) -> Option<AdtId> { |
@@ -696,9 +693,10 @@ impl Expectation { | |||
696 | } | 693 | } |
697 | 694 | ||
698 | mod diagnostics { | 695 | mod diagnostics { |
696 | use hir_def::{expr::ExprId, FunctionId, HasSource, Lookup}; | ||
699 | use hir_expand::diagnostics::DiagnosticSink; | 697 | use hir_expand::diagnostics::DiagnosticSink; |
700 | 698 | ||
701 | use crate::{db::HirDatabase, diagnostics::NoSuchField, expr::ExprId, Function, HasSource}; | 699 | use crate::{db::HirDatabase, diagnostics::NoSuchField}; |
702 | 700 | ||
703 | #[derive(Debug, PartialEq, Eq, Clone)] | 701 | #[derive(Debug, PartialEq, Eq, Clone)] |
704 | pub(super) enum InferenceDiagnostic { | 702 | pub(super) enum InferenceDiagnostic { |
@@ -709,13 +707,14 @@ mod diagnostics { | |||
709 | pub(super) fn add_to( | 707 | pub(super) fn add_to( |
710 | &self, | 708 | &self, |
711 | db: &impl HirDatabase, | 709 | db: &impl HirDatabase, |
712 | owner: Function, | 710 | owner: FunctionId, |
713 | sink: &mut DiagnosticSink, | 711 | sink: &mut DiagnosticSink, |
714 | ) { | 712 | ) { |
715 | match self { | 713 | match self { |
716 | InferenceDiagnostic::NoSuchField { expr, field } => { | 714 | InferenceDiagnostic::NoSuchField { expr, field } => { |
717 | let file = owner.source(db).file_id; | 715 | let file = owner.lookup(db).source(db).file_id; |
718 | let field = owner.body_source_map(db).field_syntax(*expr, *field); | 716 | let (_, source_map) = db.body_with_source_map(owner.into()); |
717 | let field = source_map.field_syntax(*expr, *field); | ||
719 | sink.push(NoSuchField { file, field }) | 718 | sink.push(NoSuchField { file, field }) |
720 | } | 719 | } |
721 | } | 720 | } |
diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 57f845dfa..f9ededa23 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs | |||
@@ -16,9 +16,9 @@ use hir_expand::name::{self, Name}; | |||
16 | use crate::{ | 16 | use crate::{ |
17 | db::HirDatabase, | 17 | db::HirDatabase, |
18 | ty::{ | 18 | ty::{ |
19 | autoderef, method_resolution, op, traits::InEnvironment, CallableDef, InferTy, IntTy, | 19 | autoderef, method_resolution, op, traits::InEnvironment, utils::variant_data, CallableDef, |
20 | Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, | 20 | InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, |
21 | TypeWalk, Uncertain, | 21 | TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, |
22 | }, | 22 | }, |
23 | }; | 23 | }; |
24 | 24 | ||
@@ -100,7 +100,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
100 | let projection = ProjectionPredicate { | 100 | let projection = ProjectionPredicate { |
101 | ty: pat_ty.clone(), | 101 | ty: pat_ty.clone(), |
102 | projection_ty: ProjectionTy { | 102 | projection_ty: ProjectionTy { |
103 | associated_ty: into_iter_item_alias.id, | 103 | associated_ty: into_iter_item_alias, |
104 | parameters: Substs::single(iterable_ty), | 104 | parameters: Substs::single(iterable_ty), |
105 | }, | 105 | }, |
106 | }; | 106 | }; |
@@ -218,22 +218,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
218 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 218 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
219 | let field_types = | 219 | let field_types = |
220 | def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default(); | 220 | def_id.map(|it| self.db.field_types(it.into())).unwrap_or_default(); |
221 | let variant_data = def_id.map(|it| variant_data(self.db, it)); | ||
221 | for (field_idx, field) in fields.iter().enumerate() { | 222 | for (field_idx, field) in fields.iter().enumerate() { |
222 | let field_def = def_id.and_then(|it| match it.field(self.db, &field.name) { | 223 | let field_def = |
223 | Some(field) => Some(field), | 224 | variant_data.as_ref().and_then(|it| match it.field(&field.name) { |
224 | None => { | 225 | Some(local_id) => { |
225 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { | 226 | Some(StructFieldId { parent: def_id.unwrap(), local_id }) |
226 | expr: tgt_expr, | 227 | } |
227 | field: field_idx, | 228 | None => { |
228 | }); | 229 | self.push_diagnostic(InferenceDiagnostic::NoSuchField { |
229 | None | 230 | expr: tgt_expr, |
230 | } | 231 | field: field_idx, |
231 | }); | 232 | }); |
233 | None | ||
234 | } | ||
235 | }); | ||
232 | if let Some(field_def) = field_def { | 236 | if let Some(field_def) = field_def { |
233 | self.result.record_field_resolutions.insert(field.expr, field_def); | 237 | self.result.record_field_resolutions.insert(field.expr, field_def); |
234 | } | 238 | } |
235 | let field_ty = field_def | 239 | let field_ty = field_def |
236 | .map_or(Ty::Unknown, |it| field_types[it.id].clone()) | 240 | .map_or(Ty::Unknown, |it| field_types[it.local_id].clone()) |
237 | .subst(&substs); | 241 | .subst(&substs); |
238 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); | 242 | self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); |
239 | } | 243 | } |
@@ -262,7 +266,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
262 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 266 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { |
263 | let field = StructFieldId { parent: s.into(), local_id }.into(); | 267 | let field = StructFieldId { parent: s.into(), local_id }.into(); |
264 | self.write_field_resolution(tgt_expr, field); | 268 | self.write_field_resolution(tgt_expr, field); |
265 | self.db.field_types(s.into())[field.id] | 269 | self.db.field_types(s.into())[field.local_id] |
266 | .clone() | 270 | .clone() |
267 | .subst(&a_ty.parameters) | 271 | .subst(&a_ty.parameters) |
268 | }) | 272 | }) |
@@ -285,7 +289,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
285 | let projection = ProjectionPredicate { | 289 | let projection = ProjectionPredicate { |
286 | ty: ty.clone(), | 290 | ty: ty.clone(), |
287 | projection_ty: ProjectionTy { | 291 | projection_ty: ProjectionTy { |
288 | associated_ty: future_future_output_alias.id, | 292 | associated_ty: future_future_output_alias, |
289 | parameters: Substs::single(inner_ty), | 293 | parameters: Substs::single(inner_ty), |
290 | }, | 294 | }, |
291 | }; | 295 | }; |
@@ -304,7 +308,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
304 | let projection = ProjectionPredicate { | 308 | let projection = ProjectionPredicate { |
305 | ty: ty.clone(), | 309 | ty: ty.clone(), |
306 | projection_ty: ProjectionTy { | 310 | projection_ty: ProjectionTy { |
307 | associated_ty: ops_try_ok_alias.id, | 311 | associated_ty: ops_try_ok_alias, |
308 | parameters: Substs::single(inner_ty), | 312 | parameters: Substs::single(inner_ty), |
309 | }, | 313 | }, |
310 | }; | 314 | }; |
@@ -557,7 +561,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
557 | Some((ty, func)) => { | 561 | Some((ty, func)) => { |
558 | let ty = canonicalized_receiver.decanonicalize_ty(ty); | 562 | let ty = canonicalized_receiver.decanonicalize_ty(ty); |
559 | self.write_method_resolution(tgt_expr, func); | 563 | self.write_method_resolution(tgt_expr, func); |
560 | (ty, self.db.value_ty(func.id.into()), Some(self.db.generic_params(func.id.into()))) | 564 | (ty, self.db.value_ty(func.into()), Some(self.db.generic_params(func.into()))) |
561 | } | 565 | } |
562 | None => (receiver_ty, Ty::Unknown, None), | 566 | None => (receiver_ty, Ty::Unknown, None), |
563 | }; | 567 | }; |
diff --git a/crates/ra_hir/src/ty/infer/pat.rs b/crates/ra_hir/src/ty/infer/pat.rs index 6dbf03eb2..a14774607 100644 --- a/crates/ra_hir/src/ty/infer/pat.rs +++ b/crates/ra_hir/src/ty/infer/pat.rs | |||
@@ -14,7 +14,7 @@ use test_utils::tested_by; | |||
14 | use super::{BindingMode, InferenceContext}; | 14 | use super::{BindingMode, InferenceContext}; |
15 | use crate::{ | 15 | use crate::{ |
16 | db::HirDatabase, | 16 | db::HirDatabase, |
17 | ty::{Substs, Ty, TypeCtor, TypeWalk}, | 17 | ty::{utils::variant_data, Substs, Ty, TypeCtor, TypeWalk}, |
18 | }; | 18 | }; |
19 | 19 | ||
20 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 20 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
@@ -26,16 +26,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
26 | default_bm: BindingMode, | 26 | default_bm: BindingMode, |
27 | ) -> Ty { | 27 | ) -> Ty { |
28 | let (ty, def) = self.resolve_variant(path); | 28 | let (ty, def) = self.resolve_variant(path); |
29 | 29 | let var_data = def.map(|it| variant_data(self.db, it)); | |
30 | self.unify(&ty, expected); | 30 | self.unify(&ty, expected); |
31 | 31 | ||
32 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 32 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
33 | 33 | ||
34 | let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); | 34 | let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); |
35 | |||
35 | for (i, &subpat) in subpats.iter().enumerate() { | 36 | for (i, &subpat) in subpats.iter().enumerate() { |
36 | let expected_ty = def | 37 | let expected_ty = var_data |
37 | .and_then(|d| d.field(self.db, &Name::new_tuple_field(i))) | 38 | .as_ref() |
38 | .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) | 39 | .and_then(|d| d.field(&Name::new_tuple_field(i))) |
40 | .map_or(Ty::Unknown, |field| field_tys[field].clone()) | ||
39 | .subst(&substs); | 41 | .subst(&substs); |
40 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 42 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
41 | self.infer_pat(subpat, &expected_ty, default_bm); | 43 | self.infer_pat(subpat, &expected_ty, default_bm); |
@@ -53,6 +55,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
53 | id: PatId, | 55 | id: PatId, |
54 | ) -> Ty { | 56 | ) -> Ty { |
55 | let (ty, def) = self.resolve_variant(path); | 57 | let (ty, def) = self.resolve_variant(path); |
58 | let var_data = def.map(|it| variant_data(self.db, it)); | ||
56 | if let Some(variant) = def { | 59 | if let Some(variant) = def { |
57 | self.write_variant_resolution(id.into(), variant); | 60 | self.write_variant_resolution(id.into(), variant); |
58 | } | 61 | } |
@@ -63,10 +66,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
63 | 66 | ||
64 | let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); | 67 | let field_tys = def.map(|it| self.db.field_types(it.into())).unwrap_or_default(); |
65 | for subpat in subpats { | 68 | for subpat in subpats { |
66 | let matching_field = def.and_then(|it| it.field(self.db, &subpat.name)); | 69 | let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); |
67 | let expected_ty = matching_field | 70 | let expected_ty = |
68 | .map_or(Ty::Unknown, |field| field_tys[field.id].clone()) | 71 | matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone()).subst(&substs); |
69 | .subst(&substs); | ||
70 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 72 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
71 | self.infer_pat(subpat.pat, &expected_ty, default_bm); | 73 | self.infer_pat(subpat.pat, &expected_ty, default_bm); |
72 | } | 74 | } |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 1c0f71adc..5dce2f342 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -11,7 +11,7 @@ use std::sync::Arc; | |||
11 | use hir_def::{ | 11 | use hir_def::{ |
12 | builtin_type::BuiltinType, | 12 | builtin_type::BuiltinType, |
13 | generics::WherePredicate, | 13 | generics::WherePredicate, |
14 | path::{GenericArg, PathSegment}, | 14 | path::{GenericArg, Path, PathSegment}, |
15 | resolver::{HasResolver, Resolver, TypeNs}, | 15 | resolver::{HasResolver, Resolver, TypeNs}, |
16 | type_ref::{TypeBound, TypeRef}, | 16 | type_ref::{TypeBound, TypeRef}, |
17 | AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, | 17 | AdtId, AstItemDef, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, |
@@ -28,11 +28,10 @@ use crate::{ | |||
28 | db::HirDatabase, | 28 | db::HirDatabase, |
29 | ty::{ | 29 | ty::{ |
30 | primitive::{FloatTy, IntTy}, | 30 | primitive::{FloatTy, IntTy}, |
31 | utils::{all_super_traits, associated_type_by_name_including_super_traits}, | 31 | utils::{all_super_traits, associated_type_by_name_including_super_traits, variant_data}, |
32 | }, | 32 | }, |
33 | util::make_mut_slice, | 33 | util::make_mut_slice, |
34 | Adt, Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, Trait, | 34 | ImplBlock, Trait, |
35 | TypeAlias, Union, | ||
36 | }; | 35 | }; |
37 | 36 | ||
38 | impl Ty { | 37 | impl Ty { |
@@ -514,13 +513,11 @@ pub(crate) fn field_types_query( | |||
514 | db: &impl HirDatabase, | 513 | db: &impl HirDatabase, |
515 | variant_id: VariantId, | 514 | variant_id: VariantId, |
516 | ) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { | 515 | ) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { |
517 | let (resolver, var_data) = match variant_id { | 516 | let var_data = variant_data(db, variant_id); |
518 | VariantId::StructId(it) => (it.resolver(db), db.struct_data(it).variant_data.clone()), | 517 | let resolver = match variant_id { |
519 | VariantId::UnionId(it) => (it.resolver(db), db.union_data(it).variant_data.clone()), | 518 | VariantId::StructId(it) => it.resolver(db), |
520 | VariantId::EnumVariantId(it) => ( | 519 | VariantId::UnionId(it) => it.resolver(db), |
521 | it.parent.resolver(db), | 520 | VariantId::EnumVariantId(it) => it.parent.resolver(db), |
522 | db.enum_data(it.parent).variants[it.local_id].variant_data.clone(), | ||
523 | ), | ||
524 | }; | 521 | }; |
525 | let mut res = ArenaMap::default(); | 522 | let mut res = ArenaMap::default(); |
526 | for (field_id, field_data) in var_data.fields().iter() { | 523 | for (field_id, field_data) in var_data.fields().iter() { |
@@ -696,42 +693,6 @@ fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { | |||
696 | } | 693 | } |
697 | 694 | ||
698 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 695 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
699 | pub enum TypableDef { | ||
700 | Function(Function), | ||
701 | Adt(Adt), | ||
702 | EnumVariant(EnumVariant), | ||
703 | TypeAlias(TypeAlias), | ||
704 | Const(Const), | ||
705 | Static(Static), | ||
706 | BuiltinType(BuiltinType), | ||
707 | } | ||
708 | impl_froms!( | ||
709 | TypableDef: Function, | ||
710 | Adt(Struct, Enum, Union), | ||
711 | EnumVariant, | ||
712 | TypeAlias, | ||
713 | Const, | ||
714 | Static, | ||
715 | BuiltinType | ||
716 | ); | ||
717 | |||
718 | impl From<ModuleDef> for Option<TypableDef> { | ||
719 | fn from(def: ModuleDef) -> Option<TypableDef> { | ||
720 | let res = match def { | ||
721 | ModuleDef::Function(f) => f.into(), | ||
722 | ModuleDef::Adt(adt) => adt.into(), | ||
723 | ModuleDef::EnumVariant(v) => v.into(), | ||
724 | ModuleDef::TypeAlias(t) => t.into(), | ||
725 | ModuleDef::Const(v) => v.into(), | ||
726 | ModuleDef::Static(v) => v.into(), | ||
727 | ModuleDef::BuiltinType(t) => t.into(), | ||
728 | ModuleDef::Module(_) | ModuleDef::Trait(_) => return None, | ||
729 | }; | ||
730 | Some(res) | ||
731 | } | ||
732 | } | ||
733 | |||
734 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
735 | pub enum CallableDef { | 696 | pub enum CallableDef { |
736 | FunctionId(FunctionId), | 697 | FunctionId(FunctionId), |
737 | StructId(StructId), | 698 | StructId(StructId), |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 02e81fb34..5cc249855 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -7,7 +7,7 @@ use std::sync::Arc; | |||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::{ | 8 | use hir_def::{ |
9 | lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, type_ref::Mutability, | 9 | lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, type_ref::Mutability, |
10 | AssocItemId, AstItemDef, HasModule, ImplId, TraitId, | 10 | AssocItemId, AstItemDef, FunctionId, HasModule, ImplId, TraitId, |
11 | }; | 11 | }; |
12 | use hir_expand::name::Name; | 12 | use hir_expand::name::Name; |
13 | use ra_db::CrateId; | 13 | use ra_db::CrateId; |
@@ -18,7 +18,6 @@ use crate::{ | |||
18 | db::HirDatabase, | 18 | db::HirDatabase, |
19 | ty::primitive::{FloatBitness, Uncertain}, | 19 | ty::primitive::{FloatBitness, Uncertain}, |
20 | ty::{utils::all_super_traits, Ty, TypeCtor}, | 20 | ty::{utils::all_super_traits, Ty, TypeCtor}, |
21 | Function, | ||
22 | }; | 21 | }; |
23 | 22 | ||
24 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; | 23 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; |
@@ -154,10 +153,10 @@ pub(crate) fn lookup_method( | |||
154 | db: &impl HirDatabase, | 153 | db: &impl HirDatabase, |
155 | name: &Name, | 154 | name: &Name, |
156 | resolver: &Resolver, | 155 | resolver: &Resolver, |
157 | ) -> Option<(Ty, Function)> { | 156 | ) -> Option<(Ty, FunctionId)> { |
158 | iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f | 157 | iterate_method_candidates(ty, db, resolver, Some(name), LookupMode::MethodCall, |ty, f| match f |
159 | { | 158 | { |
160 | AssocItemId::FunctionId(f) => Some((ty.clone(), f.into())), | 159 | AssocItemId::FunctionId(f) => Some((ty.clone(), f)), |
161 | _ => None, | 160 | _ => None, |
162 | }) | 161 | }) |
163 | } | 162 | } |
diff --git a/crates/ra_hir/src/ty/op.rs b/crates/ra_hir/src/ty/op.rs index bcfa3a6a2..cc6e244f4 100644 --- a/crates/ra_hir/src/ty/op.rs +++ b/crates/ra_hir/src/ty/op.rs | |||
@@ -1,10 +1,8 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | use hir_def::expr::{BinaryOp, CmpOp}; | ||
2 | 3 | ||
3 | use super::{InferTy, Ty, TypeCtor}; | 4 | use super::{InferTy, Ty, TypeCtor}; |
4 | use crate::{ | 5 | use crate::ty::ApplicationTy; |
5 | expr::{BinaryOp, CmpOp}, | ||
6 | ty::ApplicationTy, | ||
7 | }; | ||
8 | 6 | ||
9 | pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { | 7 | pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { |
10 | match op { | 8 | match op { |
diff --git a/crates/ra_hir/src/ty/utils.rs b/crates/ra_hir/src/ty/utils.rs index 80ffceb4b..f82e6ac9b 100644 --- a/crates/ra_hir/src/ty/utils.rs +++ b/crates/ra_hir/src/ty/utils.rs | |||
@@ -1,11 +1,13 @@ | |||
1 | //! Helper functions for working with def, which don't need to be a separate | 1 | //! Helper functions for working with def, which don't need to be a separate |
2 | //! query, but can't be computed directly from `*Data` (ie, which need a `db`). | 2 | //! query, but can't be computed directly from `*Data` (ie, which need a `db`). |
3 | use std::sync::Arc; | ||
3 | 4 | ||
4 | use hir_def::{ | 5 | use hir_def::{ |
6 | adt::VariantData, | ||
5 | db::DefDatabase, | 7 | db::DefDatabase, |
6 | resolver::{HasResolver, TypeNs}, | 8 | resolver::{HasResolver, TypeNs}, |
7 | type_ref::TypeRef, | 9 | type_ref::TypeRef, |
8 | TraitId, TypeAliasId, | 10 | TraitId, TypeAliasId, VariantId, |
9 | }; | 11 | }; |
10 | use hir_expand::name::{self, Name}; | 12 | use hir_expand::name::{self, Name}; |
11 | 13 | ||
@@ -61,3 +63,13 @@ pub(super) fn associated_type_by_name_including_super_traits( | |||
61 | .into_iter() | 63 | .into_iter() |
62 | .find_map(|t| db.trait_data(t).associated_type_by_name(name)) | 64 | .find_map(|t| db.trait_data(t).associated_type_by_name(name)) |
63 | } | 65 | } |
66 | |||
67 | pub(super) fn variant_data(db: &impl DefDatabase, var: VariantId) -> Arc<VariantData> { | ||
68 | match var { | ||
69 | VariantId::StructId(it) => db.struct_data(it).variant_data.clone(), | ||
70 | VariantId::UnionId(it) => db.union_data(it).variant_data.clone(), | ||
71 | VariantId::EnumVariantId(it) => { | ||
72 | db.enum_data(it.parent).variants[it.local_id].variant_data.clone() | ||
73 | } | ||
74 | } | ||
75 | } | ||