mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
v: cleanup if smartcasts in the compiler (#24734)
This commit is contained in:
parent
e7905ea841
commit
e14853d6e0
13 changed files with 89 additions and 133 deletions
|
@ -2594,12 +2594,10 @@ pub fn (mut lx IndexExpr) recursive_arraymap_set_is_setter() {
|
|||
lx.is_setter = true
|
||||
if mut lx.left is IndexExpr {
|
||||
lx.left.recursive_arraymap_set_is_setter()
|
||||
} else if mut lx.left is SelectorExpr {
|
||||
if mut lx.left.expr is IndexExpr {
|
||||
} else if mut lx.left is SelectorExpr && lx.left.expr is IndexExpr {
|
||||
lx.left.expr.recursive_arraymap_set_is_setter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return all the registers for the given architecture
|
||||
pub fn all_registers(mut t Table, arch pref.Arch) map[string]ScopeObject {
|
||||
|
|
|
@ -103,11 +103,9 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
|||
c.error('cannot assign a `none` value to a variable', right.pos)
|
||||
}
|
||||
// Handle `left_name := unsafe { none }`
|
||||
if mut right is ast.UnsafeExpr {
|
||||
if mut right.expr is ast.None {
|
||||
if mut right is ast.UnsafeExpr && right.expr is ast.None {
|
||||
c.error('cannot use `none` in `unsafe` blocks', right.expr.pos)
|
||||
}
|
||||
}
|
||||
if mut right is ast.AnonFn {
|
||||
if right.decl.generic_names.len > 0 {
|
||||
c.error('cannot assign generic function to a variable', right.decl.pos)
|
||||
|
@ -159,11 +157,9 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
|||
c.error('cannot dereference a function call on the left side of an assignment, use a temporary variable',
|
||||
left.pos)
|
||||
}
|
||||
} else if mut left is ast.IndexExpr {
|
||||
if left.index is ast.RangeExpr {
|
||||
} else if mut left is ast.IndexExpr && left.index is ast.RangeExpr {
|
||||
c.error('cannot reassign using range expression on the left side of an assignment',
|
||||
left.pos)
|
||||
}
|
||||
} else if mut left is ast.Ident && node.op == .decl_assign {
|
||||
if left.name in c.global_names {
|
||||
c.note('the global variable named `${left.name}` already exists', left.pos)
|
||||
|
@ -199,11 +195,9 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
|||
}
|
||||
if node.right_types.len < node.left.len { // first type or multi return types added above
|
||||
old_inside_ref_lit := c.inside_ref_lit
|
||||
if mut left is ast.Ident {
|
||||
if mut left.info is ast.IdentVar {
|
||||
if mut left is ast.Ident && left.info is ast.IdentVar {
|
||||
c.inside_ref_lit = c.inside_ref_lit || left.info.share == .shared_t
|
||||
}
|
||||
}
|
||||
c.inside_decl_rhs = is_decl
|
||||
mut expr := node.right[i]
|
||||
if left is ast.Ident && left.is_mut() && expr is ast.StructInit && expr.is_anon {
|
||||
|
@ -666,13 +660,11 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
|
|||
}
|
||||
}
|
||||
}
|
||||
if mut left is ast.Ident {
|
||||
if mut left.info is ast.IdentVar {
|
||||
if mut left is ast.Ident && left.info is ast.IdentVar {
|
||||
if left.info.is_static && right_sym.kind == .map {
|
||||
c.error('maps cannot be static', left.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Single side check
|
||||
match node.op {
|
||||
.assign {} // No need to do single side check for =. But here put it first for speed.
|
||||
|
|
|
@ -911,11 +911,9 @@ fn (mut c Checker) fail_if_immutable(mut expr ast.Expr) (string, token.Pos) {
|
|||
}
|
||||
ast.ComptimeSelector {
|
||||
mut expr_left := expr.left
|
||||
if mut expr.left is ast.Ident {
|
||||
if mut expr.left.obj is ast.Var {
|
||||
if mut expr.left is ast.Ident && expr.left.obj is ast.Var {
|
||||
c.fail_if_immutable(mut expr_left)
|
||||
}
|
||||
}
|
||||
return '', expr.pos
|
||||
}
|
||||
ast.Ident {
|
||||
|
@ -1117,6 +1115,9 @@ fn (mut c Checker) fail_if_immutable(mut expr ast.Expr) (string, token.Pos) {
|
|||
}
|
||||
return '', expr.pos
|
||||
}
|
||||
ast.AsCast {
|
||||
to_lock, pos = c.fail_if_immutable(mut expr.expr)
|
||||
}
|
||||
else {
|
||||
if !expr.is_pure_literal() {
|
||||
c.error('unexpected expression `${expr.type_name()}`', expr.pos())
|
||||
|
@ -1678,12 +1679,10 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
|||
c.inside_selector_expr = true
|
||||
mut typ := c.expr(mut node.expr)
|
||||
if node.expr.is_auto_deref_var() {
|
||||
if mut node.expr is ast.Ident {
|
||||
if mut node.expr.obj is ast.Var {
|
||||
if mut node.expr is ast.Ident && node.expr.obj is ast.Var {
|
||||
typ = node.expr.obj.typ
|
||||
}
|
||||
}
|
||||
}
|
||||
c.inside_selector_expr = old_selector_expr
|
||||
c.using_new_err_struct = using_new_err_struct_save
|
||||
if typ == ast.void_type_idx {
|
||||
|
@ -4417,11 +4416,9 @@ fn (mut c Checker) smartcast(mut expr ast.Expr, cur_type ast.Type, to_type_ ast.
|
|||
}
|
||||
}
|
||||
mut expr_str := expr.expr.str()
|
||||
if mut expr.expr is ast.ParExpr {
|
||||
if mut expr.expr.expr is ast.AsCast {
|
||||
if mut expr.expr is ast.ParExpr && expr.expr.expr is ast.AsCast {
|
||||
expr_str = expr.expr.expr.expr.str()
|
||||
}
|
||||
}
|
||||
field := scope.find_struct_field(expr_str, expr.expr_type, expr.field_name)
|
||||
if field != unsafe { nil } {
|
||||
smartcasts << field.smartcasts
|
||||
|
@ -5058,15 +5055,12 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
|||
|| typ.is_pointer() {
|
||||
mut is_ok := false
|
||||
mut is_mut_struct := false
|
||||
if mut node.left is ast.Ident {
|
||||
if mut node.left.obj is ast.Var {
|
||||
if mut node.left is ast.Ident && node.left.obj is ast.Var {
|
||||
// `mut param []T` function parameter
|
||||
is_ok = node.left.obj.is_mut && node.left.obj.is_arg && !typ.deref().is_ptr()
|
||||
&& typ_sym.kind != .struct
|
||||
// `mut param Struct`
|
||||
is_mut_struct = node.left.obj.is_mut && node.left.obj.is_arg
|
||||
&& typ_sym.kind == .struct
|
||||
}
|
||||
is_mut_struct = node.left.obj.is_mut && node.left.obj.is_arg && typ_sym.kind == .struct
|
||||
}
|
||||
if !is_ok && node.index is ast.RangeExpr {
|
||||
s := c.table.type_to_str(typ)
|
||||
|
|
|
@ -799,12 +799,10 @@ fn (mut c Checker) check_append(mut node ast.InfixExpr, left_type ast.Type, righ
|
|||
right := node.right
|
||||
if right is ast.PrefixExpr && right.op == .amp {
|
||||
mut expr2 := right.right
|
||||
if mut expr2 is ast.Ident {
|
||||
if !node.left.is_blank_ident() && expr2.obj is ast.ConstField {
|
||||
if mut expr2 is ast.Ident && !node.left.is_blank_ident() && expr2.obj is ast.ConstField {
|
||||
c.error('cannot have mutable reference to const `${expr2.name}`', expr2.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
if left_value_sym.kind == .interface {
|
||||
if right_final_sym.kind != .array {
|
||||
// []Animal << Cat
|
||||
|
|
|
@ -1520,12 +1520,10 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
|
|||
}
|
||||
node.args[i].typ = arg_typ
|
||||
if c.comptime.comptime_for_field_var != '' {
|
||||
if mut call_arg.expr is ast.Ident {
|
||||
if mut call_arg.expr.obj is ast.Var {
|
||||
if mut call_arg.expr is ast.Ident && call_arg.expr.obj is ast.Var {
|
||||
node.args[i].typ = call_arg.expr.obj.typ
|
||||
}
|
||||
}
|
||||
}
|
||||
arg_typ_sym := c.table.sym(arg_typ)
|
||||
if arg_typ_sym.kind == .none && param.typ.has_flag(.generic) && !param.typ.has_flag(.option) {
|
||||
c.error('cannot use `none` as generic argument', call_arg.pos)
|
||||
|
|
|
@ -318,8 +318,7 @@ fn (mut c Checker) for_stmt(mut node ast.ForStmt) {
|
|||
c.error('non-bool used as for condition', node.pos)
|
||||
}
|
||||
}
|
||||
if mut node.cond is ast.InfixExpr {
|
||||
if node.cond.op == .key_is {
|
||||
if mut node.cond is ast.InfixExpr && node.cond.op == .key_is {
|
||||
if node.cond.right is ast.TypeNode && node.cond.left in [ast.Ident, ast.SelectorExpr] {
|
||||
if c.table.type_kind(node.cond.left_type) in [.sum_type, .interface] {
|
||||
c.smartcast(mut node.cond.left, node.cond.left_type, node.cond.right_type, mut
|
||||
|
@ -327,7 +326,6 @@ fn (mut c Checker) for_stmt(mut node ast.ForStmt) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: update loop var type
|
||||
// how does this work currently?
|
||||
c.check_loop_labels(node.label, node.pos)
|
||||
|
|
|
@ -308,11 +308,9 @@ fn (mut c Checker) get_comptime_number_value(mut expr ast.Expr) ?i64 {
|
|||
if mut expr is ast.IntegerLiteral {
|
||||
return expr.val.i64()
|
||||
}
|
||||
if mut expr is ast.CastExpr {
|
||||
if mut expr.expr is ast.IntegerLiteral {
|
||||
if mut expr is ast.CastExpr && expr.expr is ast.IntegerLiteral {
|
||||
return expr.expr.val.i64()
|
||||
}
|
||||
}
|
||||
if mut expr is ast.Ident {
|
||||
if mut obj := c.table.global_scope.find_const(expr.full_name()) {
|
||||
if obj.typ == 0 {
|
||||
|
|
|
@ -82,11 +82,9 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
|
|||
return
|
||||
}
|
||||
// Handle `return unsafe { none }`
|
||||
if mut expr is ast.UnsafeExpr {
|
||||
if mut expr.expr is ast.None {
|
||||
if mut expr is ast.UnsafeExpr && expr.expr is ast.None {
|
||||
c.error('cannot return `none` in unsafe block', expr.expr.pos)
|
||||
}
|
||||
}
|
||||
if typ == ast.void_type {
|
||||
c.error('`${expr}` used as value', node.pos)
|
||||
return
|
||||
|
@ -102,8 +100,7 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
|
|||
expr_idxs << i
|
||||
}
|
||||
} else {
|
||||
if mut expr is ast.Ident {
|
||||
if mut expr.obj is ast.Var {
|
||||
if mut expr is ast.Ident && expr.obj is ast.Var {
|
||||
if expr.obj.smartcasts.len > 0 {
|
||||
typ = c.unwrap_generic(expr.obj.smartcasts.last())
|
||||
}
|
||||
|
@ -116,7 +113,6 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
got_types << typ
|
||||
expr_idxs << i
|
||||
}
|
||||
|
|
|
@ -231,18 +231,15 @@ fn (mut g Gen) gen_assert_single_expr(expr ast.Expr, typ ast.Type) {
|
|||
&& expr in [ast.IndexExpr, ast.CallExpr, ast.StringLiteral, ast.StringInterLiteral] {
|
||||
should_clone = false
|
||||
}
|
||||
if expr is ast.CTempVar {
|
||||
if expr.orig is ast.CallExpr {
|
||||
if expr is ast.CTempVar && expr.orig is ast.CallExpr {
|
||||
should_clone = false
|
||||
if expr.orig.or_block.kind == .propagate_option {
|
||||
should_clone = true
|
||||
}
|
||||
if expr.orig.is_method && expr.orig.args.len == 0
|
||||
&& expr.orig.name == 'type_name' {
|
||||
if expr.orig.is_method && expr.orig.args.len == 0 && expr.orig.name == 'type_name' {
|
||||
should_clone = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if should_clone {
|
||||
g.write('string_clone(')
|
||||
}
|
||||
|
|
|
@ -34,15 +34,13 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) {
|
|||
}
|
||||
// var.$(field.name)
|
||||
if node.expr is ast.ComptimeSelector && node.expr.is_name {
|
||||
if node.expr.field_expr is ast.SelectorExpr {
|
||||
if node.expr.field_expr.expr is ast.Ident {
|
||||
if node.expr.field_expr is ast.SelectorExpr && node.expr.field_expr.expr is ast.Ident {
|
||||
if node.expr.field_expr.expr.name == g.comptime.comptime_for_field_var {
|
||||
field, _ := g.type_resolver.get_comptime_selector_var_type(node.expr)
|
||||
name = g.styp(g.unwrap_generic(field.typ.clear_flags(.shared_f, .result)))
|
||||
expr_type = field.typ
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if node.expr is ast.Ident && node.expr.ct_expr {
|
||||
expr_type = g.type_resolver.get_type(node.expr)
|
||||
name = g.styp(g.unwrap_generic(expr_type.clear_flags(.shared_f, .result))).replace('*',
|
||||
|
|
|
@ -1227,13 +1227,10 @@ fn (mut g Gen) gen_array_method_call(node ast.CallExpr, left_type ast.Type, left
|
|||
array_depth := g.get_array_depth(array_info.elem_type)
|
||||
to_depth := if array_depth >= 0 { '_to_depth' } else { '' }
|
||||
mut is_range_slice := false
|
||||
if node.left is ast.IndexExpr {
|
||||
if node.left.index is ast.RangeExpr {
|
||||
if node.name == 'clone' {
|
||||
if node.left is ast.IndexExpr && node.left.index is ast.RangeExpr
|
||||
&& node.name == 'clone' {
|
||||
is_range_slice = true
|
||||
}
|
||||
}
|
||||
}
|
||||
to_static := if is_range_slice { '_static' } else { '' }
|
||||
g.write('array_${node.name}${to_static}${to_depth}(')
|
||||
if node.name == 'clone' {
|
||||
|
@ -2072,8 +2069,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
|||
typ = m.return_type
|
||||
}
|
||||
}
|
||||
} else if expr is ast.Ident {
|
||||
if expr.obj is ast.Var {
|
||||
} else if expr is ast.Ident && expr.obj is ast.Var {
|
||||
typ = expr.obj.typ
|
||||
if expr.obj.smartcasts.len > 0 {
|
||||
typ = g.unwrap_generic(expr.obj.smartcasts.last())
|
||||
|
@ -2089,7 +2085,6 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
|||
typ = typ.clear_flag(.option)
|
||||
}
|
||||
}
|
||||
}
|
||||
g.gen_expr_to_string(expr, typ)
|
||||
g.write(')')
|
||||
}
|
||||
|
@ -2744,13 +2739,11 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
|
|||
if (arg_sym.info is ast.Alias || exp_sym.info is ast.Alias) && expected_type != arg_typ {
|
||||
g.expr_opt_with_alias(arg.expr, arg_typ, expected_type)
|
||||
} else {
|
||||
if arg.expr is ast.Ident {
|
||||
if arg.expr.obj is ast.Var {
|
||||
if arg.expr is ast.Ident && arg.expr.obj is ast.Var {
|
||||
if arg.expr.obj.smartcasts.len > 0 {
|
||||
arg_typ = arg.expr.obj.smartcasts.last()
|
||||
}
|
||||
}
|
||||
}
|
||||
g.expr_with_opt(arg.expr, arg_typ, expected_type)
|
||||
}
|
||||
return
|
||||
|
|
|
@ -80,8 +80,7 @@ fn (mut g Gen) for_c_stmt(node ast.ForCStmt) {
|
|||
g.write('; ')
|
||||
if node.has_inc {
|
||||
mut processed := false
|
||||
if node.inc is ast.ExprStmt {
|
||||
if node.inc.expr is ast.ConcatExpr {
|
||||
if node.inc is ast.ExprStmt && node.inc.expr is ast.ConcatExpr {
|
||||
for inc_expr_idx, inc_expr in node.inc.expr.vals {
|
||||
g.expr(inc_expr)
|
||||
if inc_expr_idx < node.inc.expr.vals.len - 1 {
|
||||
|
@ -90,7 +89,6 @@ fn (mut g Gen) for_c_stmt(node ast.ForCStmt) {
|
|||
}
|
||||
processed = true
|
||||
}
|
||||
}
|
||||
if !processed {
|
||||
g.stmt(node.inc)
|
||||
}
|
||||
|
|
|
@ -132,10 +132,8 @@ pub fn (mut t TypeResolver) typeof_field_type(typ ast.Type, field_name string) a
|
|||
// get_ct_type_var gets the comptime type of the variable (.generic_param, .key_var, etc)
|
||||
@[inline]
|
||||
pub fn (t &ResolverInfo) get_ct_type_var(node ast.Expr) ast.ComptimeVarKind {
|
||||
if node is ast.Ident {
|
||||
if node.obj is ast.Var {
|
||||
if node is ast.Ident && node.obj is ast.Var {
|
||||
return node.obj.ct_type_var
|
||||
}
|
||||
} else if node is ast.IndexExpr {
|
||||
return t.get_ct_type_var(node.left)
|
||||
} else if node is ast.InfixExpr {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue