Skip to content

Commit 50fb2a4

Browse files
committed
auto merge of #12610 : eddyb/rust/deref-now-auto, r=nikomatsakis
Enables the dereference overloads introduced by #12491 to be applied wherever automatic dereferences would be used (field accesses, method calls and indexing).
2 parents 2c8bce1 + 01a15d5 commit 50fb2a4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1632
-1100
lines changed

src/doc/tutorial.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1687,7 +1687,7 @@ let x = Rc::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
16871687
let y = x.clone(); // a new owner
16881688
let z = x; // this moves `x` into `z`, rather than creating a new owner
16891689

1690-
assert!(*z.borrow() == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1690+
assert!(*z == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
16911691

16921692
// the variable is mutable, but not the contents of the box
16931693
let mut a = Rc::new([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);

src/libarena/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ struct Chunk {
5151
}
5252
impl Chunk {
5353
fn capacity(&self) -> uint {
54-
self.data.borrow().borrow().get().capacity()
54+
self.data.deref().borrow().get().capacity()
5555
}
5656

5757
unsafe fn as_ptr(&self) -> *u8 {
58-
self.data.borrow().borrow().get().as_ptr()
58+
self.data.deref().borrow().get().as_ptr()
5959
}
6060
}
6161

src/libnum/complex.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl<T: Clone + Float> Cmplx<T> {
101101
/// Convert a polar representation into a complex number.
102102
#[inline]
103103
pub fn from_polar(r: &T, theta: &T) -> Cmplx<T> {
104-
Cmplx::new(r * theta.cos(), r * theta.sin())
104+
Cmplx::new(*r * theta.cos(), *r * theta.sin())
105105
}
106106
}
107107

src/librustc/driver/driver.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,8 @@ pub fn build_session_(sopts: @session::Options,
10201020
lints: RefCell::new(HashMap::new()),
10211021
node_id: Cell::new(1),
10221022
crate_types: @RefCell::new(Vec::new()),
1023-
features: front::feature_gate::Features::new()
1023+
features: front::feature_gate::Features::new(),
1024+
recursion_limit: Cell::new(64),
10241025
}
10251026
}
10261027

src/librustc/driver/session.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,11 @@ pub struct Session_ {
194194
Vec<(lint::Lint, codemap::Span, ~str)> >>,
195195
node_id: Cell<ast::NodeId>,
196196
crate_types: @RefCell<Vec<CrateType> >,
197-
features: front::feature_gate::Features
197+
features: front::feature_gate::Features,
198+
199+
/// The maximum recursion limit for potentially infinitely recursive
200+
/// operations such as auto-dereference and monomorphization.
201+
recursion_limit: Cell<uint>,
198202
}
199203

200204
pub type Session = @Session_;

src/librustc/middle/astencode.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use metadata::tydecode;
2121
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
2222
RegionParameter};
2323
use metadata::tyencode;
24-
use middle::typeck::{MethodCallee, MethodOrigin};
24+
use middle::typeck::{MethodCall, MethodCallee, MethodOrigin};
2525
use middle::{ty, typeck, moves};
2626
use middle;
2727
use util::ppaux::ty_to_str;
@@ -1039,7 +1039,8 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10391039
}
10401040
}
10411041

