diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-09-16 13:43:21 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-09-16 13:43:21 +0100 |
commit | ba583091e60553633dd3cc9ab37a1d9f64827a1e (patch) | |
tree | 41a9b72f46b1119ff32964f77365459fdb46a37d /crates/ra_hir/src/ty/infer.rs | |
parent | 6b33b90091b0cecd4c092d34451aba9f2492063c (diff) | |
parent | 7ed3be32916facf3b709d5277381408cd3ec134a (diff) |
Merge #1817
1817: Support path starting with a type r=matklad a=uHOOCCOOHu
The path syntax `<Ty>::foo`
Co-authored-by: uHOOCCOOHu <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/infer.rs')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 127 |
1 files changed, 52 insertions, 75 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 7d9b86752..bf9609d8c 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -44,11 +44,12 @@ use crate::{ | |||
44 | generics::{GenericParams, HasGenericParams}, | 44 | generics::{GenericParams, HasGenericParams}, |
45 | name, | 45 | name, |
46 | nameres::Namespace, | 46 | nameres::Namespace, |
47 | path::{GenericArg, GenericArgs, PathKind, PathSegment}, | 47 | path::{known, GenericArg, GenericArgs}, |
48 | resolve::{Resolver, TypeNs, ValueNs, ValueOrPartial}, | 48 | resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs}, |
49 | ty::infer::diagnostics::InferenceDiagnostic, | 49 | ty::infer::diagnostics::InferenceDiagnostic, |
50 | type_ref::{Mutability, TypeRef}, | 50 | type_ref::{Mutability, TypeRef}, |
51 | Adt, ConstData, DefWithBody, FnData, Function, HasBody, ImplItem, Name, Path, StructField, | 51 | Adt, ConstData, DefWithBody, Either, FnData, Function, HasBody, ImplItem, Name, Path, |
52 | StructField, | ||
52 | }; | 53 | }; |
53 | 54 | ||
54 | mod unify; | 55 | mod unify; |
@@ -470,9 +471,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
470 | let value_or_partial = resolver.resolve_path_in_value_ns(self.db, &path)?; | 471 | let value_or_partial = resolver.resolve_path_in_value_ns(self.db, &path)?; |
471 | 472 | ||
472 | let (value, self_subst) = match value_or_partial { | 473 | let (value, self_subst) = match value_or_partial { |
473 | ValueOrPartial::ValueNs(it) => (it, None), | 474 | ResolveValueResult::ValueNs(it) => (it, None), |
474 | ValueOrPartial::Partial(def, remaining_index) => { | 475 | ResolveValueResult::Partial(def, remaining_index) => { |
475 | self.resolve_assoc_item(def, path, remaining_index, id)? | 476 | self.resolve_assoc_item(Either::A(def), path, remaining_index, id)? |
477 | } | ||
478 | ResolveValueResult::TypeRef(type_ref) => { | ||
479 | let ty = self.make_ty(type_ref); | ||
480 | self.resolve_assoc_item(Either::B(ty), path, 0, id)? | ||
476 | } | 481 | } |
477 | }; | 482 | }; |
478 | 483 | ||
@@ -503,7 +508,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
503 | 508 | ||
504 | fn resolve_assoc_item( | 509 | fn resolve_assoc_item( |
505 | &mut self, | 510 | &mut self, |
506 | mut def: TypeNs, | 511 | mut def_or_ty: Either<TypeNs, Ty>, |
507 | path: &Path, | 512 | path: &Path, |
508 | remaining_index: usize, | 513 | remaining_index: usize, |
509 | id: ExprOrPatId, | 514 | id: ExprOrPatId, |
@@ -516,30 +521,33 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
516 | // resolve intermediate segments | 521 | // resolve intermediate segments |
517 | for (i, segment) in path.segments[remaining_index..].iter().enumerate() { | 522 | for (i, segment) in path.segments[remaining_index..].iter().enumerate() { |
518 | let is_last_segment = i == path.segments[remaining_index..].len() - 1; | 523 | let is_last_segment = i == path.segments[remaining_index..].len() - 1; |
519 | ty = { | 524 | ty = match def_or_ty { |
520 | let typable: TypableDef = match def { | 525 | Either::A(def) => { |
521 | TypeNs::Adt(it) => it.into(), | 526 | let typable: TypableDef = match def { |
522 | TypeNs::TypeAlias(it) => it.into(), | 527 | TypeNs::Adt(it) => it.into(), |
523 | TypeNs::BuiltinType(it) => it.into(), | 528 | TypeNs::TypeAlias(it) => it.into(), |
524 | // FIXME associated item of traits, generics, and Self | 529 | TypeNs::BuiltinType(it) => it.into(), |
525 | TypeNs::Trait(_) | TypeNs::GenericParam(_) | TypeNs::SelfType(_) => { | 530 | // FIXME associated item of traits, generics, and Self |
526 | return None; | 531 | TypeNs::Trait(_) | TypeNs::GenericParam(_) | TypeNs::SelfType(_) => { |
527 | } | 532 | return None; |
528 | // FIXME: report error here | 533 | } |
529 | TypeNs::EnumVariant(_) => return None, | 534 | // FIXME: report error here |
530 | }; | 535 | TypeNs::EnumVariant(_) => return None, |
531 | 536 | }; | |
532 | let ty = self.db.type_for_def(typable, Namespace::Types); | ||
533 | 537 | ||
534 | // For example, this substs will take `Gen::*<u32>*::make` | 538 | let ty = self.db.type_for_def(typable, Namespace::Types); |
535 | assert!(remaining_index > 0); | 539 | |
536 | let substs = Ty::substs_from_path_segment( | 540 | // For example, this substs will take `Gen::*<u32>*::make` |
537 | self.db, | 541 | assert!(remaining_index > 0); |
538 | &self.resolver, | 542 | let substs = Ty::substs_from_path_segment( |
539 | &path.segments[remaining_index + i - 1], | 543 | self.db, |
540 | typable, | 544 | &self.resolver, |
541 | ); | 545 | &path.segments[remaining_index + i - 1], |
542 | ty.subst(&substs) | 546 | typable, |
547 | ); | ||
548 | ty.subst(&substs) | ||
549 | } | ||
550 | Either::B(ty) => ty, | ||
543 | }; | 551 | }; |
544 | if is_last_segment { | 552 | if is_last_segment { |
545 | break; | 553 | break; |
@@ -550,15 +558,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
550 | log::debug!("looking for path segment: {:?}", segment); | 558 | log::debug!("looking for path segment: {:?}", segment); |
551 | 559 | ||
552 | let ty = mem::replace(&mut ty, Ty::Unknown); | 560 | let ty = mem::replace(&mut ty, Ty::Unknown); |
553 | def = ty.iterate_impl_items(self.db, krate, |item| { | 561 | def_or_ty = ty.iterate_impl_items(self.db, krate, |item| { |
554 | match item { | 562 | match item { |
555 | crate::ImplItem::Method(_) => None, | 563 | crate::ImplItem::Method(_) => None, |
556 | crate::ImplItem::Const(_) => None, | 564 | crate::ImplItem::Const(_) => None, |
557 | 565 | ||
558 | // FIXME: Resolve associated types | 566 | // FIXME: Resolve associated types |
559 | crate::ImplItem::TypeAlias(_) => { | 567 | crate::ImplItem::TypeAlias(_) => { |
560 | // Some(TypeNs::TypeAlias(..)) | 568 | // Some(Either::A(TypeNs::TypeAlias(..))) |
561 | None::<TypeNs> | 569 | None |
562 | } | 570 | } |
563 | } | 571 | } |
564 | })?; | 572 | })?; |
@@ -1434,57 +1442,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1434 | } | 1442 | } |
1435 | 1443 | ||
1436 | fn resolve_into_iter_item(&self) -> Option<TypeAlias> { | 1444 | fn resolve_into_iter_item(&self) -> Option<TypeAlias> { |
1437 | let into_iter_path = Path { | 1445 | let path = known::std_iter_into_iterator(); |
1438 | kind: PathKind::Abs, | 1446 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; |
1439 | segments: vec![ | 1447 | trait_.associated_type_by_name(self.db, &name::ITEM_TYPE) |
1440 | PathSegment { name: name::STD, args_and_bindings: None }, | ||
1441 | PathSegment { name: name::ITER, args_and_bindings: None }, | ||
1442 | PathSegment { name: name::INTO_ITERATOR, args_and_bindings: None }, | ||
1443 | ], | ||
1444 | }; | ||
1445 | |||
1446 | let trait_ = self.resolver.resolve_known_trait(self.db, &into_iter_path)?; | ||
1447 | trait_.associated_type_by_name(self.db, &name::ITEM) | ||
1448 | } | 1448 | } |
1449 | 1449 | ||
1450 | fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { | 1450 | fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { |
1451 | let ops_try_path = Path { | 1451 | let path = known::std_ops_try(); |
1452 | kind: PathKind::Abs, | 1452 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; |
1453 | segments: vec![ | 1453 | trait_.associated_type_by_name(self.db, &name::OK_TYPE) |
1454 | PathSegment { name: name::STD, args_and_bindings: None }, | ||
1455 | PathSegment { name: name::OPS, args_and_bindings: None }, | ||
1456 | PathSegment { name: name::TRY, args_and_bindings: None }, | ||
1457 | ], | ||
1458 | }; | ||
1459 | |||
1460 | let trait_ = self.resolver.resolve_known_trait(self.db, &ops_try_path)?; | ||
1461 | trait_.associated_type_by_name(self.db, &name::OK) | ||
1462 | } | 1454 | } |
1463 | 1455 | ||
1464 | fn resolve_future_future_output(&self) -> Option<TypeAlias> { | 1456 | fn resolve_future_future_output(&self) -> Option<TypeAlias> { |
1465 | let future_future_path = Path { | 1457 | let path = known::std_future_future(); |
1466 | kind: PathKind::Abs, | 1458 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; |
1467 | segments: vec![ | 1459 | trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) |
1468 | PathSegment { name: name::STD, args_and_bindings: None }, | ||
1469 | PathSegment { name: name::FUTURE_MOD, args_and_bindings: None }, | ||
1470 | PathSegment { name: name::FUTURE_TYPE, args_and_bindings: None }, | ||
1471 | ], | ||
1472 | }; | ||
1473 | |||
1474 | let trait_ = self.resolver.resolve_known_trait(self.db, &future_future_path)?; | ||
1475 | trait_.associated_type_by_name(self.db, &name::OUTPUT) | ||
1476 | } | 1460 | } |
1477 | 1461 | ||
1478 | fn resolve_boxed_box(&self) -> Option<Adt> { | 1462 | fn resolve_boxed_box(&self) -> Option<Adt> { |
1479 | let boxed_box_path = Path { | 1463 | let path = known::std_boxed_box(); |
1480 | kind: PathKind::Abs, | 1464 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; |
1481 | segments: vec![ | ||
1482 | PathSegment { name: name::STD, args_and_bindings: None }, | ||
1483 | PathSegment { name: name::BOXED_MOD, args_and_bindings: None }, | ||
1484 | PathSegment { name: name::BOX_TYPE, args_and_bindings: None }, | ||
1485 | ], | ||
1486 | }; | ||
1487 | let struct_ = self.resolver.resolve_known_struct(self.db, &boxed_box_path)?; | ||
1488 | Some(Adt::Struct(struct_)) | 1465 | Some(Adt::Struct(struct_)) |
1489 | } | 1466 | } |
1490 | } | 1467 | } |