Browse Source

Allow `x in ptr_to_map_or_bit_set`

gingerBill 4 years ago
parent
commit
3662275119
3 changed files with 18 additions and 10 deletions
  1. 11 9
      src/check_expr.cpp
  2. 2 1
      src/check_stmt.cpp
  3. 5 0
      src/llvm_backend.cpp

+ 11 - 9
src/check_expr.cpp

@@ -2597,15 +2597,16 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint
 
 	case Token_in:
 	case Token_not_in:
+	{
 		// IMPORTANT NOTE(bill): This uses right-left evaluation in type checking only no in
-
 		check_expr(c, y, be->right);
+		Type *rhs_type = type_deref(y->type);
 
-		if (is_type_bit_set(y->type)) {
-			Type *elem = base_type(y->type)->BitSet.elem;
+		if (is_type_bit_set(rhs_type)) {
+			Type *elem = base_type(rhs_type)->BitSet.elem;
 			check_expr_with_type_hint(c, x, be->left, elem);
-		} else if (is_type_map(y->type)) {
-			Type *key = base_type(y->type)->Map.key;
+		} else if (is_type_map(rhs_type)) {
+			Type *key = base_type(rhs_type)->Map.key;
 			check_expr_with_type_hint(c, x, be->left, key);
 		} else {
 			check_expr(c, x, be->left);
@@ -2620,8 +2621,8 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint
 			return;
 		}
 
-		if (is_type_map(y->type)) {
-			Type *yt = base_type(y->type);
+		if (is_type_map(rhs_type)) {
+			Type *yt = base_type(rhs_type);
 			if (op.kind == Token_in) {
 				check_assignment(c, x, yt->Map.key, str_lit("map 'in'"));
 			} else {
@@ -2629,8 +2630,8 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint
 			}
 
 			add_package_dependency(c, "runtime", "__dynamic_map_get");
-		} else if (is_type_bit_set(y->type)) {
-			Type *yt = base_type(y->type);
+		} else if (is_type_bit_set(rhs_type)) {
+			Type *yt = base_type(rhs_type);
 
 			if (op.kind == Token_in) {
 				check_assignment(c, x, yt->BitSet.elem, str_lit("bit_set 'in'"));
@@ -2679,6 +2680,7 @@ void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Type *type_hint
 		x->expr = node;
 
 		return;
+	}
 
 	default:
 		if (is_ise_expr(be->left)) {

+ 2 - 1
src/check_stmt.cpp

@@ -1884,7 +1884,8 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 				error(operand.expr, "Cannot iterate over '%s' of type '%s'", s, t);
 
 				if (rs->vals.count == 1) {
-					if (is_type_map(operand.type) || is_type_bit_set(operand.type)) {
+					Type *t = type_deref(operand.type);
+					if (is_type_map(t) || is_type_bit_set(t)) {
 						gbString v = expr_to_string(rs->vals[0]);
 						defer (gb_string_free(v));
 						error_line("\tSuggestion: place parentheses around the expression\n");

+ 5 - 0
src/llvm_backend.cpp

@@ -7753,6 +7753,11 @@ lbValue lb_build_binary_expr(lbProcedure *p, Ast *expr) {
 			Type *type = default_type(tv.type);
 			lbValue right = lb_build_expr(p, be->right);
 			Type *rt = base_type(right.type);
+			if (is_type_pointer(rt)) {
+				right = lb_emit_load(p, right);
+				rt = type_deref(rt);
+			}
+
 			switch (rt->kind) {
 			case Type_Map:
 				{