diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-11-27 14:12:33 -0800 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-11-28 11:01:14 -0800 |
| commit | ca6970a65ebdc153d53e9b6c2ccb224ee705ac94 (patch) | |
| tree | 883d7bd463736587a47d4d86a559180960521c1c | |
| parent | 082a88e42cdefce78a8f1f869971bbabd74ebca2 (diff) | |
| download | rust-ca6970a65ebdc153d53e9b6c2ccb224ee705ac94.tar.gz rust-ca6970a65ebdc153d53e9b6c2ccb224ee705ac94.zip | |
librustc: Make overloaded operators with explicit self translate correctly
| -rw-r--r-- | src/librustc/middle/borrowck.rs | 10 | ||||
| -rw-r--r-- | src/librustc/middle/borrowck/check_loans.rs | 7 | ||||
| -rw-r--r-- | src/librustc/middle/mem_categorization.rs | 23 | ||||
| -rw-r--r-- | src/librustc/middle/trans/expr.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/operator-overloading-explicit-self.rs | 16 |
5 files changed, 56 insertions, 2 deletions
diff --git a/src/librustc/middle/borrowck.rs b/src/librustc/middle/borrowck.rs index 25e184c2c02..5745d2e84bf 100644 --- a/src/librustc/middle/borrowck.rs +++ b/src/librustc/middle/borrowck.rs @@ -513,6 +513,16 @@ impl borrowck_ctxt { cat_expr(self.tcx, self.method_map, expr) } + fn cat_expr_unadjusted(expr: @ast::expr) -> cmt { + cat_expr_unadjusted(self.tcx, self.method_map, expr) + } + + fn cat_expr_autoderefd(expr: @ast::expr, + adj: @ty::AutoAdjustment) + -> cmt { + cat_expr_autoderefd(self.tcx, self.method_map, expr, adj) + } + fn cat_def(id: ast::node_id, span: span, ty: ty::t, diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 366dd7e7e85..03bd403bf46 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -362,7 +362,12 @@ impl check_loan_ctxt { } fn check_assignment(at: assignment_type, ex: @ast::expr) { - let cmt = self.bccx.cat_expr(ex); + // We don't use cat_expr() here because we don't want to treat + // auto-ref'd parameters in overloaded operators as rvalues. + let cmt = match self.bccx.tcx.adjustments.find(ex.id) { + None => self.bccx.cat_expr_unadjusted(ex), + Some(adj) => self.bccx.cat_expr_autoderefd(ex, adj) + }; debug!("check_assignment(cmt=%s)", self.bccx.cmt_to_repr(cmt)); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index ebc06435c64..9eafec930f6 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -573,6 +573,29 @@ fn cat_expr( return mcx.cat_expr(expr); } +fn cat_expr_unadjusted( + tcx: ty::ctxt, + method_map: typeck::method_map, + expr: @ast::expr) -> cmt { + + let mcx = &mem_categorization_ctxt { + tcx: tcx, method_map: method_map + }; + return mcx.cat_expr_unadjusted(expr); +} + +fn cat_expr_autoderefd( + tcx: ty::ctxt, + method_map: typeck::method_map, + expr: @ast::expr, + adj: @ty::AutoAdjustment) -> cmt { + + let mcx = &mem_categorization_ctxt { + tcx: tcx, method_map: method_map + }; + return mcx.cat_expr_autoderefd(expr, adj); +} + fn cat_def( tcx: ty::ctxt, method_map: typeck::method_map, diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 2e4d95acdfb..4927d2773c1 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -1572,7 +1572,7 @@ fn trans_assign_op(bcx: block, debug!("trans_assign_op(expr=%s)", bcx.expr_to_str(expr)); // Evaluate LHS (destination), which should be an lvalue - let dst_datum = unpack_datum!(bcx, trans_lvalue(bcx, dst)); + let dst_datum = unpack_datum!(bcx, trans_lvalue_unadjusted(bcx, dst)); // A user-defined operator method if bcx.ccx().maps.method_map.find(expr.id).is_some() { diff --git a/src/test/run-pass/operator-overloading-explicit-self.rs b/src/test/run-pass/operator-overloading-explicit-self.rs new file mode 100644 index 00000000000..3b198078cf8 --- /dev/null +++ b/src/test/run-pass/operator-overloading-explicit-self.rs @@ -0,0 +1,16 @@ +struct S { + x: int +} + +impl S { + pure fn add(&self, other: &S) -> S { + S { x: self.x + other.x } + } +} + +fn main() { + let mut s = S { x: 1 }; + s += S { x: 2 }; + assert s.x == 3; +} + |
