Skip to content

Commit 9b88b5f

Browse files
committed
rustc: Don't allow private fields to be named in constructors or destructured
1 parent fba673b commit 9b88b5f

File tree

3 files changed

+79
-3
lines changed

3 files changed

+79
-3
lines changed

src/rustc/middle/privacy.rs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33

44
use /*mod*/ syntax::ast;
55
use /*mod*/ syntax::visit;
6-
use syntax::ast::{expr_field, ident, item_class, item_impl, item_trait};
7-
use syntax::ast::{local_crate, node_id, private, provided, required};
6+
use syntax::ast::{expr_field, expr_struct, ident, item_class, item_impl};
7+
use syntax::ast::{item_trait, local_crate, node_id, pat_struct, private};
8+
use syntax::ast::{provided, required};
89
use syntax::ast_map::{node_item, node_method};
910
use ty::ty_class;
1011
use typeck::{method_map, method_origin, method_param, method_static};
@@ -160,7 +161,7 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
160161
match method_map.find(expr.id) {
161162
None => {
162163
debug!("(privacy checking) checking \
163-
field");
164+
field access");
164165
check_field(expr.span, id, ident);
165166
}
166167
Some(entry) => {
@@ -173,11 +174,58 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
173174
_ => {}
174175
}
175176
}
177+
expr_struct(_, fields, _) => {
178+
match ty::get(ty::expr_ty(tcx, expr)).struct {
179+
ty_class(id, _) => {
180+
if id.crate != local_crate ||
181+
!privileged_items.contains(id.node) {
182+
for fields.each |field| {
183+
debug!("(privacy checking) checking \
184+
field in struct literal");
185+
check_field(expr.span, id,
186+
field.node.ident);
187+
}
188+
}
189+
}
190+
_ => {
191+
tcx.sess.span_bug(expr.span, ~"struct expr \
192+
didn't have \
193+
struct type?!");
194+
}
195+
}
196+
}
176197
_ => {}
177198
}
178199

179200
visit::visit_expr(expr, method_map, visitor);
180201
},
202+
visit_pat: |pattern, method_map, visitor| {
203+
match pattern.node {
204+
pat_struct(_, fields, _) => {
205+
match ty::get(ty::pat_ty(tcx, pattern)).struct {
206+
ty_class(id, _) => {
207+
if id.crate != local_crate ||
208+
!privileged_items.contains(id.node) {
209+
for fields.each |field| {
210+
debug!("(privacy checking) checking \
211+
struct pattern");
212+
check_field(pattern.span, id,
213+
field.ident);
214+
}
215+
}
216+
}
217+
_ => {
218+
tcx.sess.span_bug(pattern.span,
219+
~"struct pattern didn't have \
220+
struct type?!");
221+
}
222+
}
223+
}
224+
_ => {}
225+
}
226+
227+
visit::visit_pat(pattern, method_map, visitor);
228+
},
181229
.. *visit::default_visitor()
182230
});
183231
visit::visit_crate(*crate, method_map, visitor);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
mod a {
2+
struct Foo {
3+
priv x: int
4+
}
5+
}
6+
7+
fn main() {
8+
let s = a::Foo { x: 1 }; //~ ERROR field `x` is private
9+
}
10+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use a::Foo;
2+
3+
mod a {
4+
struct Foo {
5+
priv x: int
6+
}
7+
8+
fn make() -> Foo {
9+
Foo { x: 3 }
10+
}
11+
}
12+
13+
fn main() {
14+
match a::make() {
15+
Foo { x: _ } => {} //~ ERROR field `x` is private
16+
}
17+
}
18+

0 commit comments

Comments
 (0)