1042-
for &method in maps.method_map.borrow().get().find(&id).iter() {
1042+
let method_call = MethodCall::expr(id);
1043+
for &method in maps.method_map.borrow().get().find(&method_call).iter() {
10431044
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
10441045
ebml_w.id(id);
10451046
ebml_w.tag(c::tag_table_val, |ebml_w| {
@@ -1081,7 +1082,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10811082
ebml_w.tag(c::tag_table_capture_map, |ebml_w| {
10821083
ebml_w.id(id);
10831084
ebml_w.tag(c::tag_table_val, |ebml_w| {
1084-
ebml_w.emit_from_vec(cap_vars.borrow().as_slice(),
1085+
ebml_w.emit_from_vec(cap_vars.deref().as_slice(),
10851086
|ebml_w, cap_var| {
10861087
cap_var.encode(ebml_w);
10871088
})
@@ -1385,7 +1386,8 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
13851386
}
13861387
c::tag_table_method_map => {
13871388
let method = val_dsr.read_method_callee(xcx);
1388-
dcx.maps.method_map.borrow_mut().get().insert(id, method);
1389+
let method_call = MethodCall::expr(id);
1390+
dcx.maps.method_map.borrow_mut().get().insert(method_call, method);
13891391
}
13901392
c::tag_table_vtable_map => {
13911393
let vtable_res =

src/librustc/middle/borrowck/check_loans.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use mc = middle::mem_categorization;
2222
use middle::borrowck::*;
2323
use middle::moves;
2424
use middle::ty;
25+
use middle::typeck::MethodCall;
2526
use std::vec_ng::Vec;
2627
use syntax::ast;
2728
use syntax::ast_util;
@@ -716,7 +717,7 @@ impl<'a> CheckLoanCtxt<'a> {
716717
span: Span) {
717718
let capture_map = self.bccx.capture_map.borrow();
718719
let cap_vars = capture_map.get().get(&closure_id);
719-
for cap_var in cap_vars.borrow().iter() {
720+
for cap_var in cap_vars.deref().iter() {
720721
let var_id = ast_util::def_id_of_def(cap_var.def).node;
721722
let var_path = @LpVar(var_id);
722723
self.check_if_path_is_moved(closure_id, span,
@@ -838,11 +839,11 @@ fn check_loans_in_expr<'a>(this: &mut CheckLoanCtxt<'a>,
838839
this.check_call(expr, None, expr.span, args.as_slice());
839840
}
840841
ast::ExprIndex(_, rval) | ast::ExprBinary(_, _, rval)
841-
if method_map.get().contains_key(&expr.id) => {
842+
if method_map.get().contains_key(&MethodCall::expr(expr.id)) => {
842843
this.check_call(expr, None, expr.span, [rval]);
843844
}
844845
ast::ExprUnary(_, _) | ast::ExprIndex(_, _)
845-
if method_map.get().contains_key(&expr.id) => {
846+
if method_map.get().contains_key(&MethodCall::expr(expr.id)) => {
846847
this.check_call(expr, None, expr.span, []);
847848
}
848849
ast::ExprInlineAsm(ref ia) => {

src/librustc/middle/borrowck/gather_loans/gather_moves.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub fn gather_captures(bccx: &BorrowckCtxt,
4949
closure_expr: &ast::Expr) {
5050
let capture_map = bccx.capture_map.borrow();
5151
let captured_vars = capture_map.get().get(&closure_expr.id);
52-
for captured_var in captured_vars.borrow().iter() {
52+
for captured_var in captured_vars.deref().iter() {
5353
match captured_var.mode {
5454
moves::CapMove => {
5555
let cmt = bccx.cat_captured_var(closure_expr.id,

src/librustc/middle/borrowck/gather_loans/mod.rs

+40-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use middle::moves;
2323
use middle::pat_util;
2424
use middle::ty::{ty_region};
2525
use middle::ty;
26+
use middle::typeck::MethodCall;
2627
use util::common::indenter;
2728
use util::ppaux::{Repr};
2829

@@ -242,7 +243,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
242243

243244
ast::ExprIndex(_, arg) |
244245
ast::ExprBinary(_, _, arg)
245-
if method_map.get().contains_key(&ex.id) => {
246+
if method_map.get().contains_key(&MethodCall::expr(ex.id)) => {
246247
// Arguments in method calls are always passed by ref.
247248
//
248249
// Currently these do not use adjustments, so we have to
@@ -325,6 +326,39 @@ impl<'a> GatherLoanCtxt<'a> {
325326
assert_eq!(id, popped);
326327
}
327328

329+
pub fn guarantee_autoderefs(&mut self,
330+
expr: &ast::Expr,
331+
autoderefs: uint) {
332+
let method_map = self.bccx.method_map.borrow();
333+
for i in range(0, autoderefs) {
334+
match method_map.get().find(&MethodCall::autoderef(expr.id, i as u32)) {
335+
Some(method) => {
336+
// Treat overloaded autoderefs as if an AutoRef adjustment
337+
// was applied on the base type, as that is always the case.
338+
let mut mc = self.bccx.mc();
339+
let cmt = match mc.cat_expr_autoderefd(expr, i) {
340+
Ok(v) => v,
341+
Err(()) => self.tcx().sess.span_bug(expr.span, "Err from mc")
342+
};
343+
let self_ty = *ty::ty_fn_args(method.ty).get(0);
344+
let (m, r) = match ty::get(self_ty).sty {
345+
ty::ty_rptr(r, ref m) => (m.mutbl, r),
346+
_ => self.tcx().sess.span_bug(expr.span,
347+
format!("bad overloaded deref type {}",
348+
method.ty.repr(self.tcx())))
349+
};
350+
self.guarantee_valid(expr.id,
351+
expr.span,
352+
cmt,
353+
m,
354+
r,
355+
AutoRef);
356+
}
357+
None => {}
358+
}
359+
}
360+
}
361+
328362
pub fn guarantee_adjustments(&mut self,
329363
expr: &ast::Expr,
330364
adjustment: &ty::AutoAdjustment) {
@@ -340,15 +374,17 @@ impl<'a> GatherLoanCtxt<'a> {
340374

341375
ty::AutoDerefRef(
342376
ty::AutoDerefRef {
343-
autoref: None, .. }) => {
377+
autoref: None, autoderefs }) => {
344378
debug!("no autoref");
379+
self.guarantee_autoderefs(expr, autoderefs);
345380
return;
346381
}
347382

348383
ty::AutoDerefRef(
349384
ty::AutoDerefRef {
350385
autoref: Some(ref autoref),
351-
autoderefs: autoderefs}) => {
386+
autoderefs}) => {
387+
self.guarantee_autoderefs(expr, autoderefs);
352388
let mut mc = self.bccx.mc();
353389
let cmt = match mc.cat_expr_autoderefd(expr, autoderefs) {
354390
Ok(v) => v,
@@ -406,7 +442,7 @@ impl<'a> GatherLoanCtxt<'a> {
406442
closure_expr: &ast::Expr) {
407443
let capture_map = self.bccx.capture_map.borrow();
408444
let captured_vars = capture_map.get().get(&closure_expr.id);
409-
for captured_var in captured_vars.borrow().iter() {
445+
for captured_var in captured_vars.deref().iter() {
410446
match captured_var.mode {
411447
moves::CapCopy | moves::CapMove => { continue; }
412448
moves::CapRef => { }

src/librustc/middle/borrowck/mod.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,8 @@ impl BorrowckCtxt {
556556
move_data::MoveExpr => {
557557
let (expr_ty, expr_span) = match self.tcx.map.find(move.id) {
558558
Some(ast_map::NodeExpr(expr)) => {
559-
(ty::expr_ty_adjusted(self.tcx, expr), expr.span)
559+
(ty::expr_ty_adjusted(self.tcx, expr,
560+
self.method_map.borrow().get()), expr.span)
560561
}
561562
r => self.tcx.sess.bug(format!("MoveExpr({:?}) maps to {:?}, not Expr",
562563
move.id, r))
@@ -582,7 +583,8 @@ impl BorrowckCtxt {
582583
move_data::Captured => {
583584
let (expr_ty, expr_span) = match self.tcx.map.find(move.id) {
584585
Some(ast_map::NodeExpr(expr)) => {
585-
(ty::expr_ty_adjusted(self.tcx, expr), expr.span)
586+
(ty::expr_ty_adjusted(self.tcx, expr,
587+
self.method_map.borrow().get()), expr.span)
586588
}
587589
r => self.tcx.sess.bug(format!("Captured({:?}) maps to {:?}, not Expr",
588590
move.id, r))
@@ -922,8 +924,8 @@ impl mc::Typer for TcxTyper {
922924
Ok(ty::node_id_to_type(self.tcx, id))
923925
}
924926

925-
fn node_method_ty(&mut self, id: ast::NodeId) -> Option<ty::t> {
926-
self.method_map.borrow().get().find(&id).map(|method| method.ty)
927+
fn node_method_ty(&mut self, method_call: typeck::MethodCall) -> Option<ty::t> {
928+
self.method_map.borrow().get().find(&method_call).map(|method| method.ty)
927929
}
928930

929931
fn adjustment(&mut self, id: ast::NodeId) -> Option<@ty::AutoAdjustment> {
@@ -932,7 +934,7 @@ impl mc::Typer for TcxTyper {
932934
}
933935

934936
fn is_method_call(&mut self, id: ast::NodeId) -> bool {
935-
self.method_map.borrow().get().contains_key(&id)
937+
self.method_map.borrow().get().contains_key(&typeck::MethodCall::expr(id))
936938
}
937939

938940
fn temporary_scope(&mut self, id: ast::NodeId) -> Option<ast::NodeId> {

src/librustc/middle/cfg/construct.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,7 @@ impl CFGBuilder {
523523
}
524524

525525
fn is_method_call(&self, expr: &ast::Expr) -> bool {
526-
let method_map = self.method_map.borrow();
527-
method_map.get().contains_key(&expr.id)
526+
let method_call = typeck::MethodCall::expr(expr.id);
527+
self.method_map.borrow().get().contains_key(&method_call)
528528
}
529529
}

src/librustc/middle/check_const.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ pub fn check_expr(v: &mut CheckCrateVisitor,
117117
}
118118
ExprLit(lit) if ast_util::lit_is_str(lit) => {}
119119
ExprBinary(..) | ExprUnary(..) => {
120-
let method_map = method_map.borrow();
121-
if method_map.get().contains_key(&e.id) {
120+
let method_call = typeck::MethodCall::expr(e.id);
121+
if method_map.borrow().get().contains_key(&method_call) {
122122
sess.span_err(e.span, "user-defined operators are not \
123123
allowed in constant expressions");
124124
}

src/librustc/middle/const_eval.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use middle::astencode;
1616
use middle::ty;
1717
use middle::typeck::astconv;
1818
use middle;
19-
use util::nodemap::{DefIdMap, NodeMap};
19+
use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
2020

2121
use syntax::ast::*;
2222
use syntax::parse::token::InternedString;
@@ -136,7 +136,7 @@ pub fn lookup_variant_by_id(tcx: ty::ctxt,
136136
}
137137
let maps = astencode::Maps {
138138
root_map: @RefCell::new(HashMap::new()),
139-
method_map: @RefCell::new(NodeMap::new()),
139+
method_map: @RefCell::new(FnvHashMap::new()),
140140
vtable_map: @RefCell::new(NodeMap::new()),
141141
capture_map: @RefCell::new(NodeMap::new())
142142
};
@@ -186,7 +186,7 @@ pub fn lookup_const_by_id(tcx: ty::ctxt, def_id: ast::DefId)
186186
}
187187
let maps = astencode::Maps {
188188
root_map: @RefCell::new(HashMap::new()),
189-
method_map: @RefCell::new(NodeMap::new()),
189+
method_map: @RefCell::new(FnvHashMap::new()),
190190
vtable_map: @RefCell::new(NodeMap::new()),
191191
capture_map: @RefCell::new(NodeMap::new())
192192
};
@@ -512,7 +512,7 @@ pub fn lit_to_const(lit: &Lit) -> const_val {
512512
match lit.node {
513513
LitStr(ref s, _) => const_str((*s).clone()),
514514
LitBinary(ref data) => {
515-
const_binary(Rc::new(data.borrow().iter().map(|x| *x).collect()))
515+
const_binary(Rc::new(data.deref().iter().map(|x| *x).collect()))
516516
}
517517
LitChar(n) => const_uint(n as u64),
518518
LitInt(n, _) => const_int(n),

src/librustc/middle/dataflow.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -810,8 +810,8 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
810810
}
811811

812812
fn is_method_call(&self, expr: &ast::Expr) -> bool {
813-
let method_map = self.dfcx.method_map.borrow();
814-
method_map.get().contains_key(&expr.id)
813+
let method_call = typeck::MethodCall::expr(expr.id);
814+
self.dfcx.method_map.borrow().get().contains_key(&method_call)
815815
}
816816

817817
fn reset(&mut self, bits: &mut [uint]) {

src/librustc/middle/dead.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,10 @@ impl MarkSymbolVisitor {
9292
}
9393
}
9494

95-
fn lookup_and_handle_method(&mut self, id: &ast::NodeId,
95+
fn lookup_and_handle_method(&mut self, id: ast::NodeId,
9696
span: codemap::Span) {
97-
match self.method_map.borrow().get().find(id) {
97+
let method_call = typeck::MethodCall::expr(id);
98+
match self.method_map.borrow().get().find(&method_call) {
9899
Some(method) => {
99100
match method.origin {
100101
typeck::MethodStatic(def_id) => {
@@ -179,7 +180,7 @@ impl Visitor<()> for MarkSymbolVisitor {
179180
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
180181
match expr.node {
181182
ast::ExprMethodCall(..) => {
182-
self.lookup_and_handle_method(&expr.id, expr.span);
183+
self.lookup_and_handle_method(expr.id, expr.span);
183184
}
184185
_ => ()
185186
}

src/librustc/middle/effect.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/// `unsafe`.
1313
1414
use middle::ty;
15-
use middle::typeck::MethodMap;
15+
use middle::typeck::{MethodCall, MethodMap};
1616
use util::ppaux;
1717

1818
use syntax::ast;
@@ -138,7 +138,8 @@ impl Visitor<()> for EffectCheckVisitor {
138138
fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
139139
match expr.node {
140140
ast::ExprMethodCall(_, _, _) => {
141-
let base_type = self.method_map.borrow().get().get(&expr.id).ty;
141+
let method_call = MethodCall::expr(expr.id);
142+
let base_type = self.method_map.borrow().get().get(&method_call).ty;
142143
debug!("effect: method call case, base type is {}",
143144
ppaux::ty_to_str(self.tcx, base_type));
144145
if type_is_unsafe_function(base_type) {

src/librustc/middle/kind.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
267267
// Handle any kind bounds on type parameters
268268
{
269269
let method_map = cx.method_map.borrow();
270-
let method = method_map.get().find(&e.id);
270+
let method = method_map.get().find(&typeck::MethodCall::expr(e.id));
271271
let node_type_substs = cx.tcx.node_type_substs.borrow();
272272
let r = match method {
273273
Some(method) => Some(&method.substs.tps),
@@ -298,7 +298,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
298298
}
299299
}
300300
};
301-
let type_param_defs = type_param_defs.borrow();
301+
let type_param_defs = type_param_defs.deref();
302302
if ts.len() != type_param_defs.len() {
303303
// Fail earlier to make debugging easier
304304
fail!("internal error: in kind::check_expr, length \
@@ -341,7 +341,8 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
341341
match **adjustment {
342342
ty::AutoObject(..) => {
343343
let source_ty = ty::expr_ty(cx.tcx, e);
344-
let target_ty = ty::expr_ty_adjusted(cx.tcx, e);
344+
let target_ty = ty::expr_ty_adjusted(cx.tcx, e,
345+
cx.method_map.borrow().get());
345346
check_trait_cast(cx, source_ty, target_ty, e.span);
346347
}
347348
ty::AutoAddEnv(..) |

0 commit comments

Comments
 (0)