diff --git a/src/compiler/resolver_method.cc b/src/compiler/resolver_method.cc index de344aa03..efdec94ef 100644 --- a/src/compiler/resolver_method.cc +++ b/src/compiler/resolver_method.cc @@ -4031,7 +4031,30 @@ ir::Expression* MethodResolver::_assign_identifier(ast::Binary* node, } else { ir_value = resolve_expression(ast_right, "Can't use block value in assignment", true); } - return create_set(ir_value); + auto result = create_set(ir_value); + if (result->is_AssignmentLocal()) { + bool reported_warning = false; + auto assig = result->as_AssignmentLocal(); + auto local = assig->local(); + auto right = assig->right(); + if (right->is_ReferenceLocal() && right->as_ReferenceLocal()->target() == local) { + if (_method->is_constructor() || _method->is_instance()) { + auto fields = _method->holder()->fields(); + for (int i = 0; i < fields.length(); i++) { + auto field_name = fields[i]->name(); + if (field_name.is_valid() && field_name == local->name()) { + diagnostics()->report_warning(node, "Assigning local to itself has no effect. Did you forget 'this.'?"); + reported_warning = true; + break; + } + } + } + if (!reported_warning) { + diagnostics()->report_warning(node, "Assigning local to itself"); + } + } + } + return result; } diff --git a/tests/negative/assign_self_test.toit b/tests/negative/assign_self_test.toit new file mode 100644 index 000000000..d81ab4dca --- /dev/null +++ b/tests/negative/assign_self_test.toit @@ -0,0 +1,16 @@ +main: + local := 3 + local = local + unresolved + +class A: + field := 499 + + constructor field: + field = field + + method field: + field = field + + static static_method field: + field = field diff --git a/tests/negative/gold/assign_self_test.gold b/tests/negative/gold/assign_self_test.gold new file mode 100644 index 000000000..30e2b1051 --- /dev/null +++ b/tests/negative/gold/assign_self_test.gold @@ -0,0 +1,16 @@ +tests/negative/assign_self_test.toit:3:9: warning: Assigning local to itself + local = local + ^ +tests/negative/assign_self_test.toit:4:3: error: Unresolved identifier: 'unresolved' + unresolved + ^~~~~~~~~~ +tests/negative/assign_self_test.toit:10:11: warning: Assigning local to itself has no effect. Did you forget 'this.'? + field = field + ^ +tests/negative/assign_self_test.toit:16:11: warning: Assigning local to itself + field = field + ^ +tests/negative/assign_self_test.toit:13:11: warning: Assigning local to itself has no effect. Did you forget 'this.'? + field = field + ^ +Compilation failed.