mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: fix type checker on auto deref var (#18842)
This commit is contained in:
parent
efcb15d05b
commit
029e8a815b
@ -2013,6 +2013,17 @@ pub fn (expr Expr) is_expr() bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (expr Expr) get_pure_type() Type {
|
||||
match expr {
|
||||
BoolLiteral { return bool_type }
|
||||
CharLiteral { return char_type }
|
||||
FloatLiteral { return f64_type }
|
||||
StringLiteral { return string_type }
|
||||
IntegerLiteral { return i64_type }
|
||||
else { return void_type }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (expr Expr) is_pure_literal() bool {
|
||||
return match expr {
|
||||
BoolLiteral, CharLiteral, FloatLiteral, StringLiteral, IntegerLiteral { true }
|
||||
|
@ -664,11 +664,28 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if !is_blank_ident && !left.is_auto_deref_var() && !right.is_auto_deref_var()
|
||||
&& right_sym.kind != .placeholder && left_sym.kind != .interface_
|
||||
if !is_blank_ident && right_sym.kind != .placeholder && left_sym.kind != .interface_
|
||||
&& !right_type.has_flag(.generic) && !left_type.has_flag(.generic) {
|
||||
// Dual sides check (compatibility check)
|
||||
c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
|
||||
// allow literal values to auto deref var (e.g.`for mut v in values { v = 1.0 }`)
|
||||
if left.is_auto_deref_var() || right.is_auto_deref_var() {
|
||||
left_deref := if left.is_auto_deref_var() {
|
||||
left_type.deref()
|
||||
} else {
|
||||
left_type
|
||||
}
|
||||
right_deref := if right.is_pure_literal() {
|
||||
right.get_pure_type()
|
||||
} else if right.is_auto_deref_var() {
|
||||
right_type.deref()
|
||||
} else {
|
||||
right_type
|
||||
}
|
||||
if c.check_types(left_deref, right_deref) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
// allow for ptr += 2
|
||||
if left_type_unwrapped.is_ptr() && right_type_unwrapped.is_int()
|
||||
&& node.op in [.plus_assign, .minus_assign] {
|
||||
|
6
vlib/v/checker/tests/auto_deref_assign_err.out
Normal file
6
vlib/v/checker/tests/auto_deref_assign_err.out
Normal file
@ -0,0 +1,6 @@
|
||||
vlib/v/checker/tests/auto_deref_assign_err.vv:10:6: error: cannot assign to `o`: expected `&int`, not `string`
|
||||
8 | fn sub( mut o &int ) {
|
||||
9 | println( 'in function got: ' + o.str() )
|
||||
10 | o = "mutate int as string??"
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
11 | }
|
11
vlib/v/checker/tests/auto_deref_assign_err.vv
Normal file
11
vlib/v/checker/tests/auto_deref_assign_err.vv
Normal file
@ -0,0 +1,11 @@
|
||||
fn main() {
|
||||
mut a := 42
|
||||
println( 'before sub: ' + a.str() )
|
||||
sub( mut a )
|
||||
println( 'after sub: ' + a.str() )
|
||||
}
|
||||
|
||||
fn sub( mut o &int ) {
|
||||
println( 'in function got: ' + o.str() )
|
||||
o = "mutate int as string??"
|
||||
}
|
Loading…
Reference in New Issue
Block a user