aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs20
-rw-r--r--crates/ra_hir/src/db.rs17
-rw-r--r--crates/ra_hir/src/from_id.rs60
-rw-r--r--crates/ra_hir/src/source_binder.rs16
-rw-r--r--crates/ra_hir/src/ty.rs2
-rw-r--r--crates/ra_hir/src/ty/infer.rs91
-rw-r--r--crates/ra_hir/src/ty/infer/expr.rs42
-rw-r--r--crates/ra_hir/src/ty/infer/pat.rs20
-rw-r--r--crates/ra_hir/src/ty/lower.rs55
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs7
-rw-r--r--crates/ra_hir/src/ty/op.rs6
-rw-r--r--crates/ra_hir/src/ty/utils.rs14
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
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId}; 5use hir_def::{DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId};
6use ra_arena::map::ArenaMap; 6use ra_arena::map::ArenaMap;
7use ra_db::{salsa, CrateId}; 7use ra_db::{salsa, CrateId};
8 8
9use crate::{ 9use 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
19pub use hir_def::db::{ 16pub use hir_def::db::{
@@ -32,7 +29,7 @@ pub use hir_expand::db::{
32#[salsa::requires(salsa::Database)] 29#[salsa::requires(salsa::Database)]
33pub trait HirDatabase: DefDatabase { 30pub 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
6use hir_def::{ 6use 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
11use crate::{ 11use 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
16impl From<ra_db::CrateId> for Crate { 16impl From<ra_db::CrateId> for Crate {
@@ -137,58 +137,6 @@ impl From<GenericDef> for GenericDefId {
137 } 137 }
138} 138}
139 139
140impl From<AdtId> for TypableDef {
141 fn from(id: AdtId) -> Self {
142 Adt::from(id).into()
143 }
144}
145
146impl From<StructId> for TypableDef {
147 fn from(id: StructId) -> Self {
148 AdtId::StructId(id).into()
149 }
150}
151
152impl From<UnionId> for TypableDef {
153 fn from(id: UnionId) -> Self {
154 AdtId::UnionId(id).into()
155 }
156}
157
158impl From<EnumId> for TypableDef {
159 fn from(id: EnumId) -> Self {
160 AdtId::EnumId(id).into()
161 }
162}
163
164impl From<EnumVariantId> for TypableDef {
165 fn from(id: EnumVariantId) -> Self {
166 EnumVariant::from(id).into()
167 }
168}
169
170impl From<TypeAliasId> for TypableDef {
171 fn from(id: TypeAliasId) -> Self {
172 TypeAlias::from(id).into()
173 }
174}
175
176impl From<FunctionId> for TypableDef {
177 fn from(id: FunctionId) -> Self {
178 Function::from(id).into()
179 }
180}
181impl From<ConstId> for TypableDef {
182 fn from(id: ConstId) -> Self {
183 Const::from(id).into()
184 }
185}
186impl From<StaticId> for TypableDef {
187 fn from(id: StaticId) -> Self {
188 Static::from(id).into()
189 }
190}
191
192impl From<Adt> for GenericDefId { 140impl 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;
38pub(crate) use lower::{ 38pub(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};
43pub(crate) use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 43pub(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};
22use rustc_hash::FxHashMap; 22use rustc_hash::FxHashMap;
23 23
24use hir_def::{ 24use 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};
31use hir_expand::{diagnostics::DiagnosticSink, name}; 33use hir_expand::{diagnostics::DiagnosticSink, name};
32use ra_arena::map::ArenaMap; 34use ra_arena::map::ArenaMap;
@@ -34,17 +36,12 @@ use ra_prof::profile;
34use test_utils::tested_by; 36use test_utils::tested_by;
35 37
36use super::{ 38use 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};
41use crate::{ 44use 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
49macro_rules! ty_app { 46macro_rules! ty_app {
50 ($ctor:pat, $param:pat) => { 47 ($ctor:pat, $param:pat) => {
@@ -62,15 +59,15 @@ mod pat;
62mod coerce; 59mod coerce;
63 60
64/// The entry point of type inference. 61/// The entry point of type inference.
65pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<InferenceResult> { 62pub 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)]
122pub struct InferenceResult { 119pub 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
139impl InferenceResult { 136impl 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)]
192struct InferenceContext<'a, D: HirDatabase> { 189struct 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
211impl<'a, D: HirDatabase> InferenceContext<'a, D> { 208impl<'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
698mod diagnostics { 695mod 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};
16use crate::{ 16use 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;
14use super::{BindingMode, InferenceContext}; 14use super::{BindingMode, InferenceContext};
15use crate::{ 15use 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
20impl<'a, D: HirDatabase> InferenceContext<'a, D> { 20impl<'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;
11use hir_def::{ 11use 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
38impl Ty { 37impl 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)]
699pub enum TypableDef {
700 Function(Function),
701 Adt(Adt),
702 EnumVariant(EnumVariant),
703 TypeAlias(TypeAlias),
704 Const(Const),
705 Static(Static),
706 BuiltinType(BuiltinType),
707}
708impl_froms!(
709 TypableDef: Function,
710 Adt(Struct, Enum, Union),
711 EnumVariant,
712 TypeAlias,
713 Const,
714 Static,
715 BuiltinType
716);
717
718impl 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)]
735pub enum CallableDef { 696pub 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;
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::{ 8use 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};
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13use ra_db::CrateId; 13use 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
24use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; 23use 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
2use hir_def::expr::{BinaryOp, CmpOp};
2 3
3use super::{InferTy, Ty, TypeCtor}; 4use super::{InferTy, Ty, TypeCtor};
4use crate::{ 5use crate::ty::ApplicationTy;
5 expr::{BinaryOp, CmpOp},
6 ty::ApplicationTy,
7};
8 6
9pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { 7pub(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`).
3use std::sync::Arc;
3 4
4use hir_def::{ 5use 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};
10use hir_expand::name::{self, Name}; 12use 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
67pub(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}