1
0
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:
Felipe Pena 2023-07-13 05:56:11 -03:00 committed by GitHub
parent efcb15d05b
commit 029e8a815b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 47 additions and 2 deletions

View File

@ -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 { pub fn (expr Expr) is_pure_literal() bool {
return match expr { return match expr {
BoolLiteral, CharLiteral, FloatLiteral, StringLiteral, IntegerLiteral { true } BoolLiteral, CharLiteral, FloatLiteral, StringLiteral, IntegerLiteral { true }

View File

@ -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() if !is_blank_ident && right_sym.kind != .placeholder && left_sym.kind != .interface_
&& right_sym.kind != .placeholder && left_sym.kind != .interface_
&& !right_type.has_flag(.generic) && !left_type.has_flag(.generic) { && !right_type.has_flag(.generic) && !left_type.has_flag(.generic) {
// Dual sides check (compatibility check) // Dual sides check (compatibility check)
c.check_expected(right_type_unwrapped, left_type_unwrapped) or { 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 // allow for ptr += 2
if left_type_unwrapped.is_ptr() && right_type_unwrapped.is_int() if left_type_unwrapped.is_ptr() && right_type_unwrapped.is_int()
&& node.op in [.plus_assign, .minus_assign] { && node.op in [.plus_assign, .minus_assign] {

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

View 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??"
}