diff options
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 218 |
1 files changed, 117 insertions, 101 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index e690ae158..c7f77e7a3 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -24,15 +24,14 @@ use std::ops::Index; | |||
24 | use std::sync::Arc; | 24 | use std::sync::Arc; |
25 | use std::{fmt, mem}; | 25 | use std::{fmt, mem}; |
26 | 26 | ||
27 | use log; | ||
28 | use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError}; | 27 | use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError}; |
29 | use ra_arena::map::ArenaMap; | 28 | use ra_arena::map::ArenaMap; |
30 | use join_to_string::join; | 29 | use join_to_string::join; |
31 | use rustc_hash::FxHashMap; | 30 | use rustc_hash::FxHashMap; |
32 | 31 | ||
33 | use crate::{ | 32 | use crate::{ |
34 | Def, DefId, Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, | 33 | Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, |
35 | FnSignature, FnScopes, | 34 | FnSignature, FnScopes, ModuleDef, AdtDef, |
36 | db::HirDatabase, | 35 | db::HirDatabase, |
37 | type_ref::{TypeRef, Mutability}, | 36 | type_ref::{TypeRef, Mutability}, |
38 | name::KnownName, | 37 | name::KnownName, |
@@ -184,7 +183,7 @@ pub enum Ty { | |||
184 | /// Structures, enumerations and unions. | 183 | /// Structures, enumerations and unions. |
185 | Adt { | 184 | Adt { |
186 | /// The DefId of the struct/enum. | 185 | /// The DefId of the struct/enum. |
187 | def_id: DefId, | 186 | def_id: AdtDef, |
188 | /// The name, for displaying. | 187 | /// The name, for displaying. |
189 | name: Name, | 188 | name: Name, |
190 | /// Substitutions for the generic parameters of the type. | 189 | /// Substitutions for the generic parameters of the type. |
@@ -381,12 +380,16 @@ impl Ty { | |||
381 | } | 380 | } |
382 | 381 | ||
383 | // Resolve in module (in type namespace) | 382 | // Resolve in module (in type namespace) |
384 | let resolved = match module.resolve_path(db, path).take_types() { | 383 | let typable: TypableDef = match module |
385 | Some(r) => r, | 384 | .resolve_path(db, path) |
385 | .take_types() | ||
386 | .and_then(|it| it.into()) | ||
387 | { | ||
386 | None => return Ty::Unknown, | 388 | None => return Ty::Unknown, |
389 | Some(it) => it, | ||
387 | }; | 390 | }; |
388 | let ty = db.type_for_def(resolved); | 391 | let ty = db.type_for_def(typable); |
389 | let substs = Ty::substs_from_path(db, module, impl_block, generics, path, resolved); | 392 | let substs = Ty::substs_from_path(db, module, impl_block, generics, path, typable); |
390 | ty.apply_substs(substs) | 393 | ty.apply_substs(substs) |
391 | } | 394 | } |
392 | 395 | ||
@@ -399,20 +402,18 @@ impl Ty { | |||
399 | impl_block: Option<&ImplBlock>, | 402 | impl_block: Option<&ImplBlock>, |
400 | outer_generics: &GenericParams, | 403 | outer_generics: &GenericParams, |
401 | path: &Path, | 404 | path: &Path, |
402 | resolved: DefId, | 405 | resolved: TypableDef, |
403 | ) -> Substs { | 406 | ) -> Substs { |
404 | let mut substs = Vec::new(); | 407 | let mut substs = Vec::new(); |
405 | let def = resolved.resolve(db); | ||
406 | let last = path | 408 | let last = path |
407 | .segments | 409 | .segments |
408 | .last() | 410 | .last() |
409 | .expect("path should have at least one segment"); | 411 | .expect("path should have at least one segment"); |
410 | let (def_generics, segment) = match def { | 412 | let (def_generics, segment) = match resolved { |
411 | Def::Struct(s) => (s.generic_params(db), last), | 413 | TypableDef::Function(func) => (func.generic_params(db), last), |
412 | Def::Enum(e) => (e.generic_params(db), last), | 414 | TypableDef::Struct(s) => (s.generic_params(db), last), |
413 | Def::Function(f) => (f.generic_params(db), last), | 415 | TypableDef::Enum(e) => (e.generic_params(db), last), |
414 | Def::Trait(t) => (t.generic_params(db), last), | 416 | TypableDef::EnumVariant(var) => { |
415 | Def::EnumVariant(ev) => { | ||
416 | // the generic args for an enum variant may be either specified | 417 | // the generic args for an enum variant may be either specified |
417 | // on the segment referring to the enum, or on the segment | 418 | // on the segment referring to the enum, or on the segment |
418 | // referring to the variant. So `Option::<T>::None` and | 419 | // referring to the variant. So `Option::<T>::None` and |
@@ -426,9 +427,8 @@ impl Ty { | |||
426 | // Option::None::<T> | 427 | // Option::None::<T> |
427 | last | 428 | last |
428 | }; | 429 | }; |
429 | (ev.parent_enum(db).generic_params(db), segment) | 430 | (var.parent_enum(db).generic_params(db), segment) |
430 | } | 431 | } |
431 | _ => return Substs::empty(), | ||
432 | }; | 432 | }; |
433 | // substs_from_path | 433 | // substs_from_path |
434 | if let Some(generic_args) = &segment.args_and_bindings { | 434 | if let Some(generic_args) = &segment.args_and_bindings { |
@@ -639,7 +639,7 @@ fn make_substs(generics: &GenericParams) -> Substs { | |||
639 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { | 639 | fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { |
640 | let generics = s.generic_params(db); | 640 | let generics = s.generic_params(db); |
641 | Ty::Adt { | 641 | Ty::Adt { |
642 | def_id: s.def_id(), | 642 | def_id: s.into(), |
643 | name: s.name(db).unwrap_or_else(Name::missing), | 643 | name: s.name(db).unwrap_or_else(Name::missing), |
644 | substs: make_substs(&generics), | 644 | substs: make_substs(&generics), |
645 | } | 645 | } |
@@ -648,7 +648,7 @@ fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { | |||
648 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { | 648 | pub(crate) fn type_for_enum(db: &impl HirDatabase, s: Enum) -> Ty { |
649 | let generics = s.generic_params(db); | 649 | let generics = s.generic_params(db); |
650 | Ty::Adt { | 650 | Ty::Adt { |
651 | def_id: s.def_id(), | 651 | def_id: s.into(), |
652 | name: s.name(db).unwrap_or_else(Name::missing), | 652 | name: s.name(db).unwrap_or_else(Name::missing), |
653 | substs: make_substs(&generics), | 653 | substs: make_substs(&generics), |
654 | } | 654 | } |
@@ -660,66 +660,74 @@ pub(crate) fn type_for_enum_variant(db: &impl HirDatabase, ev: EnumVariant) -> T | |||
660 | type_for_enum(db, enum_parent) | 660 | type_for_enum(db, enum_parent) |
661 | } | 661 | } |
662 | 662 | ||
663 | pub(super) fn type_for_def(db: &impl HirDatabase, def_id: DefId) -> Ty { | 663 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
664 | let def = def_id.resolve(db); | 664 | pub enum TypableDef { |
665 | Function(Function), | ||
666 | Struct(Struct), | ||
667 | Enum(Enum), | ||
668 | EnumVariant(EnumVariant), | ||
669 | } | ||
670 | impl_froms!(TypableDef: Function, Struct, Enum, EnumVariant); | ||
671 | |||
672 | impl From<ModuleDef> for Option<TypableDef> { | ||
673 | fn from(def: ModuleDef) -> Option<TypableDef> { | ||
674 | let res = match def { | ||
675 | ModuleDef::Function(f) => f.into(), | ||
676 | ModuleDef::Struct(s) => s.into(), | ||
677 | ModuleDef::Enum(e) => e.into(), | ||
678 | ModuleDef::EnumVariant(v) => v.into(), | ||
679 | ModuleDef::Const(_) | ||
680 | | ModuleDef::Static(_) | ||
681 | | ModuleDef::Module(_) | ||
682 | | ModuleDef::Trait(_) | ||
683 | | ModuleDef::Type(_) => return None, | ||
684 | }; | ||
685 | Some(res) | ||
686 | } | ||
687 | } | ||
688 | |||
689 | pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { | ||
665 | match def { | 690 | match def { |
666 | Def::Module(..) => { | 691 | TypableDef::Function(f) => type_for_fn(db, f), |
667 | log::debug!("trying to get type for module {:?}", def_id); | 692 | TypableDef::Struct(s) => type_for_struct(db, s), |
668 | Ty::Unknown | 693 | TypableDef::Enum(e) => type_for_enum(db, e), |
669 | } | 694 | TypableDef::EnumVariant(v) => type_for_enum_variant(db, v), |
670 | Def::Function(f) => type_for_fn(db, f), | ||
671 | Def::Struct(s) => type_for_struct(db, s), | ||
672 | Def::Enum(e) => type_for_enum(db, e), | ||
673 | Def::EnumVariant(ev) => type_for_enum_variant(db, ev), | ||
674 | _ => { | ||
675 | log::debug!( | ||
676 | "trying to get type for item of unknown type {:?} {:?}", | ||
677 | def_id, | ||
678 | def | ||
679 | ); | ||
680 | Ty::Unknown | ||
681 | } | ||
682 | } | 695 | } |
683 | } | 696 | } |
684 | 697 | ||
685 | pub(super) fn type_for_field(db: &impl HirDatabase, def_id: DefId, field: Name) -> Option<Ty> { | 698 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
686 | let def = def_id.resolve(db); | 699 | pub enum VariantDef { |
687 | let (variant_data, generics) = match def { | 700 | Struct(Struct), |
688 | Def::Struct(s) => (s.variant_data(db), s.generic_params(db)), | 701 | EnumVariant(EnumVariant), |
689 | Def::EnumVariant(ev) => (ev.variant_data(db), ev.parent_enum(db).generic_params(db)), | 702 | } |
690 | // TODO: unions | 703 | impl_froms!(VariantDef: Struct, EnumVariant); |
691 | Def::Enum(_) => { | 704 | |
692 | // this can happen in (invalid) code, but enums don't have fields themselves | 705 | pub(super) fn type_for_field(db: &impl HirDatabase, def: VariantDef, field: Name) -> Option<Ty> { |
693 | return None; | 706 | let (variant_data, generics, module) = match def { |
694 | } | 707 | VariantDef::Struct(s) => (s.variant_data(db), s.generic_params(db), s.module(db)), |
695 | _ => panic!( | 708 | VariantDef::EnumVariant(var) => ( |
696 | "trying to get type for field {:?} in non-struct/variant {:?}", | 709 | var.variant_data(db), |
697 | field, def_id | 710 | var.parent_enum(db).generic_params(db), |
711 | var.module(db), | ||
698 | ), | 712 | ), |
699 | }; | 713 | }; |
700 | let module = def_id.module(db); | 714 | // We can't have an impl block ere, right? |
701 | let impl_block = def_id.impl_block(db); | 715 | // let impl_block = def_id.impl_block(db); |
702 | let type_ref = variant_data.get_field_type_ref(&field)?; | 716 | let type_ref = variant_data.get_field_type_ref(&field)?; |
703 | Some(Ty::from_hir( | 717 | Some(Ty::from_hir(db, &module, None, &generics, &type_ref)) |
704 | db, | ||
705 | &module, | ||
706 | impl_block.as_ref(), | ||
707 | &generics, | ||
708 | &type_ref, | ||
709 | )) | ||
710 | } | 718 | } |
711 | 719 | ||
712 | /// The result of type inference: A mapping from expressions and patterns to types. | 720 | /// The result of type inference: A mapping from expressions and patterns to types. |
713 | #[derive(Clone, PartialEq, Eq, Debug)] | 721 | #[derive(Clone, PartialEq, Eq, Debug)] |
714 | pub struct InferenceResult { | 722 | pub struct InferenceResult { |
715 | /// For each method call expr, record the function it resolved to. | 723 | /// For each method call expr, record the function it resolved to. |
716 | method_resolutions: FxHashMap<ExprId, DefId>, | 724 | method_resolutions: FxHashMap<ExprId, Function>, |
717 | type_of_expr: ArenaMap<ExprId, Ty>, | 725 | type_of_expr: ArenaMap<ExprId, Ty>, |
718 | type_of_pat: ArenaMap<PatId, Ty>, | 726 | type_of_pat: ArenaMap<PatId, Ty>, |
719 | } | 727 | } |
720 | 728 | ||
721 | impl InferenceResult { | 729 | impl InferenceResult { |
722 | pub fn method_resolution(&self, expr: ExprId) -> Option<DefId> { | 730 | pub fn method_resolution(&self, expr: ExprId) -> Option<Function> { |
723 | self.method_resolutions.get(&expr).map(|it| *it) | 731 | self.method_resolutions.get(&expr).map(|it| *it) |
724 | } | 732 | } |
725 | } | 733 | } |
@@ -749,7 +757,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
749 | module: Module, | 757 | module: Module, |
750 | impl_block: Option<ImplBlock>, | 758 | impl_block: Option<ImplBlock>, |
751 | var_unification_table: InPlaceUnificationTable<TypeVarId>, | 759 | var_unification_table: InPlaceUnificationTable<TypeVarId>, |
752 | method_resolutions: FxHashMap<ExprId, DefId>, | 760 | method_resolutions: FxHashMap<ExprId, Function>, |
753 | type_of_expr: ArenaMap<ExprId, Ty>, | 761 | type_of_expr: ArenaMap<ExprId, Ty>, |
754 | type_of_pat: ArenaMap<PatId, Ty>, | 762 | type_of_pat: ArenaMap<PatId, Ty>, |
755 | /// The return type of the function being inferred. | 763 | /// The return type of the function being inferred. |
@@ -875,8 +883,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
875 | self.type_of_expr.insert(expr, ty); | 883 | self.type_of_expr.insert(expr, ty); |
876 | } | 884 | } |
877 | 885 | ||
878 | fn write_method_resolution(&mut self, expr: ExprId, def_id: DefId) { | 886 | fn write_method_resolution(&mut self, expr: ExprId, func: Function) { |
879 | self.method_resolutions.insert(expr, def_id); | 887 | self.method_resolutions.insert(expr, func); |
880 | } | 888 | } |
881 | 889 | ||
882 | fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { | 890 | fn write_pat_ty(&mut self, pat: PatId, ty: Ty) { |
@@ -1063,20 +1071,30 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1063 | }; | 1071 | }; |
1064 | 1072 | ||
1065 | // resolve in module | 1073 | // resolve in module |
1066 | let resolved = self.module.resolve_path(self.db, &path).take_values()?; | 1074 | let typable: Option<TypableDef> = self |
1067 | let ty = self.db.type_for_def(resolved); | 1075 | .module |
1076 | .resolve_path(self.db, &path) | ||
1077 | .take_values()? | ||
1078 | .into(); | ||
1079 | let typable = typable?; | ||
1080 | let ty = self.db.type_for_def(typable); | ||
1068 | let ty = self.insert_type_vars(ty); | 1081 | let ty = self.insert_type_vars(ty); |
1069 | Some(ty) | 1082 | Some(ty) |
1070 | } | 1083 | } |
1071 | 1084 | ||
1072 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<DefId>) { | 1085 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) { |
1073 | let path = match path { | 1086 | let path = match path { |
1074 | Some(path) => path, | 1087 | Some(path) => path, |
1075 | None => return (Ty::Unknown, None), | 1088 | None => return (Ty::Unknown, None), |
1076 | }; | 1089 | }; |
1077 | let def_id = match self.module.resolve_path(self.db, &path).take_types() { | 1090 | let typable: Option<TypableDef> = self |
1078 | Some(def_id) => def_id, | 1091 | .module |
1079 | _ => return (Ty::Unknown, None), | 1092 | .resolve_path(self.db, &path) |
1093 | .take_types() | ||
1094 | .and_then(|it| it.into()); | ||
1095 | let def = match typable { | ||
1096 | None => return (Ty::Unknown, None), | ||
1097 | Some(it) => it, | ||
1080 | }; | 1098 | }; |
1081 | // TODO remove the duplication between here and `Ty::from_path`? | 1099 | // TODO remove the duplication between here and `Ty::from_path`? |
1082 | // TODO provide generics of function | 1100 | // TODO provide generics of function |
@@ -1087,38 +1105,34 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1087 | self.impl_block.as_ref(), | 1105 | self.impl_block.as_ref(), |
1088 | &generics, | 1106 | &generics, |
1089 | path, | 1107 | path, |
1090 | def_id, | 1108 | def, |
1091 | ); | 1109 | ); |
1092 | match def_id.resolve(self.db) { | 1110 | match def { |
1093 | Def::Struct(s) => { | 1111 | TypableDef::Struct(s) => { |
1094 | let ty = type_for_struct(self.db, s); | 1112 | let ty = type_for_struct(self.db, s); |
1095 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | 1113 | let ty = self.insert_type_vars(ty.apply_substs(substs)); |
1096 | (ty, Some(def_id)) | 1114 | (ty, Some(s.into())) |
1097 | } | 1115 | } |
1098 | Def::EnumVariant(ev) => { | 1116 | TypableDef::EnumVariant(var) => { |
1099 | let ty = type_for_enum_variant(self.db, ev); | 1117 | let ty = type_for_enum_variant(self.db, var); |
1100 | let ty = self.insert_type_vars(ty.apply_substs(substs)); | 1118 | let ty = self.insert_type_vars(ty.apply_substs(substs)); |
1101 | (ty, Some(def_id)) | 1119 | (ty, Some(var.into())) |
1102 | } | 1120 | } |
1103 | _ => (Ty::Unknown, None), | 1121 | TypableDef::Enum(_) | TypableDef::Function(_) => (Ty::Unknown, None), |
1104 | } | 1122 | } |
1105 | } | 1123 | } |
1106 | 1124 | ||
1107 | fn resolve_fields(&mut self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> { | 1125 | fn resolve_fields(&mut self, path: Option<&Path>) -> Option<(Ty, Vec<StructField>)> { |
1108 | let (ty, def_id) = self.resolve_variant(path); | 1126 | let (ty, def) = self.resolve_variant(path); |
1109 | let def_id = def_id?; | 1127 | match def? { |
1110 | let def = def_id.resolve(self.db); | 1128 | VariantDef::Struct(s) => { |
1111 | |||
1112 | match def { | ||
1113 | Def::Struct(s) => { | ||
1114 | let fields = s.fields(self.db); | 1129 | let fields = s.fields(self.db); |
1115 | Some((ty, fields)) | 1130 | Some((ty, fields)) |
1116 | } | 1131 | } |
1117 | Def::EnumVariant(ev) => { | 1132 | VariantDef::EnumVariant(var) => { |
1118 | let fields = ev.fields(self.db); | 1133 | let fields = var.fields(self.db); |
1119 | Some((ty, fields)) | 1134 | Some((ty, fields)) |
1120 | } | 1135 | } |
1121 | _ => None, | ||
1122 | } | 1136 | } |
1123 | } | 1137 | } |
1124 | 1138 | ||
@@ -1216,6 +1230,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1216 | .module | 1230 | .module |
1217 | .resolve_path(self.db, &path) | 1231 | .resolve_path(self.db, &path) |
1218 | .take_values() | 1232 | .take_values() |
1233 | .and_then(|module_def| module_def.into()) | ||
1219 | .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), | 1234 | .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), |
1220 | Pat::Bind { | 1235 | Pat::Bind { |
1221 | mode, | 1236 | mode, |
@@ -1336,9 +1351,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1336 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); | 1351 | let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); |
1337 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); | 1352 | let resolved = receiver_ty.clone().lookup_method(self.db, method_name); |
1338 | let method_ty = match resolved { | 1353 | let method_ty = match resolved { |
1339 | Some(def_id) => { | 1354 | Some(func) => { |
1340 | self.write_method_resolution(expr, def_id); | 1355 | self.write_method_resolution(expr, func); |
1341 | self.db.type_for_def(def_id) | 1356 | self.db.type_for_def(func.into()) |
1342 | } | 1357 | } |
1343 | None => Ty::Unknown, | 1358 | None => Ty::Unknown, |
1344 | }; | 1359 | }; |
@@ -1407,7 +1422,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1407 | for field in fields { | 1422 | for field in fields { |
1408 | let field_ty = if let Some(def_id) = def_id { | 1423 | let field_ty = if let Some(def_id) = def_id { |
1409 | self.db | 1424 | self.db |
1410 | .type_for_field(def_id, field.name.clone()) | 1425 | .type_for_field(def_id.into(), field.name.clone()) |
1411 | .unwrap_or(Ty::Unknown) | 1426 | .unwrap_or(Ty::Unknown) |
1412 | .subst(&substs) | 1427 | .subst(&substs) |
1413 | } else { | 1428 | } else { |
@@ -1431,10 +1446,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1431 | i.and_then(|i| fields.get(i).cloned()) | 1446 | i.and_then(|i| fields.get(i).cloned()) |
1432 | } | 1447 | } |
1433 | Ty::Adt { | 1448 | Ty::Adt { |
1434 | def_id, ref substs, .. | 1449 | def_id: AdtDef::Struct(s), |
1450 | ref substs, | ||
1451 | .. | ||
1435 | } => self | 1452 | } => self |
1436 | .db | 1453 | .db |
1437 | .type_for_field(def_id, name.clone()) | 1454 | .type_for_field(s.into(), name.clone()) |
1438 | .map(|ty| ty.subst(substs)), | 1455 | .map(|ty| ty.subst(substs)), |
1439 | _ => None, | 1456 | _ => None, |
1440 | }) | 1457 | }) |
@@ -1607,16 +1624,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1607 | } | 1624 | } |
1608 | } | 1625 | } |
1609 | 1626 | ||
1610 | pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Arc<InferenceResult> { | 1627 | pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> { |
1611 | db.check_canceled(); | 1628 | db.check_canceled(); |
1612 | let function = Function::new(def_id); // TODO: consts also need inference | 1629 | let body = func.body(db); |
1613 | let body = function.body(db); | 1630 | let scopes = db.fn_scopes(func); |
1614 | let scopes = db.fn_scopes(def_id); | 1631 | let module = func.module(db); |
1615 | let module = function.module(db); | 1632 | let impl_block = func.impl_block(db); |
1616 | let impl_block = function.impl_block(db); | ||
1617 | let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); | 1633 | let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); |
1618 | 1634 | ||
1619 | let signature = function.signature(db); | 1635 | let signature = func.signature(db); |
1620 | ctx.collect_fn_signature(&signature); | 1636 | ctx.collect_fn_signature(&signature); |
1621 | 1637 | ||
1622 | ctx.infer_body(); | 1638 | ctx.infer_body(); |