v: cleanup if smartcasts in the compiler (#24734)

This commit is contained in:
Felipe Pena 2025-06-17 12:49:49 -03:00 committed by GitHub
parent e7905ea841
commit e14853d6e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 89 additions and 133 deletions

View file

@ -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 {

View file

@ -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.

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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 {

View file

@ -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
}

View file

@ -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(')
}

View file

@ -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('*',

View file

@ -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

View file

@ -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)
}

View file

@ -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 {