@@ -787,23 +787,19 @@ 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)" ) ;
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) ;
807
803
}
808
804
}
809
805
}
@@ -818,7 +814,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
818
814
debug ! ( "walk_autoderefs expr={} autoderefs={}" , expr. repr( self . tcx( ) ) , autoderefs) ;
819
815
820
816
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 ) ;
822
818
match self . typer . node_method_ty ( deref_id) {
823
819
None => { }
824
820
Some ( method_ty) => {
@@ -852,30 +848,19 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
852
848
853
849
self . walk_autoderefs ( expr, adj. autoderefs ) ;
854
850
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 ) ;
872
856
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
+ }
877
861
}
878
862
863
+
879
864
/// Walks the autoref `opt_autoref` applied to the autoderef'd
880
865
/// `expr`. `cmt_derefd` is the mem-categorized form of `expr`
881
866
/// 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> {
886
871
/// autoref.
887
872
fn walk_autoref ( & mut self ,
888
873
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 > > )
891
876
-> mc:: cmt < ' tcx >
892
877
{
893
878
debug ! ( "walk_autoref(expr.id={} cmt_derefd={} opt_autoref={:?})" ,
894
879
expr. id,
895
- cmt_derefd . repr( self . tcx( ) ) ,
880
+ cmt_base . repr( self . tcx( ) ) ,
896
881
opt_autoref) ;
897
882
883
+ let cmt_base_ty = cmt_base. ty ;
884
+
898
885
let autoref = match opt_autoref {
899
- Some ( autoref) => autoref,
886
+ Some ( ref autoref) => autoref,
900
887
None => {
901
- // No recursive step here, this is a base case .
902
- return cmt_derefd . clone ( ) ;
888
+ // No AutoRef .
889
+ return cmt_base ;
903
890
}
904
891
} ;
905
892
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( ) ) ) ;
913
896
897
+ match * autoref {
898
+ ty:: AutoPtr ( r, m) => {
914
899
self . delegate . borrow ( expr. id ,
915
900
expr. span ,
916
901
cmt_base,
917
- r,
902
+ * r,
918
903
ty:: BorrowKind :: from_mutbl ( m) ,
919
904
AutoRef ) ;
920
905
}
921
906
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) => {
962
908
debug ! ( "walk_autoref: expr.id={} cmt_base={}" ,
963
909
expr. id,
964
910
cmt_base. repr( self . tcx( ) ) ) ;
@@ -983,24 +929,12 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
983
929
984
930
let adj_ty =
985
931
ty:: adjust_ty_for_autoref ( self . tcx ( ) ,
986
- expr. span ,
987
- cmt_derefd. ty ,
932
+ cmt_base_ty,
988
933
opt_autoref) ;
989
934
990
935
self . mc . cat_rvalue_node ( expr. id , expr. span , adj_ty)
991
936
}
992
937
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
-
1004
938
1005
939
// When this returns true, it means that the expression *is* a
1006
940
// method-call (i.e. via the operator-overload). This true result
0 commit comments