瀏覽代碼

Let -vet ignore intentional declaration shadowing #637

gingerBill 5 年之前
父節點
當前提交
fcdfcfce19
共有 3 個文件被更改,包括 27 次插入7 次删除
  1. 4 0
      src/check_decl.cpp
  2. 22 7
      src/checker.cpp
  3. 1 0
      src/entity.cpp

+ 4 - 0
src/check_decl.cpp

@@ -40,6 +40,10 @@ Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, Stri
 		return nullptr;
 	}
 
+	if (e->kind == Entity_Variable) {
+		e->Variable.init_expr = operand->expr;
+	}
+
 	if (operand->mode == Addressing_Type) {
 		if (e->type != nullptr && is_type_typeid(e->type)) {
 			add_type_info_type(ctx, operand->type);

+ 22 - 7
src/checker.cpp

@@ -506,15 +506,30 @@ bool check_vet_shadowing(Checker *c, Entity *e, VettedEntity *ve) {
 		return false;
 	}
 	// NOTE(bill): If the types differ, don't complain
-	if (are_types_identical(e->type, shadowed->type)) {
-		gb_zero_item(ve);
-		ve->kind = VettedEntity_Shadowed;
-		ve->entity = e;
-		ve->other = shadowed;
-		return true;
+	if (!are_types_identical(e->type, shadowed->type)) {
+		return false;
 	}
 
-	return false;
+	// NOTE(bill): Ignore intentional redeclaration
+	// x := x;
+	// Suggested in issue #637 (2020-05-11)
+	if ((e->flags & EntityFlag_Using) == 0 && e->kind == Entity_Variable) {
+		Ast *init = unparen_expr(e->Variable.init_expr);
+		if (init != nullptr && init->kind == Ast_Ident) {
+			// TODO(bill): Which logic is better? Same name or same entity
+			// bool ignore = init->Ident.token.string == name;
+			bool ignore = init->Ident.entity == shadowed;
+			if (ignore) {
+				return false;
+			}
+		}
+	}
+
+	gb_zero_item(ve);
+	ve->kind = VettedEntity_Shadowed;
+	ve->entity = e;
+	ve->other = shadowed;
+	return true;
 }
 
 bool check_vet_unused(Checker *c, Entity *e, VettedEntity *ve) {

+ 1 - 0
src/entity.cpp

@@ -121,6 +121,7 @@ struct Entity {
 			ExactValue value;
 		} Constant;
 		struct {
+			Ast *init_expr; // only used for some variables within procedure bodies
 			i32        field_index;
 			i32        field_src_index;