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:
|
||||
typ table.Type
|
||||
is_tmp_autofree bool
|
||||
pos token.Position
|
||||
// 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)
|
||||
is_generic := left_type.has_flag(.generic)
|
||||
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))
|
||||
method_name := call_expr.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 {
|
||||
arg_type = c.expr(arg.expr)
|
||||
}
|
||||
call_expr.return_type = left_type
|
||||
call_expr.receiver_type = left_type
|
||||
if method_name == 'map' {
|
||||
// check fn
|
||||
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)
|
||||
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)
|
||||
if sym.kind == .array_fixed {
|
||||
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 {
|
||||
inited_fields[field.name] = i
|
||||
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 {
|
||||
continue
|
||||
}
|
||||
|
@ -3894,6 +3901,9 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
|||
if sym.kind != .struct_ {
|
||||
field_name := c_name(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)
|
||||
mut cloned := false
|
||||
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
|
||||
for field in info.fields {
|
||||
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 {
|
||||
continue
|
||||
}
|
||||
|
@ -4132,8 +4146,13 @@ fn verror(s string) {
|
|||
}
|
||||
|
||||
fn (g &Gen) error(s string, pos token.Position) {
|
||||
p := if pos.line_nr == 0 { '?' } else { '${pos.line_nr + 1}' }
|
||||
util.verror('$g.file.path:$p: cgen error', s)
|
||||
ferror := util.formatted_error('cgen error:', s, g.file.path, pos)
|
||||
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() {
|
||||
|
|
|
@ -326,7 +326,10 @@ pub fn (g &Gen) unwrap_generic(typ table.Type) table.Type {
|
|||
fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||
// TODO: there are still due to unchecked exprs (opt/some fn arg)
|
||||
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.typ(node.receiver_type)
|
||||
|
@ -545,6 +548,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
|||
// Handle `print(x)`
|
||||
if is_print && node.args[0].typ != table.string_type { // && !free_tmp_arg_vars {
|
||||
typ := node.args[0].typ
|
||||
if typ == 0 {
|
||||
g.checker_bug('print arg.typ is 0', node.pos)
|
||||
}
|
||||
mut styp := g.typ(typ)
|
||||
sym := g.table.get_type_symbol(typ)
|
||||
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) {
|
||||
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
|
||||
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)
|
||||
if arg.is_mut && !arg_is_ptr {
|
||||
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 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)
|
||||
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
|
||||
|
|
|
@ -140,6 +140,7 @@ pub fn (mut p Parser) call_args() []ast.CallArg {
|
|||
share: table.sharetype_from_flags(is_shared, is_atomic)
|
||||
expr: e
|
||||
comments: comments
|
||||
pos: p.tok.position()
|
||||
}
|
||||
if p.tok.kind != .rpar {
|
||||
p.check(.comma)
|
||||
|
|
Loading…
Reference in New Issue