diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 9cbf6bf74a1..3b49f8c33ad 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -1766,6 +1766,32 @@ fn check_exports(e: @env) { } } + fn check_enum_ok(e: @env, sp:span, id: ident, val: @indexed_mod) + -> node_id { + alt val.index.find(id) { + none { e.sess.span_fatal(sp, #fmt("error: undefined id %s\ + in an export", id)); } + some(ms) { + let maybe_id = list::find(ms) {|m| + alt m { + mie_item(an_item) { + alt an_item.node { + item_tag(_,_) { /* OK */ some(an_item.id) } + _ { none } + } + } + _ { none } + } + }; + alt maybe_id { + some(an_id) { ret an_id; } + _ { e.sess.span_fatal(sp, #fmt("error: %s does not refer \ + to an enumeration", id)); } + } + } + } + } + e.mod_map.values {|val| alt val.m { some(m) { @@ -1776,14 +1802,44 @@ fn check_exports(e: @env) { check_export(e, ident, val, vi); } } + ast::view_item_export_tag_none(id, _) { + let _ = check_enum_ok(e, vi.span, id, val); + } + ast::view_item_export_tag_some(id, ids, _) { + // Check that it's an enum and all the given variants + // belong to it + let parent_id = check_enum_ok(e, vi.span, id, val); + for variant_id in ids { + alt val.index.find(variant_id.node.name) { + some(ms) { + list::iter(ms) {|m| + alt m { + mie_tag_variant(parent_item,_) { + if parent_item.id != parent_id { + e.sess.span_err(vi.span, + #fmt("variant %s \ + doesn't belong to enum %s", + variant_id.node.name, + id)); + } + } + _ { e.sess.span_err(vi.span, + #fmt("%s is not a \ + variant", variant_id.node.name)); } + }} + } + _ { e.sess.span_err(vi.span, #fmt("%s is not a\ + variant", variant_id.node.name)); } + } + } + } _ { } } } } none { } } - }; -} + }} // Impl resolution diff --git a/src/test/compile-fail/bad-tag-export-2.rs b/src/test/compile-fail/bad-tag-export-2.rs new file mode 100644 index 00000000000..09018c2167f --- /dev/null +++ b/src/test/compile-fail/bad-tag-export-2.rs @@ -0,0 +1,11 @@ +// error-pattern:b does not refer to an enumeration +import bad::*; + +mod bad { + export b::{}; + + fn b() { fail; } +} + +fn main() { +} \ No newline at end of file diff --git a/src/test/compile-fail/bad-tag-export-3.rs b/src/test/compile-fail/bad-tag-export-3.rs new file mode 100644 index 00000000000..e6934688e21 --- /dev/null +++ b/src/test/compile-fail/bad-tag-export-3.rs @@ -0,0 +1,13 @@ +// error-pattern:b does not refer to an enumeration +import bad::*; + +mod bad { + export b::{f, z}; + + fn b() { fail; } + fn f() { fail; } + fn z() { fail; } +} + +fn main() { +} \ No newline at end of file diff --git a/src/test/compile-fail/bad-tag-export-4.rs b/src/test/compile-fail/bad-tag-export-4.rs new file mode 100644 index 00000000000..fadf0c353a3 --- /dev/null +++ b/src/test/compile-fail/bad-tag-export-4.rs @@ -0,0 +1,12 @@ +// error-pattern:f is not a variant +import bad::*; + +mod bad { + export b::{f, z}; + + enum b { z, k } + fn f() { fail; } +} + +fn main() { +} \ No newline at end of file diff --git a/src/test/compile-fail/bad-tag-export.rs b/src/test/compile-fail/bad-tag-export.rs new file mode 100644 index 00000000000..fb9d9b8682c --- /dev/null +++ b/src/test/compile-fail/bad-tag-export.rs @@ -0,0 +1,14 @@ +// error-pattern:variant e doesn't belong to enum floop +import bad::*; + +mod bad { + + export floop::{a, e}; + + enum floop {a, b, c} + enum bloop {d, e, f} + +} + +fn main() { +} \ No newline at end of file