mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parent
398bd2280d
commit
032cb3f115
@ -598,26 +598,28 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||
c.error('unwrapped optional cannot be used in an infix expression', opt_infix_pos)
|
||||
}
|
||||
// Dual sides check (compatibility check)
|
||||
if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type))
|
||||
&& !c.pref.translated && !c.file.is_translated && !node.left.is_auto_deref_var()
|
||||
&& !node.right.is_auto_deref_var() {
|
||||
// for type-unresolved consts
|
||||
if left_type == ast.void_type || right_type == ast.void_type {
|
||||
return ast.void_type
|
||||
}
|
||||
if left_type.nr_muls() > 0 && right_type.is_int() {
|
||||
// pointer arithmetic is fine, it is checked in other places
|
||||
return return_type
|
||||
}
|
||||
c.error('infix expr: cannot use `$right_sym.name` (right expression) as `$left_sym.name`',
|
||||
left_right_pos)
|
||||
} else if left_type.is_ptr() {
|
||||
for_ptr_op := c.table.type_is_for_pointer_arithmetic(left_type)
|
||||
if left_sym.language == .v && !c.pref.translated && !c.inside_unsafe && !for_ptr_op
|
||||
&& right_type.is_int() {
|
||||
sugg := ' (you can use it inside an `unsafe` block)'
|
||||
c.error('infix expr: cannot use `$right_sym.name` (right expression) as `$left_sym.name` $sugg',
|
||||
if node.left !is ast.ComptimeCall && node.right !is ast.ComptimeCall {
|
||||
if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type))
|
||||
&& !c.pref.translated && !c.file.is_translated && !node.left.is_auto_deref_var()
|
||||
&& !node.right.is_auto_deref_var() {
|
||||
// for type-unresolved consts
|
||||
if left_type == ast.void_type || right_type == ast.void_type {
|
||||
return ast.void_type
|
||||
}
|
||||
if left_type.nr_muls() > 0 && right_type.is_int() {
|
||||
// pointer arithmetic is fine, it is checked in other places
|
||||
return return_type
|
||||
}
|
||||
c.error('infix expr: cannot use `$right_sym.name` (right expression) as `$left_sym.name`',
|
||||
left_right_pos)
|
||||
} else if left_type.is_ptr() {
|
||||
for_ptr_op := c.table.type_is_for_pointer_arithmetic(left_type)
|
||||
if left_sym.language == .v && !c.pref.translated && !c.inside_unsafe && !for_ptr_op
|
||||
&& right_type.is_int() {
|
||||
sugg := ' (you can use it inside an `unsafe` block)'
|
||||
c.error('infix expr: cannot use `$right_sym.name` (right expression) as `$left_sym.name` $sugg',
|
||||
left_right_pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -104,7 +104,7 @@ pub fn (mut c Checker) return_stmt(mut node ast.Return) {
|
||||
c.error('cannot use `${c.table.type_to_str(got_typ)}` as type `${c.table.type_to_str(exp_type)}` in return argument',
|
||||
pos)
|
||||
}
|
||||
if !c.check_types(got_typ, exp_type) {
|
||||
if node.exprs[expr_idxs[i]] !is ast.ComptimeCall && !c.check_types(got_typ, exp_type) {
|
||||
got_typ_sym := c.table.sym(got_typ)
|
||||
mut exp_typ_sym := c.table.sym(exp_type)
|
||||
if exp_typ_sym.kind == .interface_ {
|
||||
|
24
vlib/v/tests/comptime_call_type_test.v
Normal file
24
vlib/v/tests/comptime_call_type_test.v
Normal file
@ -0,0 +1,24 @@
|
||||
struct App {}
|
||||
|
||||
fn (mut app App) method_one() int {
|
||||
return 1
|
||||
}
|
||||
|
||||
fn (mut app App) method_two() int {
|
||||
return 2
|
||||
}
|
||||
|
||||
fn reflect_call(method_name string) int {
|
||||
a := App{}
|
||||
$for method in App.methods {
|
||||
if method.name == method_name {
|
||||
return a.$method()
|
||||
}
|
||||
}
|
||||
panic('Method not supported: $method_name')
|
||||
}
|
||||
|
||||
fn test_comptime_call_type() {
|
||||
result := reflect_call('method_one')
|
||||
assert result == 1
|
||||
}
|
Loading…
Reference in New Issue
Block a user