diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-01 22:37:59 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-01 22:37:59 +0000 |
commit | 4447019f4b5f24728bb7b91b161755ddb373c74c (patch) | |
tree | c53ff3531cbbad182e821eb92fa9ad201d2bff0c /crates/ra_hir/src/ty.rs | |
parent | 2b5c226e86892113bcab478cdf4c9adaf1e7b2f6 (diff) | |
parent | c5852f422ff45adaa21815c1a15e03b067a56a82 (diff) |
Merge #693
693: Name resolution refactoring r=matklad a=flodiebold
This is still very WIP, but it's becoming quite big and I want to make sure this isn't going in a completely bad direction :sweat_smile:. I'm not really happy with how the path resolution looks, and I'm not sure `PerNs<Resolution>` is the best return type -- there are 'this cannot happen in the (types/values) namespace' cases everywhere. I also want to unify the `resolver` and `nameres` namespaces once I'm done switching everything to `Resolver`. Also, `Resolver` only has a lifetime because it needs to have a reference to the `ItemMap` during import resolution :confused:
The differences in the completion snapshots are almost completely just ordering (except it completes `Self` as well now), so I changed it to sort the completions before snapshotting.
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r-- | crates/ra_hir/src/ty.rs | 270 |
1 files changed, 113 insertions, 157 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index d3e31981a..cc5afad75 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -33,15 +33,16 @@ use rustc_hash::FxHashMap; | |||
33 | use test_utils::tested_by; | 33 | use test_utils::tested_by; |
34 | 34 | ||
35 | use crate::{ | 35 | use crate::{ |
36 | Module, Function, Struct, StructField, Enum, EnumVariant, Path, Name, ImplBlock, | 36 | Function, Struct, StructField, Enum, EnumVariant, Path, Name, |
37 | FnSignature, ExprScopes, ModuleDef, AdtDef, | 37 | FnSignature, ModuleDef, AdtDef, |
38 | HirDatabase, | 38 | HirDatabase, |
39 | type_ref::{TypeRef, Mutability}, | 39 | type_ref::{TypeRef, Mutability}, |
40 | name::KnownName, | 40 | name::KnownName, |
41 | expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat}, | 41 | expr::{Body, Expr, BindingAnnotation, Literal, ExprId, Pat, PatId, UnaryOp, BinaryOp, Statement, FieldPat, self}, |
42 | generics::GenericParams, | 42 | generics::GenericParams, |
43 | path::GenericArg, | 43 | path::GenericArg, |
44 | adt::VariantDef, | 44 | adt::VariantDef, |
45 | resolve::{Resolver, Resolution}, | ||
45 | }; | 46 | }; |
46 | 47 | ||
47 | /// The ID of a type variable. | 48 | /// The ID of a type variable. |
@@ -300,47 +301,38 @@ pub struct FnSig { | |||
300 | } | 301 | } |
301 | 302 | ||
302 | impl Ty { | 303 | impl Ty { |
303 | pub(crate) fn from_hir( | 304 | pub(crate) fn from_hir(db: &impl HirDatabase, resolver: &Resolver, type_ref: &TypeRef) -> Self { |
304 | db: &impl HirDatabase, | ||
305 | // TODO: the next three parameters basically describe the scope for name | ||
306 | // resolution; this should be refactored into something like a general | ||
307 | // resolver architecture | ||
308 | module: &Module, | ||
309 | impl_block: Option<&ImplBlock>, | ||
310 | generics: &GenericParams, | ||
311 | type_ref: &TypeRef, | ||
312 | ) -> Self { | ||
313 | match type_ref { | 305 | match type_ref { |
314 | TypeRef::Never => Ty::Never, | 306 | TypeRef::Never => Ty::Never, |
315 | TypeRef::Tuple(inner) => { | 307 | TypeRef::Tuple(inner) => { |
316 | let inner_tys = inner | 308 | let inner_tys = inner |
317 | .iter() | 309 | .iter() |
318 | .map(|tr| Ty::from_hir(db, module, impl_block, generics, tr)) | 310 | .map(|tr| Ty::from_hir(db, resolver, tr)) |
319 | .collect::<Vec<_>>(); | 311 | .collect::<Vec<_>>(); |
320 | Ty::Tuple(inner_tys.into()) | 312 | Ty::Tuple(inner_tys.into()) |
321 | } | 313 | } |
322 | TypeRef::Path(path) => Ty::from_hir_path(db, module, impl_block, generics, path), | 314 | TypeRef::Path(path) => Ty::from_hir_path(db, resolver, path), |
323 | TypeRef::RawPtr(inner, mutability) => { | 315 | TypeRef::RawPtr(inner, mutability) => { |
324 | let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); | 316 | let inner_ty = Ty::from_hir(db, resolver, inner); |
325 | Ty::RawPtr(Arc::new(inner_ty), *mutability) | 317 | Ty::RawPtr(Arc::new(inner_ty), *mutability) |
326 | } | 318 | } |
327 | TypeRef::Array(inner) => { | 319 | TypeRef::Array(inner) => { |
328 | let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); | 320 | let inner_ty = Ty::from_hir(db, resolver, inner); |
329 | Ty::Array(Arc::new(inner_ty)) | 321 | Ty::Array(Arc::new(inner_ty)) |
330 | } | 322 | } |
331 | TypeRef::Slice(inner) => { | 323 | TypeRef::Slice(inner) => { |
332 | let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); | 324 | let inner_ty = Ty::from_hir(db, resolver, inner); |
333 | Ty::Slice(Arc::new(inner_ty)) | 325 | Ty::Slice(Arc::new(inner_ty)) |
334 | } | 326 | } |
335 | TypeRef::Reference(inner, mutability) => { | 327 | TypeRef::Reference(inner, mutability) => { |
336 | let inner_ty = Ty::from_hir(db, module, impl_block, generics, inner); | 328 | let inner_ty = Ty::from_hir(db, resolver, inner); |
337 | Ty::Ref(Arc::new(inner_ty), *mutability) | 329 | Ty::Ref(Arc::new(inner_ty), *mutability) |
338 | } | 330 | } |
339 | TypeRef::Placeholder => Ty::Unknown, | 331 | TypeRef::Placeholder => Ty::Unknown, |
340 | TypeRef::Fn(params) => { | 332 | TypeRef::Fn(params) => { |
341 | let mut inner_tys = params | 333 | let mut inner_tys = params |
342 | .iter() | 334 | .iter() |
343 | .map(|tr| Ty::from_hir(db, module, impl_block, generics, tr)) | 335 | .map(|tr| Ty::from_hir(db, resolver, tr)) |
344 | .collect::<Vec<_>>(); | 336 | .collect::<Vec<_>>(); |
345 | let return_ty = inner_tys | 337 | let return_ty = inner_tys |
346 | .pop() | 338 | .pop() |
@@ -355,40 +347,13 @@ impl Ty { | |||
355 | } | 347 | } |
356 | } | 348 | } |
357 | 349 | ||
358 | pub(crate) fn from_hir_opt( | 350 | pub(crate) fn from_hir_path(db: &impl HirDatabase, resolver: &Resolver, path: &Path) -> Self { |
359 | db: &impl HirDatabase, | ||
360 | module: &Module, | ||
361 | impl_block: Option<&ImplBlock>, | ||
362 | generics: &GenericParams, | ||
363 | type_ref: Option<&TypeRef>, | ||
364 | ) -> Self { | ||
365 | type_ref.map_or(Ty::Unknown, |t| { | ||
366 | Ty::from_hir(db, module, impl_block, generics, t) | ||
367 | }) | ||
368 | } | ||
369 | |||
370 | pub(crate) fn from_hir_path( | ||
371 | db: &impl HirDatabase, | ||
372 | module: &Module, | ||
373 | impl_block: Option<&ImplBlock>, | ||
374 | generics: &GenericParams, | ||
375 | path: &Path, | ||
376 | ) -> Self { | ||
377 | if let Some(name) = path.as_ident() { | 351 | if let Some(name) = path.as_ident() { |
352 | // TODO handle primitive type names in resolver as well? | ||
378 | if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { | 353 | if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { |
379 | return Ty::Int(int_ty); | 354 | return Ty::Int(int_ty); |
380 | } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { | 355 | } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { |
381 | return Ty::Float(float_ty); | 356 | return Ty::Float(float_ty); |
382 | } else if name.as_known_name() == Some(KnownName::SelfType) { | ||
383 | // TODO pass the impl block's generics? | ||
384 | let generics = &GenericParams::default(); | ||
385 | return Ty::from_hir_opt( | ||
386 | db, | ||
387 | module, | ||
388 | None, | ||
389 | generics, | ||
390 | impl_block.map(|i| i.target_type()), | ||
391 | ); | ||
392 | } else if let Some(known) = name.as_known_name() { | 357 | } else if let Some(known) = name.as_known_name() { |
393 | match known { | 358 | match known { |
394 | KnownName::Bool => return Ty::Bool, | 359 | KnownName::Bool => return Ty::Bool, |
@@ -396,25 +361,40 @@ impl Ty { | |||
396 | KnownName::Str => return Ty::Str, | 361 | KnownName::Str => return Ty::Str, |
397 | _ => {} | 362 | _ => {} |
398 | } | 363 | } |
399 | } else if let Some(generic_param) = generics.find_by_name(&name) { | 364 | } |
365 | } | ||
366 | |||
367 | // Resolve the path (in type namespace) | ||
368 | let resolution = resolver.resolve_path(db, path).take_types(); | ||
369 | |||
370 | let def = match resolution { | ||
371 | Some(Resolution::Def(def)) => def, | ||
372 | Some(Resolution::LocalBinding(..)) => { | ||
373 | // this should never happen | ||
374 | panic!("path resolved to local binding in type ns"); | ||
375 | } | ||
376 | Some(Resolution::GenericParam(idx)) => { | ||
400 | return Ty::Param { | 377 | return Ty::Param { |
401 | idx: generic_param.idx, | 378 | idx, |
402 | name: generic_param.name.clone(), | 379 | // TODO: maybe return name in resolution? |
380 | name: path | ||
381 | .as_ident() | ||
382 | .expect("generic param should be single-segment path") | ||
383 | .clone(), | ||
403 | }; | 384 | }; |
404 | } | 385 | } |
405 | } | 386 | Some(Resolution::SelfType(impl_block)) => { |
387 | return impl_block.target_ty(db); | ||
388 | } | ||
389 | None => return Ty::Unknown, | ||
390 | }; | ||
406 | 391 | ||
407 | // Resolve in module (in type namespace) | 392 | let typable: TypableDef = match def.into() { |
408 | let typable: TypableDef = match module | ||
409 | .resolve_path(db, path) | ||
410 | .take_types() | ||
411 | .and_then(|it| it.into()) | ||
412 | { | ||
413 | None => return Ty::Unknown, | 393 | None => return Ty::Unknown, |
414 | Some(it) => it, | 394 | Some(it) => it, |
415 | }; | 395 | }; |
416 | let ty = db.type_for_def(typable); | 396 | let ty = db.type_for_def(typable); |
417 | let substs = Ty::substs_from_path(db, module, impl_block, generics, path, typable); | 397 | let substs = Ty::substs_from_path(db, resolver, path, typable); |
418 | ty.apply_substs(substs) | 398 | ty.apply_substs(substs) |
419 | } | 399 | } |
420 | 400 | ||
@@ -422,10 +402,7 @@ impl Ty { | |||
422 | /// `create_substs_for_ast_path` and `def_to_ty` in rustc. | 402 | /// `create_substs_for_ast_path` and `def_to_ty` in rustc. |
423 | fn substs_from_path( | 403 | fn substs_from_path( |
424 | db: &impl HirDatabase, | 404 | db: &impl HirDatabase, |
425 | // the scope of the segment... | 405 | resolver: &Resolver, |
426 | module: &Module, | ||
427 | impl_block: Option<&ImplBlock>, | ||
428 | outer_generics: &GenericParams, | ||
429 | path: &Path, | 406 | path: &Path, |
430 | resolved: TypableDef, | 407 | resolved: TypableDef, |
431 | ) -> Substs { | 408 | ) -> Substs { |
@@ -462,7 +439,7 @@ impl Ty { | |||
462 | for arg in generic_args.args.iter().take(param_count) { | 439 | for arg in generic_args.args.iter().take(param_count) { |
463 | match arg { | 440 | match arg { |
464 | GenericArg::Type(type_ref) => { | 441 | GenericArg::Type(type_ref) => { |
465 | let ty = Ty::from_hir(db, module, impl_block, outer_generics, type_ref); | 442 | let ty = Ty::from_hir(db, resolver, type_ref); |
466 | substs.push(ty); | 443 | substs.push(ty); |
467 | } | 444 | } |
468 | } | 445 | } |
@@ -666,24 +643,17 @@ impl fmt::Display for Ty { | |||
666 | /// function body. | 643 | /// function body. |
667 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { | 644 | fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { |
668 | let signature = def.signature(db); | 645 | let signature = def.signature(db); |
669 | let module = def.module(db); | 646 | let resolver = def.resolver(db); |
670 | let impl_block = def.impl_block(db); | ||
671 | let generics = def.generic_params(db); | 647 | let generics = def.generic_params(db); |
648 | let name = def.name(db); | ||
672 | let input = signature | 649 | let input = signature |
673 | .params() | 650 | .params() |
674 | .iter() | 651 | .iter() |
675 | .map(|tr| Ty::from_hir(db, &module, impl_block.as_ref(), &generics, tr)) | 652 | .map(|tr| Ty::from_hir(db, &resolver, tr)) |
676 | .collect::<Vec<_>>(); | 653 | .collect::<Vec<_>>(); |
677 | let output = Ty::from_hir( | 654 | let output = Ty::from_hir(db, &resolver, signature.ret_type()); |
678 | db, | ||
679 | &module, | ||
680 | impl_block.as_ref(), | ||
681 | &generics, | ||
682 | signature.ret_type(), | ||
683 | ); | ||
684 | let sig = Arc::new(FnSig { input, output }); | 655 | let sig = Arc::new(FnSig { input, output }); |
685 | let substs = make_substs(&generics); | 656 | let substs = make_substs(&generics); |
686 | let name = def.name(db); | ||
687 | Ty::FnDef { | 657 | Ty::FnDef { |
688 | def, | 658 | def, |
689 | sig, | 659 | sig, |
@@ -764,13 +734,13 @@ pub(super) fn type_for_def(db: &impl HirDatabase, def: TypableDef) -> Ty { | |||
764 | 734 | ||
765 | pub(super) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { | 735 | pub(super) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { |
766 | let parent_def = field.parent_def(db); | 736 | let parent_def = field.parent_def(db); |
767 | let (generics, module) = match parent_def { | 737 | let resolver = match parent_def { |
768 | VariantDef::Struct(it) => (it.generic_params(db), it.module(db)), | 738 | VariantDef::Struct(it) => it.resolver(db), |
769 | VariantDef::EnumVariant(it) => (it.parent_enum(db).generic_params(db), it.module(db)), | 739 | VariantDef::EnumVariant(it) => it.parent_enum(db).resolver(db), |
770 | }; | 740 | }; |
771 | let var_data = parent_def.variant_data(db); | 741 | let var_data = parent_def.variant_data(db); |
772 | let type_ref = &var_data.fields().unwrap()[field.id].type_ref; | 742 | let type_ref = &var_data.fields().unwrap()[field.id].type_ref; |
773 | Ty::from_hir(db, &module, None, &generics, type_ref) | 743 | Ty::from_hir(db, &resolver, type_ref) |
774 | } | 744 | } |
775 | 745 | ||
776 | /// The result of type inference: A mapping from expressions and patterns to types. | 746 | /// The result of type inference: A mapping from expressions and patterns to types. |
@@ -814,9 +784,7 @@ impl Index<PatId> for InferenceResult { | |||
814 | struct InferenceContext<'a, D: HirDatabase> { | 784 | struct InferenceContext<'a, D: HirDatabase> { |
815 | db: &'a D, | 785 | db: &'a D, |
816 | body: Arc<Body>, | 786 | body: Arc<Body>, |
817 | scopes: Arc<ExprScopes>, | 787 | resolver: Resolver, |
818 | module: Module, | ||
819 | impl_block: Option<ImplBlock>, | ||
820 | var_unification_table: InPlaceUnificationTable<TypeVarId>, | 788 | var_unification_table: InPlaceUnificationTable<TypeVarId>, |
821 | method_resolutions: FxHashMap<ExprId, Function>, | 789 | method_resolutions: FxHashMap<ExprId, Function>, |
822 | field_resolutions: FxHashMap<ExprId, StructField>, | 790 | field_resolutions: FxHashMap<ExprId, StructField>, |
@@ -905,13 +873,7 @@ fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { | |||
905 | } | 873 | } |
906 | 874 | ||
907 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 875 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
908 | fn new( | 876 | fn new(db: &'a D, body: Arc<Body>, resolver: Resolver) -> Self { |
909 | db: &'a D, | ||
910 | body: Arc<Body>, | ||
911 | scopes: Arc<ExprScopes>, | ||
912 | module: Module, | ||
913 | impl_block: Option<ImplBlock>, | ||
914 | ) -> Self { | ||
915 | InferenceContext { | 877 | InferenceContext { |
916 | method_resolutions: FxHashMap::default(), | 878 | method_resolutions: FxHashMap::default(), |
917 | field_resolutions: FxHashMap::default(), | 879 | field_resolutions: FxHashMap::default(), |
@@ -921,9 +883,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
921 | return_ty: Ty::Unknown, // set in collect_fn_signature | 883 | return_ty: Ty::Unknown, // set in collect_fn_signature |
922 | db, | 884 | db, |
923 | body, | 885 | body, |
924 | scopes, | 886 | resolver, |
925 | module, | ||
926 | impl_block, | ||
927 | } | 887 | } |
928 | } | 888 | } |
929 | 889 | ||
@@ -940,8 +900,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
940 | *ty = resolved; | 900 | *ty = resolved; |
941 | } | 901 | } |
942 | InferenceResult { | 902 | InferenceResult { |
943 | method_resolutions: mem::replace(&mut self.method_resolutions, Default::default()), | 903 | method_resolutions: self.method_resolutions, |
944 | field_resolutions: mem::replace(&mut self.field_resolutions, Default::default()), | 904 | field_resolutions: self.field_resolutions, |
945 | type_of_expr: expr_types, | 905 | type_of_expr: expr_types, |
946 | type_of_pat: pat_types, | 906 | type_of_pat: pat_types, |
947 | } | 907 | } |
@@ -964,13 +924,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
964 | } | 924 | } |
965 | 925 | ||
966 | fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { | 926 | fn make_ty(&mut self, type_ref: &TypeRef) -> Ty { |
967 | // TODO provide generics of function | ||
968 | let generics = GenericParams::default(); | ||
969 | let ty = Ty::from_hir( | 927 | let ty = Ty::from_hir( |
970 | self.db, | 928 | self.db, |
971 | &self.module, | 929 | // TODO use right resolver for block |
972 | self.impl_block.as_ref(), | 930 | &self.resolver, |
973 | &generics, | ||
974 | type_ref, | 931 | type_ref, |
975 | ); | 932 | ); |
976 | let ty = self.insert_type_vars(ty); | 933 | let ty = self.insert_type_vars(ty); |
@@ -1147,38 +1104,31 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1147 | }) | 1104 | }) |
1148 | } | 1105 | } |
1149 | 1106 | ||
1150 | fn infer_path_expr(&mut self, expr: ExprId, path: &Path) -> Option<Ty> { | 1107 | fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> { |
1151 | if path.is_ident() || path.is_self() { | 1108 | let resolved = resolver.resolve_path(self.db, &path).take_values()?; |
1152 | // resolve locally | 1109 | match resolved { |
1153 | let name = path.as_ident().cloned().unwrap_or_else(Name::self_param); | 1110 | Resolution::Def(def) => { |
1154 | if let Some(scope_entry) = self.scopes.resolve_local_name(expr, name) { | 1111 | let typable: Option<TypableDef> = def.into(); |
1155 | let ty = self.type_of_pat.get(scope_entry.pat())?; | 1112 | let typable = typable?; |
1113 | let substs = Ty::substs_from_path(self.db, &self.resolver, path, typable); | ||
1114 | let ty = self.db.type_for_def(typable).apply_substs(substs); | ||
1115 | let ty = self.insert_type_vars(ty); | ||
1116 | Some(ty) | ||
1117 | } | ||
1118 | Resolution::LocalBinding(pat) => { | ||
1119 | let ty = self.type_of_pat.get(pat)?; | ||
1156 | let ty = self.resolve_ty_as_possible(&mut vec![], ty.clone()); | 1120 | let ty = self.resolve_ty_as_possible(&mut vec![], ty.clone()); |
1157 | return Some(ty); | 1121 | Some(ty) |
1158 | }; | 1122 | } |
1159 | }; | 1123 | Resolution::GenericParam(..) => { |
1160 | 1124 | // generic params can't refer to values... yet | |
1161 | // resolve in module | 1125 | None |
1162 | let typable: Option<TypableDef> = self | 1126 | } |
1163 | .module | 1127 | Resolution::SelfType(_) => { |
1164 | .resolve_path(self.db, &path) | 1128 | log::error!("path expr {:?} resolved to Self type in values ns", path); |
1165 | .take_values()? | 1129 | None |
1166 | .into(); | 1130 | } |
1167 | let typable = typable?; | 1131 | } |
1168 | let ty = self.db.type_for_def(typable); | ||
1169 | let generics = GenericParams::default(); | ||
1170 | let substs = Ty::substs_from_path( | ||
1171 | self.db, | ||
1172 | &self.module, | ||
1173 | self.impl_block.as_ref(), | ||
1174 | &generics, | ||
1175 | path, | ||
1176 | typable, | ||
1177 | ); | ||
1178 | let ty = ty.apply_substs(substs); | ||
1179 | let ty = self.insert_type_vars(ty); | ||
1180 | |||
1181 | Some(ty) | ||
1182 | } | 1132 | } |
1183 | 1133 | ||
1184 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) { | 1134 | fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantDef>) { |
@@ -1186,26 +1136,30 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1186 | Some(path) => path, | 1136 | Some(path) => path, |
1187 | None => return (Ty::Unknown, None), | 1137 | None => return (Ty::Unknown, None), |
1188 | }; | 1138 | }; |
1189 | let typable: Option<TypableDef> = self | 1139 | let resolver = &self.resolver; |
1190 | .module | 1140 | let typable: Option<TypableDef> = match resolver.resolve_path(self.db, &path).take_types() { |
1191 | .resolve_path(self.db, &path) | 1141 | Some(Resolution::Def(def)) => def.into(), |
1192 | .take_types() | 1142 | Some(Resolution::LocalBinding(..)) => { |
1193 | .and_then(|it| it.into()); | 1143 | // this cannot happen |
1144 | log::error!("path resolved to local binding in type ns"); | ||
1145 | return (Ty::Unknown, None); | ||
1146 | } | ||
1147 | Some(Resolution::GenericParam(..)) => { | ||
1148 | // generic params can't be used in struct literals | ||
1149 | return (Ty::Unknown, None); | ||
1150 | } | ||
1151 | Some(Resolution::SelfType(..)) => { | ||
1152 | // TODO this is allowed in an impl for a struct, handle this | ||
1153 | return (Ty::Unknown, None); | ||
1154 | } | ||
1155 | None => return (Ty::Unknown, None), | ||
1156 | }; | ||
1194 | let def = match typable { | 1157 | let def = match typable { |
1195 | None => return (Ty::Unknown, None), | 1158 | None => return (Ty::Unknown, None), |
1196 | Some(it) => it, | 1159 | Some(it) => it, |
1197 | }; | 1160 | }; |
1198 | // TODO remove the duplication between here and `Ty::from_path`? | 1161 | // TODO remove the duplication between here and `Ty::from_path`? |
1199 | // TODO provide generics of function | 1162 | let substs = Ty::substs_from_path(self.db, resolver, path, def); |
1200 | let generics = GenericParams::default(); | ||
1201 | let substs = Ty::substs_from_path( | ||
1202 | self.db, | ||
1203 | &self.module, | ||
1204 | self.impl_block.as_ref(), | ||
1205 | &generics, | ||
1206 | path, | ||
1207 | def, | ||
1208 | ); | ||
1209 | match def { | 1163 | match def { |
1210 | TypableDef::Struct(s) => { | 1164 | TypableDef::Struct(s) => { |
1211 | let ty = type_for_struct(self.db, s); | 1165 | let ty = type_for_struct(self.db, s); |
@@ -1303,12 +1257,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1303 | path: ref p, | 1257 | path: ref p, |
1304 | args: ref fields, | 1258 | args: ref fields, |
1305 | } => self.infer_struct_pat(p.as_ref(), fields, expected), | 1259 | } => self.infer_struct_pat(p.as_ref(), fields, expected), |
1306 | Pat::Path(path) => self | 1260 | Pat::Path(path) => { |
1307 | .module | 1261 | // TODO use correct resolver for the surrounding expression |
1308 | .resolve_path(self.db, &path) | 1262 | let resolver = self.resolver.clone(); |
1309 | .take_values() | 1263 | self.infer_path_expr(&resolver, &path) |
1310 | .and_then(|module_def| module_def.into()) | 1264 | .unwrap_or(Ty::Unknown) |
1311 | .map_or(Ty::Unknown, |resolved| self.db.type_for_def(resolved)), | 1265 | } |
1312 | Pat::Bind { | 1266 | Pat::Bind { |
1313 | mode, | 1267 | mode, |
1314 | name: _name, | 1268 | name: _name, |
@@ -1496,7 +1450,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1496 | 1450 | ||
1497 | expected.ty | 1451 | expected.ty |
1498 | } | 1452 | } |
1499 | Expr::Path(p) => self.infer_path_expr(tgt_expr, p).unwrap_or(Ty::Unknown), | 1453 | Expr::Path(p) => { |
1454 | // TODO this could be more efficient... | ||
1455 | let resolver = expr::resolver_for_expr(self.body.clone(), self.db, tgt_expr); | ||
1456 | self.infer_path_expr(&resolver, p).unwrap_or(Ty::Unknown) | ||
1457 | } | ||
1500 | Expr::Continue => Ty::Never, | 1458 | Expr::Continue => Ty::Never, |
1501 | Expr::Break { expr } => { | 1459 | Expr::Break { expr } => { |
1502 | if let Some(expr) = expr { | 1460 | if let Some(expr) = expr { |
@@ -1730,10 +1688,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1730 | pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> { | 1688 | pub fn infer(db: &impl HirDatabase, func: Function) -> Arc<InferenceResult> { |
1731 | db.check_canceled(); | 1689 | db.check_canceled(); |
1732 | let body = func.body(db); | 1690 | let body = func.body(db); |
1733 | let scopes = db.expr_scopes(func); | 1691 | let resolver = func.resolver(db); |
1734 | let module = func.module(db); | 1692 | let mut ctx = InferenceContext::new(db, body, resolver); |
1735 | let impl_block = func.impl_block(db); | ||
1736 | let mut ctx = InferenceContext::new(db, body, scopes, module, impl_block); | ||
1737 | 1693 | ||
1738 | let signature = func.signature(db); | 1694 | let signature = func.signature(db); |
1739 | ctx.collect_fn_signature(&signature); | 1695 | ctx.collect_fn_signature(&signature); |