about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBenjamin Herr <ben@0x539.de>2014-04-05 19:28:01 +0200
committerBenjamin Herr <ben@0x539.de>2014-04-06 02:37:25 +0200
commitd4b73a741195f70d540e9be7df7b9d41f87ab570 (patch)
tree873b38a66ffcdcfa0c2679564e8e9ef418d4502a
parent9539be6d746bec6b7b43e358999a91e4d1f9a759 (diff)
downloadrust-d4b73a741195f70d540e9be7df7b9d41f87ab570.tar.gz
rust-d4b73a741195f70d540e9be7df7b9d41f87ab570.zip
name struct in "field `...` is private" error
-rw-r--r--src/librustc/middle/privacy.rs38
-rw-r--r--src/test/auxiliary/privacy-struct-variant.rs17
-rw-r--r--src/test/compile-fail/issue-3763.rs12
-rw-r--r--src/test/compile-fail/privacy-struct-variant.rs48
-rw-r--r--src/test/compile-fail/privacy5.rs41
-rw-r--r--src/test/compile-fail/private-struct-field-cross-crate.rs3
-rw-r--r--src/test/compile-fail/private-struct-field-ctor.rs2
-rw-r--r--src/test/compile-fail/private-struct-field-pattern.rs2
-rw-r--r--src/test/compile-fail/private-struct-field.rs2
-rw-r--r--src/test/compile-fail/struct-field-privacy.rs8
10 files changed, 135 insertions, 38 deletions
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 9d9faee3645..ee514ba5f24 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -576,15 +576,37 @@ impl<'a> PrivacyVisitor<'a> {
             }
             UnnamedField(idx) => fields.get(idx)
         };
-        if field.vis == ast::Public { return }
-        if !is_local(field.id) || !self.private_accessible(field.id.node) {
-            let msg = match name {
-                NamedField(name) => format!("field `{}` is private",
-                                            token::get_ident(name)),
-                UnnamedField(idx) => format!("field \\#{} is private", idx + 1),
-            };
-            self.tcx.sess.span_err(span, msg);
+        if field.vis == ast::Public ||
+            (is_local(field.id) && self.private_accessible(field.id.node)) {
+            return
         }
+
+        let struct_type = ty::lookup_item_type(self.tcx, id).ty;
+        let struct_desc = match ty::get(struct_type).sty {
+            ty::ty_struct(_, _) => format!("struct `{}`", ty::item_path_str(self.tcx, id)),
+            ty::ty_bare_fn(ty::BareFnTy { sig: ty::FnSig { output, .. }, .. }) => {
+                // Struct `id` is really a struct variant of an enum,
+                // and we're really looking at the variant's constructor
+                // function. So get the return type for a detailed error
+                // message.
+                let enum_id = match ty::get(output).sty {
+                    ty::ty_enum(id, _) => id,
+                    _ => self.tcx.sess.span_bug(span, "enum variant doesn't \
+                                                       belong to an enum")
+                };
+                format!("variant `{}` of enum `{}`",
+                        ty::with_path(self.tcx, id, |mut p| p.last().unwrap()),
+                        ty::item_path_str(self.tcx, enum_id))
+            }
+            _ => self.tcx.sess.span_bug(span, "can't find struct for field")
+        };
+        let msg = match name {
+            NamedField(name) => format!("field `{}` of {} is private",
+                                        token::get_ident(name), struct_desc),
+            UnnamedField(idx) => format!("field \\#{} of {} is private",
+                                         idx + 1, struct_desc),
+        };
+        self.tcx.sess.span_err(span, msg);
     }
 
     // Given the ID of a method, checks to ensure it's in scope.
