mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32: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,10 +2594,8 @@ 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 {
|
||||
lx.left.expr.recursive_arraymap_set_is_setter()
|
||||
}
|
||||
} else if mut lx.left is SelectorExpr && lx.left.expr is IndexExpr {
|
||||
lx.left.expr.recursive_arraymap_set_is_setter()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,10 +103,8 @@ 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 {
|
||||
c.error('cannot use `none` in `unsafe` blocks', right.expr.pos)
|
||||
}
|
||||
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 {
|
||||
|
@ -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 {
|
||||
c.error('cannot reassign using range expression on the left side of an assignment',
|
||||
left.pos)
|
||||
}
|
||||
} 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,10 +195,8 @@ 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 {
|
||||
c.inside_ref_lit = c.inside_ref_lit || left.info.share == .shared_t
|
||||
}
|
||||
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]
|
||||
|
@ -666,11 +660,9 @@ 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 left.info.is_static && right_sym.kind == .map {
|
||||
c.error('maps cannot be static', left.pos)
|
||||
}
|
||||
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
|
||||
|
|
|
@ -911,10 +911,8 @@ 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 {
|
||||
c.fail_if_immutable(mut expr_left)
|
||||
}
|
||||
if mut expr.left is ast.Ident && expr.left.obj is ast.Var {
|
||||
c.fail_if_immutable(mut expr_left)
|
||||
}
|
||||
return '', expr.pos
|
||||
}
|
||||
|
@ -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,10 +1679,8 @@ 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 {
|
||||
typ = node.expr.obj.typ
|
||||
}
|
||||
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
|
||||
|
@ -4417,10 +4416,8 @@ 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 {
|
||||
expr_str = expr.expr.expr.expr.str()
|
||||
}
|
||||
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 } {
|
||||
|
@ -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 {
|
||||
// `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
|
||||
}
|
||||
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
|
||||
}
|
||||
if !is_ok && node.index is ast.RangeExpr {
|
||||
s := c.table.type_to_str(typ)
|
||||
|
|
|
@ -799,10 +799,8 @@ 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 {
|
||||
c.error('cannot have mutable reference to const `${expr2.name}`', expr2.pos)
|
||||
}
|
||||
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 {
|
||||
|
|
|
@ -1520,10 +1520,8 @@ 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 {
|
||||
node.args[i].typ = call_arg.expr.obj.typ
|
||||
}
|
||||
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)
|
||||
|
|
|
@ -318,13 +318,11 @@ 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 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
|
||||
node.scope, false, false)
|
||||
}
|
||||
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
|
||||
node.scope, false, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,10 +308,8 @@ 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 {
|
||||
return expr.expr.val.i64()
|
||||
}
|
||||
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()) {
|
||||
|
|
|
@ -82,10 +82,8 @@ 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 {
|
||||
c.error('cannot return `none` in unsafe block', expr.expr.pos)
|
||||
}
|
||||
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)
|
||||
|
@ -102,18 +100,16 @@ 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 expr.obj.smartcasts.len > 0 {
|
||||
typ = c.unwrap_generic(expr.obj.smartcasts.last())
|
||||
}
|
||||
if expr.obj.ct_type_var != .no_comptime {
|
||||
typ = c.type_resolver.get_type_or_default(expr, typ)
|
||||
}
|
||||
if mut expr.obj.expr is ast.IfGuardExpr {
|
||||
if var := expr.scope.find_var(expr.name) {
|
||||
typ = var.typ
|
||||
}
|
||||
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())
|
||||
}
|
||||
if expr.obj.ct_type_var != .no_comptime {
|
||||
typ = c.type_resolver.get_type_or_default(expr, typ)
|
||||
}
|
||||
if mut expr.obj.expr is ast.IfGuardExpr {
|
||||
if var := expr.scope.find_var(expr.name) {
|
||||
typ = var.typ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -231,16 +231,13 @@ 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 {
|
||||
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' {
|
||||
should_clone = true
|
||||
}
|
||||
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' {
|
||||
should_clone = true
|
||||
}
|
||||
}
|
||||
if should_clone {
|
||||
|
|
|
@ -34,13 +34,11 @@ 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.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
|
||||
}
|
||||
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 {
|
||||
|
|
|
@ -1227,12 +1227,9 @@ 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' {
|
||||
is_range_slice = true
|
||||
}
|
||||
}
|
||||
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}(')
|
||||
|
@ -2072,23 +2069,21 @@ 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 {
|
||||
typ = expr.obj.typ
|
||||
if expr.obj.smartcasts.len > 0 {
|
||||
typ = g.unwrap_generic(expr.obj.smartcasts.last())
|
||||
cast_sym := g.table.sym(typ)
|
||||
if cast_sym.info is ast.Aggregate {
|
||||
typ = cast_sym.info.types[g.aggregate_type_idx]
|
||||
} else if expr.obj.ct_type_var == .smartcast {
|
||||
typ = g.unwrap_generic(g.type_resolver.get_type(expr))
|
||||
}
|
||||
}
|
||||
// handling println( var or { ... })
|
||||
if typ.has_flag(.option) && expr.or_expr.kind != .absent {
|
||||
typ = typ.clear_flag(.option)
|
||||
} 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())
|
||||
cast_sym := g.table.sym(typ)
|
||||
if cast_sym.info is ast.Aggregate {
|
||||
typ = cast_sym.info.types[g.aggregate_type_idx]
|
||||
} else if expr.obj.ct_type_var == .smartcast {
|
||||
typ = g.unwrap_generic(g.type_resolver.get_type(expr))
|
||||
}
|
||||
}
|
||||
// handling println( var or { ... })
|
||||
if typ.has_flag(.option) && expr.or_expr.kind != .absent {
|
||||
typ = typ.clear_flag(.option)
|
||||
}
|
||||
}
|
||||
g.gen_expr_to_string(expr, typ)
|
||||
g.write(')')
|
||||
|
@ -2744,11 +2739,9 @@ 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.obj.smartcasts.len > 0 {
|
||||
arg_typ = arg.expr.obj.smartcasts.last()
|
||||
}
|
||||
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)
|
||||
|
|
|
@ -80,16 +80,14 @@ 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 {
|
||||
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 {
|
||||
g.write(', ')
|
||||
}
|
||||
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 {
|
||||
g.write(', ')
|
||||
}
|
||||
processed = true
|
||||
}
|
||||
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 {
|
||||
return node.obj.ct_type_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