diff options
Diffstat (limited to 'crates/hir_ty/src/infer.rs')
-rw-r--r-- | crates/hir_ty/src/infer.rs | 70 |
1 files changed, 37 insertions, 33 deletions
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 7c6c3600b..6af0c59b8 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs | |||
@@ -487,36 +487,13 @@ impl<'a> InferenceContext<'a> { | |||
487 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); | 487 | let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); |
488 | let substs = generics.type_params_subst(self.db); | 488 | let substs = generics.type_params_subst(self.db); |
489 | let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs); | 489 | let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs); |
490 | match unresolved { | 490 | self.resolve_variant_on_alias(ty, unresolved, path) |
491 | None => { | ||
492 | let variant = ty_variant(&ty); | ||
493 | (ty, variant) | ||
494 | } | ||
495 | Some(1) => { | ||
496 | let segment = path.mod_path().segments().last().unwrap(); | ||
497 | // this could be an enum variant or associated type | ||
498 | if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() { | ||
499 | let enum_data = self.db.enum_data(enum_id); | ||
500 | if let Some(local_id) = enum_data.variant(segment) { | ||
501 | let variant = EnumVariantId { parent: enum_id, local_id }; | ||
502 | return (ty, Some(variant.into())); | ||
503 | } | ||
504 | } | ||
505 | // FIXME potentially resolve assoc type | ||
506 | (self.err_ty(), None) | ||
507 | } | ||
508 | Some(_) => { | ||
509 | // FIXME diagnostic | ||
510 | (self.err_ty(), None) | ||
511 | } | ||
512 | } | ||
513 | } | 491 | } |
514 | TypeNs::TypeAliasId(it) => { | 492 | TypeNs::TypeAliasId(it) => { |
515 | let ty = TyBuilder::def_ty(self.db, it.into()) | 493 | let ty = TyBuilder::def_ty(self.db, it.into()) |
516 | .fill(std::iter::repeat_with(|| self.table.new_type_var())) | 494 | .fill(std::iter::repeat_with(|| self.table.new_type_var())) |
517 | .build(); | 495 | .build(); |
518 | let variant = ty_variant(&ty); | 496 | self.resolve_variant_on_alias(ty, unresolved, path) |
519 | forbid_unresolved_segments((ty, variant), unresolved) | ||
520 | } | 497 | } |
521 | TypeNs::AdtSelfType(_) => { | 498 | TypeNs::AdtSelfType(_) => { |
522 | // FIXME this could happen in array size expressions, once we're checking them | 499 | // FIXME this could happen in array size expressions, once we're checking them |
@@ -543,16 +520,43 @@ impl<'a> InferenceContext<'a> { | |||
543 | (TyKind::Error.intern(&Interner), None) | 520 | (TyKind::Error.intern(&Interner), None) |
544 | } | 521 | } |
545 | } | 522 | } |
523 | } | ||
546 | 524 | ||
547 | fn ty_variant(ty: &Ty) -> Option<VariantId> { | 525 | fn resolve_variant_on_alias( |
548 | ty.as_adt().and_then(|(adt_id, _)| match adt_id { | 526 | &mut self, |
549 | AdtId::StructId(s) => Some(VariantId::StructId(s)), | 527 | ty: Ty, |
550 | AdtId::UnionId(u) => Some(VariantId::UnionId(u)), | 528 | unresolved: Option<usize>, |
551 | AdtId::EnumId(_) => { | 529 | path: &Path, |
552 | // FIXME Error E0071, expected struct, variant or union type, found enum `Foo` | 530 | ) -> (Ty, Option<VariantId>) { |
553 | None | 531 | match unresolved { |
532 | None => { | ||
533 | let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id { | ||
534 | AdtId::StructId(s) => Some(VariantId::StructId(s)), | ||
535 | AdtId::UnionId(u) => Some(VariantId::UnionId(u)), | ||
536 | AdtId::EnumId(_) => { | ||
537 | // FIXME Error E0071, expected struct, variant or union type, found enum `Foo` | ||
538 | None | ||
539 | } | ||
540 | }); | ||
541 | (ty, variant) | ||
542 | } | ||
543 | Some(1) => { | ||
544 | let segment = path.mod_path().segments().last().unwrap(); | ||
545 | // this could be an enum variant or associated type | ||
546 | if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() { | ||
547 | let enum_data = self.db.enum_data(enum_id); | ||
548 | if let Some(local_id) = enum_data.variant(segment) { | ||
549 | let variant = EnumVariantId { parent: enum_id, local_id }; | ||
550 | return (ty, Some(variant.into())); | ||
551 | } | ||
554 | } | 552 | } |
555 | }) | 553 | // FIXME potentially resolve assoc type |
554 | (self.err_ty(), None) | ||
555 | } | ||
556 | Some(_) => { | ||
557 | // FIXME diagnostic | ||
558 | (self.err_ty(), None) | ||
559 | } | ||
556 | } | 560 | } |
557 | } | 561 | } |
558 | 562 | ||