@@ -10,8 +10,8 @@ use rustc_hir::{
1010 def:: { CtorOf , DefKind , Res } ,
1111 def_id:: LocalDefId ,
1212 intravisit:: { walk_inf, walk_ty, Visitor } ,
13- Expr , ExprKind , FnRetTy , FnSig , GenericArg , HirId , Impl , ImplItemKind , Item , ItemKind , Pat , PatKind , Path , QPath ,
14- TyKind ,
13+ Expr , ExprKind , FnRetTy , FnSig , GenericArg , GenericParam , GenericParamKind , HirId , Impl , ImplItemKind , Item ,
14+ ItemKind , Pat , PatKind , Path , QPath , Ty , TyKind ,
1515} ;
1616use rustc_hir_analysis:: hir_ty_to_ty;
1717use rustc_lint:: { LateContext , LateLintPass } ;
@@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
9696 // avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that
9797 // we're in an `impl` or nested item, that we don't want to lint
9898 let stack_item = if_chain ! {
99- if let ItemKind :: Impl ( Impl { self_ty, .. } ) = item. kind;
99+ if let ItemKind :: Impl ( Impl { self_ty, generics , .. } ) = item. kind;
100100 if let TyKind :: Path ( QPath :: Resolved ( _, item_path) ) = self_ty. kind;
101101 let parameters = & item_path. segments. last( ) . expect( SEGMENTS_MSG ) . args;
102102 if parameters. as_ref( ) . map_or( true , |params| {
@@ -105,10 +105,17 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
105105 if !item. span. from_expansion( ) ;
106106 if !is_from_proc_macro( cx, item) ; // expensive, should be last check
107107 then {
108+ // Self cannot be used inside const generic parameters
109+ let types_to_skip = generics. params. iter( ) . filter_map( |param| {
110+ match param {
111+ GenericParam { kind: GenericParamKind :: Const { ty: Ty { hir_id, ..} , ..} , ..} => Some ( * hir_id) ,
112+ _ => None ,
113+ }
114+ } ) . chain( std:: iter:: once( self_ty. hir_id) ) . collect( ) ;
108115 StackItem :: Check {
109116 impl_id: item. owner_id. def_id,
110117 in_body: 0 ,
111- types_to_skip: std :: iter :: once ( self_ty . hir_id ) . collect ( ) ,
118+ types_to_skip,
112119 }
113120 } else {
114121 StackItem :: NoCheck
0 commit comments