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
This commit is contained in:
Tim Chevalier 2012-12-11 19:15:12 -08:00
parent a7159be24a
commit d42bdf1997
2 changed files with 17 additions and 7 deletions

View File

@ -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)) => {

View File

@ -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
}