about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/condition.rs1
-rw-r--r--src/libcore/io.rs14
-rw-r--r--src/libcore/managed.rs36
-rw-r--r--src/libcore/option.rs1
-rw-r--r--src/libcore/pipes.rs16
-rw-r--r--src/libcore/unstable.rs1
-rw-r--r--src/libcore/unstable/finally.rs1
-rw-r--r--src/librustc/middle/kind.rs99
-rw-r--r--src/librustc/middle/trans/base.rs9
-rw-r--r--src/libstd/arena.rs1
-rw-r--r--src/libstd/c_vec.rs9
-rw-r--r--src/libstd/future.rs1
-rw-r--r--src/libstd/net_tcp.rs1
-rw-r--r--src/libstd/sort.rs1
-rw-r--r--src/libstd/sync.rs12
-rw-r--r--src/libstd/task_pool.rs1
-rw-r--r--src/libsyntax/parse/obsolete.rs5
-rw-r--r--src/libsyntax/parse/parser.rs10
-rw-r--r--src/test/auxiliary/issue-2526.rs1
-rw-r--r--src/test/bench/task-perf-alloc-unwind.rs1
-rw-r--r--src/test/compile-fail/borrowck-assign-to-subfield.rs3
-rw-r--r--src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs5
-rw-r--r--src/test/compile-fail/borrowck-pat-enum-in-box.rs37
-rw-r--r--src/test/compile-fail/borrowck-uniq-via-box.rs12
-rw-r--r--src/test/compile-fail/coerce-bad-variance.rs17
-rw-r--r--src/test/compile-fail/fn-variance-1.rs3
-rw-r--r--src/test/compile-fail/fn-variance-2.rs3
-rw-r--r--src/test/compile-fail/issue-2548.rs7
-rw-r--r--src/test/compile-fail/kindck-destructor-owned.rs12
-rw-r--r--src/test/compile-fail/mutable-huh-box-assign.rs19
-rw-r--r--src/test/compile-fail/no-send-res-ports.rs1
-rw-r--r--src/test/compile-fail/pinned-deep-copy.rs5
-rw-r--r--src/test/compile-fail/tps-invariant-class.rs33
-rw-r--r--src/test/compile-fail/tps-invariant-enum.rs30
-rw-r--r--src/test/compile-fail/tps-invariant-trait.rs41
-rw-r--r--src/test/compile-fail/trait-impl-method-mismatch.rs10
-rw-r--r--src/test/compile-fail/trait-impl-subtype.rs31
-rw-r--r--src/test/compile-fail/unique-vec-res.rs5
-rw-r--r--src/test/run-fail/unwind-resource-fail3.rs1
-rw-r--r--src/test/run-pass/drop-trait-generic.rs1
-rw-r--r--src/test/run-pass/init-res-into-things.rs5
-rw-r--r--src/test/run-pass/issue-2718.rs2
-rw-r--r--src/test/run-pass/issue-2735-2.rs5
-rw-r--r--src/test/run-pass/issue-2735-3.rs5
-rw-r--r--src/test/run-pass/issue-979.rs5
-rw-r--r--src/test/run-pass/option-unwrap.rs5
-rw-r--r--src/test/run-pass/resource-assign-is-not-copy.rs5
-rw-r--r--src/test/run-pass/resource-destruct.rs5
-rw-r--r--src/test/run-pass/resource-generic.rs5
-rw-r--r--src/test/run-pass/resource-in-struct.rs5
-rw-r--r--src/test/run-pass/task-killjoin-rsrc.rs17
-rw-r--r--src/test/run-pass/unique-pinned-nocopy-2.rs5
-rw-r--r--src/test/run-pass/unwind-resource2.rs1
-rw-r--r--src/test/run-pass/vec-slice-drop.rs5
54 files changed, 277 insertions, 295 deletions
diff --git a/src/libcore/condition.rs b/src/libcore/condition.rs
index 56b690ca8af..66e9b970fa7 100644
--- a/src/libcore/condition.rs
+++ b/src/libcore/condition.rs
@@ -84,6 +84,7 @@ struct Guard<T, U> {
     cond: &'self Condition/&self<T, U>
 }
 
+#[unsafe_destructor]
 impl<T, U> Drop for Guard/&self<T, U> {
     fn finalize(&self) {
         unsafe {
diff --git a/src/libcore/io.rs b/src/libcore/io.rs
index 7fd61c48207..e77dc0bbc78 100644
--- a/src/libcore/io.rs
+++ b/src/libcore/io.rs
@@ -1230,15 +1230,17 @@ pub mod fsync {
         arg: Arg<t>,
     }
 
+    #[unsafe_destructor]
     impl<T:Copy> Drop for Res<T> {
         fn finalize(&self) {
-          match self.arg.opt_level {
-            None => (),
-            Some(level) => {
-              // fail hard if not succesful
-              fail_unless!(((self.arg.fsync_fn)(self.arg.val, level) != -1));
+            match self.arg.opt_level {
+                None => (),
+                Some(level) => {
+                  // fail hard if not succesful
+                  fail_unless!(((self.arg.fsync_fn)(self.arg.val, level)
+                    != -1));
+                }
             }
-          }
         }
     }
 
diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs
index 1bef895ea0b..b177dced888 100644
--- a/src/libcore/managed.rs
+++ b/src/libcore/managed.rs
@@ -49,23 +49,43 @@ pub pure fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool {
 }
 
 #[cfg(notest)]
-impl<T:Eq> Eq for @const T {
+impl<T:Eq> Eq for @T {
     #[inline(always)]
-    pure fn eq(&self, other: &@const T) -> bool { *(*self) == *(*other) }
+    pure fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) }
     #[inline(always)]
-    pure fn ne(&self, other: &@const T) -> bool { *(*self) != *(*other) }
+    pure fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) }
 }
 
 #[cfg(notest)]
-impl<T:Ord> Ord for @const T {
+impl<T:Eq> Eq for @mut T {
     #[inline(always)]
-    pure fn lt(&self, other: &@const T) -> bool { *(*self) < *(*other) }
+    pure fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) }
     #[inline(always)]
-    pure fn le(&self, other: &@const T) -> bool { *(*self) <= *(*other) }
+    pure fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) }
+}
+
+#[cfg(notest)]
+impl<T:Ord> Ord for @T {
+    #[inline(always)]
+    pure fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) }
+    #[inline(always)]
+    pure fn le(&self, other: &@T) -> bool { *(*self) <= *(*other) }
+    #[inline(always)]
+    pure fn ge(&self, other: &@T) -> bool { *(*self) >= *(*other) }
+    #[inline(always)]
+    pure fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) }
+}
+
+#[cfg(notest)]
+impl<T:Ord> Ord for @mut T {
+    #[inline(always)]
+    pure fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) }
+    #[inline(always)]
+    pure fn le(&self, other: &@mut T) -> bool { *(*self) <= *(*other) }
     #[inline(always)]
