about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-01-22 21:09:43 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-01-23 15:48:08 -0800
commit9dc59e15061827122dc0f08d3f66acd17ba329dc (patch)
treed98b61d751f5db6d33c844d3706a9c6a4f399524
parente51599932478db1d841912a6e0a10cbc20335e1f (diff)
downloadrust-9dc59e15061827122dc0f08d3f66acd17ba329dc.tar.gz
rust-9dc59e15061827122dc0f08d3f66acd17ba329dc.zip
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.
-rw-r--r--src/comp/middle/resolve.rs2
-rw-r--r--src/comp/syntax/ast.rs2
-rw-r--r--src/comp/syntax/ast_util.rs27
-rw-r--r--src/comp/syntax/parse/parser.rs23
-rw-r--r--src/comp/syntax/print/pprust.rs13
-rw-r--r--src/test/compile-fail/export-no-tag-variants.rs12
-rw-r--r--src/test/compile-fail/tag-exports-2.rs16
-rw-r--r--src/test/compile-fail/tag-exports-3.rs17
-rw-r--r--src/test/compile-fail/tag-exports.rs16
-rw-r--r--src/test/run-pass/tag-exports.rs24
10 files changed, 89 insertions, 63 deletions
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index 6f0ae757049..9cbf6bf74a1 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -1403,6 +1403,8 @@ fn index_mod(md: ast::_mod) -> mod_index {
           }
           //globbed imports have to be resolved lazily.
           ast::view_item_import_glob(_, _) | ast::view_item_export(_, _) {}
