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), + } +}