@@ -787,23 +787,30 @@ 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)" ) ;
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_autoderefs ( expr, adj. autoderefs ) ;
803+ if let Some ( ref r) = adj. autoref {
804+ self . walk_autoref ( expr, r, adj. autoderefs ) ;
805+ } else if adj. unsize . is_some ( ) {
806+ assert ! ( adj. autoderefs == 0 ,
807+ format!( "Expected no derefs with \
808+ unsize AutoRefs, found: {}",
809+ adj. repr( self . tcx( ) ) ) ) ;
800810 let cmt_unadjusted =
801811 return_if_err ! ( self . mc. cat_expr_unadjusted( expr) ) ;
802812 self . delegate_consume ( expr. id , expr. span , cmt_unadjusted) ;
803813 }
804- ty:: AdjustDerefRef ( ref adj) => {
805- self . walk_autoderefref ( expr, adj) ;
806- }
807814 }
808815 }
809816 }
@@ -818,7 +825,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
818825 debug ! ( "walk_autoderefs expr={} autoderefs={}" , expr. repr( self . tcx( ) ) , autoderefs) ;
819826
820827 for i in 0 ..autoderefs {
821- let deref_id = ty:: MethodCall :: autoderef ( expr. id , i) ;
828+ let deref_id = ty:: MethodCall :: autoderef ( expr. id , i as u32 ) ;
822829 match self . typer . node_method_ty ( deref_id) {
823830 None => { }
824831 Some ( method_ty) => {
@@ -903,59 +910,22 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
903910 }
904911 } ;
905912
906- match * autoref {
907- ty:: AutoPtr ( r, m, ref baseref) => {
908- let cmt_base = self . walk_autoref_recursively ( expr, cmt_derefd, baseref) ;
913+ let cmt_base = self . walk_autoref_recursively ( expr, cmt_derefd, baseref) ;
909914
910- debug ! ( "walk_autoref: expr.id={} cmt_base={}" ,
911- expr. id,
912- cmt_base. repr( self . tcx( ) ) ) ;
915+ debug ! ( "walk_autoref: expr.id={} cmt_base={}" ,
916+ expr. id,
917+ cmt_base. repr( self . tcx( ) ) ) ;
913918
919+ match * autoref {
920+ ty:: AutoPtr ( r, m) => {
914921 self . delegate . borrow ( expr. id ,
915922 expr. span ,
916- cmt_base ,
917- r,
923+ cmt_derefd ,
924+ * r,
918925 ty:: BorrowKind :: from_mutbl ( m) ,
919926 AutoRef ) ;
920927 }
921928
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-
959929 ty:: AutoUnsafe ( m, ref baseref) => {
960930 let cmt_base = self . walk_autoref_recursively ( expr, cmt_derefd, baseref) ;
961931
0 commit comments