about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-03-08 16:21:58 -0800
committerPatrick Walton <pcwalton@mimiga.net>2013-03-11 09:36:00 -0700
commit08c840205ea477d4f76216abac45be6a4ce9fa4b (patch)
tree7c5b611ac00f1054d51fd657d7fb7d143291fce2
parent7353568cd8d079fd4d9f928bc49a228276e86d19 (diff)
downloadrust-08c840205ea477d4f76216abac45be6a4ce9fa4b.tar.gz
rust-08c840205ea477d4f76216abac45be6a4ce9fa4b.zip
librustc: Lint the old `drop` destructor notation off
-rw-r--r--doc/rust.md12
-rw-r--r--doc/tutorial.md18
-rw-r--r--src/libcore/core.rc1
-rw-r--r--src/librustc/middle/lint.rs29
-rw-r--r--src/libsyntax/print/pprust.rs29
-rw-r--r--src/test/compile-fail/issue-2063.rs2
-rw-r--r--src/test/compile-fail/issue-2718-a.rs2
-rw-r--r--src/test/run-pass/coherence-copy-bound.rs13
-rw-r--r--src/test/run-pass/operator-overloading-explicit-self.rs26
9 files changed, 51 insertions, 81 deletions
diff --git a/doc/rust.md b/doc/rust.md
index 8924ee6f4f6..e559af62e36 100644
--- a/doc/rust.md
+++ b/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()));
diff --git a/doc/tutorial.md b/doc/tutorial.md
index 23ab1ce4400..e4775e1b11b 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -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); }
     }
 }
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 4d686c8ab33..db1dc1e28aa 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -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")]
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 5ff731a27f0..93f0557028e 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -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,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index e7e2435587e..49899fdeec4 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -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,
diff --git a/src/test/compile-fail/issue-2063.rs b/src/test/compile-fail/issue-2063.rs
index 2f174671bd9..0ebf0218efe 100644
--- a/src/test/compile-fail/issue-2063.rs
+++ b/src/test/compile-fail/issue-2063.rs
@@ -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.
diff --git a/src/test/compile-fail/issue-2718-a.rs b/src/test/compile-fail/issue-2718-a.rs
index 318982c3b13..8afaf8995c2 100644
--- a/src/test/compile-fail/issue-2718-a.rs
+++ b/src/test/compile-fail/issue-2718-a.rs
@@ -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.
diff --git a/src/test/run-pass/coherence-copy-bound.rs b/src/test/run-pass/coherence-copy-bound.rs
deleted file mode 100644
index 9921389da66..00000000000
--- a/src/test/run-pass/coherence-copy-bound.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-trait X {}
-
-impl<A:Copy> X for A {}
-
-struct S {
-    x: int,
-    drop {}
-}
-
-impl X for S {}
-
-pub fn main(){}
-
diff --git a/src/test/run-pass/operator-overloading-explicit-self.rs b/src/test/run-pass/operator-overloading-explicit-self.rs
deleted file mode 100644
index 3d2fd649f15..00000000000
--- a/src/test/run-pass/operator-overloading-explicit-self.rs
+++ /dev/null
@@ -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);
-}
-