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
|
// TODO: replace Param
|
||||||
pub type Node = CallArg | ConstField | EmptyNode | EnumField | Expr | File | GlobalField |
|
pub type Node = CallArg | ConstField | EmptyNode | EnumField | Expr | File | GlobalField |
|
||||||
IfBranch | MatchBranch | NodeError | Param | ScopeObject | SelectBranch | Stmt | StructField |
|
IfBranch | MatchBranch | NodeError | Param | ScopeObject | SelectBranch | Stmt | StructField |
|
||||||
StructInitField | SumTypeVariant
|
StructInitField
|
||||||
|
|
||||||
pub struct TypeNode {
|
pub struct TypeNode {
|
||||||
pub:
|
pub:
|
||||||
|
@ -952,13 +952,7 @@ pub:
|
||||||
comments []Comment
|
comments []Comment
|
||||||
typ Type
|
typ Type
|
||||||
pub mut:
|
pub mut:
|
||||||
variants []SumTypeVariant
|
variants []TypeNode
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SumTypeVariant {
|
|
||||||
pub:
|
|
||||||
typ Type
|
|
||||||
pos token.Position
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FnTypeDecl {
|
pub struct FnTypeDecl {
|
||||||
|
@ -1661,8 +1655,7 @@ pub fn (node Node) position() token.Position {
|
||||||
StructField {
|
StructField {
|
||||||
return node.pos.extend(node.type_pos)
|
return node.pos.extend(node.type_pos)
|
||||||
}
|
}
|
||||||
MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, CallArg,
|
MatchBranch, SelectBranch, EnumField, ConstField, StructInitField, GlobalField, CallArg {
|
||||||
SumTypeVariant {
|
|
||||||
return node.pos
|
return node.pos
|
||||||
}
|
}
|
||||||
Param {
|
Param {
|
||||||
|
@ -1810,7 +1803,7 @@ pub fn (node Node) children() []Node {
|
||||||
}
|
}
|
||||||
TypeDecl {
|
TypeDecl {
|
||||||
if node is SumTypeDecl {
|
if node is SumTypeDecl {
|
||||||
children << node.variants.map(Node(it))
|
children << node.variants.map(Node(Expr(it)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
|
|
|
@ -350,6 +350,9 @@ pub fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) {
|
||||||
} else if sym.kind == .interface_ {
|
} else if sym.kind == .interface_ {
|
||||||
c.error('sum type cannot hold an interface', variant.pos)
|
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
|
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)
|
c.error('unwrapped optional cannot be used in an infix expression', left_right_pos)
|
||||||
}
|
}
|
||||||
// Dual sides check (compatibility check)
|
// 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
|
// for type-unresolved consts
|
||||||
if left_type == ast.void_type || right_type == ast.void_type {
|
if left_type == ast.void_type || right_type == ast.void_type {
|
||||||
return 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)
|
decl_pos)
|
||||||
return ast.FnTypeDecl{}
|
return ast.FnTypeDecl{}
|
||||||
}
|
}
|
||||||
mut sum_variants := []ast.SumTypeVariant{}
|
mut sum_variants := []ast.TypeNode{}
|
||||||
p.check(.assign)
|
p.check(.assign)
|
||||||
mut type_pos := p.tok.position()
|
mut type_pos := p.tok.position()
|
||||||
mut comments := []ast.Comment{}
|
mut comments := []ast.Comment{}
|
||||||
|
@ -3012,7 +3012,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
||||||
mut type_end_pos := p.prev_tok.position()
|
mut type_end_pos := p.prev_tok.position()
|
||||||
type_pos = type_pos.extend(type_end_pos)
|
type_pos = type_pos.extend(type_end_pos)
|
||||||
p.next()
|
p.next()
|
||||||
sum_variants << ast.SumTypeVariant{
|
sum_variants << {
|
||||||
typ: first_type
|
typ: first_type
|
||||||
pos: type_pos
|
pos: type_pos
|
||||||
}
|
}
|
||||||
|
@ -3024,7 +3024,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
|
||||||
prev_tok := p.prev_tok
|
prev_tok := p.prev_tok
|
||||||
type_end_pos = prev_tok.position()
|
type_end_pos = prev_tok.position()
|
||||||
type_pos = type_pos.extend(type_end_pos)
|
type_pos = type_pos.extend(type_end_pos)
|
||||||
sum_variants << ast.SumTypeVariant{
|
sum_variants << {
|
||||||
typ: variant_type
|
typ: variant_type
|
||||||
pos: type_pos
|
pos: type_pos
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue