checker: move check_types() on top; small c2v fixes

pull/12779/head
Alexander Medvednikov 2021-12-09 05:44:41 +03:00
parent 0021fbbaa9
commit 8f9f681e81
2 changed files with 71 additions and 71 deletions

View File

@ -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))

View File

@ -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)
}