@@ -23,6 +23,7 @@ use middle::moves;
2323use middle:: pat_util;
2424use middle:: ty:: { ty_region} ;
2525use middle:: ty;
26+ use middle:: typeck:: MethodCall ;
2627use util:: common:: indenter;
2728use 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 => { }
0 commit comments