Skip to content

Commit 9242549

Browse files
committed
Fix the actual bug for #20232: when creating the cmt for the implicit
deref that is associated with an overloaded index, we should not consult the method lookup table. This deref is *always* a deref of an `&T` and hence is never overloaded (and is also not present in the tables; it has no "id" or other associated key).
1 parent 2387651 commit 9242549

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

src/librustc/middle/mem_categorization.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
460460
autoderefs,
461461
cmt.repr(self.tcx()));
462462
for deref in range(1u, autoderefs + 1) {
463-
cmt = try!(self.cat_deref(expr, cmt, deref, false));
463+
cmt = try!(self.cat_deref(expr, cmt, deref));
464464
}
465465
return Ok(cmt);
466466
}
@@ -472,7 +472,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
472472
match expr.node {
473473
ast::ExprUnary(ast::UnDeref, ref e_base) => {
474474
let base_cmt = try!(self.cat_expr(&**e_base));
475-
self.cat_deref(expr, base_cmt, 0, false)
475+
self.cat_deref(expr, base_cmt, 0)
476476
}
477477

478478
ast::ExprField(ref base, f_name) => {
@@ -496,10 +496,23 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
496496
// If this is an index implemented by a method call, then it
497497
// will include an implicit deref of the result.
498498
let ret_ty = self.overloaded_method_return_ty(method_ty);
499-
self.cat_deref(expr,
500-
self.cat_rvalue_node(expr.id(),
501-
expr.span(),
502-
ret_ty), 1, true)
499+
500+
// The index method always returns an `&T`, so
501+
// dereference it to find the result type.
502+
let elem_ty = match ret_ty.sty {
503+
ty::ty_rptr(_, mt) => mt.ty,
504+
_ => {
505+
debug!("cat_expr_unadjusted: return type of overloaded index is {}?",
506+
ret_ty.repr(self.tcx()));
507+
return Err(());
508+
}
509+
};
510+
511+
// The call to index() returns a `&T` value, which
512+
// is an rvalue. That is what we will be
513+
// dereferencing.
514+
let base_cmt = self.cat_rvalue_node(expr.id(), expr.span(), ret_ty);
515+
self.cat_deref_common(expr, base_cmt, 1, elem_ty, true)
503516
}
504517
None => {
505518
self.cat_index(expr, try!(self.cat_expr(&**base)))
@@ -844,8 +857,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
844857
fn cat_deref<N:ast_node>(&self,
845858
node: &N,
846859
base_cmt: cmt<'tcx>,
847-
deref_cnt: uint,
848-
implicit: bool)
860+
deref_cnt: uint)
849861
-> McResult<cmt<'tcx>> {
850862
let adjustment = match self.typer.adjustments().borrow().get(&node.id()) {
851863
Some(adj) if ty::adjust_is_object(adj) => ty::AutoObject,
@@ -873,7 +885,8 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
873885
};
874886
let base_cmt_ty = base_cmt.ty;
875887
match ty::deref(base_cmt_ty, true) {
876-
Some(mt) => self.cat_deref_common(node, base_cmt, deref_cnt, mt.ty, implicit),
888+
Some(mt) => self.cat_deref_common(node, base_cmt, deref_cnt, mt.ty,
889+
/* implicit: */ false),
877890
None => {
878891
debug!("Explicit deref of non-derefable type: {}",
879892
base_cmt_ty.repr(self.tcx()));
@@ -1243,7 +1256,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
12431256
// box p1, &p1, &mut p1. we can ignore the mutability of
12441257
// PatRegion since that information is already contained
12451258
// in the type.
1246-
let subcmt = try!(self.cat_deref(pat, cmt, 0, false));
1259+
let subcmt = try!(self.cat_deref(pat, cmt, 0));
12471260
try!(self.cat_pattern_(subcmt, &**subpat, op));
12481261
}
12491262

0 commit comments

Comments
 (0)