From 7024a9d5298a6ead78cfead653b3697a40a1b8b7 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Wed, 18 Sep 2013 06:03:22 +0200 Subject: [PATCH 1/9] std::borrow: Use raw pointer comparison for `ref_eq` Compare as `*T` in `ref_eq` instead of casting to uint, to match what std::ptr does. --- src/libstd/borrow.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/libstd/borrow.rs b/src/libstd/borrow.rs index 6c3d4c5f1fbea..0626b3fc6183c 100644 --- a/src/libstd/borrow.rs +++ b/src/libstd/borrow.rs @@ -22,7 +22,7 @@ pub fn to_uint(thing: &T) -> uint { /// Determine if two borrowed pointers point to the same thing. #[inline] pub fn ref_eq<'a, 'b, T>(thing: &'a T, other: &'b T) -> bool { - to_uint(thing) == to_uint(other) + (thing as *T) == (other as *T) } // Equality for region pointers @@ -70,3 +70,17 @@ impl<'self, T: TotalEq> TotalEq for &'self T { #[inline] fn equals(&self, other: & &'self T) -> bool { (**self).equals(*other) } } + +#[cfg(test)] +mod tests { + use super::ref_eq; + + #[test] + fn test_ref_eq() { + let x = 1; + let y = 1; + + assert!(ref_eq(&x, &x)); + assert!(!ref_eq(&x, &y)); + } +} From 47576313695170013cfe07d57e81c2e879a14c14 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Wed, 18 Sep 2013 07:21:57 -0400 Subject: [PATCH 2/9] Remove and replace cond! Closes #9282. --- src/libextra/num/bigint.rs | 4 +-- src/libstd/char.rs | 24 +++++++-------- src/libstd/num/f32.rs | 36 +++++++++++----------- src/libstd/num/f64.rs | 36 +++++++++++----------- src/libstd/num/uint_macros.rs | 10 +++--- src/libsyntax/ext/expand.rs | 36 ---------------------- src/test/run-pass/cond-macro-no-default.rs | 23 -------------- src/test/run-pass/cond-macro.rs | 23 -------------- 8 files changed, 55 insertions(+), 137 deletions(-) delete mode 100644 src/test/run-pass/cond-macro-no-default.rs delete mode 100644 src/test/run-pass/cond-macro.rs diff --git a/src/libextra/num/bigint.rs b/src/libextra/num/bigint.rs index 039694f58810b..936efed94e474 100644 --- a/src/libextra/num/bigint.rs +++ b/src/libextra/num/bigint.rs @@ -115,8 +115,8 @@ impl TotalOrd for BigUint { if s_len > o_len { return Greater; } for (&self_i, &other_i) in self.data.rev_iter().zip(other.data.rev_iter()) { - cond!((self_i < other_i) { return Less; } - (self_i > other_i) { return Greater; }) + if self_i < other_i { return Less; } + if self_i > other_i { return Greater; } } return Equal; } diff --git a/src/libstd/char.rs b/src/libstd/char.rs index 911d883f88ac9..431fc27a202d3 100644 --- a/src/libstd/char.rs +++ b/src/libstd/char.rs @@ -281,11 +281,11 @@ pub fn escape_unicode(c: char, f: &fn(char)) { // avoid calling str::to_str_radix because we don't really need to allocate // here. f('\\'); - let pad = cond!( - (c <= '\xff') { f('x'); 2 } - (c <= '\uffff') { f('u'); 4 } - _ { f('U'); 8 } - ); + let pad = match () { + _ if c <= '\xff' => { f('x'); 2 } + _ if c <= '\uffff' => { f('u'); 4 } + _ => { f('U'); 8 } + }; for offset in range_step::(4 * (pad - 1), -1, -4) { unsafe { match ((c as i32) >> offset) & 0xf { @@ -329,13 +329,13 @@ pub fn len_utf8_bytes(c: char) -> uint { static MAX_FOUR_B: uint = 2097152u; let code = c as uint; - cond!( - (code < MAX_ONE_B) { 1u } - (code < MAX_TWO_B) { 2u } - (code < MAX_THREE_B) { 3u } - (code < MAX_FOUR_B) { 4u } - _ { fail!("invalid character!") } - ) + match () { + _ if code < MAX_ONE_B => 1u, + _ if code < MAX_TWO_B => 2u, + _ if code < MAX_THREE_B => 3u, + _ if code < MAX_FOUR_B => 4u, + _ => fail!("invalid character!"), + } } impl ToStr for char { diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 0addcce3eb608..c2babdf92db03 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -206,35 +206,35 @@ impl Orderable for f32 { /// Returns `NaN` if either of the numbers are `NaN`. #[inline] fn min(&self, other: &f32) -> f32 { - cond!( - (self.is_NaN()) { *self } - (other.is_NaN()) { *other } - (*self < *other) { *self } - _ { *other } - ) + match () { + _ if self.is_NaN() => *self, + _ if other.is_NaN() => *other, + _ if *self < *other => *self, + _ => *other, + } } /// Returns `NaN` if either of the numbers are `NaN`. #[inline] fn max(&self, other: &f32) -> f32 { - cond!( - (self.is_NaN()) { *self } - (other.is_NaN()) { *other } - (*self > *other) { *self } - _ { *other } - ) + match () { + _ if self.is_NaN() => *self, + _ if other.is_NaN() => *other, + _ if *self > *other => *self, + _ => *other, + } } /// Returns the number constrained within the range `mn <= self <= mx`. /// If any of the numbers are `NaN` then `NaN` is returned. #[inline] fn clamp(&self, mn: &f32, mx: &f32) -> f32 { - cond!( - (self.is_NaN()) { *self } - (!(*self <= *mx)) { *mx } - (!(*self >= *mn)) { *mn } - _ { *self } - ) + match () { + _ if self.is_NaN() => *self, + _ if !(*self <= *mx) => *mx, + _ if !(*self >= *mn) => *mn, + _ => *self, + } } } diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs index b0675278238e4..5b2f3ac119b41 100644 --- a/src/libstd/num/f64.rs +++ b/src/libstd/num/f64.rs @@ -229,35 +229,35 @@ impl Orderable for f64 { /// Returns `NaN` if either of the numbers are `NaN`. #[inline] fn min(&self, other: &f64) -> f64 { - cond!( - (self.is_NaN()) { *self } - (other.is_NaN()) { *other } - (*self < *other) { *self } - _ { *other } - ) + match () { + _ if self.is_NaN() => *self, + _ if other.is_NaN() => *other, + _ if *self < *other => *self, + _ => *other, + } } /// Returns `NaN` if either of the numbers are `NaN`. #[inline] fn max(&self, other: &f64) -> f64 { - cond!( - (self.is_NaN()) { *self } - (other.is_NaN()) { *other } - (*self > *other) { *self } - _ { *other } - ) + match () { + _ if self.is_NaN() => *self, + _ if other.is_NaN() => *other, + _ if *self > *other => *self, + _ => *other, + } } /// Returns the number constrained within the range `mn <= self <= mx`. /// If any of the numbers are `NaN` then `NaN` is returned. #[inline] fn clamp(&self, mn: &f64, mx: &f64) -> f64 { - cond!( - (self.is_NaN()) { *self } - (!(*self <= *mx)) { *mx } - (!(*self >= *mn)) { *mn } - _ { *self } - ) + match () { + _ if self.is_NaN() => *self, + _ if !(*self <= *mx) => *mx, + _ if !(*self >= *mn) => *mn, + _ => *self, + } } } diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index 0a9c912a6e2ac..7cd1be7ab7406 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -70,11 +70,11 @@ impl Orderable for $T { /// Returns the number constrained within the range `mn <= self <= mx`. #[inline] fn clamp(&self, mn: &$T, mx: &$T) -> $T { - cond!( - (*self > *mx) { *mx } - (*self < *mn) { *mn } - _ { *self } - ) + match () { + _ if (*self > *mx) => *mx, + _ if (*self < *mn) => *mn, + _ => *self, + } } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index ac094c27a8119..5163642e484b8 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -898,42 +898,6 @@ pub fn std_macros() -> @str { } ) - // - // A scheme-style conditional that helps to improve code clarity in some instances when - // the `if`, `else if`, and `else` keywords obscure predicates undesirably. - // - // # Example - // - // ~~~ - // let clamped = - // if x > mx { mx } - // else if x < mn { mn } - // else { x }; - // ~~~ - // - // Using `cond!`, the above could be written as: - // - // ~~~ - // let clamped = cond!( - // (x > mx) { mx } - // (x < mn) { mn } - // _ { x } - // ); - // ~~~ - // - // The optional default case is denoted by `_`. - // - macro_rules! cond ( - ( $(($pred:expr) $body:block)+ _ $default:block ) => ( - $(if $pred $body else)+ - $default - ); - // for if the default case was ommitted - ( $(($pred:expr) $body:block)+ ) => ( - $(if $pred $body)else+ - ); - ) - // NOTE(acrichto): start removing this after the next snapshot macro_rules! printf ( ($arg:expr) => ( diff --git a/src/test/run-pass/cond-macro-no-default.rs b/src/test/run-pass/cond-macro-no-default.rs deleted file mode 100644 index 8bd1a772e55ed..0000000000000 --- a/src/test/run-pass/cond-macro-no-default.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 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 clamp(x: T, mn: T, mx: T) -> T { - cond!( - (x > mx) { return mx; } - (x < mn) { return mn; } - ) - return x; -} - -fn main() { - assert_eq!(clamp(1, 2, 4), 2); - assert_eq!(clamp(8, 2, 4), 4); - assert_eq!(clamp(3, 2, 4), 3); -} diff --git a/src/test/run-pass/cond-macro.rs b/src/test/run-pass/cond-macro.rs deleted file mode 100644 index 61a51b6726114..0000000000000 --- a/src/test/run-pass/cond-macro.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2013 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 clamp(x: T, mn: T, mx: T) -> T { - cond!( - (x > mx) { mx } - (x < mn) { mn } - _ { x } - ) -} - -fn main() { - assert_eq!(clamp(1, 2, 4), 2); - assert_eq!(clamp(8, 2, 4), 4); - assert_eq!(clamp(3, 2, 4), 3); -} From 82ce5d0dd0a365b5eb63508586c4d82ac5fd57fa Mon Sep 17 00:00:00 2001 From: "U-NOV2010\\eugals" Date: Tue, 17 Sep 2013 13:33:36 +0400 Subject: [PATCH 3/9] optimized trans_to_datum::auto_borrow_obj code generation in case some trivial cases where simple copying can be applied --- src/librustc/middle/trans/expr.rs | 40 ++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 0a55786975832..99ea455941c5b 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -313,6 +313,37 @@ pub fn trans_to_datum(bcx: @mut Block, expr: @ast::Expr) -> DatumBlock { let target_obj_ty = expr_ty_adjusted(bcx, expr); debug!("auto_borrow_obj(target=%s)", target_obj_ty.repr(tcx)); + + // Extract source store information + let (source_store, source_mutbl) = match ty::get(source_datum.ty).sty { + ty::ty_trait(_, _, s, m, _) => (s, m), + _ => { + bcx.sess().span_bug( + expr.span, + fmt!("auto_borrow_trait_obj expected a trait, found %s", + source_datum.ty.repr(bcx.tcx()))); + } + }; + + // check if any borrowing is really needed or we could reuse the source_datum instead + match ty::get(target_obj_ty).sty { + ty::ty_trait(_, _, ty::RegionTraitStore(target_scope), target_mutbl, _) => { + if target_mutbl == ast::MutImmutable && target_mutbl == source_mutbl { + match source_store { + ty::RegionTraitStore(source_scope) => { + if tcx.region_maps.is_subregion_of(target_scope, source_scope) { + return DatumBlock { bcx: bcx, datum: source_datum }; + } + }, + _ => {} + + }; + } + }, + _ => {} + } + + let scratch = scratch_datum(bcx, target_obj_ty, "__auto_borrow_obj", false); @@ -331,15 +362,6 @@ pub fn trans_to_datum(bcx: @mut Block, expr: @ast::Expr) -> DatumBlock { // ~T, or &T, depending on source_obj_ty. let source_data_ptr = GEPi(bcx, source_llval, [0u, abi::trt_field_box]); let source_data = Load(bcx, source_data_ptr); // always a ptr - let (source_store, source_mutbl) = match ty::get(source_datum.ty).sty { - ty::ty_trait(_, _, s, m, _) => (s, m), - _ => { - bcx.sess().span_bug( - expr.span, - fmt!("auto_borrow_trait_obj expected a trait, found %s", - source_datum.ty.repr(bcx.tcx()))); - } - }; let target_data = match source_store { ty::BoxTraitStore(*) => { // For deref of @T or @mut T, create a dummy datum and From f96edfde7e413340a1786790e2f137d003d9a785 Mon Sep 17 00:00:00 2001 From: "U-NOV2010\\eugals" Date: Tue, 17 Sep 2013 13:36:47 +0400 Subject: [PATCH 4/9] minor Type::opaque_trait code cleanup --- src/librustc/middle/trans/type_.rs | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 8b221a89c36bc..0954302ba81f4 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -278,23 +278,12 @@ impl Type { pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type { let tydesc_ptr = ctx.tydesc_type.ptr_to(); - match store { - ty::BoxTraitStore => { - Type::struct_( - [ tydesc_ptr, Type::opaque_box(ctx).ptr_to() ], - false) - } - ty::UniqTraitStore => { - Type::struct_( - [ tydesc_ptr, Type::unique(ctx, &Type::i8()).ptr_to()], - false) - } - ty::RegionTraitStore(*) => { - Type::struct_( - [ tydesc_ptr, Type::i8().ptr_to() ], - false) - } - } + let box_ty = match store { + ty::BoxTraitStore => Type::opaque_box(ctx), + ty::UniqTraitStore => Type::unique(ctx, &Type::i8()), + ty::RegionTraitStore(*) => Type::i8() + }; + Type::struct_([tydesc_ptr, box_ty.ptr_to()], false) } pub fn kind(&self) -> TypeKind { From 7ccd71f00b0da629bde416bf4f36cf56c7f962db Mon Sep 17 00:00:00 2001 From: "U-NOV2010\\eugals" Date: Wed, 18 Sep 2013 16:55:39 +0400 Subject: [PATCH 5/9] will not copy trait_callee on stack if it's source expr is a plain borrowed ref --- src/librustc/middle/trans/expr.rs | 1 - src/librustc/middle/trans/meth.rs | 19 ++++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 99ea455941c5b..01702e749a356 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -343,7 +343,6 @@ pub fn trans_to_datum(bcx: @mut Block, expr: @ast::Expr) -> DatumBlock { _ => {} } - let scratch = scratch_datum(bcx, target_obj_ty, "__auto_borrow_obj", false); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 06d88f66323fe..934dfabbb4de4 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -434,13 +434,22 @@ pub fn trans_trait_callee(bcx: @mut Block, let _icx = push_ctxt("impl::trans_trait_callee"); let mut bcx = bcx; + // make a local copy for trait if needed let self_ty = expr_ty_adjusted(bcx, self_expr); - let self_scratch = scratch_datum(bcx, self_ty, "__trait_callee", false); - bcx = expr::trans_into(bcx, self_expr, expr::SaveIn(self_scratch.val)); + let self_scratch = match ty::get(self_ty).sty { + ty::ty_trait(_, _, ty::RegionTraitStore(*), _, _) => { + unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr)) + } + _ => { + let d = scratch_datum(bcx, self_ty, "__trait_callee", false); + bcx = expr::trans_into(bcx, self_expr, expr::SaveIn(d.val)); + // Arrange a temporary cleanup for the object in case something + // should go wrong before the method is actually *invoked*. + d.add_clean(bcx); + d + } + }; - // Arrange a temporary cleanup for the object in case something - // should go wrong before the method is actually *invoked*. - self_scratch.add_clean(bcx); let callee_ty = node_id_type(bcx, callee_id); trans_trait_callee_from_llval(bcx, From 2927ab13df9436ae2042866885ea0b9d29cdcedc Mon Sep 17 00:00:00 2001 From: "U-NOV2010\\eugals" Date: Tue, 17 Sep 2013 13:33:36 +0400 Subject: [PATCH 6/9] optimized trans_to_datum::auto_borrow_obj code generation in case some trivial cases where simple copying can be applied --- src/librustc/middle/trans/expr.rs | 40 ++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 0a55786975832..99ea455941c5b 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -313,6 +313,37 @@ pub fn trans_to_datum(bcx: @mut Block, expr: @ast::Expr) -> DatumBlock { let target_obj_ty = expr_ty_adjusted(bcx, expr); debug!("auto_borrow_obj(target=%s)", target_obj_ty.repr(tcx)); + + // Extract source store information + let (source_store, source_mutbl) = match ty::get(source_datum.ty).sty { + ty::ty_trait(_, _, s, m, _) => (s, m), + _ => { + bcx.sess().span_bug( + expr.span, + fmt!("auto_borrow_trait_obj expected a trait, found %s", + source_datum.ty.repr(bcx.tcx()))); + } + }; + + // check if any borrowing is really needed or we could reuse the source_datum instead + match ty::get(target_obj_ty).sty { + ty::ty_trait(_, _, ty::RegionTraitStore(target_scope), target_mutbl, _) => { + if target_mutbl == ast::MutImmutable && target_mutbl == source_mutbl { + match source_store { + ty::RegionTraitStore(source_scope) => { + if tcx.region_maps.is_subregion_of(target_scope, source_scope) { + return DatumBlock { bcx: bcx, datum: source_datum }; + } + }, + _ => {} + + }; + } + }, + _ => {} + } + + let scratch = scratch_datum(bcx, target_obj_ty, "__auto_borrow_obj", false); @@ -331,15 +362,6 @@ pub fn trans_to_datum(bcx: @mut Block, expr: @ast::Expr) -> DatumBlock { // ~T, or &T, depending on source_obj_ty. let source_data_ptr = GEPi(bcx, source_llval, [0u, abi::trt_field_box]); let source_data = Load(bcx, source_data_ptr); // always a ptr - let (source_store, source_mutbl) = match ty::get(source_datum.ty).sty { - ty::ty_trait(_, _, s, m, _) => (s, m), - _ => { - bcx.sess().span_bug( - expr.span, - fmt!("auto_borrow_trait_obj expected a trait, found %s", - source_datum.ty.repr(bcx.tcx()))); - } - }; let target_data = match source_store { ty::BoxTraitStore(*) => { // For deref of @T or @mut T, create a dummy datum and From dfa3f5fa8d20bc970843c88bc5cbca398a26ce7c Mon Sep 17 00:00:00 2001 From: "U-NOV2010\\eugals" Date: Tue, 17 Sep 2013 13:36:47 +0400 Subject: [PATCH 7/9] minor Type::opaque_trait code cleanup --- src/librustc/middle/trans/type_.rs | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 8b221a89c36bc..0954302ba81f4 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -278,23 +278,12 @@ impl Type { pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type { let tydesc_ptr = ctx.tydesc_type.ptr_to(); - match store { - ty::BoxTraitStore => { - Type::struct_( - [ tydesc_ptr, Type::opaque_box(ctx).ptr_to() ], - false) - } - ty::UniqTraitStore => { - Type::struct_( - [ tydesc_ptr, Type::unique(ctx, &Type::i8()).ptr_to()], - false) - } - ty::RegionTraitStore(*) => { - Type::struct_( - [ tydesc_ptr, Type::i8().ptr_to() ], - false) - } - } + let box_ty = match store { + ty::BoxTraitStore => Type::opaque_box(ctx), + ty::UniqTraitStore => Type::unique(ctx, &Type::i8()), + ty::RegionTraitStore(*) => Type::i8() + }; + Type::struct_([tydesc_ptr, box_ty.ptr_to()], false) } pub fn kind(&self) -> TypeKind { From 0c3b6ad6b8c196b996e366aaf864db9e23767f0f Mon Sep 17 00:00:00 2001 From: "U-NOV2010\\eugals" Date: Wed, 18 Sep 2013 16:55:39 +0400 Subject: [PATCH 8/9] will not copy trait_callee on stack if it's source expr is a plain borrowed ref --- src/librustc/middle/trans/expr.rs | 1 - src/librustc/middle/trans/meth.rs | 19 ++++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 99ea455941c5b..01702e749a356 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -343,7 +343,6 @@ pub fn trans_to_datum(bcx: @mut Block, expr: @ast::Expr) -> DatumBlock { _ => {} } - let scratch = scratch_datum(bcx, target_obj_ty, "__auto_borrow_obj", false); diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 06d88f66323fe..934dfabbb4de4 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -434,13 +434,22 @@ pub fn trans_trait_callee(bcx: @mut Block, let _icx = push_ctxt("impl::trans_trait_callee"); let mut bcx = bcx; + // make a local copy for trait if needed let self_ty = expr_ty_adjusted(bcx, self_expr); - let self_scratch = scratch_datum(bcx, self_ty, "__trait_callee", false); - bcx = expr::trans_into(bcx, self_expr, expr::SaveIn(self_scratch.val)); + let self_scratch = match ty::get(self_ty).sty { + ty::ty_trait(_, _, ty::RegionTraitStore(*), _, _) => { + unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr)) + } + _ => { + let d = scratch_datum(bcx, self_ty, "__trait_callee", false); + bcx = expr::trans_into(bcx, self_expr, expr::SaveIn(d.val)); + // Arrange a temporary cleanup for the object in case something + // should go wrong before the method is actually *invoked*. + d.add_clean(bcx); + d + } + }; - // Arrange a temporary cleanup for the object in case something - // should go wrong before the method is actually *invoked*. - self_scratch.add_clean(bcx); let callee_ty = node_id_type(bcx, callee_id); trans_trait_callee_from_llval(bcx, From fadc6cc4b006d0eb6250afb899f10f8b67ad546d Mon Sep 17 00:00:00 2001 From: Evgeny Sologubov Date: Thu, 19 Sep 2013 21:23:04 +0400 Subject: [PATCH 9/9] pacified test/run-pass/core-run-destroy on Win7x64 --- src/test/run-pass/core-run-destroy.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/run-pass/core-run-destroy.rs b/src/test/run-pass/core-run-destroy.rs index 1c3e83f3cab24..789295edaaa07 100644 --- a/src/test/run-pass/core-run-destroy.rs +++ b/src/test/run-pass/core-run-destroy.rs @@ -55,6 +55,7 @@ fn test_destroy_actually_kills(force: bool) { #[cfg(windows)] fn process_exists(pid: libc::pid_t) -> bool { + #[fixed_stack_segment]; use std::libc::types::os::arch::extra::DWORD; use std::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};