kind: kind,
};
- debug!("unadjusted-expr={:?} applying adjustments={:?}",
+ debug!("make_mirror: unadjusted-expr={:?} applying adjustments={:?}",
expr, cx.tcx.tables.borrow().adjustments.get(&self.id));
// Now apply adjustments, if any.
self.span,
i,
|mc| cx.tcx.tables.borrow().method_map.get(&mc).map(|m| m.ty));
- let kind = if cx.tcx.is_overloaded_autoderef(self.id, i) {
- overloaded_lvalue(cx, self, ty::MethodCall::autoderef(self.id, i),
- PassArgs::ByValue, expr.to_ref(), vec![])
+ debug!("make_mirror: autoderef #{}, adjusted_ty={:?}", i, adjusted_ty);
+ let method_key = ty::MethodCall::autoderef(self.id, i);
+ let meth_ty =
+ cx.tcx.tables.borrow().method_map.get(&method_key).map(|m| m.ty);
+ let kind = if let Some(meth_ty) = meth_ty {
+ debug!("make_mirror: overloaded autoderef (meth_ty={:?})", meth_ty);
+
+ let ref_ty = cx.tcx.no_late_bound_regions(&meth_ty.fn_ret());
+ let (region, mutbl) = match ref_ty {
+ Some(ty::FnConverging(&ty::TyS {
+ sty: ty::TyRef(region, mt), ..
+ })) => (region, mt.mutbl),
+ _ => cx.tcx.sess.span_bug(
+ expr.span, "autoderef returned bad type")
+ };
+
+ expr = Expr {
+ temp_lifetime: temp_lifetime,
+ ty: cx.tcx.mk_ref(
+ region, ty::TypeAndMut { ty: expr.ty, mutbl: mutbl }),
+ span: expr.span,
+ kind: ExprKind::Borrow {
+ region: *region,
+ borrow_kind: to_borrow_kind(mutbl),
+ arg: expr.to_ref()
+ }
+ };
+
+ overloaded_lvalue(cx, self, method_key,
+ PassArgs::ByRef, expr.to_ref(), vec![])
} else {
+ debug!("make_mirror: built-in autoderef");
ExprKind::Deref { arg: expr.to_ref() }
};
expr = Expr {
--- /dev/null
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_attrs)]
+
+use std::ops::{Deref, DerefMut};
+
+pub struct MyRef(u32);
+
+impl Deref for MyRef {
+ type Target = u32;
+ fn deref(&self) -> &u32 { &self.0 }
+}
+
+impl DerefMut for MyRef {
+ fn deref_mut(&mut self) -> &mut u32 { &mut self.0 }
+}
+
+
+#[rustc_mir]
+fn deref(x: &MyRef) -> &u32 {
+ x
+}
+
+#[rustc_mir]
+fn deref_mut(x: &mut MyRef) -> &mut u32 {
+ x
+}
+
+fn main() {
+ let mut r = MyRef(2);
+ assert_eq!(deref(&r) as *const _, &r.0 as *const _);
+ assert_eq!(deref_mut(&mut r) as *mut _, &mut r.0 as *mut _);
+}