diff --git a/src/test/auxiliary/privacy-struct-variant.rs b/src/test/auxiliary/privacy-struct-variant.rs
new file mode 100644
index 00000000000..af2e3328d3a
--- /dev/null
+++ b/src/test/auxiliary/privacy-struct-variant.rs
@@ -0,0 +1,17 @@
+// 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.
+
+#![feature(struct_variant)]
+
+pub enum Foo {
+    Bar {
+        baz: int
+    }
+}
diff --git a/src/test/compile-fail/issue-3763.rs b/src/test/compile-fail/issue-3763.rs
index 736ac55aef5..8eed8aa8644 100644
--- a/src/test/compile-fail/issue-3763.rs
+++ b/src/test/compile-fail/issue-3763.rs
@@ -24,11 +24,15 @@ mod my_mod {
 
 fn main() {
     let my_struct = my_mod::MyStruct();
-    let _woohoo = (&my_struct).priv_field; //~ ERROR field `priv_field` is private
-    let _woohoo = (~my_struct).priv_field; //~ ERROR field `priv_field` is private
-    let _woohoo = (@my_struct).priv_field; //~ ERROR field `priv_field` is private
+    let _woohoo = (&my_struct).priv_field;
+    //~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
+    let _woohoo = (~my_struct).priv_field;
+    //~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
+    let _woohoo = (@my_struct).priv_field;
+    //~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
     (&my_struct).happyfun();               //~ ERROR method `happyfun` is private
     (~my_struct).happyfun();               //~ ERROR method `happyfun` is private
     (@my_struct).happyfun();               //~ ERROR method `happyfun` is private
-    let nope = my_struct.priv_field;       //~ ERROR field `priv_field` is private
+    let nope = my_struct.priv_field;
+    //~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
 }
diff --git a/src/test/compile-fail/privacy-struct-variant.rs b/src/test/compile-fail/privacy-struct-variant.rs
new file mode 100644
index 00000000000..d6fab326ba1
--- /dev/null
+++ b/src/test/compile-fail/privacy-struct-variant.rs
@@ -0,0 +1,48 @@
+// 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:privacy-struct-variant.rs
+
+#![feature(struct_variant)]
+
+extern crate other = "privacy-struct-variant";
+
+mod a {
+    pub enum Foo {
+        Bar {
+            baz: int
+        }
+    }
+
+    fn test() {
+        let foo = Bar { baz: 42 };
+
+        let Bar { baz: _ } = foo;
+        match foo { Bar { baz: _ } => {} }
+    }
+}
+
+fn main() {
+    let foo = a::Bar { baz: 42 };
+    //~^ ERROR: field `baz` of variant `Bar` of enum `a::Foo` is private
+
+    let a::Bar { baz: _ } = foo;
+    //~^ ERROR: field `baz` of variant `Bar` of enum `a::Foo` is private
+    match foo { a::Bar { baz: _ } => {} }
+    //~^ ERROR: field `baz` of variant `Bar` of enum `a::Foo` is private
+    //
+    let foo = other::Bar { baz: 42 };
+    //~^ ERROR: field `baz` of variant `Bar` of enum `privacy-struct-variant::Foo` is private
+
+    let other::Bar { baz: _ } = foo;
+    //~^ ERROR: field `baz` of variant `Bar` of enum `privacy-struct-variant::Foo` is private
+    match foo { other::Bar { baz: _ } => {} }
+    //~^ ERROR: field `baz` of variant `Bar` of enum `privacy-struct-variant::Foo` is private
+}
diff --git a/src/test/compile-fail/privacy5.rs b/src/test/compile-fail/privacy5.rs
index c057236265e..2683022c4c8 100644
--- a/src/test/compile-fail/privacy5.rs
+++ b/src/test/compile-fail/privacy5.rs
@@ -64,25 +64,25 @@ fn this_crate() {
     let c = a::C(2, 3); //~ ERROR: cannot invoke tuple struct constructor
     let d = a::D(4);
 
-    let a::A(()) = a; //~ ERROR: field #1 is private
+    let a::A(()) = a; //~ ERROR: field #1 of struct `a::A` is private
     let a::A(_) = a;
-    match a { a::A(()) => {} } //~ ERROR: field #1 is private
+    match a { a::A(()) => {} } //~ ERROR: field #1 of struct `a::A` is private
     match a { a::A(_) => {} }
 
     let a::B(_) = b;
-    let a::B(_b) = b; //~ ERROR: field #1 is private
+    let a::B(_b) = b; //~ ERROR: field #1 of struct `a::B` is private
     match b { a::B(_) => {} }
-    match b { a::B(_b) => {} } //~ ERROR: field #1 is private
-    match b { a::B(1) => {} a::B(_) => {} } //~ ERROR: field #1 is private
+    match b { a::B(_b) => {} } //~ ERROR: field #1 of struct `a::B` is private
+    match b { a::B(1) => {} a::B(_) => {} } //~ ERROR: field #1 of struct `a::B` is private
 
     let a::C(_, _) = c;
     let a::C(_a, _) = c;
-    let a::C(_, _b) = c; //~ ERROR: field #2 is private
-    let a::C(_a, _b) = c; //~ ERROR: field #2 is private
+    let a::C(_, _b) = c; //~ ERROR: field #2 of struct `a::C` is private
+    let a::C(_a, _b) = c; //~ ERROR: field #2 of struct `a::C` is private
     match c { a::C(_, _) => {} }
     match c { a::C(_a, _) => {} }
-    match c { a::C(_, _b) => {} } //~ ERROR: field #2 is private
-    match c { a::C(_a, _b) => {} } //~ ERROR: field #2 is private
+    match c { a::C(_, _b) => {} } //~ ERROR: field #2 of struct `a::C` is private
+    match c { a::C(_a, _b) => {} } //~ ERROR: field #2 of struct `a::C` is private
 
     let a::D(_) = d;
     let a::D(_d) = d;
@@ -102,25 +102,30 @@ fn xcrate() {
     let c = other::C(2, 3); //~ ERROR: cannot invoke tuple struct constructor
     let d = other::D(4);
 
-    let other::A(()) = a; //~ ERROR: field #1 is private
+    let other::A(()) = a; //~ ERROR: field #1 of struct `privacy-tuple-struct::A` is private
     let other::A(_) = a;
-    match a { other::A(()) => {} } //~ ERROR: field #1 is private
+    match a { other::A(()) => {} }
+    //~^ ERROR: field #1 of struct `privacy-tuple-struct::A` is private
     match a { other::A(_) => {} }
 
     let other::B(_) = b;
-    let other::B(_b) = b; //~ ERROR: field #1 is private
+    let other::B(_b) = b; //~ ERROR: field #1 of struct `privacy-tuple-struct::B` is private
     match b { other::B(_) => {} }
-    match b { other::B(_b) => {} } //~ ERROR: field #1 is private
-    match b { other::B(1) => {} other::B(_) => {} } //~ ERROR: field #1 is private
+    match b { other::B(_b) => {} }
+    //~^ ERROR: field #1 of struct `privacy-tuple-struct::B` is private
+    match b { other::B(1) => {} other::B(_) => {} }
+    //~^ ERROR: field #1 of struct `privacy-tuple-struct::B` is private
 
     let other::C(_, _) = c;
     let other::C(_a, _) = c;
-    let other::C(_, _b) = c; //~ ERROR: field #2 is private
-    let other::C(_a, _b) = c; //~ ERROR: field #2 is private
+    let other::C(_, _b) = c; //~ ERROR: field #2 of struct `privacy-tuple-struct::C` is private
+    let other::C(_a, _b) = c; //~ ERROR: field #2 of struct `privacy-tuple-struct::C` is private
     match c { other::C(_, _) => {} }
     match c { other::C(_a, _) => {} }
-    match c { other::C(_, _b) => {} } //~ ERROR: field #2 is private
-    match c { other::C(_a, _b) => {} } //~ ERROR: field #2 is private
+    match c { other::C(_, _b) => {} }
+    //~^ ERROR: field #2 of struct `privacy-tuple-struct::C` is private
+    match c { other::C(_a, _b) => {} }
+    //~^ ERROR: field #2 of struct `privacy-tuple-struct::C` is private
 
     let other::D(_) = d;
     let other::D(_d) = d;
diff --git a/src/test/compile-fail/private-struct-field-cross-crate.rs b/src/test/compile-fail/private-struct-field-cross-crate.rs
index 0993ac9a64a..45c4b2b7ae1 100644
--- a/src/test/compile-fail/private-struct-field-cross-crate.rs
+++ b/src/test/compile-fail/private-struct-field-cross-crate.rs
@@ -14,5 +14,6 @@ use cci_class::kitties::cat;
 
 fn main() {
   let nyan : cat = cat(52u, 99);
-  assert!((nyan.meows == 52u));   //~ ERROR field `meows` is private
+  assert!((nyan.meows == 52u));
+  //~^ ERROR field `meows` of struct `cci_class::kitties::cat` is private
 }
diff --git a/src/test/compile-fail/private-struct-field-ctor.rs b/src/test/compile-fail/private-struct-field-ctor.rs
index a5cee47d4e3..ae19c221496 100644
--- a/src/test/compile-fail/private-struct-field-ctor.rs
+++ b/src/test/compile-fail/private-struct-field-ctor.rs
@@ -15,5 +15,5 @@ mod a {
 }
 
 fn main() {
-    let s = a::Foo { x: 1 };    //~ ERROR field `x` is private
+    let s = a::Foo { x: 1 };    //~ ERROR field `x` of struct `a::Foo` is private
 }
diff --git a/src/test/compile-fail/private-struct-field-pattern.rs b/src/test/compile-fail/private-struct-field-pattern.rs
index ee1303b99dd..991457ef1ce 100644
--- a/src/test/compile-fail/private-struct-field-pattern.rs
+++ b/src/test/compile-fail/private-struct-field-pattern.rs
@@ -22,6 +22,6 @@ mod a {
 
 fn main() {
     match a::make() {
-        Foo { x: _ } => {}  //~ ERROR field `x` is private
+        Foo { x: _ } => {}  //~ ERROR field `x` of struct `a::Foo` is private
     }
 }
diff --git a/src/test/compile-fail/private-struct-field.rs b/src/test/compile-fail/private-struct-field.rs
index 52e979342f5..3f6fa573cc0 100644
--- a/src/test/compile-fail/private-struct-field.rs
+++ b/src/test/compile-fail/private-struct-field.rs
@@ -20,5 +20,5 @@ mod cat {
 
 fn main() {
     let nyan = cat::new_cat();
-    assert!(nyan.meows == 52);    //~ ERROR field `meows` is private
+    assert!(nyan.meows == 52);    //~ ERROR field `meows` of struct `cat::Cat` is private
 }
diff --git a/src/test/compile-fail/struct-field-privacy.rs b/src/test/compile-fail/struct-field-privacy.rs
index b6ae7235bb3..82ba9a02a30 100644
--- a/src/test/compile-fail/struct-field-privacy.rs
+++ b/src/test/compile-fail/struct-field-privacy.rs
@@ -32,16 +32,16 @@ fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B) {
     //~^^ ERROR: struct `A` is private
 
     a.a;
-    b.a; //~ ERROR: field `a` is private
+    b.a; //~ ERROR: field `a` of struct `inner::A` is private
     b.b;
     c.a;
-    c.b; //~ ERROR: field `b` is private
+    c.b; //~ ERROR: field `b` of struct `inner::B` is private
 
-    d.a; //~ ERROR: field `a` is private
+    d.a; //~ ERROR: field `a` of struct `struct-field-privacy::A` is private
     d.b;
 
     e.a;
-    e.b; //~ ERROR: field `b` is private
+    e.b; //~ ERROR: field `b` of struct `struct-field-privacy::B` is private
 }
 
 fn main() {}