From b53a920c2b14a6a05854c3a052feba8bbf394080 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 28 Nov 2012 15:42:16 -0800 Subject: [PATCH 1/3] librustc: Make the Drop trait use explicit self --- src/libcore/ops.rs | 2 +- src/librustc/middle/trans/expr.rs | 2 +- src/librustc/middle/trans/glue.rs | 35 ++++++++++++++---- src/librustc/middle/trans/machine.rs | 2 +- src/librustc/middle/trans/type_of.rs | 2 +- src/librustc/middle/ty.rs | 36 +++++++++++++++---- src/libstd/arc.rs | 2 +- src/libstd/arena.rs | 2 +- src/libstd/c_vec.rs | 10 +++--- src/libstd/future.rs | 2 +- src/libstd/net_tcp.rs | 8 ++--- src/libstd/sort.rs | 2 +- src/libstd/sync.rs | 18 +++++----- src/test/auxiliary/issue-2526.rs | 4 +-- src/test/auxiliary/issue-3012-1.rs | 2 +- src/test/auxiliary/issue2170lib.rs | 2 +- src/test/auxiliary/test_comm.rs | 2 +- src/test/bench/task-perf-alloc-unwind.rs | 2 +- ...her-can-live-while-the-other-survives-1.rs | 2 +- ...her-can-live-while-the-other-survives-2.rs | 2 +- ...her-can-live-while-the-other-survives-3.rs | 2 +- ...her-can-live-while-the-other-survives-4.rs | 2 +- .../compile-fail/bind-by-move-no-lvalues-1.rs | 2 +- .../compile-fail/bind-by-move-no-lvalues-2.rs | 2 +- .../bind-by-move-no-sub-bindings.rs | 2 +- .../block-must-not-have-result-res.rs | 2 +- .../borrowck-borrowed-uniq-rvalue-2.rs | 2 +- .../compile-fail/borrowck-unary-move-2.rs | 2 +- .../compile-fail/cap-clause-illegal-cap.rs | 2 +- src/test/compile-fail/copy-a-resource.rs | 2 +- ...lowed-deconstructing-destructing-struct.rs | 2 +- src/test/compile-fail/drop-on-non-struct.rs | 2 +- .../compile-fail/explicit-call-to-dtor.rs | 2 +- .../explicit-call-to-supertrait-dtor.rs | 2 +- .../compile-fail/functional-struct-update.rs | 2 +- src/test/compile-fail/issue-2487-b.rs | 2 +- src/test/compile-fail/issue-2548.rs | 2 +- src/test/compile-fail/issue-2587-2.rs | 2 +- src/test/compile-fail/issue-2823.rs | 2 +- src/test/compile-fail/issue-3214.rs | 2 +- src/test/compile-fail/liveness-unused.rs | 2 +- src/test/compile-fail/no-send-res-ports.rs | 2 +- src/test/compile-fail/non-const.rs | 4 +-- src/test/compile-fail/noncopyable-class.rs | 2 +- src/test/compile-fail/pinned-deep-copy.rs | 2 +- src/test/compile-fail/record-with-resource.rs | 2 +- src/test/compile-fail/regions-in-rsrcs.rs | 6 ++-- .../compile-fail/repeat-to-run-dtor-twice.rs | 2 +- .../compile-fail/unique-object-noncopyable.rs | 2 +- src/test/compile-fail/unique-pinned-nocopy.rs | 2 +- src/test/compile-fail/unique-vec-res.rs | 2 +- src/test/compile-fail/vec-res-add.rs | 2 +- src/test/run-fail/issue-2061.rs | 2 +- src/test/run-fail/morestack2.rs | 2 +- src/test/run-fail/morestack3.rs | 2 +- src/test/run-fail/morestack4.rs | 2 +- src/test/run-fail/rt-set-exit-status-fail2.rs | 2 +- src/test/run-fail/unwind-box-res.rs | 2 +- src/test/run-fail/unwind-resource-fail3.rs | 2 +- src/test/run-pass/class-attributes-1.rs | 2 +- src/test/run-pass/class-attributes-2.rs | 2 +- src/test/run-pass/class-dtor.rs | 2 +- src/test/run-pass/drop-trait-generic.rs | 2 +- src/test/run-pass/drop-trait.rs | 2 +- src/test/run-pass/init-res-into-things.rs | 2 +- src/test/run-pass/issue-2487-a.rs | 2 +- src/test/run-pass/issue-2708.rs | 2 +- src/test/run-pass/issue-2718.rs | 4 +-- src/test/run-pass/issue-2735-2.rs | 2 +- src/test/run-pass/issue-2735-3.rs | 2 +- src/test/run-pass/issue-2895.rs | 2 +- src/test/run-pass/issue-3220.rs | 2 +- src/test/run-pass/issue-979.rs | 2 +- src/test/run-pass/option-unwrap.rs | 2 +- .../run-pass/pipe-presentation-examples.rs | 2 +- .../run-pass/resource-assign-is-not-copy.rs | 2 +- src/test/run-pass/resource-cycle.rs | 2 +- src/test/run-pass/resource-cycle2.rs | 2 +- src/test/run-pass/resource-cycle3.rs | 2 +- src/test/run-pass/resource-destruct.rs | 2 +- src/test/run-pass/resource-generic.rs | 2 +- src/test/run-pass/resource-in-struct.rs | 2 +- src/test/run-pass/send-resource.rs | 2 +- src/test/run-pass/struct-literal-dtor.rs | 2 +- src/test/run-pass/task-compare.rs | 2 +- src/test/run-pass/task-killjoin-rsrc.rs | 2 +- src/test/run-pass/type-param-constraints.rs | 2 +- src/test/run-pass/unique-pinned-nocopy-2.rs | 2 +- src/test/run-pass/unwind-resource.rs | 2 +- src/test/run-pass/unwind-resource2.rs | 2 +- src/test/run-pass/vec-slice-drop.rs | 2 +- 91 files changed, 166 insertions(+), 123 deletions(-) diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 87c165266f82d..5c56ed7608f25 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -25,7 +25,7 @@ pub trait Owned { #[lang="drop"] pub trait Drop { - fn finalize(); // XXX: Rename to "drop"? --pcwalton + fn finalize(&self); // XXX: Rename to "drop"? --pcwalton } #[lang="add"] diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 721e4fddb4c72..36696594e423c 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -888,7 +888,7 @@ fn with_field_tys(tcx: ty::ctxt, } ty::ty_class(did, ref substs) => { - let has_dtor = ty::ty_dtor(tcx, did).is_some(); + let has_dtor = ty::ty_dtor(tcx, did).is_present(); op(has_dtor, class_items_as_mutable_fields(tcx, did, substs)) } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 76d5770ac3d27..0a44028c7dfdb 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -397,8 +397,14 @@ fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { } ty::ty_class(did, ref substs) => { // Call the dtor if there is one - do option::map_default(&ty::ty_dtor(bcx.tcx(), did), bcx) |dt_id| { - trans_class_drop(bcx, v, *dt_id, did, substs) + match ty::ty_dtor(bcx.tcx(), did) { + ty::NoDtor => bcx, + ty::LegacyDtor(ref dt_id) => { + trans_class_drop(bcx, v, *dt_id, did, substs, false) + } + ty::TraitDtor(ref dt_id) => { + trans_class_drop(bcx, v, *dt_id, did, substs, true) + } } } _ => bcx @@ -410,7 +416,8 @@ fn trans_class_drop(bcx: block, v0: ValueRef, dtor_did: ast::def_id, class_did: ast::def_id, - substs: &ty::substs) -> block { + substs: &ty::substs, + take_ref: bool) -> block { let drop_flag = GEPi(bcx, v0, struct_dtor()); do with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag))) |cx| { let mut bcx = cx; @@ -427,7 +434,18 @@ fn trans_class_drop(bcx: block, // just consist of the output pointer and the environment // (self) assert(params.len() == 2); - let self_arg = PointerCast(bcx, v0, params[1]); + + // If we need to take a reference to the class (because it's using + // the Drop trait), do so now. + let llval; + if take_ref { + llval = alloca(bcx, val_ty(v0)); + Store(bcx, v0, llval); + } else { + llval = v0; + } + + let self_arg = PointerCast(bcx, llval, params[1]); let args = ~[bcx.fcx.llretptr, self_arg]; Call(bcx, dtor_addr, args); @@ -465,10 +483,13 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { ty::ty_class(did, ref substs) => { let tcx = bcx.tcx(); match ty::ty_dtor(tcx, did) { - Some(dtor) => { - trans_class_drop(bcx, v0, dtor, did, substs) + ty::TraitDtor(dtor) => { + trans_class_drop(bcx, v0, dtor, did, substs, true) } - None => { + ty::LegacyDtor(dtor) => { + trans_class_drop(bcx, v0, dtor, did, substs, false) + } + ty::NoDtor => { // No dtor? Just the default case iter_structural_ty(bcx, v0, t, drop_ty) } diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index 5515d80f4bdea..6f6a5c52ecdfc 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -27,7 +27,7 @@ pub fn simplify_type(tcx: ty::ctxt, typ: ty::t) -> ty::t { // Reduce a class type to a record type in which all the fields are // simplified ty::ty_class(did, ref substs) => { - let simpl_fields = (if ty::ty_dtor(tcx, did).is_some() { + let simpl_fields = (if ty::ty_dtor(tcx, did).is_present() { // remember the drop flag ~[{ident: syntax::parse::token::special_idents::dtor, mt: {ty: ty::mk_u8(tcx), diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 604bad2312f72..9251b31568419 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -199,7 +199,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef { // include a byte flag if there is a dtor so that we know when we've // been dropped - if ty::ty_dtor(cx.tcx, did) != None { + if ty::ty_dtor(cx.tcx, did).is_present() { common::set_struct_body(llty, ~[T_struct(tys), T_i8()]); } else { common::set_struct_body(llty, ~[T_struct(tys)]); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 520875f3b158f..b37fbd9feb456 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -75,6 +75,7 @@ export enum_variants, substd_enum_variants, enum_is_univariant; export trait_methods, store_trait_methods, impl_traits; export enum_variant_with_id; export ty_dtor; +export DtorKind, NoDtor, LegacyDtor, TraitDtor; export ty_param_bounds_and_ty; export ty_param_substs_and_ty; export ty_bool, mk_bool, type_is_bool; @@ -1868,7 +1869,7 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool { } ty_class(did, ref substs) => { // Any class with a dtor needs a drop - ty_dtor(cx, did).is_some() || { + ty_dtor(cx, did).is_present() || { for vec::each(ty::class_items_as_fields(cx, did, substs)) |f| { if type_needs_drop(cx, f.mt.ty) { accum = true; } } @@ -3954,11 +3955,29 @@ fn item_path_str(cx: ctxt, id: ast::def_id) -> ~str { ast_map::path_to_str(item_path(cx, id), cx.sess.parse_sess.interner) } +enum DtorKind { + NoDtor, + LegacyDtor(def_id), + TraitDtor(def_id) +} + +impl DtorKind { + pure fn is_not_present(&const self) -> bool { + match *self { + NoDtor => true, + _ => false + } + } + pure fn is_present(&const self) -> bool { + !self.is_not_present() + } +} + /* If class_id names a class with a dtor, return Some(the dtor's id). Otherwise return none. */ -fn ty_dtor(cx: ctxt, class_id: def_id) -> Option { +fn ty_dtor(cx: ctxt, class_id: def_id) -> DtorKind { match cx.destructor_for_type.find(class_id) { - Some(method_def_id) => return Some(method_def_id), + Some(method_def_id) => return TraitDtor(method_def_id), None => {} // Continue. } @@ -3968,18 +3987,21 @@ fn ty_dtor(cx: ctxt, class_id: def_id) -> Option { node: ast::item_class(@{ dtor: Some(dtor), _ }, _), _ }, _)) => - Some(local_def(dtor.node.id)), + LegacyDtor(local_def(dtor.node.id)), _ => - None + NoDtor } } else { - csearch::class_dtor(cx.sess.cstore, class_id) + match csearch::class_dtor(cx.sess.cstore, class_id) { + None => NoDtor, + Some(did) => LegacyDtor(did), + } } } fn has_dtor(cx: ctxt, class_id: def_id) -> bool { - ty_dtor(cx, class_id).is_some() + ty_dtor(cx, class_id).is_present() } fn item_path(cx: ctxt, id: ast::def_id) -> ast_map::path { diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 628d72f99c1e3..3ced56e6f508f 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -229,7 +229,7 @@ struct PoisonOnFail { } impl PoisonOnFail : Drop { - fn finalize() { + fn finalize(&self) { /* assert !*self.failed; -- might be false in case of cond.wait() */ if task::failing() { *self.failed = true; } } diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index cf8bbc628f0c1..ea247d4bd3fba 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -58,7 +58,7 @@ pub struct Arena { } impl Arena : Drop { - fn finalize() { + fn finalize(&self) { unsafe { destroy_chunk(&self.head); for list::each(self.chunks) |chunk| { diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 2e94f07d2d88d..8777592eaccd3 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -42,11 +42,11 @@ struct DtorRes { } impl DtorRes : Drop { - fn finalize() { - match self.dtor { - option::None => (), - option::Some(f) => f() - } + fn finalize(&self) { + match self.dtor { + option::None => (), + option::Some(f) => f() + } } } diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 31144740c8ade..a22e4d674683b 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -28,7 +28,7 @@ pub struct Future { // FIXME(#2829) -- futures should not be copyable, because they close // over fn~'s that have pipes and so forth within! impl Future : Drop { - fn finalize() {} + fn finalize(&self) {} } priv enum FutureState { diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 182ec2a233c97..2dd0c2b286d8f 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -30,10 +30,10 @@ struct TcpSocket { } impl TcpSocket : Drop { - fn finalize() { - unsafe { - tear_down_socket_data(self.socket_data) - } + fn finalize(&self) { + unsafe { + tear_down_socket_data(self.socket_data) + } } } diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index c6e8c72e6d649..c9981c2fef5c5 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -1137,7 +1137,7 @@ mod big_tests { } impl LVal : Drop { - fn finalize() { + fn finalize(&self) { let x = unsafe { task::local_data::local_data_get(self.key) }; match x { Some(@y) => { diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index c288e4dc4d37d..61201d44d2f88 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -153,7 +153,7 @@ struct SemRelease { } impl SemRelease : Drop { - fn finalize() { + fn finalize(&self) { self.sem.release(); } } @@ -170,7 +170,7 @@ struct SemAndSignalRelease { } impl SemAndSignalRelease : Drop { - fn finalize() { + fn finalize(&self) { self.sem.release(); } } @@ -185,7 +185,7 @@ fn SemAndSignalRelease(sem: &r/Sem<~[mut Waitqueue]>) /// A mechanism for atomic-unlock-and-deschedule blocking and signalling. pub struct Condvar { priv sem: &Sem<~[mut Waitqueue]> } -impl Condvar : Drop { fn finalize() {} } +impl Condvar : Drop { fn finalize(&self) {} } impl &Condvar { /** @@ -257,7 +257,7 @@ impl &Condvar { } impl SemAndSignalReacquire : Drop { - fn finalize() { + fn finalize(&self) { unsafe { // Needs to succeed, instead of itself dying. do task::unkillable { @@ -607,7 +607,7 @@ struct RWlockReleaseRead { } impl RWlockReleaseRead : Drop { - fn finalize() { + fn finalize(&self) { unsafe { do task::unkillable { let mut last_reader = false; @@ -641,7 +641,7 @@ struct RWlockReleaseDowngrade { } impl RWlockReleaseDowngrade : Drop { - fn finalize() { + fn finalize(&self) { unsafe { do task::unkillable { let mut writer_or_last_reader = false; @@ -678,10 +678,10 @@ fn RWlockReleaseDowngrade(lock: &r/RWlock) -> RWlockReleaseDowngrade/&r { /// The "write permission" token used for rwlock.write_downgrade(). pub struct RWlockWriteMode { /* priv */ lock: &RWlock } -impl RWlockWriteMode : Drop { fn finalize() {} } +impl RWlockWriteMode : Drop { fn finalize(&self) {} } /// The "read permission" token used for rwlock.write_downgrade(). pub struct RWlockReadMode { priv lock: &RWlock } -impl RWlockReadMode : Drop { fn finalize() {} } +impl RWlockReadMode : Drop { fn finalize(&self) {} } impl &RWlockWriteMode { /// Access the pre-downgrade rwlock in write mode. @@ -993,7 +993,7 @@ mod tests { } impl SendOnFailure : Drop { - fn finalize() { + fn finalize(&self) { self.c.send(()); } } diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index d17de197e24a9..b3e5c645edbc1 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -12,7 +12,7 @@ struct arc_destruct { } impl arc_destruct : Drop { - fn finalize() {} + fn finalize(&self) {} } fn arc_destruct(data: int) -> arc_destruct { @@ -34,7 +34,7 @@ struct context_res { } impl context_res : Drop { - fn finalize() {} + fn finalize(&self) {} } fn context_res() -> context_res { diff --git a/src/test/auxiliary/issue-3012-1.rs b/src/test/auxiliary/issue-3012-1.rs index ba123cf5254e1..15c7cf53e2f6c 100644 --- a/src/test/auxiliary/issue-3012-1.rs +++ b/src/test/auxiliary/issue-3012-1.rs @@ -12,7 +12,7 @@ struct socket_handle { } impl socket_handle : Drop { - fn finalize() { + fn finalize(&self) { /* c::close(self.sockfd); */ } } diff --git a/src/test/auxiliary/issue2170lib.rs b/src/test/auxiliary/issue2170lib.rs index 3ce738fd5e0c6..9a78fd346130c 100644 --- a/src/test/auxiliary/issue2170lib.rs +++ b/src/test/auxiliary/issue2170lib.rs @@ -8,7 +8,7 @@ struct rsrc { } impl rsrc : Drop { - fn finalize() { + fn finalize(&self) { foo(self.x); } } diff --git a/src/test/auxiliary/test_comm.rs b/src/test/auxiliary/test_comm.rs index 9664dc24c3335..36e336d2ad391 100644 --- a/src/test/auxiliary/test_comm.rs +++ b/src/test/auxiliary/test_comm.rs @@ -32,7 +32,7 @@ struct port_ptr { } impl port_ptr : Drop { - fn finalize() { + fn finalize(&self) { unsafe { debug!("in the port_ptr destructor"); do task::unkillable { diff --git a/src/test/bench/task-perf-alloc-unwind.rs b/src/test/bench/task-perf-alloc-unwind.rs index 65fb9ec173918..f2652b10cdc1a 100644 --- a/src/test/bench/task-perf-alloc-unwind.rs +++ b/src/test/bench/task-perf-alloc-unwind.rs @@ -45,7 +45,7 @@ struct r { } impl r : Drop { - fn finalize() {} + fn finalize(&self) {} } fn r(l: @nillist) -> r { diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs index 1f7989d1ae935..5753a8625829f 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-1.rs @@ -1,7 +1,7 @@ struct X { x: () } impl X : Drop { - fn finalize() { + fn finalize(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs index 598fc4b0a0805..2cf08c0139fa0 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-2.rs @@ -1,7 +1,7 @@ struct X { x: (), } impl X : Drop { - fn finalize() { + fn finalize(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs index 1cd62e9288922..3dd000a1da8f5 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-3.rs @@ -1,7 +1,7 @@ struct X { x: (), } impl X : Drop { - fn finalize() { + fn finalize(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs index 3cd6c45af0b8a..e7f146e5bd359 100644 --- a/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs +++ b/src/test/compile-fail/bind-by-move-neither-can-live-while-the-other-survives-4.rs @@ -1,7 +1,7 @@ struct X { x: (), } impl X : Drop { - fn finalize() { + fn finalize(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-no-lvalues-1.rs b/src/test/compile-fail/bind-by-move-no-lvalues-1.rs index 29d21ee670d8b..cd5bf5e17f3d0 100644 --- a/src/test/compile-fail/bind-by-move-no-lvalues-1.rs +++ b/src/test/compile-fail/bind-by-move-no-lvalues-1.rs @@ -1,7 +1,7 @@ struct X { x: (), } impl X : Drop { - fn finalize() { + fn finalize(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-no-lvalues-2.rs b/src/test/compile-fail/bind-by-move-no-lvalues-2.rs index b1b38b587e869..be016034ff34d 100644 --- a/src/test/compile-fail/bind-by-move-no-lvalues-2.rs +++ b/src/test/compile-fail/bind-by-move-no-lvalues-2.rs @@ -1,7 +1,7 @@ struct X { x: (), } impl X : Drop { - fn finalize() { + fn finalize(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/bind-by-move-no-sub-bindings.rs b/src/test/compile-fail/bind-by-move-no-sub-bindings.rs index 2a36d9e0db6f6..3c1ffbd86d782 100644 --- a/src/test/compile-fail/bind-by-move-no-sub-bindings.rs +++ b/src/test/compile-fail/bind-by-move-no-sub-bindings.rs @@ -1,7 +1,7 @@ struct X { x: (), } impl X : Drop { - fn finalize() { + fn finalize(&self) { error!("destructor runs"); } } diff --git a/src/test/compile-fail/block-must-not-have-result-res.rs b/src/test/compile-fail/block-must-not-have-result-res.rs index a282352123426..464d6b1bc0385 100644 --- a/src/test/compile-fail/block-must-not-have-result-res.rs +++ b/src/test/compile-fail/block-must-not-have-result-res.rs @@ -3,7 +3,7 @@ struct r {} impl r : Drop { - fn finalize() { + fn finalize(&self) { true } } 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 4920a0239a577..cd24a8bb323e6 100644 --- a/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs +++ b/src/test/compile-fail/borrowck-borrowed-uniq-rvalue-2.rs @@ -3,7 +3,7 @@ struct defer { } impl defer : Drop { - fn finalize() { + fn finalize(&self) { error!("%?", self.x); } } diff --git a/src/test/compile-fail/borrowck-unary-move-2.rs b/src/test/compile-fail/borrowck-unary-move-2.rs index b8fcf695c3fdc..eedeac84f8346 100644 --- a/src/test/compile-fail/borrowck-unary-move-2.rs +++ b/src/test/compile-fail/borrowck-unary-move-2.rs @@ -3,7 +3,7 @@ struct noncopyable { } impl noncopyable : Drop { - fn finalize() { + fn finalize(&self) { error!("dropped"); } } diff --git a/src/test/compile-fail/cap-clause-illegal-cap.rs b/src/test/compile-fail/cap-clause-illegal-cap.rs index be630ec851810..c174a4b50bcc9 100644 --- a/src/test/compile-fail/cap-clause-illegal-cap.rs +++ b/src/test/compile-fail/cap-clause-illegal-cap.rs @@ -3,7 +3,7 @@ struct foo { x: int, } impl foo : Drop { - fn finalize() {} + fn finalize(&self) {} } fn foo(x: int) -> foo { diff --git a/src/test/compile-fail/copy-a-resource.rs b/src/test/compile-fail/copy-a-resource.rs index 9f86b9e894a58..311eecae7db59 100644 --- a/src/test/compile-fail/copy-a-resource.rs +++ b/src/test/compile-fail/copy-a-resource.rs @@ -5,7 +5,7 @@ struct foo { } impl foo : Drop { - fn finalize() {} + fn finalize(&self) {} } fn foo(i:int) -> foo { diff --git a/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs b/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs index 407b786016d60..053a4075d2f87 100644 --- a/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs +++ b/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs @@ -3,7 +3,7 @@ struct X { } impl X : Drop { - fn finalize() { + fn finalize(&self) { error!("value: %s", self.x); } } diff --git a/src/test/compile-fail/drop-on-non-struct.rs b/src/test/compile-fail/drop-on-non-struct.rs index 8ee72d9d2fdcc..f3db004da1326 100644 --- a/src/test/compile-fail/drop-on-non-struct.rs +++ b/src/test/compile-fail/drop-on-non-struct.rs @@ -1,7 +1,7 @@ type Foo = @[u8]; impl Foo : Drop { //~ ERROR the Drop trait may only be implemented - fn finalize() { + fn finalize(&self) { io::println("kaboom"); } } diff --git a/src/test/compile-fail/explicit-call-to-dtor.rs b/src/test/compile-fail/explicit-call-to-dtor.rs index 56af671852b58..0f78d8e1ae3f1 100644 --- a/src/test/compile-fail/explicit-call-to-dtor.rs +++ b/src/test/compile-fail/explicit-call-to-dtor.rs @@ -3,7 +3,7 @@ struct Foo { } impl Foo : Drop { - fn finalize() { + fn finalize(&self) { io::println("kaboom"); } } diff --git a/src/test/compile-fail/explicit-call-to-supertrait-dtor.rs b/src/test/compile-fail/explicit-call-to-supertrait-dtor.rs index c7c2748235acc..83464270eb521 100644 --- a/src/test/compile-fail/explicit-call-to-supertrait-dtor.rs +++ b/src/test/compile-fail/explicit-call-to-supertrait-dtor.rs @@ -7,7 +7,7 @@ trait Bar : Drop { } impl Foo : Drop { - fn finalize() { + fn finalize(&self) { io::println("kaboom"); } } diff --git a/src/test/compile-fail/functional-struct-update.rs b/src/test/compile-fail/functional-struct-update.rs index 13012f146bf28..a1a156d9ff534 100644 --- a/src/test/compile-fail/functional-struct-update.rs +++ b/src/test/compile-fail/functional-struct-update.rs @@ -3,7 +3,7 @@ struct Bar { } impl Bar : Drop { - fn finalize() { + fn finalize(&self) { io::println("Goodbye, cruel world"); } } diff --git a/src/test/compile-fail/issue-2487-b.rs b/src/test/compile-fail/issue-2487-b.rs index 5476ab240007f..a6248c158b72e 100644 --- a/src/test/compile-fail/issue-2487-b.rs +++ b/src/test/compile-fail/issue-2487-b.rs @@ -3,7 +3,7 @@ struct socket { } impl socket : Drop { - fn finalize() {} + fn finalize(&self) {} } impl socket { diff --git a/src/test/compile-fail/issue-2548.rs b/src/test/compile-fail/issue-2548.rs index 5567e5855e47b..d47d51b2a2b9a 100644 --- a/src/test/compile-fail/issue-2548.rs +++ b/src/test/compile-fail/issue-2548.rs @@ -7,7 +7,7 @@ struct foo { } impl foo : Drop { - fn finalize() { + fn finalize(&self) { io::println("Goodbye, World!"); *self.x += 1; } diff --git a/src/test/compile-fail/issue-2587-2.rs b/src/test/compile-fail/issue-2587-2.rs index 8b1bcb69e01bc..d8d2f82da97bf 100644 --- a/src/test/compile-fail/issue-2587-2.rs +++ b/src/test/compile-fail/issue-2587-2.rs @@ -9,7 +9,7 @@ struct S { } impl S : Drop { - fn finalize() {} + fn finalize(&self) {} } fn S(x: int) -> S { S { x: x } } diff --git a/src/test/compile-fail/issue-2823.rs b/src/test/compile-fail/issue-2823.rs index 5b02a6da45892..e613114fee54d 100644 --- a/src/test/compile-fail/issue-2823.rs +++ b/src/test/compile-fail/issue-2823.rs @@ -3,7 +3,7 @@ struct C { } impl C : Drop { - fn finalize() { + fn finalize(&self) { error!("dropping: %?", self.x); } } diff --git a/src/test/compile-fail/issue-3214.rs b/src/test/compile-fail/issue-3214.rs index 9e38c39bb72a3..ad97377324ce8 100644 --- a/src/test/compile-fail/issue-3214.rs +++ b/src/test/compile-fail/issue-3214.rs @@ -5,7 +5,7 @@ fn foo() { } impl foo : Drop { - fn finalize() {} + fn finalize(&self) {} } } fn main() { } diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs index 3aaaa2ef16fd0..3c4d70e058bbc 100644 --- a/src/test/compile-fail/liveness-unused.rs +++ b/src/test/compile-fail/liveness-unused.rs @@ -53,7 +53,7 @@ struct r { } impl r : Drop { - fn finalize() {} + fn finalize(&self) {} } fn main() { diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs index 7f5c7e1f59b5f..87f149d3928b4 100644 --- a/src/test/compile-fail/no-send-res-ports.rs +++ b/src/test/compile-fail/no-send-res-ports.rs @@ -4,7 +4,7 @@ fn main() { } impl foo : Drop { - fn finalize() {} + fn finalize(&self) {} } fn foo(x: comm::Port<()>) -> foo { diff --git a/src/test/compile-fail/non-const.rs b/src/test/compile-fail/non-const.rs index 084b357561acd..0808997676bca 100644 --- a/src/test/compile-fail/non-const.rs +++ b/src/test/compile-fail/non-const.rs @@ -7,7 +7,7 @@ struct r { } impl r : Drop { - fn finalize() {} + fn finalize(&self) {} } fn r(x:int) -> r { @@ -21,7 +21,7 @@ struct r2 { } impl r2 : Drop { - fn finalize() {} + fn finalize(&self) {} } fn r2(x:@mut int) -> r2 { diff --git a/src/test/compile-fail/noncopyable-class.rs b/src/test/compile-fail/noncopyable-class.rs index 0d56867225d6d..ee786370dfb18 100644 --- a/src/test/compile-fail/noncopyable-class.rs +++ b/src/test/compile-fail/noncopyable-class.rs @@ -7,7 +7,7 @@ struct bar { } impl bar : Drop { - fn finalize() {} + fn finalize(&self) {} } fn bar(x:int) -> bar { diff --git a/src/test/compile-fail/pinned-deep-copy.rs b/src/test/compile-fail/pinned-deep-copy.rs index c95e2f0b54d1e..dbb57d7ee8617 100644 --- a/src/test/compile-fail/pinned-deep-copy.rs +++ b/src/test/compile-fail/pinned-deep-copy.rs @@ -5,7 +5,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { *(self.i) = *(self.i) + 1; } } diff --git a/src/test/compile-fail/record-with-resource.rs b/src/test/compile-fail/record-with-resource.rs index 6bcac8f56e0a6..01a6c729e7fa1 100644 --- a/src/test/compile-fail/record-with-resource.rs +++ b/src/test/compile-fail/record-with-resource.rs @@ -5,7 +5,7 @@ struct my_resource { } impl my_resource : Drop { - fn finalize() { + fn finalize(&self) { log(error, self.x); } } diff --git a/src/test/compile-fail/regions-in-rsrcs.rs b/src/test/compile-fail/regions-in-rsrcs.rs index cce998bea2db7..bcd7e5b03ab25 100644 --- a/src/test/compile-fail/regions-in-rsrcs.rs +++ b/src/test/compile-fail/regions-in-rsrcs.rs @@ -3,7 +3,7 @@ struct yes0 { } impl yes0 : Drop { - fn finalize() {} + fn finalize(&self) {} } struct yes1 { @@ -11,7 +11,7 @@ struct yes1 { } impl yes1 : Drop { - fn finalize() {} + fn finalize(&self) {} } struct yes2 { @@ -19,7 +19,7 @@ struct yes2 { } impl yes2 : Drop { - fn finalize() {} + fn finalize(&self) {} } fn main() {} diff --git a/src/test/compile-fail/repeat-to-run-dtor-twice.rs b/src/test/compile-fail/repeat-to-run-dtor-twice.rs index fb5b2509cb890..2037358c36d20 100644 --- a/src/test/compile-fail/repeat-to-run-dtor-twice.rs +++ b/src/test/compile-fail/repeat-to-run-dtor-twice.rs @@ -7,7 +7,7 @@ struct Foo { } impl Foo : Drop { - fn finalize() { + fn finalize(&self) { io::println("Goodbye!"); } } diff --git a/src/test/compile-fail/unique-object-noncopyable.rs b/src/test/compile-fail/unique-object-noncopyable.rs index 32739a1075ae2..f42bfea9562e5 100644 --- a/src/test/compile-fail/unique-object-noncopyable.rs +++ b/src/test/compile-fail/unique-object-noncopyable.rs @@ -7,7 +7,7 @@ struct Bar { } impl Bar : Drop { - fn finalize() {} + fn finalize(&self) {} } impl Bar : Foo { diff --git a/src/test/compile-fail/unique-pinned-nocopy.rs b/src/test/compile-fail/unique-pinned-nocopy.rs index 6a665c2924037..d9eeced26fe90 100644 --- a/src/test/compile-fail/unique-pinned-nocopy.rs +++ b/src/test/compile-fail/unique-pinned-nocopy.rs @@ -5,7 +5,7 @@ struct r { } impl r : Drop { - fn finalize() {} + fn finalize(&self) {} } fn main() { diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs index 157b4435d077e..0c3ab53dcc768 100644 --- a/src/test/compile-fail/unique-vec-res.rs +++ b/src/test/compile-fail/unique-vec-res.rs @@ -5,7 +5,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { *(self.i) = *(self.i) + 1; } } diff --git a/src/test/compile-fail/vec-res-add.rs b/src/test/compile-fail/vec-res-add.rs index 452c7e490cc69..c0e6f2b60c169 100644 --- a/src/test/compile-fail/vec-res-add.rs +++ b/src/test/compile-fail/vec-res-add.rs @@ -7,7 +7,7 @@ struct r { fn r(i:int) -> r { r { i: i } } impl r : Drop { - fn finalize() {} + fn finalize(&self) {} } fn main() { diff --git a/src/test/run-fail/issue-2061.rs b/src/test/run-fail/issue-2061.rs index bed54138acb4e..9ffc10b86ae97 100644 --- a/src/test/run-fail/issue-2061.rs +++ b/src/test/run-fail/issue-2061.rs @@ -5,7 +5,7 @@ struct R { } impl R : Drop { - fn finalize() { + fn finalize(&self) { let _y = R { b: self.b }; } } diff --git a/src/test/run-fail/morestack2.rs b/src/test/run-fail/morestack2.rs index 29ea363ecaea8..32b45c5396eb4 100644 --- a/src/test/run-fail/morestack2.rs +++ b/src/test/run-fail/morestack2.rs @@ -26,7 +26,7 @@ struct and_then_get_big_again { } impl and_then_get_big_again : Drop { - fn finalize() { + fn finalize(&self) { fn getbig(i: int) { if i != 0 { getbig(i - 1); diff --git a/src/test/run-fail/morestack3.rs b/src/test/run-fail/morestack3.rs index 9d021b96226c4..1892be596c164 100644 --- a/src/test/run-fail/morestack3.rs +++ b/src/test/run-fail/morestack3.rs @@ -18,7 +18,7 @@ struct and_then_get_big_again { } impl and_then_get_big_again : Drop { - fn finalize() { + fn finalize(&self) { fn getbig(i: int) { if i != 0 { getbig(i - 1); diff --git a/src/test/run-fail/morestack4.rs b/src/test/run-fail/morestack4.rs index fac54ae250770..c5d3161cbf69f 100644 --- a/src/test/run-fail/morestack4.rs +++ b/src/test/run-fail/morestack4.rs @@ -18,7 +18,7 @@ struct and_then_get_big_again { } impl and_then_get_big_again : Drop { - fn finalize() {} + fn finalize(&self) {} } fn and_then_get_big_again(x:int) -> and_then_get_big_again { diff --git a/src/test/run-fail/rt-set-exit-status-fail2.rs b/src/test/run-fail/rt-set-exit-status-fail2.rs index d8c5662e193ae..45385927566e0 100644 --- a/src/test/run-fail/rt-set-exit-status-fail2.rs +++ b/src/test/run-fail/rt-set-exit-status-fail2.rs @@ -8,7 +8,7 @@ struct r { // failed has no effect and the process exits with the // runtime's exit code impl r : Drop { - fn finalize() { + fn finalize(&self) { os::set_exit_status(50); } } diff --git a/src/test/run-fail/unwind-box-res.rs b/src/test/run-fail/unwind-box-res.rs index d9e347079f42c..1c61704bdbe49 100644 --- a/src/test/run-fail/unwind-box-res.rs +++ b/src/test/run-fail/unwind-box-res.rs @@ -9,7 +9,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { unsafe { let _v2: ~int = cast::reinterpret_cast(&self.v); } diff --git a/src/test/run-fail/unwind-resource-fail3.rs b/src/test/run-fail/unwind-resource-fail3.rs index 628ef64626cf2..17acfd105bbfc 100644 --- a/src/test/run-fail/unwind-resource-fail3.rs +++ b/src/test/run-fail/unwind-resource-fail3.rs @@ -8,7 +8,7 @@ struct faily_box { fn faily_box(i: @int) -> faily_box { faily_box { i: i } } impl faily_box : Drop { - fn finalize() { + fn finalize(&self) { fail ~"quux"; } } diff --git a/src/test/run-pass/class-attributes-1.rs b/src/test/run-pass/class-attributes-1.rs index f3f887230d24d..29abb4c9d7ea2 100644 --- a/src/test/run-pass/class-attributes-1.rs +++ b/src/test/run-pass/class-attributes-1.rs @@ -6,7 +6,7 @@ struct cat { impl cat: Drop { #[cat_dropper] - fn finalize() { error!("%s landed on hir feet",self.name); } + fn finalize(&self) { error!("%s landed on hir feet",self.name); } } diff --git a/src/test/run-pass/class-attributes-2.rs b/src/test/run-pass/class-attributes-2.rs index 5bcec8d3b0d74..00d3730554e62 100644 --- a/src/test/run-pass/class-attributes-2.rs +++ b/src/test/run-pass/class-attributes-2.rs @@ -7,7 +7,7 @@ impl cat : Drop { /** Actually, cats don't always land on their feet when you drop them. */ - fn finalize() { + fn finalize(&self) { error!("%s landed on hir feet", self.name); } } diff --git a/src/test/run-pass/class-dtor.rs b/src/test/run-pass/class-dtor.rs index 318392921d873..e9194f057781d 100644 --- a/src/test/run-pass/class-dtor.rs +++ b/src/test/run-pass/class-dtor.rs @@ -4,7 +4,7 @@ struct cat { } impl cat : Drop { - fn finalize() { + fn finalize(&self) { self.done(self.meows); } } diff --git a/src/test/run-pass/drop-trait-generic.rs b/src/test/run-pass/drop-trait-generic.rs index 6df59ed8ca92a..a56cd0f6eca8f 100644 --- a/src/test/run-pass/drop-trait-generic.rs +++ b/src/test/run-pass/drop-trait-generic.rs @@ -3,7 +3,7 @@ struct S { } impl S : core::ops::Drop { - fn finalize() { + fn finalize(&self) { io::println("bye"); } } diff --git a/src/test/run-pass/drop-trait.rs b/src/test/run-pass/drop-trait.rs index 3a379a4c9dc4f..f55981e58bef8 100644 --- a/src/test/run-pass/drop-trait.rs +++ b/src/test/run-pass/drop-trait.rs @@ -3,7 +3,7 @@ struct Foo { } impl Foo : Drop { - fn finalize() { + 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 04520d925b1c3..c9824d96c9c03 100644 --- a/src/test/run-pass/init-res-into-things.rs +++ b/src/test/run-pass/init-res-into-things.rs @@ -6,7 +6,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { *(self.i) = *(self.i) + 1; } } diff --git a/src/test/run-pass/issue-2487-a.rs b/src/test/run-pass/issue-2487-a.rs index 15c46ffbaf875..1007486463265 100644 --- a/src/test/run-pass/issue-2487-a.rs +++ b/src/test/run-pass/issue-2487-a.rs @@ -4,7 +4,7 @@ struct socket { } impl socket : Drop { - fn finalize() {} + fn finalize(&self) {} } impl socket { diff --git a/src/test/run-pass/issue-2708.rs b/src/test/run-pass/issue-2708.rs index aefcca9004b9e..e4ff1fef539cd 100644 --- a/src/test/run-pass/issue-2708.rs +++ b/src/test/run-pass/issue-2708.rs @@ -6,7 +6,7 @@ struct Font { } impl Font : Drop { - fn finalize() {} + fn finalize(&self) {} } fn Font() -> Font { diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 3148c68fe113f..82ad82c64a3c9 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -144,7 +144,7 @@ mod pipes { } impl send_packet : Drop { - fn finalize() { + fn finalize(&self) { if self.p != None { let mut p = None; p <-> self.p; @@ -172,7 +172,7 @@ mod pipes { } impl recv_packet : Drop { - fn finalize() { + fn finalize(&self) { if self.p != None { let mut p = None; p <-> self.p; diff --git a/src/test/run-pass/issue-2735-2.rs b/src/test/run-pass/issue-2735-2.rs index 86458989ffd0a..501d37f7d3986 100644 --- a/src/test/run-pass/issue-2735-2.rs +++ b/src/test/run-pass/issue-2735-2.rs @@ -4,7 +4,7 @@ struct defer { } impl defer : Drop { - fn finalize() { + fn finalize(&self) { *(self.b) = true; } } diff --git a/src/test/run-pass/issue-2735-3.rs b/src/test/run-pass/issue-2735-3.rs index 4a93de936bc0b..cfaad51f3b629 100644 --- a/src/test/run-pass/issue-2735-3.rs +++ b/src/test/run-pass/issue-2735-3.rs @@ -4,7 +4,7 @@ struct defer { } impl defer : Drop { - fn finalize() { + fn finalize(&self) { *(self.b) = true; } } diff --git a/src/test/run-pass/issue-2895.rs b/src/test/run-pass/issue-2895.rs index d15edccaa1830..c45a582fd667d 100644 --- a/src/test/run-pass/issue-2895.rs +++ b/src/test/run-pass/issue-2895.rs @@ -10,7 +10,7 @@ struct Kitty { } impl Kitty : Drop { - fn finalize() {} + fn finalize(&self) {} } #[cfg(target_arch = "x86_64")] diff --git a/src/test/run-pass/issue-3220.rs b/src/test/run-pass/issue-3220.rs index 273db8505a1ab..6e51ae80baf43 100644 --- a/src/test/run-pass/issue-3220.rs +++ b/src/test/run-pass/issue-3220.rs @@ -1,7 +1,7 @@ struct thing { x: int, } impl thing : Drop { - fn finalize() {} + fn finalize(&self) {} } fn thing() -> thing { diff --git a/src/test/run-pass/issue-979.rs b/src/test/run-pass/issue-979.rs index 970afb0597ecf..e8e1def99c025 100644 --- a/src/test/run-pass/issue-979.rs +++ b/src/test/run-pass/issue-979.rs @@ -3,7 +3,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { *(self.b) += 1; } } diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/run-pass/option-unwrap.rs index d2ae1e02a41d3..3294f76c25ecf 100644 --- a/src/test/run-pass/option-unwrap.rs +++ b/src/test/run-pass/option-unwrap.rs @@ -4,7 +4,7 @@ struct dtor { } impl dtor : Drop { - fn finalize() { + fn finalize(&self) { // abuse access to shared mutable state to write this code *self.x -= 1; } diff --git a/src/test/run-pass/pipe-presentation-examples.rs b/src/test/run-pass/pipe-presentation-examples.rs index 06c1734a28f73..e29eb9787c0a2 100644 --- a/src/test/run-pass/pipe-presentation-examples.rs +++ b/src/test/run-pass/pipe-presentation-examples.rs @@ -69,7 +69,7 @@ struct Buffer { } impl Buffer : Drop { - fn finalize() {} + fn finalize(&self) {} } proto! double_buffer ( 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 522392d99add9..8a6a9a48a0407 100644 --- a/src/test/run-pass/resource-assign-is-not-copy.rs +++ b/src/test/run-pass/resource-assign-is-not-copy.rs @@ -3,7 +3,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { *(self.i) += 1; } } diff --git a/src/test/run-pass/resource-cycle.rs b/src/test/run-pass/resource-cycle.rs index 6b637e668edc4..e9ec45d97e98d 100644 --- a/src/test/run-pass/resource-cycle.rs +++ b/src/test/run-pass/resource-cycle.rs @@ -5,7 +5,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { unsafe { debug!("r's dtor: self = %x, self.v = %x, self.v's value = %x", cast::reinterpret_cast::<*r, uint>(&ptr::addr_of(&self)), diff --git a/src/test/run-pass/resource-cycle2.rs b/src/test/run-pass/resource-cycle2.rs index ec04699ae986b..00225ee1190f2 100644 --- a/src/test/run-pass/resource-cycle2.rs +++ b/src/test/run-pass/resource-cycle2.rs @@ -11,7 +11,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { unsafe { let v2: ~int = cast::reinterpret_cast(&self.v.c); } diff --git a/src/test/run-pass/resource-cycle3.rs b/src/test/run-pass/resource-cycle3.rs index 22b0f1272a84c..62703724337d2 100644 --- a/src/test/run-pass/resource-cycle3.rs +++ b/src/test/run-pass/resource-cycle3.rs @@ -15,7 +15,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { unsafe { let _v2: ~int = cast::reinterpret_cast(&self.v.c); // let _v3: ~int = unsafe::reinterpret_cast(self.x); diff --git a/src/test/run-pass/resource-destruct.rs b/src/test/run-pass/resource-destruct.rs index 92a57004b5074..82023aa99d2d2 100644 --- a/src/test/run-pass/resource-destruct.rs +++ b/src/test/run-pass/resource-destruct.rs @@ -3,7 +3,7 @@ struct shrinky_pointer { } impl shrinky_pointer : Drop { - fn finalize() { + fn finalize(&self) { log(error, ~"Hello!"); **(self.i) -= 1; } } diff --git a/src/test/run-pass/resource-generic.rs b/src/test/run-pass/resource-generic.rs index 476f695e783db..04c4c6672a3c1 100644 --- a/src/test/run-pass/resource-generic.rs +++ b/src/test/run-pass/resource-generic.rs @@ -6,7 +6,7 @@ struct finish { } impl finish : Drop { - fn finalize() { + fn finalize(&self) { 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 b350955bec0c5..b4ffab2782ada 100644 --- a/src/test/run-pass/resource-in-struct.rs +++ b/src/test/run-pass/resource-in-struct.rs @@ -9,7 +9,7 @@ struct close_res { } impl close_res : Drop { - fn finalize() { + fn finalize(&self) { *(self.i) = false; } } diff --git a/src/test/run-pass/send-resource.rs b/src/test/run-pass/send-resource.rs index ebef3f39eea6d..f183f7cc65059 100644 --- a/src/test/run-pass/send-resource.rs +++ b/src/test/run-pass/send-resource.rs @@ -6,7 +6,7 @@ struct test { } impl test : Drop { - fn finalize() {} + fn finalize(&self) {} } fn test(f: int) -> test { diff --git a/src/test/run-pass/struct-literal-dtor.rs b/src/test/run-pass/struct-literal-dtor.rs index 6bc605f2a0865..27fdbcc07b9fe 100644 --- a/src/test/run-pass/struct-literal-dtor.rs +++ b/src/test/run-pass/struct-literal-dtor.rs @@ -3,7 +3,7 @@ struct foo { } impl foo : Drop { - fn finalize() { + fn finalize(&self) { error!("%s", self.x); } } diff --git a/src/test/run-pass/task-compare.rs b/src/test/run-pass/task-compare.rs index 2996ce8ff73cb..552f1a13c1cb8 100644 --- a/src/test/run-pass/task-compare.rs +++ b/src/test/run-pass/task-compare.rs @@ -12,7 +12,7 @@ struct notify { } impl notify : Drop { - fn finalize() { + fn finalize(&self) { error!("notify: task=%? v=%x unwinding=%b b=%b", task::get_task(), ptr::addr_of(&(*(self.v))) as uint, diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs index fbbdaea2c943a..68b09166b661d 100644 --- a/src/test/run-pass/task-killjoin-rsrc.rs +++ b/src/test/run-pass/task-killjoin-rsrc.rs @@ -10,7 +10,7 @@ struct notify { } impl notify : Drop { - fn finalize() { + fn finalize(&self) { error!("notify: task=%? v=%x unwinding=%b b=%b", task::get_task(), ptr::addr_of(&(*(self.v))) as uint, diff --git a/src/test/run-pass/type-param-constraints.rs b/src/test/run-pass/type-param-constraints.rs index 3016778dea35c..a668105ab5ac9 100644 --- a/src/test/run-pass/type-param-constraints.rs +++ b/src/test/run-pass/type-param-constraints.rs @@ -10,7 +10,7 @@ struct r { } impl r : Drop { - fn finalize() {} + fn finalize(&self) {} } fn r(i:int) -> r { diff --git a/src/test/run-pass/unique-pinned-nocopy-2.rs b/src/test/run-pass/unique-pinned-nocopy-2.rs index ad7e8d20400ea..fb5f45416342d 100644 --- a/src/test/run-pass/unique-pinned-nocopy-2.rs +++ b/src/test/run-pass/unique-pinned-nocopy-2.rs @@ -3,7 +3,7 @@ struct r { } impl r : Drop { - fn finalize() { + fn finalize(&self) { *(self.i) = *(self.i) + 1; } } diff --git a/src/test/run-pass/unwind-resource.rs b/src/test/run-pass/unwind-resource.rs index 00ab35e9e6181..e49a5ddc19b87 100644 --- a/src/test/run-pass/unwind-resource.rs +++ b/src/test/run-pass/unwind-resource.rs @@ -6,7 +6,7 @@ struct complainer { } impl complainer : Drop { - fn finalize() { + fn finalize(&self) { error!("About to send!"); comm::send(self.c, true); error!("Sent!"); diff --git a/src/test/run-pass/unwind-resource2.rs b/src/test/run-pass/unwind-resource2.rs index 7a159464aabf3..8458dcfb9ea20 100644 --- a/src/test/run-pass/unwind-resource2.rs +++ b/src/test/run-pass/unwind-resource2.rs @@ -6,7 +6,7 @@ struct complainer { } impl complainer : Drop { - fn finalize() {} + fn finalize(&self) {} } fn complainer(c: @int) -> complainer { diff --git a/src/test/run-pass/vec-slice-drop.rs b/src/test/run-pass/vec-slice-drop.rs index e057117c4a57c..732075868bffc 100644 --- a/src/test/run-pass/vec-slice-drop.rs +++ b/src/test/run-pass/vec-slice-drop.rs @@ -4,7 +4,7 @@ struct foo { } impl foo : Drop { - fn finalize() { + fn finalize(&self) { *self.x += 1; } } From d2a206d87d5b4b3989a7aa62eb1bed71ca79e2e1 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 28 Nov 2012 17:33:30 -0800 Subject: [PATCH 2/3] librustc: Implement simple explicit self for objects --- src/librustc/middle/astencode.rs | 8 +++ src/librustc/middle/trans/meth.rs | 65 ++++++++++++++++--- src/librustc/middle/trans/reflect.rs | 11 ++-- src/librustc/middle/typeck.rs | 3 + src/librustc/middle/typeck/check/method.rs | 29 +++++++-- .../run-pass/explicit-self-objects-simple.rs | 21 ++++++ 6 files changed, 119 insertions(+), 18 deletions(-) create mode 100644 src/test/run-pass/explicit-self-objects-simple.rs diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 64aaef99ef6b1..63998f03d7930 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -443,6 +443,9 @@ fn serialize_method_map_entry(ecx: @e::encode_ctxt, do ebml_w.emit_field(~"self_arg", 0u) { ebml_w.emit_arg(ecx, mme.self_arg); } + do ebml_w.emit_field(~"explicit_self", 2u) { + mme.explicit_self.serialize(&ebml_w); + } do ebml_w.emit_field(~"origin", 1u) { mme.origin.serialize(&ebml_w); } @@ -456,6 +459,11 @@ impl Reader::Deserializer: read_method_map_entry_helper { self.read_field(~"self_arg", 0u, || { self.read_arg(xcx) }), + explicit_self: + self.read_field(~"explicit_self", 2u, || { + let self_type: ast::self_ty_ = deserialize(&self); + self_type + }), origin: self.read_field(~"origin", 1u, || { let method_origin: method_origin = deserialize(&self); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 616a193a9b43e..aa9f54d8d50e9 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -202,7 +202,12 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id, } } typeck::method_trait(_, off, vstore) => { - trans_trait_callee(bcx, callee_id, off, self, vstore) + trans_trait_callee(bcx, + callee_id, + off, + self, + vstore, + mentry.explicit_self) } typeck::method_self(*) => { fail ~"method_self should have been handled above" @@ -388,7 +393,12 @@ fn trans_monomorphized_callee(bcx: block, } } typeck::vtable_trait(_, _) => { - trans_trait_callee(bcx, callee_id, n_method, base, ty::vstore_box) + trans_trait_callee(bcx, + callee_id, + n_method, + base, + ty::vstore_box, + mentry.explicit_self) } typeck::vtable_param(*) => { fail ~"vtable_param left in monomorphized function's vtable substs"; @@ -490,8 +500,9 @@ fn trans_trait_callee(bcx: block, callee_id: ast::node_id, n_method: uint, self_expr: @ast::expr, - vstore: ty::vstore) - -> Callee + vstore: ty::vstore, + explicit_self: ast::self_ty_) + -> Callee { //! // @@ -507,15 +518,21 @@ fn trans_trait_callee(bcx: block, let self_datum = unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr)); let llpair = self_datum.to_ref_llval(bcx); let callee_ty = node_id_type(bcx, callee_id); - trans_trait_callee_from_llval(bcx, callee_ty, n_method, llpair, vstore) + trans_trait_callee_from_llval(bcx, + callee_ty, + n_method, + llpair, + vstore, + explicit_self) } fn trans_trait_callee_from_llval(bcx: block, callee_ty: ty::t, n_method: uint, llpair: ValueRef, - vstore: ty::vstore) - -> Callee + vstore: ty::vstore, + explicit_self: ast::self_ty_) + -> Callee { //! // @@ -527,6 +544,8 @@ fn trans_trait_callee_from_llval(bcx: block, let mut bcx = bcx; // Load the vtable from the @Trait pair + debug!("(translating trait callee) loading vtable from pair %s", + val_str(bcx.ccx().tn, llpair)); let llvtable = Load(bcx, PointerCast(bcx, GEPi(bcx, llpair, [0u, 0u]), @@ -534,7 +553,8 @@ fn trans_trait_callee_from_llval(bcx: block, // Load the box from the @Trait pair and GEP over the box header if // necessary: - let llself; + let mut llself; + debug!("(translating trait callee) loading second index from pair"); let llbox = Load(bcx, GEPi(bcx, llpair, [0u, 1u])); match vstore { ty::vstore_box | ty::vstore_uniq => { @@ -548,7 +568,32 @@ fn trans_trait_callee_from_llval(bcx: block, } } + // Munge `llself` appropriately for the type of `self` in the method. + match explicit_self { + ast::sty_static => { + bcx.tcx().sess.bug(~"shouldn't see static method here"); + } + ast::sty_by_ref => {} // Nothing to do. + ast::sty_value => { + bcx.tcx().sess.bug(~"methods with by-value self should not be \ + called on objects"); + } + ast::sty_region(_) => { + let llscratch = alloca(bcx, val_ty(llself)); + Store(bcx, llself, llscratch); + llself = llscratch; + } + ast::sty_box(_) => { + // Bump the reference count on the box. + debug!("(translating trait callee) callee type is `%s`", + bcx.ty_to_str(callee_ty)); + bcx = glue::take_ty(bcx, llself, callee_ty); + } + ast::sty_uniq(_) => {} // Nothing to do here. + } + // Load the function from the vtable and cast it to the expected type. + debug!("(translating trait callee) loading method"); let llcallee_ty = type_of::type_of_fn_from_ty(ccx, callee_ty); let mptr = Load(bcx, GEPi(bcx, llvtable, [0u, n_method])); let mptr = PointerCast(bcx, mptr, T_ptr(llcallee_ty)); @@ -631,8 +676,12 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t], make_vtable(ccx, vec::map(*ty::trait_methods(tcx, trt_id), |im| { let fty = ty::subst_tps(tcx, substs, None, ty::mk_fn(tcx, im.fty)); if (*im.tps).len() > 0u || ty::type_has_self(fty) { + debug!("(making impl vtable) method has self or type params: %s", + tcx.sess.str_of(im.ident)); C_null(T_ptr(T_nil())) } else { + debug!("(making impl vtable) adding method to vtable: %s", + tcx.sess.str_of(im.ident)); let mut m_id = method_with_name(ccx, impl_id, im.ident); if has_tps { // If the method is in another crate, need to make an inlined diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 5c4380ffe85f0..02423d27ac183 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -72,9 +72,12 @@ impl reflector { // XXX: Should not be vstore_box! let bcx = callee::trans_call_inner( self.bcx, None, mth_ty, bool_ty, - |bcx| meth::trans_trait_callee_from_llval(bcx, mth_ty, - mth_idx, v, - ty::vstore_box), + |bcx| meth::trans_trait_callee_from_llval(bcx, + mth_ty, + mth_idx, + v, + ty::vstore_box, + ast::sty_by_ref), ArgVals(args), SaveIn(scratch.val), DontAutorefArg); let result = scratch.to_value_llval(bcx); let next_bcx = sub_block(bcx, ~"next"); @@ -307,4 +310,4 @@ fn ast_proto_constant(proto: ast::Proto) -> uint { ast::ProtoBox => 3u, ast::ProtoBorrowed => 4u, } -} \ No newline at end of file +} diff --git a/src/librustc/middle/typeck.rs b/src/librustc/middle/typeck.rs index 421c68fa9a21e..20e3003f5fb4c 100644 --- a/src/librustc/middle/typeck.rs +++ b/src/librustc/middle/typeck.rs @@ -116,6 +116,9 @@ type method_map_entry = { // in the fn type (FIXME #3446) self_arg: ty::arg, + // the type of explicit self on the method + explicit_self: ast::self_ty_, + // method details being invoked origin: method_origin }; diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 78cd677725738..a018025157e3e 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -130,6 +130,7 @@ struct LookupContext { struct Candidate { rcvr_ty: ty::t, rcvr_substs: ty::substs, + explicit_self: ast::self_ty_, // FIXME #3446---these two fields should be easily derived from // origin, yet are not @@ -394,6 +395,7 @@ impl LookupContext { self.inherent_candidates.push(Candidate { rcvr_ty: rcvr_ty, rcvr_substs: rcvr_substs, + explicit_self: method.self_ty, num_method_tps: method.tps.len(), self_mode: get_mode_from_self_type(method.self_ty), origin: method_param({trait_id:trait_id, @@ -450,6 +452,7 @@ impl LookupContext { self.inherent_candidates.push(Candidate { rcvr_ty: rcvr_ty, rcvr_substs: move rcvr_substs, + explicit_self: method.self_ty, num_method_tps: method.tps.len(), self_mode: get_mode_from_self_type(method.self_ty), origin: method_trait(did, index, vstore) @@ -477,6 +480,7 @@ impl LookupContext { self.inherent_candidates.push(Candidate { rcvr_ty: rcvr_ty, rcvr_substs: move rcvr_substs, + explicit_self: method.self_ty, num_method_tps: method.tps.len(), self_mode: get_mode_from_self_type(method.self_ty), origin: method_self(did, index) @@ -528,6 +532,7 @@ impl LookupContext { candidates.push(Candidate { rcvr_ty: impl_ty, rcvr_substs: move impl_substs, + explicit_self: method.self_type, num_method_tps: method.n_tps, self_mode: get_mode_from_self_type(method.self_type), origin: method_static(method.did) @@ -562,6 +567,7 @@ impl LookupContext { candidates.push(Candidate { rcvr_ty: impl_ty, rcvr_substs: move impl_substs, + explicit_self: provided_method_info.method_info.self_type, num_method_tps: provided_method_info.method_info.n_tps, self_mode: get_mode_from_self_type( provided_method_info.method_info.self_type), @@ -724,12 +730,22 @@ impl LookupContext { match self.search_for_method(autoref_ty) { None => {} Some(move mme) => { - self.fcx.write_adjustment( - self.self_expr.id, - @{autoderefs: autoderefs, - autoref: Some({kind: kind, - region: region, - mutbl: *mutbl})}); + match mme.origin { + method_trait(*) => { + // Do not write adjustments; they make no sense + // here since the adjustments are to be performed + // on the self element of the object pair/triple, + // not the object itself. + } + _ => { + self.fcx.write_adjustment( + self.self_expr.id, + @{autoderefs: autoderefs, + autoref: Some({kind: kind, + region: region, + mutbl: *mutbl})}); + } + } return Some(mme); } } @@ -848,6 +864,7 @@ impl LookupContext { self.fcx.write_ty_substs(self.callee_id, fty, all_substs); return {self_arg: {mode: ast::expl(candidate.self_mode), ty: candidate.rcvr_ty}, + explicit_self: candidate.explicit_self, origin: candidate.origin}; } diff --git a/src/test/run-pass/explicit-self-objects-simple.rs b/src/test/run-pass/explicit-self-objects-simple.rs new file mode 100644 index 0000000000000..49e48279dc643 --- /dev/null +++ b/src/test/run-pass/explicit-self-objects-simple.rs @@ -0,0 +1,21 @@ +trait Foo { + fn f(&self); +} + +struct S { + x: int +} + +impl S : Foo { + fn f(&self) { + assert self.x == 3; + } +} + +fn main() { + let x = @S { x: 3 }; + let y = x as @Foo; + y.f(); +} + + From a592939243e1673ba0c4fd19585d2ed58bd0735f Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 29 Nov 2012 10:59:49 -0800 Subject: [PATCH 3/3] librustc: Implement explicit @self and ~self for objects --- src/librustc/middle/trans/meth.rs | 75 +++++++++++++++---- src/librustc/middle/typeck/check/method.rs | 54 ++++++++++--- .../run-pass/explicit-self-objects-box.rs | 24 ++++++ .../run-pass/explicit-self-objects-uniq.rs | 23 ++++++ 4 files changed, 149 insertions(+), 27 deletions(-) create mode 100644 src/test/run-pass/explicit-self-objects-box.rs create mode 100644 src/test/run-pass/explicit-self-objects-uniq.rs diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index aa9f54d8d50e9..792b6e5b79750 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -556,40 +556,85 @@ fn trans_trait_callee_from_llval(bcx: block, let mut llself; debug!("(translating trait callee) loading second index from pair"); let llbox = Load(bcx, GEPi(bcx, llpair, [0u, 1u])); - match vstore { - ty::vstore_box | ty::vstore_uniq => { - llself = GEPi(bcx, llbox, [0u, abi::box_field_body]); - } - ty::vstore_slice(_) => { - llself = llbox; - } - ty::vstore_fixed(*) => { - bcx.tcx().sess.bug(~"vstore_fixed trait"); - } - } // Munge `llself` appropriately for the type of `self` in the method. + let self_mode; match explicit_self { ast::sty_static => { bcx.tcx().sess.bug(~"shouldn't see static method here"); } - ast::sty_by_ref => {} // Nothing to do. + ast::sty_by_ref => { + // We need to pass a pointer to a pointer to the payload. + match vstore { + ty::vstore_box | ty::vstore_uniq => { + llself = GEPi(bcx, llbox, [0u, abi::box_field_body]); + } + ty::vstore_slice(_) => { + llself = llbox; + } + ty::vstore_fixed(*) => { + bcx.tcx().sess.bug(~"vstore_fixed trait"); + } + } + + self_mode = ast::by_ref; + } ast::sty_value => { bcx.tcx().sess.bug(~"methods with by-value self should not be \ called on objects"); } ast::sty_region(_) => { + // As before, we need to pass a pointer to a pointer to the + // payload. + match vstore { + ty::vstore_box | ty::vstore_uniq => { + llself = GEPi(bcx, llbox, [0u, abi::box_field_body]); + } + ty::vstore_slice(_) => { + llself = llbox; + } + ty::vstore_fixed(*) => { + bcx.tcx().sess.bug(~"vstore_fixed trait"); + } + } + let llscratch = alloca(bcx, val_ty(llself)); Store(bcx, llself, llscratch); llself = llscratch; + + self_mode = ast::by_ref; } ast::sty_box(_) => { // Bump the reference count on the box. debug!("(translating trait callee) callee type is `%s`", bcx.ty_to_str(callee_ty)); - bcx = glue::take_ty(bcx, llself, callee_ty); + bcx = glue::take_ty(bcx, llbox, callee_ty); + + // Pass a pointer to the box. + match vstore { + ty::vstore_box => llself = llbox, + _ => bcx.tcx().sess.bug(~"@self receiver with non-@Trait") + } + + let llscratch = alloca(bcx, val_ty(llself)); + Store(bcx, llself, llscratch); + llself = llscratch; + + self_mode = ast::by_ref; + } + ast::sty_uniq(_) => { + // Pass the unique pointer. + match vstore { + ty::vstore_uniq => llself = llbox, + _ => bcx.tcx().sess.bug(~"~self receiver with non-~Trait") + } + + let llscratch = alloca(bcx, val_ty(llself)); + Store(bcx, llself, llscratch); + llself = llscratch; + + self_mode = ast::by_ref; } - ast::sty_uniq(_) => {} // Nothing to do here. } // Load the function from the vtable and cast it to the expected type. @@ -604,7 +649,7 @@ fn trans_trait_callee_from_llval(bcx: block, llfn: mptr, llself: llself, self_ty: ty::mk_opaque_box(bcx.tcx()), - self_mode: ast::by_ref, // XXX: is this bogosity? + self_mode: self_mode, /* XXX: Some(llbox) */ }) }; diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index a018025157e3e..c2aebbb04670d 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -140,6 +140,15 @@ struct Candidate { origin: method_origin, } +/** + * Whether the self type should be transformed according to the form of + * explicit self provided by the method. + */ +enum TransformTypeFlag { + DontTransformType, + TransformType +} + impl LookupContext { fn do_lookup(&self, self_ty: ty::t) -> Option { debug!("do_lookup(self_ty=%s, expr=%s, self_expr=%s)", @@ -390,7 +399,10 @@ impl LookupContext { let (rcvr_ty, rcvr_substs) = self.create_rcvr_ty_and_substs_for_method( - method.self_ty, rcvr_ty, move rcvr_substs); + method.self_ty, + rcvr_ty, + move rcvr_substs, + TransformType); self.inherent_candidates.push(Candidate { rcvr_ty: rcvr_ty, @@ -446,8 +458,10 @@ impl LookupContext { let rcvr_substs = {self_ty: Some(self_ty), ..*substs}; let (rcvr_ty, rcvr_substs) = - self.create_rcvr_ty_and_substs_for_method( - method.self_ty, self_ty, move rcvr_substs); + self.create_rcvr_ty_and_substs_for_method(method.self_ty, + self_ty, + move rcvr_substs, + DontTransformType); self.inherent_candidates.push(Candidate { rcvr_ty: rcvr_ty, @@ -475,7 +489,10 @@ impl LookupContext { let rcvr_substs = { self_ty: Some(self_ty), ..*substs }; let (rcvr_ty, rcvr_substs) = self.create_rcvr_ty_and_substs_for_method( - method.self_ty, self_ty, move rcvr_substs); + method.self_ty, + self_ty, + move rcvr_substs, + TransformType); self.inherent_candidates.push(Candidate { rcvr_ty: rcvr_ty, @@ -527,7 +544,10 @@ impl LookupContext { let (impl_ty, impl_substs) = self.create_rcvr_ty_and_substs_for_method( - method.self_type, impl_ty, move impl_substs); + method.self_type, + impl_ty, + move impl_substs, + TransformType); candidates.push(Candidate { rcvr_ty: impl_ty, @@ -562,7 +582,8 @@ impl LookupContext { self.create_rcvr_ty_and_substs_for_method( provided_method_info.method_info.self_type, self_ty, - dummy_substs); + dummy_substs, + TransformType); candidates.push(Candidate { rcvr_ty: impl_ty, @@ -579,8 +600,9 @@ impl LookupContext { fn create_rcvr_ty_and_substs_for_method(&self, self_decl: ast::self_ty_, self_ty: ty::t, - +self_substs: ty::substs) - -> (ty::t, ty::substs) { + +self_substs: ty::substs, + transform_type: TransformTypeFlag) + -> (ty::t, ty::substs) { // If the self type includes a region (like &self), we need to // ensure that the receiver substitutions have a self region. // If the receiver type does not itself contain borrowed @@ -609,10 +631,18 @@ impl LookupContext { } }; - let rcvr_ty = - transform_self_type_for_method( - self.tcx(), rcvr_substs.self_r, - self_ty, self_decl); + let rcvr_ty; + match transform_type { + TransformType => { + rcvr_ty = transform_self_type_for_method(self.tcx(), + rcvr_substs.self_r, + self_ty, + self_decl); + } + DontTransformType => { + rcvr_ty = self_ty; + } + } (rcvr_ty, rcvr_substs) } diff --git a/src/test/run-pass/explicit-self-objects-box.rs b/src/test/run-pass/explicit-self-objects-box.rs new file mode 100644 index 0000000000000..6ada89b1e6714 --- /dev/null +++ b/src/test/run-pass/explicit-self-objects-box.rs @@ -0,0 +1,24 @@ +trait Foo { + fn f(@self); +} + +struct S { + x: int +} + +impl S : Foo { + fn f(@self) { + assert self.x == 3; + } +} + +fn main() { + let x = @S { x: 3 }; + let y = x as @Foo; + y.f(); + y.f(); + y.f(); + y.f(); +} + + diff --git a/src/test/run-pass/explicit-self-objects-uniq.rs b/src/test/run-pass/explicit-self-objects-uniq.rs new file mode 100644 index 0000000000000..26b2f4b830917 --- /dev/null +++ b/src/test/run-pass/explicit-self-objects-uniq.rs @@ -0,0 +1,23 @@ +trait Foo { + fn f(~self); +} + +struct S { + x: int +} + +impl S : Foo { + fn f(~self) { + assert self.x == 3; + } +} + +fn main() { + let x = ~S { x: 3 }; + let y = x as ~Foo; + y.f(); + y.f(); + y.f(); +} + +