Skip to content

Commit 1022672

Browse files
committed
Diagnose shorthand in patterns as well
1 parent e9903a9 commit 1022672

File tree

1 file changed

+94
-5
lines changed

1 file changed

+94
-5
lines changed

crates/ide/src/diagnostics.rs

Lines changed: 94 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,19 +192,20 @@ fn check_field_shorthand(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &Synt
192192
match_ast! {
193193
match node {
194194
ast::RecordExpr(it) => check_expr_field_shorthand(acc, file_id, it),
195-
_ => None
195+
ast::RecordPat(it) => check_pat_field_shorthand(acc, file_id, it),
196+
_ => ()
196197
}
197198
};
198199
}
199200

200201
fn check_expr_field_shorthand(
201202
acc: &mut Vec<Diagnostic>,
202203
file_id: FileId,
203-
record_lit: ast::RecordExpr,
204+
record_expr: ast::RecordExpr,
204205
) {
205-
let record_field_list = match record_lit.record_expr_field_list() {
206+
let record_field_list = match record_expr.record_expr_field_list() {
206207
Some(it) => it,
207-
None => (),
208+
None => return,
208209
};
209210
for record_field in record_field_list.fields() {
210211
let (name_ref, expr) = match record_field.name_ref().zip(record_field.expr()) {
@@ -239,6 +240,48 @@ fn check_expr_field_shorthand(
239240
}
240241
}
241242

243+
fn check_pat_field_shorthand(
244+
acc: &mut Vec<Diagnostic>,
245+
file_id: FileId,
246+
record_pat: ast::RecordPat,
247+
) {
248+
let record_pat_field_list = match record_pat.record_pat_field_list() {
249+
Some(it) => it,
250+
None => return,
251+
};
252+
for record_pat_field in record_pat_field_list.fields() {
253+
let (name_ref, pat) = match record_pat_field.name_ref().zip(record_pat_field.pat()) {
254+
Some(it) => it,
255+
None => continue,
256+
};
257+
258+
let field_name = name_ref.syntax().text().to_string();
259+
let field_pat = pat.syntax().text().to_string();
260+
let field_name_is_tup_index = name_ref.as_tuple_field().is_some();
261+
if field_name != field_pat || field_name_is_tup_index {
262+
continue;
263+
}
264+
265+
let mut edit_builder = TextEdit::builder();
266+
edit_builder.delete(record_pat_field.syntax().text_range());
267+
edit_builder.insert(record_pat_field.syntax().text_range().start(), field_name);
268+
let edit = edit_builder.finish();
269+
270+
let field_range = record_pat_field.syntax().text_range();
271+
acc.push(Diagnostic {
272+
// name: None,
273+
range: field_range,
274+
message: "Shorthand struct pattern".to_string(),
275+
severity: Severity::WeakWarning,
276+
fix: Some(Fix::new(
277+
"Use struct field shorthand",
278+
SourceFileEdit { file_id, edit }.into(),
279+
field_range,
280+
)),
281+
});
282+
}
283+
}
284+
242285
#[cfg(test)]
243286
mod tests {
244287
use expect_test::{expect, Expect};
@@ -735,7 +778,7 @@ mod a {
735778
}
736779

737780
#[test]
738-
fn test_check_struct_shorthand_initialization() {
781+
fn test_check_expr_field_shorthand() {
739782
check_no_diagnostics(
740783
r#"
741784
struct A { a: &'static str }
@@ -786,6 +829,52 @@ fn main() {
786829
);
787830
}
788831

832+
#[test]
833+
fn test_check_pat_field_shorthand() {
834+
check_no_diagnostics(
835+
r#"
836+
struct A { a: &'static str }
837+
fn f(a: A) { let A { a: hello } = a; }
838+
"#,
839+
);
840+
check_no_diagnostics(
841+
r#"
842+
struct A(usize);
843+
fn f(a: A) { let A { 0: 0 } = a; }
844+
"#,
845+
);
846+
847+
check_fix(
848+
r#"
849+
struct A { a: &'static str }
850+
fn f(a: A) {
851+
let A { a<|>: a } = a;
852+
}
853+
"#,
854+
r#"
855+
struct A { a: &'static str }
856+
fn f(a: A) {
857+
let A { a } = a;
858+
}
859+
"#,
860+
);
861+
862+
check_fix(
863+
r#"
864+
struct A { a: &'static str, b: &'static str }
865+
fn f(a: A) {
866+
let A { a<|>: a, b } = a;
867+
}
868+
"#,
869+
r#"
870+
struct A { a: &'static str, b: &'static str }
871+
fn f(a: A) {
872+
let A { a, b } = a;
873+
}
874+
"#,
875+
);
876+
}
877+
789878
#[test]
790879
fn test_add_field_from_usage() {
791880
check_fix(

0 commit comments

Comments
 (0)