@@ -704,89 +704,55 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
704
704
// consumed or borrowed as part of the automatic adjustment
705
705
// process.
706
706
fn walk_adjustment ( & mut self , expr : & hir:: Expr ) {
707
- let infcx = self . mc . infcx ;
708
707
//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 ( ) ;
710
709
let mut cmt = return_if_err ! ( self . mc. cat_expr_unadjusted( expr) ) ;
711
- if let Some ( adjustment) = adj {
710
+ for adjustment in adjustments {
712
711
debug ! ( "walk_adjustment expr={:?} adj={:?}" , expr, adjustment) ;
713
712
match adjustment. kind {
714
713
adjustment:: Adjust :: NeverToAny |
715
714
adjustment:: Adjust :: ReifyFnPointer |
716
715
adjustment:: Adjust :: UnsafeFnPointer |
717
716
adjustment:: Adjust :: ClosureFnPointer |
718
- adjustment:: Adjust :: MutToConstPointer => {
717
+ adjustment:: Adjust :: MutToConstPointer |
718
+ adjustment:: Adjust :: Unsize => {
719
719
// Creating a closure/fn-pointer or unsizing consumes
720
720
// 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 ( ) ) ;
727
722
}
728
- }
729
723
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
+ }
738
736
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
+ }
757
740
}
741
+ cmt = return_if_err ! ( self . mc. cat_expr_adjusted( expr, cmt, & adjustment) ) ;
758
742
}
759
- Ok ( cmt)
760
743
}
761
744
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.
770
748
fn walk_autoref ( & mut self ,
771
749
expr : & hir:: Expr ,
772
750
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={:?})" ,
777
753
expr. id,
778
754
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) ;
790
756
791
757
match * autoref {
792
758
adjustment:: AutoBorrow :: Ref ( r, m) => {
@@ -816,14 +782,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
816
782
AutoUnsafe ) ;
817
783
}
818
784
}
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)
827
785
}
828
786
829
787
0 commit comments