librustc: Lint the old drop
destructor notation off
This commit is contained in:
parent
7353568cd8
commit
08c840205e
12
doc/rust.md
12
doc/rust.md
@ -889,10 +889,10 @@ declared, in an angle-bracket-enclosed, comma-separated list following
|
||||
the function name.
|
||||
|
||||
~~~~ {.xfail-test}
|
||||
fn iter<T>(seq: &[T], f: fn(T)) {
|
||||
fn iter<T>(seq: &[T], f: &fn(T)) {
|
||||
for seq.each |elt| { f(elt); }
|
||||
}
|
||||
fn map<T, U>(seq: &[T], f: fn(T) -> U) -> ~[U] {
|
||||
fn map<T, U>(seq: &[T], f: &fn(T) -> U) -> ~[U] {
|
||||
let mut acc = ~[];
|
||||
for seq.each |elt| { acc.push(f(elt)); }
|
||||
acc
|
||||
@ -1198,7 +1198,7 @@ These appear after the trait name, using the same syntax used in [generic functi
|
||||
trait Seq<T> {
|
||||
fn len() -> uint;
|
||||
fn elt_at(n: uint) -> T;
|
||||
fn iter(fn(T));
|
||||
fn iter(&fn(T));
|
||||
}
|
||||
~~~~
|
||||
|
||||
@ -2074,7 +2074,7 @@ and moving values from the environment into the lambda expression's captured env
|
||||
An example of a lambda expression:
|
||||
|
||||
~~~~
|
||||
fn ten_times(f: fn(int)) {
|
||||
fn ten_times(f: &fn(int)) {
|
||||
let mut i = 0;
|
||||
while i < 10 {
|
||||
f(i);
|
||||
@ -2177,7 +2177,7 @@ If the `expr` is a [field expression](#field-expressions), it is parsed as thoug
|
||||
In this example, both calls to `f` are equivalent:
|
||||
|
||||
~~~~
|
||||
# fn f(f: fn(int)) { }
|
||||
# fn f(f: &fn(int)) { }
|
||||
# fn g(i: int) { }
|
||||
|
||||
f(|j| g(j));
|
||||
@ -2755,7 +2755,7 @@ and the cast expression in `main`.
|
||||
Within the body of an item that has type parameter declarations, the names of its type parameters are types:
|
||||
|
||||
~~~~~~~
|
||||
fn map<A: Copy, B: Copy>(f: fn(A) -> B, xs: &[A]) -> ~[B] {
|
||||
fn map<A: Copy, B: Copy>(f: &fn(A) -> B, xs: &[A]) -> ~[B] {
|
||||
if xs.len() == 0 { return ~[]; }
|
||||
let first: B = f(xs[0]);
|
||||
let rest: ~[B] = map(f, xs.slice(1, xs.len()));
|
||||
|
@ -1361,7 +1361,7 @@ the enclosing scope.
|
||||
|
||||
~~~~
|
||||
# use println = core::io::println;
|
||||
fn call_closure_with_ten(b: fn(int)) { b(10); }
|
||||
fn call_closure_with_ten(b: &fn(int)) { b(10); }
|
||||
|
||||
let captured_var = 20;
|
||||
let closure = |arg| println(fmt!("captured_var=%d, arg=%d", captured_var, arg));
|
||||
@ -1447,7 +1447,7 @@ should almost always declare the type of that argument as `fn()`. That way,
|
||||
callers may pass any kind of closure.
|
||||
|
||||
~~~~
|
||||
fn call_twice(f: fn()) { f(); f(); }
|
||||
fn call_twice(f: &fn()) { f(); f(); }
|
||||
let closure = || { "I'm a closure, and it doesn't matter what type I am"; };
|
||||
fn function() { "I'm a normal function"; }
|
||||
call_twice(closure);
|
||||
@ -1467,7 +1467,7 @@ Consider this function that iterates over a vector of
|
||||
integers, passing in a pointer to each integer in the vector:
|
||||
|
||||
~~~~
|
||||
fn each(v: &[int], op: fn(v: &int)) {
|
||||
fn each(v: &[int], op: &fn(v: &int)) {
|
||||
let mut n = 0;
|
||||
while n < v.len() {
|
||||
op(&v[n]);
|
||||
@ -1488,7 +1488,7 @@ argument, we can write it in a way that has a pleasant, block-like
|
||||
structure.
|
||||
|
||||
~~~~
|
||||
# fn each(v: &[int], op: fn(v: &int)) { }
|
||||
# fn each(v: &[int], op: &fn(v: &int)) { }
|
||||
# fn do_some_work(i: &int) { }
|
||||
each([1, 2, 3], |n| {
|
||||
do_some_work(n);
|
||||
@ -1499,7 +1499,7 @@ This is such a useful pattern that Rust has a special form of function
|
||||
call that can be written more like a built-in control structure:
|
||||
|
||||
~~~~
|
||||
# fn each(v: &[int], op: fn(v: &int)) { }
|
||||
# fn each(v: &[int], op: &fn(v: &int)) { }
|
||||
# fn do_some_work(i: &int) { }
|
||||
do each([1, 2, 3]) |n| {
|
||||
do_some_work(n);
|
||||
@ -1546,7 +1546,7 @@ Consider again our `each` function, this time improved to
|
||||
break early when the iteratee returns `false`:
|
||||
|
||||
~~~~
|
||||
fn each(v: &[int], op: fn(v: &int) -> bool) {
|
||||
fn each(v: &[int], op: &fn(v: &int) -> bool) {
|
||||
let mut n = 0;
|
||||
while n < v.len() {
|
||||
if !op(&v[n]) {
|
||||
@ -1770,7 +1770,7 @@ vector consisting of the result of applying `function` to each element
|
||||
of `vector`:
|
||||
|
||||
~~~~
|
||||
fn map<T, U>(vector: &[T], function: fn(v: &T) -> U) -> ~[U] {
|
||||
fn map<T, U>(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] {
|
||||
let mut accumulator = ~[];
|
||||
for vec::each(vector) |element| {
|
||||
accumulator.push(function(element));
|
||||
@ -1969,12 +1969,12 @@ types might look like the following:
|
||||
~~~~
|
||||
trait Seq<T> {
|
||||
fn len(&self) -> uint;
|
||||
fn iter(&self, b: fn(v: &T));
|
||||
fn iter(&self, b: &fn(v: &T));
|
||||
}
|
||||
|
||||
impl<T> Seq<T> for ~[T] {
|
||||
fn len(&self) -> uint { vec::len(*self) }
|
||||
fn iter(&self, b: fn(v: &T)) {
|
||||
fn iter(&self, b: &fn(v: &T)) {
|
||||
for vec::each(*self) |elt| { b(elt); }
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ Implicitly, all crates behave as if they included the following prologue:
|
||||
#[deny(non_camel_case_types)];
|
||||
#[allow(deprecated_mutable_fields)];
|
||||
#[deny(deprecated_self)];
|
||||
#[allow(deprecated_drop)];
|
||||
|
||||
// On Linux, link to the runtime with -lrt.
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -77,6 +77,7 @@ pub enum lint {
|
||||
default_methods,
|
||||
deprecated_self,
|
||||
deprecated_mutable_fields,
|
||||
deprecated_drop,
|
||||
|
||||
managed_heap_memory,
|
||||
owned_heap_memory,
|
||||
@ -251,6 +252,13 @@ pub fn get_lint_dict() -> LintDict {
|
||||
default: deny
|
||||
}),
|
||||
|
||||
(@~"deprecated_drop",
|
||||
@LintSpec {
|
||||
lint: deprecated_drop,
|
||||
desc: "deprecated \"drop\" notation for the destructor",
|
||||
default: deny
|
||||
}),
|
||||
|
||||
/* FIXME(#3266)--make liveness warnings lintable
|
||||
(@~"unused_variable",
|
||||
@LintSpec {
|
||||
@ -483,6 +491,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
|
||||
check_item_default_methods(cx, i);
|
||||
check_item_deprecated_self(cx, i);
|
||||
check_item_deprecated_mutable_fields(cx, i);
|
||||
check_item_deprecated_drop(cx, i);
|
||||
}
|
||||
|
||||
// Take a visitor, and modify it so that it will not proceed past subitems.
|
||||
@ -720,6 +729,26 @@ fn check_item_deprecated_mutable_fields(cx: ty::ctxt, item: @ast::item) {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item_deprecated_drop(cx: ty::ctxt, item: @ast::item) {
|
||||
match item.node {
|
||||
ast::item_struct(struct_def, _) => {
|
||||
match struct_def.dtor {
|
||||
None => {}
|
||||
Some(ref dtor) => {
|
||||
cx.sess.span_lint(deprecated_drop,
|
||||
item.id,
|
||||
item.id,
|
||||
dtor.span,
|
||||
~"`drop` notation for destructors is \
|
||||
deprecated; implement the `Drop` \
|
||||
trait instead");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
|
||||
|
||||
fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id,
|
||||
|
@ -612,36 +612,11 @@ pub fn print_item(s: @ps, &&item: @ast::item) {
|
||||
pub fn print_enum_def(s: @ps, enum_definition: ast::enum_def,
|
||||
generics: &ast::Generics, ident: ast::ident,
|
||||
span: codemap::span, visibility: ast::visibility) {
|
||||
let mut newtype =
|
||||
vec::len(enum_definition.variants) == 1u &&
|
||||
ident == enum_definition.variants[0].node.name;
|
||||
if newtype {
|
||||
match enum_definition.variants[0].node.kind {
|
||||
ast::tuple_variant_kind(ref args) if args.len() == 1 => {}
|
||||
_ => newtype = false
|
||||
}
|
||||
}
|
||||
if newtype {
|
||||
ibox(s, indent_unit);
|
||||
word_space(s, visibility_qualified(visibility, ~"enum"));
|
||||
} else {
|
||||
head(s, visibility_qualified(visibility, ~"enum"));
|
||||
}
|
||||
|
||||
head(s, visibility_qualified(visibility, ~"enum"));
|
||||
print_ident(s, ident);
|
||||
print_generics(s, generics);
|
||||
space(s.s);
|
||||
if newtype {
|
||||
word_space(s, ~"=");
|
||||
match /*bad*/ copy enum_definition.variants[0].node.kind {
|
||||
ast::tuple_variant_kind(args) => print_type(s, args[0].ty),
|
||||
_ => fail!(~"newtype syntax with struct?")
|
||||
}
|
||||
word(s.s, ~";");
|
||||
end(s);
|
||||
} else {
|
||||
print_variants(s, enum_definition.variants, span);
|
||||
}
|
||||
print_variants(s, enum_definition.variants, span);
|
||||
}
|
||||
|
||||
pub fn print_variants(s: @ps,
|
||||
|
@ -1,3 +1,5 @@
|
||||
// xfail-test
|
||||
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
|
@ -1,3 +1,5 @@
|
||||
// xfail-test
|
||||
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
|
@ -1,13 +0,0 @@
|
||||
trait X {}
|
||||
|
||||
impl<A:Copy> X for A {}
|
||||
|
||||
struct S {
|
||||
x: int,
|
||||
drop {}
|
||||
}
|
||||
|
||||
impl X for S {}
|
||||
|
||||
pub fn main(){}
|
||||
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
struct S {
|
||||
x: int
|
||||
}
|
||||
|
||||
pub impl S {
|
||||
pure fn add(&self, other: &S) -> S {
|
||||
S { x: self.x + other.x }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let mut s = S { x: 1 };
|
||||
s += S { x: 2 };
|
||||
fail_unless!(s.x == 3);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user