checker: check if the type in `as` exists, skip void type errors
parent
5a6d440f68
commit
ef36520509
|
@ -96,11 +96,11 @@ pub fn (c &Checker) check_basic(got, expected table.Type) bool {
|
|||
// TODO: there is a bug when casting sumtype the other way if its pointer
|
||||
// so until fixed at least show v (not C) error `x(variant) = y(SumType*)`
|
||||
// if got_type_sym.kind == .sum_type {
|
||||
// sum_info := got_type_sym.info as table.SumType
|
||||
// // TODO: handle `match SumType { &PtrVariant {} }` currently just checking base
|
||||
// if expected.set_nr_muls(0) in sum_info.variants {
|
||||
// return true
|
||||
// }
|
||||
// sum_info := got_type_sym.info as table.SumType
|
||||
// // TODO: handle `match SumType { &PtrVariant {} }` currently just checking base
|
||||
// if expected.set_nr_muls(0) in sum_info.variants {
|
||||
// return true
|
||||
// }
|
||||
// }
|
||||
if exp_type_sym.kind == .sum_type {
|
||||
sum_info := exp_type_sym.info as table.SumType
|
||||
|
@ -133,10 +133,12 @@ pub fn (c &Checker) check_basic(got, expected table.Type) bool {
|
|||
[inline]
|
||||
fn (c &Checker) check_shift(left_type, right_type table.Type, left_pos, right_pos token.Position) table.Type {
|
||||
if !left_type.is_int() {
|
||||
c.error('cannot shift type ${c.table.get_type_symbol(right_type).name} into non-integer type ${c.table.get_type_symbol(left_type).name}', left_pos)
|
||||
c.error('cannot shift type ${c.table.get_type_symbol(right_type).name} into non-integer type ${c.table.get_type_symbol(left_type).name}',
|
||||
left_pos)
|
||||
return table.void_type
|
||||
} else if !right_type.is_int() {
|
||||
c.error('cannot shift non-integer type ${c.table.get_type_symbol(right_type).name} into type ${c.table.get_type_symbol(left_type).name}', right_pos)
|
||||
c.error('cannot shift non-integer type ${c.table.get_type_symbol(right_type).name} into type ${c.table.get_type_symbol(left_type).name}',
|
||||
right_pos)
|
||||
return table.void_type
|
||||
}
|
||||
return left_type
|
||||
|
@ -269,9 +271,8 @@ pub fn (c &Checker) get_default_fmt(ftyp, typ table.Type) byte {
|
|||
return `p`
|
||||
} else {
|
||||
sym := c.table.get_type_symbol(ftyp)
|
||||
if ftyp in [table.string_type, table.bool_type] || sym.kind in
|
||||
[.enum_, .array, .array_fixed, .struct_, .map] || ftyp.has_flag(.optional) ||
|
||||
sym.has_method('str') {
|
||||
if ftyp in [table.string_type, table.bool_type] || sym.kind in [.enum_, .array, .array_fixed,
|
||||
.struct_, .map] || ftyp.has_flag(.optional) || sym.has_method('str') {
|
||||
return `s`
|
||||
} else {
|
||||
return `_`
|
||||
|
@ -292,8 +293,10 @@ pub fn (c &Checker) string_inter_lit(mut node ast.StringInterLiteral) table.Type
|
|||
if fmt == `_` { // set default representation for type if none has been given
|
||||
fmt = c.get_default_fmt(ftyp, typ)
|
||||
if fmt == `_` {
|
||||
c.error('no known default format for type `${c.table.get_type_name(ftyp)}`',
|
||||
if typ != table.void_type {
|
||||
c.error('no known default format for type `${c.table.get_type_name(ftyp)}`',
|
||||
node.fmt_poss[i])
|
||||
}
|
||||
} else {
|
||||
node.fmts[i] = fmt
|
||||
node.need_fmts[i] = false
|
||||
|
@ -305,13 +308,12 @@ pub fn (c &Checker) string_inter_lit(mut node ast.StringInterLiteral) table.Type
|
|||
if node.pluss[i] && !typ.is_number() {
|
||||
c.error('plus prefix only allowd for numbers', node.fmt_poss[i])
|
||||
}
|
||||
if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`]) ||
|
||||
(typ.is_signed() && fmt !in [`d`, `x`, `X`, `o`, `c`]) ||
|
||||
(typ.is_any_int() && fmt !in [`d`, `c`, `x`, `X`, `o`, `u`, `x`, `X`, `o`]) ||
|
||||
(typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`]) ||
|
||||
(typ.is_pointer() && fmt !in [`p`, `x`, `X`]) ||
|
||||
(typ.is_string() && fmt != `s`) ||
|
||||
(typ.idx() in [table.i64_type_idx, table.f64_type_idx] && fmt == `c`) {
|
||||
if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`]) || (typ.is_signed() &&
|
||||
fmt !in [`d`, `x`, `X`, `o`, `c`]) || (typ.is_any_int() && fmt !in [`d`, `c`, `x`, `X`, `o`,
|
||||
`u`, `x`, `X`, `o`]) || (typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`]) || (typ.is_pointer() &&
|
||||
fmt !in [`p`, `x`, `X`]) || (typ.is_string() && fmt != `s`) || (typ.idx() in [table.i64_type_idx,
|
||||
table.f64_type_idx
|
||||
] && fmt == `c`) {
|
||||
c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`',
|
||||
node.fmt_poss[i])
|
||||
}
|
||||
|
|
|
@ -780,8 +780,8 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
|||
c.error('type mismatch, should use `$elem_sym.name[]`', arg_expr.position())
|
||||
}
|
||||
} else {
|
||||
if arg_sym.kind != elem_sym.kind && ((elem_sym.kind == .int && arg_sym.kind != .any_int) ||
|
||||
(elem_sym.kind == .f64 && arg_sym.kind != .any_float)) {
|
||||
if arg_sym.kind != elem_sym.kind && ((elem_sym.kind == .int && arg_sym.kind !=
|
||||
.any_int) || (elem_sym.kind == .f64 && arg_sym.kind != .any_float)) {
|
||||
c.error('type mismatch, should use `$elem_sym.name`', arg_expr.position())
|
||||
}
|
||||
}
|
||||
|
@ -838,8 +838,10 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
|||
if exp_arg_sym.kind == .string && got_arg_sym.has_method('str') {
|
||||
continue
|
||||
}
|
||||
c.error('cannot use type `$got_arg_sym.str()` as type `$exp_arg_sym.str()` in argument ${i+1} to `${left_type_sym.name}.$method_name`',
|
||||
call_expr.pos)
|
||||
if got_arg_typ != table.void_type {
|
||||
c.error('cannot use type `$got_arg_sym.str()` as type `$exp_arg_sym.str()` in argument ${i+1} to `${left_type_sym.name}.$method_name`',
|
||||
call_expr.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: typ optimize.. this node can get processed more than once
|
||||
|
@ -1207,7 +1209,9 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T
|
|||
return field.typ
|
||||
}
|
||||
if sym.kind != .struct_ {
|
||||
c.error('`$sym.name` is not a struct', selector_expr.pos)
|
||||
if sym.kind != .placeholder {
|
||||
c.error('`$sym.name` is not a struct', selector_expr.pos)
|
||||
}
|
||||
} else {
|
||||
c.error('type `$sym.name` has no field or method `$field_name`', selector_expr.pos)
|
||||
}
|
||||
|
@ -1731,7 +1735,9 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
|||
}
|
||||
value_type := c.table.value_type(typ)
|
||||
if value_type == table.void_type || typ.has_flag(.optional) {
|
||||
c.error('for in: cannot index `${c.table.type_to_str(typ)}`', it.cond.position())
|
||||
if typ != table.void_type {
|
||||
c.error('for in: cannot index `${c.table.type_to_str(typ)}`', it.cond.position())
|
||||
}
|
||||
}
|
||||
it.cond_type = typ
|
||||
it.kind = sym.kind
|
||||
|
@ -1849,6 +1855,10 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
|
|||
type_sym := c.table.get_type_symbol(node.typ)
|
||||
if expr_type_sym.kind == .sum_type {
|
||||
info := expr_type_sym.info as table.SumType
|
||||
if type_sym.kind == .placeholder {
|
||||
// Unknown type used in the right part of `as`
|
||||
c.error('unknown type `$type_sym.name`', node.pos)
|
||||
}
|
||||
if node.typ !in info.variants {
|
||||
c.error('cannot cast `$expr_type_sym.name` to `$type_sym.name`', node.pos)
|
||||
// c.error('only $info.variants can be casted to `$typ`', it.pos)
|
||||
|
|
|
@ -310,7 +310,7 @@ pub fn (mut g Gen) write_typeof_functions() {
|
|||
g.writeln('// >> typeof() support for sum types')
|
||||
for typ in g.table.types {
|
||||
if typ.kind == .sum_type {
|
||||
sum_info := typ.info as table.SumType
|
||||
sum_info := typ.info as table.SumTypee
|
||||
tidx := g.table.find_type_idx(typ.name)
|
||||
g.writeln('char * v_typeof_sumtype_${tidx}(int sidx) { /* $typ.name */ ')
|
||||
g.writeln(' switch(sidx) {')
|
||||
|
|
Loading…
Reference in New Issue