From a7bc3198073f29d285ae36acf77ceda8032a548d Mon Sep 17 00:00:00 2001 From: Cam Swords Date: Mon, 1 Jul 2024 15:54:30 -0700 Subject: [PATCH] [move][move-2024] Add raw address support for patterns (#18482) ## Description This allows raw addresses to be used as pattern prefixes ## Test plan New tests --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: --- .../crates/move-compiler/src/parser/syntax.rs | 115 +++++++++--------- .../tests/move_2024/matching/raw_address.move | 11 ++ .../matching/raw_address_invalid.exp | 18 +++ .../matching/raw_address_invalid.move | 13 ++ 4 files changed, 102 insertions(+), 55 deletions(-) create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address.move create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address_invalid.exp create mode 100644 external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address_invalid.move diff --git a/external-crates/move/crates/move-compiler/src/parser/syntax.rs b/external-crates/move/crates/move-compiler/src/parser/syntax.rs index 385064bc486ce..895d27c68b4b5 100644 --- a/external-crates/move/crates/move-compiler/src/parser/syntax.rs +++ b/external-crates/move/crates/move-compiler/src/parser/syntax.rs @@ -2093,66 +2093,71 @@ fn parse_match_pattern(context: &mut Context) -> Result ok_with_loc!(context, { - let mut_ = parse_mut_opt(context)?; - let name_access_chain = parse_name_access_chain( - context, - /* macros */ false, - /* tyargs */ true, - || "a pattern entry", - )?; - - fn report_invalid_mut(context: &mut Context, mut_: Option) { - if let Some(loc) = mut_ { - let diag = diag!( - Syntax::UnexpectedToken, - (loc, "Invalid 'mut' keyword on non-variable pattern") - ); - context.env.add_diag(diag); + t @ (Tok::Mut | Tok::Identifier | Tok::NumValue) + if !matches!(t, Tok::NumValue) + || matches!(context.tokens.lookahead(), Ok(Tok::ColonColon)) => + { + ok_with_loc!(context, { + let mut_ = parse_mut_opt(context)?; + let name_access_chain = parse_name_access_chain( + context, + /* macros */ false, + /* tyargs */ true, + || "a pattern entry", + )?; + + fn report_invalid_mut(context: &mut Context, mut_: Option) { + if let Some(loc) = mut_ { + let diag = diag!( + Syntax::UnexpectedToken, + (loc, "Invalid 'mut' keyword on non-variable pattern") + ); + context.env.add_diag(diag); + } } - } - match context.tokens.peek() { - Tok::LParen => { - let mut pattern_start_set = VALUE_START_SET.clone(); - pattern_start_set.add_all(&[ - Tok::PeriodPeriod, - Tok::LParen, - Tok::Mut, - Tok::Identifier, - ]); - let (loc, patterns) = with_loc!( - context, - parse_comma_list( - context, + match context.tokens.peek() { + Tok::LParen => { + let mut pattern_start_set = VALUE_START_SET.clone(); + pattern_start_set.add_all(&[ + Tok::PeriodPeriod, Tok::LParen, - Tok::RParen, - &pattern_start_set, - parse_positional_field_pattern, - "a pattern", - ) - ); - report_invalid_mut(context, mut_); - MP::PositionalConstructor(name_access_chain, sp(loc, patterns)) - } - Tok::LBrace => { - let (loc, patterns) = with_loc!( - context, - parse_comma_list( + Tok::Mut, + Tok::Identifier, + ]); + let (loc, patterns) = with_loc!( context, - Tok::LBrace, - Tok::RBrace, - &TokenSet::from([Tok::PeriodPeriod, Tok::Mut, Tok::Identifier]), - parse_field_pattern, - "a field pattern", - ) - ); - report_invalid_mut(context, mut_); - MP::FieldConstructor(name_access_chain, sp(loc, patterns)) + parse_comma_list( + context, + Tok::LParen, + Tok::RParen, + &pattern_start_set, + parse_positional_field_pattern, + "a pattern", + ) + ); + report_invalid_mut(context, mut_); + MP::PositionalConstructor(name_access_chain, sp(loc, patterns)) + } + Tok::LBrace => { + let (loc, patterns) = with_loc!( + context, + parse_comma_list( + context, + Tok::LBrace, + Tok::RBrace, + &TokenSet::from([Tok::PeriodPeriod, Tok::Mut, Tok::Identifier]), + parse_field_pattern, + "a field pattern", + ) + ); + report_invalid_mut(context, mut_); + MP::FieldConstructor(name_access_chain, sp(loc, patterns)) + } + _ => MP::Name(mut_, name_access_chain), } - _ => MP::Name(mut_, name_access_chain), - } - }), + }) + } _ => { if let Some(value) = maybe_parse_value(context)? { Ok(sp(value.loc, MP::Literal(value))) diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address.move new file mode 100644 index 0000000000000..ea10dc7cdf977 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address.move @@ -0,0 +1,11 @@ +module 0x42::m; + +public enum E { + V0(u64, u64) +} + +public fun match_e(e: &E): (&u64, &u64) { + match (e) { + 0x42::m::E::V0(x, y) => (x, y), + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address_invalid.exp new file mode 100644 index 0000000000000..ec516162de735 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address_invalid.exp @@ -0,0 +1,18 @@ +error[E04007]: incompatible types + ┌─ tests/move_2024/matching/raw_address_invalid.move:10:9 + │ + 7 │ public fun match_e(e: &E, rx: &u64, ry: &u64): (&u64, &u64) { + │ - Expected: '0x42::m::E' + · +10 │ 0x42 => (rx, ry), + │ ^^^^ + │ │ + │ Invalid pattern + │ Given: integer + +error[E03006]: unexpected name in this position + ┌─ tests/move_2024/matching/raw_address_invalid.move:11:9 + │ +11 │ 0x42::m => (rx, ry), + │ ^^^^^^^ Unexpected module identifier. A module identifier is not a valid pattern constructor + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address_invalid.move b/external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address_invalid.move new file mode 100644 index 0000000000000..e9e29e9da6180 --- /dev/null +++ b/external-crates/move/crates/move-compiler/tests/move_2024/matching/raw_address_invalid.move @@ -0,0 +1,13 @@ +module 0x42::m; + +public enum E { + V0(u64, u64) +} + +public fun match_e(e: &E, rx: &u64, ry: &u64): (&u64, &u64) { + match (e) { + 0x42::m::E::V0(x, y) => (x, y), + 0x42 => (rx, ry), + 0x42::m => (rx, ry), + } +}