-    pure fn ge(&self, other: &@const T) -> bool { *(*self) >= *(*other) }
+    pure fn ge(&self, other: &@mut T) -> bool { *(*self) >= *(*other) }
     #[inline(always)]
-    pure fn gt(&self, other: &@const T) -> bool { *(*self) > *(*other) }
+    pure fn gt(&self, other: &@mut T) -> bool { *(*self) > *(*other) }
 }
 
 #[test]
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 5e5396ea121..8103166909c 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -514,6 +514,7 @@ fn test_unwrap_resource() {
        i: @mut int,
     }
 
+    #[unsafe_destructor]
     impl ::ops::Drop for R {
        fn finalize(&self) { *(self.i) += 1; }
     }
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs
index eb385d90354..a5d1cfa2793 100644
--- a/src/libcore/pipes.rs
+++ b/src/libcore/pipes.rs
@@ -350,6 +350,7 @@ struct BufferResource<T> {
 
 }
 
+#[unsafe_destructor]
 impl<T> ::ops::Drop for BufferResource<T> {
     fn finalize(&self) {
         unsafe {
@@ -445,16 +446,17 @@ pub fn try_recv<T:Owned,Tbuffer:Owned>(p: RecvPacketBuffered<T, Tbuffer>)
     let p_ = p.unwrap();
     let p = unsafe { &*p_ };
 
+    #[unsafe_destructor]
     struct DropState {
         p: &'self PacketHeader,
 
         drop {
-            if task::failing() {
-                self.p.state = Terminated;
-                let old_task = swap_task(&mut self.p.blocked_task,
-                                         ptr::null());
-                if !old_task.is_null() {
-                    unsafe {
+            unsafe {
+                if task::failing() {
+                    self.p.state = Terminated;
+                    let old_task = swap_task(&mut self.p.blocked_task,
+                                             ptr::null());
+                    if !old_task.is_null() {
                         rustrt::rust_task_deref(old_task);
                     }
                 }
@@ -773,6 +775,7 @@ pub struct SendPacketBuffered<T, Tbuffer> {
     mut buffer: Option<BufferResource<Tbuffer>>,
 }
 
+#[unsafe_destructor]
 impl<T:Owned,Tbuffer:Owned> ::ops::Drop for SendPacketBuffered<T,Tbuffer> {
     fn finalize(&self) {
         //if self.p != none {
@@ -842,6 +845,7 @@ pub struct RecvPacketBuffered<T, Tbuffer> {
     mut buffer: Option<BufferResource<Tbuffer>>,
 }
 
+#[unsafe_destructor]
 impl<T:Owned,Tbuffer:Owned> ::ops::Drop for RecvPacketBuffered<T,Tbuffer> {
     fn finalize(&self) {
         //if self.p != none {
diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs
index 899d01cd996..0ef736d5198 100644
--- a/src/libcore/unstable.rs
+++ b/src/libcore/unstable.rs
@@ -118,6 +118,7 @@ struct ArcDestruct<T> {
     mut data: *libc::c_void,
 }
 
+#[unsafe_destructor]
 impl<T> Drop for ArcDestruct<T>{
     fn finalize(&self) {
         unsafe {
diff --git a/src/libcore/unstable/finally.rs b/src/libcore/unstable/finally.rs
index e8c27ff7d92..c96889cebc8 100644
--- a/src/libcore/unstable/finally.rs
+++ b/src/libcore/unstable/finally.rs
@@ -45,6 +45,7 @@ struct Finallyalizer {
     dtor: &'self fn()
 }
 
+#[unsafe_destructor]
 impl Drop for Finallyalizer/&self {
     fn finalize(&self) {
         (self.dtor)();
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 4b1b0d0200f..0564e244437 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -22,6 +22,7 @@ use core::str;
 use core::vec;
 use std::oldmap::HashMap;
 use syntax::ast::*;
+use syntax::attr::attrs_contains_name;
 use syntax::codemap::{span, spanned};
 use syntax::print::pprust::expr_to_str;
 use syntax::{visit, ast_util};
@@ -55,6 +56,8 @@ use syntax::{visit, ast_util};
 // primitives in the stdlib are explicitly annotated to only take sendable
 // types.
 
+use core::hashmap::linear::LinearSet;
+
 pub const try_adding: &'static str = "Try adding a move";
 
 pub type rval_map = HashMap<node_id, ()>;
@@ -63,7 +66,7 @@ pub struct Context {
     tcx: ty::ctxt,
     method_map: typeck::method_map,
     last_use_map: liveness::last_use_map,
-    current_item: node_id
+    current_item: node_id,
 }
 
 pub fn check_crate(tcx: ty::ctxt,
@@ -74,16 +77,15 @@ pub fn check_crate(tcx: ty::ctxt,
         tcx: tcx,
         method_map: method_map,
         last_use_map: last_use_map,
-        current_item: -1
+        current_item: -1,
     };
     let visit = visit::mk_vt(@visit::Visitor {
         visit_arm: check_arm,
         visit_expr: check_expr,
         visit_fn: check_fn,
         visit_ty: check_ty,
-        visit_item: |i, cx, v| {
-            visit::visit_item(i, Context { current_item: i.id,.. cx }, v);
-        },
+        visit_item: check_item,
+        visit_block: check_block,
         .. *visit::default_visitor()
     });
     visit::visit_crate(*crate, ctx, visit);
@@ -92,6 +94,93 @@ pub fn check_crate(tcx: ty::ctxt,
 
 type check_fn = @fn(Context, @freevar_entry);
 
+fn check_struct_safe_for_destructor(cx: Context,
+                                    span: span,
+                                    struct_did: def_id) {
+    let struct_tpt = ty::lookup_item_type(cx.tcx, struct_did);
+    if struct_tpt.bounds.len() == 0 {
+        let struct_ty = ty::mk_struct(cx.tcx, struct_did, ty::substs {
+            self_r: None,
+            self_ty: None,
+            tps: ~[]
+        });
+        if !ty::type_is_owned(cx.tcx, struct_ty) {
+            cx.tcx.sess.span_err(span,
+                                 ~"cannot implement a destructor on a struct \
+                                   that is not Owned");
+            cx.tcx.sess.span_note(span,
+                                  ~"use \"#[unsafe_destructor]\" on the \
+                                    implementation to force the compiler to \
+                                    allow this");
+        }
+    } else {
+        cx.tcx.sess.span_err(span,
+                             ~"cannot implement a destructor on a struct \
+                               with type parameters");
+        cx.tcx.sess.span_note(span,
+                              ~"use \"#[unsafe_destructor]\" on the \
+                                implementation to force the compiler to \
+                                allow this");
+    }
+}
+
+fn check_block(block: &blk, cx: Context, visitor: visit::vt<Context>) {
+    visit::visit_block(block, cx, visitor);
+}
+
+fn check_item(item: @item, cx: Context, visitor: visit::vt<Context>) {
+    // If this is a destructor, check kinds.
+    if !attrs_contains_name(item.attrs, "unsafe_destructor") {
+        match item.node {
+            item_impl(_, Some(trait_ref), self_type, _) => {
+                match cx.tcx.def_map.find(&trait_ref.ref_id) {
+                    None => cx.tcx.sess.bug(~"trait ref not in def map!"),
+                    Some(trait_def) => {
+                        let trait_def_id = ast_util::def_id_of_def(trait_def);
+                        if cx.tcx.lang_items.drop_trait() == trait_def_id {
+                            // Yes, it's a destructor.
+                            match self_type.node {
+                                ty_path(_, path_node_id) => {
+                                    let struct_def = cx.tcx.def_map.get(
+                                        &path_node_id);
+                                    let struct_did =
+                                        ast_util::def_id_of_def(struct_def);
+                                    check_struct_safe_for_destructor(
+                                        cx,
+                                        self_type.span,
+                                        struct_did);
+                                }
+                                _ => {
+                                    cx.tcx.sess.span_bug(self_type.span,
+                                                         ~"the self type for \
+                                                           the Drop trait \
+                                                           impl is not a \
+                                                           path");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            item_struct(struct_def, _) => {
+                match struct_def.dtor {
+                    None => {}
+                    Some(ref dtor) => {
+                        let struct_did = def_id { crate: 0, node: item.id };
+                        check_struct_safe_for_destructor(cx,
+                                                         dtor.span,
+                                                         struct_did);
+                    }
+                }
+            }
+            _ => {}
+        }
+    }
+
+    let cx = Context { current_item: item.id, ..cx };
+    visit::visit_item(item, cx, visitor);
+}
+
 // Yields the appropriate function to check the kind of closed over
 // variables. `id` is the node_id for some expression that creates the
 // closure.
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 9346872f949..62fff583766 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -88,11 +88,14 @@ pub struct icx_popper {
     ccx: @CrateContext,
 }
 
+#[unsafe_destructor]
 impl Drop for icx_popper {
     fn finalize(&self) {
-      if self.ccx.sess.count_llvm_insns() {
-          self.ccx.stats.llvm_insn_ctxt.pop();
-      }
+        unsafe {
+            if self.ccx.sess.count_llvm_insns() {
+                self.ccx.stats.llvm_insn_ctxt.pop();
+            }
+        }
     }
 }
 
diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs
index 68132a1c08d..911abf95ff8 100644
--- a/src/libstd/arena.rs
+++ b/src/libstd/arena.rs
@@ -88,6 +88,7 @@ pub struct Arena {
     priv mut chunks: @List<Chunk>,
 }
 
+#[unsafe_destructor]
 impl Drop for Arena {
     fn finalize(&self) {
         unsafe {
diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs
index 8e75f694fa3..d9595656f05 100644
--- a/src/libstd/c_vec.rs
+++ b/src/libstd/c_vec.rs
@@ -54,11 +54,14 @@ struct DtorRes {
   dtor: Option<@fn()>,
 }
 
+#[unsafe_destructor]
 impl Drop for DtorRes {
     fn finalize(&self) {
-        match self.dtor {
-          option::None => (),
-          option::Some(f) => f()
+        unsafe {
+            match self.dtor {
+                option::None => (),
+                option::Some(f) => f()
+            }
         }
     }
 }
diff --git a/src/libstd/future.rs b/src/libstd/future.rs
index 4867204ea39..fc60932b67a 100644
--- a/src/libstd/future.rs
+++ b/src/libstd/future.rs
@@ -35,6 +35,7 @@ pub struct Future<A> {
 
 // FIXME(#2829) -- futures should not be copyable, because they close
 // over ~fn's that have pipes and so forth within!
+#[unsafe_destructor]
 impl<A> Drop for Future<A> {
     fn finalize(&self) {}
 }
diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs
index a93e94e0d04..c49f65d0f99 100644
--- a/src/libstd/net_tcp.rs
+++ b/src/libstd/net_tcp.rs
@@ -55,6 +55,7 @@ pub struct TcpSocket {
   socket_data: @TcpSocketData,
 }
 
+#[unsafe_destructor]
 impl Drop for TcpSocket {
     fn finalize(&self) {
         unsafe {
diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs
index 40be303a147..db8311ca035 100644
--- a/src/libstd/sort.rs
+++ b/src/libstd/sort.rs
@@ -1190,6 +1190,7 @@ mod big_tests {
         key: &'self fn(@uint),
     }
 
+    #[unsafe_destructor]
     impl Drop for LVal/&self {
         fn finalize(&self) {
             let x = unsafe { task::local_data::local_data_get(self.key) };
diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs
index d47232cc535..00de601da6f 100644
--- a/src/libstd/sync.rs
+++ b/src/libstd/sync.rs
@@ -167,9 +167,12 @@ type SemRelease = SemReleaseGeneric<'self, ()>;
 type SemAndSignalRelease = SemReleaseGeneric<'self, ~[Waitqueue]>;
 struct SemReleaseGeneric<Q> { sem: &'self Sem<Q> }
 
+#[unsafe_destructor]
 impl<Q:Owned> Drop for SemReleaseGeneric/&self<Q> {
     fn finalize(&self) {
-        self.sem.release();
+        unsafe {
+            self.sem.release();
+        }
     }
 }
 
@@ -189,6 +192,7 @@ fn SemAndSignalRelease(sem: &'r Sem<~[Waitqueue]>)
 /// A mechanism for atomic-unlock-and-deschedule blocking and signalling.
 pub struct Condvar { priv sem: &'self Sem<~[Waitqueue]> }
 
+#[unsafe_destructor]
 impl Drop for Condvar/&self { fn finalize(&self) {} }
 
 pub impl Condvar/&self {
@@ -261,6 +265,7 @@ pub impl Condvar/&self {
             sem: &'self Sem<~[Waitqueue]>,
         }
 
+        #[unsafe_destructor]
         impl Drop for SemAndSignalReacquire/&self {
             fn finalize(&self) {
                 unsafe {
@@ -613,6 +618,7 @@ struct RWlockReleaseRead {
     lock: &'self RWlock,
 }
 
+#[unsafe_destructor]
 impl Drop for RWlockReleaseRead/&self {
     fn finalize(&self) {
         unsafe {
@@ -643,10 +649,12 @@ fn RWlockReleaseRead(lock: &'r RWlock) -> RWlockReleaseRead/&r {
 
 // FIXME(#3588) should go inside of downgrade()
 #[doc(hidden)]
+#[unsafe_destructor]
 struct RWlockReleaseDowngrade {
     lock: &'self RWlock,
 }
 
+#[unsafe_destructor]
 impl Drop for RWlockReleaseDowngrade/&self {
     fn finalize(&self) {
         unsafe {
@@ -685,10 +693,12 @@ fn RWlockReleaseDowngrade(lock: &'r RWlock) -> RWlockReleaseDowngrade/&r {
 
 /// The "write permission" token used for rwlock.write_downgrade().
 pub struct RWlockWriteMode { priv lock: &'self RWlock }
+#[unsafe_destructor]
 impl Drop for RWlockWriteMode/&self { fn finalize(&self) {} }
 
 /// The "read permission" token used for rwlock.write_downgrade().
 pub struct RWlockReadMode  { priv lock: &'self RWlock }
+#[unsafe_destructor]
 impl Drop for RWlockReadMode/&self { fn finalize(&self) {} }
 
 pub impl RWlockWriteMode/&self {
diff --git a/src/libstd/task_pool.rs b/src/libstd/task_pool.rs
index 09cab72ab21..d8ca5559f42 100644
--- a/src/libstd/task_pool.rs
+++ b/src/libstd/task_pool.rs
@@ -28,6 +28,7 @@ pub struct TaskPool<T> {
 
 }
 
+#[unsafe_destructor]
 impl<T> Drop for TaskPool<T> {
     fn finalize(&self) {
         for self.channels.each |channel| {
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index f5e83a1beae..573f90af020 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -58,6 +58,7 @@ pub enum ObsoleteSyntax {
     ObsoleteMode,
     ObsoleteImplicitSelf,
     ObsoleteLifetimeNotation,
+    ObsoleteConstManagedPointer,
 }
 
 impl to_bytes::IterBytes for ObsoleteSyntax {
@@ -193,6 +194,10 @@ pub impl Parser {
                 "instead of `&foo/bar`, write `&'foo bar`; instead of \
                  `bar/&foo`, write `&bar<'foo>"
             ),
+            ObsoleteConstManagedPointer => (
+                "const `@` pointer",
+                "instead of `@const Foo`, write `@Foo`"
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index de861075a5b..95f8afd538a 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -79,7 +79,7 @@ use parse::obsolete::{ObsoleteRecordType, ObsoleteRecordPattern};
 use parse::obsolete::{ObsoleteAssertion, ObsoletePostFnTySigil};
 use parse::obsolete::{ObsoleteBareFnType, ObsoleteNewtypeEnum};
 use parse::obsolete::{ObsoleteMode, ObsoleteImplicitSelf};
-use parse::obsolete::{ObsoleteLifetimeNotation};
+use parse::obsolete::{ObsoleteLifetimeNotation, ObsoleteConstManagedPointer};
 use parse::prec::{as_prec, token_to_binop};
 use parse::token::{can_begin_expr, is_ident, is_ident_or_path};
 use parse::token::{is_plain_ident, INTERPOLATED, special_idents};
@@ -268,6 +268,7 @@ pub struct Parser {
 
 }
 
+#[unsafe_destructor]
 impl Drop for Parser {
     /* do not copy the parser; its state is tied to outside state */
     fn finalize(&self) {}
@@ -709,6 +710,9 @@ pub impl Parser {
         if mt.mutbl != m_imm && sigil == OwnedSigil {
             self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
         }
+        if mt.mutbl == m_const && sigil == ManagedSigil {
+            self.obsolete(*self.last_span, ObsoleteConstManagedPointer);
+        }
 
         ctor(mt)
     }
@@ -1635,6 +1639,10 @@ pub impl Parser {
           token::AT => {
             self.bump();
             let m = self.parse_mutability();
+            if m == m_const {
+                self.obsolete(*self.last_span, ObsoleteConstManagedPointer);
+            }
+
             let e = self.parse_prefix_expr();
             hi = e.span.hi;
             // HACK: turn @[...] into a @-evec
diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs
index c09e64eac8c..775955ff38c 100644
--- a/src/test/auxiliary/issue-2526.rs
+++ b/src/test/auxiliary/issue-2526.rs
@@ -19,6 +19,7 @@ struct arc_destruct<T> {
   _data: int,
 }
 
+#[unsafe_destructor]
 impl<T:Const> Drop for arc_destruct<T> {
     fn finalize(&self) {}
 }
diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs
index 4a372d016f9..c29ab9a769e 100644
--- a/src/test/bench/task-perf-alloc-unwind.rs
+++ b/src/test/bench/task-perf-alloc-unwind.rs
@@ -56,6 +56,7 @@ struct r {
   _l: @nillist,
 }
 
+#[unsafe_destructor]
 impl Drop for r {
     fn finalize(&self) {}
 }
diff --git a/src/test/compile-fail/borrowck-assign-to-subfield.rs b/src/test/compile-fail/borrowck-assign-to-subfield.rs
index 736e950cd82..610802ca68b 100644
--- a/src/test/compile-fail/borrowck-assign-to-subfield.rs
+++ b/src/test/compile-fail/borrowck-assign-to-subfield.rs
@@ -13,7 +13,6 @@ fn main() {
         a: int,
         w: B,
         x: @B,
-        y: @const B,
         z: @mut B
     }
     struct B {
@@ -23,7 +22,6 @@ fn main() {
         a: 1,
         w: B {a: 1},
         x: @B {a: 1},
-        y: @const B {a: 1},
         z: @mut B {a: 1}
     };
 
@@ -37,6 +35,5 @@ fn main() {
     // in these cases we pass through a box, so the mut
     // of the box is dominant
     p.x.a = 2;     //~ ERROR assigning to immutable field
-    p.y.a = 2;     //~ ERROR assigning to const field
     p.z.a = 2;
 }
diff --git a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs
index fd8190358c9..fe7b29cf9a8 100644
--- a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs
+++ b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs
@@ -12,9 +12,12 @@ struct defer {
     x: &'self [&'self str],
 }
 
+#[unsafe_destructor]
 impl Drop for defer<'self> {
     fn finalize(&self) {
-        error!("%?", self.x);
+        unsafe {
+            error!("%?", self.x);
+        }
     }
 }
 
diff --git a/src/test/compile-fail/borrowck-pat-enum-in-box.rs b/src/test/compile-fail/borrowck-pat-enum-in-box.rs
deleted file mode 100644
index bd1001bf38c..00000000000
--- a/src/test/compile-fail/borrowck-pat-enum-in-box.rs
+++ /dev/null
@@ -1,37 +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.
-
-fn match_imm_box(v: &const @Option<int>) -> int {
-    match *v {
-      @Some(ref i) => {*i}
-      @None => {0}
-    }
-}
-
-fn match_const_box(v: &const @const Option<int>) -> int {
-    match *v {
-      @Some(ref i) => { *i } // ok because this is pure
-      @None => {0}
-    }
-}
-
-fn process(_i: int) {}
-
-fn match_const_box_and_do_bad_things(v: &const @const Option<int>) {
-    match *v {
-      @Some(ref i) => { //~ ERROR illegal borrow unless pure
-        process(*i) //~ NOTE impure due to access to impure function
-      }
-      @None => {}
-    }
-}
-
-fn main() {
-}
diff --git a/src/test/compile-fail/borrowck-uniq-via-box.rs b/src/test/compile-fail/borrowck-uniq-via-box.rs
index 914b5caa011..e1c0e67ff8d 100644
--- a/src/test/compile-fail/borrowck-uniq-via-box.rs
+++ b/src/test/compile-fail/borrowck-uniq-via-box.rs
@@ -50,18 +50,6 @@ fn box_imm_recs(v: @Outer) {
     borrow(v.f.g.h); // OK
 }
 
-fn box_const(v: @const ~int) {
-    borrow(*v); //~ ERROR illegal borrow unless pure
-}
-
-fn box_const_rec(v: @const Rec) {
-    borrow(v.f); //~ ERROR illegal borrow unless pure
-}
-
-fn box_const_recs(v: @const Outer) {
-    borrow(v.f.g.h); //~ ERROR illegal borrow unless pure
-}
-
 fn main() {
 }
 
diff --git a/src/test/compile-fail/coerce-bad-variance.rs b/src/test/compile-fail/coerce-bad-variance.rs
deleted file mode 100644
index 6ce969c7eaf..00000000000
--- a/src/test/compile-fail/coerce-bad-variance.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-fn mutate(x: &mut @const int) {
-    *x = @3;
-}
-
-fn give_away1(y: @mut @mut int) {
-    mutate(y); //~ ERROR values differ in mutability
-}
-
-fn give_away2(y: @mut @const int) {
-    mutate(y);
-}
-
-fn give_away3(y: @mut @int) {
-    mutate(y); //~ ERROR values differ in mutability
-}
-
-fn main() {}
diff --git a/src/test/compile-fail/fn-variance-1.rs b/src/test/compile-fail/fn-variance-1.rs
index c5c29bd3ecf..6f3ccfd35ac 100644
--- a/src/test/compile-fail/fn-variance-1.rs
+++ b/src/test/compile-fail/fn-variance-1.rs
@@ -11,7 +11,6 @@
 #[legacy_modes];
 
 fn takes_mut(&&x: @mut int) { }
-fn takes_const(&&x: @const int) { }
 fn takes_imm(&&x: @int) { }
 
 fn apply<T>(t: T, f: &fn(T)) {
@@ -20,10 +19,8 @@ fn apply<T>(t: T, f: &fn(T)) {
 
 fn main() {
     apply(@3, takes_mut); //~ ERROR (values differ in mutability)
-    apply(@3, takes_const);
     apply(@3, takes_imm);
 
     apply(@mut 3, takes_mut);
-    apply(@mut 3, takes_const);
     apply(@mut 3, takes_imm); //~ ERROR (values differ in mutability)
 }
diff --git a/src/test/compile-fail/fn-variance-2.rs b/src/test/compile-fail/fn-variance-2.rs
index 2a30f9fb96f..61668cbdb9e 100644
--- a/src/test/compile-fail/fn-variance-2.rs
+++ b/src/test/compile-fail/fn-variance-2.rs
@@ -25,9 +25,6 @@ fn main() {
     // @mut int.
     let f: @mut int = r();
 
-    // OK.
-    let g: @const int = r();
-
     // Bad.
     let h: @int = r(); //~ ERROR (values differ in mutability)
 }
diff --git a/src/test/compile-fail/issue-2548.rs b/src/test/compile-fail/issue-2548.rs
index 83fdb86628b..f8f973dbc6b 100644
--- a/src/test/compile-fail/issue-2548.rs
+++ b/src/test/compile-fail/issue-2548.rs
@@ -16,10 +16,13 @@ struct foo {
 
 }
 
+#[unsafe_destructor]
 impl Drop for foo {
     fn finalize(&self) {
-        io::println("Goodbye, World!");
-        *self.x += 1;
+        unsafe {
+            io::println("Goodbye, World!");
+            *self.x += 1;
+        }
     }
 }
 
diff --git a/src/test/compile-fail/kindck-destructor-owned.rs b/src/test/compile-fail/kindck-destructor-owned.rs
new file mode 100644
index 00000000000..e956f95b422
--- /dev/null
+++ b/src/test/compile-fail/kindck-destructor-owned.rs
@@ -0,0 +1,12 @@
+struct Foo {
+    f: @mut int,
+}
+
+impl Drop for Foo { //~ ERROR cannot implement a destructor on a struct that is not Owned
+    fn finalize(&self) {
+        *self.f = 10;
+    }
+}
+
+fn main() { }
+
diff --git a/src/test/compile-fail/mutable-huh-box-assign.rs b/src/test/compile-fail/mutable-huh-box-assign.rs
deleted file mode 100644
index bb06cbb6d03..00000000000
--- a/src/test/compile-fail/mutable-huh-box-assign.rs
+++ /dev/null
@@ -1,19 +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.
-
-fn main() {
-    fn f(&&v: @const int) {
-        *v = 1 //~ ERROR assigning to dereference of const @ pointer
-    }
-
-    let v = @0;
-
-    f(v);
-}
diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs
index 192cde21bf1..c1071e5a8c4 100644
--- a/src/test/compile-fail/no-send-res-ports.rs
+++ b/src/test/compile-fail/no-send-res-ports.rs
@@ -17,6 +17,7 @@ fn main() {
       _x: Port<()>,
     }
 
+    #[unsafe_destructor]
     impl Drop for foo {
         fn finalize(&self) {}
     }
diff --git a/src/test/compile-fail/pinned-deep-copy.rs b/src/test/compile-fail/pinned-deep-copy.rs
index 5df65832099..17e23360a5b 100644
--- a/src/test/compile-fail/pinned-deep-copy.rs
+++ b/src/test/compile-fail/pinned-deep-copy.rs
@@ -12,9 +12,12 @@ struct r {
   i: @mut int,
 }
 
+#[unsafe_destructor]
 impl Drop for r {
     fn finalize(&self) {
-        *(self.i) = *(self.i) + 1;
+        unsafe {
+            *(self.i) = *(self.i) + 1;
+        }
     }
 }
 
diff --git a/src/test/compile-fail/tps-invariant-class.rs b/src/test/compile-fail/tps-invariant-class.rs
deleted file mode 100644
index 0411eeb05eb..00000000000
--- a/src/test/compile-fail/tps-invariant-class.rs
+++ /dev/null
@@ -1,33 +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 box_impl<T> {
-    f: T,
-}
-
-fn box_impl<T>(f: T) -> box_impl<T> {
-    box_impl {
-        f: f
-    }
-}
-
-fn set_box_impl<T>(b: box_impl<@const T>, v: @const T) {
-    b.f = v;
-}
-
-fn main() {
-    let b = box_impl::<@int>(@3);
-    set_box_impl(b, @mut 5);
-    //~^ ERROR values differ in mutability
-
-    // No error when type of parameter actually IS @const int
-    let b = box_impl::<@const int>(@3);
-    set_box_impl(b, @mut 5);
-}
diff --git a/src/test/compile-fail/tps-invariant-enum.rs b/src/test/compile-fail/tps-invariant-enum.rs
deleted file mode 100644
index 9e19ecdcb75..00000000000
--- a/src/test/compile-fail/tps-invariant-enum.rs
+++ /dev/null
@@ -1,30 +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 box<T> {
-    f: T
-}
-
-struct box_impl<T>(box<T>);
-
-fn set_box_impl<T>(b: box_impl<@const T>, v: @const T) {
-    b.f = v;
-}
-
-fn main() {
-    let b = box_impl::<@int>(box::<@int> {f: @3});
-    set_box_impl(b, @mut 5);
-    //~^ ERROR values differ in mutability
-
-    // No error when type of parameter actually IS @const int
-    let x: @const int = @3; // only way I could find to upcast
-    let b = box_impl::<@const int>(box::<@const int>{f: x});
-    set_box_impl(b, @mut 5);
-}
diff --git a/src/test/compile-fail/tps-invariant-trait.rs b/src/test/compile-fail/tps-invariant-trait.rs
deleted file mode 100644
index 127aa23d6ab..00000000000
--- a/src/test/compile-fail/tps-invariant-trait.rs
+++ /dev/null
@@ -1,41 +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.
-
-trait box_trait<T> {
-    fn get(&self) -> T;
-    fn set(&self, t: T);
-}
-
-struct box<T> {
-    f: T
-}
-
-struct box_impl<T>(box<T>);
-
-impl<T:Copy> box_trait<T> for box_impl<T> {
-    fn get(&self) -> T { return self.f; }
-    fn set(&self, t: T) { self.f = t; }
-}
-
-fn set_box_trait<T>(b: @box_trait<@const T>, v: @const T) {
-    b.set(v);
-}
-
-fn set_box_impl<T>(b: box_impl<@const T>, v: @const T) {
-    b.set(v);
-}
-
-fn main() {
-    let b = box_impl::<@int>(box::<@int> {f: @3});
-    set_box_trait(@b as @box_trait<@int>, @mut 5);
-    //~^ ERROR values differ in mutability
-    set_box_impl(b, @mut 5);
-    //~^ ERROR values differ in mutability
-}
diff --git a/src/test/compile-fail/trait-impl-method-mismatch.rs b/src/test/compile-fail/trait-impl-method-mismatch.rs
index 6676cde3c96..7f4c227d2d0 100644
--- a/src/test/compile-fail/trait-impl-method-mismatch.rs
+++ b/src/test/compile-fail/trait-impl-method-mismatch.rs
@@ -10,22 +10,12 @@
 
 trait Mumbo {
     fn jumbo(&self, x: @uint) -> uint;
-    fn jambo(&self, x: @const uint) -> uint;
-    fn jbmbo(&self) -> @uint;
 }
 
 impl Mumbo for uint {
     // Cannot have a larger effect than the trait:
     unsafe fn jumbo(&self, x: @uint) { *self + *x; }
     //~^ ERROR expected impure fn but found unsafe fn
-
-    // Cannot accept a narrower range of parameters:
-    fn jambo(&self, x: @uint) { *self + *x; }
-    //~^ ERROR values differ in mutability
-
-    // Cannot return a wider range of values:
-    fn jbmbo(&self) -> @const uint { @const 0 }
-    //~^ ERROR values differ in mutability
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/trait-impl-subtype.rs b/src/test/compile-fail/trait-impl-subtype.rs
deleted file mode 100644
index eb34ebbdfb0..00000000000
--- a/src/test/compile-fail/trait-impl-subtype.rs
+++ /dev/null
@@ -1,31 +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.
-
-trait Mumbo {
-    fn jumbo(&self, x: @uint) -> uint;
-}
-
-impl Mumbo for uint {
-    // Note: this method def is ok, it is more accepting and
-    // less effecting than the trait method:
-    pure fn jumbo(&self, x: @const uint) -> uint { *self + *x }
-}
-
-fn main() {
-    let a = 3u;
-    let b = a.jumbo(@mut 6);
-
-    let x = @a as @Mumbo;
-    let y = x.jumbo(@mut 6); //~ ERROR values differ in mutability
-    let z = x.jumbo(@6);
-}
-
-
-
diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs
index 3f4636328b6..a3c51e2b7b1 100644
--- a/src/test/compile-fail/unique-vec-res.rs
+++ b/src/test/compile-fail/unique-vec-res.rs
@@ -12,9 +12,12 @@ struct r {
   i: @mut int,
 }
 
+#[unsafe_destructor]
 impl Drop for r {
     fn finalize(&self) {
-        *(self.i) = *(self.i) + 1;
+        unsafe {
+            *(self.i) = *(self.i) + 1;
+        }
     }
 }
 
diff --git a/src/test/run-fail/unwind-resource-fail3.rs b/src/test/run-fail/unwind-resource-fail3.rs
index 27e0ebe7761..d3ba5737b71 100644
--- a/src/test/run-fail/unwind-resource-fail3.rs
+++ b/src/test/run-fail/unwind-resource-fail3.rs
@@ -17,6 +17,7 @@ struct faily_box {
  
 fn faily_box(i: @int) -> faily_box { faily_box { i: i } }
 
+#[unsafe_destructor]
 impl Drop for faily_box {
     fn finalize(&self) {
         fail!(~"quux");
diff --git a/src/test/run-pass/drop-trait-generic.rs b/src/test/run-pass/drop-trait-generic.rs
index 270137c2fd2..21b85084117 100644
--- a/src/test/run-pass/drop-trait-generic.rs
+++ b/src/test/run-pass/drop-trait-generic.rs
@@ -12,6 +12,7 @@ struct S<T> {
     x: T
 }
 
+#[unsafe_destructor]
 impl<T> ::core::ops::Drop for S<T> {
     fn finalize(&self) {
         io::println("bye");
diff --git a/src/test/run-pass/init-res-into-things.rs b/src/test/run-pass/init-res-into-things.rs
index 50b31361cee..5db8e34c7b5 100644
--- a/src/test/run-pass/init-res-into-things.rs
+++ b/src/test/run-pass/init-res-into-things.rs
@@ -17,9 +17,12 @@ struct r {
 
 struct Box { x: r }
 
+#[unsafe_destructor]
 impl Drop for r {
     fn finalize(&self) {
-        *(self.i) = *(self.i) + 1;
+        unsafe {
+            *(self.i) = *(self.i) + 1;
+        }
     }
 }
 
diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs
index ae927ff7918..c8c2d381a7e 100644
--- a/src/test/run-pass/issue-2718.rs
+++ b/src/test/run-pass/issue-2718.rs
@@ -155,6 +155,7 @@ pub mod pipes {
         p: Option<*packet<T>>,
     }
 
+    #[unsafe_destructor]
     impl<T:Owned> Drop for send_packet<T> {
         fn finalize(&self) {
             unsafe {
@@ -187,6 +188,7 @@ pub mod pipes {
         p: Option<*packet<T>>,
     }
 
+    #[unsafe_destructor]
     impl<T:Owned> Drop for recv_packet<T> {
         fn finalize(&self) {
             unsafe {
diff --git a/src/test/run-pass/issue-2735-2.rs b/src/test/run-pass/issue-2735-2.rs
index 4c8559f0552..52a5f193447 100644
--- a/src/test/run-pass/issue-2735-2.rs
+++ b/src/test/run-pass/issue-2735-2.rs
@@ -13,9 +13,12 @@ struct defer {
     b: &'self mut bool,
 }
 
+#[unsafe_destructor]
 impl Drop for defer/&self {
     fn finalize(&self) {
-        *(self.b) = true;
+        unsafe {
+            *(self.b) = true;
+        }
     }
 }
 
diff --git a/src/test/run-pass/issue-2735-3.rs b/src/test/run-pass/issue-2735-3.rs
index 9fa1d56406a..02e9f6f8b67 100644
--- a/src/test/run-pass/issue-2735-3.rs
+++ b/src/test/run-pass/issue-2735-3.rs
@@ -13,9 +13,12 @@ struct defer {
     b: &'self mut bool,
 }
 
+#[unsafe_destructor]
 impl Drop for defer/&self {
     fn finalize(&self) {
-        *(self.b) = true;
+        unsafe {
+            *(self.b) = true;
+        }
     }
 }
 
diff --git a/src/test/run-pass/issue-979.rs b/src/test/run-pass/issue-979.rs
index d46f62c6ae0..d5184efa4c3 100644
--- a/src/test/run-pass/issue-979.rs
+++ b/src/test/run-pass/issue-979.rs
@@ -12,9 +12,12 @@ struct r {
   b: @mut int,
 }
 
+#[unsafe_destructor]
 impl Drop for r {
     fn finalize(&self) {
-        *(self.b) += 1;
+        unsafe {
+            *(self.b) += 1;
+        }
     }
 }
 
diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/run-pass/option-unwrap.rs
index d2e5911111d..207428c2cec 100644
--- a/src/test/run-pass/option-unwrap.rs
+++ b/src/test/run-pass/option-unwrap.rs
@@ -13,10 +13,13 @@ struct dtor {
 
 }
 
+#[unsafe_destructor]
 impl Drop for dtor {
     fn finalize(&self) {
         // abuse access to shared mutable state to write this code
-        *self.x -= 1;
+        unsafe {
+            *self.x -= 1;
+        }
     }
 }
 
diff --git a/src/test/run-pass/resource-assign-is-not-copy.rs b/src/test/run-pass/resource-assign-is-not-copy.rs
index df084c13427..7d9c01cd2e3 100644
--- a/src/test/run-pass/resource-assign-is-not-copy.rs
+++ b/src/test/run-pass/resource-assign-is-not-copy.rs
@@ -12,9 +12,12 @@ struct r {
   i: @mut int,
 }
 
+#[unsafe_destructor]
 impl Drop for r {
     fn finalize(&self) {
-        *(self.i) += 1;
+        unsafe {
+            *(self.i) += 1;
+        }
     }
 }
 
diff --git a/src/test/run-pass/resource-destruct.rs b/src/test/run-pass/resource-destruct.rs
index db444f08fab..cc9a27fd9e4 100644
--- a/src/test/run-pass/resource-destruct.rs
+++ b/src/test/run-pass/resource-destruct.rs
@@ -12,9 +12,12 @@ struct shrinky_pointer {
   i: @@mut int,
 }
 
+#[unsafe_destructor]
 impl Drop for shrinky_pointer {
     fn finalize(&self) {
-        error!(~"Hello!"); **(self.i) -= 1;
+        unsafe {
+            error!(~"Hello!"); **(self.i) -= 1;
+        }
     }
 }
 
diff --git a/src/test/run-pass/resource-generic.rs b/src/test/run-pass/resource-generic.rs
index e43b90c30b0..4ce6a37956c 100644
--- a/src/test/run-pass/resource-generic.rs
+++ b/src/test/run-pass/resource-generic.rs
@@ -16,9 +16,12 @@ struct finish<T> {
   arg: Arg<T>
 }
 
+#[unsafe_destructor]
 impl<T:Copy> Drop for finish<T> {
     fn finalize(&self) {
-        (self.arg.fin)(self.arg.val);
+        unsafe {
+            (self.arg.fin)(self.arg.val);
+        }
     }
 }
 
diff --git a/src/test/run-pass/resource-in-struct.rs b/src/test/run-pass/resource-in-struct.rs
index 53c76680bde..9eb680ed7cc 100644
--- a/src/test/run-pass/resource-in-struct.rs
+++ b/src/test/run-pass/resource-in-struct.rs
@@ -18,9 +18,12 @@ struct close_res {
 
 }
 
+#[unsafe_destructor]
 impl Drop for close_res {
     fn finalize(&self) {
-        *(self.i) = false;
+        unsafe {
+            *(self.i) = false;
+        }
     }
 }
 
diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs
index 39651f86e22..042ae1785d1 100644
--- a/src/test/run-pass/task-killjoin-rsrc.rs
+++ b/src/test/run-pass/task-killjoin-rsrc.rs
@@ -20,15 +20,18 @@ struct notify {
     ch: Chan<bool>, v: @mut bool,
 }
 
+#[unsafe_destructor]
 impl Drop for notify {
     fn finalize(&self) {
-        error!("notify: task=%? v=%x unwinding=%b b=%b",
-               task::get_task(),
-               ptr::addr_of(&(*(self.v))) as uint,
-               task::failing(),
-               *(self.v));
-        let b = *(self.v);
-        self.ch.send(b);
+        unsafe {
+            error!("notify: task=%? v=%x unwinding=%b b=%b",
+                   task::get_task(),
+                   ptr::addr_of(&(*(self.v))) as uint,
+                   task::failing(),
+                   *(self.v));
+            let b = *(self.v);
+            self.ch.send(b);
+        }
     }
 }
 
diff --git a/src/test/run-pass/unique-pinned-nocopy-2.rs b/src/test/run-pass/unique-pinned-nocopy-2.rs
index 3fc22c9a5a5..ff22c18b02c 100644
--- a/src/test/run-pass/unique-pinned-nocopy-2.rs
+++ b/src/test/run-pass/unique-pinned-nocopy-2.rs
@@ -12,9 +12,12 @@ struct r {
   i: @mut int,
 }
 
+#[unsafe_destructor]
 impl Drop for r {
     fn finalize(&self) {
-        *(self.i) = *(self.i) + 1;
+        unsafe {
+            *(self.i) = *(self.i) + 1;
+        }
     }
 }
 
diff --git a/src/test/run-pass/unwind-resource2.rs b/src/test/run-pass/unwind-resource2.rs
index 75ce797cfc8..993acc2264f 100644
--- a/src/test/run-pass/unwind-resource2.rs
+++ b/src/test/run-pass/unwind-resource2.rs
@@ -15,6 +15,7 @@ struct complainer {
   c: @int,
 }
 
+#[unsafe_destructor]
 impl Drop for complainer {
     fn finalize(&self) {}
 }
diff --git a/src/test/run-pass/vec-slice-drop.rs b/src/test/run-pass/vec-slice-drop.rs
index 71963e073db..2a7c9610ad4 100644
--- a/src/test/run-pass/vec-slice-drop.rs
+++ b/src/test/run-pass/vec-slice-drop.rs
@@ -13,9 +13,12 @@ struct foo {
     x: @mut int,
 }
 
+#[unsafe_destructor]
 impl Drop for foo {
     fn finalize(&self) {
-        *self.x += 1;
+        unsafe {
+            *self.x += 1;
+        }
     }
 }