diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-01-23 15:46:12 -0800 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-01-23 15:48:08 -0800 |
| commit | 6db688e893f69632624fb8d2e3b747a3b81000b0 (patch) | |
| tree | 522ab62d11e6fea23652b7342a4dfbb599483b9d /src/comp | |
| parent | 9dc59e15061827122dc0f08d3f66acd17ba329dc (diff) | |
| download | rust-6db688e893f69632624fb8d2e3b747a3b81000b0.tar.gz rust-6db688e893f69632624fb8d2e3b747a3b81000b0.zip | |
Check that the names mentioned in tag exports are actually types (or variants)
Check that in export foo{}, foo is an enum type, and that in export
foo{bar, quux}, foo is an enum type and bar and quux are variants belonging
to foo.
Diffstat (limited to 'src/comp')
| -rw-r--r-- | src/comp/middle/resolve.rs | 60 |
1 files changed, 58 insertions, 2 deletions
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 |
