@@ -704,89 +704,55 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
704704 // consumed or borrowed as part of the automatic adjustment
705705 // process.
706706 fn walk_adjustment ( & mut self , expr : & hir:: Expr ) {
707- let infcx = self . mc . infcx ;
708707 //NOTE(@jroesch): mixed RefCell borrow causes crash
709- let adj = infcx. tables . borrow ( ) . adjustments . get ( & expr. id ) . cloned ( ) ;
708+ let adjustments = self . mc . infcx . tables . borrow ( ) . expr_adjustments ( expr) . to_vec ( ) ;
710709 let mut cmt = return_if_err ! ( self . mc. cat_expr_unadjusted( expr) ) ;
711- if let Some ( adjustment) = adj {
710+ for adjustment in adjustments {
712711 debug ! ( "walk_adjustment expr={:?} adj={:?}" , expr, adjustment) ;
713712 match adjustment. kind {
714713 adjustment:: Adjust :: NeverToAny |
715714 adjustment:: Adjust :: ReifyFnPointer |
716715 adjustment:: Adjust :: UnsafeFnPointer |
717716 adjustment:: Adjust :: ClosureFnPointer |
718- adjustment:: Adjust :: MutToConstPointer => {
717+ adjustment:: Adjust :: MutToConstPointer |
718+ adjustment:: Adjust :: Unsize => {
719719 // Creating a closure/fn-pointer or unsizing consumes
720720 // the input and stores it into the resulting rvalue.
721- self . delegate_consume ( expr. id , expr. span , cmt) ;
722- assert ! ( adjustment. autoref. is_none( ) && !adjustment. unsize) ;
723- return ;
724- }
725- adjustment:: Adjust :: Deref ( ref autoderefs) => {
726- cmt = return_if_err ! ( self . walk_autoderefs( expr, cmt, autoderefs) ) ;
721+ self . delegate_consume ( expr. id , expr. span , cmt. clone ( ) ) ;
727722 }
728- }
729723
730- cmt = self . walk_autoref ( expr, cmt, adjustment. autoref ) ;
731-
732- if adjustment. unsize {
733- // Unsizing consumes the thin pointer and produces a fat one.
734- self . delegate_consume ( expr. id , expr. span , cmt) ;
735- }
736- }
737- }
724+ adjustment:: Adjust :: Deref ( None ) => { }
725+
726+ // Autoderefs for overloaded Deref calls in fact reference
727+ // their receiver. That is, if we have `(*x)` where `x`
728+ // is of type `Rc<T>`, then this in fact is equivalent to
729+ // `x.deref()`. Since `deref()` is declared with `&self`,
730+ // this is an autoref of `x`.
731+ adjustment:: Adjust :: Deref ( Some ( ref deref) ) => {
732+ let bk = ty:: BorrowKind :: from_mutbl ( deref. mutbl ) ;
733+ self . delegate . borrow ( expr. id , expr. span , cmt. clone ( ) ,
734+ deref. region , bk, AutoRef ) ;
735+ }
738736
739- /// Autoderefs for overloaded Deref calls in fact reference their receiver. That is, if we have
740- /// `(*x)` where `x` is of type `Rc<T>`, then this in fact is equivalent to `x.deref()`. Since
741- /// `deref()` is declared with `&self`, this is an autoref of `x`.
742- fn walk_autoderefs ( & mut self ,
743- expr : & hir:: Expr ,
744- mut cmt : mc:: cmt < ' tcx > ,
745- autoderefs : & [ Option < adjustment:: OverloadedDeref < ' tcx > > ] )
746- -> mc:: McResult < mc:: cmt < ' tcx > > {
747- debug ! ( "walk_autoderefs expr={:?} autoderefs={:?}" , expr, autoderefs) ;
748-
749- for & overloaded in autoderefs {
750- if let Some ( deref) = overloaded {
751- let bk = ty:: BorrowKind :: from_mutbl ( deref. mutbl ) ;
752- self . delegate . borrow ( expr. id , expr. span , cmt. clone ( ) ,
753- deref. region , bk, AutoRef ) ;
754- cmt = self . mc . cat_overloaded_autoderef ( expr, deref) ?;
755- } else {
756- cmt = self . mc . cat_deref ( expr, cmt, false ) ?;
737+ adjustment:: Adjust :: Borrow ( ref autoref) => {
738+ self . walk_autoref ( expr, cmt. clone ( ) , autoref) ;
739+ }
757740 }
741+ cmt = return_if_err ! ( self . mc. cat_expr_adjusted( expr, cmt, & adjustment) ) ;
758742 }
759- Ok ( cmt)
760743 }
761744
762- /// Walks the autoref `opt_autoref` applied to the autoderef'd
763- /// `expr`. `cmt_derefd` is the mem-categorized form of `expr`
764- /// after all relevant autoderefs have occurred. Because AutoRefs
765- /// can be recursive, this function is recursive: it first walks
766- /// deeply all the way down the autoref chain, and then processes
767- /// the autorefs on the way out. At each point, it returns the
768- /// `cmt` for the rvalue that will be produced by introduced an
769- /// autoref.
745+ /// Walks the autoref `autoref` applied to the autoderef'd
746+ /// `expr`. `cmt_base` is the mem-categorized form of `expr`
747+ /// after all relevant autoderefs have occurred.
770748 fn walk_autoref ( & mut self ,
771749 expr : & hir:: Expr ,
772750 cmt_base : mc:: cmt < ' tcx > ,
773- opt_autoref : Option < adjustment:: AutoBorrow < ' tcx > > )
774- -> mc:: cmt < ' tcx >
775- {
776- debug ! ( "walk_autoref(expr.id={} cmt_derefd={:?} opt_autoref={:?})" ,
751+ autoref : & adjustment:: AutoBorrow < ' tcx > ) {
752+ debug ! ( "walk_autoref(expr.id={} cmt_base={:?} autoref={:?})" ,
777753 expr. id,
778754 cmt_base,
779- opt_autoref) ;
780-
781- let cmt_base_ty = cmt_base. ty ;
782-
783- let autoref = match opt_autoref {
784- Some ( ref autoref) => autoref,
785- None => {
786- // No AutoRef.
787- return cmt_base;
788- }
789- } ;
755+ autoref) ;
790756
791757 match * autoref {
792758 adjustment:: AutoBorrow :: Ref ( r, m) => {
@@ -816,14 +782,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
816782 AutoUnsafe ) ;
817783 }
818784 }
819-
820- // Construct the categorization for the result of the autoref.
821- // This is always an rvalue, since we are producing a new
822- // (temporary) indirection.
823-
824- let adj_ty = cmt_base_ty. adjust_for_autoref ( self . tcx ( ) , opt_autoref) ;
825-
826- self . mc . cat_rvalue_node ( expr. id , expr. span , adj_ty)
827785 }
828786
829787
0 commit comments