checker: protect against assigning to a typeless variable (#11094)
							parent
							
								
									1d3786ff1e
								
							
						
					
					
						commit
						9af65d8830
					
				| 
						 | 
				
			
			@ -3834,11 +3834,13 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
 | 
			
		|||
			left_type = c.expr(left)
 | 
			
		||||
			c.expected_type = c.unwrap_generic(left_type)
 | 
			
		||||
			// `map = {}`
 | 
			
		||||
			sym := c.table.get_type_symbol(left_type)
 | 
			
		||||
			if sym.kind == .map && node.right[i] is ast.StructInit {
 | 
			
		||||
				c.warn('assigning a struct literal to a map is deprecated - use `map{}` instead',
 | 
			
		||||
					node.right[i].position())
 | 
			
		||||
				node.right[i] = ast.MapInit{}
 | 
			
		||||
			if left_type != 0 {
 | 
			
		||||
				sym := c.table.get_type_symbol(left_type)
 | 
			
		||||
				if sym.kind == .map && node.right[i] is ast.StructInit {
 | 
			
		||||
					c.warn('assigning a struct literal to a map is deprecated - use `map{}` instead',
 | 
			
		||||
						node.right[i].position())
 | 
			
		||||
					node.right[i] = ast.MapInit{}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if node.right_types.len < node.left.len { // first type or multi return types added above
 | 
			
		||||
| 
						 | 
				
			
			@ -4038,14 +4040,16 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
 | 
			
		|||
			// right type was a generic `T`
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		left_sym := c.table.get_type_symbol(left_type_unwrapped)
 | 
			
		||||
		right_sym := c.table.get_type_symbol(right_type_unwrapped)
 | 
			
		||||
 | 
			
		||||
		if c.pref.translated {
 | 
			
		||||
			// TODO fix this in C2V instead, for example cast enums to int before using `|` on them.
 | 
			
		||||
			// TODO replace all c.pref.translated checks with `$if !translated` for performance
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if left_type_unwrapped == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		left_sym := c.table.get_type_symbol(left_type_unwrapped)
 | 
			
		||||
		right_sym := c.table.get_type_symbol(right_type_unwrapped)
 | 
			
		||||
		if left_sym.kind == .array && !c.inside_unsafe && node.op in [.assign, .decl_assign]
 | 
			
		||||
			&& right_sym.kind == .array && (left is ast.Ident && !left.is_blank_ident())
 | 
			
		||||
			&& right is ast.Ident {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
vlib/v/checker/tests/assign_to_typeless_variable_err.vv:2:10: error: invalid empty map initilization syntax, use e.g. map[string]int{} instead
 | 
			
		||||
    1 | fn main() {
 | 
			
		||||
    2 |   val := {}
 | 
			
		||||
      |          ~~
 | 
			
		||||
    3 |   val = 1
 | 
			
		||||
    4 | }
 | 
			
		||||
vlib/v/checker/tests/assign_to_typeless_variable_err.vv:3:3: error: `val` is immutable, declare it with `mut` to make it mutable
 | 
			
		||||
    1 | fn main() {
 | 
			
		||||
    2 |   val := {}
 | 
			
		||||
    3 |   val = 1
 | 
			
		||||
      |   ~~~
 | 
			
		||||
    4 | }
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
fn main() {
 | 
			
		||||
  val := {}
 | 
			
		||||
  val = 1
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue