@@ -668,14 +668,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
668668 ..
669669 } ) if span. ctxt ( ) == ctxt => {
670670 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) )
679672 } ,
680673
681674 Node :: Item ( & Item {
@@ -699,18 +692,7 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
699692 let output = cx
700693 . tcx
701694 . 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) )
714696 } ,
715697
716698 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, &
730712 let output = cx
731713 . tcx
732714 . 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)
745716 } ,
746717 )
747718 } ,
@@ -757,7 +728,8 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
757728 // Type inference for closures can depend on how they're called. Only go by the explicit
758729 // types here.
759730 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 ( ) ,
761733 } ) ,
762734 ExprKind :: MethodCall ( _, args, _) => {
763735 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, &
798770 Position :: MethodReceiver
799771 }
800772 } else {
801- param_auto_deref_stability (
773+ ty_auto_deref_stability (
802774 cx,
803775 cx. tcx . erase_late_bound_regions ( cx. tcx . fn_sig ( id) . input ( i) ) ,
804776 precedence,
805777 )
778+ . position_for_arg ( )
806779 }
807780 } )
808781 } ,
@@ -813,7 +786,9 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
813786 . find ( |f| f. expr . hir_id == child_id)
814787 . zip ( variant)
815788 . 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+ } )
817792 } ,
818793 ExprKind :: Field ( child, name) if child. hir_id == e. hir_id => Some ( Position :: FieldAccess ( name. name ) ) ,
819794 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
890865 | TyKind :: Never
891866 | TyKind :: Tup ( _)
892867 | TyKind :: Ptr ( _)
893- | TyKind :: TraitObject ( ..)
894868 | TyKind :: Path ( _) => Position :: DerefStable (
895869 precedence,
896870 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 ( ) ) ,
900874 ) ,
901875 TyKind :: OpaqueDef ( ..)
902876 | TyKind :: Infer
903877 | TyKind :: Typeof ( ..)
878+ | TyKind :: TraitObject ( ..)
904879 | TyKind :: Err => Position :: ReborrowStable ( precedence) ,
905880 } ;
906881 }
@@ -937,10 +912,39 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
937912 v. 0
938913}
939914
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+
940944// 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 > {
942946 let ty:: Ref ( _, mut ty, _) = * ty. kind ( ) else {
943- return Position :: Other ( precedence) ;
947+ return Position :: Other ( precedence) . into ( ) ;
944948 } ;
945949
946950 loop {
@@ -949,38 +953,38 @@ fn param_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, preced
949953 ty = ref_ty;
950954 continue ;
951955 } ,
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 ( )
961959 } ,
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
964967 | ty:: Char
965968 | ty:: Int ( _)
966969 | ty:: Uint ( _)
967- | ty:: Float ( _)
968- | ty:: Foreign ( _)
969- | ty:: Str
970970 | ty:: Array ( ..)
971- | ty:: Slice ( .. )
971+ | ty:: Float ( _ )
972972 | 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 ( _)
973977 | ty:: FnDef ( ..)
974- | ty:: FnPtr ( _)
975- | ty:: Closure ( ..)
976978 | ty:: Generator ( ..)
977979 | ty:: GeneratorWitness ( ..)
980+ | ty:: Closure ( ..)
978981 | ty:: Never
979982 | ty:: Tuple ( _)
980983 | ty:: Projection ( _) => Position :: DerefStable (
981984 precedence,
982985 ty. is_sized ( cx. tcx . at ( DUMMY_SP ) , cx. param_env . without_caller_bounds ( ) ) ,
983- ) ,
986+ )
987+ . into ( ) ,
984988 } ;
985989 }
986990}
0 commit comments