@@ -787,23 +787,30 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
787
787
// process.
788
788
fn walk_adjustment ( & mut self , expr : & ast:: Expr ) {
789
789
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( ) ) ) ) ;
800
810
let cmt_unadjusted =
801
811
return_if_err ! ( self . mc. cat_expr_unadjusted( expr) ) ;
802
812
self . delegate_consume ( expr. id , expr. span , cmt_unadjusted) ;
803
813
}
804
- ty:: AdjustDerefRef ( ref adj) => {
805
- self . walk_autoderefref ( expr, adj) ;
806
- }
807
814
}
808
815
}
809
816
}
@@ -818,7 +825,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
818
825
debug ! ( "walk_autoderefs expr={} autoderefs={}" , expr. repr( self . tcx( ) ) , autoderefs) ;
819
826
820
827
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 ) ;
822
829
match self . typer . node_method_ty ( deref_id) {
823
830
None => { }
824
831
Some ( method_ty) => {
@@ -903,59 +910,22 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
903
910
}
904
911
} ;
905
912
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) ;
909
914
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( ) ) ) ;
913
918
919
+ match * autoref {
920
+ ty:: AutoPtr ( r, m) => {
914
921
self . delegate . borrow ( expr. id ,
915
922
expr. span ,
916
- cmt_base ,
917
- r,
923
+ cmt_derefd ,
924
+ * r,
918
925
ty:: BorrowKind :: from_mutbl ( m) ,
919
926
AutoRef ) ;
920
927
}
921
928
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
929
ty:: AutoUnsafe ( m, ref baseref) => {
960
930
let cmt_base = self . walk_autoref_recursively ( expr, cmt_derefd, baseref) ;
961
931
0 commit comments