aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDawer <[email protected]>2021-05-20 19:50:27 +0100
committerDawer <[email protected]>2021-05-20 19:56:26 +0100
commit570eff655208b5f7d28d2e0a587ee514b91b4a42 (patch)
tree38526138e7f4369ea3105274fc7fbcbdd7350a0c
parent63d317c71a088bc20c6eee7d9ee71a7db44afde0 (diff)
fix: `fill_match_arms` hangs on a tuple of large enums
-rw-r--r--crates/ide_assists/src/handlers/fill_match_arms.rs16
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 =