11use crate :: assist_context:: { AssistContext , Assists } ;
22use ide_db:: { assists:: AssistId , defs:: Definition , search:: SearchScope } ;
33use syntax:: {
4- AstNode , AstToken , SyntaxKind , T , TextRange ,
4+ AstNode , AstToken , SyntaxKind , T ,
55 ast:: {
66 self , HasDocComments , HasGenericParams , HasName , HasVisibility , edit:: AstNodeEdit ,
77 syntax_factory:: SyntaxFactory ,
@@ -173,22 +173,15 @@ fn used_params(
173173 make : & SyntaxFactory ,
174174 ctx : & AssistContext < ' _ , ' _ > ,
175175) -> Option < ast:: GenericParamList > {
176- let item_in_trait_range = |item| match item {
177- ast:: AssocItem :: Const ( _) | ast:: AssocItem :: MacroCall ( _) | ast:: AssocItem :: TypeAlias ( _) => {
178- item. syntax ( ) . text_range ( )
179- }
180- ast:: AssocItem :: Fn ( fn_item) => {
181- let range = fn_item. syntax ( ) . text_range ( ) ;
182- fn_item. body ( ) . map_or ( range, |body| {
183- TextRange :: new ( range. start ( ) , body. syntax ( ) . text_range ( ) . start ( ) )
184- } )
185- }
186- } ;
187- let trait_ranges = impl_ast
176+ let impl_only_ranges = impl_ast
188177 . assoc_item_list ( )
189178 . into_iter ( )
190179 . flat_map ( |list| list. assoc_items ( ) )
191- . map ( item_in_trait_range)
180+ . filter_map ( |item| match item {
181+ ast:: AssocItem :: Fn ( f) => Some ( f. body ( ) ?. syntax ( ) . text_range ( ) ) ,
182+ _ => None ,
183+ } )
184+ . chain ( impl_ast. self_ty ( ) . map ( |it| it. syntax ( ) . text_range ( ) ) )
192185 . collect :: < Vec < _ > > ( ) ;
193186 let used_in_impl = |param : & ast:: GenericParam | {
194187 let Some ( def) = ctx. sema . to_def ( param) else { return true } ;
@@ -197,7 +190,7 @@ fn used_params(
197190 . in_scope ( & SearchScope :: single_file ( ctx. file_id ( ) ) )
198191 . all ( )
199192 . file_ranges ( )
200- . any ( |it| trait_ranges . iter ( ) . any ( |range| range. contains_range ( it. range ) ) )
193+ . any ( |it| !impl_only_ranges . iter ( ) . any ( |range| range. contains_range ( it. range ) ) )
201194 } ;
202195 let params = impl_ast. generic_param_list ( ) ?;
203196 let mut params = params. generic_params ( ) . filter ( used_in_impl) . peekable ( ) ;
@@ -478,6 +471,32 @@ impl<T, const N: usize> SpecLen<T, N> for Foo<T, N> {
478471 fn spec_len(&self, other: [T; N]) -> usize {
479472 0
480473 }
474+ }
475+ "# ,
476+ ) ;
477+
478+ check_assist_no_snippet_cap (
479+ generate_trait_from_impl,
480+ r#"
481+ struct Foo<T, const N: usize>([T; N]);
482+
483+ impl<T, const N: usize> F$0oo<T, N> where T: Copy {
484+ fn spec_len(&self) -> usize {
485+ 0
486+ }
487+ }
488+ "# ,
489+ r#"
490+ struct Foo<T, const N: usize>([T; N]);
491+
492+ trait SpecLen<T> where T: Copy {
493+ fn spec_len(&self) -> usize;
494+ }
495+
496+ impl<T, const N: usize> SpecLen<T> for Foo<T, N> where T: Copy {
497+ fn spec_len(&self) -> usize {
498+ 0
499+ }
481500}
482501 "# ,
483502 ) ;
0 commit comments