mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
085a09ebdb
commit
bd3c9e888d
@ -110,26 +110,43 @@ 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 node.exprs[expr_idxs[i]] !is ast.ComptimeCall && !c.check_types(got_typ, exp_type) {
|
||||
if node.exprs[expr_idxs[i]] !is ast.ComptimeCall {
|
||||
got_typ_sym := c.table.sym(got_typ)
|
||||
mut exp_typ_sym := c.table.sym(exp_type)
|
||||
if exp_typ_sym.kind == .interface_ {
|
||||
if c.type_implements(got_typ, exp_type, node.pos) {
|
||||
if !got_typ.is_ptr() && !got_typ.is_pointer() && got_typ_sym.kind != .interface_
|
||||
&& !c.inside_unsafe {
|
||||
c.mark_as_referenced(mut &node.exprs[expr_idxs[i]], true)
|
||||
exp_typ_sym := c.table.sym(exp_type)
|
||||
pos := node.exprs[expr_idxs[i]].pos()
|
||||
if c.check_types(got_typ, exp_type) {
|
||||
if exp_type.is_unsigned() && got_typ.is_int_literal() {
|
||||
if node.exprs[expr_idxs[i]] is ast.IntegerLiteral {
|
||||
var := (node.exprs[expr_idxs[i]] as ast.IntegerLiteral).val
|
||||
if var[0] == `-` {
|
||||
c.note('cannot use a negative value as value of type `${c.table.type_to_str(exp_type)}` in return argument',
|
||||
pos)
|
||||
}
|
||||
} else {
|
||||
if node.exprs[expr_idxs[i]] !is ast.Ident {
|
||||
c.note('use signed type `${c.table.type_to_str(got_typ)}` as unsigned type `${c.table.type_to_str(exp_type)}` in return argument may cause unexpected',
|
||||
pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if got_typ_sym.kind == .function && exp_typ_sym.kind == .function {
|
||||
if (got_typ_sym.info as ast.FnType).is_anon {
|
||||
} else {
|
||||
if exp_typ_sym.kind == .interface_ {
|
||||
if c.type_implements(got_typ, exp_type, node.pos) {
|
||||
if !got_typ.is_ptr() && !got_typ.is_pointer()
|
||||
&& got_typ_sym.kind != .interface_ && !c.inside_unsafe {
|
||||
c.mark_as_referenced(mut &node.exprs[expr_idxs[i]], true)
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if got_typ_sym.kind == .function && exp_typ_sym.kind == .function {
|
||||
if (got_typ_sym.info as ast.FnType).is_anon {
|
||||
continue
|
||||
}
|
||||
}
|
||||
c.error('cannot use `$got_typ_sym.name` as type `${c.table.type_to_str(exp_type)}` in return argument',
|
||||
pos)
|
||||
}
|
||||
pos := node.exprs[expr_idxs[i]].pos()
|
||||
c.error('cannot use `$got_typ_sym.name` as type `${c.table.type_to_str(exp_type)}` in return argument',
|
||||
pos)
|
||||
}
|
||||
if (got_typ.is_ptr() || got_typ.is_pointer())
|
||||
&& (!exp_type.is_ptr() && !exp_type.is_pointer()) {
|
||||
|
13
vlib/v/checker/tests/fn_return_unsign_type_mismatch.out
Normal file
13
vlib/v/checker/tests/fn_return_unsign_type_mismatch.out
Normal file
@ -0,0 +1,13 @@
|
||||
vlib/v/checker/tests/fn_return_unsign_type_mismatch.vv:2:9: notice: use signed type `int literal` as unsigned type `u64` in return argument may cause unexpected
|
||||
1 | fn foo() u64 {
|
||||
2 | return -(3 - 1)
|
||||
| ^
|
||||
3 | }
|
||||
4 |
|
||||
vlib/v/checker/tests/fn_return_unsign_type_mismatch.vv:6:9: notice: cannot use a negative value as value of type `u64` in return argument
|
||||
4 |
|
||||
5 | fn bar() u64 {
|
||||
6 | return -1
|
||||
| ~~
|
||||
7 | }
|
||||
8 |
|
12
vlib/v/checker/tests/fn_return_unsign_type_mismatch.vv
Normal file
12
vlib/v/checker/tests/fn_return_unsign_type_mismatch.vv
Normal file
@ -0,0 +1,12 @@
|
||||
fn foo() u64 {
|
||||
return -(3 - 1)
|
||||
}
|
||||
|
||||
fn bar() u64 {
|
||||
return -1
|
||||
}
|
||||
|
||||
fn main() {
|
||||
dump(foo())
|
||||
dump(bar())
|
||||
}
|
@ -209,7 +209,7 @@ pub mut:
|
||||
cache_manager vcache.CacheManager
|
||||
gc_mode GarbageCollectionMode = .unknown // .no_gc, .boehm, .boehm_leak, ...
|
||||
assert_failure_mode AssertFailureMode // whether to call abort() or print_backtrace() after an assertion failure
|
||||
message_limit int = 100 // the maximum amount of warnings/errors/notices that will be accumulated
|
||||
message_limit int = 150 // the maximum amount of warnings/errors/notices that will be accumulated
|
||||
nofloat bool // for low level code, like kernels: replaces f32 with u32 and f64 with u64
|
||||
// checker settings:
|
||||
checker_match_exhaustive_cutoff_limit int = 12
|
||||
|
Loading…
Reference in New Issue
Block a user