Skip to content

Commit a8f1e41

Browse files
bors[bot]Veykril
andauthored
Merge #8394
8394: Infer variants through type aliased enums r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2 parents ad50f50 + 41563fd commit a8f1e41

File tree

2 files changed

+70
-33
lines changed

2 files changed

+70
-33
lines changed

crates/hir_ty/src/infer.rs

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -487,36 +487,13 @@ impl<'a> InferenceContext<'a> {
487487
let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
488488
let substs = generics.type_params_subst(self.db);
489489
let ty = self.db.impl_self_ty(impl_id).substitute(&Interner, &substs);
490-
match unresolved {
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-
}
490+
self.resolve_variant_on_alias(ty, unresolved, path)
513491
}
514492
TypeNs::TypeAliasId(it) => {
515493
let ty = TyBuilder::def_ty(self.db, it.into())
516494
.fill(std::iter::repeat_with(|| self.table.new_type_var()))
517495
.build();
518-
let variant = ty_variant(&ty);
519-
forbid_unresolved_segments((ty, variant), unresolved)
496+
self.resolve_variant_on_alias(ty, unresolved, path)
520497
}
521498
TypeNs::AdtSelfType(_) => {
522499
// FIXME this could happen in array size expressions, once we're checking them
@@ -543,16 +520,43 @@ impl<'a> InferenceContext<'a> {
543520
(TyKind::Error.intern(&Interner), None)
544521
}
545522
}
523+
}
546524

547-
fn ty_variant(ty: &Ty) -> Option<VariantId> {
548-
ty.as_adt().and_then(|(adt_id, _)| match adt_id {
549-
AdtId::StructId(s) => Some(VariantId::StructId(s)),
550-
AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
551-
AdtId::EnumId(_) => {
552-
// FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
553-
None
525+
fn resolve_variant_on_alias(
526+
&mut self,
527+
ty: Ty,
528+
unresolved: Option<usize>,
529+
path: &Path,
530+
) -> (Ty, Option<VariantId>) {
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+
}
554552
}
555-
})
553+
// FIXME potentially resolve assoc type
554+
(self.err_ty(), None)
555+
}
556+
Some(_) => {
557+
// FIXME diagnostic
558+
(self.err_ty(), None)
559+
}
556560
}
557561
}
558562

crates/hir_ty/src/tests/simple.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2564,3 +2564,36 @@ fn f() {
25642564
"#,
25652565
)
25662566
}
2567+
2568+
#[test]
2569+
fn infer_type_alias_variant() {
2570+
check_infer(
2571+
r#"
2572+
type Qux = Foo;
2573+
enum Foo {
2574+
Bar(i32),
2575+
Baz { baz: f32 }
2576+
}
2577+
2578+
fn f() {
2579+
match Foo::Bar(3) {
2580+
Qux::Bar(bar) => (),
2581+
Qux::Baz { baz } => (),
2582+
}
2583+
}
2584+
"#,
2585+
expect![[r#"
2586+
72..166 '{ ... } }': ()
2587+
78..164 'match ... }': ()
2588+
84..92 'Foo::Bar': Bar(i32) -> Foo
2589+
84..95 'Foo::Bar(3)': Foo
2590+
93..94 '3': i32
2591+
106..119 'Qux::Bar(bar)': Foo
2592+
115..118 'bar': i32
2593+
123..125 '()': ()
2594+
135..151 'Qux::B... baz }': Foo
2595+
146..149 'baz': f32
2596+
155..157 '()': ()
2597+
"#]],
2598+
)
2599+
}

0 commit comments

Comments
 (0)