@@ -6,6 +6,7 @@ use ide_db::{
66 source_change:: SourceChangeBuilder ,
77} ;
88use syntax:: ToSmolStr ;
9+ use syntax:: ast:: edit:: AstNodeEdit ;
910
1011use crate :: { Diagnostic , DiagnosticCode , DiagnosticsContext } ;
1112
@@ -23,33 +24,32 @@ pub(crate) fn trait_impl_redundant_assoc_item(
2324
2425 let default_range = d. impl_ . syntax_node_ptr ( ) . text_range ( ) ;
2526 let trait_name = d. trait_ . name ( db) . display_no_db ( ctx. edition ) . to_smolstr ( ) ;
27+ let indent_level = d. trait_ . source ( db) . map_or ( 0 , |it| it. value . indent_level ( ) . 0 ) + 1 ;
2628
2729 let ( redundant_item_name, diagnostic_range, redundant_item_def) = match assoc_item {
2830 hir:: AssocItem :: Function ( id) => {
2931 let function = id;
3032 (
3133 format ! ( "`fn {redundant_assoc_item_name}`" ) ,
3234 function. source ( db) . map ( |it| it. syntax ( ) . text_range ( ) ) . unwrap_or ( default_range) ,
33- format ! ( "\n {};" , function. display( db, ctx. display_target) ) ,
35+ format ! ( "\n {};" , function. display( db, ctx. display_target) ) ,
3436 )
3537 }
3638 hir:: AssocItem :: Const ( id) => {
3739 let constant = id;
3840 (
3941 format ! ( "`const {redundant_assoc_item_name}`" ) ,
4042 constant. source ( db) . map ( |it| it. syntax ( ) . text_range ( ) ) . unwrap_or ( default_range) ,
41- format ! ( "\n {};" , constant. display( db, ctx. display_target) ) ,
43+ format ! ( "\n {};" , constant. display( db, ctx. display_target) ) ,
4244 )
4345 }
4446 hir:: AssocItem :: TypeAlias ( id) => {
4547 let type_alias = id;
4648 (
4749 format ! ( "`type {redundant_assoc_item_name}`" ) ,
4850 type_alias. source ( db) . map ( |it| it. syntax ( ) . text_range ( ) ) . unwrap_or ( default_range) ,
49- format ! (
50- "\n type {};" ,
51- type_alias. name( ctx. sema. db) . display_no_db( ctx. edition) . to_smolstr( )
52- ) ,
51+ // FIXME cannot generate generic parameter and bounds
52+ format ! ( "\n type {};" , type_alias. name( ctx. sema. db) . display_no_db( ctx. edition) ) ,
5353 )
5454 }
5555 } ;
@@ -65,7 +65,7 @@ pub(crate) fn trait_impl_redundant_assoc_item(
6565 . with_fixes ( quickfix_for_redundant_assoc_item (
6666 ctx,
6767 d,
68- redundant_item_def,
68+ stdx :: indent_string ( redundant_item_def, indent_level ) . into ( ) ,
6969 diagnostic_range,
7070 ) )
7171}
@@ -191,6 +191,89 @@ impl Marker for Foo {
191191 )
192192 }
193193
194+ #[ test]
195+ fn quickfix_indentations ( ) {
196+ check_fix (
197+ r#"
198+ mod indent {
199+ trait Marker {
200+ fn boo();
201+ }
202+ struct Foo;
203+ impl Marker for Foo {
204+ fn$0 bar<T: Copy>(_a: i32, _b: T) -> String {}
205+ fn boo() {}
206+ }
207+ }
208+ "# ,
209+ r#"
210+ mod indent {
211+ trait Marker {
212+ fn bar<T>(_a: i32, _b: T) -> String
213+ where
214+ T: Copy,;
215+ fn boo();
216+ }
217+ struct Foo;
218+ impl Marker for Foo {
219+ fn bar<T: Copy>(_a: i32, _b: T) -> String {}
220+ fn boo() {}
221+ }
222+ }
223+ "# ,
224+ ) ;
225+
226+ check_fix (
227+ r#"
228+ mod indent {
229+ trait Marker {
230+ fn foo () {}
231+ }
232+ struct Foo;
233+ impl Marker for Foo {
234+ const FLAG: bool$0 = false;
235+ }
236+ }
237+ "# ,
238+ r#"
239+ mod indent {
240+ trait Marker {
241+ const FLAG: bool;
242+ fn foo () {}
243+ }
244+ struct Foo;
245+ impl Marker for Foo {
246+ const FLAG: bool = false;
247+ }
248+ }
249+ "# ,
250+ ) ;
251+
252+ check_fix (
253+ r#"
254+ mod indent {
255+ trait Marker {
256+ }
257+ struct Foo;
258+ impl Marker for Foo {
259+ type T = i32;$0
260+ }
261+ }
262+ "# ,
263+ r#"
264+ mod indent {
265+ trait Marker {
266+ type T;
267+ }
268+ struct Foo;
269+ impl Marker for Foo {
270+ type T = i32;
271+ }
272+ }
273+ "# ,
274+ ) ;
275+ }
276+
194277 #[ test]
195278 fn quickfix_dont_work ( ) {
196279 check_no_fix (
0 commit comments