aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide/src/diagnostics.rs99
1 files changed, 94 insertions, 5 deletions
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs
index d3d8c86b5..c36c321f2 100644
--- a/crates/ide/src/diagnostics.rs
+++ b/crates/ide/src/diagnostics.rs
@@ -192,7 +192,8 @@ fn check_field_shorthand(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &Synt
192 match_ast! { 192 match_ast! {
193 match node { 193 match node {
194 ast::RecordExpr(it) => check_expr_field_shorthand(acc, file_id, it), 194 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 _ => ()
196 } 197 }
197 }; 198 };
198} 199}
@@ -200,11 +201,11 @@ fn check_field_shorthand(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &Synt
200fn check_expr_field_shorthand( 201fn check_expr_field_shorthand(
201 acc: &mut Vec<Diagnostic>, 202 acc: &mut Vec<Diagnostic>,
202 file_id: FileId, 203 file_id: FileId,
203 record_lit: ast::RecordExpr, 204 record_expr: ast::RecordExpr,
204) { 205) {
205 let record_field_list = match record_lit.record_expr_field_list() { 206 let record_field_list = match record_expr.record_expr_field_list() {
206 Some(it) => it, 207 Some(it) => it,
207 None => (), 208 None => return,
208 }; 209 };
209 for record_field in record_field_list.fields() { 210 for record_field in record_field_list.fields() {
210 let (name_ref, expr) = match record_field.name_ref().zip(record_field.expr()) { 211 let (name_ref, expr) = match record_field.name_ref().zip(record_field.expr()) {
@@ -239,6 +240,48 @@ fn check_expr_field_shorthand(
239 } 240 }
240} 241}
241 242
243fn 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
242#[cfg(test)] 285#[cfg(test)]
243mod tests { 286mod tests {
244 use expect_test::{expect, Expect}; 287 use expect_test::{expect, Expect};
@@ -735,7 +778,7 @@ mod a {
735 } 778 }
736 779
737 #[test] 780 #[test]
738 fn test_check_struct_shorthand_initialization() { 781 fn test_check_expr_field_shorthand() {
739 check_no_diagnostics( 782 check_no_diagnostics(
740 r#" 783 r#"
741struct A { a: &'static str } 784struct A { a: &'static str }
@@ -787,6 +830,52 @@ fn main() {
787 } 830 }
788 831
789 #[test] 832 #[test]
833 fn test_check_pat_field_shorthand() {
834 check_no_diagnostics(
835 r#"
836struct A { a: &'static str }
837fn f(a: A) { let A { a: hello } = a; }
838"#,
839 );
840 check_no_diagnostics(
841 r#"
842struct A(usize);
843fn f(a: A) { let A { 0: 0 } = a; }
844"#,
845 );
846
847 check_fix(
848 r#"
849struct A { a: &'static str }
850fn f(a: A) {
851 let A { a<|>: a } = a;
852}
853"#,
854 r#"
855struct A { a: &'static str }
856fn f(a: A) {
857 let A { a } = a;
858}
859"#,
860 );
861
862 check_fix(
863 r#"
864struct A { a: &'static str, b: &'static str }
865fn f(a: A) {
866 let A { a<|>: a, b } = a;
867}
868"#,
869 r#"
870struct A { a: &'static str, b: &'static str }
871fn f(a: A) {
872 let A { a, b } = a;
873}
874"#,
875 );
876 }
877
878 #[test]
790 fn test_add_field_from_usage() { 879 fn test_add_field_from_usage() {
791 check_fix( 880 check_fix(
792 r" 881 r"