mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: move check_types() on top; small c2v fixes
This commit is contained in:
parent
0021fbbaa9
commit
8f9f681e81
@ -6,6 +6,74 @@ module checker
|
||||
import v.ast
|
||||
import v.token
|
||||
|
||||
// TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged
|
||||
pub fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
|
||||
if got == expected {
|
||||
return true
|
||||
}
|
||||
got_is_ptr := got.is_ptr()
|
||||
exp_is_ptr := expected.is_ptr()
|
||||
if got_is_ptr && exp_is_ptr {
|
||||
if got.nr_muls() != expected.nr_muls() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
exp_idx := expected.idx()
|
||||
got_idx := got.idx()
|
||||
if exp_idx == got_idx {
|
||||
return true
|
||||
}
|
||||
if exp_idx == ast.voidptr_type_idx || exp_idx == ast.byteptr_type_idx
|
||||
|| (expected.is_ptr() && expected.deref().idx() == ast.byte_type_idx) {
|
||||
if got.is_ptr() || got.is_pointer() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// allow direct int-literal assignment for pointers for now
|
||||
// maybe in the future optionals should be used for that
|
||||
if expected.is_real_pointer() {
|
||||
if got == ast.int_literal_type {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if got_idx == ast.voidptr_type_idx || got_idx == ast.byteptr_type_idx
|
||||
|| (got_idx == ast.byte_type_idx && got.is_ptr()) {
|
||||
if expected.is_ptr() || expected.is_pointer() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if expected == ast.charptr_type && got == ast.char_type.ref() {
|
||||
return true
|
||||
}
|
||||
if expected.has_flag(.optional) {
|
||||
sym := c.table.get_type_symbol(got)
|
||||
if (sym.kind == .interface_ && sym.name == 'IError')
|
||||
|| got in [ast.none_type, ast.error_type] {
|
||||
return true
|
||||
} else if !c.check_basic(got, expected.clear_flag(.optional)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if !c.check_basic(got, expected) { // TODO: this should go away...
|
||||
return false
|
||||
}
|
||||
if got.is_number() && expected.is_number() {
|
||||
if got == ast.rune_type && expected == ast.byte_type {
|
||||
return true
|
||||
} else if expected == ast.rune_type && got == ast.byte_type {
|
||||
return true
|
||||
}
|
||||
if c.promote_num(expected, got) != expected {
|
||||
// println('could not promote ${c.table.get_type_symbol(got).name} to ${c.table.get_type_symbol(expected).name}')
|
||||
return false
|
||||
}
|
||||
}
|
||||
if expected.has_flag(.generic) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, language ast.Language, arg ast.CallArg) ? {
|
||||
if got == 0 {
|
||||
return error('unexpected 0 type')
|
||||
@ -190,7 +258,7 @@ fn (mut c Checker) check_shift(mut node ast.InfixExpr, left_type ast.Type, right
|
||||
c.error('invalid operation: shift on type `$left_sym.name`', node.left.position())
|
||||
return ast.void_type
|
||||
}
|
||||
if !right_type.is_int() {
|
||||
if !right_type.is_int() && !c.pref.translated {
|
||||
left_sym := c.table.get_type_symbol(left_type)
|
||||
right_sym := c.table.get_type_symbol(right_type)
|
||||
c.error('cannot shift non-integer type `$right_sym.name` into type `$left_sym.name`',
|
||||
@ -260,7 +328,7 @@ fn (mut c Checker) check_shift(mut node ast.InfixExpr, left_type ast.Type, right
|
||||
ast.u64_type { 63 }
|
||||
else { 64 }
|
||||
}
|
||||
if ival > moffset {
|
||||
if ival > moffset && !c.pref.translated {
|
||||
c.error('shift count for type `$left_sym_final.name` too large (maximum: $moffset bits)',
|
||||
node.right.position())
|
||||
return left_type
|
||||
@ -354,74 +422,6 @@ fn (c &Checker) promote_num(left_type ast.Type, right_type ast.Type) ast.Type {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: promote(), check_types(), symmetric_check() and check() overlap - should be rearranged
|
||||
pub fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
|
||||
if got == expected {
|
||||
return true
|
||||
}
|
||||
got_is_ptr := got.is_ptr()
|
||||
exp_is_ptr := expected.is_ptr()
|
||||
if got_is_ptr && exp_is_ptr {
|
||||
if got.nr_muls() != expected.nr_muls() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
exp_idx := expected.idx()
|
||||
got_idx := got.idx()
|
||||
if exp_idx == got_idx {
|
||||
return true
|
||||
}
|
||||
if exp_idx == ast.voidptr_type_idx || exp_idx == ast.byteptr_type_idx
|
||||
|| (expected.is_ptr() && expected.deref().idx() == ast.byte_type_idx) {
|
||||
if got.is_ptr() || got.is_pointer() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// allow direct int-literal assignment for pointers for now
|
||||
// maybe in the future optionals should be used for that
|
||||
if expected.is_real_pointer() {
|
||||
if got == ast.int_literal_type {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if got_idx == ast.voidptr_type_idx || got_idx == ast.byteptr_type_idx
|
||||
|| (got_idx == ast.byte_type_idx && got.is_ptr()) {
|
||||
if expected.is_ptr() || expected.is_pointer() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if expected == ast.charptr_type && got == ast.char_type.ref() {
|
||||
return true
|
||||
}
|
||||
if expected.has_flag(.optional) {
|
||||
sym := c.table.get_type_symbol(got)
|
||||
if (sym.kind == .interface_ && sym.name == 'IError')
|
||||
|| got in [ast.none_type, ast.error_type] {
|
||||
return true
|
||||
} else if !c.check_basic(got, expected.clear_flag(.optional)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if !c.check_basic(got, expected) { // TODO: this should go away...
|
||||
return false
|
||||
}
|
||||
if got.is_number() && expected.is_number() {
|
||||
if got == ast.rune_type && expected == ast.byte_type {
|
||||
return true
|
||||
} else if expected == ast.rune_type && got == ast.byte_type {
|
||||
return true
|
||||
}
|
||||
if c.promote_num(expected, got) != expected {
|
||||
// println('could not promote ${c.table.get_type_symbol(got).name} to ${c.table.get_type_symbol(expected).name}')
|
||||
return false
|
||||
}
|
||||
}
|
||||
if expected.has_flag(.generic) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) check_expected(got ast.Type, expected ast.Type) ? {
|
||||
if !c.check_types(got, expected) {
|
||||
return error(c.expected_msg(got, expected))
|
||||
|
@ -7463,7 +7463,7 @@ pub fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
|
||||
if right_type.is_ptr() {
|
||||
return right_type.deref()
|
||||
}
|
||||
if !right_type.is_pointer() {
|
||||
if !right_type.is_pointer() && !c.pref.translated {
|
||||
s := c.table.type_to_str(right_type)
|
||||
c.error('invalid indirect of `$s`', node.pos)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user