about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-05-06 16:45:21 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-05-06 16:45:21 -0700
commit49efab8ac9044e2cb8ea31ac16fa088af88faf4d (patch)
tree18ac9280a00c938c88615ed38d33232511a44d6c
parentcf6857b9e9427f14d383ae2924555bedc251fa02 (diff)
downloadrust-49efab8ac9044e2cb8ea31ac16fa088af88faf4d.tar.gz
rust-49efab8ac9044e2cb8ea31ac16fa088af88faf4d.zip
rustc: Fix enum variant privacy across crates
The code in resolve erroneously assumed that private enums weren't visited, so
the logic was adjusted to check to see if the enum definition itself was public.

Closes #11680
-rw-r--r--src/librustc/middle/resolve.rs14
-rw-r--r--src/test/auxiliary/issue-11680.rs19
-rw-r--r--src/test/compile-fail/issue-11680.rs21
3 files changed, 48 insertions, 6 deletions
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 95f18b75bec..27373ce045d 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -1620,18 +1620,20 @@ impl<'a> Resolver<'a> {
 
         match def {
           DefMod(_) | DefForeignMod(_) => {}
-          DefVariant(_, variant_id, is_struct) => {
+          DefVariant(enum_did, variant_id, is_struct) => {
             debug!("(building reduced graph for external crate) building \
                     variant {}",
                    final_ident);
-            // We assume the parent is visible, or else we wouldn't have seen
-            // it. Also variants are public-by-default if the parent was also
-            // public.
+            // If this variant is public, then it was publicly reexported,
+            // otherwise we need to inherit the visibility of the enum
+            // definition.
+            let is_exported = is_public ||
+                              self.external_exports.contains(&enum_did);
             if is_struct {
-                child_name_bindings.define_type(def, DUMMY_SP, true);
+                child_name_bindings.define_type(def, DUMMY_SP, is_exported);
                 self.structs.insert(variant_id);
             } else {
-                child_name_bindings.define_value(def, DUMMY_SP, true);
+                child_name_bindings.define_value(def, DUMMY_SP, is_exported);
             }
           }
           DefFn(..) | DefStaticMethod(..) | DefStatic(..) => {
diff --git a/src/test/auxiliary/issue-11680.rs b/src/test/auxiliary/issue-11680.rs
new file mode 100644
index 00000000000..249a1bab465
--- /dev/null
+++ b/src/test/auxiliary/issue-11680.rs
@@ -0,0 +1,19 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+enum Foo {
+    Bar(int)
+}
+
+pub mod test {
+    enum Foo {
+        Bar(int)
+    }
+}
diff --git a/src/test/compile-fail/issue-11680.rs b/src/test/compile-fail/issue-11680.rs
new file mode 100644
index 00000000000..9c9663a2f38
--- /dev/null
+++ b/src/test/compile-fail/issue-11680.rs
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:issue-11680.rs
+
+extern crate other = "issue-11680";
+
+fn main() {
+    let _b = other::Bar(1);
+    //~^ ERROR: variant `Bar` is private
+
+    let _b = other::test::Bar(1);
+    //~^ ERROR: variant `Bar` is private
+}