Skip to content

Commit ca6970a

Browse files
committed
librustc: Make overloaded operators with explicit self translate correctly
1 parent 082a88e commit ca6970a

File tree

5 files changed

+56
-2
lines changed

5 files changed

+56
-2
lines changed

src/librustc/middle/borrowck.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,16 @@ impl borrowck_ctxt {
513513
cat_expr(self.tcx, self.method_map, expr)
514514
}
515515

516+
fn cat_expr_unadjusted(expr: @ast::expr) -> cmt {
517+
cat_expr_unadjusted(self.tcx, self.method_map, expr)
518+
}
519+
520+
fn cat_expr_autoderefd(expr: @ast::expr,
521+
adj: @ty::AutoAdjustment)
522+
-> cmt {
523+
cat_expr_autoderefd(self.tcx, self.method_map, expr, adj)
524+
}
525+
516526
fn cat_def(id: ast::node_id,
517527
span: span,
518528
ty: ty::t,

src/librustc/middle/borrowck/check_loans.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,12 @@ impl check_loan_ctxt {
362362
}
363363

364364
fn check_assignment(at: assignment_type, ex: @ast::expr) {
365-
let cmt = self.bccx.cat_expr(ex);
365+
// We don't use cat_expr() here because we don't want to treat
366+
// auto-ref'd parameters in overloaded operators as rvalues.
367+
let cmt = match self.bccx.tcx.adjustments.find(ex.id) {
368+
None => self.bccx.cat_expr_unadjusted(ex),
369+
Some(adj) => self.bccx.cat_expr_autoderefd(ex, adj)
370+
};
366371

367372
debug!("check_assignment(cmt=%s)",
368373
self.bccx.cmt_to_repr(cmt));

src/librustc/middle/mem_categorization.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,29 @@ fn cat_expr(
573573
return mcx.cat_expr(expr);
574574
}
575575

576+
fn cat_expr_unadjusted(
577+
tcx: ty::ctxt,
578+
method_map: typeck::method_map,
579+
expr: @ast::expr) -> cmt {
580+
581+
let mcx = &mem_categorization_ctxt {
582+
tcx: tcx, method_map: method_map
583+
};
584+
return mcx.cat_expr_unadjusted(expr);
585+
}
586+
587+
fn cat_expr_autoderefd(
588+
tcx: ty::ctxt,
589+
method_map: typeck::method_map,
590+
expr: @ast::expr,
591+
adj: @ty::AutoAdjustment) -> cmt {
592+
593+
let mcx = &mem_categorization_ctxt {
594+
tcx: tcx, method_map: method_map
595+
};
596+
return mcx.cat_expr_autoderefd(expr, adj);
597+
}
598+
576599
fn cat_def(
577600
tcx: ty::ctxt,
578601
method_map: typeck::method_map,

src/librustc/middle/trans/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1572,7 +1572,7 @@ fn trans_assign_op(bcx: block,
15721572
debug!("trans_assign_op(expr=%s)", bcx.expr_to_str(expr));
15731573

15741574
// Evaluate LHS (destination), which should be an lvalue
1575-
let dst_datum = unpack_datum!(bcx, trans_lvalue(bcx, dst));
1575+
let dst_datum = unpack_datum!(bcx, trans_lvalue_unadjusted(bcx, dst));
15761576

15771577
// A user-defined operator method
15781578
if bcx.ccx().maps.method_map.find(expr.id).is_some() {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
struct S {
2+
x: int
3+
}
4+
5+
impl S {
6+
pure fn add(&self, other: &S) -> S {
7+
S { x: self.x + other.x }
8+
}
9+
}
10+
11+
fn main() {
12+
let mut s = S { x: 1 };
13+
s += S { x: 2 };
14+
assert s.x == 3;
15+
}
16+

0 commit comments

Comments
 (0)