@@ -23,6 +23,7 @@ use middle::moves;
23
23
use middle:: pat_util;
24
24
use middle:: ty:: { ty_region} ;
25
25
use middle:: ty;
26
+ use middle:: typeck:: MethodCall ;
26
27
use util:: common:: indenter;
27
28
use util:: ppaux:: { Repr } ;
28
29
@@ -242,7 +243,7 @@ fn gather_loans_in_expr(this: &mut GatherLoanCtxt,
242
243
243
244
ast:: ExprIndex ( _, arg) |
244
245
ast:: ExprBinary ( _, _, arg)
245
- if method_map. get ( ) . contains_key ( & ex. id ) => {
246
+ if method_map. get ( ) . contains_key ( & MethodCall :: expr ( ex. id ) ) => {
246
247
// Arguments in method calls are always passed by ref.
247
248
//
248
249
// Currently these do not use adjustments, so we have to
@@ -325,6 +326,39 @@ impl<'a> GatherLoanCtxt<'a> {
325
326
assert_eq ! ( id, popped) ;
326
327
}
327
328
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
+
328
362
pub fn guarantee_adjustments ( & mut self ,
329
363
expr : & ast:: Expr ,
330
364
adjustment : & ty:: AutoAdjustment ) {
@@ -340,15 +374,17 @@ impl<'a> GatherLoanCtxt<'a> {
340
374
341
375
ty:: AutoDerefRef (
342
376
ty:: AutoDerefRef {
343
- autoref : None , .. } ) => {
377
+ autoref : None , autoderefs } ) => {
344
378
debug ! ( "no autoref" ) ;
379
+ self . guarantee_autoderefs ( expr, autoderefs) ;
345
380
return ;
346
381
}
347
382
348
383
ty:: AutoDerefRef (
349
384
ty:: AutoDerefRef {
350
385
autoref : Some ( ref autoref) ,
351
- autoderefs : autoderefs} ) => {
386
+ autoderefs} ) => {
387
+ self . guarantee_autoderefs ( expr, autoderefs) ;
352
388
let mut mc = self . bccx . mc ( ) ;
353
389
let cmt = match mc. cat_expr_autoderefd ( expr, autoderefs) {
354
390
Ok ( v) => v,
@@ -406,7 +442,7 @@ impl<'a> GatherLoanCtxt<'a> {
406
442
closure_expr : & ast:: Expr ) {
407
443
let capture_map = self . bccx . capture_map . borrow ( ) ;
408
444
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 ( ) {
410
446
match captured_var. mode {
411
447
moves:: CapCopy | moves:: CapMove => { continue ; }
412
448
moves:: CapRef => { }
0 commit comments