+          // exports: ignore
+          _ {}
         }
     }
     for it: @ast::item in md.items {
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index cafea5ed976..661bb68309d 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -442,7 +442,7 @@ enum view_item_ {
     // export foo::{}
     view_item_export_tag_none(ident, node_id),
     // 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
diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs
index 24b9757a4f4..7a88359d26c 100644
--- a/src/comp/syntax/ast_util.rs
+++ b/src/comp/syntax/ast_util.rs
@@ -113,12 +113,16 @@ fn float_ty_to_str(t: float_ty) -> str {
 
 fn is_exported(i: ident, m: _mod) -> bool {
     let nonlocal = true;
+    let parent_tag : option<ident> = none;
     for it: @item in m.items {
         if it.ident == i { nonlocal = false; }
         alt it.node {
           item_tag(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,9 +133,28 @@ fn is_exported(i: ident, m: _mod) -> bool {
     for vi: @view_item in m.view_items {
         alt vi.node {
           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;
+          }
           _ {/* fall through */ }
         }
     }
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index d020c46c6a0..b18db178fcd 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -194,10 +194,18 @@ fn spanned<T: copy>(lo: uint, hi: uint, node: T) -> spanned<T> {
 fn parse_ident(p: parser) -> ast::ident {
     alt p.token {
       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 {
     check_bad_word(p);
     ret parse_ident(p);
@@ -2316,12 +2324,6 @@ fn parse_rest_import_name(p: parser, first: ast::ident,
 
 
           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_ =
                 parse_seq(token::LBRACE, token::RBRACE, seq_sep(token::COMMA),
                           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_ {
-    let tagnames:[ast::ident] =
+    let tagnames:[ast::import_ident] =
         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();
     if vec::is_empty(tagnames) {
        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_ {
     let first = parse_ident(p);
     alt p.token {
-       token::COLON {
+       token::MOD_SEP {
            p.bump();
-           expect(p, token::COLON);
            ret parse_tag_export(p, first);
        }
        t {
diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs
index a57cf3add14..2ebcaa055a7 100644
--- a/src/comp/syntax/print/pprust.rs
+++ b/src/comp/syntax/print/pprust.rs
@@ -1303,6 +1303,19 @@ fn print_view_item(s: ps, item: @ast::view_item) {
         commasep(s, inconsistent, ids,
                  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, ";");
     end(s); // end inner head-block
diff --git a/src/test/compile-fail/export-no-tag-variants.rs b/src/test/compile-fail/export-no-tag-variants.rs
deleted file mode 100644
index 7de42bf0a0d..00000000000
--- a/src/test/compile-fail/export-no-tag-variants.rs
+++ /dev/null
@@ -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; }
diff --git a/src/test/compile-fail/tag-exports-2.rs b/src/test/compile-fail/tag-exports-2.rs
index 04bac524d9b..94727838488 100644
--- a/src/test/compile-fail/tag-exports-2.rs
+++ b/src/test/compile-fail/tag-exports-2.rs
@@ -1,18 +1,18 @@
-// xfail-test
+// error-pattern:unresolved name: lovejoy
+import alder::*;
+
 mod alder {
   export burnside;
   export everett::{flanders};
   export irving::{johnson, kearney};
   export marshall::{};
 
-  tag burnside { couch, davis }
-  tag everett { flanders, glisan, hoyt }
-  tag irving { johnson, kearney, lovejoy }
-  tag marshall { northrup, overton }
+  enum burnside { couch, davis }
+  enum everett { flanders, glisan, hoyt }
+  enum irving { johnson, kearney, lovejoy }
+  enum marshall { northrup, overton }
 }
 
-import alder::*;
-
 fn main() {
   let raleigh: irving = lovejoy;
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/tag-exports-3.rs b/src/test/compile-fail/tag-exports-3.rs
index 8b58c1b9ff0..e51a0aca115 100644
--- a/src/test/compile-fail/tag-exports-3.rs
+++ b/src/test/compile-fail/tag-exports-3.rs
@@ -1,19 +1,18 @@
-// xfail-test
+// error-pattern:unresolved name: northrup
+import alder::*;
+
 mod alder {
   export burnside;
   export everett::{flanders};
   export irving::{johnson, kearney};
   export marshall::{};
 
-  tag burnside { couch, davis }
-  tag everett { flanders, glisan, hoyt }
-  tag irving { johnson, kearney, lovejoy }
-  tag marshall { northrup, overton }
+  enum burnside { couch, davis }
+  enum everett { flanders, glisan, hoyt }
+  enum irving { johnson, kearney, lovejoy }
+  enum marshall { northrup, overton }
 }
 
-import alder::*;
-
 fn main() {
   let savier: marshall = northrup;
-
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/tag-exports.rs b/src/test/compile-fail/tag-exports.rs
index 79cb33f0fb2..18965c91842 100644
--- a/src/test/compile-fail/tag-exports.rs
+++ b/src/test/compile-fail/tag-exports.rs
@@ -1,18 +1,18 @@
-// xfail-test
+// error-pattern:unresolved name: glisan
+import alder::*;
+
 mod alder {
   export burnside;
   export everett::{flanders};
   export irving::{johnson, kearney};
   export marshall::{};
 
-  tag burnside { couch, davis }
-  tag everett { flanders, glisan, hoyt }
-  tag irving { johnson, kearney, lovejoy }
-  tag marshall { northrup, overton }
+  enum burnside { couch, davis }
+  enum everett { flanders, glisan, hoyt }
+  enum irving { johnson, kearney, lovejoy }
+  enum marshall { northrup, overton }
 }
 
-import alder::*;
-
 fn main() {
   let quimby: everett = glisan;
-}
\ No newline at end of file
+}
diff --git a/src/test/run-pass/tag-exports.rs b/src/test/run-pass/tag-exports.rs
index 719e252b732..597bcc66f96 100644
--- a/src/test/run-pass/tag-exports.rs
+++ b/src/test/run-pass/tag-exports.rs
@@ -1,21 +1,21 @@
-// xfail-test
+import alder::*;
+
 mod alder {
   export burnside;
   export everett::{flanders};
   export irving::{johnson, kearney};
   export marshall::{};
 
-  tag burnside { couch, davis }
-  tag everett { flanders, glisan, hoyt }
-  tag irving { johnson, kearney, lovejoy }
-  tag marshall { northrup, overton }
-}
+  enum burnside { couch, davis }
+  enum everett { flanders, glisan, hoyt }
+  enum irving { johnson, kearney, lovejoy }
+  enum marshall { northrup, overton }
 
-import alder::*;
+}
 
 fn main() {
-  let pettygrove: burnside = couch;
-  let quimby: everett = flanders;
-  let raleigh: irving = johnson;
-  let savier: marshall;
-}
\ No newline at end of file
+  let _pettygrove: burnside = couch;
+  let _quimby: everett = flanders;
+  let _raleigh: irving = johnson;
+  let _savier: marshall;
+}