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
} else if ident.kind == .unresolved {
// 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) {
match mut obj1 as obj {
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)
if left_sym.kind == .sum_type && branch.left_as_name.len > 0 {
mut is_mut := false
if infix.left is ast.Ident {
is_mut = (infix.left as ast.Ident).is_mut
mut scope := c.file.scope.innermost(branch.body_pos.pos)
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 {
selector := infix.left as ast.SelectorExpr
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
}
mut scope := c.file.scope.innermost(branch.body_pos.pos)
scope.register(branch.left_as_name, ast.Var{
name: branch.left_as_name
typ: right_expr.typ.to_ptr()

View File

@ -1826,6 +1826,11 @@ fn (mut g Gen) expr(node ast.Expr) {
g.write(')')
} else if sym.kind == .sum_type {
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 {
// styp := g.table.Type_to_str(it.typ)
styp := g.typ(node.typ)

View File

@ -118,7 +118,7 @@ fn (mut p Parser) if_expr() ast.IfExpr {
cond: cond
stmts: stmts
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
left_as_name: left_as_name
}

View File

@ -51,7 +51,7 @@ fn test_mutable_with_struct() {
mut x := Test{Abc{'test'}}
if x.abc is Abc as test {
mut ttt := test
assert u64(ttt) == u64(ttt)
assert u64(ttt) == u64(ttt)
ttt.val = 'test'
assert ttt.val == 'test'
}
@ -63,3 +63,26 @@ fn test_as_cast_with_struct() {
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')
}
}