@@ -3,7 +3,7 @@ use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exact
33use clippy_utils:: msrvs:: { self , Msrv } ;
44use clippy_utils:: source:: { snippet_with_applicability, snippet_with_context} ;
55use clippy_utils:: sugg:: has_enclosing_paren;
6- use clippy_utils:: ty:: { expr_sig, is_copy, peel_mid_ty_refs, ty_sig, variant_of_res } ;
6+ use clippy_utils:: ty:: { adt_and_variant_of_res , expr_sig, is_copy, peel_mid_ty_refs, ty_sig} ;
77use clippy_utils:: {
88 fn_def_id, get_parent_expr, get_parent_expr_for_hir, is_lint_allowed, path_to_local, walk_to_expr_usage,
99} ;
@@ -26,8 +26,8 @@ use rustc_lint::{LateContext, LateLintPass};
2626use rustc_middle:: mir:: { Rvalue , StatementKind } ;
2727use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow , AutoBorrowMutability } ;
2828use rustc_middle:: ty:: {
29- self , Binder , BoundVariableKind , Clause , EarlyBinder , FnSig , GenericArgKind , List , ParamTy , PredicateKind ,
30- ProjectionPredicate , Ty , TyCtxt , TypeVisitable , TypeckResults ,
29+ self , Binder , BoundVariableKind , Clause , EarlyBinder , FnSig , GenericArgKind , List , ParamEnv , ParamTy ,
30+ PredicateKind , ProjectionPredicate , Ty , TyCtxt , TypeVisitable , TypeckResults ,
3131} ;
3232use rustc_session:: { declare_tool_lint, impl_lint_pass} ;
3333use rustc_span:: { symbol:: sym, Span , Symbol } ;
@@ -736,7 +736,7 @@ fn walk_parents<'tcx>(
736736 ..
737737 } ) if span. ctxt ( ) == ctxt => {
738738 let ty = cx. tcx . type_of ( owner_id. def_id ) ;
739- Some ( ty_auto_deref_stability ( cx, ty, precedence) . position_for_result ( cx) )
739+ Some ( ty_auto_deref_stability ( cx. tcx , cx . param_env , ty, precedence) . position_for_result ( cx) )
740740 } ,
741741
742742 Node :: Item ( & Item {
@@ -760,18 +760,31 @@ fn walk_parents<'tcx>(
760760 let output = cx
761761 . tcx
762762 . erase_late_bound_regions ( cx. tcx . fn_sig ( owner_id) . subst_identity ( ) . output ( ) ) ;
763- Some ( ty_auto_deref_stability ( cx, output, precedence) . position_for_result ( cx) )
763+ Some ( ty_auto_deref_stability ( cx. tcx , cx . param_env , output, precedence) . position_for_result ( cx) )
764764 } ,
765765
766766 Node :: ExprField ( field) if field. span . ctxt ( ) == ctxt => match get_parent_expr_for_hir ( cx, field. hir_id ) {
767767 Some ( Expr {
768768 hir_id,
769769 kind : ExprKind :: Struct ( path, ..) ,
770770 ..
771- } ) => variant_of_res ( cx, cx. qpath_res ( path, * hir_id) )
772- . and_then ( |variant| variant. fields . iter ( ) . find ( |f| f. name == field. ident . name ) )
773- . map ( |field_def| {
774- ty_auto_deref_stability ( cx, cx. tcx . type_of ( field_def. did ) , precedence) . position_for_arg ( )
771+ } ) => adt_and_variant_of_res ( cx, cx. qpath_res ( path, * hir_id) )
772+ . and_then ( |( adt, variant) | {
773+ variant
774+ . fields
775+ . iter ( )
776+ . find ( |f| f. name == field. ident . name )
777+ . map ( |f| ( adt, f) )
778+ } )
779+ . map ( |( adt, field_def) | {
780+ ty_auto_deref_stability (
781+ cx. tcx ,
782+ // Use the param_env of the target type.
783+ cx. tcx . param_env ( adt. did ( ) ) ,
784+ cx. tcx . type_of ( field_def. did ) ,
785+ precedence,
786+ )
787+ . position_for_arg ( )
775788 } ) ,
776789 _ => None ,
777790 } ,
@@ -792,7 +805,7 @@ fn walk_parents<'tcx>(
792805 let output = cx
793806 . tcx
794807 . erase_late_bound_regions ( cx. tcx . fn_sig ( owner_id) . subst_identity ( ) . output ( ) ) ;
795- ty_auto_deref_stability ( cx, output, precedence) . position_for_result ( cx)
808+ ty_auto_deref_stability ( cx. tcx , cx . param_env , output, precedence) . position_for_result ( cx)
796809 } ,
797810 )
798811 } ,
@@ -835,15 +848,20 @@ fn walk_parents<'tcx>(
835848 msrv,
836849 )
837850 } else {
838- ty_auto_deref_stability ( cx, cx. tcx . erase_late_bound_regions ( ty) , precedence)
839- . position_for_arg ( )
851+ ty_auto_deref_stability (
852+ cx. tcx ,
853+ // Use the param_env of the target function.
854+ sig. predicates_id ( ) . map_or ( ParamEnv :: empty ( ) , |id| cx. tcx . param_env ( id) ) ,
855+ cx. tcx . erase_late_bound_regions ( ty) ,
856+ precedence
857+ ) . position_for_arg ( )
840858 }
841859 } ,
842860 }
843861 } )
844862 } ) ,
845863 ExprKind :: MethodCall ( method, receiver, args, _) => {
846- let id = cx. typeck_results ( ) . type_dependent_def_id ( parent. hir_id ) . unwrap ( ) ;
864+ let fn_id = cx. typeck_results ( ) . type_dependent_def_id ( parent. hir_id ) . unwrap ( ) ;
847865 if receiver. hir_id == child_id {
848866 // Check for calls to trait methods where the trait is implemented on a reference.
849867 // Two cases need to be handled:
@@ -852,13 +870,17 @@ fn walk_parents<'tcx>(
852870 // priority.
853871 if e. hir_id != child_id {
854872 return Some ( Position :: ReborrowStable ( precedence) )
855- } else if let Some ( trait_id) = cx. tcx . trait_of_item ( id )
873+ } else if let Some ( trait_id) = cx. tcx . trait_of_item ( fn_id )
856874 && let arg_ty = cx. tcx . erase_regions ( cx. typeck_results ( ) . expr_ty_adjusted ( e) )
857875 && let ty:: Ref ( _, sub_ty, _) = * arg_ty. kind ( )
858876 && let subs = cx
859877 . typeck_results ( )
860878 . node_substs_opt ( parent. hir_id ) . map ( |subs| & subs[ 1 ..] ) . unwrap_or_default ( )
861- && let impl_ty = if cx. tcx . fn_sig ( id) . subst_identity ( ) . skip_binder ( ) . inputs ( ) [ 0 ] . is_ref ( ) {
879+ && let impl_ty = if cx. tcx . fn_sig ( fn_id)
880+ . subst_identity ( )
881+ . skip_binder ( )
882+ . inputs ( ) [ 0 ] . is_ref ( )
883+ {
862884 // Trait methods taking `&self`
863885 sub_ty
864886 } else {
@@ -879,10 +901,13 @@ fn walk_parents<'tcx>(
879901 return Some ( Position :: MethodReceiver ) ;
880902 }
881903 args. iter ( ) . position ( |arg| arg. hir_id == child_id) . map ( |i| {
882- let ty = cx. tcx . fn_sig ( id ) . subst_identity ( ) . skip_binder ( ) . inputs ( ) [ i + 1 ] ;
904+ let ty = cx. tcx . fn_sig ( fn_id ) . subst_identity ( ) . input ( i + 1 ) ;
883905 // `e.hir_id == child_id` for https://github.com/rust-lang/rust-clippy/issues/9739
884906 // `method.args.is_none()` for https://github.com/rust-lang/rust-clippy/issues/9782
885- if e. hir_id == child_id && method. args . is_none ( ) && let ty:: Param ( param_ty) = ty. kind ( ) {
907+ if e. hir_id == child_id
908+ && method. args . is_none ( )
909+ && let ty:: Param ( param_ty) = ty. skip_binder ( ) . kind ( )
910+ {
886911 needless_borrow_impl_arg_position (
887912 cx,
888913 possible_borrowers,
@@ -895,8 +920,10 @@ fn walk_parents<'tcx>(
895920 )
896921 } else {
897922 ty_auto_deref_stability (
898- cx,
899- cx. tcx . erase_late_bound_regions ( cx. tcx . fn_sig ( id) . subst_identity ( ) . input ( i + 1 ) ) ,
923+ cx. tcx ,
924+ // Use the param_env of the target function.
925+ cx. tcx . param_env ( fn_id) ,
926+ cx. tcx . erase_late_bound_regions ( ty) ,
900927 precedence,
901928 )
902929 . position_for_arg ( )
@@ -1378,11 +1405,18 @@ impl<'tcx> TyPosition<'tcx> {
13781405}
13791406
13801407// Checks whether a type is stable when switching to auto dereferencing,
1381- fn ty_auto_deref_stability < ' tcx > ( cx : & LateContext < ' tcx > , ty : Ty < ' tcx > , precedence : i8 ) -> TyPosition < ' tcx > {
1408+ fn ty_auto_deref_stability < ' tcx > (
1409+ tcx : TyCtxt < ' tcx > ,
1410+ param_env : ParamEnv < ' tcx > ,
1411+ ty : Ty < ' tcx > ,
1412+ precedence : i8 ,
1413+ ) -> TyPosition < ' tcx > {
13821414 let ty:: Ref ( _, mut ty, _) = * ty. kind ( ) else {
13831415 return Position :: Other ( precedence) . into ( ) ;
13841416 } ;
13851417
1418+ ty = tcx. try_normalize_erasing_regions ( param_env, ty) . unwrap_or ( ty) ;
1419+
13861420 loop {
13871421 break match * ty. kind ( ) {
13881422 ty:: Ref ( _, ref_ty, _) => {
@@ -1423,9 +1457,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
14231457 | ty:: Closure ( ..)
14241458 | ty:: Never
14251459 | ty:: Tuple ( _)
1426- | ty:: Alias ( ty:: Projection , _) => {
1427- Position :: DerefStable ( precedence, ty. is_sized ( cx. tcx , cx. param_env . without_caller_bounds ( ) ) ) . into ( )
1428- } ,
1460+ | ty:: Alias ( ty:: Projection , _) => Position :: DerefStable ( precedence, ty. is_sized ( tcx, param_env) ) . into ( ) ,
14291461 } ;
14301462 }
14311463}
0 commit comments