Skip to content

Commit c518fe7

Browse files
bors[bot]popzxcbnjjj
authored
Merge #6130 #6135
6130: Items case quick fix (snake_case / UPPER_SNAKE_CASE / CamelCase) r=matklad a=popzxc Resolves #4598. After a third try, it finally works. Boy, it appeared tougher than it seemed. Initially I thought like "Ha, `rustc` already tells us where idents are named incorrectly. It shouldn't be that hard, should it?". Well, the problems with the information provided by `rustc` appeared shortly: - `rustc` warnings are `flycheck` warnings, which are slightly aside from our diagnostics with fixes. When we map flycheck diagnostic to LSP, we can convert it into a fix, but only if it's marked as `Applicability::MachineApplicable`. Name case fix is marked `Applicability::MaybeIncorrect`, and for a reason: it only suggest to rename symbol under cursor, without tracking any references. - Warning spawned by `rustc` are identified by string labels rather than enum. It means that if one day the diagnostic will be renamed in `rustc`, `rust-analyzer` code will still compile, but won't find the required diagnostic by name anymore. If by chance this will happen when some unlucky guy will decide to create their first pull request, they'll be confused by suddenly failing tests (likely) not related to their changes. - Even if we'll try to build fixes atop of `rustc` warnings, we'll have to do it in the `rust_analyzer::diagnostics::to_proto` module, which is far less convenient for that matter than `ide` crate. That's why I decided that it's worth a separate `rust-analyzer` diagnostic, which will implement `DiagnosticWithFix` trait. After that, I discovered that currently `hir_ty::diagnostics` only check `DefWithBody` types, like function bodies. I had to add support for diagnostics which look at any `ModuleDef`. And of course, since I'd added a lot of new functionality, it required extensive testing. That explains why the diff is so big for a (looking) relatively small feature. I hope that this PR doesn't only add a small feature, but also creates a base for building another features. ## Example: ![case_quick_fix](https://user-images.githubusercontent.com/12111581/95008475-e07ee780-0622-11eb-9978-62a9ea0e7782.gif) P.S. My eyes were bleeding when I had to write the code for the example... 6135: when generating new function, focus on return type instead of body r=matklad a=bnjjj I made a little change when we use the assist to generate a new function, instead of focusing on the function body, it will focus on return type Co-authored-by: Igor Aleksanov <[email protected]> Co-authored-by: Benjamin Coenen <[email protected]>
3 parents ef33953 + 991d019 + 3bfa3e8 commit c518fe7

File tree

15 files changed

+1407
-84
lines changed

15 files changed

+1407
-84
lines changed

crates/assists/src/handlers/generate_function.rs

