From 5cb3e7a41b89b5612cefe9c688f0ffdff18d4df4 Mon Sep 17 00:00:00 2001 From: fprasx Date: Wed, 3 Aug 2022 14:44:21 -0400 Subject: [PATCH 1/5] Added fixup for match statements w/ missing parts Passes tests --- crates/hir-expand/src/fixup.rs | 111 ++++++++++++++++++++++++++++++++- 1 file changed, 110 insertions(+), 1 deletion(-) diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs index e46f43a878..c875b23b2d 100644 --- a/crates/hir-expand/src/fixup.rs +++ b/crates/hir-expand/src/fixup.rs @@ -67,7 +67,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups { preorder.skip_subtree(); continue; } - // In some other situations, we can fix things by just appending some tokens. let end_range = TextRange::empty(node.text_range().end()); match_ast! { @@ -195,6 +194,69 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups { }, // FIXME: foo:: // FIXME: for, match etc. + ast::MatchExpr(it) => { + if it.expr().is_none() { + let match_token = match it.match_token() { + Some(t) => t, + None => continue + }; + append.insert(match_token.into(), vec![ + SyntheticToken { + kind: SyntaxKind::IDENT, + text: "__ra_fixup".into(), + range: end_range, + id: EMPTY_ID + }, + ]); + } + if it.match_arm_list().is_none() { + // No match arms + append.insert(node.clone().into(), vec![ + SyntheticToken { + kind: SyntaxKind::L_CURLY, + text: "{".into(), + range: end_range, + id: EMPTY_ID, + }, + SyntheticToken { + kind: SyntaxKind::UNDERSCORE, + text: "_".into(), + range: end_range, + id: EMPTY_ID + }, + SyntheticToken { + kind: SyntaxKind::EQ, + text: "=".into(), + range: end_range, + id: EMPTY_ID + }, + SyntheticToken { + kind: SyntaxKind::R_ANGLE, + text: ">".into(), + range: end_range, + id: EMPTY_ID + }, + SyntheticToken { + kind: SyntaxKind::L_CURLY, + text: "{".into(), + range: end_range, + id: EMPTY_ID, + }, + SyntheticToken { + kind: SyntaxKind::R_CURLY, + text: "}".into(), + range: end_range, + id: EMPTY_ID, + }, + SyntheticToken { + kind: SyntaxKind::R_CURLY, + text: "}".into(), + range: end_range, + id: EMPTY_ID, + }, + ]); + } + }, _ => (), } } @@ -287,6 +349,53 @@ mod tests { assert_eq!(tt.to_string(), original_as_tt.to_string()); } + + #[test] + fn match_no_expr_no_arms() { + check( + r#" +fn foo() { + match +} +"#, + expect![[r#" +fn foo () {match __ra_fixup {_ => {}}} +"#]], + ) + } + + #[test] + fn match_expr_no_arms() { + check( + r#" +fn foo() { + match x { + + } +} +"#, + expect![[r#" +fn foo () {match x {}} +"#]], + ) + } + + #[test] + fn match_no_expr() { + check( + r#" +fn foo() { + match { + _ => {} + } +} +"#, + expect![[r#" +fn foo () {match __ra_fixup {_ => {}}} +"#]], + ) + } + #[test] fn incomplete_field_expr_1() { check( From d513b4c8baaf2c71e5f13ce790bd0083ccb81a64 Mon Sep 17 00:00:00 2001 From: fprasx Date: Wed, 3 Aug 2022 15:51:30 -0400 Subject: [PATCH 2/5] Added fixup for for loops w/ missing parts --- crates/hir-expand/src/fixup.rs | 78 +++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs index c875b23b2d..ade28f27bf 100644 --- a/crates/hir-expand/src/fixup.rs +++ b/crates/hir-expand/src/fixup.rs @@ -193,7 +193,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups { } }, // FIXME: foo:: - // FIXME: for, match etc. ast::MatchExpr(it) => { if it.expr().is_none() { let match_token = match it.match_token() { @@ -257,6 +256,42 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups { ]); } }, + ast::ForExpr(it) => { + let for_token = match it.for_token() { + Some(token) => token, + None => continue + }; + + let [pat, in_token, iter] = [ + (SyntaxKind::UNDERSCORE, "_"), + (SyntaxKind::IN_KW, "in"), + (SyntaxKind::IDENT, "__ra_fixup") + ].map(|(kind, text)| SyntheticToken { kind, text: text.into(), range: end_range, id: EMPTY_ID}); + + if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() { + append.insert(for_token.into(), vec![pat, in_token, iter]); + } + + // Tricky: add logic to add in just a pattern or iterable if not all + // the pieces are missing + + if it.loop_body().is_none() { + append.insert(node.clone().into(), vec![ + SyntheticToken { + kind: SyntaxKind::L_CURLY, + text: "{".into(), + range: end_range, + id: EMPTY_ID, + }, + SyntheticToken { + kind: SyntaxKind::R_CURLY, + text: "}".into(), + range: end_range, + id: EMPTY_ID, + }, + ]); + } + }, _ => (), } } @@ -349,6 +384,47 @@ mod tests { assert_eq!(tt.to_string(), original_as_tt.to_string()); } + #[test] + fn for_no_iter_no_body() { + check( + r#" +fn foo() { + for +} +"#, + expect![[r#" +fn foo () {for _ in __ra_fixup {}} +"#]], + ) + } + + #[test] + fn for_no_iter() { + check( + r#" +fn foo() { + for {} +} +"#, + expect![[r#" +fn foo () {for _ in __ra_fixup {}} +"#]], + ) + } + + #[test] + fn for_no_body() { + check( + r#" +fn foo() { + for bar in qux +} +"#, + expect![[r#" +fn foo () {for bar in qux {}} +"#]], + ) + } #[test] fn match_no_expr_no_arms() { From ef2eabbfa84fb11deda705df724b28ef3431256c Mon Sep 17 00:00:00 2001 From: fprasx Date: Wed, 3 Aug 2022 16:27:43 -0400 Subject: [PATCH 3/5] Tidy formatted --- crates/hir-expand/src/fixup.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs index ade28f27bf..cd02c802e5 100644 --- a/crates/hir-expand/src/fixup.rs +++ b/crates/hir-expand/src/fixup.rs @@ -263,14 +263,14 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups { }; let [pat, in_token, iter] = [ - (SyntaxKind::UNDERSCORE, "_"), - (SyntaxKind::IN_KW, "in"), + (SyntaxKind::UNDERSCORE, "_"), + (SyntaxKind::IN_KW, "in"), (SyntaxKind::IDENT, "__ra_fixup") ].map(|(kind, text)| SyntheticToken { kind, text: text.into(), range: end_range, id: EMPTY_ID}); if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() { append.insert(for_token.into(), vec![pat, in_token, iter]); - } + } // Tricky: add logic to add in just a pattern or iterable if not all // the pieces are missing From d6d8a1c18f29ad6402f9594e3908cbb6d80aa31c Mon Sep 17 00:00:00 2001 From: fprasx Date: Thu, 4 Aug 2022 09:28:25 -0400 Subject: [PATCH 4/5] Shortened fixup for match, added cases for for Previously added a blank _ => {} for match statements --- crates/hir-expand/src/fixup.rs | 53 ++++++++++++---------------------- 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs index cd02c802e5..58d73f2d6c 100644 --- a/crates/hir-expand/src/fixup.rs +++ b/crates/hir-expand/src/fixup.rs @@ -217,36 +217,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups { range: end_range, id: EMPTY_ID, }, - SyntheticToken { - kind: SyntaxKind::UNDERSCORE, - text: "_".into(), - range: end_range, - id: EMPTY_ID - }, - SyntheticToken { - kind: SyntaxKind::EQ, - text: "=".into(), - range: end_range, - id: EMPTY_ID - }, - SyntheticToken { - kind: SyntaxKind::R_ANGLE, - text: ">".into(), - range: end_range, - id: EMPTY_ID - }, - SyntheticToken { - kind: SyntaxKind::L_CURLY, - text: "{".into(), - range: end_range, - id: EMPTY_ID, - }, - SyntheticToken { - kind: SyntaxKind::R_CURLY, - text: "}".into(), - range: end_range, - id: EMPTY_ID, - }, SyntheticToken { kind: SyntaxKind::R_CURLY, text: "}".into(), @@ -270,11 +240,12 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups { if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() { append.insert(for_token.into(), vec![pat, in_token, iter]); + } else if it.pat().is_none() { + append.insert(for_token.into(), vec![pat]); + } else if it.pat().is_none() && it.in_token().is_none() { + append.insert(for_token.into(), vec![pat, in_token]); } - // Tricky: add logic to add in just a pattern or iterable if not all - // the pieces are missing - if it.loop_body().is_none() { append.insert(node.clone().into(), vec![ SyntheticToken { @@ -398,6 +369,18 @@ fn foo () {for _ in __ra_fixup {}} ) } + fn for_no_iter_no_in() { + check( + r#" +fn foo() { + for _ {} +} +"#, + expect![[r#" +fn foo () {for _ in __ra_fixup {}} +"#]], + ) + } #[test] fn for_no_iter() { check( @@ -435,7 +418,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {match __ra_fixup {_ => {}}} +fn foo () {match __ra_fixup {}} "#]], ) } @@ -467,7 +450,7 @@ fn foo() { } "#, expect![[r#" -fn foo () {match __ra_fixup {_ => {}}} +fn foo () {match __ra_fixup {}} "#]], ) } From ab44a811501c12c4e3c471387f02ad451034639f Mon Sep 17 00:00:00 2001 From: fprasx Date: Thu, 4 Aug 2022 10:43:09 -0400 Subject: [PATCH 5/5] Fixed up for loops, added fixme with problem https://github.com/rust-lang/rust-analyzer/pull/12937#discussion_r937633695 --- crates/hir-expand/src/fixup.rs | 36 +++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs index 58d73f2d6c..46257b6bc4 100644 --- a/crates/hir-expand/src/fixup.rs +++ b/crates/hir-expand/src/fixup.rs @@ -240,10 +240,9 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups { if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() { append.insert(for_token.into(), vec![pat, in_token, iter]); + // does something funky -- see test case for_no_pat } else if it.pat().is_none() { append.insert(for_token.into(), vec![pat]); - } else if it.pat().is_none() && it.in_token().is_none() { - append.insert(for_token.into(), vec![pat, in_token]); } if it.loop_body().is_none() { @@ -356,7 +355,7 @@ mod tests { } #[test] - fn for_no_iter_no_body() { + fn just_for_token() { check( r#" fn foo() { @@ -369,20 +368,8 @@ fn foo () {for _ in __ra_fixup {}} ) } - fn for_no_iter_no_in() { - check( - r#" -fn foo() { - for _ {} -} -"#, - expect![[r#" -fn foo () {for _ in __ra_fixup {}} -"#]], - ) - } #[test] - fn for_no_iter() { + fn for_no_iter_pattern() { check( r#" fn foo() { @@ -409,6 +396,23 @@ fn foo () {for bar in qux {}} ) } + // FIXME: https://github.com/rust-lang/rust-analyzer/pull/12937#discussion_r937633695 + #[test] + fn for_no_pat() { + check( + r#" +fn foo() { + for in qux { + + } +} +"#, + expect![[r#" +fn foo () {__ra_fixup} +"#]], + ) + } + #[test] fn match_no_expr_no_arms() { check(