1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

ast, checker: change stmt(node_ ast.Stmt) to stmt(mut node ast.Stmt) (#18756)

This commit is contained in:
yuyi 2023-07-04 04:10:00 +08:00 committed by GitHub
parent ab258aebfb
commit c1550b3efa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 68 additions and 66 deletions

View File

@ -176,9 +176,10 @@ pub const (
// `{stmts}` or `unsafe {stmts}` // `{stmts}` or `unsafe {stmts}`
pub struct Block { pub struct Block {
pub: pub:
stmts []Stmt
is_unsafe bool is_unsafe bool
pos token.Pos pos token.Pos
pub mut:
stmts []Stmt
} }
// | IncDecStmt k // | IncDecStmt k
@ -1166,11 +1167,11 @@ pub enum ComptimeForKind {
pub struct ComptimeFor { pub struct ComptimeFor {
pub: pub:
val_var string val_var string
stmts []Stmt
kind ComptimeForKind kind ComptimeForKind
pos token.Pos pos token.Pos
typ_pos token.Pos typ_pos token.Pos
pub mut: pub mut:
stmts []Stmt
typ Type typ Type
} }
@ -1193,7 +1194,6 @@ pub:
val_var string val_var string
is_range bool is_range bool
high Expr // `10` in `for i in 0..10 {` high Expr // `10` in `for i in 0..10 {`
stmts []Stmt
pos token.Pos pos token.Pos
comments []Comment comments []Comment
val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array val_is_mut bool // `for mut val in vals {` means that modifying `val` will modify the array
@ -1208,6 +1208,7 @@ pub mut:
kind Kind // array/map/string kind Kind // array/map/string
label string // `label: for {` label string // `label: for {`
scope &Scope = unsafe { nil } scope &Scope = unsafe { nil }
stmts []Stmt
} }
pub struct ForCStmt { pub struct ForCStmt {
@ -1362,9 +1363,9 @@ pub:
[minify] [minify]
pub struct DeferStmt { pub struct DeferStmt {
pub: pub:
stmts []Stmt
pos token.Pos pos token.Pos
pub mut: pub mut:
stmts []Stmt
defer_vars []Ident defer_vars []Ident
ifdef string ifdef string
idx_in_fn int = -1 // index in FnDecl.defer_stmts idx_in_fn int = -1 // index in FnDecl.defer_stmts
@ -1717,9 +1718,10 @@ pub enum OrKind {
// `or { ... }` // `or { ... }`
pub struct OrExpr { pub struct OrExpr {
pub: pub:
stmts []Stmt
kind OrKind kind OrKind
pos token.Pos pos token.Pos
pub mut:
stmts []Stmt
} }
/* /*
@ -1854,7 +1856,6 @@ pub:
is_env bool is_env bool
env_pos token.Pos env_pos token.Pos
is_pkgconfig bool is_pkgconfig bool
or_block OrExpr
pub mut: pub mut:
vweb_tmpl File vweb_tmpl File
left_type Type left_type Type
@ -1863,6 +1864,7 @@ pub mut:
args_var string args_var string
args []CallArg args []CallArg
embed_file EmbeddedFile embed_file EmbeddedFile
or_block OrExpr
} }
pub struct None { pub struct None {
@ -1916,7 +1918,6 @@ pub:
is_array bool is_array bool
// is_generated indicates a statement is generated by ORM for complex queries with related tables. // is_generated indicates a statement is generated by ORM for complex queries with related tables.
is_generated bool is_generated bool
or_expr OrExpr
pos token.Pos pos token.Pos
pub mut: pub mut:
typ Type typ Type
@ -1928,6 +1929,7 @@ pub mut:
table_expr TypeNode table_expr TypeNode
fields []StructField fields []StructField
sub_structs map[int]SqlExpr sub_structs map[int]SqlExpr
or_expr OrExpr
} }
pub struct NodeError { pub struct NodeError {

View File

@ -208,7 +208,7 @@ pub fn (mut c Checker) check(mut ast_file ast.File) {
for mut stmt in ast_file.stmts { for mut stmt in ast_file.stmts {
if stmt in [ast.ConstDecl, ast.ExprStmt] { if stmt in [ast.ConstDecl, ast.ExprStmt] {
c.expr_level = 0 c.expr_level = 0
c.stmt(stmt) c.stmt(mut stmt)
} }
if c.should_abort { if c.should_abort {
return return
@ -219,7 +219,7 @@ pub fn (mut c Checker) check(mut ast_file ast.File) {
for mut stmt in ast_file.stmts { for mut stmt in ast_file.stmts {
if stmt is ast.GlobalDecl { if stmt is ast.GlobalDecl {
c.expr_level = 0 c.expr_level = 0
c.stmt(stmt) c.stmt(mut stmt)
} }
if c.should_abort { if c.should_abort {
return return
@ -230,7 +230,7 @@ pub fn (mut c Checker) check(mut ast_file ast.File) {
for mut stmt in ast_file.stmts { for mut stmt in ast_file.stmts {
if stmt !in [ast.ConstDecl, ast.GlobalDecl, ast.ExprStmt] { if stmt !in [ast.ConstDecl, ast.GlobalDecl, ast.ExprStmt] {
c.expr_level = 0 c.expr_level = 0
c.stmt(stmt) c.stmt(mut stmt)
} }
if c.should_abort { if c.should_abort {
return return
@ -267,8 +267,8 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
// not used right now // not used right now
pub fn (mut c Checker) check2(mut ast_file ast.File) []errors.Error { pub fn (mut c Checker) check2(mut ast_file ast.File) []errors.Error {
c.change_current_file(ast_file) c.change_current_file(ast_file)
for stmt in ast_file.stmts { for mut stmt in ast_file.stmts {
c.stmt(stmt) c.stmt(mut stmt)
} }
return c.errors return c.errors
} }
@ -1491,7 +1491,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
node.typ = field.typ node.typ = field.typ
if node.or_block.kind == .block { if node.or_block.kind == .block {
c.expected_or_type = node.typ.clear_flags(.option, .result) c.expected_or_type = node.typ.clear_flags(.option, .result)
c.stmts_ending_with_expression(node.or_block.stmts) c.stmts_ending_with_expression(mut node.or_block.stmts)
c.check_or_expr(node.or_block, node.typ, c.expected_or_type, node) c.check_or_expr(node.or_block, node.typ, c.expected_or_type, node)
c.expected_or_type = ast.void_type c.expected_or_type = ast.void_type
} }
@ -1833,8 +1833,7 @@ fn (mut c Checker) check_loop_label(label string, pos token.Pos) {
c.loop_label = label c.loop_label = label
} }
fn (mut c Checker) stmt(node_ ast.Stmt) { fn (mut c Checker) stmt(mut node ast.Stmt) {
mut node := unsafe { node_ }
$if trace_checker ? { $if trace_checker ? {
ntype := typeof(node).replace('v.ast.', '') ntype := typeof(node).replace('v.ast.', '')
eprintln('checking: ${c.file.path:-30} | pos: ${node.pos.line_str():-39} | node: ${ntype} | ${node}') eprintln('checking: ${c.file.path:-30} | pos: ${node.pos.line_str():-39} | node: ${ntype} | ${node}')
@ -1858,13 +1857,13 @@ fn (mut c Checker) stmt(node_ ast.Stmt) {
c.assign_stmt(mut node) c.assign_stmt(mut node)
} }
ast.Block { ast.Block {
c.block(node) c.block(mut node)
} }
ast.BranchStmt { ast.BranchStmt {
c.branch_stmt(node) c.branch_stmt(node)
} }
ast.ComptimeFor { ast.ComptimeFor {
c.comptime_for(node) c.comptime_for(mut node)
} }
ast.ConstDecl { ast.ConstDecl {
c.inside_const = true c.inside_const = true
@ -1898,7 +1897,7 @@ fn (mut c Checker) stmt(node_ ast.Stmt) {
} }
} }
c.inside_defer = true c.inside_defer = true
c.stmts(node.stmts) c.stmts(mut node.stmts)
c.inside_defer = false c.inside_defer = false
} }
ast.EnumDecl { ast.EnumDecl {
@ -1941,7 +1940,7 @@ fn (mut c Checker) stmt(node_ ast.Stmt) {
c.fn_decl(mut node) c.fn_decl(mut node)
} }
ast.ForCStmt { ast.ForCStmt {
c.for_c_stmt(node) c.for_c_stmt(mut node)
} }
ast.ForInStmt { ast.ForInStmt {
c.for_in_stmt(mut node) c.for_in_stmt(mut node)
@ -2011,14 +2010,14 @@ fn (mut c Checker) assert_stmt(node ast.AssertStmt) {
c.expected_type = cur_exp_typ c.expected_type = cur_exp_typ
} }
fn (mut c Checker) block(node ast.Block) { fn (mut c Checker) block(mut node ast.Block) {
if node.is_unsafe { if node.is_unsafe {
prev_unsafe := c.inside_unsafe prev_unsafe := c.inside_unsafe
c.inside_unsafe = true c.inside_unsafe = true
c.stmts(node.stmts) c.stmts(mut node.stmts)
c.inside_unsafe = prev_unsafe c.inside_unsafe = prev_unsafe
} else { } else {
c.stmts(node.stmts) c.stmts(mut node.stmts)
} }
} }
@ -2366,10 +2365,10 @@ fn (mut c Checker) import_stmt(node ast.Import) {
} }
// stmts should be used for processing normal statement lists (fn bodies, for loop bodies etc). // stmts should be used for processing normal statement lists (fn bodies, for loop bodies etc).
fn (mut c Checker) stmts(stmts []ast.Stmt) { fn (mut c Checker) stmts(mut stmts []ast.Stmt) {
old_stmt_level := c.stmt_level old_stmt_level := c.stmt_level
c.stmt_level = 0 c.stmt_level = 0
c.stmts_ending_with_expression(stmts) c.stmts_ending_with_expression(mut stmts)
c.stmt_level = old_stmt_level c.stmt_level = old_stmt_level
} }
@ -2378,7 +2377,7 @@ fn (mut c Checker) stmts(stmts []ast.Stmt) {
// `x := opt() or { stmt1 stmt2 ExprStmt }`, // `x := opt() or { stmt1 stmt2 ExprStmt }`,
// `x := if cond { stmt1 stmt2 ExprStmt } else { stmt2 stmt3 ExprStmt }`, // `x := if cond { stmt1 stmt2 ExprStmt } else { stmt2 stmt3 ExprStmt }`,
// `x := match expr { Type1 { stmt1 stmt2 ExprStmt } else { stmt2 stmt3 ExprStmt }`. // `x := match expr { Type1 { stmt1 stmt2 ExprStmt } else { stmt2 stmt3 ExprStmt }`.
fn (mut c Checker) stmts_ending_with_expression(stmts []ast.Stmt) { fn (mut c Checker) stmts_ending_with_expression(mut stmts []ast.Stmt) {
if stmts.len == 0 { if stmts.len == 0 {
c.scope_returns = false c.scope_returns = false
return return
@ -2392,14 +2391,14 @@ fn (mut c Checker) stmts_ending_with_expression(stmts []ast.Stmt) {
line_nr: -1 line_nr: -1
} }
c.stmt_level++ c.stmt_level++
for i, stmt in stmts { for i, mut stmt in stmts {
c.is_last_stmt = i == stmts.len - 1 c.is_last_stmt = i == stmts.len - 1
if c.scope_returns { if c.scope_returns {
if unreachable.line_nr == -1 { if unreachable.line_nr == -1 {
unreachable = stmt.pos unreachable = stmt.pos
} }
} }
c.stmt(stmt) c.stmt(mut stmt)
if stmt is ast.GotoLabel { if stmt is ast.GotoLabel {
unreachable = token.Pos{ unreachable = token.Pos{
line_nr: -1 line_nr: -1
@ -3297,7 +3296,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
} }
unwrapped_typ := typ.clear_flags(.option, .result) unwrapped_typ := typ.clear_flags(.option, .result)
c.expected_or_type = unwrapped_typ c.expected_or_type = unwrapped_typ
c.stmts_ending_with_expression(node.or_expr.stmts) c.stmts_ending_with_expression(mut node.or_expr.stmts)
c.check_or_expr(node.or_expr, typ, c.expected_or_type, node) c.check_or_expr(node.or_expr, typ, c.expected_or_type, node)
return unwrapped_typ return unwrapped_typ
} }
@ -3402,7 +3401,7 @@ fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
} }
unwrapped_typ := typ.clear_flags(.option, .result) unwrapped_typ := typ.clear_flags(.option, .result)
c.expected_or_type = unwrapped_typ c.expected_or_type = unwrapped_typ
c.stmts_ending_with_expression(node.or_expr.stmts) c.stmts_ending_with_expression(mut node.or_expr.stmts)
c.check_or_expr(node.or_expr, typ, c.expected_or_type, node) c.check_or_expr(node.or_expr, typ, c.expected_or_type, node)
return unwrapped_typ return unwrapped_typ
} }
@ -3655,9 +3654,9 @@ fn (mut c Checker) smartcast(expr_ ast.Expr, cur_type ast.Type, to_type_ ast.Typ
fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type { fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type {
node.is_expr = c.expected_type != ast.void_type node.is_expr = c.expected_type != ast.void_type
node.expected_type = c.expected_type node.expected_type = c.expected_type
for branch in node.branches { for mut branch in node.branches {
c.stmt(branch.stmt) c.stmt(mut branch.stmt)
match branch.stmt { match mut branch.stmt {
ast.ExprStmt { ast.ExprStmt {
if branch.is_timeout { if branch.is_timeout {
if !branch.stmt.typ.is_int() { if !branch.stmt.typ.is_int() {
@ -3666,7 +3665,7 @@ fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type {
branch.stmt.pos) branch.stmt.pos)
} }
} else { } else {
if branch.stmt.expr is ast.InfixExpr { if mut branch.stmt.expr is ast.InfixExpr {
if branch.stmt.expr.left !in [ast.Ident, ast.SelectorExpr, ast.IndexExpr] { if branch.stmt.expr.left !in [ast.Ident, ast.SelectorExpr, ast.IndexExpr] {
c.error('channel in `select` key must be predefined', branch.stmt.expr.left.pos()) c.error('channel in `select` key must be predefined', branch.stmt.expr.left.pos())
} }
@ -3708,7 +3707,7 @@ fn (mut c Checker) select_expr(mut node ast.SelectExpr) ast.Type {
} }
} }
} }
c.stmts(branch.stmts) c.stmts(mut branch.stmts)
} }
return ast.bool_type return ast.bool_type
} }
@ -3737,7 +3736,7 @@ fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
c.locked_names << id_name c.locked_names << id_name
} }
} }
c.stmts(node.stmts) c.stmts(mut node.stmts)
// handle `x := rlock a { a.getval() }` // handle `x := rlock a { a.getval() }`
mut ret_type := ast.void_type mut ret_type := ast.void_type
if node.stmts.len > 0 { if node.stmts.len > 0 {
@ -4026,7 +4025,7 @@ fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
} }
if node.op == .arrow { if node.op == .arrow {
if right_sym.kind == .chan { if right_sym.kind == .chan {
c.stmts_ending_with_expression(node.or_block.stmts) c.stmts_ending_with_expression(mut node.or_block.stmts)
return right_sym.chan_info().elem_type return right_sym.chan_info().elem_type
} }
c.type_error_for_operator('<-', '`chan`', right_sym.name, node.pos) c.type_error_for_operator('<-', '`chan`', right_sym.name, node.pos)
@ -4209,7 +4208,7 @@ fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
if node.or_expr.stmts.len > 0 && node.or_expr.stmts.last() is ast.ExprStmt { if node.or_expr.stmts.len > 0 && node.or_expr.stmts.last() is ast.ExprStmt {
c.expected_or_type = typ c.expected_or_type = typ
} }
c.stmts_ending_with_expression(node.or_expr.stmts) c.stmts_ending_with_expression(mut node.or_expr.stmts)
c.check_expr_opt_call(node, typ) c.check_expr_opt_call(node, typ)
return typ return typ
} }

View File

@ -149,7 +149,7 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
// check each arg expression // check each arg expression
node.args[i].typ = c.expr(arg.expr) node.args[i].typ = c.expr(arg.expr)
} }
c.stmts_ending_with_expression(node.or_block.stmts) c.stmts_ending_with_expression(mut node.or_block.stmts)
// assume string for now // assume string for now
return ast.string_type return ast.string_type
} }
@ -246,7 +246,7 @@ fn (mut c Checker) comptime_selector(mut node ast.ComptimeSelector) ast.Type {
return ast.void_type return ast.void_type
} }
fn (mut c Checker) comptime_for(node ast.ComptimeFor) { fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) {
typ := c.unwrap_generic(node.typ) typ := c.unwrap_generic(node.typ)
sym := c.table.final_sym(typ) sym := c.table.final_sym(typ)
if sym.kind == .placeholder || typ.has_flag(.generic) { if sym.kind == .placeholder || typ.has_flag(.generic) {
@ -274,7 +274,7 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
c.comptime_for_field_var = node.val_var c.comptime_for_field_var = node.val_var
c.comptime_fields_type[node.val_var] = node.typ c.comptime_fields_type[node.val_var] = node.typ
c.comptime_fields_default_type = field.typ c.comptime_fields_default_type = field.typ
c.stmts(node.stmts) c.stmts(mut node.stmts)
unwrapped_expr_type := c.unwrap_generic(field.typ) unwrapped_expr_type := c.unwrap_generic(field.typ)
tsym := c.table.sym(unwrapped_expr_type) tsym := c.table.sym(unwrapped_expr_type)
@ -294,11 +294,11 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
c.comptime_enum_field_value = field c.comptime_enum_field_value = field
c.comptime_for_field_var = node.val_var c.comptime_for_field_var = node.val_var
c.comptime_fields_type[node.val_var] = node.typ c.comptime_fields_type[node.val_var] = node.typ
c.stmts(node.stmts) c.stmts(mut node.stmts)
} }
} }
} else { } else {
c.stmts(node.stmts) c.stmts(mut node.stmts)
} }
} }

View File

@ -379,7 +379,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
} }
} }
c.fn_scope = node.scope c.fn_scope = node.scope
c.stmts(node.stmts) c.stmts(mut node.stmts)
node_has_top_return := has_top_return(node.stmts) node_has_top_return := has_top_return(node.stmts)
node.has_return = c.returns || node_has_top_return node.has_return = c.returns || node_has_top_return
c.check_noreturn_fn_decl(mut node) c.check_noreturn_fn_decl(mut node)
@ -463,7 +463,7 @@ fn (mut c Checker) anon_fn(mut node ast.AnonFn) ast.Type {
c.error('generic closure fn must specify type parameter, e.g. fn [foo] [T]()', c.error('generic closure fn must specify type parameter, e.g. fn [foo] [T]()',
node.decl.pos) node.decl.pos)
} }
c.stmts(node.decl.stmts) c.stmts(mut node.decl.stmts)
c.fn_decl(mut node.decl) c.fn_decl(mut node.decl)
return node.typ return node.typ
} }
@ -514,7 +514,7 @@ fn (mut c Checker) call_expr(mut node ast.CallExpr) ast.Type {
} }
} }
c.expected_or_type = node.return_type.clear_flag(.result) c.expected_or_type = node.return_type.clear_flag(.result)
c.stmts_ending_with_expression(node.or_block.stmts) c.stmts_ending_with_expression(mut node.or_block.stmts)
c.expected_or_type = ast.void_type c.expected_or_type = ast.void_type
if !c.inside_const && c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.is_main if !c.inside_const && c.table.cur_fn != unsafe { nil } && !c.table.cur_fn.is_main

View File

@ -5,15 +5,15 @@ module checker
import v.ast import v.ast
import v.token import v.token
fn (mut c Checker) for_c_stmt(node ast.ForCStmt) { fn (mut c Checker) for_c_stmt(mut node ast.ForCStmt) {
c.in_for_count++ c.in_for_count++
prev_loop_label := c.loop_label prev_loop_label := c.loop_label
if node.has_init { if node.has_init {
c.stmt(node.init) c.stmt(mut node.init)
} }
c.expr(node.cond) c.expr(node.cond)
if node.has_inc { if node.has_inc {
if node.inc is ast.AssignStmt { if mut node.inc is ast.AssignStmt {
assign := node.inc assign := node.inc
if assign.op == .decl_assign { if assign.op == .decl_assign {
@ -29,10 +29,10 @@ fn (mut c Checker) for_c_stmt(node ast.ForCStmt) {
} }
} }
} }
c.stmt(node.inc) c.stmt(mut node.inc)
} }
c.check_loop_label(node.label, node.pos) c.check_loop_label(node.label, node.pos)
c.stmts(node.stmts) c.stmts(mut node.stmts)
c.loop_label = prev_loop_label c.loop_label = prev_loop_label
c.in_for_count-- c.in_for_count--
} }
@ -270,7 +270,7 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
} }
} }
c.check_loop_label(node.label, node.pos) c.check_loop_label(node.label, node.pos)
c.stmts(node.stmts) c.stmts(mut node.stmts)
c.loop_label = prev_loop_label c.loop_label = prev_loop_label
c.in_for_count-- c.in_for_count--
} }
@ -299,7 +299,7 @@ fn (mut c Checker) for_stmt(mut node ast.ForStmt) {
// TODO: update loop var type // TODO: update loop var type
// how does this work currently? // how does this work currently?
c.check_loop_label(node.label, node.pos) c.check_loop_label(node.label, node.pos)
c.stmts(node.stmts) c.stmts(mut node.stmts)
c.loop_label = prev_loop_label c.loop_label = prev_loop_label
c.in_for_count-- c.in_for_count--
if c.smartcast_mut_pos != token.Pos{} { if c.smartcast_mut_pos != token.Pos{} {

View File

@ -273,9 +273,9 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
} }
if !c.skip_flags { if !c.skip_flags {
if node_is_expr { if node_is_expr {
c.stmts_ending_with_expression(branch.stmts) c.stmts_ending_with_expression(mut branch.stmts)
} else { } else {
c.stmts(branch.stmts) c.stmts(mut branch.stmts)
c.check_non_expr_branch_last_stmt(branch.stmts) c.check_non_expr_branch_last_stmt(branch.stmts)
} }
} else if c.pref.output_cross_c { } else if c.pref.output_cross_c {
@ -290,9 +290,9 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
node.branches[i].stmts = [] node.branches[i].stmts = []
} }
if node_is_expr { if node_is_expr {
c.stmts_ending_with_expression(branch.stmts) c.stmts_ending_with_expression(mut branch.stmts)
} else { } else {
c.stmts(branch.stmts) c.stmts(mut branch.stmts)
c.check_non_expr_branch_last_stmt(branch.stmts) c.check_non_expr_branch_last_stmt(branch.stmts)
} }
} else if !is_comptime_type_is_expr { } else if !is_comptime_type_is_expr {
@ -309,9 +309,9 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
// smartcast sumtypes and interfaces when using `is` // smartcast sumtypes and interfaces when using `is`
c.smartcast_if_conds(branch.cond, mut branch.scope) c.smartcast_if_conds(branch.cond, mut branch.scope)
if node_is_expr { if node_is_expr {
c.stmts_ending_with_expression(branch.stmts) c.stmts_ending_with_expression(mut branch.stmts)
} else { } else {
c.stmts(branch.stmts) c.stmts(mut branch.stmts)
c.check_non_expr_branch_last_stmt(branch.stmts) c.check_non_expr_branch_last_stmt(branch.stmts)
} }
c.smartcast_mut_pos = token.Pos{} c.smartcast_mut_pos = token.Pos{}

View File

@ -667,7 +667,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
c.error('cannot push non-reference `${right_sym.name}` on `${left_sym.name}`', c.error('cannot push non-reference `${right_sym.name}` on `${left_sym.name}`',
right_pos) right_pos)
} }
c.stmts_ending_with_expression(node.or_block.stmts) c.stmts_ending_with_expression(mut node.or_block.stmts)
} else { } else {
c.error('cannot push on non-channel `${left_sym.name}`', left_pos) c.error('cannot push on non-channel `${left_sym.name}`', left_pos)
} }

View File

@ -37,11 +37,11 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
mut ret_type := ast.void_type mut ret_type := ast.void_type
mut nbranches_with_return := 0 mut nbranches_with_return := 0
mut nbranches_without_return := 0 mut nbranches_without_return := 0
for branch in node.branches { for mut branch in node.branches {
if node.is_expr { if node.is_expr {
c.stmts_ending_with_expression(branch.stmts) c.stmts_ending_with_expression(mut branch.stmts)
} else { } else {
c.stmts(branch.stmts) c.stmts(mut branch.stmts)
} }
c.smartcast_mut_pos = token.Pos{} c.smartcast_mut_pos = token.Pos{}
c.smartcast_cond_pos = token.Pos{} c.smartcast_cond_pos = token.Pos{}

View File

@ -534,7 +534,8 @@ fn (mut c Checker) check_orm_or_expr(expr ORMExpr) {
if expr.or_expr.kind == .block { if expr.or_expr.kind == .block {
c.expected_or_type = return_type.clear_flag(.result) c.expected_or_type = return_type.clear_flag(.result)
c.stmts_ending_with_expression(expr.or_expr.stmts) mut expr_ := unsafe { expr }
c.stmts_ending_with_expression(mut expr_.or_expr.stmts)
c.expected_or_type = ast.void_type c.expected_or_type = ast.void_type
} }
} }