diff options
-rw-r--r-- | crates/ide_assists/src/handlers/fill_match_arms.rs | 20 | ||||
-rw-r--r-- | crates/ide_assists/src/tests.rs | 21 |
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 | |||
279 | mod tests { | 280 | mod 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#" | ||
1072 | enum A { One, Two, } | ||
1073 | fn 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] | ||
66 | pub(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] |
65 | fn check_doc_test(assist_id: &str, before: &str, after: &str) { | 71 | fn 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 | ||
98 | enum ExpectedResult<'a> { | 104 | enum 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) => (), |