aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs20
-rw-r--r--crates/ide_assists/src/tests.rs21
2 files changed, 38 insertions, 3 deletions
diff --git a/crates/ide_assists/src/handlers/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs
index 3532759bf..97435f021 100644
--- a/crates/ide_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ide_assists/src/handlers/fill_match_arms.rs
@@ -105,6 +105,7 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
105 let missing_pats = variants_of_enums 105 let missing_pats = variants_of_enums
106 .into_iter() 106 .into_iter()
107 .multi_cartesian_product() 107 .multi_cartesian_product()
108 .inspect(|_| cov_mark::hit!(fill_match_arms_lazy_computation))
108 .map(|variants| { 109 .map(|variants| {
109 let patterns = 110 let patterns =
110 variants.into_iter().filter_map(|variant| build_pat(ctx.db(), module, variant)); 111 variants.into_iter().filter_map(|variant| build_pat(ctx.db(), module, variant));
@@ -279,7 +280,9 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: ExtendedVariant) -> Op
279mod tests { 280mod tests {
280 use ide_db::helpers::FamousDefs; 281 use ide_db::helpers::FamousDefs;
281 282
282 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 283 use crate::tests::{
284 check_assist, check_assist_not_applicable, check_assist_target, check_assist_unresolved,
285 };
283 286
284 use super::fill_match_arms; 287 use super::fill_match_arms;
285 288
@@ -1058,4 +1061,19 @@ fn foo(t: Test) {
1058}"#, 1061}"#,
1059 ); 1062 );
1060 } 1063 }
1064
1065 #[test]
1066 fn lazy_computation() {
1067 // Computing a single missing arm is enough to determine applicability of the assist.
1068 cov_mark::check_count!(fill_match_arms_lazy_computation, 1);
1069 check_assist_unresolved(
1070 fill_match_arms,
1071 r#"
1072enum A { One, Two, }
1073fn foo(tuple: (A, A)) {
1074 match $0tuple {};
1075}
1076"#,
1077 );
1078 }
1061} 1079}
diff --git a/crates/ide_assists/src/tests.rs b/crates/ide_assists/src/tests.rs
index 0d3969c36..b091ab91a 100644
--- a/crates/ide_assists/src/tests.rs
+++ b/crates/ide_assists/src/tests.rs
@@ -61,6 +61,12 @@ pub(crate) fn check_assist_not_applicable(assist: Handler, ra_fixture: &str) {
61 check(assist, ra_fixture, ExpectedResult::NotApplicable, None); 61 check(assist, ra_fixture, ExpectedResult::NotApplicable, None);
62} 62}
63 63
64/// Check assist in unresolved state. Useful to check assists for lazy computation.
65#[track_caller]
66pub(crate) fn check_assist_unresolved(assist: Handler, ra_fixture: &str) {
67 check(assist, ra_fixture, ExpectedResult::Unresolved, None);
68}
69
64#[track_caller] 70#[track_caller]
65fn check_doc_test(assist_id: &str, before: &str, after: &str) { 71fn check_doc_test(assist_id: &str, before: &str, after: &str) {
66 let after = trim_indent(after); 72 let after = trim_indent(after);
@@ -97,6 +103,7 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) {
97 103
98enum ExpectedResult<'a> { 104enum ExpectedResult<'a> {
99 NotApplicable, 105 NotApplicable,
106 Unresolved,
100 After(&'a str), 107 After(&'a str),
101 Target(&'a str), 108 Target(&'a str),
102} 109}
@@ -111,7 +118,11 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
111 let sema = Semantics::new(&db); 118 let sema = Semantics::new(&db);
112 let config = TEST_CONFIG; 119 let config = TEST_CONFIG;
113 let ctx = AssistContext::new(sema, &config, frange); 120 let ctx = AssistContext::new(sema, &config, frange);
114 let mut acc = Assists::new(&ctx, AssistResolveStrategy::All); 121 let resolve = match expected {
122 ExpectedResult::Unresolved => AssistResolveStrategy::None,
123 _ => AssistResolveStrategy::All,
124 };
125 let mut acc = Assists::new(&ctx, resolve);
115 handler(&mut acc, &ctx); 126 handler(&mut acc, &ctx);
116 let mut res = acc.finish(); 127 let mut res = acc.finish();
117 128
@@ -159,8 +170,14 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label:
159 let range = assist.target; 170 let range = assist.target;
160 assert_eq_text!(&text_without_caret[range], target); 171 assert_eq_text!(&text_without_caret[range], target);
161 } 172 }
173 (Some(assist), ExpectedResult::Unresolved) => assert!(
174 assist.source_change.is_none(),
175 "unresolved assist should not contain source changes"
176 ),
162 (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"), 177 (Some(_), ExpectedResult::NotApplicable) => panic!("assist should not be applicable!"),
163 (None, ExpectedResult::After(_)) | (None, ExpectedResult::Target(_)) => { 178 (None, ExpectedResult::After(_))
179 | (None, ExpectedResult::Target(_))
180 | (None, ExpectedResult::Unresolved) => {
164 panic!("code action is not applicable") 181 panic!("code action is not applicable")
165 } 182 }
166 (None, ExpectedResult::NotApplicable) => (), 183 (None, ExpectedResult::NotApplicable) => (),