@@ -691,32 +691,75 @@ fn (mut c Checker) match_sumtype_has_variant(parent ast.Type, variant ast.Type)
691691 if c.table.sym (parent).kind == .sum_type {
692692 return false
693693 }
694- for candidate in c.concrete_sumtype_variants (parent) {
694+ for candidate in c.match_sumtype_matchable_variants (parent) {
695695 if c.match_sumtype_variant_is_handled (candidate, variant) {
696696 return true
697697 }
698698 }
699699 return false
700700}
701701
702+ fn (mut c Checker) match_sumtype_matchable_variants (parent ast.Type) []ast.Type {
703+ if c.table.sym (parent).kind == .sum_type {
704+ return c.table.sumtype_matchable_variants (parent)
705+ }
706+ mut variants := []ast.Type{}
707+ mut seen := map [u32 ]bool {}
708+ c.collect_match_sumtype_matchable_variants (parent, mut seen, mut variants)
709+ return variants
710+ }
711+
712+ fn (mut c Checker) collect_match_sumtype_matchable_variants (parent ast.Type, mut seen map [u32 ]bool , mut variants []ast.Type) {
713+ for variant in c.concrete_sumtype_variants (parent) {
714+ key := u32 (variant)
715+ if key in seen {
716+ continue
717+ }
718+ seen[key] = true
719+ variants << variant
720+ if c.concrete_sumtype_variants (variant).len > 0 {
721+ c.collect_match_sumtype_matchable_variants (variant, mut seen, mut variants)
722+ }
723+ }
724+ }
725+
702726fn (mut c Checker) match_sumtype_missing_variants (parent ast.Type, handled []ast.Type) []ast.Type {
703727 if c.table.sym (parent).kind == .sum_type {
704728 return c.table.sumtype_missing_variants (parent, handled)
705729 }
706730 mut missing := []ast.Type{}
731+ mut seen := map [u32 ]bool {}
732+ c.collect_match_sumtype_missing_variants (parent, handled, mut seen, mut missing)
733+ return missing
734+ }
735+
736+ fn (mut c Checker) collect_match_sumtype_missing_variants (parent ast.Type, handled []ast.Type, mut seen map [u32 ]bool , mut missing []ast.Type) {
737+ if c.match_sumtype_variant_is_handled_by (parent, handled) {
738+ return
739+ }
707740 for variant in c.concrete_sumtype_variants (parent) {
708- mut is_handled := false
709- for handled_variant in handled {
710- if c.match_sumtype_variant_is_handled (variant, handled_variant) {
711- is_handled = true
712- break
741+ if c.match_sumtype_variant_is_handled_by (variant, handled) {
742+ continue
743+ }
744+ if c.concrete_sumtype_variants (variant).len > 0 {
745+ c.collect_match_sumtype_missing_variants (variant, handled, mut seen, mut missing)
746+ } else {
747+ key := u32 (variant)
748+ if key ! in seen {
749+ seen[key] = true
750+ missing << variant
713751 }
714752 }
715- if ! is_handled {
716- missing << variant
753+ }
754+ }
755+
756+ fn (mut c Checker) match_sumtype_variant_is_handled_by (variant ast.Type, handled []ast.Type) bool {
757+ for handled_variant in handled {
758+ if c.match_sumtype_variant_is_handled (variant, handled_variant) {
759+ return true
717760 }
718761 }
719- return missing
762+ return false
720763}
721764
722765fn (mut c Checker) match_sumtype_variant_is_handled (variant ast.Type, handled ast.Type) bool {
@@ -737,7 +780,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym
737780 is_alias_to_matchable_type := cond_type_sym.kind == .alias
738781 && cond_final_sym.kind in [.interface , .sum_type]
739782 cond_match_sym := if is_alias_to_matchable_type { cond_final_sym } else { cond_type_sym }
740- sumtype_match_variants := c.concrete_sumtype_variants (cond_match_type)
783+ sumtype_match_variants := c.match_sumtype_matchable_variants (cond_match_type)
741784 is_cond_match_sumtype := sumtype_match_variants.len > 0
742785 mut enum_ref_checked := false
743786 mut is_comptime_value_match := false
0 commit comments