@@ -6,8 +6,9 @@ use clippy_utils::{get_parent_expr, is_lint_allowed, path_to_local, walk_to_expr
66use rustc_ast:: util:: parser:: { PREC_POSTFIX , PREC_PREFIX } ;
77use rustc_data_structures:: fx:: FxIndexMap ;
88use rustc_errors:: Applicability ;
9+ use rustc_hir:: intravisit:: { walk_ty, Visitor } ;
910use rustc_hir:: {
10- self as hir, BindingAnnotation , Body , BodyId , BorrowKind , Expr , ExprKind , FnRetTy , GenericArg , HirId , ImplItem ,
11+ self as hir, BindingAnnotation , Body , BodyId , BorrowKind , Expr , ExprKind , GenericArg , HirId , ImplItem ,
1112 ImplItemKind , Item , ItemKind , Local , MatchSource , Mutability , Node , Pat , PatKind , Path , QPath , TraitItem ,
1213 TraitItemKind , TyKind , UnOp ,
1314} ;
@@ -870,38 +871,32 @@ fn binding_ty_auto_deref_stability(ty: &hir::Ty<'_>, precedence: i8) -> Position
870871// Checks whether a type is inferred at some point.
871872// e.g. `_`, `Box<_>`, `[_]`
872873fn ty_contains_infer ( ty : & hir:: Ty < ' _ > ) -> bool {
873- match & ty . kind {
874- TyKind :: Slice ( ty ) | TyKind :: Array ( ty , _ ) => ty_contains_infer ( ty ) ,
875- TyKind :: Ptr ( ty ) | TyKind :: Rptr ( _ , ty) => ty_contains_infer ( ty . ty ) ,
876- TyKind :: Tup ( tys ) => tys . iter ( ) . any ( ty_contains_infer ) ,
877- TyKind :: BareFn ( ty ) => {
878- if ty. decl . inputs . iter ( ) . any ( ty_contains_infer ) {
879- return true ;
880- }
881- if let FnRetTy :: Return ( ty ) = & ty . decl . output {
882- ty_contains_infer ( ty )
874+ struct V ( bool ) ;
875+ impl Visitor < ' _ > for V {
876+ fn visit_ty ( & mut self , ty : & hir :: Ty < ' _ > ) {
877+ if self . 0
878+ || matches ! (
879+ ty. kind ,
880+ TyKind :: OpaqueDef ( .. ) | TyKind :: Infer | TyKind :: Typeof ( _ ) | TyKind :: Err
881+ )
882+ {
883+ self . 0 = true ;
883884 } else {
884- false
885+ walk_ty ( self , ty ) ;
885886 }
886- } ,
887- & TyKind :: Path (
888- QPath :: TypeRelative ( _, path)
889- | QPath :: Resolved (
890- _,
891- Path {
892- segments : [ .., path] , ..
893- } ,
894- ) ,
895- ) => path. args . map_or ( false , |args| {
896- args. args . iter ( ) . any ( |arg| match arg {
897- GenericArg :: Infer ( _) => true ,
898- GenericArg :: Type ( ty) => ty_contains_infer ( ty) ,
899- _ => false ,
900- } )
901- } ) ,
902- TyKind :: Path ( _) | TyKind :: OpaqueDef ( ..) | TyKind :: Infer | TyKind :: Typeof ( _) | TyKind :: Err => true ,
903- TyKind :: Never | TyKind :: TraitObject ( ..) => false ,
887+ }
888+
889+ fn visit_generic_arg ( & mut self , arg : & GenericArg < ' _ > ) {
890+ if self . 0 || matches ! ( arg, GenericArg :: Infer ( _) ) {
891+ self . 0 = true ;
892+ } else if let GenericArg :: Type ( ty) = arg {
893+ self . visit_ty ( ty) ;
894+ }
895+ }
904896 }
897+ let mut v = V ( false ) ;
898+ v. visit_ty ( ty) ;
899+ v. 0
905900}
906901
907902// Checks whether a type is stable when switching to auto dereferencing,
@@ -951,7 +946,7 @@ fn param_auto_deref_stability(ty: Ty<'_>, precedence: i8) -> Position {
951946
952947fn ty_contains_field ( ty : Ty < ' _ > , name : Symbol ) -> bool {
953948 if let ty:: Adt ( adt, _) = * ty. kind ( ) {
954- adt. is_struct ( ) && adt. non_enum_variant ( ) . fields . iter ( ) . any ( |f| f. name == name)
949+ adt. is_struct ( ) && adt. all_fields ( ) . any ( |f| f. name == name)
955950 } else {
956951 false
957952 }
0 commit comments