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.
This commit is contained in:
parent
9dc59e1506
commit
6db688e893
@ -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
|
||||
|
||||
|
11
src/test/compile-fail/bad-tag-export-2.rs
Normal file
11
src/test/compile-fail/bad-tag-export-2.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// error-pattern:b does not refer to an enumeration
|
||||
import bad::*;
|
||||
|
||||
mod bad {
|
||||
export b::{};
|
||||
|
||||
fn b() { fail; }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
13
src/test/compile-fail/bad-tag-export-3.rs
Normal file
13
src/test/compile-fail/bad-tag-export-3.rs
Normal file
@ -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() {
|
||||
}
|
12
src/test/compile-fail/bad-tag-export-4.rs
Normal file
12
src/test/compile-fail/bad-tag-export-4.rs
Normal file
@ -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() {
|
||||
}
|
14
src/test/compile-fail/bad-tag-export.rs
Normal file
14
src/test/compile-fail/bad-tag-export.rs
Normal file
@ -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() {
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user