cgen: show more informative errors, instead of a `invalid type (typ=0 idx=0)` verror panic
parent
60659f1407
commit
70cbf56655
|
@ -318,6 +318,7 @@ pub:
|
||||||
pub mut:
|
pub mut:
|
||||||
typ table.Type
|
typ table.Type
|
||||||
is_tmp_autofree bool
|
is_tmp_autofree bool
|
||||||
|
pos token.Position
|
||||||
// tmp_name string // for autofree
|
// tmp_name string // for autofree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1057,6 +1057,10 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
left_type := c.expr(call_expr.left)
|
left_type := c.expr(call_expr.left)
|
||||||
is_generic := left_type.has_flag(.generic)
|
is_generic := left_type.has_flag(.generic)
|
||||||
call_expr.left_type = left_type
|
call_expr.left_type = left_type
|
||||||
|
// Set default values for .return_type & .receiver_type too,
|
||||||
|
// or there will be hard to diagnose 0 type panics in cgen.
|
||||||
|
call_expr.return_type = left_type
|
||||||
|
call_expr.receiver_type = left_type
|
||||||
left_type_sym := c.table.get_type_symbol(c.unwrap_generic(left_type))
|
left_type_sym := c.table.get_type_symbol(c.unwrap_generic(left_type))
|
||||||
method_name := call_expr.name
|
method_name := call_expr.name
|
||||||
mut unknown_method_msg := 'unknown method: `${left_type_sym.source_name}.$method_name`'
|
mut unknown_method_msg := 'unknown method: `${left_type_sym.source_name}.$method_name`'
|
||||||
|
@ -1095,8 +1099,6 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
for arg in call_expr.args {
|
for arg in call_expr.args {
|
||||||
arg_type = c.expr(arg.expr)
|
arg_type = c.expr(arg.expr)
|
||||||
}
|
}
|
||||||
call_expr.return_type = left_type
|
|
||||||
call_expr.receiver_type = left_type
|
|
||||||
if method_name == 'map' {
|
if method_name == 'map' {
|
||||||
// check fn
|
// check fn
|
||||||
c.check_map_and_filter(true, elem_typ, call_expr)
|
c.check_map_and_filter(true, elem_typ, call_expr)
|
||||||
|
|
|
@ -2309,6 +2309,9 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||||
g.typeof_name(left)
|
g.typeof_name(left)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if node.expr_type == 0 {
|
||||||
|
g.checker_bug('unexpected SelectorExpr.expr_type = 0', node.pos)
|
||||||
|
}
|
||||||
sym := g.table.get_type_symbol(node.expr_type)
|
sym := g.table.get_type_symbol(node.expr_type)
|
||||||
if sym.kind == .array_fixed {
|
if sym.kind == .array_fixed {
|
||||||
assert node.field_name == 'len'
|
assert node.field_name == 'len'
|
||||||
|
@ -3886,7 +3889,11 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
for i, field in struct_init.fields {
|
for i, field in struct_init.fields {
|
||||||
inited_fields[field.name] = i
|
inited_fields[field.name] = i
|
||||||
if sym.info is table.Struct as struct_info {
|
if sym.info is table.Struct as struct_info {
|
||||||
tfield := struct_info.fields.filter(it.name == field.name)[0]
|
equal_fields := struct_info.fields.filter(it.name == field.name)
|
||||||
|
if equal_fields.len == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tfield := equal_fields[0]
|
||||||
if tfield.embed_alias_for.len != 0 {
|
if tfield.embed_alias_for.len != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -3894,6 +3901,9 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
if sym.kind != .struct_ {
|
if sym.kind != .struct_ {
|
||||||
field_name := c_name(field.name)
|
field_name := c_name(field.name)
|
||||||
g.write('.$field_name = ')
|
g.write('.$field_name = ')
|
||||||
|
if field.typ == 0 {
|
||||||
|
g.checker_bug('struct init, field.typ is 0', field.pos)
|
||||||
|
}
|
||||||
field_type_sym := g.table.get_type_symbol(field.typ)
|
field_type_sym := g.table.get_type_symbol(field.typ)
|
||||||
mut cloned := false
|
mut cloned := false
|
||||||
if g.autofree && !field.typ.is_ptr() && field_type_sym.kind in [.array, .string] {
|
if g.autofree && !field.typ.is_ptr() && field_type_sym.kind in [.array, .string] {
|
||||||
|
@ -3931,7 +3941,11 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
// nr_fields = info.fields.len
|
// nr_fields = info.fields.len
|
||||||
for field in info.fields {
|
for field in info.fields {
|
||||||
if sym.info is table.Struct as struct_info {
|
if sym.info is table.Struct as struct_info {
|
||||||
tfield := struct_info.fields.filter(it.name == field.name)[0]
|
equal_fields := struct_info.fields.filter(it.name == field.name)
|
||||||
|
if equal_fields.len == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
tfield := equal_fields[0]
|
||||||
if tfield.embed_alias_for.len != 0 {
|
if tfield.embed_alias_for.len != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -4132,8 +4146,13 @@ fn verror(s string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g &Gen) error(s string, pos token.Position) {
|
fn (g &Gen) error(s string, pos token.Position) {
|
||||||
p := if pos.line_nr == 0 { '?' } else { '${pos.line_nr + 1}' }
|
ferror := util.formatted_error('cgen error:', s, g.file.path, pos)
|
||||||
util.verror('$g.file.path:$p: cgen error', s)
|
eprintln(ferror)
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (g &Gen) checker_bug(s string, pos token.Position) {
|
||||||
|
g.error('checker bug; $s', pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) write_init_function() {
|
fn (mut g Gen) write_init_function() {
|
||||||
|
|
|
@ -326,7 +326,10 @@ pub fn (g &Gen) unwrap_generic(typ table.Type) table.Type {
|
||||||
fn (mut g Gen) method_call(node ast.CallExpr) {
|
fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||||
// TODO: there are still due to unchecked exprs (opt/some fn arg)
|
// TODO: there are still due to unchecked exprs (opt/some fn arg)
|
||||||
if node.left_type == 0 {
|
if node.left_type == 0 {
|
||||||
verror('method receiver type is 0, this means there are some uchecked exprs')
|
g.checker_bug('CallExpr.left_type is 0 in method_call', node.pos)
|
||||||
|
}
|
||||||
|
if node.receiver_type == 0 {
|
||||||
|
g.checker_bug('CallExpr.receiver_type is 0 in method_call', node.pos)
|
||||||
}
|
}
|
||||||
// mut receiver_type_name := g.cc_type(node.receiver_type)
|
// mut receiver_type_name := g.cc_type(node.receiver_type)
|
||||||
// mut receiver_type_name := g.typ(node.receiver_type)
|
// mut receiver_type_name := g.typ(node.receiver_type)
|
||||||
|
@ -545,6 +548,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||||
// Handle `print(x)`
|
// Handle `print(x)`
|
||||||
if is_print && node.args[0].typ != table.string_type { // && !free_tmp_arg_vars {
|
if is_print && node.args[0].typ != table.string_type { // && !free_tmp_arg_vars {
|
||||||
typ := node.args[0].typ
|
typ := node.args[0].typ
|
||||||
|
if typ == 0 {
|
||||||
|
g.checker_bug('print arg.typ is 0', node.pos)
|
||||||
|
}
|
||||||
mut styp := g.typ(typ)
|
mut styp := g.typ(typ)
|
||||||
sym := g.table.get_type_symbol(typ)
|
sym := g.table.get_type_symbol(typ)
|
||||||
if typ.is_ptr() {
|
if typ.is_ptr() {
|
||||||
|
@ -831,6 +837,9 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
|
||||||
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
|
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
|
||||||
arg_is_ptr := expected_type.is_ptr() || expected_type.idx() in table.pointer_type_idxs
|
arg_is_ptr := expected_type.is_ptr() || expected_type.idx() in table.pointer_type_idxs
|
||||||
expr_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in table.pointer_type_idxs
|
expr_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in table.pointer_type_idxs
|
||||||
|
if expected_type == 0 {
|
||||||
|
g.checker_bug('ref_or_deref_arg expected_type is 0', arg.pos)
|
||||||
|
}
|
||||||
exp_sym := g.table.get_type_symbol(expected_type)
|
exp_sym := g.table.get_type_symbol(expected_type)
|
||||||
if arg.is_mut && !arg_is_ptr {
|
if arg.is_mut && !arg_is_ptr {
|
||||||
g.write('&/*mut*/')
|
g.write('&/*mut*/')
|
||||||
|
@ -851,6 +860,9 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !g.is_json_fn {
|
if !g.is_json_fn {
|
||||||
|
if arg.typ == 0 {
|
||||||
|
g.checker_bug('ref_or_deref_arg arg.typ is 0', arg.pos)
|
||||||
|
}
|
||||||
arg_typ_sym := g.table.get_type_symbol(arg.typ)
|
arg_typ_sym := g.table.get_type_symbol(arg.typ)
|
||||||
expected_deref_type := if expected_type.is_ptr() { expected_type.deref() } else { expected_type }
|
expected_deref_type := if expected_type.is_ptr() { expected_type.deref() } else { expected_type }
|
||||||
is_sum_type := g.table.get_type_symbol(expected_deref_type).kind == .sum_type
|
is_sum_type := g.table.get_type_symbol(expected_deref_type).kind == .sum_type
|
||||||
|
|
|
@ -140,6 +140,7 @@ pub fn (mut p Parser) call_args() []ast.CallArg {
|
||||||
share: table.sharetype_from_flags(is_shared, is_atomic)
|
share: table.sharetype_from_flags(is_shared, is_atomic)
|
||||||
expr: e
|
expr: e
|
||||||
comments: comments
|
comments: comments
|
||||||
|
pos: p.tok.position()
|
||||||
}
|
}
|
||||||
if p.tok.kind != .rpar {
|
if p.tok.kind != .rpar {
|
||||||
p.check(.comma)
|
p.check(.comma)
|
||||||
|
|
Loading…
Reference in New Issue