Export all enum variants by default; new syntax for selectively exporting variants
See issue 1426 for details. Now, the semantics of "export t;" where t is a tag are to export all of t's variants as well. "export t{};" exports t but not its variants, while "export t{a, b, c};" exports only variants a, b, c of t. To do: - documentation - there's currently no checking that a, b, c are actually variants of t in the above example - there's also no checking that t is an enum type, in the second two examples above - change the modules listed in issue 1426 that should have the old export semantics to use the t{} syntax I deleted the test export-no-tag-variants since we're doing the opposite now, and other tests cover the same behavior.
This commit is contained in:
parent
e515999324
commit
9dc59e1506
10 changed files with 89 additions and 63 deletions
|
@ -1403,6 +1403,8 @@ fn index_mod(md: ast::_mod) -> mod_index {
|
||||||
}
|
}
|
||||||
//globbed imports have to be resolved lazily.
|
//globbed imports have to be resolved lazily.
|
||||||
ast::view_item_import_glob(_, _) | ast::view_item_export(_, _) {}
|
ast::view_item_import_glob(_, _) | ast::view_item_export(_, _) {}
|
||||||
|
// exports: ignore
|
||||||
|
_ {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for it: @ast::item in md.items {
|
for it: @ast::item in md.items {
|
||||||
|
|
|
@ -442,7 +442,7 @@ enum view_item_ {
|
||||||
// export foo::{}
|
// export foo::{}
|
||||||
view_item_export_tag_none(ident, node_id),
|
view_item_export_tag_none(ident, node_id),
|
||||||
// export foo::{bar, baz, blat}
|
// export foo::{bar, baz, blat}
|
||||||
view_item_export_tag_some(ident, [ident], node_id)
|
view_item_export_tag_some(ident, [import_ident], node_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Meta-data associated with an item
|
// Meta-data associated with an item
|
||||||
|
|
|
@ -113,12 +113,16 @@ fn float_ty_to_str(t: float_ty) -> str {
|
||||||
|
|
||||||
fn is_exported(i: ident, m: _mod) -> bool {
|
fn is_exported(i: ident, m: _mod) -> bool {
|
||||||
let nonlocal = true;
|
let nonlocal = true;
|
||||||
|
let parent_tag : option<ident> = none;
|
||||||
for it: @item in m.items {
|
for it: @item in m.items {
|
||||||
if it.ident == i { nonlocal = false; }
|
if it.ident == i { nonlocal = false; }
|
||||||
alt it.node {
|
alt it.node {
|
||||||
item_tag(variants, _) {
|
item_tag(variants, _) {
|
||||||
for v: variant in variants {
|
for v: variant in variants {
|
||||||
if v.node.name == i { nonlocal = false; }
|
if v.node.name == i {
|
||||||
|
nonlocal = false;
|
||||||
|
parent_tag = some(it.ident);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ { }
|
_ { }
|
||||||
|
@ -129,7 +133,26 @@ fn is_exported(i: ident, m: _mod) -> bool {
|
||||||
for vi: @view_item in m.view_items {
|
for vi: @view_item in m.view_items {
|
||||||
alt vi.node {
|
alt vi.node {
|
||||||
view_item_export(ids, _) {
|
view_item_export(ids, _) {
|
||||||
for id in ids { if str::eq(i, id) { ret true; } }
|
// If any of ids is a tag, we want to consider
|
||||||
|
// all the variants to be exported
|
||||||
|
for id in ids {
|
||||||
|
if str::eq(i, id) { ret true; }
|
||||||
|
alt parent_tag {
|
||||||
|
some(parent_tag_id) {
|
||||||
|
if str::eq(id, parent_tag_id) { ret true; }
|
||||||
|
}
|
||||||
|
_ { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count += 1u;
|
||||||
|
}
|
||||||
|
view_item_export_tag_none(id, _) {
|
||||||
|
if str::eq(i, id) { ret true; }
|
||||||
|
count += 1u;
|
||||||
|
}
|
||||||
|
view_item_export_tag_some(id, ids, _) {
|
||||||
|
if str::eq(i, id) { ret true; }
|
||||||
|
for id in ids { if str::eq(i, id.node.name) { ret true; } }
|
||||||
count += 1u;
|
count += 1u;
|
||||||
}
|
}
|
||||||
_ {/* fall through */ }
|
_ {/* fall through */ }
|
||||||
|
|
|
@ -194,10 +194,18 @@ fn spanned<T: copy>(lo: uint, hi: uint, node: T) -> spanned<T> {
|
||||||
fn parse_ident(p: parser) -> ast::ident {
|
fn parse_ident(p: parser) -> ast::ident {
|
||||||
alt p.token {
|
alt p.token {
|
||||||
token::IDENT(i, _) { p.bump(); ret p.get_str(i); }
|
token::IDENT(i, _) { p.bump(); ret p.get_str(i); }
|
||||||
_ { p.fatal("expecting ident"); }
|
_ { p.fatal("expecting ident, found "
|
||||||
|
+ token::to_str(p.reader, p.token)); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_import_ident(p: parser) -> ast::import_ident {
|
||||||
|
let lo = p.span.lo;
|
||||||
|
let ident = parse_ident(p);
|
||||||
|
let hi = p.span.hi;
|
||||||
|
ret spanned(lo, hi, {name: ident, id: p.get_id()});
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_value_ident(p: parser) -> ast::ident {
|
fn parse_value_ident(p: parser) -> ast::ident {
|
||||||
check_bad_word(p);
|
check_bad_word(p);
|
||||||
ret parse_ident(p);
|
ret parse_ident(p);
|
||||||
|
@ -2316,12 +2324,6 @@ fn parse_rest_import_name(p: parser, first: ast::ident,
|
||||||
|
|
||||||
|
|
||||||
token::LBRACE {
|
token::LBRACE {
|
||||||
fn parse_import_ident(p: parser) -> ast::import_ident {
|
|
||||||
let lo = p.span.lo;
|
|
||||||
let ident = parse_ident(p);
|
|
||||||
let hi = p.span.hi;
|
|
||||||
ret spanned(lo, hi, {name: ident, id: p.get_id()});
|
|
||||||
}
|
|
||||||
let from_idents_ =
|
let from_idents_ =
|
||||||
parse_seq(token::LBRACE, token::RBRACE, seq_sep(token::COMMA),
|
parse_seq(token::LBRACE, token::RBRACE, seq_sep(token::COMMA),
|
||||||
parse_import_ident, p).node;
|
parse_import_ident, p).node;
|
||||||
|
@ -2392,9 +2394,9 @@ fn parse_import(p: parser) -> ast::view_item_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_tag_export(p:parser, tyname:ast::ident) -> ast::view_item_ {
|
fn parse_tag_export(p:parser, tyname:ast::ident) -> ast::view_item_ {
|
||||||
let tagnames:[ast::ident] =
|
let tagnames:[ast::import_ident] =
|
||||||
parse_seq(token::LBRACE, token::RBRACE,
|
parse_seq(token::LBRACE, token::RBRACE,
|
||||||
seq_sep(token::COMMA), {|p| parse_ident(p) }, p).node;
|
seq_sep(token::COMMA), {|p| parse_import_ident(p) }, p).node;
|
||||||
let id = p.get_id();
|
let id = p.get_id();
|
||||||
if vec::is_empty(tagnames) {
|
if vec::is_empty(tagnames) {
|
||||||
ret ast::view_item_export_tag_none(tyname, id);
|
ret ast::view_item_export_tag_none(tyname, id);
|
||||||
|
@ -2407,9 +2409,8 @@ fn parse_tag_export(p:parser, tyname:ast::ident) -> ast::view_item_ {
|
||||||
fn parse_export(p: parser) -> ast::view_item_ {
|
fn parse_export(p: parser) -> ast::view_item_ {
|
||||||
let first = parse_ident(p);
|
let first = parse_ident(p);
|
||||||
alt p.token {
|
alt p.token {
|
||||||
token::COLON {
|
token::MOD_SEP {
|
||||||
p.bump();
|
p.bump();
|
||||||
expect(p, token::COLON);
|
|
||||||
ret parse_tag_export(p, first);
|
ret parse_tag_export(p, first);
|
||||||
}
|
}
|
||||||
t {
|
t {
|
||||||
|
|
|
@ -1303,6 +1303,19 @@ fn print_view_item(s: ps, item: @ast::view_item) {
|
||||||
commasep(s, inconsistent, ids,
|
commasep(s, inconsistent, ids,
|
||||||
fn@(s: ps, &&w: ast::ident) { word(s.s, w) });
|
fn@(s: ps, &&w: ast::ident) { word(s.s, w) });
|
||||||
}
|
}
|
||||||
|
ast::view_item_export_tag_none(id, _) {
|
||||||
|
head(s, "export");
|
||||||
|
word(s.s, id);
|
||||||
|
word(s.s, "::{}");
|
||||||
|
}
|
||||||
|
ast::view_item_export_tag_some(id, ids, _) {
|
||||||
|
head(s, "export");
|
||||||
|
word(s.s, id);
|
||||||
|
word(s.s, "::{");
|
||||||
|
commasep(s, inconsistent, ids, fn@(s:ps, &&w: ast::import_ident) {
|
||||||
|
word(s.s, w.node.name) });
|
||||||
|
word(s.s, "}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
word(s.s, ";");
|
word(s.s, ";");
|
||||||
end(s); // end inner head-block
|
end(s); // end inner head-block
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
// error-pattern: unresolved name
|
|
||||||
|
|
||||||
// Tag variants are not exported with their tags. This allows for a
|
|
||||||
// simple sort of ADT.
|
|
||||||
|
|
||||||
mod foo {
|
|
||||||
export t;
|
|
||||||
|
|
||||||
enum t { t1, }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() { let x = foo::t1; }
|
|
|
@ -1,18 +1,18 @@
|
||||||
// xfail-test
|
// error-pattern:unresolved name: lovejoy
|
||||||
|
import alder::*;
|
||||||
|
|
||||||
mod alder {
|
mod alder {
|
||||||
export burnside;
|
export burnside;
|
||||||
export everett::{flanders};
|
export everett::{flanders};
|
||||||
export irving::{johnson, kearney};
|
export irving::{johnson, kearney};
|
||||||
export marshall::{};
|
export marshall::{};
|
||||||
|
|
||||||
tag burnside { couch, davis }
|
enum burnside { couch, davis }
|
||||||
tag everett { flanders, glisan, hoyt }
|
enum everett { flanders, glisan, hoyt }
|
||||||
tag irving { johnson, kearney, lovejoy }
|
enum irving { johnson, kearney, lovejoy }
|
||||||
tag marshall { northrup, overton }
|
enum marshall { northrup, overton }
|
||||||
}
|
}
|
||||||
|
|
||||||
import alder::*;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let raleigh: irving = lovejoy;
|
let raleigh: irving = lovejoy;
|
||||||
}
|
}
|
|
@ -1,19 +1,18 @@
|
||||||
// xfail-test
|
// error-pattern:unresolved name: northrup
|
||||||
|
import alder::*;
|
||||||
|
|
||||||
mod alder {
|
mod alder {
|
||||||
export burnside;
|
export burnside;
|
||||||
export everett::{flanders};
|
export everett::{flanders};
|
||||||
export irving::{johnson, kearney};
|
export irving::{johnson, kearney};
|
||||||
export marshall::{};
|
export marshall::{};
|
||||||
|
|
||||||
tag burnside { couch, davis }
|
enum burnside { couch, davis }
|
||||||
tag everett { flanders, glisan, hoyt }
|
enum everett { flanders, glisan, hoyt }
|
||||||
tag irving { johnson, kearney, lovejoy }
|
enum irving { johnson, kearney, lovejoy }
|
||||||
tag marshall { northrup, overton }
|
enum marshall { northrup, overton }
|
||||||
}
|
}
|
||||||
|
|
||||||
import alder::*;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let savier: marshall = northrup;
|
let savier: marshall = northrup;
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,18 +1,18 @@
|
||||||
// xfail-test
|
// error-pattern:unresolved name: glisan
|
||||||
|
import alder::*;
|
||||||
|
|
||||||
mod alder {
|
mod alder {
|
||||||
export burnside;
|
export burnside;
|
||||||
export everett::{flanders};
|
export everett::{flanders};
|
||||||
export irving::{johnson, kearney};
|
export irving::{johnson, kearney};
|
||||||
export marshall::{};
|
export marshall::{};
|
||||||
|
|
||||||
tag burnside { couch, davis }
|
enum burnside { couch, davis }
|
||||||
tag everett { flanders, glisan, hoyt }
|
enum everett { flanders, glisan, hoyt }
|
||||||
tag irving { johnson, kearney, lovejoy }
|
enum irving { johnson, kearney, lovejoy }
|
||||||
tag marshall { northrup, overton }
|
enum marshall { northrup, overton }
|
||||||
}
|
}
|
||||||
|
|
||||||
import alder::*;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let quimby: everett = glisan;
|
let quimby: everett = glisan;
|
||||||
}
|
}
|
|
@ -1,21 +1,21 @@
|
||||||
// xfail-test
|
import alder::*;
|
||||||
|
|
||||||
mod alder {
|
mod alder {
|
||||||
export burnside;
|
export burnside;
|
||||||
export everett::{flanders};
|
export everett::{flanders};
|
||||||
export irving::{johnson, kearney};
|
export irving::{johnson, kearney};
|
||||||
export marshall::{};
|
export marshall::{};
|
||||||
|
|
||||||
tag burnside { couch, davis }
|
enum burnside { couch, davis }
|
||||||
tag everett { flanders, glisan, hoyt }
|
enum everett { flanders, glisan, hoyt }
|
||||||
tag irving { johnson, kearney, lovejoy }
|
enum irving { johnson, kearney, lovejoy }
|
||||||
tag marshall { northrup, overton }
|
enum marshall { northrup, overton }
|
||||||
}
|
|
||||||
|
|
||||||
import alder::*;
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let pettygrove: burnside = couch;
|
let _pettygrove: burnside = couch;
|
||||||
let quimby: everett = flanders;
|
let _quimby: everett = flanders;
|
||||||
let raleigh: irving = johnson;
|
let _raleigh: irving = johnson;
|
||||||
let savier: marshall;
|
let _savier: marshall;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue