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 { cond: &'self Condition/&self } +#[unsafe_destructor] impl Drop for Guard/&self { 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, } + #[unsafe_destructor] impl Drop for Res { 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(a: @mut T, b: @mut T) -> bool { } #[cfg(notest)] -impl Eq for @const T { +impl 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 Ord for @const T { +impl 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 Ord for @T { #[inline(always)] - pure fn ge(&self, other: &@const T) -> bool { *(*self) >= *(*other) } + pure fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) } #[inline(always)] - pure fn gt(&self, other: &@const T) -> bool { *(*self) > *(*other) } + 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 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: &@mut T) -> bool { *(*self) >= *(*other) } + #[inline(always)] + 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 { } +#[unsafe_destructor] impl ::ops::Drop for BufferResource { fn finalize(&self) { unsafe { @@ -445,16 +446,17 @@ pub fn try_recv(p: RecvPacketBuffered) 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 { mut buffer: Option>, } +#[unsafe_destructor] impl ::ops::Drop for SendPacketBuffered { fn finalize(&self) { //if self.p != none { @@ -842,6 +845,7 @@ pub struct RecvPacketBuffered { mut buffer: Option>, } +#[unsafe_destructor] impl ::ops::Drop for RecvPacketBuffered { 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 { mut data: *libc::c_void, } +#[unsafe_destructor] impl Drop for ArcDestruct{ 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; @@ -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) { + visit::visit_block(block, cx, visitor); +} + +fn check_item(item: @item, cx: Context, visitor: visit::vt) { + // 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, } +#[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 { // FIXME(#2829) -- futures should not be copyable, because they close // over ~fn's that have pipes and so forth within! +#[unsafe_destructor] impl Drop for Future { 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 { sem: &'self Sem } +#[unsafe_destructor] impl Drop for SemReleaseGeneric/&self { 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 { } +#[unsafe_destructor] impl Drop for TaskPool { 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 { _data: int, } +#[unsafe_destructor] impl Drop for arc_destruct { 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 or the MIT license -// , 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 { - match *v { - @Some(ref i) => {*i} - @None => {0} - } -} - -fn match_const_box(v: &const @const Option) -> 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) { - 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, f: &fn(T)) { @@ -20,10 +19,8 @@ fn apply(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 or the MIT license -// , 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct box_impl { - f: T, -} - -fn box_impl(f: T) -> box_impl { - box_impl { - f: f - } -} - -fn set_box_impl(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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -struct box { - f: T -} - -struct box_impl(box); - -fn set_box_impl(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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -trait box_trait { - fn get(&self) -> T; - fn set(&self, t: T); -} - -struct box { - f: T -} - -struct box_impl(box); - -impl box_trait for box_impl { - fn get(&self) -> T { return self.f; } - fn set(&self, t: T) { self.f = t; } -} - -fn set_box_trait(b: @box_trait<@const T>, v: @const T) { - b.set(v); -} - -fn set_box_impl(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 or the MIT license -// , 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 { x: T } +#[unsafe_destructor] impl ::core::ops::Drop for S { 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>, } + #[unsafe_destructor] impl Drop for send_packet { fn finalize(&self) { unsafe { @@ -187,6 +188,7 @@ pub mod pipes { p: Option<*packet>, } + #[unsafe_destructor] impl Drop for recv_packet { 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 { arg: Arg } +#[unsafe_destructor] impl Drop for finish { 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, 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; + } } }