mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser: add more precise errors, for fn (p Point) += (q Point) Point {
(#17167)
This commit is contained in:
parent
0d04104112
commit
b487c9d38e
|
@ -280,6 +280,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
p.fn_language = language
|
p.fn_language = language
|
||||||
}
|
}
|
||||||
mut name := ''
|
mut name := ''
|
||||||
|
mut type_sym := p.table.sym(rec.typ)
|
||||||
name_pos := p.tok.pos()
|
name_pos := p.tok.pos()
|
||||||
if p.tok.kind == .name {
|
if p.tok.kind == .name {
|
||||||
// TODO high order fn
|
// TODO high order fn
|
||||||
|
@ -292,12 +293,11 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
scope: 0
|
scope: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
type_sym := p.table.sym(rec.typ)
|
|
||||||
if is_method {
|
if is_method {
|
||||||
mut is_duplicate := type_sym.has_method(name)
|
mut is_duplicate := type_sym.has_method(name)
|
||||||
// make sure this is a normal method and not an interface method
|
// make sure this is a normal method and not an interface method
|
||||||
if type_sym.kind == .interface_ && is_duplicate {
|
if type_sym.kind == .interface_ && is_duplicate {
|
||||||
if type_sym.info is ast.Interface {
|
if mut type_sym.info is ast.Interface {
|
||||||
// if the method is in info then its an interface method
|
// if the method is in info then its an interface method
|
||||||
is_duplicate = !type_sym.info.has_method(name)
|
is_duplicate = !type_sym.info.has_method(name)
|
||||||
}
|
}
|
||||||
|
@ -327,6 +327,19 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
} else if p.tok.kind in [.ne, .gt, .ge, .le] && p.peek_tok.kind == .lpar {
|
} else if p.tok.kind in [.ne, .gt, .ge, .le] && p.peek_tok.kind == .lpar {
|
||||||
p.error_with_pos('cannot overload `!=`, `>`, `<=` and `>=` as they are auto generated from `==` and`<`',
|
p.error_with_pos('cannot overload `!=`, `>`, `<=` and `>=` as they are auto generated from `==` and`<`',
|
||||||
p.tok.pos())
|
p.tok.pos())
|
||||||
|
} else if p.tok.kind in [.plus_assign, .minus_assign, .div_assign, .mult_assign, .mod_assign] {
|
||||||
|
extracted_op := match p.tok.kind {
|
||||||
|
.plus_assign { '+' }
|
||||||
|
.minus_assign { '-' }
|
||||||
|
.div_assign { '/' }
|
||||||
|
.mod_assign { '%' }
|
||||||
|
.mult_assign { '*' }
|
||||||
|
else { 'unknown op' }
|
||||||
|
}
|
||||||
|
if type_sym.has_method(extracted_op) {
|
||||||
|
p.error('cannot overload `${p.tok.kind}`, operator is implicitly overloaded because the `${extracted_op}` operator is overloaded')
|
||||||
|
}
|
||||||
|
p.error('cannot overload `${p.tok.kind}`, overload `${extracted_op}` and `${p.tok.kind}` will be automatically generated')
|
||||||
} else {
|
} else {
|
||||||
p.error_with_pos('expecting method name', p.tok.pos())
|
p.error_with_pos('expecting method name', p.tok.pos())
|
||||||
return ast.FnDecl{
|
return ast.FnDecl{
|
||||||
|
@ -412,7 +425,6 @@ run them via `v file.v` instead',
|
||||||
}
|
}
|
||||||
// Register
|
// Register
|
||||||
if is_method {
|
if is_method {
|
||||||
mut type_sym := p.table.sym(rec.typ)
|
|
||||||
// Do not allow to modify / add methods to types from other modules
|
// Do not allow to modify / add methods to types from other modules
|
||||||
// arrays/maps dont belong to a module only their element types do
|
// arrays/maps dont belong to a module only their element types do
|
||||||
// we could also check if kind is .array, .array_fixed, .map instead of mod.len
|
// we could also check if kind is .array, .array_fixed, .map instead of mod.len
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
vlib/v/parser/tests/argumented_op_overloading_fn_decl_err.vv:10:14: error: cannot overload `+=`, overload `+` and `+=` will be automatically generated
|
||||||
|
8 | }
|
||||||
|
9 |
|
||||||
|
10 | fn (p Point) += (q Point) Point {
|
||||||
|
| ~~
|
||||||
|
11 | return Point{p.x + q.x, p.y + q.y}
|
||||||
|
12 | }
|
21
vlib/v/parser/tests/argumented_op_overloading_fn_decl_err.vv
Normal file
21
vlib/v/parser/tests/argumented_op_overloading_fn_decl_err.vv
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
struct Point {
|
||||||
|
x i64
|
||||||
|
y i64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (p Point) foo() {
|
||||||
|
println(p.x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (p Point) += (q Point) Point {
|
||||||
|
return Point{p.x + q.x, p.y + q.y}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
mut p := Point{1, 2}
|
||||||
|
q := Point{3, 4}
|
||||||
|
p += q
|
||||||
|
p -= q
|
||||||
|
println(p)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
vlib/v/parser/tests/argumented_op_overloading_fn_op_overloaded_decl_err.vv:14:14: error: cannot overload `+=`, operator is implicitly overloaded because the `+` operator is overloaded
|
||||||
|
12 | }
|
||||||
|
13 |
|
||||||
|
14 | fn (p Point) += (q Point) Point {
|
||||||
|
| ~~
|
||||||
|
15 | return Point{p.x + q.x, p.y + q.y}
|
||||||
|
16 | }
|
|
@ -0,0 +1,25 @@
|
||||||
|
struct Point {
|
||||||
|
x i64
|
||||||
|
y i64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (p Point) foo() {
|
||||||
|
println(p.x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (p Point) + (q Point) Point {
|
||||||
|
return Point{p.x + q.x, p.y + q.y}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (p Point) += (q Point) Point {
|
||||||
|
return Point{p.x + q.x, p.y + q.y}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
mut p := Point{1, 2}
|
||||||
|
q := Point{3, 4}
|
||||||
|
p += q
|
||||||
|
p -= q
|
||||||
|
println(p)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user