Lines changed: 67 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ use crate::{
3636
// bar("", baz());
3737
// }
3838
//
39-
// fn bar(arg: &str, baz: Baz) {
40-
// ${0:todo!()}
39+
// fn bar(arg: &str, baz: Baz) ${0:-> ()} {
40+
// todo!()
4141
// }
4242
//
4343
// ```
@@ -80,21 +80,19 @@ pub(crate) fn generate_function(acc: &mut Assists, ctx: &AssistContext) -> Optio
8080

8181
struct FunctionTemplate {
8282
insert_offset: TextSize,
83-
placeholder_expr: ast::MacroCall,
8483
leading_ws: String,
8584
fn_def: ast::Fn,
85+
ret_type: ast::RetType,
8686
trailing_ws: String,
8787
file: FileId,
8888
}
8989

9090
impl FunctionTemplate {
9191
fn to_string(&self, cap: Option<SnippetCap>) -> String {
9292
let f = match cap {
93-
Some(cap) => render_snippet(
94-
cap,
95-
self.fn_def.syntax(),
96-
Cursor::Replace(self.placeholder_expr.syntax()),
97-
),
93+
Some(cap) => {
94+
render_snippet(cap, self.fn_def.syntax(), Cursor::Replace(self.ret_type.syntax()))
95+
}
9896
None => self.fn_def.to_string(),
9997
};
10098
format!("{}{}{}", self.leading_ws, f, self.trailing_ws)
@@ -141,8 +139,14 @@ impl FunctionBuilder {
141139
let placeholder_expr = make::expr_todo();
142140
let fn_body = make::block_expr(vec![], Some(placeholder_expr));
143141
let visibility = if self.needs_pub { Some(make::visibility_pub_crate()) } else { None };
144-
let mut fn_def =
145-
make::fn_(visibility, self.fn_name, self.type_params, self.params, fn_body);
142+
let mut fn_def = make::fn_(
143+
visibility,
144+
self.fn_name,
145+
self.type_params,
146+
self.params,
147+
fn_body,
148+
Some(make::ret_type(make::ty("()"))),
149+
);
146150
let leading_ws;
147151
let trailing_ws;
148152

@@ -163,12 +167,10 @@ impl FunctionBuilder {
163167
}
164168
};
165169

166-
let placeholder_expr =
167-
fn_def.syntax().descendants().find_map(ast::MacroCall::cast).unwrap();
168170
FunctionTemplate {
169171
insert_offset,
170-
placeholder_expr,
171172
leading_ws,
173+
ret_type: fn_def.ret_type().unwrap(),
172174
fn_def,
173175
trailing_ws,
174176
file: self.file,
@@ -349,8 +351,8 @@ fn foo() {
349351
bar();
350352
}
351353
352-
fn bar() {
353-
${0:todo!()}
354+
fn bar() ${0:-> ()} {
355+
todo!()
354356
}
355357
",
356358
)
@@ -376,8 +378,8 @@ impl Foo {
376378
}
377379
}
378380
379-
fn bar() {
380-
${0:todo!()}
381+
fn bar() ${0:-> ()} {
382+
todo!()
381383
}
382384
",
383385
)
@@ -400,8 +402,8 @@ fn foo1() {
400402
bar();
401403
}
402404
403-
fn bar() {
404-
${0:todo!()}
405+
fn bar() ${0:-> ()} {
406+
todo!()
405407
}
406408
407409
fn foo2() {}
@@ -426,8 +428,8 @@ mod baz {
426428
bar();
427429
}
428430
429-
fn bar() {
430-
${0:todo!()}
431+
fn bar() ${0:-> ()} {
432+
todo!()
431433
}
432434
}
433435
",
@@ -452,8 +454,8 @@ fn foo() {
452454
bar(baz());
453455
}
454456
455-
fn bar(baz: Baz) {
456-
${0:todo!()}
457+
fn bar(baz: Baz) ${0:-> ()} {
458+
todo!()
457459
}
458460
",
459461
);
@@ -485,8 +487,8 @@ impl Baz {
485487
}
486488
}
487489
488-
fn bar(baz: Baz) {
489-
${0:todo!()}
490+
fn bar(baz: Baz) ${0:-> ()} {
491+
todo!()
490492
}
491493
",
492494
)
@@ -506,8 +508,8 @@ fn foo() {
506508
bar("bar")
507509
}
508510
509-
fn bar(arg: &str) {
510-
${0:todo!()}
511+
fn bar(arg: &str) ${0:-> ()} {
512+
todo!()
511513
}
512514
"#,
513515
)
@@ -527,8 +529,8 @@ fn foo() {
527529
bar('x')
528530
}
529531
530-
fn bar(arg: char) {
531-
${0:todo!()}
532+
fn bar(arg: char) ${0:-> ()} {
533+
todo!()
532534
}
533535
"#,
534536
)
@@ -548,8 +550,8 @@ fn foo() {
548550
bar(42)
549551
}
550552
551-
fn bar(arg: i32) {
552-
${0:todo!()}
553+
fn bar(arg: i32) ${0:-> ()} {
554+
todo!()
553555
}
554556
",
555557
)
@@ -569,8 +571,8 @@ fn foo() {
569571
bar(42 as u8)
570572
}
571573
572-
fn bar(arg: u8) {
573-
${0:todo!()}
574+
fn bar(arg: u8) ${0:-> ()} {
575+
todo!()
574576
}
575577
",
576578
)
@@ -594,8 +596,8 @@ fn foo() {
594596
bar(x as u8)
595597
}
596598
597-
fn bar(x: u8) {
598-
${0:todo!()}
599+
fn bar(x: u8) ${0:-> ()} {
600+
todo!()
599601
}
600602
",
601603
)
@@ -617,8 +619,8 @@ fn foo() {
617619
bar(worble)
618620
}
619621
620-
fn bar(worble: ()) {
621-
${0:todo!()}
622+
fn bar(worble: ()) ${0:-> ()} {
623+
todo!()
622624
}
623625
",
624626
)
@@ -646,8 +648,8 @@ fn baz() {
646648
bar(foo())
647649
}
648650
649-
fn bar(foo: impl Foo) {
650-
${0:todo!()}
651+
fn bar(foo: impl Foo) ${0:-> ()} {
652+
todo!()
651653
}
652654
",
653655
)
@@ -673,8 +675,8 @@ fn foo() {
673675
bar(&baz())
674676
}
675677
676-
fn bar(baz: &Baz) {
677-
${0:todo!()}
678+
fn bar(baz: &Baz) ${0:-> ()} {
679+
todo!()
678680
}
679681
",
680682
)
@@ -702,8 +704,8 @@ fn foo() {
702704
bar(Baz::baz())
703705
}
704706
705-
fn bar(baz: Baz::Bof) {
706-
${0:todo!()}
707+
fn bar(baz: Baz::Bof) ${0:-> ()} {
708+
todo!()
707709
}
708710
",
709711
)
@@ -725,8 +727,8 @@ fn foo<T>(t: T) {
725727
bar(t)
726728
}
727729
728-
fn bar<T>(t: T) {
729-
${0:todo!()}
730+
fn bar<T>(t: T) ${0:-> ()} {
731+
todo!()
730732
}
731733
",
732734
)
@@ -756,8 +758,8 @@ fn foo() {
756758
bar(Baz::new);
757759
}
758760
759-
fn bar(arg: fn() -> Baz) {
760-
${0:todo!()}
761+
fn bar(arg: fn() -> Baz) ${0:-> ()} {
762+
todo!()
761763
}
762764
",
763765
)
@@ -781,8 +783,8 @@ fn foo() {
781783
bar(closure)
782784
}
783785
784-
fn bar(closure: impl Fn(i64) -> i64) {
785-
${0:todo!()}
786+
fn bar(closure: impl Fn(i64) -> i64) ${0:-> ()} {
787+
todo!()
786788
}
787789
",
788790
)
@@ -802,8 +804,8 @@ fn foo() {
802804
bar(baz)
803805
}
804806
805-
fn bar(baz: ()) {
806-
${0:todo!()}
807+
fn bar(baz: ()) ${0:-> ()} {
808+
todo!()
807809
}
808810
",
809811
)
@@ -827,8 +829,8 @@ fn foo() {
827829
bar(baz(), baz())
828830
}
829831
830-
fn bar(baz_1: Baz, baz_2: Baz) {
831-
${0:todo!()}
832+
fn bar(baz_1: Baz, baz_2: Baz) ${0:-> ()} {
833+
todo!()
832834
}
833835
",
834836
)
@@ -852,8 +854,8 @@ fn foo() {
852854
bar(baz(), baz(), "foo", "bar")
853855
}
854856
855-
fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) {
856-
${0:todo!()}
857+
fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) ${0:-> ()} {
858+
todo!()
857859
}
858860
"#,
859861
)
@@ -872,8 +874,8 @@ fn foo() {
872874
",
873875
r"
874876
mod bar {
875-
pub(crate) fn my_fn() {
876-
${0:todo!()}
877+
pub(crate) fn my_fn() ${0:-> ()} {
878+
todo!()
877879
}
878880
}
879881
@@ -911,8 +913,8 @@ fn bar() {
911913
baz(foo)
912914
}
913915
914-
fn baz(foo: foo::Foo) {
915-
${0:todo!()}
916+
fn baz(foo: foo::Foo) ${0:-> ()} {
917+
todo!()
916918
}
917919
",
918920
)
@@ -935,8 +937,8 @@ fn foo() {
935937
mod bar {
936938
fn something_else() {}
937939
938-
pub(crate) fn my_fn() {
939-
${0:todo!()}
940+
pub(crate) fn my_fn() ${0:-> ()} {
941+
todo!()
940942
}
941943
}
942944
@@ -963,8 +965,8 @@ fn foo() {
963965
r"
964966
mod bar {
965967
mod baz {
966-
pub(crate) fn my_fn() {
967-
${0:todo!()}
968+
pub(crate) fn my_fn() ${0:-> ()} {
969+
todo!()
968970
}
969971
}
970972
}
@@ -992,8 +994,8 @@ fn main() {
992994
r"
993995
994996
995-
pub(crate) fn bar() {
996-
${0:todo!()}
997+
pub(crate) fn bar() ${0:-> ()} {
998+
todo!()
997999
}",
9981000
)
9991001
}

crates/assists/src/tests/generated.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,8 @@ fn foo() {
454454
bar("", baz());
455455
}
456456
457-
fn bar(arg: &str, baz: Baz) {
458-
${0:todo!()}
457+
fn bar(arg: &str, baz: Baz) ${0:-> ()} {
458+
todo!()
459459
}
460460
461461
"#####,

0 commit comments

Comments
 (0)