From b808cfbb74a6d9ee01d22a1754f8ddfe3022b1e5 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Sun, 2 Sep 2012 16:50:00 -0700 Subject: rustc: Don't translate the expression twice when adapting a borrowed method receiver. Closes #3357. Adds a test case. I had to stare at this one for a bit. --- src/rustc/middle/trans/base.rs | 5 ++++- src/rustc/middle/typeck/check/method.rs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/rustc') diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index cb49daa4814..49d626cce96 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -3151,6 +3151,9 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr, // routine consults this table and performs these adaptations. It returns a // new location for the borrowed result as well as a new type for the argument // that reflects the borrowed value and not the original. +// +// NB: "e" has already been translated; do not translate it again. If you do, +// this will cause problems with autoderef and method receivers (bug #3357). fn adapt_borrowed_value(lv: lval_result, e: @ast::expr, e_ty: ty::t) -> {lv: lval_result, @@ -3200,7 +3203,7 @@ fn adapt_borrowed_value(lv: lval_result, _ => { // Just take a reference. This is basically like trans_addr_of. - let mut {bcx, val, kind} = trans_temp_lval(bcx, e); + let mut {bcx, val, kind} = lv; let is_immediate = ty::type_is_immediate(e_ty); if (kind == lv_temporary && is_immediate) || kind == lv_owned_imm { val = do_spill(bcx, val, e_ty); diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs index 93bab0f84e5..b3dc032f0bf 100644 --- a/src/rustc/middle/typeck/check/method.rs +++ b/src/rustc/middle/typeck/check/method.rs @@ -183,6 +183,7 @@ struct lookup { match ty::deref(self.tcx(), self.self_ty, false) { None => break, Some(mt) => { + debug!("(checking method) ... autodereffing"); self.self_ty = mt.ty; self.derefs += 1u; } -- cgit 1.4.1-3-g733a5