checker: fixes typechecking for a sum type with an alias type (#13974)
parent
dc08105022
commit
48c295150f
|
@ -1280,25 +1280,54 @@ pub fn (t &Table) sumtype_has_variant(parent Type, variant Type, is_as bool) boo
|
||||||
if parent_sym.kind == .sum_type {
|
if parent_sym.kind == .sum_type {
|
||||||
parent_info := parent_sym.info as SumType
|
parent_info := parent_sym.info as SumType
|
||||||
var_sym := t.sym(variant)
|
var_sym := t.sym(variant)
|
||||||
if var_sym.kind == .aggregate {
|
match var_sym.kind {
|
||||||
var_info := var_sym.info as Aggregate
|
.aggregate {
|
||||||
for var_type in var_info.types {
|
return t.sumtype_check_aggregate_variant(parent, variant, is_as)
|
||||||
if !t.sumtype_has_variant(parent, var_type, is_as) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
.alias {
|
||||||
} else {
|
return t.sumtype_check_alias_variant(parent, variant, is_as)
|
||||||
for v in parent_info.variants {
|
}
|
||||||
if v.idx() == variant.idx() && (!is_as || v.nr_muls() == variant.nr_muls()) {
|
else {
|
||||||
return true
|
return t.sumtype_check_variant_in_type(parent_info, variant, is_as)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (t &Table) sumtype_check_variant_in_type(parent_info SumType, variant Type, is_as bool) bool {
|
||||||
|
for v in parent_info.variants {
|
||||||
|
if v.idx() == variant.idx() && (!is_as || v.nr_muls() == variant.nr_muls()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (t &Table) sumtype_check_aggregate_variant(parent_type Type, aggregate_type &Type, is_as bool) bool {
|
||||||
|
aggregate_sym := t.sym(aggregate_type).info as Aggregate
|
||||||
|
for var_type in aggregate_sym.types {
|
||||||
|
if !t.sumtype_has_variant(parent_type, var_type, is_as) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (t &Table) sumtype_check_alias_variant(parent_type Type, alias_type Type, is_as bool) bool {
|
||||||
|
parent_sym := t.sym(parent_type).info as SumType
|
||||||
|
if !t.sumtype_check_variant_in_type(parent_sym, alias_type, is_as) {
|
||||||
|
alias_info := t.sym(alias_type).info as Alias
|
||||||
|
// The alias is an alias or of the same sumtype parent, or one
|
||||||
|
// of the SumType variant. e.g: alias of another sum type.
|
||||||
|
// https://github.com/vlang/v/issues/14029
|
||||||
|
return parent_type == alias_info.parent_type
|
||||||
|
|| t.sumtype_has_variant(parent_type, alias_info.parent_type, is_as)
|
||||||
|
}
|
||||||
|
// the alias_type is inside one of the variant of the sum type
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (t &Table) is_sumtype_or_in_variant(parent Type, typ Type) bool {
|
pub fn (t &Table) is_sumtype_or_in_variant(parent Type, typ Type) bool {
|
||||||
if typ == 0 {
|
if typ == 0 {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
// THE END.
|
|
@ -0,0 +1,32 @@
|
||||||
|
type ParseRes = Result<[]Token, ParseErr>
|
||||||
|
|
||||||
|
struct ParseErr {}
|
||||||
|
|
||||||
|
type Opt<T> = None<T> | Some<T>
|
||||||
|
|
||||||
|
struct None<T> {}
|
||||||
|
|
||||||
|
struct Some<T> {
|
||||||
|
value T
|
||||||
|
}
|
||||||
|
|
||||||
|
type Result<T, U> = Err<U> | Ok<T>
|
||||||
|
|
||||||
|
struct Ok<T> {
|
||||||
|
value T
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Err<U> {
|
||||||
|
value U
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
r := Opt<ParseRes>(None<ParseRes>{})
|
||||||
|
match r {
|
||||||
|
Some<ParseRes> {
|
||||||
|
// make possible cast fo the same type!
|
||||||
|
rx := Result<[]Token, ParseErr>(r.value)
|
||||||
|
}
|
||||||
|
None<ParseRes> {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,6 @@
|
||||||
type ParseRes = Result<[]Token, ParseErr>
|
type ParseRes = Result<[]Token, ParseErr>
|
||||||
|
|
||||||
struct ParseErr{
|
struct ParseErr {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type Opt<T> = None<T> | Some<T>
|
type Opt<T> = None<T> | Some<T>
|
||||||
|
|
||||||
|
@ -26,7 +24,7 @@ fn test_report() {
|
||||||
r := Opt<ParseRes>(None<ParseRes>{})
|
r := Opt<ParseRes>(None<ParseRes>{})
|
||||||
match r {
|
match r {
|
||||||
Some<ParseRes> {
|
Some<ParseRes> {
|
||||||
rx := Result<[]Token, ParseErr>(r)
|
rx := Result<[]Token, ParseErr>(r.value)
|
||||||
}
|
}
|
||||||
None<ParseRes> {}
|
None<ParseRes> {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue