checker: minor cleanup of assign_stmt() (#10314)
							parent
							
								
									86d70fade7
								
							
						
					
					
						commit
						fedf07ddd8
					
				|  | @ -3216,50 +3216,50 @@ pub fn (mut c Checker) enum_decl(decl ast.EnumDecl) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { | ||||||
| 	c.expected_type = ast.none_type // TODO a hack to make `x := if ... work`
 | 	c.expected_type = ast.none_type // TODO a hack to make `x := if ... work`
 | ||||||
| 	defer { | 	defer { | ||||||
| 		c.expected_type = ast.void_type | 		c.expected_type = ast.void_type | ||||||
| 	} | 	} | ||||||
| 	right_first := assign_stmt.right[0] | 	right_first := node.right[0] | ||||||
| 	mut right_len := assign_stmt.right.len | 	mut right_len := node.right.len | ||||||
| 	mut right_type0 := ast.void_type | 	mut right_type0 := ast.void_type | ||||||
| 	for i, right in assign_stmt.right { | 	for i, right in node.right { | ||||||
| 		if right is ast.CallExpr || right is ast.IfExpr || right is ast.LockExpr | 		if right is ast.CallExpr || right is ast.IfExpr || right is ast.LockExpr | ||||||
| 			|| right is ast.MatchExpr { | 			|| right is ast.MatchExpr { | ||||||
| 			right_type := c.expr(right) | 			right_type := c.expr(right) | ||||||
| 			if i == 0 { | 			if i == 0 { | ||||||
| 				right_type0 = right_type | 				right_type0 = right_type | ||||||
| 				assign_stmt.right_types = [ | 				node.right_types = [ | ||||||
| 					c.check_expr_opt_call(right, right_type0), | 					c.check_expr_opt_call(right, right_type0), | ||||||
| 				] | 				] | ||||||
| 			} | 			} | ||||||
| 			right_type_sym := c.table.get_type_symbol(right_type) | 			right_type_sym := c.table.get_type_symbol(right_type) | ||||||
| 			if right_type_sym.kind == .multi_return { | 			if right_type_sym.kind == .multi_return { | ||||||
| 				if assign_stmt.right.len > 1 { | 				if node.right.len > 1 { | ||||||
| 					c.error('cannot use multi-value $right_type_sym.name in single-value context', | 					c.error('cannot use multi-value $right_type_sym.name in single-value context', | ||||||
| 						right.position()) | 						right.position()) | ||||||
| 				} | 				} | ||||||
| 				assign_stmt.right_types = right_type_sym.mr_info().types | 				node.right_types = right_type_sym.mr_info().types | ||||||
| 				right_len = assign_stmt.right_types.len | 				right_len = node.right_types.len | ||||||
| 			} else if right_type == ast.void_type { | 			} else if right_type == ast.void_type { | ||||||
| 				right_len = 0 | 				right_len = 0 | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if assign_stmt.left.len != right_len { | 	if node.left.len != right_len { | ||||||
| 		if right_first is ast.CallExpr { | 		if right_first is ast.CallExpr { | ||||||
| 			c.error('assignment mismatch: $assign_stmt.left.len variable(s) but `${right_first.name}()` returns $right_len value(s)', | 			c.error('assignment mismatch: $node.left.len variable(s) but `${right_first.name}()` returns $right_len value(s)', | ||||||
| 				assign_stmt.pos) | 				node.pos) | ||||||
| 		} else { | 		} else { | ||||||
| 			c.error('assignment mismatch: $assign_stmt.left.len variable(s) $right_len value(s)', | 			c.error('assignment mismatch: $node.left.len variable(s) $right_len value(s)', | ||||||
| 				assign_stmt.pos) | 				node.pos) | ||||||
| 		} | 		} | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	is_decl := assign_stmt.op == .decl_assign | 	is_decl := node.op == .decl_assign | ||||||
| 	for i, left in assign_stmt.left { | 	for i, left in node.left { | ||||||
| 		if left is ast.CallExpr { | 		if left is ast.CallExpr { | ||||||
| 			c.error('cannot call function `${left.name}()` on the left side of an assignment', | 			c.error('cannot call function `${left.name}()` on the left side of an assignment', | ||||||
| 				left.pos) | 				left.pos) | ||||||
|  | @ -3274,13 +3274,13 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 			c.expected_type = c.unwrap_generic(left_type) | 			c.expected_type = c.unwrap_generic(left_type) | ||||||
| 			// `map = {}`
 | 			// `map = {}`
 | ||||||
| 			sym := c.table.get_type_symbol(left_type) | 			sym := c.table.get_type_symbol(left_type) | ||||||
| 			if sym.kind == .map && assign_stmt.right[i] is ast.StructInit { | 			if sym.kind == .map && node.right[i] is ast.StructInit { | ||||||
| 				c.warn('assigning a struct literal to a map is deprecated - use `map{}` instead', | 				c.warn('assigning a struct literal to a map is deprecated - use `map{}` instead', | ||||||
| 					assign_stmt.right[i].position()) | 					node.right[i].position()) | ||||||
| 				assign_stmt.right[i] = ast.MapInit{} | 				node.right[i] = ast.MapInit{} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		if assign_stmt.right_types.len < assign_stmt.left.len { // first type or multi return types added above
 | 		if node.right_types.len < node.left.len { // first type or multi return types added above
 | ||||||
| 			old_inside_ref_lit := c.inside_ref_lit | 			old_inside_ref_lit := c.inside_ref_lit | ||||||
| 			if left is ast.Ident { | 			if left is ast.Ident { | ||||||
| 				if left.info is ast.IdentVar { | 				if left.info is ast.IdentVar { | ||||||
|  | @ -3288,16 +3288,15 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			c.inside_decl_rhs = is_decl | 			c.inside_decl_rhs = is_decl | ||||||
| 			right_type := c.expr(assign_stmt.right[i]) | 			right_type := c.expr(node.right[i]) | ||||||
| 			c.inside_decl_rhs = false | 			c.inside_decl_rhs = false | ||||||
| 			c.inside_ref_lit = old_inside_ref_lit | 			c.inside_ref_lit = old_inside_ref_lit | ||||||
| 			if assign_stmt.right_types.len == i { | 			if node.right_types.len == i { | ||||||
| 				assign_stmt.right_types << c.check_expr_opt_call(assign_stmt.right[i], | 				node.right_types << c.check_expr_opt_call(node.right[i], right_type) | ||||||
| 					right_type) |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		right := if i < assign_stmt.right.len { assign_stmt.right[i] } else { assign_stmt.right[0] } | 		right := if i < node.right.len { node.right[i] } else { node.right[0] } | ||||||
| 		mut right_type := assign_stmt.right_types[i] | 		mut right_type := node.right_types[i] | ||||||
| 		if is_decl { | 		if is_decl { | ||||||
| 			// check generic struct init and return unwrap generic struct type
 | 			// check generic struct init and return unwrap generic struct type
 | ||||||
| 			if right is ast.StructInit { | 			if right is ast.StructInit { | ||||||
|  | @ -3351,13 +3350,13 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		assign_stmt.left_types << left_type | 		node.left_types << left_type | ||||||
| 		match mut left { | 		match mut left { | ||||||
| 			ast.Ident { | 			ast.Ident { | ||||||
| 				if left.kind == .blank_ident { | 				if left.kind == .blank_ident { | ||||||
| 					left_type = right_type | 					left_type = right_type | ||||||
| 					assign_stmt.left_types[i] = right_type | 					node.left_types[i] = right_type | ||||||
| 					if assign_stmt.op !in [.assign, .decl_assign] { | 					if node.op !in [.assign, .decl_assign] { | ||||||
| 						c.error('cannot modify blank `_` identifier', left.pos) | 						c.error('cannot modify blank `_` identifier', left.pos) | ||||||
| 					} | 					} | ||||||
| 				} else if left.info !is ast.IdentVar { | 				} else if left.info !is ast.IdentVar { | ||||||
|  | @ -3381,7 +3380,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 					if ident_var_info.share == .atomic_t { | 					if ident_var_info.share == .atomic_t { | ||||||
| 						left_type = left_type.set_flag(.atomic_f) | 						left_type = left_type.set_flag(.atomic_f) | ||||||
| 					} | 					} | ||||||
| 					assign_stmt.left_types[i] = left_type | 					node.left_types[i] = left_type | ||||||
| 					ident_var_info.typ = left_type | 					ident_var_info.typ = left_type | ||||||
| 					left.info = ident_var_info | 					left.info = ident_var_info | ||||||
| 					if left_type != 0 { | 					if left_type != 0 { | ||||||
|  | @ -3418,7 +3417,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 				if left.op == .mul { | 				if left.op == .mul { | ||||||
| 					if !c.inside_unsafe { | 					if !c.inside_unsafe { | ||||||
| 						c.error('modifying variables via dereferencing can only be done in `unsafe` blocks', | 						c.error('modifying variables via dereferencing can only be done in `unsafe` blocks', | ||||||
| 							assign_stmt.pos) | 							node.pos) | ||||||
| 					} else { | 					} else { | ||||||
| 						// mark `p` in `*p = val` as used:
 | 						// mark `p` in `*p = val` as used:
 | ||||||
| 						match mut left.right { | 						match mut left.right { | ||||||
|  | @ -3463,15 +3462,15 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 			// TODO replace all c.pref.translated checks with `$if !translated` for performance
 | 			// TODO replace all c.pref.translated checks with `$if !translated` for performance
 | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		if left_sym.kind == .array && !c.inside_unsafe && assign_stmt.op in [.assign, .decl_assign] | 		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_sym.kind == .array && (left is ast.Ident && !left.is_blank_ident()) | ||||||
| 			&& right is ast.Ident { | 			&& right is ast.Ident { | ||||||
| 			// Do not allow `a = b`, only `a = b.clone()`
 | 			// Do not allow `a = b`, only `a = b.clone()`
 | ||||||
| 			c.error('use `array2 $assign_stmt.op.str() array1.clone()` instead of `array2 $assign_stmt.op.str() array1` (or use `unsafe`)', | 			c.error('use `array2 $node.op.str() array1.clone()` instead of `array2 $node.op.str() array1` (or use `unsafe`)', | ||||||
| 				assign_stmt.pos) | 				node.pos) | ||||||
| 		} | 		} | ||||||
| 		if left_sym.kind == .map && assign_stmt.op in [.assign, .decl_assign] | 		if left_sym.kind == .map && node.op in [.assign, .decl_assign] && right_sym.kind == .map | ||||||
| 			&& right_sym.kind == .map && ((right is ast.Ident && right.is_auto_deref_var()) | 			&& ((right is ast.Ident && right.is_auto_deref_var()) | ||||||
| 			|| !right_type.is_ptr()) && !left.is_blank_ident() && right.is_lvalue() { | 			|| !right_type.is_ptr()) && !left.is_blank_ident() && right.is_lvalue() { | ||||||
| 			// Do not allow `a = b`
 | 			// Do not allow `a = b`
 | ||||||
| 			c.error('cannot copy map: call `move` or `clone` method (or use a reference)', | 			c.error('cannot copy map: call `move` or `clone` method (or use a reference)', | ||||||
|  | @ -3479,12 +3478,12 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 		} | 		} | ||||||
| 		left_is_ptr := left_type.is_ptr() || left_sym.is_pointer() | 		left_is_ptr := left_type.is_ptr() || left_sym.is_pointer() | ||||||
| 		if left_is_ptr && !left.is_auto_deref_var() { | 		if left_is_ptr && !left.is_auto_deref_var() { | ||||||
| 			if !c.inside_unsafe && assign_stmt.op !in [.assign, .decl_assign] { | 			if !c.inside_unsafe && node.op !in [.assign, .decl_assign] { | ||||||
| 				// ptr op=
 | 				// ptr op=
 | ||||||
| 				c.warn('pointer arithmetic is only allowed in `unsafe` blocks', assign_stmt.pos) | 				c.warn('pointer arithmetic is only allowed in `unsafe` blocks', node.pos) | ||||||
| 			} | 			} | ||||||
| 			right_is_ptr := right_type.is_ptr() || right_sym.is_pointer() | 			right_is_ptr := right_type.is_ptr() || right_sym.is_pointer() | ||||||
| 			if !right_is_ptr && assign_stmt.op == .assign && right_type_unwrapped.is_number() { | 			if !right_is_ptr && node.op == .assign && right_type_unwrapped.is_number() { | ||||||
| 				c.error('cannot assign to `$left`: ' + | 				c.error('cannot assign to `$left`: ' + | ||||||
| 					c.expected_msg(right_type_unwrapped, left_type_unwrapped), right.position()) | 					c.expected_msg(right_type_unwrapped, left_type_unwrapped), right.position()) | ||||||
| 			} | 			} | ||||||
|  | @ -3496,29 +3495,29 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 					rtype = rtype.deref() | 					rtype = rtype.deref() | ||||||
| 				} | 				} | ||||||
| 				right_name := c.table.type_to_str(rtype) | 				right_name := c.table.type_to_str(rtype) | ||||||
| 				c.error('mismatched types `$left_name` and `$right_name`', assign_stmt.pos) | 				c.error('mismatched types `$left_name` and `$right_name`', node.pos) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		// Single side check
 | 		// Single side check
 | ||||||
| 		match assign_stmt.op { | 		match node.op { | ||||||
| 			.assign {} // No need to do single side check for =. But here put it first for speed.
 | 			.assign {} // No need to do single side check for =. But here put it first for speed.
 | ||||||
| 			.plus_assign, .minus_assign { | 			.plus_assign, .minus_assign { | ||||||
| 				if left_type == ast.string_type { | 				if left_type == ast.string_type { | ||||||
| 					if assign_stmt.op != .plus_assign { | 					if node.op != .plus_assign { | ||||||
| 						c.error('operator `$assign_stmt.op` not defined on left operand type `$left_sym.name`', | 						c.error('operator `$node.op` not defined on left operand type `$left_sym.name`', | ||||||
| 							left.position()) | 							left.position()) | ||||||
| 					} | 					} | ||||||
| 					if right_type != ast.string_type { | 					if right_type != ast.string_type { | ||||||
| 						c.error('invalid right operand: $left_sym.name $assign_stmt.op $right_sym.name', | 						c.error('invalid right operand: $left_sym.name $node.op $right_sym.name', | ||||||
| 							right.position()) | 							right.position()) | ||||||
| 					} | 					} | ||||||
| 				} else if !left_sym.is_number() | 				} else if !left_sym.is_number() | ||||||
| 					&& left_sym.kind !in [.byteptr, .charptr, .struct_, .alias] { | 					&& left_sym.kind !in [.byteptr, .charptr, .struct_, .alias] { | ||||||
| 					c.error('operator `$assign_stmt.op` not defined on left operand type `$left_sym.name`', | 					c.error('operator `$node.op` not defined on left operand type `$left_sym.name`', | ||||||
| 						left.position()) | 						left.position()) | ||||||
| 				} else if !right_sym.is_number() | 				} else if !right_sym.is_number() | ||||||
| 					&& left_sym.kind !in [.byteptr, .charptr, .struct_, .alias] { | 					&& left_sym.kind !in [.byteptr, .charptr, .struct_, .alias] { | ||||||
| 					c.error('invalid right operand: $left_sym.name $assign_stmt.op $right_sym.name', | 					c.error('invalid right operand: $left_sym.name $node.op $right_sym.name', | ||||||
| 						right.position()) | 						right.position()) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -3526,12 +3525,12 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 				if !left_sym.is_number() | 				if !left_sym.is_number() | ||||||
| 					&& !c.table.get_final_type_symbol(left_type_unwrapped).is_int() | 					&& !c.table.get_final_type_symbol(left_type_unwrapped).is_int() | ||||||
| 					&& left_sym.kind !in [.struct_, .alias] { | 					&& left_sym.kind !in [.struct_, .alias] { | ||||||
| 					c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.name`', | 					c.error('operator $node.op.str() not defined on left operand type `$left_sym.name`', | ||||||
| 						left.position()) | 						left.position()) | ||||||
| 				} else if !right_sym.is_number() | 				} else if !right_sym.is_number() | ||||||
| 					&& !c.table.get_final_type_symbol(left_type_unwrapped).is_int() | 					&& !c.table.get_final_type_symbol(left_type_unwrapped).is_int() | ||||||
| 					&& left_sym.kind !in [.struct_, .alias] { | 					&& left_sym.kind !in [.struct_, .alias] { | ||||||
| 					c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.name`', | 					c.error('operator $node.op.str() not defined on right operand type `$right_sym.name`', | ||||||
| 						right.position()) | 						right.position()) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -3539,26 +3538,26 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 			.right_shift_assign { | 			.right_shift_assign { | ||||||
| 				if !left_sym.is_int() | 				if !left_sym.is_int() | ||||||
| 					&& !c.table.get_final_type_symbol(left_type_unwrapped).is_int() { | 					&& !c.table.get_final_type_symbol(left_type_unwrapped).is_int() { | ||||||
| 					c.error('operator $assign_stmt.op.str() not defined on left operand type `$left_sym.name`', | 					c.error('operator $node.op.str() not defined on left operand type `$left_sym.name`', | ||||||
| 						left.position()) | 						left.position()) | ||||||
| 				} else if !right_sym.is_int() | 				} else if !right_sym.is_int() | ||||||
| 					&& !c.table.get_final_type_symbol(right_type_unwrapped).is_int() { | 					&& !c.table.get_final_type_symbol(right_type_unwrapped).is_int() { | ||||||
| 					c.error('operator $assign_stmt.op.str() not defined on right operand type `$right_sym.name`', | 					c.error('operator $node.op.str() not defined on right operand type `$right_sym.name`', | ||||||
| 						right.position()) | 						right.position()) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			else {} | 			else {} | ||||||
| 		} | 		} | ||||||
| 		if assign_stmt.op in [.plus_assign, .minus_assign, .mod_assign, .mult_assign, .div_assign] | 		if node.op in [.plus_assign, .minus_assign, .mod_assign, .mult_assign, .div_assign] | ||||||
| 			&& ((left_sym.kind == .struct_ && right_sym.kind == .struct_) | 			&& ((left_sym.kind == .struct_ && right_sym.kind == .struct_) | ||||||
| 			|| left_sym.kind == .alias) { | 			|| left_sym.kind == .alias) { | ||||||
| 			left_name := c.table.type_to_str(left_type) | 			left_name := c.table.type_to_str(left_type) | ||||||
| 			right_name := c.table.type_to_str(right_type) | 			right_name := c.table.type_to_str(right_type) | ||||||
| 			parent_sym := c.table.get_final_type_symbol(left_type) | 			parent_sym := c.table.get_final_type_symbol(left_type) | ||||||
| 			if left_sym.kind == .alias && right_sym.kind != .alias { | 			if left_sym.kind == .alias && right_sym.kind != .alias { | ||||||
| 				c.error('mismatched types `$left_name` and `$right_name`', assign_stmt.pos) | 				c.error('mismatched types `$left_name` and `$right_name`', node.pos) | ||||||
| 			} | 			} | ||||||
| 			extracted_op := match assign_stmt.op { | 			extracted_op := match node.op { | ||||||
| 				.plus_assign { '+' } | 				.plus_assign { '+' } | ||||||
| 				.minus_assign { '-' } | 				.minus_assign { '-' } | ||||||
| 				.div_assign { '/' } | 				.div_assign { '/' } | ||||||
|  | @ -3569,18 +3568,18 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 			if method := left_sym.find_method(extracted_op) { | 			if method := left_sym.find_method(extracted_op) { | ||||||
| 				if method.return_type != left_type { | 				if method.return_type != left_type { | ||||||
| 					c.error('operator `$extracted_op` must return `$left_name` to be used as an assignment operator', | 					c.error('operator `$extracted_op` must return `$left_name` to be used as an assignment operator', | ||||||
| 						assign_stmt.pos) | 						node.pos) | ||||||
| 				} | 				} | ||||||
| 			} else { | 			} else { | ||||||
| 				if parent_sym.is_primitive() { | 				if parent_sym.is_primitive() { | ||||||
| 					c.error('cannot use operator methods on type alias for `$parent_sym.name`', | 					c.error('cannot use operator methods on type alias for `$parent_sym.name`', | ||||||
| 						assign_stmt.pos) | 						node.pos) | ||||||
| 				} | 				} | ||||||
| 				if left_name == right_name { | 				if left_name == right_name { | ||||||
| 					c.error('undefined operation `$left_name` $extracted_op `$right_name`', | 					c.error('undefined operation `$left_name` $extracted_op `$right_name`', | ||||||
| 						assign_stmt.pos) | 						node.pos) | ||||||
| 				} else { | 				} else { | ||||||
| 					c.error('mismatched types `$left_name` and `$right_name`', assign_stmt.pos) | 					c.error('mismatched types `$left_name` and `$right_name`', node.pos) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -3590,10 +3589,10 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 			c.check_expected(right_type_unwrapped, left_type_unwrapped) or { | 			c.check_expected(right_type_unwrapped, left_type_unwrapped) or { | ||||||
| 				// 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() | ||||||
| 					&& assign_stmt.op in [.plus_assign, .minus_assign] { | 					&& node.op in [.plus_assign, .minus_assign] { | ||||||
| 					if !c.inside_unsafe { | 					if !c.inside_unsafe { | ||||||
| 						c.warn('pointer arithmetic is only allowed in `unsafe` blocks', | 						c.warn('pointer arithmetic is only allowed in `unsafe` blocks', | ||||||
| 							assign_stmt.pos) | 							node.pos) | ||||||
| 					} | 					} | ||||||
| 				} else { | 				} else { | ||||||
| 					c.error('cannot assign to `$left`: $err.msg', right.position()) | 					c.error('cannot assign to `$left`: $err.msg', right.position()) | ||||||
|  | @ -3608,8 +3607,8 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 	// so that ident.obj is set
 | 	// so that ident.obj is set
 | ||||||
| 	// Check `x := &y` and `mut x := <-ch`
 | 	// Check `x := &y` and `mut x := <-ch`
 | ||||||
| 	if right_first is ast.PrefixExpr { | 	if right_first is ast.PrefixExpr { | ||||||
| 		node := right_first | 		right_node := right_first | ||||||
| 		left_first := assign_stmt.left[0] | 		left_first := node.left[0] | ||||||
| 		if left_first is ast.Ident { | 		if left_first is ast.Ident { | ||||||
| 			assigned_var := left_first | 			assigned_var := left_first | ||||||
| 			mut is_shared := false | 			mut is_shared := false | ||||||
|  | @ -3617,41 +3616,40 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { | ||||||
| 				is_shared = left_first.info.share == .shared_t | 				is_shared = left_first.info.share == .shared_t | ||||||
| 			} | 			} | ||||||
| 			old_inside_ref_lit := c.inside_ref_lit | 			old_inside_ref_lit := c.inside_ref_lit | ||||||
| 			c.inside_ref_lit = (c.inside_ref_lit || node.op == .amp || is_shared) | 			c.inside_ref_lit = (c.inside_ref_lit || right_node.op == .amp || is_shared) | ||||||
| 			c.expr(node.right) | 			c.expr(right_node.right) | ||||||
| 			c.inside_ref_lit = old_inside_ref_lit | 			c.inside_ref_lit = old_inside_ref_lit | ||||||
| 			if node.op == .amp { | 			if right_node.op == .amp { | ||||||
| 				if node.right is ast.Ident { | 				if right_node.right is ast.Ident { | ||||||
| 					if node.right.obj is ast.Var { | 					if right_node.right.obj is ast.Var { | ||||||
| 						v := node.right.obj | 						v := right_node.right.obj | ||||||
| 						right_type0 = v.typ | 						right_type0 = v.typ | ||||||
| 						if !v.is_mut && assigned_var.is_mut && !c.inside_unsafe { | 						if !v.is_mut && assigned_var.is_mut && !c.inside_unsafe { | ||||||
| 							c.error('`$node.right.name` is immutable, cannot have a mutable reference to it', | 							c.error('`$right_node.right.name` is immutable, cannot have a mutable reference to it', | ||||||
| 								node.pos) | 								right_node.pos) | ||||||
| 						} | 						} | ||||||
| 					} else if node.right.obj is ast.ConstField { | 					} else if right_node.right.obj is ast.ConstField { | ||||||
| 						if assigned_var.is_mut && !c.inside_unsafe { | 						if assigned_var.is_mut && !c.inside_unsafe { | ||||||
| 							c.error('`$node.right.name` is immutable, cannot have a mutable reference to it', | 							c.error('`$right_node.right.name` is immutable, cannot have a mutable reference to it', | ||||||
| 								node.pos) | 								right_node.pos) | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			if node.op == .arrow { | 			if right_node.op == .arrow { | ||||||
| 				if assigned_var.is_mut { | 				if assigned_var.is_mut { | ||||||
| 					right_sym := c.table.get_type_symbol(right_type0) | 					right_sym := c.table.get_type_symbol(right_type0) | ||||||
| 					if right_sym.kind == .chan { | 					if right_sym.kind == .chan { | ||||||
| 						chan_info := right_sym.chan_info() | 						chan_info := right_sym.chan_info() | ||||||
| 						if chan_info.elem_type.is_ptr() && !chan_info.is_mut { | 						if chan_info.elem_type.is_ptr() && !chan_info.is_mut { | ||||||
| 							c.error('cannot have a mutable reference to object from `$right_sym.name`', | 							c.error('cannot have a mutable reference to object from `$right_sym.name`', | ||||||
| 								node.pos) | 								right_node.pos) | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	// right_sym := c.table.get_type_symbol(right_type_unwrapped)
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn scope_register_it(mut s ast.Scope, pos token.Position, typ ast.Type) { | fn scope_register_it(mut s ast.Scope, pos token.Position, typ ast.Type) { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue