about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-12-11 19:15:12 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-12-11 19:17:31 -0800
commitd42bdf1997ebaeb8a893947df563ff07d039cf08 (patch)
tree5c0f15fc99198056b5bcb1c069f9bff32cb8d848
parenta7159be24a9c81517a46e09c7ff62cadc72759b6 (diff)
downloadrust-d42bdf1997ebaeb8a893947df563ff07d039cf08.tar.gz
rust-d42bdf1997ebaeb8a893947df563ff07d039cf08.zip
Auto-deref when checking field and method privacy
This disallows using pointers to sneak around priv qualifiers.

Deeming this too small for review as well. Closes #3763
-rw-r--r--src/librustc/middle/privacy.rs9
-rw-r--r--src/test/compile-fail/issue-3763.rs15
2 files changed, 17 insertions, 7 deletions
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 1bde3f82f72..78c423b791d 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -199,7 +199,10 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
         visit_expr: |expr, method_map: &method_map, visitor| {
             match expr.node {
                 expr_field(base, ident, _) => {
-                    match ty::get(ty::expr_ty(tcx, base)).sty {
+                    // With type_autoderef, make sure we don't
+                    // allow pointers to violate privacy
+                    match ty::get(ty::type_autoderef(tcx, ty::expr_ty(tcx,
+                                                          base))).sty {
                         ty_struct(id, _)
                         if id.crate != local_crate ||
                            !privileged_items.contains(&(id.node)) => {
@@ -220,7 +223,9 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
                     }
                 }
                 expr_method_call(base, _, _, _, _) => {
-                    match ty::get(ty::expr_ty(tcx, base)).sty {
+                    // Ditto
+                    match ty::get(ty::type_autoderef(tcx, ty::expr_ty(tcx,
+                                                          base))).sty {
                         ty_struct(id, _)
                         if id.crate != local_crate ||
                            !privileged_items.contains(&(id.node)) => {
diff --git a/src/test/compile-fail/issue-3763.rs b/src/test/compile-fail/issue-3763.rs
index 8ee5dab41ed..ea4b70c3c29 100644
--- a/src/test/compile-fail/issue-3763.rs
+++ b/src/test/compile-fail/issue-3763.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// xfail-test
 mod my_mod {
     pub struct MyStruct {
         priv priv_field: int
@@ -16,12 +15,18 @@ mod my_mod {
     pub fn MyStruct () -> MyStruct {
         MyStruct {priv_field: 4}
     }
+    impl MyStruct {
+        priv fn happyfun() {}
+    }
 }
 
 fn main() {
     let my_struct = my_mod::MyStruct();
-    let _woohoo = (&my_struct).priv_field; // compiles but shouldn't
-    let _woohoo = (~my_struct).priv_field; // ditto
-    let _woohoo = (@my_struct).priv_field; // ditto
-   // let nope = my_struct.priv_field;       // compile error as expected
+    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
+    (&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
 }