all: fix mutability after if-smartcast (#6129)

pull/6154/head^2
Daniel Däschle 2020-08-17 21:11:11 +02:00 committed by GitHub
parent 36c98b3e5d
commit b5c1ea44dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 6 deletions

View File

@ -2550,7 +2550,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
return info.typ return info.typ
} else if ident.kind == .unresolved { } else if ident.kind == .unresolved {
// first use // first use
start_scope := c.file.scope.innermost(ident.pos.pos) start_scope := c.file.scope.innermost(ident.pos.pos + 1)
if obj1 := start_scope.find(ident.name) { if obj1 := start_scope.find(ident.name) {
match mut obj1 as obj { match mut obj1 as obj {
ast.GlobalDecl { ast.GlobalDecl {
@ -2985,8 +2985,11 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type {
left_sym := c.table.get_type_symbol(infix.left_type) left_sym := c.table.get_type_symbol(infix.left_type)
if left_sym.kind == .sum_type && branch.left_as_name.len > 0 { if left_sym.kind == .sum_type && branch.left_as_name.len > 0 {
mut is_mut := false mut is_mut := false
if infix.left is ast.Ident { mut scope := c.file.scope.innermost(branch.body_pos.pos)
is_mut = (infix.left as ast.Ident).is_mut if infix.left is ast.Ident as infix_left {
if var := scope.find_var(infix_left.name) {
is_mut = var.is_mut
}
} else if infix.left is ast.SelectorExpr { } else if infix.left is ast.SelectorExpr {
selector := infix.left as ast.SelectorExpr selector := infix.left as ast.SelectorExpr
field := c.table.struct_find_field(left_sym, selector.field_name) or { field := c.table.struct_find_field(left_sym, selector.field_name) or {
@ -2994,7 +2997,6 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) table.Type {
} }
is_mut = field.is_mut is_mut = field.is_mut
} }
mut scope := c.file.scope.innermost(branch.body_pos.pos)
scope.register(branch.left_as_name, ast.Var{ scope.register(branch.left_as_name, ast.Var{
name: branch.left_as_name name: branch.left_as_name
typ: right_expr.typ.to_ptr() typ: right_expr.typ.to_ptr()

View File

@ -1826,6 +1826,11 @@ fn (mut g Gen) expr(node ast.Expr) {
g.write(')') g.write(')')
} else if sym.kind == .sum_type { } else if sym.kind == .sum_type {
g.expr_with_cast(node.expr, node.expr_type, node.typ) g.expr_with_cast(node.expr, node.expr_type, node.typ)
} else if sym.kind == .struct_ && !node.typ.is_ptr() && !(sym.info as table.Struct).is_typedef {
styp := g.typ(node.typ)
g.write('*(($styp *)(&')
g.expr(node.expr)
g.write('))')
} else { } else {
// styp := g.table.Type_to_str(it.typ) // styp := g.table.Type_to_str(it.typ)
styp := g.typ(node.typ) styp := g.typ(node.typ)

View File

@ -118,7 +118,7 @@ fn (mut p Parser) if_expr() ast.IfExpr {
cond: cond cond: cond
stmts: stmts stmts: stmts
pos: start_pos.extend(end_pos) pos: start_pos.extend(end_pos)
body_pos: body_pos.extend(p.tok.position()) body_pos: body_pos.extend(p.prev_tok.position())
comments: comments comments: comments
left_as_name: left_as_name left_as_name: left_as_name
} }

View File

@ -63,3 +63,26 @@ fn test_as_cast_with_struct() {
assert test.val == 'test' assert test.val == 'test'
} }
} }
struct CellStr { str string }
struct CellInt { itg i64 }
struct CellFloat { flt f64 }
type Cell = CellStr | CellInt | CellFloat
fn test_mutability() {
my_str := 'the quick brown fox jumps over the lazy dog.'
my_itg := -1234567890
my_flt := 3.14159265358979323846
my_u32 := u32(4294967296)
cell_str := CellStr{ str: my_str }
cell_itg := CellInt{ itg: my_itg }
cell_flt := CellFloat{ flt: my_flt }
mut cell := Cell{}
cell = cell_str
if cell is CellStr {
println('$cell.str')
}
cell = cell_itg
if cell is CellInt {
println('$cell.itg')
}
}