diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-09-04 14:48:32 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-09-04 14:50:46 -0700 |
| commit | 127144bf38f5bf81112bb304efb95a80d54bcaac (patch) | |
| tree | 725c4184d1820dc893f777e33880a76027dafe87 /src/rustc | |
| parent | 8182497359237cf2d842bc614eae2bf24bc2517a (diff) | |
| download | rust-127144bf38f5bf81112bb304efb95a80d54bcaac.tar.gz rust-127144bf38f5bf81112bb304efb95a80d54bcaac.zip | |
rustc: Implement private fields for max/min classes
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/driver/driver.rs | 3 | ||||
| -rw-r--r-- | src/rustc/middle/privacy.rs | 75 | ||||
| -rw-r--r-- | src/rustc/middle/ty.rs | 4 | ||||
| -rw-r--r-- | src/rustc/middle/typeck.rs | 5 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/check.rs | 16 | ||||
| -rw-r--r-- | src/rustc/rustc.rc | 1 |
6 files changed, 83 insertions, 21 deletions
diff --git a/src/rustc/driver/driver.rs b/src/rustc/driver/driver.rs index 345678bb661..9c6a168d10f 100644 --- a/src/rustc/driver/driver.rs +++ b/src/rustc/driver/driver.rs @@ -221,6 +221,9 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg, if upto == cu_typeck { return {crate: crate, tcx: Some(ty_cx)}; } + time(time_passes, ~"privacy checking", || + middle::privacy::check_crate(ty_cx, crate)); + time(time_passes, ~"loop checking", || middle::check_loop::check_crate(ty_cx, crate)); diff --git a/src/rustc/middle/privacy.rs b/src/rustc/middle/privacy.rs new file mode 100644 index 00000000000..83c341c609a --- /dev/null +++ b/src/rustc/middle/privacy.rs @@ -0,0 +1,75 @@ +// A pass that checks to make sure private fields and methods aren't used +// outside their scopes. + +use /*mod*/ syntax::ast; +use /*mod*/ syntax::visit; +use syntax::ast::{expr_field, ident, item_class, local_crate, node_id}; +use syntax::ast::{private}; +use ty::ty_class; + +use core::util::ignore; +use dvec::DVec; +use send_map::linear::LinearMap; + +fn check_crate(tcx: ty::ctxt, crate: @ast::crate) { + let privileged_structs = @DVec(); + + let add_privileged_structs = |items: &[@ast::item]| { + let mut count = 0; + for items.each |item| { + match item.node { + item_class(*) => { + privileged_structs.push(item.id); + count += 1; + } + _ => {} + } + } + count + }; + + let visitor = visit::mk_vt(@{ + visit_mod: |the_module, span, node_id, env, visitor| { + let n_added = add_privileged_structs(the_module.items); + + visit::visit_mod(the_module, span, node_id, env, visitor); + + for n_added.times { + ignore(privileged_structs.pop()); + } + }, + visit_expr: |expr, env, visitor| { + match expr.node { + expr_field(base, ident, _) => { + match ty::get(ty::expr_ty(tcx, base)).struct { + ty_class(id, _) + if id.crate != local_crate || + !privileged_structs.contains(id.node) => { + let fields = ty::lookup_class_fields(tcx, id); + for fields.each |field| { + if field.ident != ident { again; } + if field.vis == private { + tcx.sess.span_err(expr.span, + fmt!("field `%s` is \ + private", + *tcx.sess + .parse_sess + .interner + .get(ident))); + } + break; + } + } + _ => {} + } + } + _ => {} + } + + visit::visit_expr(expr, env, visitor); + } + with *visit::default_visitor() + }); + visit::visit_crate(*crate, (), visitor); +} + diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index f473244eda8..a3b9f1d05ac 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -3160,10 +3160,6 @@ fn lookup_class_field(cx: ctxt, parent: ast::def_id, field_id: ast::def_id) } } -fn lookup_public_fields(cx: ctxt, did: ast::def_id) -> ~[field_ty] { - vec::filter(lookup_class_fields(cx, did), is_public) -} - pure fn is_public(f: field_ty) -> bool { // XXX: This is wrong. match f.vis { diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index dc484f581e7..87012054779 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -51,9 +51,8 @@ use util::common::may_break; use syntax::codemap::span; use pat_util::{pat_is_variant, pat_id_map}; use middle::ty; -use middle::ty::{arg, field, node_type_table, mk_nil, - ty_param_bounds_and_ty, lookup_public_fields, - vstore_uniq}; +use middle::ty::{arg, field, node_type_table, mk_nil, ty_param_bounds_and_ty}; +use middle::ty::{vstore_uniq}; use std::smallintmap; use std::map; use std::map::{hashmap, int_hash}; diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index dd8ac61dd46..ad0eb81c826 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -1317,18 +1317,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, // (1) verify that the class id actually has a field called // field debug!("class named %s", ty_to_str(tcx, base_t)); - /* - check whether this is a self-reference or not, which - determines whether we look at all fields or only public - ones - */ - let cls_items = if self_ref(fcx, base.id) { - // base expr is "self" -- consider all fields - ty::lookup_class_fields(tcx, base_id) - } - else { - lookup_public_fields(tcx, base_id) - }; + let cls_items = ty::lookup_class_fields(tcx, base_id); match lookup_field_ty(tcx, base_id, cls_items, field, &substs) { Some(field_ty) => { // (2) look up what field's type is, and return it @@ -1370,8 +1359,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, let msg = fmt!( "attempted access of field `%s` on type `%s`, \ - but no public field or method with that name \ - was found", + but no field or method with that name was found", tcx.sess.str_of(field), fcx.infcx().ty_to_str(t_err)); tcx.sess.span_err(expr.span, msg); diff --git a/src/rustc/rustc.rc b/src/rustc/rustc.rc index da347abad87..6890ec0acdc 100644 --- a/src/rustc/rustc.rc +++ b/src/rustc/rustc.rc @@ -102,6 +102,7 @@ mod middle { mod const_eval; mod astencode; mod lang_items; + mod privacy; } mod front { |
