diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-27 13:41:55 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-27 13:41:55 +0000 |
commit | 2798beeeb05ab0e71773a2ed51b7b0c90bf6b06a (patch) | |
tree | 55f1a6eddc328b20e3a4f71036d59a9573bfaa9c /crates/ra_hir/src/ty/infer.rs | |
parent | 35f57f35ec484422f06772ebe109c8fd28966ec5 (diff) | |
parent | 12501fcdd02fec9d43dfd810d65e927ddebb1b56 (diff) |
Merge #2428
2428: Remove TypableDef r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 91 |
1 files changed, 45 insertions, 46 deletions
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 | } |