From 9791173574abd579c544138e9216245cd2cbd614 Mon Sep 17 00:00:00 2001 From: Emily Herbert <17410721+emilyaherbert@users.noreply.github.com> Date: Thu, 16 Jun 2022 18:15:44 -0500 Subject: [PATCH] Fix unnecessary check inside of the match exhaustivity algorithm (#2009) * Allow for nested patterns. * Remove the comment in code. --- .../analysis/constructor_factory.rs | 9 ++---- .../match_expression/analysis/pattern.rs | 23 ++++----------- test/src/e2e_vm_tests/mod.rs | 4 +++ .../match_expressions_with_self/Forc.lock | 14 ++++++++++ .../match_expressions_with_self/Forc.toml | 8 ++++++ .../json_abi_oracle.json | 14 ++++++++++ .../match_expressions_with_self/src/main.sw | 28 +++++++++++++++++++ 7 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/Forc.lock create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/Forc.toml create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/json_abi_oracle.json create mode 100644 test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/src/main.sw diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/analysis/constructor_factory.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/analysis/constructor_factory.rs index 3c555805692..85bf6ede2a1 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/analysis/constructor_factory.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/analysis/constructor_factory.rs @@ -629,16 +629,11 @@ impl ConstructorFactory { } fn resolve_possible_types(&self, pattern: &Pattern, span: &Span) -> CompileResult<&TypeInfo> { - let mut warnings = vec![]; + let warnings = vec![]; let mut errors = vec![]; let mut type_info = None; for possible_type in self.possible_types.iter() { - let matches = check!( - pattern.matches_type_info(possible_type, span), - continue, - warnings, - errors - ); + let matches = pattern.matches_type_info(possible_type, span); if matches { type_info = Some(possible_type); break; diff --git a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/analysis/pattern.rs b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/analysis/pattern.rs index 2d62983bf90..b8ef31573db 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/match_expression/analysis/pattern.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/match_expression/analysis/pattern.rs @@ -657,13 +657,7 @@ impl Pattern { } } - pub(crate) fn matches_type_info( - &self, - type_info: &TypeInfo, - span: &Span, - ) -> CompileResult { - let warnings = vec![]; - let mut errors = vec![]; + pub(crate) fn matches_type_info(&self, type_info: &TypeInfo, span: &Span) -> bool { match (self, type_info) { (pattern, TypeInfo::Ref(type_id, _)) => { pattern.matches_type_info(&look_up_type_id(*type_id), span) @@ -680,20 +674,13 @@ impl Pattern { .. }, ) => { - let res = l_enum_name.as_str() == r_enum_name.as_str() + l_enum_name.as_str() == r_enum_name.as_str() && variant_types .iter() - .map(|x| x.name.clone()) - .any(|x| x.as_str() == variant_name.as_str()); - ok(res, warnings, errors) - } - _ => { - errors.push(CompileError::Unimplemented( - "cannot yet compare this pattern with this type", - span.clone(), - )); - err(warnings, errors) + .map(|variant_type| variant_type.name.clone()) + .any(|name| name.as_str() == variant_name.as_str()) } + _ => false, // NOTE: We may need to expand this in the future } } diff --git a/test/src/e2e_vm_tests/mod.rs b/test/src/e2e_vm_tests/mod.rs index 66f5aca0885..b0d857f803c 100644 --- a/test/src/e2e_vm_tests/mod.rs +++ b/test/src/e2e_vm_tests/mod.rs @@ -443,6 +443,10 @@ pub fn run(locked: bool, filter_regex: Option) { 0xdc, 0xe7, 0x7f, 0x70, ])), // "ReturnData":{"data":"0000000000000002", .. } ), + ( + "should_pass/language/match_expressions_with_self", + ProgramState::Return(1), + ), ( "should_pass/test_contracts/auth_testing_contract", ProgramState::Revert(0), diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/Forc.lock b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/Forc.lock new file mode 100644 index 00000000000..1c101b4c728 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/Forc.lock @@ -0,0 +1,14 @@ +[[package]] +name = 'abort_control_flow_good' +source = 'root' +dependencies = ['std'] + +[[package]] +name = 'core' +source = 'path+from-root-CB060A17C0778A7E' +dependencies = [] + +[[package]] +name = 'std' +source = 'path+from-root-CB060A17C0778A7E' +dependencies = ['core'] diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/Forc.toml b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/Forc.toml new file mode 100644 index 00000000000..6b4d9494e92 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/Forc.toml @@ -0,0 +1,8 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "abort_control_flow_good" + +[dependencies] +std = { path = "../../../../../../../sway-lib-std" } diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/json_abi_oracle.json b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/json_abi_oracle.json new file mode 100644 index 00000000000..905c3bd1034 --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/json_abi_oracle.json @@ -0,0 +1,14 @@ +[ + { + "inputs": [], + "name": "main", + "outputs": [ + { + "components": null, + "name": "", + "type": "u64" + } + ], + "type": "function" + } +] \ No newline at end of file diff --git a/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/src/main.sw b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/src/main.sw new file mode 100644 index 00000000000..0f6d57753cd --- /dev/null +++ b/test/src/e2e_vm_tests/test_programs/should_pass/language/match_expressions_with_self/src/main.sw @@ -0,0 +1,28 @@ +script; + +use core::ops::Eq; +use std::assert::*; + +enum Initialized { + True: (), + False: (), +} + +impl Eq for Initialized { + fn eq(self, other: Self) -> bool { + match (self, other) { + (Initialized::True, Initialized::True) => true, + (Initialized::False, Initialized::False) => true, + _ => false, + } + } +} + +fn main() -> u64 { + let a = Initialized::True; + let b = Initialized::False; + let c = a == b; + assert(c == false); + + 1 +}