@@ -787,23 +787,19 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
787787 // process.
788788 fn walk_adjustment ( & mut self , expr : & ast:: Expr ) {
789789 let typer = self . typer ;
790- match typer. adjustments ( ) . borrow ( ) . get ( & expr. id ) {
791- None => { }
792- Some ( adjustment) => {
793- match * adjustment {
794- ty:: AdjustReifyFnPointer ( ..) |
795- ty:: AdjustUnsafeFnPointer ( ..) => {
796- // Creating a closure/fn-pointer consumes the
797- // input and stores it into the resulting
798- // rvalue.
799- debug ! ( "walk_adjustment(AutoAddEnv|AdjustReifyFnPointer)" ) ;
800- let cmt_unadjusted =
801- return_if_err ! ( self . mc. cat_expr_unadjusted( expr) ) ;
802- self . delegate_consume ( expr. id , expr. span , cmt_unadjusted) ;
803- }
804- ty:: AdjustDerefRef ( ref adj) => {
805- self . walk_autoderefref ( expr, adj) ;
806- }
790+ if let Some ( adjustment) = typer. adjustments ( ) . borrow ( ) . get ( & expr. id ) {
791+ match * adjustment {
792+ ty:: AdjustReifyFnPointer |
793+ ty:: AdjustUnsafeFnPointer => {
794+ // Creating a closure/fn-pointer or unsizing consumes
795+ // the input and stores it into the resulting rvalue.
796+ debug ! ( "walk_adjustment(AdjustReifyFnPointer|AdjustUnsafeFnPointer)" ) ;
797+ let cmt_unadjusted =
798+ return_if_err ! ( self . mc. cat_expr_unadjusted( expr) ) ;
799+ self . delegate_consume ( expr. id , expr. span , cmt_unadjusted) ;
800+ }
801+ ty:: AdjustDerefRef ( ref adj) => {
802+ self . walk_autoderefref ( expr, adj) ;
807803 }
808804 }
809805 }
@@ -818,7 +814,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
818814 debug ! ( "walk_autoderefs expr={} autoderefs={}" , expr. repr( self . tcx( ) ) , autoderefs) ;
819815
820816 for i in 0 ..autoderefs {
821- let deref_id = ty:: MethodCall :: autoderef ( expr. id , i) ;
817+ let deref_id = ty:: MethodCall :: autoderef ( expr. id , i as u32 ) ;
822818 match self . typer . node_method_ty ( deref_id) {
823819 None => { }
824820 Some ( method_ty) => {
@@ -852,30 +848,19 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
852848
853849 self . walk_autoderefs ( expr, adj. autoderefs ) ;
854850
855- // Weird hacky special case: AutoUnsizeUniq, which converts
856- // from a ~T to a ~Trait etc, always comes in a stylized
857- // fashion. In particular, we want to consume the ~ pointer
858- // being dereferenced, not the dereferenced content (as the
859- // content is, at least for upcasts, unsized).
860- match adj. autoref {
861- Some ( ty:: AutoUnsizeUniq ( _) ) => {
862- assert ! ( adj. autoderefs == 1 ,
863- format!( "Expected exactly 1 deref with Uniq AutoRefs, found: {}" ,
864- adj. autoderefs) ) ;
865- let cmt_unadjusted =
866- return_if_err ! ( self . mc. cat_expr_unadjusted( expr) ) ;
867- self . delegate_consume ( expr. id , expr. span , cmt_unadjusted) ;
868- return ;
869- }
870- _ => { }
871- }
851+ let cmt_derefd =
852+ return_if_err ! ( self . mc. cat_expr_autoderefd( expr, adj. autoderefs) ) ;
853+
854+ let cmt_refd =
855+ self . walk_autoref ( expr, cmt_derefd, adj. autoref ) ;
872856
873- let autoref = adj. autoref . as_ref ( ) ;
874- let cmt_derefd = return_if_err ! (
875- self . mc . cat_expr_autoderefd ( expr, adj . autoderefs ) ) ;
876- self . walk_autoref ( expr , & cmt_derefd , autoref ) ;
857+ if adj. unsize . is_some ( ) {
858+ // Unsizing consumes the thin pointer and produces a fat one.
859+ self . delegate_consume ( expr. id , expr . span , cmt_refd ) ;
860+ }
877861 }
878862
863+
879864 /// Walks the autoref `opt_autoref` applied to the autoderef'd
880865 /// `expr`. `cmt_derefd` is the mem-categorized form of `expr`
881866 /// after all relevant autoderefs have occurred. Because AutoRefs
@@ -886,79 +871,40 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
886871 /// autoref.
887872 fn walk_autoref ( & mut self ,
888873 expr : & ast:: Expr ,
889- cmt_derefd : & mc:: cmt < ' tcx > ,
890- opt_autoref : Option < & ty:: AutoRef < ' tcx > > )
874+ cmt_base : mc:: cmt < ' tcx > ,
875+ opt_autoref : Option < ty:: AutoRef < ' tcx > > )
891876 -> mc:: cmt < ' tcx >
892877 {
893878 debug ! ( "walk_autoref(expr.id={} cmt_derefd={} opt_autoref={:?})" ,
894879 expr. id,
895- cmt_derefd . repr( self . tcx( ) ) ,
880+ cmt_base . repr( self . tcx( ) ) ,
896881 opt_autoref) ;
897882
883+ let cmt_base_ty = cmt_base. ty ;
884+
898885 let autoref = match opt_autoref {
899- Some ( autoref) => autoref,
886+ Some ( ref autoref) => autoref,
900887 None => {
901- // No recursive step here, this is a base case .
902- return cmt_derefd . clone ( ) ;
888+ // No AutoRef .
889+ return cmt_base ;
903890 }
904891 } ;
905892
906- match * autoref {
907- ty:: AutoPtr ( r, m, ref baseref) => {
908- let cmt_base = self . walk_autoref_recursively ( expr, cmt_derefd, baseref) ;
909-
910- debug ! ( "walk_autoref: expr.id={} cmt_base={}" ,
911- expr. id,
912- cmt_base. repr( self . tcx( ) ) ) ;
893+ debug ! ( "walk_autoref: expr.id={} cmt_base={}" ,
894+ expr. id,
895+ cmt_base. repr( self . tcx( ) ) ) ;
913896
897+ match * autoref {
898+ ty:: AutoPtr ( r, m) => {
914899 self . delegate . borrow ( expr. id ,
915900 expr. span ,
916901 cmt_base,
917- r,
902+ * r,
918903 ty:: BorrowKind :: from_mutbl ( m) ,
919904 AutoRef ) ;
920905 }
921906
922- ty:: AutoUnsize ( _) => {
923- // Converting a `[T; N]` to `[T]` or `T` to `Trait`
924- // isn't really a borrow, move, etc, in and of itself.
925- // Also, no recursive step here, this is a base case.
926-
927- // It may seem a bit odd to return the cmt_derefd
928- // unmodified here, but in fact I think it's the right
929- // thing to do. Essentially the unsize transformation
930- // isn't really relevant to the borrowing rules --
931- // it's best thought of as a kind of side-modifier to
932- // the autoref, adding additional data that is
933- // attached to the pointer that is produced, but not
934- // affecting the data being borrowed in any other
935- // way. To see what I mean, consider this example:
936- //
937- // fn foo<'a>(&'a self) -> &'a Trait { self }
938- //
939- // This is valid because the underlying `self` value
940- // lives for the lifetime 'a. If we were to treat the
941- // "unsizing" as e.g. producing an rvalue, that would
942- // only be valid for the temporary scope, which isn't
943- // enough to justify the return value, which have the
944- // lifetime 'a.
945- //
946- // Another option would be to add a variant for
947- // categorization (like downcast) that wraps
948- // cmt_derefd and represents the unsizing operation.
949- // But I don't think there is any particular use for
950- // this (yet). -nmatsakis
951- return cmt_derefd. clone ( ) ;
952- }
953-
954- ty:: AutoUnsizeUniq ( _) => {
955- // these are handled via special case above
956- self . tcx ( ) . sess . span_bug ( expr. span , "nexpected AutoUnsizeUniq" ) ;
957- }
958-
959- ty:: AutoUnsafe ( m, ref baseref) => {
960- let cmt_base = self . walk_autoref_recursively ( expr, cmt_derefd, baseref) ;
961-
907+ ty:: AutoUnsafe ( m) => {
962908 debug ! ( "walk_autoref: expr.id={} cmt_base={}" ,
963909 expr. id,
964910 cmt_base. repr( self . tcx( ) ) ) ;
@@ -983,24 +929,12 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
983929
984930 let adj_ty =
985931 ty:: adjust_ty_for_autoref ( self . tcx ( ) ,
986- expr. span ,
987- cmt_derefd. ty ,
932+ cmt_base_ty,
988933 opt_autoref) ;
989934
990935 self . mc . cat_rvalue_node ( expr. id , expr. span , adj_ty)
991936 }
992937
993- fn walk_autoref_recursively ( & mut self ,
994- expr : & ast:: Expr ,
995- cmt_derefd : & mc:: cmt < ' tcx > ,
996- autoref : & Option < Box < ty:: AutoRef < ' tcx > > > )
997- -> mc:: cmt < ' tcx >
998- {
999- // Shuffle from a ref to an optional box to an optional ref.
1000- let autoref: Option < & ty:: AutoRef < ' tcx > > = autoref. as_ref ( ) . map ( |b| & * * b) ;
1001- self . walk_autoref ( expr, cmt_derefd, autoref)
1002- }
1003-
1004938
1005939 // When this returns true, it means that the expression *is* a
1006940 // method-call (i.e. via the operator-overload). This true result
0 commit comments