@@ -668,14 +668,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
668
668
..
669
669
} ) if span. ctxt ( ) == ctxt => {
670
670
let ty = cx. tcx . type_of ( def_id) ;
671
- Some ( if let ty:: Ref ( _, ty, _) = * ty. kind ( ) {
672
- Position :: DerefStable (
673
- precedence,
674
- ty. is_sized ( cx. tcx . at ( DUMMY_SP ) , cx. param_env . without_caller_bounds ( ) ) ,
675
- )
676
- } else {
677
- Position :: Other ( precedence)
678
- } )
671
+ Some ( ty_auto_deref_stability ( cx, ty, precedence) . position_for_result ( cx) )
679
672
} ,
680
673
681
674
Node :: Item ( & Item {
@@ -699,18 +692,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
699
692
let output = cx
700
693
. tcx
701
694
. erase_late_bound_regions ( cx. tcx . fn_sig ( def_id. to_def_id ( ) ) . output ( ) ) ;
702
- Some ( if let ty:: Ref ( _, ty, _) = * output. kind ( ) {
703
- if ty. has_placeholders ( ) || ty. has_opaque_types ( ) {
704
- Position :: ReborrowStable ( precedence)
705
- } else {
706
- Position :: DerefStable (
707
- precedence,
708
- ty. is_sized ( cx. tcx . at ( DUMMY_SP ) , cx. param_env . without_caller_bounds ( ) ) ,
709
- )
710
- }
711
- } else {
712
- Position :: Other ( precedence)
713
- } )
695
+ Some ( ty_auto_deref_stability ( cx, output, precedence) . position_for_result ( cx) )
714
696
} ,
715
697
716
698
Node :: Expr ( parent) if parent. span . ctxt ( ) == ctxt => match parent. kind {
@@ -730,18 +712,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
730
712
let output = cx
731
713
. tcx
732
714
. erase_late_bound_regions ( cx. tcx . fn_sig ( cx. tcx . hir ( ) . local_def_id ( owner_id) ) . output ( ) ) ;
733
- if let ty:: Ref ( _, ty, _) = * output. kind ( ) {
734
- if ty. has_placeholders ( ) || ty. has_opaque_types ( ) {
735
- Position :: ReborrowStable ( precedence)
736
- } else {
737
- Position :: DerefStable (
738
- precedence,
739
- ty. is_sized ( cx. tcx . at ( DUMMY_SP ) , cx. param_env . without_caller_bounds ( ) ) ,
740
- )
741
- }
742
- } else {
743
- Position :: Other ( precedence)
744
- }
715
+ ty_auto_deref_stability ( cx, output, precedence) . position_for_result ( cx)
745
716
} ,
746
717
)
747
718
} ,
@@ -757,7 +728,8 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
757
728
// Type inference for closures can depend on how they're called. Only go by the explicit
758
729
// types here.
759
730
Some ( ty) => binding_ty_auto_deref_stability ( cx, ty, precedence) ,
760
- None => param_auto_deref_stability ( cx, cx. tcx . erase_late_bound_regions ( ty) , precedence) ,
731
+ None => ty_auto_deref_stability ( cx, cx. tcx . erase_late_bound_regions ( ty) , precedence)
732
+ . position_for_arg ( ) ,
761
733
} ) ,
762
734
ExprKind :: MethodCall ( _, args, _) => {
763
735
let id = cx. typeck_results ( ) . type_dependent_def_id ( parent. hir_id ) . unwrap ( ) ;
@@ -798,11 +770,12 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
798
770
Position :: MethodReceiver
799
771
}
800
772
} else {
801
- param_auto_deref_stability (
773
+ ty_auto_deref_stability (
802
774
cx,
803
775
cx. tcx . erase_late_bound_regions ( cx. tcx . fn_sig ( id) . input ( i) ) ,
804
776
precedence,
805
777
)
778
+ . position_for_arg ( )
806
779
}
807
780
} )
808
781
} ,
@@ -813,7 +786,9 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
813
786
. find ( |f| f. expr . hir_id == child_id)
814
787
. zip ( variant)
815
788
. and_then ( |( field, variant) | variant. fields . iter ( ) . find ( |f| f. name == field. ident . name ) )
816
- . map ( |field| param_auto_deref_stability ( cx, cx. tcx . type_of ( field. did ) , precedence) )
789
+ . map ( |field| {
790
+ ty_auto_deref_stability ( cx, cx. tcx . type_of ( field. did ) , precedence) . position_for_arg ( )
791
+ } )
817
792
} ,
818
793
ExprKind :: Field ( child, name) if child. hir_id == e. hir_id => Some ( Position :: FieldAccess ( name. name ) ) ,
819
794
ExprKind :: Unary ( UnOp :: Deref , child) if child. hir_id == e. hir_id => Some ( Position :: Deref ) ,
@@ -890,17 +865,17 @@ fn binding_ty_auto_deref_stability(cx: &LateContext<'_>, ty: &hir::Ty<'_>, prece
890
865
| TyKind :: Never
891
866
| TyKind :: Tup ( _)
892
867
| TyKind :: Ptr ( _)
893
- | TyKind :: TraitObject ( ..)
894
868
| TyKind :: Path ( _) => Position :: DerefStable (
895
869
precedence,
896
870
cx
897
- . typeck_results ( )
898
- . node_type ( ty. ty . hir_id )
899
- . is_sized ( cx. tcx . at ( DUMMY_SP ) , cx. param_env . without_caller_bounds ( ) ) ,
871
+ . typeck_results ( )
872
+ . node_type ( ty. ty . hir_id )
873
+ . is_sized ( cx. tcx . at ( DUMMY_SP ) , cx. param_env . without_caller_bounds ( ) ) ,
900
874
) ,
901
875
TyKind :: OpaqueDef ( ..)
902
876
| TyKind :: Infer
903
877
| TyKind :: Typeof ( ..)
878
+ | TyKind :: TraitObject ( ..)
904
879
| TyKind :: Err => Position :: ReborrowStable ( precedence) ,
905
880
} ;
906
881
}
@@ -937,10 +912,39 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
937
912
v. 0
938
913
}
939
914
915
+ struct TyPosition < ' tcx > {
916
+ position : Position ,
917
+ ty : Option < Ty < ' tcx > > ,
918
+ }
919
+ impl From < Position > for TyPosition < ' _ > {
920
+ fn from ( position : Position ) -> Self {
921
+ Self { position, ty : None }
922
+ }
923
+ }
924
+ impl < ' tcx > TyPosition < ' tcx > {
925
+ fn new_deref_stable_for_result ( precedence : i8 , ty : Ty < ' tcx > ) -> Self {
926
+ Self {
927
+ position : Position :: ReborrowStable ( precedence) ,
928
+ ty : Some ( ty) ,
929
+ }
930
+ }
931
+ fn position_for_result ( self , cx : & LateContext < ' tcx > ) -> Position {
932
+ match ( self . position , self . ty ) {
933
+ ( Position :: ReborrowStable ( precedence) , Some ( ty) ) => {
934
+ Position :: DerefStable ( precedence, ty. is_sized ( cx. tcx . at ( DUMMY_SP ) , cx. param_env ) )
935
+ } ,
936
+ ( position, _) => position,
937
+ }
938
+ }
939
+ fn position_for_arg ( self ) -> Position {
940
+ self . position
941
+ }
942
+ }
943
+
940
944
// Checks whether a type is stable when switching to auto dereferencing,
941
- fn param_auto_deref_stability < ' tcx > ( cx : & LateContext < ' tcx > , ty : Ty < ' tcx > , precedence : i8 ) -> Position {
945
+ fn ty_auto_deref_stability < ' tcx > ( cx : & LateContext < ' tcx > , ty : Ty < ' tcx > , precedence : i8 ) -> TyPosition < ' tcx > {
942
946
let ty:: Ref ( _, mut ty, _) = * ty. kind ( ) else {
943
- return Position :: Other ( precedence) ;
947
+ return Position :: Other ( precedence) . into ( ) ;
944
948
} ;
945
949
946
950
loop {
@@ -949,38 +953,38 @@ fn param_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, preced
949
953
ty = ref_ty;
950
954
continue ;
951
955
} ,
952
- ty:: Infer ( _)
953
- | ty:: Error ( _)
954
- | ty:: Param ( _)
955
- | ty:: Bound ( ..)
956
- | ty:: Opaque ( ..)
957
- | ty:: Placeholder ( _)
958
- | ty:: Dynamic ( ..) => Position :: ReborrowStable ( precedence) ,
959
- ty:: Adt ( ..) if ty. has_placeholders ( ) || ty. has_param_types_or_consts ( ) => {
960
- Position :: ReborrowStable ( precedence)
956
+ ty:: Param ( _) => TyPosition :: new_deref_stable_for_result ( precedence, ty) ,
957
+ ty:: Infer ( _) | ty:: Error ( _) | ty:: Bound ( ..) | ty:: Opaque ( ..) | ty:: Placeholder ( _) | ty:: Dynamic ( ..) => {
958
+ Position :: ReborrowStable ( precedence) . into ( )
961
959
} ,
962
- ty:: Adt ( ..)
963
- | ty:: Bool
960
+ ty:: Adt ( ..) if ty. has_placeholders ( ) || ty. has_opaque_types ( ) => {
961
+ Position :: ReborrowStable ( precedence) . into ( )
962
+ } ,
963
+ ty:: Adt ( _, substs) if substs. has_param_types_or_consts ( ) => {
964
+ TyPosition :: new_deref_stable_for_result ( precedence, ty)
965
+ } ,
966
+ ty:: Bool
964
967
| ty:: Char
965
968
| ty:: Int ( _)
966
969
| ty:: Uint ( _)
967
- | ty:: Float ( _)
968
- | ty:: Foreign ( _)
969
- | ty:: Str
970
970
| ty:: Array ( ..)
971
- | ty:: Slice ( .. )
971
+ | ty:: Float ( _ )
972
972
| ty:: RawPtr ( ..)
973
+ | ty:: FnPtr ( _) => Position :: DerefStable ( precedence, true ) . into ( ) ,
974
+ ty:: Str | ty:: Slice ( ..) => Position :: DerefStable ( precedence, false ) . into ( ) ,
975
+ ty:: Adt ( ..)
976
+ | ty:: Foreign ( _)
973
977
| ty:: FnDef ( ..)
974
- | ty:: FnPtr ( _)
975
- | ty:: Closure ( ..)
976
978
| ty:: Generator ( ..)
977
979
| ty:: GeneratorWitness ( ..)
980
+ | ty:: Closure ( ..)
978
981
| ty:: Never
979
982
| ty:: Tuple ( _)
980
983
| ty:: Projection ( _) => Position :: DerefStable (
981
984
precedence,
982
985
ty. is_sized ( cx. tcx . at ( DUMMY_SP ) , cx. param_env . without_caller_bounds ( ) ) ,
983
- ) ,
986
+ )
987
+ . into ( ) ,
984
988
} ;
985
989
}
986
990
}
0 commit comments