librustc: Implement a lint mode for mutable structures; deny by default. r=tjc

This commit is contained in:
Patrick Walton 2013-02-25 11:34:16 -08:00
parent 9b8ce0d3b5
commit c483aab4ae
9 changed files with 64 additions and 36 deletions

View File

@ -51,6 +51,7 @@ Implicitly, all crates behave as if they included the following prologue:
#[warn(vecs_implicitly_copyable)];
#[deny(non_camel_case_types)];
#[allow(deprecated_self)];
#[allow(deprecated_mutable_fields)];
/* The Prelude. */

View File

@ -80,6 +80,7 @@ pub enum lint {
type_limits,
default_methods,
deprecated_self,
deprecated_mutable_fields,
managed_heap_memory,
owned_heap_memory,
@ -254,6 +255,13 @@ pub fn get_lint_dict() -> LintDict {
default: warn
}),
(@~"deprecated_mutable_fields",
@LintSpec {
lint: deprecated_mutable_fields,
desc: "deprecated mutable fields in structures",
default: deny
}),
/* FIXME(#3266)--make liveness warnings lintable
(@~"unused_variable",
@LintSpec {
@ -486,6 +494,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
check_item_type_limits(cx, i);
check_item_default_methods(cx, i);
check_item_deprecated_self(cx, i);
check_item_deprecated_mutable_fields(cx, i);
}
// Take a visitor, and modify it so that it will not proceed past subitems.
@ -703,6 +712,26 @@ fn check_item_deprecated_self(cx: ty::ctxt, item: @ast::item) {
}
}
fn check_item_deprecated_mutable_fields(cx: ty::ctxt, item: @ast::item) {
match item.node {
ast::item_struct(struct_def, _) => {
for struct_def.fields.each |field| {
match field.node.kind {
ast::named_field(_, ast::struct_mutable, _) => {
cx.sess.span_lint(deprecated_mutable_fields,
item.id,
item.id,
field.span,
~"mutable fields are deprecated");
}
ast::named_field(*) | ast::unnamed_field => {}
}
}
}
_ => {}
}
}
fn check_item_structural_records(cx: ty::ctxt, it: @ast::item) {
let visit = item_stopping_visitor(
visit::mk_simple_visitor(@visit::SimpleVisitor {

View File

@ -29,6 +29,7 @@ not required in or otherwise suitable for the core library.
#[allow(vecs_implicitly_copyable)];
#[deny(non_camel_case_types)];
#[allow(deprecated_self)];
#[allow(deprecated_mutable_fields)];
#[no_core];

View File

@ -8,13 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
struct foo { mut z : fn@() }
struct foo { z : fn@() }
fn nop() { }
fn nop_foo(_y: ~[int], _x : @foo) { }
fn nop_foo(_y: ~[int], _x : @mut foo) { }
pub fn main() {
let w = @foo{ z: || nop() };
let w = @mut foo{ z: || nop() };
let x : fn@() = || nop_foo(~[], w);
w.z = x;
}

View File

@ -12,23 +12,22 @@
enum maybe_pointy {
none,
p(@Pointy)
p(@mut Pointy)
}
struct Pointy {
mut a : maybe_pointy,
mut f : fn@()->(),
a : maybe_pointy,
f : fn@()->(),
}
fn empty_pointy() -> @Pointy {
return @Pointy{
mut a : none,
mut f : fn@()->(){},
fn empty_pointy() -> @mut Pointy {
return @mut Pointy{
a : none,
f : fn@()->(){},
}
}
pub fn main()
{
pub fn main() {
let v = ~[empty_pointy(), empty_pointy()];
v[0].a = p(v[0]);
}

View File

@ -10,14 +10,14 @@
enum maybe_pointy {
no_pointy,
yes_pointy(@Pointy),
yes_pointy(@mut Pointy),
}
struct Pointy {
mut x : maybe_pointy
x : maybe_pointy
}
pub fn main() {
let m = @Pointy { mut x : no_pointy };
let m = @mut Pointy { x : no_pointy };
m.x = yes_pointy(m);
}

View File

@ -9,20 +9,20 @@
// except according to those terms.
struct cat {
priv mut meows : uint,
priv meows : uint,
how_hungry : int,
how_hungry : int,
}
impl cat {
fn play() {
self.meows += 1u;
self.nap();
}
fn play(&mut self) {
self.meows += 1u;
self.nap();
}
}
priv impl cat {
fn nap() { for uint::range(1u, 10u) |_i| { }}
fn nap(&mut self) { for uint::range(1u, 10u) |_i| { }}
}
fn cat(in_x : uint, in_y : int) -> cat {
@ -33,6 +33,6 @@ fn cat(in_x : uint, in_y : int) -> cat {
}
pub fn main() {
let nyan : cat = cat(52u, 99);
let mut nyan : cat = cat(52u, 99);
nyan.play();
}

View File

@ -10,11 +10,11 @@
enum maybe_pointy {
none,
p(@Pointy),
p(@mut Pointy),
}
struct Pointy {
mut a : maybe_pointy,
a : maybe_pointy,
d : fn~() -> uint,
}
@ -22,15 +22,14 @@ fn make_uniq_closure<A:Owned + Copy>(a: A) -> fn~() -> uint {
fn~() -> uint { ptr::addr_of(&a) as uint }
}
fn empty_pointy() -> @Pointy {
return @Pointy {
fn empty_pointy() -> @mut Pointy {
return @mut Pointy {
mut a : none,
d : make_uniq_closure(~"hi")
}
}
pub fn main()
{
pub fn main() {
let v = empty_pointy();
v.a = p(v);
}

View File

@ -10,25 +10,24 @@
enum maybe_pointy {
none,
p(@Pointy),
p(@mut Pointy),
}
struct Pointy {
mut a : maybe_pointy,
a : maybe_pointy,
c : ~int,
d : fn~()->(),
}
fn empty_pointy() -> @Pointy {
return @Pointy {
mut a : none,
fn empty_pointy() -> @mut Pointy {
return @mut Pointy {
a : none,
c : ~22,
d : fn~()->(){},
}
}
pub fn main()
{
pub fn main() {
let v = empty_pointy();
v.a = p(v);
}