diff options
author | Dawer <[email protected]> | 2021-05-20 19:50:27 +0100 |
---|---|---|
committer | Dawer <[email protected]> | 2021-05-20 19:56:26 +0100 |
commit | 570eff655208b5f7d28d2e0a587ee514b91b4a42 (patch) | |
tree | 38526138e7f4369ea3105274fc7fbcbdd7350a0c /crates/ide_assists | |
parent | 63d317c71a088bc20c6eee7d9ee71a7db44afde0 (diff) |
fix: `fill_match_arms` hangs on a tuple of large enums
Diffstat (limited to 'crates/ide_assists')
-rw-r--r-- | crates/ide_assists/src/handlers/fill_match_arms.rs | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/crates/ide_assists/src/handlers/fill_match_arms.rs b/crates/ide_assists/src/handlers/fill_match_arms.rs index 12ea17d7a..3532759bf 100644 --- a/crates/ide_assists/src/handlers/fill_match_arms.rs +++ b/crates/ide_assists/src/handlers/fill_match_arms.rs | |||
@@ -84,14 +84,26 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
84 | }; | 84 | }; |
85 | missing_pats.peekable() | 85 | missing_pats.peekable() |
86 | } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) { | 86 | } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) { |
87 | let mut n_arms = 1; | ||
88 | let variants_of_enums: Vec<Vec<ExtendedVariant>> = enum_defs | ||
89 | .into_iter() | ||
90 | .map(|enum_def| enum_def.variants(ctx.db())) | ||
91 | .inspect(|variants| n_arms *= variants.len()) | ||
92 | .collect(); | ||
93 | |||
87 | // When calculating the match arms for a tuple of enums, we want | 94 | // When calculating the match arms for a tuple of enums, we want |
88 | // to create a match arm for each possible combination of enum | 95 | // to create a match arm for each possible combination of enum |
89 | // values. The `multi_cartesian_product` method transforms | 96 | // values. The `multi_cartesian_product` method transforms |
90 | // Vec<Vec<EnumVariant>> into Vec<(EnumVariant, .., EnumVariant)> | 97 | // Vec<Vec<EnumVariant>> into Vec<(EnumVariant, .., EnumVariant)> |
91 | // where each tuple represents a proposed match arm. | 98 | // where each tuple represents a proposed match arm. |
92 | let missing_pats = enum_defs | 99 | |
100 | // A number of arms grows very fast on even a small tuple of large enums. | ||
101 | // We skip the assist beyond an arbitrary threshold. | ||
102 | if n_arms > 256 { | ||
103 | return None; | ||
104 | } | ||
105 | let missing_pats = variants_of_enums | ||
93 | .into_iter() | 106 | .into_iter() |
94 | .map(|enum_def| enum_def.variants(ctx.db())) | ||
95 | .multi_cartesian_product() | 107 | .multi_cartesian_product() |
96 | .map(|variants| { | 108 | .map(|variants| { |
97 | let patterns = | 109 | let patterns = |