Commit a50474e7cf

Andrew Kelley <superjoe30@gmail.com>
2016-02-03 04:06:51
fix false positive error with same named methods in incomplete struct
1 parent d3de737
Changed files (2)
src/analyze.cpp
@@ -5062,12 +5062,20 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
         case NodeTypeFnProto:
             {
                 // if the name is missing, we immediately announce an error
-                Buf *name = &node->data.fn_proto.name;
-                if (buf_len(name) == 0) {
+                Buf *fn_name = &node->data.fn_proto.name;
+                if (buf_len(fn_name) == 0) {
                     node->data.fn_proto.skip = true;
                     add_node_error(g, node, buf_sprintf("missing function name"));
                     break;
                 }
+                Buf *qualified_name;
+                AstNode *struct_node = node->data.fn_proto.struct_node;
+                if (struct_node) {
+                    Buf *struct_name = &struct_node->data.struct_decl.name;
+                    qualified_name = buf_sprintf("%s.%s", buf_ptr(struct_name), buf_ptr(fn_name));
+                } else {
+                    qualified_name = fn_name;
+                }
 
 
                 // determine which other top level declarations this function prototype depends on.
@@ -5076,14 +5084,14 @@ static void detect_top_level_decl_deps(CodeGen *g, ImportTableEntry *import, Ast
 
                 collect_expr_decl_deps(g, import, node, decl_node);
 
-                decl_node->name = name;
+                decl_node->name = qualified_name;
                 decl_node->import = import;
                 if (decl_node->deps.size() > 0) {
-                    if (g->unresolved_top_level_decls.maybe_get(name)) {
+                    if (g->unresolved_top_level_decls.maybe_get(qualified_name)) {
                         node->data.fn_proto.skip = true;
-                        add_node_error(g, node, buf_sprintf("redefinition of '%s'", buf_ptr(name)));
+                        add_node_error(g, node, buf_sprintf("redefinition of '%s'", buf_ptr(fn_name)));
                     } else {
-                        g->unresolved_top_level_decls.put(name, node);
+                        g->unresolved_top_level_decls.put(qualified_name, node);
                     }
                 } else {
                     resolve_top_level_decl(g, import, node);
test/run_tests.cpp
@@ -1549,6 +1549,35 @@ pub fn main(args: [][]u8) -> %void {
 }
 
     )SOURCE", "OK\n");
+
+
+    add_simple_case("same named methods in incomplete struct", R"SOURCE(
+import "std.zig";
+
+struct Foo {
+    field1: Bar,
+
+    fn method(a: &Foo) -> bool { true }
+}
+
+struct Bar {
+    field2: i32,
+
+    fn method(b: &Bar) -> bool { true }
+}
+
+pub fn main(args: [][]u8) -> %void {
+    const bar = Bar {.field2 = 13,};
+    const foo = Foo {.field1 = bar,};
+    if (!foo.method()) {
+        %%stdout.printf("BAD\n");
+    }
+    if (!bar.method()) {
+        %%stdout.printf("BAD\n");
+    }
+    %%stdout.printf("OK\n");
+}
+    )SOURCE", "OK\n");
 }