checker: fix sumtype comparison and sumtype in itself (#9917)
parent
191a167f42
commit
6945f987cf
|
@ -29,7 +29,7 @@ pub type ScopeObject = AsmRegister | ConstField | GlobalField | Var
|
|||
// TODO: replace Param
|
||||
pub type Node = CallArg | ConstField | EmptyNode | EnumField | Expr | File | GlobalField |
|
||||
IfBranch | MatchBranch | NodeError | Param | ScopeObject | SelectBranch | Stmt | StructField |
|
||||
StructInitField | SumTypeVariant
|
||||
StructInitField
|
||||
|
||||
pub struct TypeNode {
|
||||
pub:
|
||||
|
@ -952,13 +952,7 @@ pub:
|
|||
comments []Comment
|
||||
typ Type
|
||||
pub mut:
|
||||
variants []SumTypeVariant
|
||||
}
|
||||
|
||||
pub struct SumTypeVariant {
|
||||
pub:
|
||||
typ Type
|
||||
pos token.Position
|
||||
variants []TypeNode
|
||||
}
|
||||
|
||||
pub struct FnTypeDecl {
|
||||
|
@ -1661,8 +1655,7 @@ pub fn (node Node) position() token.Position {
|
|||
StructField {
|
||||
return node.pos.extend(node.type_pos)
|
||||
}
|
||||
MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, CallArg,
|
||||
SumTypeVariant {
|
||||
MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, CallArg {
|
||||
return node.pos
|
||||
}
|
||||
Param {
|
||||
|
@ -1810,7 +1803,7 @@ pub fn (node Node) children() []Node {
|
|||
}
|
||||
TypeDecl {
|
||||
if node is SumTypeDecl {
|
||||
children << node.variants.map(Node(it))
|
||||
children << node.variants.map(Node(Expr(it)))
|
||||
}
|
||||
}
|
||||
else {}
|
||||
|
|
|
@ -350,6 +350,9 @@ pub fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) {
|
|||
} else if sym.kind == .interface_ {
|
||||
c.error('sum type cannot hold an interface', variant.pos)
|
||||
}
|
||||
if sym.name.trim_prefix(sym.mod + '.') == node.name {
|
||||
c.error('sum type cannot hold itself', variant.pos)
|
||||
}
|
||||
names_used << sym.name
|
||||
}
|
||||
}
|
||||
|
@ -1109,7 +1112,8 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) ast.Type {
|
|||
c.error('unwrapped optional cannot be used in an infix expression', left_right_pos)
|
||||
}
|
||||
// Dual sides check (compatibility check)
|
||||
if !c.symmetric_check(right_type, left_type) && !c.pref.translated {
|
||||
if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type))
|
||||
&& !c.pref.translated {
|
||||
// for type-unresolved consts
|
||||
if left_type == ast.void_type || right_type == ast.void_type {
|
||||
return ast.void_type
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
vlib/v/checker/tests/sumtype_in_sumtype_err.vv:1:11: error: sum type cannot hold itself
|
||||
1 | type AA = AA | int
|
||||
| ~~
|
|
@ -0,0 +1 @@
|
|||
type AA = AA | int
|
|
@ -0,0 +1,5 @@
|
|||
vlib/v/checker/tests/sumtype_mismatched_type.vv:4:8: error: infix expr: cannot use `int literal` (right expression) as `AA`
|
||||
2 |
|
||||
3 | a := AA(3)
|
||||
4 | assert a == 3
|
||||
| ~~~~~~
|
|
@ -0,0 +1,4 @@
|
|||
type AA = int | string
|
||||
|
||||
a := AA(3)
|
||||
assert a == 3
|
|
@ -2987,7 +2987,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
|||
decl_pos)
|
||||
return ast.FnTypeDecl{}
|
||||
}
|
||||
mut sum_variants := []ast.SumTypeVariant{}
|
||||
mut sum_variants := []ast.TypeNode{}
|
||||
p.check(.assign)
|
||||
mut type_pos := p.tok.position()
|
||||
mut comments := []ast.Comment{}
|
||||
|
@ -3012,7 +3012,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
|||
mut type_end_pos := p.prev_tok.position()
|
||||
type_pos = type_pos.extend(type_end_pos)
|
||||
p.next()
|
||||
sum_variants << ast.SumTypeVariant{
|
||||
sum_variants << {
|
||||
typ: first_type
|
||||
pos: type_pos
|
||||
}
|
||||
|
@ -3024,7 +3024,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
|||
prev_tok := p.prev_tok
|
||||
type_end_pos = prev_tok.position()
|
||||
type_pos = type_pos.extend(type_end_pos)
|
||||
sum_variants << ast.SumTypeVariant{
|
||||
sum_variants << {
|
||||
typ: variant_type
|
||||
pos: type_pos
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue