Skip to content

Commit 25988b6

Browse files
committed
elide noop coercions
1 parent bca07b5 commit 25988b6

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

src/librustc_typeck/check/coercion.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
218218
// to type check, we will construct the type that `&M*expr` would
219219
// yield.
220220

221-
let r_a = match a.sty {
221+
let (r_a, mt_a) = match a.sty {
222222
ty::TyRef(r_a, mt_a) => {
223223
try!(coerce_mutbls(mt_a.mutbl, mt_b.mutbl));
224-
r_a
224+
(r_a, mt_a)
225225
}
226226
_ => return self.unify_and_identity(a, b)
227227
};
@@ -355,6 +355,20 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
355355

356356
// Now apply the autoref. We have to extract the region out of
357357
// the final ref type we got.
358+
if ty == a && mt_a.mutbl == hir::MutImmutable && autoderefs == 1 {
359+
// As a special case, if we would produce `&'a *x`, that's
360+
// a total no-op. We end up with the type `&'a T` just as
361+
// we started with. In that case, just skip it
362+
// altogether. This is just an optimization.
363+
//
364+
// Note that for `&mut`, we DO want to reborrow --
365+
// otherwise, this would be a move, which might be an
366+
// error. For example `foo(self.x)` where `self` and
367+
// `self.x` both have `&mut `type would be a move of
368+
// `self.x`, but we auto-coerce it to `foo(&mut *self.x)`,
369+
// which is a borrow.
370+
return self.identity(ty);
371+
}
358372
let r_borrow = match ty.sty {
359373
ty::TyRef(r_borrow, _) => r_borrow,
360374
_ => self.tcx().sess.span_bug(span,

0 commit comments

Comments
 (0)