checker: fix sumtype comparison and sumtype in itself (#9917)

pull/9933/head
crthpl 2021-04-28 23:04:02 -07:00 committed by GitHub
parent 191a167f42
commit 6945f987cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 25 additions and 15 deletions

View File

@ -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 {}

View File

@ -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

View File

@ -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
| ~~

View File

@ -0,0 +1 @@
type AA = AA | int

View File

@ -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
| ~~~~~~

View File

@ -0,0 +1,4 @@
type AA = int | string
a := AA(3)
assert a == 3

View File

@ -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
}