diff --git a/external-crates/move/crates/move-analyzer/src/symbols.rs b/external-crates/move/crates/move-analyzer/src/symbols.rs index 1419b5e53b49b..f9702b14fce8c 100644 --- a/external-crates/move/crates/move-analyzer/src/symbols.rs +++ b/external-crates/move/crates/move-analyzer/src/symbols.rs @@ -2108,6 +2108,7 @@ impl<'a> ParsingSymbolicator<'a> { } T::Multiple(v) => v.iter().for_each(|t| self.type_symbols(t)), T::Unit => (), + T::UnresolvedError => (), } } diff --git a/external-crates/move/crates/move-compiler/src/diagnostics/mod.rs b/external-crates/move/crates/move-compiler/src/diagnostics/mod.rs index 7cb9c91bdd8ea..3a91da1737a64 100644 --- a/external-crates/move/crates/move-compiler/src/diagnostics/mod.rs +++ b/external-crates/move/crates/move-compiler/src/diagnostics/mod.rs @@ -537,6 +537,17 @@ impl Diagnostics { .any(|d| d.info.external_prefix() == Some(prefix)) } + /// Returns true if any diagnostic in the Syntax category have already been recorded. + pub fn any_syntax_error_with_primary_loc(&self, loc: Loc) -> bool { + let Self(Some(inner)) = self else { + return false; + }; + inner + .diagnostics + .iter() + .any(|d| d.info().category() == Category::Syntax as u8 && d.primary_label.0 == loc) + } + /// Returns the number of diags filtered in source (user) code (an not in the dependencies) that /// have a given prefix (first value returned) and how many different categories of diags were /// filtered. @@ -622,6 +633,10 @@ impl Diagnostic { &self.primary_label.1 } + pub fn primary_loc(&self) -> Loc { + self.primary_label.0 + } + pub fn is_migration(&self) -> bool { const MIGRATION_CATEGORY: u8 = codes::Category::Migration as u8; self.info.category() == MIGRATION_CATEGORY diff --git a/external-crates/move/crates/move-compiler/src/expansion/translate.rs b/external-crates/move/crates/move-compiler/src/expansion/translate.rs index e0104eb69569f..348a18ac8b8a4 100644 --- a/external-crates/move/crates/move-compiler/src/expansion/translate.rs +++ b/external-crates/move/crates/move-compiler/src/expansion/translate.rs @@ -2312,6 +2312,7 @@ fn type_(context: &mut Context, sp!(loc, pt_): P::Type) -> E::Type { let result = type_(context, *result); ET::Fun(args, Box::new(result)) } + PT::UnresolvedError => ET::UnresolvedError, }; sp(loc, t_) } @@ -2343,6 +2344,20 @@ fn optional_types(context: &mut Context, pts_opt: Option>) -> Optio #[growing_stack] fn sequence(context: &mut Context, loc: Loc, seq: P::Sequence) -> E::Sequence { + // removes an unresolved sequence item if it is the only item in the sequence + fn remove_single_unresolved(items: &mut VecDeque) -> Option> { + if items.len() != 1 { + return None; + } + let seq_item = items.pop_front().unwrap(); + if let E::SequenceItem_::Seq(exp) = &seq_item.value { + if exp.value == E::Exp_::UnresolvedError { + return Some(exp.clone()); + } + } + items.push_front(seq_item); + None + } let (puses, pitems, maybe_last_semicolon_loc, pfinal_item) = seq; let (new_scope, use_funs_builder) = uses(context, puses); @@ -2355,11 +2370,17 @@ fn sequence(context: &mut Context, loc: Loc, seq: P::Sequence) -> E::Sequence { let final_e_opt = pfinal_item.map(|item| exp(context, Box::new(item))); let final_e = match final_e_opt { None => { - let last_semicolon_loc = match maybe_last_semicolon_loc { - Some(l) => l, - None => loc, - }; - Box::new(sp(last_semicolon_loc, E::Exp_::Unit { trailing: true })) + // if there is only one item in the sequence and it is unresolved, do not generated the + // final sequence unit-typed expression + if let Some(unresolved) = remove_single_unresolved(&mut items) { + unresolved + } else { + let last_semicolon_loc = match maybe_last_semicolon_loc { + Some(l) => l, + None => loc, + }; + Box::new(sp(last_semicolon_loc, E::Exp_::Unit { trailing: true })) + } } Some(e) => e, }; diff --git a/external-crates/move/crates/move-compiler/src/parser/ast.rs b/external-crates/move/crates/move-compiler/src/parser/ast.rs index 20fc8e545de90..c8af8f9bf9776 100644 --- a/external-crates/move/crates/move-compiler/src/parser/ast.rs +++ b/external-crates/move/crates/move-compiler/src/parser/ast.rs @@ -395,6 +395,7 @@ pub enum Type_ { // (t1, t2, ... , tn) // Used for return values and expression blocks Multiple(Vec), + UnresolvedError, } pub type Type = Spanned; @@ -1270,6 +1271,7 @@ impl fmt::Display for Type_ { write!(f, "{}", format_comma(tys))?; write!(f, ")") } + UnresolvedError => write!(f, "_|_"), } } } @@ -1779,6 +1781,7 @@ impl AstDebug for Type_ { w.write("):"); result.ast_debug(w); } + Type_::UnresolvedError => w.write("_|_"), } } } diff --git a/external-crates/move/crates/move-compiler/src/parser/lexer.rs b/external-crates/move/crates/move-compiler/src/parser/lexer.rs index ee49f9d705083..55a58081feace 100644 --- a/external-crates/move/crates/move-compiler/src/parser/lexer.rs +++ b/external-crates/move/crates/move-compiler/src/parser/lexer.rs @@ -6,13 +6,16 @@ use crate::{ diag, diagnostics::Diagnostic, editions::{create_feature_error, Edition, FeatureGate}, - parser::syntax::make_loc, + parser::{syntax::make_loc, token_set::TokenSet}, shared::CompilationEnv, FileCommentMap, MatchedFileCommentMap, }; use move_command_line_common::{character_sets::DisplayChar, files::FileHash}; use move_ir_types::location::Loc; -use std::fmt; +use std::{collections::BTreeSet, fmt}; + +// This should be replaced with std::mem::variant::count::() if it ever comes out of nightly. +pub const TOK_COUNT: usize = 77; #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum Tok { @@ -182,7 +185,7 @@ impl fmt::Display for Tok { } pub struct Lexer<'input> { - text: &'input str, + pub text: &'input str, file_hash: FileHash, edition: Edition, doc_comments: FileCommentMap, @@ -216,6 +219,18 @@ impl<'input> Lexer<'input> { &self.text[self.cur_start..] } + pub fn at(&self, tok: Tok) -> bool { + self.token == tok + } + + pub fn at_any(&self, toks: &BTreeSet) -> bool { + toks.contains(&self.token) + } + + pub fn at_set(&self, set: &TokenSet) -> bool { + set.contains(self.token, self.content()) + } + pub fn content(&self) -> &'input str { &self.text[self.cur_start..self.cur_end] } diff --git a/external-crates/move/crates/move-compiler/src/parser/mod.rs b/external-crates/move/crates/move-compiler/src/parser/mod.rs index 7f04c9488ffde..7c1eb70f41cfd 100644 --- a/external-crates/move/crates/move-compiler/src/parser/mod.rs +++ b/external-crates/move/crates/move-compiler/src/parser/mod.rs @@ -8,6 +8,7 @@ pub(crate) mod filter; pub mod keywords; pub mod lexer; pub(crate) mod syntax; +mod token_set; pub(crate) mod verification_attribute_filter; use crate::{ 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 fe882375130f0..b5edf3299790a 100644 --- a/external-crates/move/crates/move-compiler/src/parser/syntax.rs +++ b/external-crates/move/crates/move-compiler/src/parser/syntax.rs @@ -10,7 +10,7 @@ use crate::{ diag, diagnostics::{Diagnostic, Diagnostics}, editions::{Edition, FeatureGate, UPGRADE_NOTE}, - parser::{ast::*, lexer::*}, + parser::{ast::*, lexer::*, token_set::*}, shared::*, MatchedFileCommentMap, }; @@ -24,6 +24,7 @@ struct Context<'env, 'lexer, 'input> { current_package: Option, env: &'env mut CompilationEnv, tokens: &'lexer mut Lexer<'input>, + stop_set: TokenSet, } impl<'env, 'lexer, 'input> Context<'env, 'lexer, 'input> { @@ -32,25 +33,58 @@ impl<'env, 'lexer, 'input> Context<'env, 'lexer, 'input> { tokens: &'lexer mut Lexer<'input>, package_name: Option, ) -> Self { + let stop_set = TokenSet::from([Tok::EOF]); Self { current_package: package_name, env, tokens, + stop_set, + } + } + + /// Checks if the current token is a member of the stop set. + fn at_stop_set(&self) -> bool { + self.tokens.at_set(&self.stop_set) + } + + /// Advances tokens until reaching an element of the stop set, recording diagnostics along the + /// way (including the first optional one passed as an argument). + fn advance_until_stop_set(&mut self, diag_opt: Option) { + if let Some(diag) = diag_opt { + self.add_diag(diag); + } + while !self.at_stop_set() { + if let Err(err) = self.tokens.advance() { + self.add_diag(*err); + } } } fn at_end(&self, prev: Loc) -> bool { prev.end() as usize == self.tokens.start_loc() } + + /// Advances token and records a resulting diagnostic (if any). + fn advance(&mut self) { + if let Err(diag) = self.tokens.advance() { + self.add_diag(*diag); + } + } + + fn add_diag(&mut self, diag: Diagnostic) { + self.env.add_diag(diag); + } } //************************************************************************************************** // Error Handling //************************************************************************************************** +const EOF_ERROR_STR: &str = "end-of-file"; + fn current_token_error_string(tokens: &Lexer) -> String { if tokens.peek() == Tok::EOF { - "end-of-file".to_string() + EOF_ERROR_STR.to_string() } else { format!("'{}'", tokens.content()) } @@ -269,19 +303,47 @@ fn parse_comma_list( context: &mut Context, start_token: Tok, end_token: Tok, + item_first_set: &TokenSet, parse_list_item: F, item_description: &str, -) -> Result, Box> +) -> Vec where F: Fn(&mut Context) -> Result>, { let start_loc = context.tokens.start_loc(); - consume_token(context.tokens, start_token)?; + let at_start_token = context.tokens.at(start_token); + if let Err(diag) = consume_token(context.tokens, start_token) { + if !at_start_token { + // not even starting token is present - parser has nothing much to do + context.add_diag(*diag); + return vec![]; + } + // advance token past the starting one but something went wrong, still there is a chance + // parse the rest of the list + advance_separated_items_error( + context, + start_token, + end_token, + /* separator */ Tok::Comma, + /* for list */ true, + *diag, + ); + if context.at_stop_set() { + // nothing else to do + return vec![]; + } + if context.tokens.at(end_token) { + // at the end of the list - consume end token and keep parsing at the outer level + context.advance(); + return vec![]; + } + } parse_comma_list_after_start( context, start_loc, start_token, end_token, + item_first_set, parse_list_item, item_description, ) @@ -294,45 +356,140 @@ fn parse_comma_list_after_start( start_loc: usize, start_token: Tok, end_token: Tok, + item_first_set: &TokenSet, parse_list_item: F, item_description: &str, -) -> Result, Box> +) -> Vec where F: Fn(&mut Context) -> Result>, { adjust_token(context.tokens, end_token); - if match_token(context.tokens, end_token)? { - return Ok(vec![]); - } let mut v = vec![]; - loop { - if context.tokens.peek() == Tok::Comma { + while !context.tokens.at(end_token) { + if context.tokens.at_set(item_first_set) { + match parse_list_item(context) { + Ok(item) => { + v.push(item); + adjust_token(context.tokens, end_token); + if context.tokens.peek() == end_token || context.at_stop_set() { + break; + } + // expect a commma - since we are not at stop set, consume it or advance to the + // next time or end of the list + if context.tokens.at(Tok::Comma) { + context.advance(); + } else { + let diag = unexpected_token_error( + context.tokens, + &format_oxford_list!("or", "'{}'", &[Tok::Comma, end_token]), + ); + advance_separated_items_error( + context, + start_token, + end_token, + /* separator */ Tok::Comma, + /* for list */ true, + *diag, + ); + if context.at_stop_set() { + break; + } + } + adjust_token(context.tokens, end_token); + // everything worked out so simply continue + continue; + } + Err(diag) => { + advance_separated_items_error( + context, + start_token, + end_token, + /* separator */ Tok::Comma, + /* for list */ true, + *diag, + ); + } + } + } else { let current_loc = context.tokens.start_loc(); let loc = make_loc(context.tokens.file_hash(), current_loc, current_loc); - return Err(Box::new(diag!( + let diag = diag!( Syntax::UnexpectedToken, (loc, format!("Expected {}", item_description)) - ))); + ); + advance_separated_items_error( + context, + start_token, + end_token, + /* separator */ Tok::Comma, + /* for list */ true, + diag, + ); } - v.push(parse_list_item(context)?); - adjust_token(context.tokens, end_token); - if match_token(context.tokens, end_token)? { - break Ok(v); + // The stop set check is done at the end of the loop on purpose as we need to attempt + // parsing before checking it. If we do not, in the best case, we will get a less meaningful + // error message if the item belongs to the token set incorrectly (e.g., `fun` keyword), and + // in the worst case, we will get an error in the correct code (e.g., if a function argument + // is named `entry`) + if context.at_stop_set() { + break; } - if !match_token(context.tokens, Tok::Comma)? { - let current_loc = context.tokens.start_loc(); - let loc = make_loc(context.tokens.file_hash(), current_loc, current_loc); - let loc2 = make_loc(context.tokens.file_hash(), start_loc, start_loc); - return Err(Box::new(diag!( - Syntax::UnexpectedToken, - (loc, format!("Expected '{}'", end_token)), - (loc2, format!("To match this '{}'", start_token)), - ))); + } + if consume_token(context.tokens, end_token).is_err() { + let current_loc = context.tokens.start_loc(); + let loc = make_loc(context.tokens.file_hash(), current_loc, current_loc); + let loc2 = make_loc(context.tokens.file_hash(), start_loc, start_loc); + context.add_diag(diag!( + Syntax::UnexpectedToken, + (loc, format!("Expected '{}'", end_token)), + (loc2, format!("To match this '{}'", start_token)), + )); + } + v +} + +/// Attempts to skip tokens until the end of the item in a series of separated (which started with +/// an already consumed starting token) - looks for a matched ending token or a token appearing +/// after the separator. This helper function is used when parsing lists and sequences. +fn advance_separated_items_error( + context: &mut Context, + start_token: Tok, + end_token: Tok, + sep_token: Tok, + for_list: bool, + diag: Diagnostic, +) { + context.add_diag(diag); + let mut depth: i32 = 0; // When we find another start token, we track how deep we are in them + loop { + // adjusting tokens (replacing `<<` with `<`) makes sense only when parsing lists and it + // would feel odd to also do this when using this helper function to parse other things + // (e.g., sequences) + if for_list { + adjust_token(context.tokens, end_token); } - adjust_token(context.tokens, end_token); - if match_token(context.tokens, end_token)? { - break Ok(v); + if context.at_stop_set() { + break; } + if depth == 0 { + if context.tokens.at(end_token) { + break; + } + if context.tokens.at(sep_token) { + context.advance(); + break; + } + } + + if context.tokens.at(sep_token) { + assert!(depth > 0); + } else if context.tokens.at(start_token) { + depth += 1; + } else if context.tokens.at(end_token) { + assert!(depth > 0); + depth -= 1; + } + context.advance(); } } @@ -387,9 +544,7 @@ macro_rules! ok_with_loc { //************************************************************************************************** fn report_name_migration(context: &mut Context, name: &str, loc: Loc) { - context - .env - .add_diag(diag!(Migration::NeedsRestrictedIdentifier, (loc, name))); + context.add_diag(diag!(Migration::NeedsRestrictedIdentifier, (loc, name))); } // Parse an identifier: @@ -453,9 +608,7 @@ fn parse_address_bytes( let addr_ = match addr_res { Ok(addr_) => addr_, Err(msg) => { - context - .env - .add_diag(diag!(Syntax::InvalidAddress, (loc, msg))); + context.add_diag(diag!(Syntax::InvalidAddress, (loc, msg))); NumericalAddress::DEFAULT_ERROR_ADDRESS } }; @@ -781,7 +934,7 @@ fn parse_module_member_modifiers(context: &mut Context) -> Result Result> context, Tok::LParen, Tok::RParen, + &ATTR_START_SET, parse_attribute, "attribute", - )?; + ); let end_loc = context.tokens.previous_end_loc(); Attribute_::Parameterized( n, @@ -968,9 +1120,10 @@ fn parse_attributes(context: &mut Context) -> Result, Box Result> { context, Tok::LParen, Tok::RParen, + &FIELD_BINDING_START_SET, parse_bind_or_ellipsis, "a field binding", - )?; + ); FieldBindings::Positional(args) } else { let args = parse_comma_list( context, Tok::LBrace, Tok::RBrace, + &FIELD_BINDING_START_SET, parse_bind_field, "a field binding", - )?; + ); FieldBindings::Named(args) }; let end_loc = context.tokens.previous_end_loc(); @@ -1159,9 +1314,14 @@ fn parse_bind_list(context: &mut Context) -> Result> { context, Tok::LParen, Tok::RParen, + if context.env.edition(context.current_package) == Edition::E2024_MIGRATION { + &MIGRATION_PARAM_START_SET + } else { + &PARAM_START_SET + }, parse_bind, "a variable or structure binding", - )? + ) }; let end_loc = context.tokens.previous_end_loc(); Ok(spanned(context.tokens.file_hash(), start_loc, end_loc, b)) @@ -1176,6 +1336,11 @@ fn parse_lambda_bind_list(context: &mut Context) -> Result Result Result> { let mut last_semicolon_loc = None; let mut eopt = None; while context.tokens.peek() != Tok::RBrace { - let item = parse_sequence_item(context)?; - if context.tokens.peek() == Tok::RBrace { - // If the sequence ends with an expression that is not - // followed by a semicolon, split out that expression - // from the rest of the SequenceItems. - match item.value { - SequenceItem_::Seq(e) => { - eopt = Some(Spanned { - loc: item.loc, - value: e.value, - }); + // this helps when a sequence contains a comma-separated list without the ending token (in + // which case the parser would be likely fast-forwarded to EOF) + context.stop_set.add(Tok::Semicolon); + match parse_sequence_item(context) { + Ok(item) => { + context.stop_set.remove(Tok::Semicolon); + if context.tokens.peek() == Tok::RBrace { + // If the sequence ends with an expression that is not + // followed by a semicolon, split out that expression + // from the rest of the SequenceItems. + if let SequenceItem_::Seq(e) = item.value { + eopt = Some(Spanned { + loc: item.loc, + value: e.value, + }); + } else { + context.add_diag(*unexpected_token_error(context.tokens, "';'")); + } + break; + } + seq.push(item); + last_semicolon_loc = Some(current_token_loc(context.tokens)); + if let Err(diag) = consume_token(context.tokens, Tok::Semicolon) { + advance_separated_items_error( + context, + Tok::LBrace, + Tok::RBrace, + /* separator */ Tok::Semicolon, + /* for list */ true, + *diag, + ); + if context.at_stop_set() { + break; + } + } + } + Err(diag) => { + let err_exp = sp(context.tokens.current_token_loc(), Exp_::UnresolvedError); + let err_seq_item = SequenceItem_::Seq(Box::new(err_exp)); + seq.push(sp(context.tokens.current_token_loc(), err_seq_item)); + context.stop_set.remove(Tok::Semicolon); + advance_separated_items_error( + context, + Tok::LBrace, + Tok::RBrace, + /* separator */ Tok::Semicolon, + /* for list */ true, + *diag, + ); + if context.at_stop_set() { + break; } - _ => return Err(unexpected_token_error(context.tokens, "';'")), } - break; } - seq.push(item); - last_semicolon_loc = Some(current_token_loc(context.tokens)); - consume_token(context.tokens, Tok::Semicolon)?; } - context.tokens.advance()?; // consume the RBrace + // If we reached the stop set but did not find closing of the sequence (RBrace) and we need to + // decide what to do. These are the two most likely possible scenarios: + // + // module 0x42::M { + // fun t() { + // let x = 0; + // use 0x1::M::foo; + // foo(x) + // } + // } + // + // module 0x42::M { + // fun t() { + // let x = 0; + // + // struct S {} + // } + // + // In the first case we encounter stop set's `use` as incorrect inner definition, in the second + // case, we encounter `struct` as a legit top-level definition after incomplete function + // above. We cannot magically know which is which, though, at the point of reaching stop set, + // but still need to make a decision on what to do, which at this point is to close the current + // sequence and proceed with parsing top-level definition (assume the second scenario). + if !context.at_stop_set() || context.tokens.at(Tok::RBrace) { + context.advance(); // consume (the RBrace) + } Ok((uses, seq, last_semicolon_loc, Box::new(eopt))) } @@ -1412,9 +1637,10 @@ fn parse_term(context: &mut Context) -> Result> { context, Tok::LBracket, Tok::RBracket, + &EXP_START_SET, parse_exp, "a vector argument expression", - )?; + ); let args_end_loc = context.tokens.previous_end_loc(); let args = spanned( context.tokens.file_hash(), @@ -1486,9 +1712,10 @@ fn parse_term(context: &mut Context) -> Result> { list_loc, Tok::LParen, Tok::RParen, + &EXP_START_SET, parse_exp, "an expression", - )?; + ); if es.is_empty() { Exp_::Parens(Box::new(e)) } else { @@ -1744,9 +1971,10 @@ fn parse_name_exp(context: &mut Context) -> Result> { context, Tok::LBrace, Tok::RBrace, + &TokenSet::from([Tok::Identifier, Tok::RestrictedIdentifier]), parse_exp_field, "a field expression", - )?; + ); Ok(Exp_::Pack(name, fs)) } @@ -1770,23 +1998,27 @@ fn parse_call_args(context: &mut Context) -> Result>, Box,)+ "}" fn parse_match_arms(context: &mut Context) -> Result>, Box> { + let mut match_arms_start_set = VALUE_START_SET.clone(); + match_arms_start_set.add_all(&[Tok::LParen, Tok::Mut, Tok::Identifier]); ok_with_loc!( context, parse_comma_list( context, Tok::LBrace, Tok::RBrace, + &match_arms_start_set, parse_match_arm, "a call argument expression", - )? + ) ) } @@ -1874,15 +2106,23 @@ fn parse_match_pattern(context: &mut Context) -> Result { + 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, 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)) @@ -1894,9 +2134,10 @@ fn parse_match_pattern(context: &mut Context) -> Result Result>, Box Result Result Result> { } }, |context| { - parse_comma_list( + Ok(parse_comma_list( context, Tok::LBrace, Tok::RBrace, + &EXP_START_SET, parse_exp, "a trigger expresssion", - ) + )) }, )? } else { @@ -2605,7 +2848,16 @@ fn parse_type_( let start_loc = context.tokens.start_loc(); let t = match context.tokens.peek() { Tok::LParen => { - let mut ts = parse_comma_list(context, Tok::LParen, Tok::RParen, parse_type, "a type")?; + context.stop_set.union(&TYPE_STOP_SET); + let mut ts = parse_comma_list( + context, + Tok::LParen, + Tok::RParen, + &TYPE_START_SET, + parse_type, + "a type", + ); + context.stop_set.difference(&TYPE_STOP_SET); match ts.len() { 0 => Type_::Unit, 1 => ts.pop().unwrap().value, @@ -2628,7 +2880,17 @@ fn parse_type_( context.tokens.advance()?; vec![] } else { - parse_comma_list(context, Tok::Pipe, Tok::Pipe, parse_type, "a type")? + context.stop_set.union(&TYPE_STOP_SET); + let list = parse_comma_list( + context, + Tok::Pipe, + Tok::Pipe, + &TYPE_START_SET, + parse_type, + "a type", + ); + context.stop_set.difference(&TYPE_STOP_SET); + list }; let result = if context .tokens @@ -2684,13 +2946,17 @@ fn parse_type_( // OptionalTypeArgs = '<' Comma ">" | fn parse_optional_type_args(context: &mut Context) -> Result>, Box> { if context.tokens.peek() == Tok::Less { - Ok(Some(parse_comma_list( + context.stop_set.union(&TYPE_STOP_SET); + let list = Ok(Some(parse_comma_list( context, Tok::Less, Tok::Greater, + &TYPE_START_SET, parse_type, "a type", - )?)) + ))); + context.stop_set.difference(&TYPE_STOP_SET); + list } else { Ok(None) } @@ -2787,37 +3053,45 @@ fn parse_type_parameter_with_phantom_decl( // Parse optional type parameter list. // OptionalTypeParameters = '<' Comma ">" | -fn parse_optional_type_parameters( - context: &mut Context, -) -> Result)>, Box> { +fn parse_optional_type_parameters(context: &mut Context) -> Vec<(Name, Vec)> { if context.tokens.peek() == Tok::Less { - parse_comma_list( + context.stop_set.union(&TYPE_STOP_SET); + let list = parse_comma_list( context, Tok::Less, Tok::Greater, + &TokenSet::from([ + Tok::Identifier, + Tok::SyntaxIdentifier, + Tok::RestrictedIdentifier, + ]), parse_type_parameter, "a type parameter", - ) + ); + context.stop_set.difference(&TYPE_STOP_SET); + list } else { - Ok(vec![]) + vec![] } } // Parse optional datatype type parameters: // DatatypeTypeParameter = '<' Comma ">" | -fn parse_datatype_type_parameters( - context: &mut Context, -) -> Result, Box> { +fn parse_datatype_type_parameters(context: &mut Context) -> Vec { if context.tokens.peek() == Tok::Less { - parse_comma_list( + context.stop_set.union(&TYPE_STOP_SET); + let list = parse_comma_list( context, Tok::Less, Tok::Greater, + &TokenSet::from([Tok::Identifier, Tok::RestrictedIdentifier]), parse_datatype_type_parameter, "a type parameter", - ) + ); + context.stop_set.difference(&TYPE_STOP_SET); + list } else { - Ok(vec![]) + vec![] } } @@ -2861,61 +3135,66 @@ fn parse_function_decl( // "fun" consume_token(context.tokens, Tok::Fun)?; let name = FunctionName(parse_identifier(context)?); - let type_parameters = parse_optional_type_parameters(context)?; + + context.stop_set.add(Tok::LParen); + context.stop_set.add(Tok::LBrace); + + let type_parameters = parse_optional_type_parameters(context); + context.stop_set.remove(Tok::LParen); // "(" Comma ")" let parameters = parse_comma_list( context, Tok::LParen, Tok::RParen, + if context.env.edition(context.current_package) == Edition::E2024_MIGRATION { + &MIGRATION_PARAM_START_SET + } else { + &PARAM_START_SET + }, parse_parameter, "a function parameter", - )?; + ); - // (":" )? - let return_type = if match_token(context.tokens, Tok::Colon)? { - parse_type(context)? - } else { - sp(name.loc(), Type_::Unit) - }; + let return_type = parse_ret_type(context, name) + .map_err(|diag| { + context.advance_until_stop_set(Some(*diag.clone())); + diag + }) + .ok(); - let body = match native { - Some(loc) => { - consume_token(context.tokens, Tok::Semicolon)?; - sp(loc, FunctionBody_::Native) - } - _ => { - let start_loc = context.tokens.start_loc(); - consume_token(context.tokens, Tok::LBrace)?; - let seq = parse_sequence(context)?; - let end_loc = context.tokens.previous_end_loc(); - sp( - make_loc(context.tokens.file_hash(), start_loc, end_loc), - FunctionBody_::Defined(seq), - ) - } - }; + context.stop_set.remove(Tok::LBrace); - let signature = FunctionSignature { - type_parameters, - parameters, - return_type, - }; + let body = parse_body(context, native) + .map_err(|diag| { + context.advance_until_stop_set(Some(*diag.clone())); + diag + }) + .ok(); let loc = make_loc( context.tokens.file_hash(), start_loc, context.tokens.previous_end_loc(), ); + Ok(Function { attributes, loc, visibility: visibility.unwrap_or(Visibility::Internal), entry, macro_, - signature, + signature: FunctionSignature { + type_parameters, + parameters, + return_type: return_type.unwrap_or_else(|| sp(name.loc(), Type_::UnresolvedError)), + }, name, - body, + body: body.unwrap_or_else(|| { + let loc = context.tokens.current_token_loc(); + let seq_exp = Box::new(Some(sp(loc, Exp_::UnresolvedError))); + sp(loc, FunctionBody_::Defined((vec![], vec![], None, seq_exp))) + }), }) } @@ -2937,6 +3216,75 @@ fn parse_parameter(context: &mut Context) -> Result<(Mutability, Var, Type), Box Ok((mut_, v, t)) } +// (":" )? +fn parse_ret_type(context: &mut Context, name: FunctionName) -> Result> { + if match_token(context.tokens, Tok::Colon)? { + parse_type(context) + } else { + Ok(sp(name.loc(), Type_::Unit)) + } +} + +fn parse_body(context: &mut Context, native: Option) -> Result> { + match native { + Some(loc) => { + if let Err(diag) = consume_token(context.tokens, Tok::Semicolon) { + context.advance_until_stop_set(Some(*diag)); + } + Ok(sp(loc, FunctionBody_::Native)) + } + _ => { + let start_loc = context.tokens.start_loc(); + let seq = if context.tokens.peek() == Tok::LBrace { + match consume_token(context.tokens, Tok::LBrace) { + Ok(_) => parse_sequence(context)?, + Err(diag) => { + // error advancing past opening brace - assume sequence (likely first) + // parsing problem and try skipping it + advance_separated_items_error( + context, + Tok::LBrace, + Tok::RBrace, + /* separator */ Tok::Semicolon, + /* for list */ true, + *diag, + ); + let _ = match_token(context.tokens, Tok::RBrace); + ( + vec![], + vec![], + None, + Box::new(Some(sp( + context.tokens.current_token_loc(), + Exp_::UnresolvedError, + ))), + ) + } + } + } else { + // not even opening brace - not much of a body to parse + let diag = unexpected_token_error(context.tokens, "'{'"); + context.advance_until_stop_set(Some(*diag)); + ( + vec![], + vec![], + None, + Box::new(Some(sp( + context.tokens.current_token_loc(), + Exp_::UnresolvedError, + ))), + ) + }; + + let end_loc = context.tokens.previous_end_loc(); + Ok(sp( + make_loc(context.tokens.file_hash(), start_loc, end_loc), + FunctionBody_::Defined(seq), + )) + } + } +} + //************************************************************************************************** // Enums //************************************************************************************************** @@ -2971,7 +3319,7 @@ fn parse_enum_decl( // let name = DatatypeName(parse_identifier(context)?); - let type_parameters = parse_datatype_type_parameters(context)?; + let type_parameters = parse_datatype_type_parameters(context); let infix_ability_declaration_loc = if context.tokens.peek() == Tok::Identifier && context.tokens.content() == "has" { @@ -3042,9 +3390,10 @@ fn parse_enum_variant_decls( start_loc, Tok::LBrace, Tok::RBrace, + &TokenSet::from([Tok::Identifier, Tok::RestrictedIdentifier]), parse_enum_variant_decl, "a variant", - )?; + ); Ok(variants) } @@ -3079,9 +3428,10 @@ fn parse_enum_variant_fields(context: &mut Context) -> Result { @@ -3089,9 +3439,10 @@ fn parse_enum_variant_fields(context: &mut Context) -> Result Ok(VariantFields::Empty), @@ -3160,56 +3511,79 @@ fn parse_struct_decl( // let name = DatatypeName(parse_identifier(context)?); - let type_parameters = parse_datatype_type_parameters(context)?; - let infix_ability_declaration_loc = + context + .stop_set + .add_all(&[Tok::LBrace, Tok::LParen, Tok::Semicolon]); + let type_parameters = parse_datatype_type_parameters(context); + + let mut infix_ability_declaration_loc = if context.tokens.peek() == Tok::Identifier && context.tokens.content() == "has" { Some(current_token_loc(context.tokens)) } else { None }; + // is the `has` keyword for infix abilities present + let infix_ability_has_keyword = infix_ability_declaration_loc.is_some(); + let mut abilities = if infix_ability_declaration_loc.is_some() { - context.tokens.advance()?; - parse_list( - context, - |context| match context.tokens.peek() { - Tok::Comma => { - context.tokens.advance()?; - Ok(true) - } - Tok::LBrace | Tok::Semicolon | Tok::LParen => Ok(false), - _ => Err(unexpected_token_error( - context.tokens, - &format!( - "one of: '{}', '{}', '{}', or '{}'", - Tok::Comma, - Tok::LBrace, - Tok::LParen, - Tok::Semicolon - ), - )), - }, - parse_ability, - )? + parse_infix_ability_declarations(context) + .map_err(|diag| { + // if parsing failed, assume no abilities present even if `has` keyword was present + infix_ability_declaration_loc = None; + context.advance_until_stop_set(Some(*diag.clone())); + diag + }) + .unwrap_or_default() } else { vec![] }; - let fields = match native { - Some(loc) => { - consume_token(context.tokens, Tok::Semicolon)?; - StructFields::Native(loc) - } - _ => { - let fields = parse_struct_fields(context)?; - parse_postfix_ability_declarations( - infix_ability_declaration_loc, - &mut abilities, - context, - )?; - fields - } - }; + // we are supposed to start parsing struct fields here + if !context + .tokens + .at_set(&TokenSet::from(&[Tok::LBrace, Tok::LParen, Tok::Semicolon])) + { + let unexpected_loc = current_token_loc(context.tokens); + let msg = if infix_ability_has_keyword { + format!( + "Unexpected '{}'. Expected struct fields or ';' for a native struct", + context.tokens.peek() + ) + } else { + format!( + "Unexpected '{}'. Expected struct fields, 'has' to start abilities declaration, \ + or ';' for a native struct", + context.tokens.peek() + ) + }; + let diag = diag!(Syntax::UnexpectedToken, (unexpected_loc, msg)); + context.add_diag(diag); + } + + if !context.at_stop_set() { + // try advancing until we reach fields defnition or the "outer" stop set + context.advance_until_stop_set(None); + } + + context + .stop_set + .remove_all(&[Tok::LBrace, Tok::LParen, Tok::Semicolon]); + + let mut fields = None; + if !context.at_stop_set() { + fields = parse_struct_body( + context, + native, + infix_ability_declaration_loc, + &mut abilities, + ) + .map_err(|diag| { + context.advance_until_stop_set(Some(*diag.clone())); + diag + }) + .ok(); + } let loc = make_loc( context.tokens.file_hash(), @@ -3222,7 +3596,27 @@ fn parse_struct_decl( abilities, name, type_parameters, - fields, + fields: fields.unwrap_or(StructFields::Native(loc)), + }) +} + +// Parse either just semicolon (for native structs) or fields and (optional) postfix abilities +fn parse_struct_body( + context: &mut Context, + native: Option, + infix_ability_declaration_loc: Option, + abilities: &mut Vec, +) -> Result> { + Ok(match native { + Some(loc) => { + consume_token(context.tokens, Tok::Semicolon)?; + StructFields::Native(loc) + } + _ => { + let fields = parse_struct_fields(context)?; + parse_postfix_ability_declarations(infix_ability_declaration_loc, abilities, context)?; + fields + } }) } @@ -3244,17 +3638,50 @@ fn parse_positional_field(context: &mut Context) -> Result (context.tokens.peek(), context.tokens.lookahead()), (Tok::Identifier, Ok(Tok::Colon)) ) { - return Err(Box::new(diag!( + let diag = diag!( Syntax::UnexpectedToken, ( context.tokens.current_token_loc(), "Cannot use named fields in a positional definition" ) - ))); + ); + context.add_diag(diag); + // advance to (presumably) the actual type + context.tokens.advance()?; + context.tokens.advance()?; } parse_type(context) } +// Parse a infix ability declaration: +// "has" (, )+ +fn parse_infix_ability_declarations( + context: &mut Context, +) -> Result, Box> { + context.tokens.advance()?; + parse_list( + context, + |context| match context.tokens.peek() { + Tok::Comma => { + context.tokens.advance()?; + Ok(true) + } + Tok::LBrace | Tok::Semicolon | Tok::LParen => Ok(false), + _ => Err(unexpected_token_error( + context.tokens, + &format!( + "one of: '{}', '{}', '{}', or '{}'", + Tok::Comma, + Tok::LBrace, + Tok::LParen, + Tok::Semicolon + ), + )), + }, + parse_ability, + ) +} + // Parse a postfix ability declaration: // "has" (, )+; // Error if: @@ -3285,7 +3712,7 @@ fn parse_postfix_ability_declarations( let msg = "Duplicate ability declaration. Abilities can be declared before \ or after the field declarations, but not both."; let prev_msg = "Ability declaration previously given here"; - context.env.add_diag(diag!( + context.add_diag(diag!( Syntax::InvalidModifier, (has_location, msg), (previous_declaration_loc, prev_msg) @@ -3321,22 +3748,26 @@ fn parse_struct_fields(context: &mut Context) -> Result, context: &mut Context ); let note = "Visibility annotations are required on struct declarations from the Move 2024 edition onwards."; if context.env.edition(current_package) == Edition::E2024_MIGRATION { - context - .env - .add_diag(diag!(Migration::NeedsPublic, (loc, msg.clone()))) + context.add_diag(diag!(Migration::NeedsPublic, (loc, msg.clone()))) } else { let mut err = diag!(Syntax::InvalidModifier, (loc, msg)); err.add_note(note); - context.env.add_diag(err); + context.add_diag(err); } } } else if let Some(vis) = visibility { @@ -3385,7 +3814,7 @@ fn check_struct_visibility(visibility: Option, context: &mut Context let note = "Starting in the Move 2024 edition visibility must be annotated on struct declarations."; let mut err = diag!(Syntax::InvalidModifier, (vis.loc().unwrap(), msg)); err.add_note(note); - context.env.add_diag(err); + context.add_diag(err); } } @@ -3410,9 +3839,7 @@ fn parse_constant_decl( if let Some(vis) = visibility { let msg = "Invalid constant declaration. Constants cannot have visibility modifiers as \ they are always internal"; - context - .env - .add_diag(diag!(Syntax::InvalidModifier, (vis.loc().unwrap(), msg))); + context.add_diag(diag!(Syntax::InvalidModifier, (vis.loc().unwrap(), msg))); } check_no_modifier(context, NATIVE_MODIFIER, native, "constant"); check_no_modifier(context, ENTRY_MODIFIER, entry, "constant"); @@ -3661,9 +4088,7 @@ fn parse_use_decl( let msg = "Invalid use declaration. Non-'use fun' declarations cannot have visibility \ modifiers as they are always internal"; - context - .env - .add_diag(diag!(Syntax::InvalidModifier, (vis.loc().unwrap(), msg))); + context.add_diag(diag!(Syntax::InvalidModifier, (vis.loc().unwrap(), msg))); } let address_start_loc = context.tokens.start_loc(); let address = parse_leading_name_access(context)?; @@ -3683,9 +4108,11 @@ fn parse_use_decl( context, Tok::LBrace, Tok::RBrace, + &TokenSet::from([Tok::Identifier]), parse_inner, "a module use clause", - )?; + ); + Use::NestedModuleUses(address, use_decls) } _ => { @@ -3732,9 +4159,10 @@ fn parse_use_module( context, Tok::LBrace, Tok::RBrace, + &TokenSet::from([Tok::Identifier]), parse_use_member, "a module member alias", - )?, + ), _ => vec![parse_use_member(context)?], }; ModuleUse::Members(sub_uses) @@ -3811,10 +4239,18 @@ fn parse_module( let mut next_mod_attributes = None; let mut stop_parsing = false; while context.tokens.peek() != Tok::RBrace { - let curr_token_loc = context.tokens.current_token_loc(); + context.stop_set.union(&MODULE_MEMBER_OR_MODULE_START_SET); match parse_module_member(context) { - Ok(m) => members.push(m), + Ok(m) => { + context + .stop_set + .difference(&MODULE_MEMBER_OR_MODULE_START_SET); + members.push(m); + } Err(ErrCase::ContinueToModule(attrs)) => { + context + .stop_set + .difference(&MODULE_MEMBER_OR_MODULE_START_SET); // while trying to parse module members, we moved past the current module and // encountered a new one - keep parsing it at a higher level, keeping the // already parsed attributes @@ -3823,21 +4259,16 @@ fn parse_module( break; } Err(ErrCase::Unknown(diag)) => { - context.env.add_diag(*diag); - let next_tok = - skip_to_next_desired_tok_or_eof(context, is_start_of_member_or_module); - if next_tok == Tok::EOF || next_tok == Tok::Module { + context + .stop_set + .difference(&MODULE_MEMBER_OR_MODULE_START_SET); + context.add_diag(*diag); + skip_to_next_desired_tok_or_eof(context, &MODULE_MEMBER_OR_MODULE_START_SET); + if context.tokens.at(Tok::EOF) || context.tokens.at(Tok::Module) { // either end of file or next module to potentially be parsed stop_parsing = true; break; } - if curr_token_loc == context.tokens.current_token_loc() { - // token wasn't advanced by either `parse_module_member` nor by - // `skip_to_next_member_or_module_or_eof` - no further parsing is possible (in - // particular, without this check, compiler tests get stuck) - stop_parsing = true; - break; - } } } } @@ -3863,46 +4294,19 @@ fn parse_module( /// Skips tokens until reaching the desired one or EOF. Returns true if further parsing is /// impossible and parser should stop. -fn skip_to_next_desired_tok_or_eof( - context: &mut Context, - is_desired_tok: fn(Tok, &str) -> bool, -) -> Tok { +fn skip_to_next_desired_tok_or_eof(context: &mut Context, desired_tokens: &TokenSet) { loop { - let tok = context.tokens.peek(); - let content = context.tokens.content(); - if tok == Tok::EOF || is_desired_tok(tok, content) { - return tok; + if context.tokens.at(Tok::EOF) || context.tokens.at_set(desired_tokens) { + break; } if let Err(diag) = context.tokens.advance() { // record diagnostics but keep advancing until encountering one of the desired tokens or // (which is eventually guaranteed) EOF - context.env.add_diag(*diag); + context.add_diag(*diag); } } } -fn is_start_of_member_or_module(tok: Tok, content: &str) -> bool { - match tok { - Tok::Invariant - | Tok::Spec - | Tok::Friend - | Tok::Public - | Tok::Native - | Tok::Const - | Tok::Fun - | Tok::Struct - | Tok::Use - | Tok::Module - | Tok::NumSign => true, - Tok::Identifier => content == ENTRY_MODIFIER, // TODO: add macro start - _ => false, - } -} - -fn is_start_of_module_or_spec(tok: Tok, _: &str) -> bool { - matches!(tok, Tok::Spec | Tok::Module) -} - /// Parse a single module member. Due to parsing error recovery, when attempting to parse the next /// module member, the parser may have already advanced past the end of the current module and /// encounter the next module which also should be parsed. While this is a member parsing error, @@ -3926,10 +4330,10 @@ fn parse_module_member(context: &mut Context) -> Result { // Add an extra check for better error message // if old syntax is used if context.tokens.lookahead2() == Ok((Tok::Identifier, Tok::LBrace)) { - return Err(ErrCase::Unknown(unexpected_token_error( + context.add_diag(*unexpected_token_error( context.tokens, "only 'spec', drop the 'fun' keyword", - ))); + )); } let spec_string = consume_spec_string(context)?; Ok(ModuleMember::Spec(spec_string)) @@ -4027,7 +4431,7 @@ fn parse_module_member(context: &mut Context) -> Result { ) }; if tok == Tok::Module { - context.env.add_diag(*diag); + context.add_diag(*diag); Err(ErrCase::ContinueToModule(attributes)) } else { Err(ErrCase::Unknown(diag)) @@ -4090,10 +4494,10 @@ fn parse_file(context: &mut Context) -> Result, Box> let mut defs = vec![]; while context.tokens.peek() != Tok::EOF { if let Err(diag) = parse_file_def(context, &mut defs) { - context.env.add_diag(*diag); + context.add_diag(*diag); // skip to the next def and try parsing it if it's there (ignore address blocks as they // are pretty much defunct anyway) - skip_to_next_desired_tok_or_eof(context, is_start_of_module_or_spec); + skip_to_next_desired_tok_or_eof(context, &TokenSet::from(&[Tok::Spec, Tok::Module])); } } Ok(defs) diff --git a/external-crates/move/crates/move-compiler/src/parser/token_set.rs b/external-crates/move/crates/move-compiler/src/parser/token_set.rs new file mode 100644 index 0000000000000..576ca24405ce0 --- /dev/null +++ b/external-crates/move/crates/move-compiler/src/parser/token_set.rs @@ -0,0 +1,283 @@ +// Copyright (c) The Move Contributors +// SPDX-License-Identifier: Apache-2.0 + +use crate::parser::lexer::{Tok, TOK_COUNT}; + +use move_symbol_pool::Symbol; + +use once_cell::sync::Lazy; +use std::collections::HashMap; + +use super::ast::{ENTRY_MODIFIER, MACRO_MODIFIER, NATIVE_MODIFIER}; + +#[derive(Clone, Debug)] +pub struct TokenSet { + tokens: [u8; TOK_COUNT], + identifiers: HashMap, +} + +//************************************************************************************************** +// CONSTANT SETS +//************************************************************************************************** + +const MOVE_2024_KEYWORDS: &[Tok] = &[Tok::Mut, Tok::Match, Tok::For, Tok::Enum, Tok::Type]; + +const MODULE_MEMBER_TOKENS: &[Tok] = &[ + Tok::Fun, + Tok::Struct, + Tok::Use, + Tok::Const, + Tok::Friend, + Tok::Spec, + Tok::Invariant, +]; + +const MEMBER_VISIBILITY_TOKENS: &[Tok] = &[Tok::Public]; + +const MEMBER_MODIFIER_TOKENS: &[Tok] = &[Tok::Native]; + +pub static MODULE_MEMBER_OR_MODULE_START_SET: Lazy = Lazy::new(|| { + let mut token_set = TokenSet::new(); + token_set.add_all(MODULE_MEMBER_TOKENS); + token_set.add_all(MEMBER_VISIBILITY_TOKENS); + token_set.add_all(MEMBER_MODIFIER_TOKENS); + token_set.add_identifier(MACRO_MODIFIER); + token_set.add_identifier(ENTRY_MODIFIER); + token_set.add_identifier(NATIVE_MODIFIER); + token_set.add(Tok::Module); + // both a member and module can be annotated + token_set.add(Tok::NumSign); + token_set +}); + +const PARAM_STARTS: &[Tok] = &[ + Tok::Identifier, + Tok::Mut, + Tok::SyntaxIdentifier, + Tok::LParen, + Tok::RestrictedIdentifier, +]; + +pub static PARAM_START_SET: Lazy = Lazy::new(|| TokenSet::from(PARAM_STARTS)); + +pub static MIGRATION_PARAM_START_SET: Lazy = Lazy::new(|| { + let mut param_set = TokenSet::from(PARAM_STARTS); + param_set.union(&TokenSet::from(MOVE_2024_KEYWORDS)); + param_set +}); + +const EXP_STARTS: &[Tok] = &[ + Tok::NumValue, + Tok::NumTypedValue, + Tok::ByteStringValue, + Tok::Identifier, + Tok::SyntaxIdentifier, + Tok::RestrictedIdentifier, + Tok::AtSign, + Tok::Copy, + Tok::Move, + Tok::Pipe, + Tok::PipePipe, + Tok::False, + Tok::True, + Tok::Amp, + Tok::AmpMut, + Tok::Star, + Tok::Exclaim, + Tok::LParen, + Tok::LBrace, + Tok::Abort, + Tok::Break, + Tok::Continue, + Tok::If, + Tok::Loop, + Tok::Return, + Tok::While, + Tok::BlockLabel, +]; + +pub static EXP_START_SET: Lazy = Lazy::new(|| TokenSet::from(EXP_STARTS)); + +const TYPE_STARTS: &[Tok] = &[ + Tok::Identifier, + Tok::Amp, + Tok::AmpMut, + Tok::LParen, // tuple + Tok::NumValue, // package address + Tok::Pipe, + Tok::PipePipe, + Tok::SyntaxIdentifier, + Tok::RestrictedIdentifier, +]; + +pub static TYPE_START_SET: Lazy = Lazy::new(|| TokenSet::from(TYPE_STARTS)); + +/// Never part of a type (or type parameter) +const TYPE_STOPS: &[Tok] = &[ + Tok::Percent, + Tok::LBracket, + Tok::RBracket, + Tok::Star, + Tok::Plus, + Tok::Minus, + Tok::Slash, + Tok::Colon, + Tok::Semicolon, + Tok::LessEqual, + Tok::Equal, + Tok::EqualEqual, + Tok::EqualEqualGreater, + Tok::LessEqualEqualGreater, + Tok::GreaterEqual, + Tok::Caret, + Tok::LBrace, + Tok::RBrace, + Tok::NumSign, + Tok::AtSign, + Tok::MinusGreater, +]; + +pub static TYPE_STOP_SET: Lazy = Lazy::new(|| TokenSet::from(TYPE_STOPS)); + +// including `Tok::For` here is hack for `#[syntax(for)]` attribute (similar to the one in +// `syntax::parse_attribute`) +const ATTR_STARTS: &[Tok] = &[Tok::Identifier, Tok::For]; + +pub static ATTR_START_SET: Lazy = Lazy::new(|| TokenSet::from(ATTR_STARTS)); + +const FIELD_BINDING_STARTS: &[Tok] = &[ + Tok::Mut, + Tok::Identifier, + Tok::RestrictedIdentifier, + Tok::PeriodPeriod, +]; + +pub static FIELD_BINDING_START_SET: Lazy = + Lazy::new(|| TokenSet::from(FIELD_BINDING_STARTS)); + +const VALUE_STARTS: &[Tok] = &[ + Tok::AtSign, + Tok::True, + Tok::False, + Tok::NumValue, + Tok::NumTypedValue, + Tok::ByteStringValue, +]; + +pub static VALUE_START_SET: Lazy = Lazy::new(|| TokenSet::from(VALUE_STARTS)); + +//************************************************************************************************** +// IMPLS +//************************************************************************************************** + +#[allow(dead_code)] +impl TokenSet { + pub fn new() -> Self { + let tokens = [0; TOK_COUNT]; + let identifiers = HashMap::new(); + TokenSet { + tokens, + identifiers, + } + } + + pub fn add(&mut self, tok: Tok) { + self.tokens[tok as usize] += 1; + } + + pub fn remove(&mut self, tok: Tok) { + if self.tokens[tok as usize] > 0 { + self.tokens[tok as usize] -= 1; + } + } + + pub fn add_identifier(&mut self, identifier: &str) { + *self.identifiers.entry(identifier.into()).or_default() += 1; + } + + pub fn remove_identifier(&mut self, identifier: impl AsRef) { + if let Some(entry) = self.identifiers.get_mut(&identifier.as_ref().into()) { + if *entry < 2 { + self.identifiers.remove(&identifier.as_ref().into()); + } else { + *entry -= 1; + } + } + } + + pub fn add_all(&mut self, toks: &[Tok]) { + for tok in toks { + self.add(*tok); + } + } + + pub fn remove_all(&mut self, toks: &[Tok]) { + for tok in toks { + self.remove(*tok); + } + } + + pub fn contains(&self, tok: Tok, tok_contents: impl AsRef) -> bool { + self.tokens[tok as usize] > 0 + || (tok == Tok::Identifier + || tok == Tok::RestrictedIdentifier + || tok == Tok::SyntaxIdentifier) + && self.identifiers.contains_key(&tok_contents.as_ref().into()) + } + + pub fn contains_any(&self, toks: &[Tok], tok_contents: impl AsRef) -> bool { + toks.iter() + .any(|tok| self.contains(*tok, tok_contents.as_ref())) + } + + pub fn union(&mut self, other: &TokenSet) { + for (target, n) in self.tokens.iter_mut().zip(other.tokens.iter()) { + *target += n; + } + for (identifier, n) in other.identifiers.iter() { + *self.identifiers.entry(*identifier).or_default() += n; + } + } + + pub fn difference(&mut self, other: &TokenSet) { + for (target, n) in self.tokens.iter_mut().zip(other.tokens.iter()) { + if *target >= *n { + *target -= n; + } else { + *target = 0 + } + } + for (identifier, n) in other.identifiers.iter() { + let entry = self.identifiers.entry(*identifier).or_default(); + if *entry >= *n { + *entry -= n; + } else { + *entry = 0 + } + } + } +} + +impl std::convert::From<[Tok; N]> for TokenSet { + fn from(values: [Tok; N]) -> Self { + let mut new = TokenSet::new(); + new.add_all(&values); + new + } +} + +impl std::convert::From<&[Tok; N]> for TokenSet { + fn from(values: &[Tok; N]) -> Self { + let mut new = TokenSet::new(); + new.add_all(values); + new + } +} + +impl std::convert::From<&[Tok]> for TokenSet { + fn from(values: &[Tok]) -> Self { + let mut new = TokenSet::new(); + new.add_all(values); + new + } +} diff --git a/external-crates/move/crates/move-compiler/src/shared/mod.rs b/external-crates/move/crates/move-compiler/src/shared/mod.rs index dd56c7d83eca6..5f85e46e14118 100644 --- a/external-crates/move/crates/move-compiler/src/shared/mod.rs +++ b/external-crates/move/crates/move-compiler/src/shared/mod.rs @@ -368,6 +368,19 @@ impl CompilationEnv { } pub fn add_diag(&mut self, mut diag: Diagnostic) { + if diag.info().severity() <= Severity::NonblockingError + && self + .diags + .any_syntax_error_with_primary_loc(diag.primary_loc()) + { + // do not report multiple diags for the same location (unless they are blocking) to + // avoid noise that is likely to confuse the developer trying to localize the problem + // + // TODO: this check is O(n^2) for n diags - shouldn't be a huge problem but fix if it + // becomes one + return; + } + if !self.is_filtered(&diag) { // add help to suppress warning, if applicable // TODO do we want a centralized place for tips like this? diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns.exp b/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns.exp index 25a6f11075fef..860726d5ff270 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns.exp @@ -1,3 +1,9 @@ +error[E04036]: non-exhaustive pattern + ┌─ tests/development/enums/matching/at_patterns.move:30:16 + │ +30 │ match (x) { + │ ^ Pattern 'Maybe::Just(_)' not covered + error[E01002]: unexpected token ┌─ tests/development/enums/matching/at_patterns.move:31:13 │ diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns_mut_ref.exp b/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns_mut_ref.exp index c507e79f9947c..2bb7b4c0b7a35 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns_mut_ref.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns_mut_ref.exp @@ -1,3 +1,9 @@ +error[E04036]: non-exhaustive pattern + ┌─ tests/development/enums/matching/at_patterns_mut_ref.move:30:16 + │ +30 │ match (x) { + │ ^ Pattern 'Maybe::Just(_)' not covered + error[E01002]: unexpected token ┌─ tests/development/enums/matching/at_patterns_mut_ref.move:31:13 │ diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns_ref.exp b/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns_ref.exp index cc08a649f6619..39b3736403707 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns_ref.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/matching/at_patterns_ref.exp @@ -1,3 +1,9 @@ +error[E04036]: non-exhaustive pattern + ┌─ tests/development/enums/matching/at_patterns_ref.move:30:16 + │ +30 │ match (x) { + │ ^ Pattern 'Maybe::Just(_)' not covered + error[E01002]: unexpected token ┌─ tests/development/enums/matching/at_patterns_ref.move:31:13 │ diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/matching/guard_binders.move b/external-crates/move/crates/move-compiler/tests/development/enums/matching/guard_binders.move index 65f2a5300c8b2..f2a72a2ee3074 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/matching/guard_binders.move +++ b/external-crates/move/crates/move-compiler/tests/development/enums/matching/guard_binders.move @@ -23,7 +23,7 @@ module 0x42::m { } fun t1(): u64 { - let o: Option = Option::None; + let mut o: Option = Option::None; match (&mut o) { Option::Some(n) if n == &5 => *n, Option::None => 3, diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_at.exp b/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_at.exp index 5ed984cc01293..fb841370ea980 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_at.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_at.exp @@ -1,3 +1,11 @@ +error[E01018]: invalid 'match' + ┌─ tests/development/enums/matching/invalid_at.move:8:9 + │ + 8 │ ╭ match (opt) { + 9 │ │ _ @ Option::Some(128u8) => (), +10 │ │ } + │ ╰─────────^ Invalid 'match' form. 'match' must have at least one arm + error[E01002]: unexpected token ┌─ tests/development/enums/matching/invalid_at.move:9:13 │ diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_match_tuple.exp b/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_match_tuple.exp index 43daaba36cf21..fafb3acc107ee 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_match_tuple.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_match_tuple.exp @@ -1,3 +1,11 @@ +error[E01018]: invalid 'match' + ┌─ tests/development/enums/matching/invalid_match_tuple.move:6:9 + │ +6 │ ╭ match (x()) { +7 │ │ (x, y) => () +8 │ │ } + │ ╰─────────^ Invalid 'match' form. 'match' must have at least one arm + error[E01002]: unexpected token ┌─ tests/development/enums/matching/invalid_match_tuple.move:7:15 │ @@ -7,6 +15,15 @@ error[E01002]: unexpected token │ Unexpected ',' │ Expected ')' +error[E01002]: unexpected token + ┌─ tests/development/enums/matching/invalid_match_tuple.move:7:18 + │ +7 │ (x, y) => () + │ ^ + │ │ + │ Unexpected ')' + │ Expected '=>' + error[E04005]: expected a single type ┌─ tests/development/enums/matching/invalid_match_tuple.move:12:16 │ diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_match_unit.exp b/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_match_unit.exp index 0dbe3afe73950..85d1732faf96c 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_match_unit.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/matching/invalid_match_unit.exp @@ -1,3 +1,11 @@ +error[E01018]: invalid 'match' + ┌─ tests/development/enums/matching/invalid_match_unit.move:6:9 + │ +6 │ ╭ match (x()) { +7 │ │ () => () +8 │ │ } + │ ╰─────────^ Invalid 'match' form. 'match' must have at least one arm + error[E01002]: unexpected token ┌─ tests/development/enums/matching/invalid_match_unit.move:7:14 │ diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/parser/enum_invalid.exp b/external-crates/move/crates/move-compiler/tests/development/enums/parser/enum_invalid.exp index 5f9431a6d2099..4fbd027d304cb 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/parser/enum_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/parser/enum_invalid.exp @@ -20,3 +20,12 @@ error[E01002]: unexpected token 13 │ Done(x: u64), │ ^ Cannot use named fields in a positional definition +error[E01002]: unexpected token + ┌─ tests/development/enums/parser/enum_invalid.move:14:18 + │ +14 │ Add { u64 }, + │ ^ + │ │ + │ Unexpected '}' + │ Expected ':' + diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/parser/enum_invalid_2.exp b/external-crates/move/crates/move-compiler/tests/development/enums/parser/enum_invalid_2.exp index 42fd97c5235a2..4b71e77e1fa65 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/parser/enum_invalid_2.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/parser/enum_invalid_2.exp @@ -4,3 +4,12 @@ error[E01002]: unexpected token 3 │ Done(x: u64), │ ^ Cannot use named fields in a positional definition +error[E01002]: unexpected token + ┌─ tests/development/enums/parser/enum_invalid_2.move:4:18 + │ +4 │ Add { u64 }, + │ ^ + │ │ + │ Unexpected '}' + │ Expected ':' + diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/parser/invalid_mut_usage_match.exp b/external-crates/move/crates/move-compiler/tests/development/enums/parser/invalid_mut_usage_match.exp index 708a7723ac651..33be014ce1879 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/parser/invalid_mut_usage_match.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/parser/invalid_mut_usage_match.exp @@ -1,6 +1,66 @@ +error[E04016]: too few arguments + ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:10:10 + │ +10 │ Option::Other { mut x: mut y } => y, + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Missing pattern for field 'x' in '0x42::m::Option::Other' + error[E01002]: unexpected token ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:10:26 │ 10 │ Option::Other { mut x: mut y } => y, │ ^^^ 'mut' modifier can only be used on variable bindings +error[E03009]: unbound variable + ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:10:44 + │ +10 │ Option::Other { mut x: mut y } => y, + │ ^ Unbound variable 'y' + +error[E02010]: invalid name + ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:11:33 + │ +11 │ Option::Other { x: mut y } => y, + │ ^ Invalid type arguments on a pattern variable + │ + = Type arguments cannot appear on pattern variables + +error[E04016]: too few arguments + ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:12:10 + │ +12 │ Option::Other { mut x: y } => y, + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ Missing pattern for field 'x' in '0x42::m::Option::Other' + +error[E01002]: unexpected token + ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:12:26 + │ +12 │ Option::Other { mut x: y } => y, + │ ^^^ 'mut' modifier can only be used on variable bindings + +error[E03009]: unbound variable + ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:12:40 + │ +12 │ Option::Other { mut x: y } => y, + │ ^ Unbound variable 'y' + +warning[W09002]: unused variable + ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:13:10 + │ +13 │ x @ mut Option::Some(true) => true, + │ ^ Unused local variable 'x'. Consider removing or prefixing with an underscore: '_x' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E01002]: unexpected token + ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:13:14 + │ +13 │ x @ mut Option::Some(true) => true, + │ ^^^ Invalid 'mut' keyword on non-variable pattern + +error[E02010]: invalid name + ┌─ tests/development/enums/parser/invalid_mut_usage_match.move:14:10 + │ +14 │ mut Option::None => false, + │ ^^^ ------------ This refers to a variant, not a variable binding + │ │ + │ 'mut' can only be used with variable bindings in patterns + diff --git a/external-crates/move/crates/move-compiler/tests/development/enums/parser/pattern_ellipsis_invalid.exp b/external-crates/move/crates/move-compiler/tests/development/enums/parser/pattern_ellipsis_invalid.exp index 642d5494592c1..0be5339902d3a 100644 --- a/external-crates/move/crates/move-compiler/tests/development/enums/parser/pattern_ellipsis_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/development/enums/parser/pattern_ellipsis_invalid.exp @@ -1,6 +1,14 @@ +error[E01018]: invalid 'match' + ┌─ tests/development/enums/parser/pattern_ellipsis_invalid.move:9:9 + │ + 9 │ ╭ match (x) { +10 │ │ .. +11 │ │ } + │ ╰─────────^ Invalid 'match' form. 'match' must have at least one arm + error[E01002]: unexpected token ┌─ tests/development/enums/parser/pattern_ellipsis_invalid.move:10:13 │ 10 │ .. - │ ^^ Invalid pattern + │ ^ Expected a call argument expression diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.exp b/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.exp index 299f4dc202719..fff63a63a63a6 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.exp @@ -1,18 +1,46 @@ +warning[W09002]: unused variable + ┌─ tests/move_2024/migration/match_okay.move:3:12 + │ +3 │ fun t1(t: u64, match: u64): bool { + │ ^ Unused parameter 't'. Consider removing or prefixing with an underscore: '_t' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E01002]: unexpected token + ┌─ tests/move_2024/migration/match_okay.move:3:20 + │ +3 │ fun t1(t: u64, match: u64): bool { + │ ^ Expected a function parameter + +error[E01002]: unexpected token + ┌─ tests/move_2024/migration/match_okay.move:5:5 + │ +5 │ } + │ ^ + │ │ + │ Unexpected '}' + │ Expected '(' + +warning[W09002]: unused variable + ┌─ tests/move_2024/migration/match_okay.move:7:12 + │ +7 │ fun t2(t: u64, match: u64): bool { + │ ^ Unused parameter 't'. Consider removing or prefixing with an underscore: '_t' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + error[E01002]: unexpected token - ┌─ tests/move_2024/migration/match_okay.move:3:19 + ┌─ tests/move_2024/migration/match_okay.move:7:20 │ -3 │ fun t(t: u64, match: u64): bool { - │ ^^^^^ - │ │ - │ Unexpected 'match' - │ Expected an identifier +7 │ fun t2(t: u64, match: u64): bool { + │ ^ Expected a function parameter error[E01002]: unexpected token - ┌─ tests/move_2024/migration/match_okay.move:7:19 + ┌─ tests/move_2024/migration/match_okay.move:8:23 │ -7 │ fun t(t: u64, match: u64): bool { - │ ^^^^^ - │ │ - │ Unexpected 'match' - │ Expected an identifier +8 │ if (t == match) { true } else { false } + │ ^ + │ │ + │ Unexpected ')' + │ Expected '(' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.migration.exp b/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.migration.exp index ac5464a1ad250..ff8508c16c4d3 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.migration.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.migration.exp @@ -1,12 +1,12 @@ --- tests/move_2024/migration/match_okay.move +++ tests/move_2024/migration/match_okay.move @@ -3,2 +3,2 @@ -- fun t(t: u64, match: u64): bool { +- fun t1(t: u64, match: u64): bool { - t == match -+ fun t(t: u64, `match`: u64): bool { ++ fun t1(t: u64, `match`: u64): bool { + t == `match` @@ -7,2 +7,2 @@ -- fun t(t: u64, match: u64): bool { +- fun t2(t: u64, match: u64): bool { - if (t == match) { true } else { false } -+ fun t(t: u64, `match`: u64): bool { ++ fun t2(t: u64, `match`: u64): bool { + if (t == `match`) { true } else { false } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.move b/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.move index 99f2b77c5272b..51c4e5f9c0a60 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/migration/match_okay.move @@ -1,10 +1,10 @@ module a::m { - fun t(t: u64, match: u64): bool { + fun t1(t: u64, match: u64): bool { t == match } - fun t(t: u64, match: u64): bool { + fun t2(t: u64, match: u64): bool { if (t == match) { true } else { false } } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_missing_commas.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_missing_commas.exp index f8bf55019ee54..756fd19d90e79 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_missing_commas.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_missing_commas.exp @@ -7,3 +7,12 @@ error[E01002]: unexpected token │ Unexpected 'copy' │ Expected one of: ',' or ';' +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/ability_modifier_postfix_missing_commas.move:5:1 + │ +5 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', 'struct', or 'enum' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_abilities_no_semi.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_abilities_no_semi.exp index 6b9c8c961fc76..9dbe9838cf7cd 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_abilities_no_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_abilities_no_semi.exp @@ -4,3 +4,12 @@ error[E01002]: unexpected token 4 │ } │ ^ Unexpected '}'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/ability_modifier_postfix_no_abilities_no_semi.move:5:1 + │ +5 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', 'struct', or 'enum' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_abilities_with_semi.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_abilities_with_semi.exp index 9e7317f0fe187..ce74efb8f5345 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_abilities_with_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_abilities_with_semi.exp @@ -4,3 +4,12 @@ error[E01002]: unexpected token 3 │ public struct Foo {} has; │ ^ Unexpected ';'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/ability_modifier_postfix_no_abilities_with_semi.move:5:1 + │ +5 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', 'struct', or 'enum' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_semi.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_semi.exp index 86d858c28c6eb..3a2efb0b77be5 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifier_postfix_no_semi.exp @@ -7,3 +7,12 @@ error[E01002]: unexpected token │ Unexpected '}' │ Expected one of: ',' or ';' +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/ability_modifier_postfix_no_semi.move:5:1 + │ +5 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', 'struct', or 'enum' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifies_infix_no_abilities_postfix.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifies_infix_no_abilities_postfix.exp index 6c82c5e131e47..d8944f01b73a9 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifies_infix_no_abilities_postfix.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifies_infix_no_abilities_postfix.exp @@ -20,3 +20,12 @@ error[E01002]: unexpected token 3 │ struct Foo has copy {} has; │ ^ Unexpected ';'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/ability_modifies_infix_no_abilities_postfix.move:5:1 + │ +5 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', 'struct', or 'enum' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifies_no_abilities_infix_postfix.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifies_no_abilities_infix_postfix.exp index 71fb4b93b2b6c..271c51f1b1409 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifies_no_abilities_infix_postfix.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/ability_modifies_no_abilities_infix_postfix.exp @@ -12,3 +12,18 @@ error[E01002]: unexpected token 3 │ struct Foo has {} has; │ ^ Unexpected '{'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/ability_modifies_no_abilities_infix_postfix.move:3:26 + │ +3 │ struct Foo has {} has; + │ ^ Unexpected ';'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' + +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/ability_modifies_no_abilities_infix_postfix.move:5:1 + │ +5 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', 'struct', or 'enum' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_exists_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_exists_invalid.exp index 907f8a4d3b7a7..7b59b63dd2b1b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_exists_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_exists_invalid.exp @@ -1,22 +1,8 @@ -error[E01003]: invalid modifier - ┌─ tests/move_2024/parser/global_access_exists_invalid.move:2:5 - │ -2 │ struct R {} - │ ^^^^^^ Invalid struct declaration. Internal struct declarations are not yet supported +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/global_access_exists_invalid.move:6:26 │ - = Visibility annotations are required on struct declarations from the Move 2024 edition onwards. - -error[E03011]: invalid use of reserved name - ┌─ tests/move_2024/parser/global_access_exists_invalid.move:9:9 +6 │ let _ : bool = ::exists(0x0); + │ ^^^^^^ Expected '::' after the global address in this module access chain │ -9 │ fun freeze(): u64 { 0 } - │ ^^^^^^ Invalid function name 'freeze'. 'freeze' is restricted and cannot be used to name a function - -error[E01002]: unexpected token - ┌─ tests/move_2024/parser/global_access_exists_invalid.move:13:26 - │ -13 │ let _ : bool = ::exists(0x0); - │ ^^^^^^ Expected '::' after the global address in this module access chain - │ - = Access chains that start with '::' must be multi-part + = Access chains that start with '::' must be multi-part diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_exists_invalid.move b/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_exists_invalid.move index 6d30e066afedb..9a735dec50985 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_exists_invalid.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_exists_invalid.move @@ -1,30 +1,8 @@ module 0x42::M { - struct R {} - fun exists(): u64 { 0 } - fun move_to(): u64 { 0 } - fun borrow_global(): u64 { 0 } - fun borrow_global_mut(): u64 { 0 } - fun move_from(): u64 { 0 } - fun freeze(): u64 { 0 } - fun t(account: &signer) { + fun t(_account: &signer) { let _ : u64 = exists(); let _ : bool = ::exists(0x0); - - let _ : u64 = move_to(); - let () = ::move_to(account, Self::R{}); - - let _ : u64 = borrow_global(); - let _ : &Self::R = ::borrow_global(0x0); - - let _ : u64 = move_from(); - let Self::R {} = ::move_from(0x0); - - let _ : u64 = borrow_global(); - let r : &mut Self::R = ::borrow_global_mut(0x0); - - let _ : u64 = freeze(); - let _ : &Self::R = ::freeze(r); } } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_value_invalid.move b/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_value_invalid.move index f3d93b9940f75..4d7b19f75cd5f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_value_invalid.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/global_access_value_invalid.move @@ -1,5 +1,5 @@ module 0x42::M { - fun foo(): u64 { + fun foo() { 1 + ::global_value } } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang.exp index e9207afbe4596..f4529c6d74f7b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang.exp @@ -1,9 +1,15 @@ +error[E03006]: unexpected name in this position + ┌─ tests/move_2024/parser/invalid_macro_bang.move:3:17 + │ +3 │ fun bar() { foo!(42) } + │ ^^^^^^^^ Expected name to be followed by a brace-enclosed list of field expressions or a parenthesized list of arguments for a function call + error[E01002]: unexpected token - ┌─ tests/move_2024/parser/invalid_macro_bang.move:3:30 + ┌─ tests/move_2024/parser/invalid_macro_bang.move:3:25 │ -3 │ fun bar(): u64 { foo!(42) } - │ ^ - │ │ - │ Unexpected '!' - │ Expected ';' +3 │ fun bar() { foo!(42) } + │ ^ + │ │ + │ Unexpected '!' + │ Expected ';' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang.move b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang.move index 8ba9dc9d65140..cf9aaef810ab4 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang.move @@ -1,4 +1,4 @@ module a::m { macro fun foo<$T>($x: $T): $T { $x } - fun bar(): u64 { foo!(42) } + fun bar() { foo!(42) } } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang_no_args.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang_no_args.exp index 12c98786c3b81..0a2fb151984f8 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang_no_args.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_bang_no_args.exp @@ -1,3 +1,11 @@ +error[E04016]: too few arguments + ┌─ tests/move_2024/parser/invalid_macro_bang_no_args.move:3:17 + │ +3 │ fun bar() { foo!; } + │ ^^^^- Found 0 argument(s) here + │ │ + │ Invalid call of 'a::m::foo'. The call expected 1 argument(s) but got 0 + error[E01002]: unexpected token ┌─ tests/move_2024/parser/invalid_macro_bang_no_args.move:3:21 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_locs.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_locs.exp index 25ba8a9a3a2f0..f99207139b65d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_locs.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/invalid_macro_locs.exp @@ -104,6 +104,17 @@ error[E01002]: unexpected token │ Unexpected '!' │ Expected ';' +error[E04007]: incompatible types + ┌─ tests/move_2024/parser/invalid_macro_locs.move:46:13 + │ +45 │ fun test00(): 0x42::m::S { + │ --------------- Expected: '0x42::m::S' +46 │ 0x42!::m::make_s(0u64) + │ ^ + │ │ + │ Invalid return expression + │ Given: '()' + error[E04029]: invalid function call ┌─ tests/move_2024/parser/invalid_macro_locs.move:50:9 │ @@ -130,6 +141,17 @@ error[E01002]: unexpected token │ Unexpected '!' │ Expected ';' +error[E04007]: incompatible types + ┌─ tests/move_2024/parser/invalid_macro_locs.move:54:13 + │ +53 │ fun test02(): 0x42::m::S { + │ --------------- Expected: '0x42::m::S' +54 │ 0x42!::m!::make_s(0u64) + │ ^ + │ │ + │ Invalid return expression + │ Given: '()' + error[E01016]: invalid name ┌─ tests/move_2024/parser/invalid_macro_locs.move:58:19 │ @@ -147,3 +169,14 @@ error[E01002]: unexpected token │ Unexpected '!' │ Expected ';' +error[E04007]: incompatible types + ┌─ tests/move_2024/parser/invalid_macro_locs.move:62:13 + │ +61 │ fun test04(): 0x42::m::S { + │ --------------- Expected: '0x42::m::S' +62 │ 0x42!::m!::make_s!(0u64) + │ ^ + │ │ + │ Invalid return expression + │ Given: '()' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_block_given_to_break_return_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_block_given_to_break_return_invalid.exp index 5e1703c0d2ee1..b60b2c31c03f8 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_block_given_to_break_return_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_block_given_to_break_return_invalid.exp @@ -1,3 +1,9 @@ +error[E03015]: unbound label + ┌─ tests/move_2024/parser/labeled_block_given_to_break_return_invalid.move:4:15 + │ +4 │ break 'a: { 1 }; + │ ^^ Invalid break. Unbound label 'a + error[E01002]: unexpected token ┌─ tests/move_2024/parser/labeled_block_given_to_break_return_invalid.move:4:17 │ @@ -7,6 +13,12 @@ error[E01002]: unexpected token │ Unexpected ':' │ Expected ';' +error[E03015]: unbound label + ┌─ tests/move_2024/parser/labeled_block_given_to_break_return_invalid.move:8:16 + │ +8 │ return 'a: { 1 }; + │ ^^ Invalid return. Unbound label 'a + error[E01002]: unexpected token ┌─ tests/move_2024/parser/labeled_block_given_to_break_return_invalid.move:8:18 │ @@ -16,6 +28,12 @@ error[E01002]: unexpected token │ Unexpected ':' │ Expected ';' +error[E03015]: unbound label + ┌─ tests/move_2024/parser/labeled_block_given_to_break_return_invalid.move:12:15 + │ +12 │ break 'a: loop {}; + │ ^^ Invalid break. Unbound label 'a + error[E01002]: unexpected token ┌─ tests/move_2024/parser/labeled_block_given_to_break_return_invalid.move:12:17 │ @@ -25,6 +43,12 @@ error[E01002]: unexpected token │ Unexpected ':' │ Expected ';' +error[E03015]: unbound label + ┌─ tests/move_2024/parser/labeled_block_given_to_break_return_invalid.move:16:16 + │ +16 │ return 'a: while (cond) { 1 }; + │ ^^ Invalid return. Unbound label 'a + error[E01002]: unexpected token ┌─ tests/move_2024/parser/labeled_block_given_to_break_return_invalid.move:16:18 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.exp index 7af68f1413176..a155e9d748798 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.exp @@ -1,3 +1,13 @@ +error[E04007]: incompatible types + ┌─ tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.move:13:9 + │ +13 │ if (cond) 'a: { s1 }.f else s2.f + │ ^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found: '0x42::M::S'. It is not compatible with the other type. + │ Incompatible branches + │ Found: '()'. It is not compatible with the other type. + error[E01002]: unexpected token ┌─ tests/move_2024/parser/labeled_control_exp_associativity_else_after_if_block.move:13:32 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_lambda_body_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_lambda_body_invalid.exp index 31a8a49046699..2730857b45b00 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_lambda_body_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_lambda_body_invalid.exp @@ -1,3 +1,18 @@ +error[E04016]: too few arguments + ┌─ tests/move_2024/parser/labeled_lambda_body_invalid.move:7:9 + │ +7 │ call!(|x| -> u64 'a: 0); // parsing error needs a block + │ ^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 0 argument(s) here + │ Invalid call of 'a::m::call'. The call expected 1 argument(s) but got 0 + +error[E04032]: unable to expand macro function + ┌─ tests/move_2024/parser/labeled_lambda_body_invalid.move:7:9 + │ +7 │ call!(|x| -> u64 'a: 0); // parsing error needs a block + │ ^^^^^^^^^^^^^^^^^^^^^^^ Unable to bind lambda to parameter '$f'. The lambda must be passed directly + error[E01002]: unexpected token ┌─ tests/move_2024/parser/labeled_lambda_body_invalid.move:7:30 │ @@ -7,6 +22,21 @@ error[E01002]: unexpected token │ Unexpected '0' │ Expected '{' +error[E04016]: too few arguments + ┌─ tests/move_2024/parser/labeled_lambda_body_invalid.move:11:9 + │ +11 │ call!(|x| -> u64 'a: loop { break 'a 0 }); // parsing error needs a block + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 0 argument(s) here + │ Invalid call of 'a::m::call'. The call expected 1 argument(s) but got 0 + +error[E04032]: unable to expand macro function + ┌─ tests/move_2024/parser/labeled_lambda_body_invalid.move:11:9 + │ +11 │ call!(|x| -> u64 'a: loop { break 'a 0 }); // parsing error needs a block + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Unable to bind lambda to parameter '$f'. The lambda must be passed directly + error[E01002]: unexpected token ┌─ tests/move_2024/parser/labeled_lambda_body_invalid.move:11:30 │ @@ -20,15 +50,17 @@ error[E01002]: unexpected token ┌─ tests/move_2024/parser/labeled_lambda_body_invalid.move:15:46 │ 15 │ call!(|x| -> u64 'a: { return 'a x } + 1); // parsing error, lambdas cant appear in binop - │ - ^ Expected ')' - │ │ - │ To match this '(' + │ ^ + │ │ + │ Unexpected '+' + │ Expected ',' or ')' error[E01002]: unexpected token - ┌─ tests/move_2024/parser/labeled_lambda_body_invalid.move:19:31 + ┌─ tests/move_2024/parser/labeled_lambda_body_invalid.move:19:32 │ -19 │ call!(|x| -> u6 { x } + 1); // parsing error, lambdas cant appear in binop - │ - ^ Expected ')' - │ │ - │ To match this '(' +19 │ call!(|x| -> u64 { x } + 1); // parsing error, lambdas cant appear in binop + │ ^ + │ │ + │ Unexpected '+' + │ Expected ',' or ')' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_lambda_body_invalid.move b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_lambda_body_invalid.move index 0f809cbd1a2bc..008f287c96318 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_lambda_body_invalid.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/labeled_lambda_body_invalid.move @@ -16,6 +16,6 @@ module a::m { } fun t4() { - call!(|x| -> u6 { x } + 1); // parsing error, lambdas cant appear in binop + call!(|x| -> u64 { x } + 1); // parsing error, lambdas cant appear in binop } } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/lambda_expression_return_type_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/lambda_expression_return_type_invalid.exp index 7877bf6f927c6..eaf18607cc58d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/lambda_expression_return_type_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/lambda_expression_return_type_invalid.exp @@ -1,3 +1,18 @@ +error[E04016]: too few arguments + ┌─ tests/move_2024/parser/lambda_expression_return_type_invalid.move:7:9 + │ +7 │ call!(|| -> u64 0); + │ ^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 0 argument(s) here + │ Invalid call of 'a::m::call'. The call expected 1 argument(s) but got 0 + +error[E04032]: unable to expand macro function + ┌─ tests/move_2024/parser/lambda_expression_return_type_invalid.move:7:9 + │ +7 │ call!(|| -> u64 0); + │ ^^^^^^^^^^^^^^^^^^ Unable to bind lambda to parameter '$f'. The lambda must be passed directly + error[E01002]: unexpected token ┌─ tests/move_2024/parser/lambda_expression_return_type_invalid.move:7:25 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/macro_identifier_invalid_no_following_characters.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/macro_identifier_invalid_no_following_characters.exp index 719db31dfc1f3..b903821dfa902 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/macro_identifier_invalid_no_following_characters.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/macro_identifier_invalid_no_following_characters.exp @@ -4,3 +4,12 @@ error[E01002]: unexpected token 2 │ macro fun foo($ │ ^ Expected an identifier following '$', e.g. '$x' +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/macro_identifier_invalid_no_following_characters.move:3:1 + │ +3 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected '{' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.exp index a2dcaeeca2f88..26fd1761d6aa1 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.exp @@ -1,9 +1,12 @@ +error[E04016]: too few arguments + ┌─ tests/move_2024/parser/mut_field_pun_invalid_assign.move:6:9 + │ +6 │ S { mut f } = s; + │ ^^^^^^^^^^^ Missing assignment for field 'f' in 'a::m::S' + error[E01002]: unexpected token ┌─ tests/move_2024/parser/mut_field_pun_invalid_assign.move:6:13 │ -6 │ S { mut f } = s1; - │ ^^^ - │ │ - │ Unexpected 'mut' - │ Expected an identifier +6 │ S { mut f } = s; + │ ^ Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.move b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.move index 6e45a11de282c..df9d4ad8061a6 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_assign.move @@ -1,8 +1,8 @@ module a::m { - public struct S { f: u64 } + public struct S has drop { f: u64 } public fun foo(s: S) { - let f = 0; - S { mut f } = s1; + let _f = 0; + S { mut f } = s; } } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.exp index 3502d1af31a53..be224056bef19 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.exp @@ -1,9 +1,12 @@ +error[E04016]: too few arguments + ┌─ tests/move_2024/parser/mut_field_pun_invalid_pack.move:6:9 + │ +6 │ S { mut f } + │ ^^^^^^^^^^^ Missing argument for field 'f' in 'a::m::S' + error[E01002]: unexpected token ┌─ tests/move_2024/parser/mut_field_pun_invalid_pack.move:6:13 │ 6 │ S { mut f } - │ ^^^ - │ │ - │ Unexpected 'mut' - │ Expected an identifier + │ ^ Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.move b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.move index c3ca646691f75..1f371eb27e0b0 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_field_pun_invalid_pack.move @@ -2,7 +2,7 @@ module a::m { public struct S { f: u64 } public fun foo(): S { - let f = 0; + let _f = 0; S { mut f } } } diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_keyword.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_keyword.exp index 92e3a42483669..718456cd9958e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_keyword.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/mut_keyword.exp @@ -7,3 +7,12 @@ error[E01002]: unexpected token │ Unexpected ':' │ Expected an identifier +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/mut_keyword.move:6:9 + │ +6 │ mut + │ ^^^ + │ │ + │ Unexpected 'mut' + │ Expected an expression term + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid.exp index 3040c4759f2b0..3a662550b49a2 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid.exp @@ -1,3 +1,9 @@ +error[E03009]: unbound variable + ┌─ tests/move_2024/parser/named_blocks_invalid.move:4:9 + │ +4 │ name: { + │ ^^^^ Unbound variable 'name' + error[E01002]: unexpected token ┌─ tests/move_2024/parser/named_blocks_invalid.move:4:13 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid.move b/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid.move index 47542d464a64e..7b255497770f2 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid.move @@ -1,6 +1,6 @@ module 0x42::m { - fun t0(cond: bool): u64 { + fun t0(_cond: bool) { name: { if (cond) { return 'name 10 }; 20 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid_2.move b/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid_2.move index eb68cf153ca11..23a4aa7aa8c58 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid_2.move +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_blocks_invalid_2.move @@ -1,6 +1,6 @@ module 0x42::m { - fun t0(cond: bool): u64 { + fun t0(_cond: bool) { 'name { if (cond) { return 'name 10 }; 20 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_struct_with_positional_fields.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_struct_with_positional_fields.exp index b940a70308507..6086ecd38b8db 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_struct_with_positional_fields.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/named_struct_with_positional_fields.exp @@ -7,3 +7,12 @@ error[E01002]: unexpected token │ Unexpected ',' │ Expected ':' +error[E01002]: unexpected token + ┌─ tests/move_2024/parser/named_struct_with_positional_fields.move:3:31 + │ +3 │ public struct Foo{u64, u16} has copy, drop; + │ ^ + │ │ + │ Unexpected '}' + │ Expected ':' + diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_explicit_type_arg_assign.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_explicit_type_arg_assign.exp index 623f94ca49b6a..c6050c2417b06 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_explicit_type_arg_assign.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_explicit_type_arg_assign.exp @@ -1,3 +1,38 @@ +error[E03003]: unbound module member + ┌─ tests/move_2024/parser/positional_struct_explicit_type_arg_assign.move:5:9 + │ +5 │ Foo (_) = Foo(0); + │ ^^^ Invalid module access. Unbound constant 'Foo' in module '0x42::M' + +error[E04003]: built-in operation not supported + ┌─ tests/move_2024/parser/positional_struct_explicit_type_arg_assign.move:5:9 + │ +5 │ Foo (_) = Foo(0); + │ ^^^^^^^^ + │ │ + │ Invalid argument to '>' + │ Found: 'bool'. But expected: 'u8', 'u16', 'u32', 'u64', 'u128', 'u256' + +error[E03009]: unbound variable + ┌─ tests/move_2024/parser/positional_struct_explicit_type_arg_assign.move:5:14 + │ +5 │ Foo (_) = Foo(0); + │ ^^^ Unbound variable 'u64' + +error[E03009]: unbound variable + ┌─ tests/move_2024/parser/positional_struct_explicit_type_arg_assign.move:5:19 + │ +5 │ Foo (_) = Foo(0); + │ ^ Unbound variable '_' + +error[E04003]: built-in operation not supported + ┌─ tests/move_2024/parser/positional_struct_explicit_type_arg_assign.move:5:19 + │ +5 │ Foo (_) = Foo(0); + │ -------- ^ Invalid argument to '>' + │ │ + │ Found: 'bool'. But expected: 'u8', 'u16', 'u32', 'u64', 'u128', 'u256' + error[E01002]: unexpected token ┌─ tests/move_2024/parser/positional_struct_explicit_type_arg_assign.move:5:22 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_keyword_field.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_keyword_field.exp index 7bd66dcf598c1..02bd5b07c6190 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_keyword_field.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_keyword_field.exp @@ -2,10 +2,7 @@ error[E01002]: unexpected token ┌─ tests/move_2024/parser/positional_struct_fields_keyword_field.move:3:23 │ 3 │ public struct Foo(fun) - │ ^^^ - │ │ - │ Unexpected 'fun' - │ Expected a type name + │ ^ Expected a type error[E01002]: unexpected token ┌─ tests/move_2024/parser/positional_struct_fields_keyword_field.move:3:26 diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_non_type_field.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_non_type_field.exp index 90a89c13ae6d8..38d513fccd621 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_non_type_field.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/positional_struct_fields_non_type_field.exp @@ -1,8 +1,15 @@ +error[E03004]: unbound type + ┌─ tests/move_2024/parser/positional_struct_fields_non_type_field.move:3:23 + │ +3 │ public struct Foo(Not a type) + │ ^^^ Unbound type 'Not' in current scope + error[E01002]: unexpected token ┌─ tests/move_2024/parser/positional_struct_fields_non_type_field.move:3:27 │ 3 │ public struct Foo(Not a type) - │ - ^ Expected ')' - │ │ - │ To match this '(' + │ ^ + │ │ + │ Unexpected 'a' + │ Expected ',' or ')' diff --git a/external-crates/move/crates/move-compiler/tests/move_2024/parser/struct_ellipsis_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_2024/parser/struct_ellipsis_invalid.exp index d612cd0f27dfa..631200af32eec 100644 --- a/external-crates/move/crates/move-compiler/tests/move_2024/parser/struct_ellipsis_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_2024/parser/struct_ellipsis_invalid.exp @@ -1,3 +1,11 @@ +warning[W09002]: unused variable + ┌─ tests/move_2024/parser/struct_ellipsis_invalid.move:8:11 + │ +8 │ fun f(y: X): u64 { + │ ^ Unused parameter 'y'. Consider removing or prefixing with an underscore: '_y' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + error[E01002]: unexpected token ┌─ tests/move_2024/parser/struct_ellipsis_invalid.move:9:13 │ @@ -7,3 +15,9 @@ error[E01002]: unexpected token │ Unexpected '..' │ Expected a variable or struct name +error[E03009]: unbound variable + ┌─ tests/move_2024/parser/struct_ellipsis_invalid.move:10:9 + │ +10 │ x + │ ^ Unbound variable 'x' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_not_name.move b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_not_name.move index cb21061d8d132..85f662131e28b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_not_name.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_not_name.move @@ -1,6 +1,6 @@ module 0x42::M { fun foo() { - let f = 0; + let _f = 0; 0 { f } = 0; } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.exp index ef6dec2e9ced4..94080d4dbc66f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.exp @@ -7,3 +7,23 @@ error[E01002]: unexpected token │ Unexpected '{' │ Expected ';' +error[E03003]: unbound module member + ┌─ tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.move:5:9 + │ +5 │ foo() = 0; + │ ^^^ Invalid module access. Unbound struct 'foo' in module '0x42::M' + +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.move:5:9 + │ +5 │ foo() = 0; + │ ^^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + +error[E01009]: invalid assignment + ┌─ tests/move_check/expansion/invalid_unpack_assign_lhs_other_value.move:7:9 + │ +7 │ foo().bar() = 0; + │ ^^^^^^^^^^^ Invalid assignment syntax. Expected: a local, a field write, or a deconstructing assignment + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/mdot_with_non_address_exp.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/mdot_with_non_address_exp.exp index 63f8c7db9e760..37e07fee6ff54 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/mdot_with_non_address_exp.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/mdot_with_non_address_exp.exp @@ -16,6 +16,23 @@ error[E01002]: unexpected token │ Unexpected '::' │ Expected ';' +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/expansion/mdot_with_non_address_exp.move:17:9 + │ +17 │ foo().bar().X::bar() + │ ^^^^^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + +error[E04023]: invalid method call + ┌─ tests/move_check/expansion/mdot_with_non_address_exp.move:17:9 + │ + 8 │ fun foo() { + │ --- Method calls are only supported on single types. Got an expression of type: '()' + · +17 │ foo().bar().X::bar() + │ ^^^^^^^^^^^ Invalid method call + error[E01002]: unexpected token ┌─ tests/move_check/expansion/mdot_with_non_address_exp.move:17:22 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.exp index b922a9341b2bb..0366c61028b5f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.exp @@ -1,9 +1,29 @@ error[E01002]: unexpected token - ┌─ tests/move_check/expansion/pack_no_fields_block_expr.move:4:21 + ┌─ tests/move_check/expansion/pack_no_fields_block_expr.move:4:22 │ -4 │ let s = S { let x = 0; x }; - │ ^^^ - │ │ - │ Unexpected 'let' - │ Expected an identifier +4 │ let _s = S { let x = 0; x }; + │ ^ Expected a field expression + +error[E01002]: unexpected token + ┌─ tests/move_check/expansion/pack_no_fields_block_expr.move:4:31 + │ +4 │ let _s = S { let x = 0; x }; + │ - ^ Expected '}' + │ │ + │ To match this '{' + +error[E03009]: unbound variable + ┌─ tests/move_check/expansion/pack_no_fields_block_expr.move:4:33 + │ +4 │ let _s = S { let x = 0; x }; + │ ^ Unbound variable 'x' + +error[E01002]: unexpected token + ┌─ tests/move_check/expansion/pack_no_fields_block_expr.move:4:36 + │ +4 │ let _s = S { let x = 0; x }; + │ ^ + │ │ + │ Unexpected ';' + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.move b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.move index 7457bc5846fd8..181e59ce0652e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_block_expr.move @@ -1,7 +1,7 @@ module 0x42::M { struct S {} fun foo() { - let s = S { let x = 0; x }; - let s = S { let y = 0; let z = 0; x + foo() }; + let _s = S { let x = 0; x }; + let _s = S { let y = 0; let z = 0; x + foo() }; } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.exp index 0b0036fb99e36..22354ac94760e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.exp @@ -1,9 +1,24 @@ +error[E04016]: too few arguments + ┌─ tests/move_check/expansion/pack_no_fields_single_block_expr.move:4:18 + │ +4 │ let _s = S { false }; + │ ^^^^^^^^^^^ Missing argument for field 'f' in '0x42::M::S' + +error[E01002]: unexpected token + ┌─ tests/move_check/expansion/pack_no_fields_single_block_expr.move:4:22 + │ +4 │ let _s = S { false }; + │ ^ Expected a field expression + +error[E04016]: too few arguments + ┌─ tests/move_check/expansion/pack_no_fields_single_block_expr.move:5:18 + │ +5 │ let _s = S { 0 }; + │ ^^^^^^^ Missing argument for field 'f' in '0x42::M::S' + error[E01002]: unexpected token - ┌─ tests/move_check/expansion/pack_no_fields_single_block_expr.move:4:21 + ┌─ tests/move_check/expansion/pack_no_fields_single_block_expr.move:5:22 │ -4 │ let s = S { false }; - │ ^^^^^ - │ │ - │ Unexpected 'false' - │ Expected an identifier +5 │ let _s = S { 0 }; + │ ^ Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.move b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.move index 1c2b3b35c5b94..5a64057866996 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_expr.move @@ -1,7 +1,7 @@ module 0x42::M { struct S { f: u64 } fun foo() { - let s = S { false }; - let s = S { 0 }; + let _s = S { false }; + let _s = S { 0 }; } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.exp index a23a1e35c0b4f..22da1d2fc3ec0 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.exp @@ -1,9 +1,50 @@ +error[E03003]: unbound module member + ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:6:18 + │ +6 │ let _s = S 0; + │ ^ Invalid module access. Unbound constant 'S' in module '0x42::M' + +error[E01002]: unexpected token + ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:6:20 + │ +6 │ let _s = S 0; + │ ^ + │ │ + │ Unexpected '0' + │ Expected ';' + +error[E03003]: unbound module member + ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:7:18 + │ +7 │ let _s = S f; + │ ^ Invalid module access. Unbound constant 'S' in module '0x42::M' + +error[E01002]: unexpected token + ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:7:20 + │ +7 │ let _s = S f; + │ ^ + │ │ + │ Unexpected 'f' + │ Expected ';' + +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:8:18 + │ +8 │ let _g = G (); + │ ^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + +error[E03013]: positional call mismatch + ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:8:18 + │ +8 │ let _g = G (); + │ ^^^^ Invalid struct instantiation. Named struct declarations require named instantiations. + error[E01002]: unexpected token - ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:6:19 + ┌─ tests/move_check/expansion/pack_no_fields_single_block_other_expr.move:9:22 │ -6 │ let s = S 0; - │ ^ - │ │ - │ Unexpected '0' - │ Expected ';' +9 │ let _g = G { {} }; + │ ^ Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.move b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.move index 6a665053dfb7a..0ceafbcbee1dc 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/pack_no_fields_single_block_other_expr.move @@ -2,10 +2,10 @@ module 0x42::M { struct S { f: u64 } struct G {} fun foo() { - let f = 0; - let s = S 0; - let s = S f; - let g = G (); - let g = G { {} }; + let _f = 0; + let _s = S 0; + let _s = S f; + let _g = G (); + let _g = G { {} }; } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/standalone_fields.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/standalone_fields.exp index 4757b1b12eb0b..c0087c61a6da6 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/standalone_fields.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/standalone_fields.exp @@ -1,3 +1,9 @@ +error[E03009]: unbound variable + ┌─ tests/move_check/expansion/standalone_fields.move:3:10 + │ +3 │ {f: 1, g: 0}; + │ ^ Unbound variable 'f' + error[E01002]: unexpected token ┌─ tests/move_check/expansion/standalone_fields.move:3:11 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/type_arguments_on_field_access.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/type_arguments_on_field_access.exp index ca954559aea0a..34687fe678899 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/type_arguments_on_field_access.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/type_arguments_on_field_access.exp @@ -1,3 +1,20 @@ +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/expansion/type_arguments_on_field_access.move:6:9 + │ +6 │ x.f; + │ ^^^^^^^^ Method syntax is not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + +error[E04023]: invalid method call + ┌─ tests/move_check/expansion/type_arguments_on_field_access.move:6:9 + │ +6 │ x.f; + │ ^^^^^^^^ + │ │ │ + │ │ No local 'use fun' alias was found for '0x42::M::S.f', and no function 'f' was found in the defining module '0x42::M' + │ Invalid method call. No known method 'f' on type '0x42::M::S' + error[E01002]: unexpected token ┌─ tests/move_check/expansion/type_arguments_on_field_access.move:6:17 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_expr.exp index bb406949dd8c0..ec26e6b5c073c 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_expr.exp @@ -1,9 +1,41 @@ +error[E04016]: too few arguments + ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:9 + │ +4 │ S { let f = 0; } = S { f: 0 }; + │ ^^^^^^^^^^^^^ Missing argument for field 'f' in '0x42::M::S' + +error[E05001]: ability constraint not satisfied + ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:9 + │ +2 │ struct S { f: u64 } + │ - To satisfy the constraint, the 'drop' ability would need to be added here +3 │ fun foo() { +4 │ S { let f = 0; } = S { f: 0 }; + │ ^^^^^^^^^^^^^ + │ │ + │ Cannot ignore values without the 'drop' ability. The value must be used + │ The type '0x42::M::S' does not have the ability 'drop' + error[E01002]: unexpected token ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:13 │ 4 │ S { let f = 0; } = S { f: 0 }; - │ ^^^ - │ │ - │ Unexpected 'let' - │ Expected an identifier + │ ^ Expected a field expression + +error[E01002]: unexpected token + ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:22 + │ +4 │ S { let f = 0; } = S { f: 0 }; + │ - ^ Expected '}' + │ │ + │ To match this '{' + +error[E01002]: unexpected token + ┌─ tests/move_check/expansion/unpack_assign_block_expr.move:4:26 + │ +4 │ S { let f = 0; } = S { f: 0 }; + │ ^ + │ │ + │ Unexpected '=' + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_single_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_single_expr.exp index 704367ea30ee3..e9971fb374a2f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_single_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_block_single_expr.exp @@ -1,9 +1,12 @@ +error[E04016]: too few arguments + ┌─ tests/move_check/expansion/unpack_assign_block_single_expr.move:4:9 + │ +4 │ S { 0 } = S { f: 0 }; + │ ^^^^^^^ Missing assignment for field 'f' in '0x42::M::S' + error[E01002]: unexpected token ┌─ tests/move_check/expansion/unpack_assign_block_single_expr.move:4:13 │ 4 │ S { 0 } = S { f: 0 }; - │ ^ - │ │ - │ Unexpected '0' - │ Expected an identifier + │ ^ Expected a field expression diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_other_expr.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_other_expr.exp index c7b21d511bf69..7350c2f55a097 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_other_expr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/unpack_assign_other_expr.exp @@ -1,3 +1,43 @@ +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:6:9 + │ +6 │ S ( f ) = S { f: 0 }; + │ ^^^^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + +error[E03013]: positional call mismatch + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:6:9 + │ +6 │ S ( f ) = S { f: 0 }; + │ ^^^^^^^ Invalid deconstruction. Named struct field declarations require named deconstruction + +error[E04016]: too few arguments + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:6:9 + │ +6 │ S ( f ) = S { f: 0 }; + │ ^^^^^^^ Missing assignment for field 'f' in '0x42::M::S' + +error[E03010]: unbound field + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:6:9 + │ +6 │ S ( f ) = S { f: 0 }; + │ ^^^^^^^ Unbound field '0' in '0x42::M::S' + +warning[W09002]: unused variable + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:8:13 + │ +8 │ let f: u64; + │ ^ Unused local variable 'f'. Consider removing or prefixing with an underscore: '_f' + │ + = This warning can be suppressed with '#[allow(unused_variable)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + +error[E03003]: unbound module member + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:9:9 + │ +9 │ S f = S { f: 0 }; + │ ^ Invalid module access. Unbound constant 'S' in module '0x42::M' + error[E01002]: unexpected token ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:9:11 │ @@ -7,3 +47,23 @@ error[E01002]: unexpected token │ Unexpected 'f' │ Expected ';' +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:11:9 + │ +11 │ G () = G {}; + │ ^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + +error[E03013]: positional call mismatch + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:11:9 + │ +11 │ G () = G {}; + │ ^^^^ Invalid deconstruction. Named struct field declarations require named deconstruction + +error[E01002]: unexpected token + ┌─ tests/move_check/expansion/unpack_assign_other_expr.move:12:12 + │ +12 │ G {{}} = G{}; + │ ^ Expected a field expression + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/weird_apply_assign.exp b/external-crates/move/crates/move-compiler/tests/move_check/expansion/weird_apply_assign.exp index 41f25f90cdf53..7335d9bbde5c2 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/weird_apply_assign.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/weird_apply_assign.exp @@ -1,3 +1,15 @@ +error[E01009]: invalid assignment + ┌─ tests/move_check/expansion/weird_apply_assign.move:5:9 + │ +5 │ { f } = S { f: 0 }; + │ ^^^^^ Invalid assignment syntax. Expected: a local, a field write, or a deconstructing assignment + +error[E03003]: unbound module member + ┌─ tests/move_check/expansion/weird_apply_assign.move:7:9 + │ +7 │ S f = S { f: 0 }; + │ ^ Invalid module access. Unbound constant 'S' in module '0x42::M' + error[E01002]: unexpected token ┌─ tests/move_check/expansion/weird_apply_assign.move:7:11 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/expansion/weird_apply_assign.move b/external-crates/move/crates/move-compiler/tests/move_check/expansion/weird_apply_assign.move index 1bf9ea2964a70..611645f7a3dea 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/expansion/weird_apply_assign.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/expansion/weird_apply_assign.move @@ -1,7 +1,7 @@ module 0x42::M { struct S { f: u64 } fun foo() { - let f: u64; + let _f: u64; { f } = S { f: 0 }; S f = S { f: 0 }; diff --git a/external-crates/move/crates/move-compiler/tests/move_check/naming/named_blocks_invalid.move b/external-crates/move/crates/move-compiler/tests/move_check/naming/named_blocks_invalid.move index 12c758b07dc13..94603f3add8f7 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/naming/named_blocks_invalid.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/naming/named_blocks_invalid.move @@ -1,5 +1,5 @@ module 0x42::m { - fun t0(cond: bool): u64 { + fun t0(_cond: bool) { 'name: { if (cond) { break 'name 10 }; if (cond) { continue 'name }; @@ -7,13 +7,13 @@ module 0x42::m { } } - fun t1(cond: bool): u64 { + fun t1(_cond: bool) { loop 'name: { if (cond) { return 'name 10 }; } } - fun t2(cond: bool): u64 { + fun t2(_cond: bool) { loop 'outer: { loop 'inner: { if (cond) { return 'outer 10 }; @@ -22,7 +22,7 @@ module 0x42::m { } } - fun t3(cond: bool) { + fun t3(_cond: bool) { while (cond) 'outer: { while (cond) 'inner: { if (cond) { return 'outer }; @@ -31,7 +31,7 @@ module 0x42::m { } } - fun t4(cond: bool) { + fun t4(_cond: bool) { while (cond) 'outer: { let _x = 'inner: { if (cond) { return 'outer }; @@ -49,21 +49,21 @@ module 0x42::m { } } - fun t6(cond: bool): u64 { + fun t6(_cond: bool) { 'name: { if (cond) { return 'name2 10 }; 20 } } - fun t7(cond: bool): u64 { + fun t7(_cond: bool) { loop 'name: { if (cond) { continue 'name2 }; if (cond) { break 'name2 10 }; } } - fun t8(cond: bool): u64 { + fun t8(_cond: bool) { loop 'outer2: { loop 'inner2: { if (cond) { break 'outer 10 }; @@ -72,7 +72,7 @@ module 0x42::m { } } - fun t9(cond: bool) { + fun t9(_cond: bool) { while (cond) 'outer: { while (cond) 'inner: { if (cond) { continue 'outer2 }; diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.exp index 1f36cb8219b66..c7b5a24b5475e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.exp @@ -4,3 +4,11 @@ error[E01002]: unexpected token 4 │ struct Foo has {} has copy; │ ^ Unexpected '{'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/parser/ability_modifier_invalid_infix_with_valid_postfix.move:4:23 + │ +4 │ struct Foo has {} has copy; + │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_commas.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_commas.exp index f5bf6c7d66d13..a47a243ca2915 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_commas.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_missing_commas.exp @@ -15,3 +15,12 @@ error[E01002]: unexpected token │ Unexpected 'copy' │ Expected one of: ',' or ';' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/ability_modifier_postfix_missing_commas.move:8:1 + │ +8 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.exp index 320ba365e3906..3334f435cf6a9 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.exp @@ -12,3 +12,12 @@ error[E01002]: unexpected token 6 │ } │ ^ Unexpected '}'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/ability_modifier_postfix_no_abilities_no_semi.move:8:1 + │ +8 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.exp index 4dd591b45fa68..e29baaf3fcee2 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.exp @@ -12,3 +12,12 @@ error[E01002]: unexpected token 5 │ struct Foo {} has; │ ^ Unexpected ';'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/ability_modifier_postfix_no_abilities_with_semi.move:8:1 + │ +8 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_semi.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_semi.exp index b91b009bcfef6..9b15192721e84 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_semi.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifier_postfix_no_semi.exp @@ -15,3 +15,12 @@ error[E01002]: unexpected token │ Unexpected '}' │ Expected one of: ',' or ';' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/ability_modifier_postfix_no_semi.move:8:1 + │ +8 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.exp index 94606dc7684da..37587798c5d0f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.exp @@ -20,3 +20,12 @@ error[E01002]: unexpected token 4 │ struct Foo has copy {} has; │ ^ Unexpected ';'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/ability_modifies_infix_no_abilities_postfix.move:7:1 + │ +7 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.exp index ab5a1e8562054..f7129990acce7 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.exp @@ -4,3 +4,26 @@ error[E01002]: unexpected token 4 │ struct Foo has {} has; │ ^ Unexpected '{'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.move:4:23 + │ +4 │ struct Foo has {} has; + │ ^^^ Postfix abilities are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature + │ + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.move:4:26 + │ +4 │ struct Foo has {} has; + │ ^ Unexpected ';'. Expected a type ability, one of: 'copy', 'drop', 'store', or 'key' + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/ability_modifies_no_abilities_infix_postfix.move:8:1 + │ +8 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/attribute_no_closing_bracket.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/attribute_no_closing_bracket.exp index bfc04c01742ef..67ccfc115f03a 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/attribute_no_closing_bracket.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/attribute_no_closing_bracket.exp @@ -1,3 +1,9 @@ +warning[W02018]: unknown attribute + ┌─ tests/move_check/parser/attribute_no_closing_bracket.move:3:7 + │ +3 │ #[attr = 0 + │ ^^^^ Unknown attribute 'attr'. Custom attributes must be wrapped in 'ext', e.g. #[ext(attr)] + error[E01002]: unexpected token ┌─ tests/move_check/parser/attribute_no_closing_bracket.move:4:5 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/borrow_mut_space.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/borrow_mut_space.exp index 144ccb4dd4929..9f2312a01989e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/borrow_mut_space.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/borrow_mut_space.exp @@ -1,3 +1,9 @@ +error[E03009]: unbound variable + ┌─ tests/move_check/parser/borrow_mut_space.move:6:11 + │ +6 │ & mut x.f + │ ^^^ Unbound variable 'mut' + error[E01002]: unexpected token ┌─ tests/move_check/parser/borrow_mut_space.move:6:15 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/borrow_mut_space.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/borrow_mut_space.move index b09c62b0ae65c..e871d503abf23 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/borrow_mut_space.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/borrow_mut_space.move @@ -2,7 +2,7 @@ module a::m { struct S { f: u64, } - public fun foo(x: &mut S): &mut u64 { + public fun foo(_x: &mut S) { & mut x.f } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_else_after_if_block.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_else_after_if_block.exp index a05e423d0d8bf..f8e6e2bde401f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_else_after_if_block.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/control_exp_associativity_else_after_if_block.exp @@ -1,3 +1,15 @@ +error[E04007]: incompatible types + ┌─ tests/move_check/parser/control_exp_associativity_else_after_if_block.move:13:9 + │ + 7 │ fun t(cond: bool, s1: S, s2: S) { + │ - Found: '0x42::M::S'. It is not compatible with the other type. + · +13 │ if (cond) { s1 }.f else s2.f + │ ^^^^^^^^^^^^^^^^ + │ │ + │ Incompatible branches + │ Found: '()'. It is not compatible with the other type. + error[E01002]: unexpected token ┌─ tests/move_check/parser/control_exp_associativity_else_after_if_block.move:13:28 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.move index ea422dfc2b1fc..2b53c3c6bbe93 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_abort_missing_value.move @@ -1,5 +1,5 @@ module 0x42::M { - fun f(v: u64) { + fun f(_v: u64) { // Aborts always require a value if (v > 100) abort } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_if_missing_parens.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_if_missing_parens.move index 2552c1d34891c..2e1eba6fade4b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_if_missing_parens.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_if_missing_parens.move @@ -1,5 +1,5 @@ module 0x42::M { - fun f(v: u64) { + fun f(_v: u64) { // Test an "if" expression missing parenthesis around the condition if v < 3 () } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_unary_negation.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_unary_negation.exp index 79265cd4f279f..f3fb8cdbb9c71 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_unary_negation.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_unary_negation.exp @@ -1,3 +1,12 @@ +error[E04016]: too few arguments + ┌─ tests/move_check/parser/expr_unary_negation.move:5:5 + │ +5 │ assert!(((1 - -2) == 3) && (-(1 - 2) == 1), 100); + │ ^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ Found 0 argument(s) here + │ Invalid call of 'assert'. The call expected 2 argument(s) but got 0 + error[E01002]: unexpected token ┌─ tests/move_check/parser/expr_unary_negation.move:5:19 │ @@ -7,3 +16,21 @@ error[E01002]: unexpected token │ Unexpected '-' │ Expected an expression term +error[E04007]: incompatible types + ┌─ tests/move_check/parser/expr_unary_negation.move:5:23 + │ +5 │ assert!(((1 - -2) == 3) && (-(1 - 2) == 1), 100); + │ ----------------- ^^ - Found: integer. It is not compatible with the other type. + │ │ │ + │ │ Incompatible arguments to '==' + │ Found: '()'. It is not compatible with the other type. + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/expr_unary_negation.move:5:27 + │ +5 │ assert!(((1 - -2) == 3) && (-(1 - 2) == 1), 100); + │ ^ + │ │ + │ Unexpected ')' + │ Expected ';' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_while_missing_parens.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_while_missing_parens.move index 51e7a37d6e96d..17f1efaa6f002 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_while_missing_parens.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/expr_while_missing_parens.move @@ -1,5 +1,5 @@ module 0x42::M { - fun f(v: u64) { + fun f(_v: u64) { // Test a "while" expression missing parenthesis around the condition while v < 3 { v = v + 1 } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_incomplete.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_incomplete.exp index 27429d9b06188..40dc50a549852 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_incomplete.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_incomplete.exp @@ -1,9 +1,36 @@ error[E01002]: unexpected token - ┌─ tests/move_check/parser/function_incomplete.move:5:1 + ┌─ tests/move_check/parser/function_incomplete.move:6:5 │ -5 │ - │ ^ - │ - │ Unexpected end-of-file - │ Expected an expression term +6 │ fun just_type_args + │ ^^^ + │ │ + │ Unexpected 'fun' + │ Expected '(' + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/function_incomplete.move:8:5 + │ +8 │ fun just_param(_u: u64) + │ ^^^ + │ │ + │ Unexpected 'fun' + │ Expected '(' + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/function_incomplete.move:10:5 + │ +10 │ fun just_ret(_u: u64): u64 + │ ^^^ + │ │ + │ Unexpected 'fun' + │ Expected '{' + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/function_incomplete.move:12:5 + │ +12 │ fun everything(u: u64): u64 { + │ ^^^ + │ │ + │ Unexpected 'fun' + │ Expected '{' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_incomplete.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_incomplete.move index 80c15638f1f46..9ffa04494b90c 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_incomplete.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_incomplete.move @@ -1,4 +1,23 @@ +// correct compilation of partial function definitions as evidenced by the ability to call all its +// variants without an error module 0x42::m { -fun main() { -// } -//} + fun just_name + + fun just_type_args + + fun just_param(_u: u64) + + fun just_ret(_u: u64): u64 + + fun everything(u: u64): u64 { + u + } + + fun foo() { + just_name(); + just_type_args(); + just_param(42); + let _n1 = just_ret(42); + let _n2 = everything(42); + } +} diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_native_with_body.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_native_with_body.exp index 030ea84a21ca3..4bffeb7c6f62e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_native_with_body.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_native_with_body.exp @@ -7,3 +7,12 @@ error[E01002]: unexpected token │ Unexpected '{' │ Expected ';' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/function_native_with_body.move:5:1 + │ +5 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_without_body.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_without_body.exp index a131539347cc2..2774b3238a6de 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/function_without_body.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/function_without_body.exp @@ -7,3 +7,12 @@ error[E01002]: unexpected token │ Unexpected ';' │ Expected '{' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/function_without_body.move:5:1 + │ +5 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access.exp index 5ed8ad5e31d88..c9ccfa1801244 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access.exp @@ -1,15 +1,9 @@ -error[E03011]: invalid use of reserved name - ┌─ tests/move_check/parser/global_access.move:9:9 - │ -9 │ fun freeze(): u64 { 0 } - │ ^^^^^^ Invalid function name 'freeze'. 'freeze' is restricted and cannot be used to name a function - error[E01002]: unexpected token - ┌─ tests/move_check/parser/global_access.move:13:24 - │ -13 │ let _ : bool = ::exists(0x0); - │ ^^ - │ │ - │ Unexpected '::' - │ Expected an expression term + ┌─ tests/move_check/parser/global_access.move:6:24 + │ +6 │ let _ : bool = ::exists(0x0); + │ ^^ + │ │ + │ Unexpected '::' + │ Expected an expression term diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access.move index 6d30e066afedb..9a735dec50985 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access.move @@ -1,30 +1,8 @@ module 0x42::M { - struct R {} - fun exists(): u64 { 0 } - fun move_to(): u64 { 0 } - fun borrow_global(): u64 { 0 } - fun borrow_global_mut(): u64 { 0 } - fun move_from(): u64 { 0 } - fun freeze(): u64 { 0 } - fun t(account: &signer) { + fun t(_account: &signer) { let _ : u64 = exists(); let _ : bool = ::exists(0x0); - - let _ : u64 = move_to(); - let () = ::move_to(account, Self::R{}); - - let _ : u64 = borrow_global(); - let _ : &Self::R = ::borrow_global(0x0); - - let _ : u64 = move_from(); - let Self::R {} = ::move_from(0x0); - - let _ : u64 = borrow_global(); - let r : &mut Self::R = ::borrow_global_mut(0x0); - - let _ : u64 = freeze(); - let _ : &Self::R = ::freeze(r); } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access_value.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access_value.move index f3d93b9940f75..4d7b19f75cd5f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access_value.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/global_access_value.move @@ -1,5 +1,5 @@ module 0x42::M { - fun foo(): u64 { + fun foo() { 1 + ::global_value } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_missing_quote.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_missing_quote.move index e44e6b04a5ce0..fc699ddd917b2 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_missing_quote.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_missing_quote.move @@ -1,5 +1,5 @@ module 0x42::M { - public fun missing_quote(): vector { + public fun missing_quote() { x"abcd } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof1.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof1.exp index e8b22c3dfef23..b07714aa816a3 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof1.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof1.exp @@ -4,3 +4,12 @@ error[E01008]: invalid hex string 3 │ x" │ ^^ Missing closing quote (") after byte string +error[E01002]: unexpected token + ┌─ tests/move_check/parser/hexstring_token_eof1.move:4:1 + │ +4 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof1.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof1.move index bf2a0ee77743f..ea48d10746616 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof1.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof1.move @@ -1,3 +1,3 @@ module 0x42::M { - public fun foo(): vector { + public fun foo() { x" diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof2.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof2.exp index 1190c337c0a62..a04174259ad53 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof2.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof2.exp @@ -4,3 +4,12 @@ error[E01008]: invalid hex string 3 │ x"abcd │ ^^^^^^ Missing closing quote (") after byte string +error[E01002]: unexpected token + ┌─ tests/move_check/parser/hexstring_token_eof2.move:4:1 + │ +4 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof2.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof2.move index db7eb5307ac0f..97273f395418d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof2.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/hexstring_token_eof2.move @@ -1,3 +1,3 @@ module 0x42::M { - public fun foo(): vector { + public fun foo() { x"abcd diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_complex_expression.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_complex_expression.exp index fee0df0f4e049..0538b533cf1df 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_complex_expression.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_complex_expression.exp @@ -7,3 +7,12 @@ error[E01002]: unexpected token │ Unexpected '(' │ Expected ';' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/invalid_call_lhs_complex_expression.move:4:27 + │ +4 │ (while (false) {})(0, 1); + │ ^ + │ │ + │ Unexpected '(' + │ Expected ';' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_parens_around_name.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_parens_around_name.exp index 49558ae3304f2..d1d281f51c188 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_parens_around_name.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_parens_around_name.exp @@ -1,3 +1,9 @@ +error[E03009]: unbound variable + ┌─ tests/move_check/parser/invalid_call_lhs_parens_around_name.move:3:10 + │ +3 │ (foo)() + │ ^^^ Unbound variable 'foo' + error[E01002]: unexpected token ┌─ tests/move_check/parser/invalid_call_lhs_parens_around_name.move:3:14 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_value.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_value.exp index e75abc53ec0b7..f6294f34718ac 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_value.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_call_lhs_value.exp @@ -7,3 +7,12 @@ error[E01002]: unexpected token │ Unexpected '(' │ Expected ';' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/invalid_call_lhs_value.move:4:10 + │ +4 │ 5(0, 1); + │ ^ + │ │ + │ Unexpected '(' + │ Expected ';' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_pack_mname_non_addr.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_pack_mname_non_addr.exp index 923a623be25cf..f42030a5befa0 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_pack_mname_non_addr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_pack_mname_non_addr.exp @@ -10,7 +10,7 @@ error[E01002]: unexpected token error[E01002]: unexpected token ┌─ tests/move_check/parser/invalid_pack_mname_non_addr.move:8:9 │ -8 │ fun bar()::bar()::M::S { } +8 │ fun baz()::baz()::M::S { } │ ^^^ │ │ │ Unexpected 'fun' @@ -19,9 +19,18 @@ error[E01002]: unexpected token error[E01002]: unexpected token ┌─ tests/move_check/parser/invalid_pack_mname_non_addr.move:8:18 │ -8 │ fun bar()::bar()::M::S { } +8 │ fun baz()::baz()::M::S { } │ ^^ │ │ │ Unexpected '::' │ Expected '{' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/invalid_pack_mname_non_addr.move:11:1 + │ +11 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_pack_mname_non_addr.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_pack_mname_non_addr.move index 09e08a31e6191..15425d4e561cb 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_pack_mname_non_addr.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_pack_mname_non_addr.move @@ -5,6 +5,6 @@ module 0x42::M { } fun bar() { - fun bar()::bar()::M::S { } + fun baz()::baz()::M::S { } } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.exp index 46bc5a920cb85..3ffde1ad4a2ea 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.exp @@ -7,3 +7,39 @@ error[E01002]: unexpected token │ Unexpected '::' │ Expected ';' +error[E03006]: unexpected name in this position + ┌─ tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.move:7:9 + │ +7 │ 0::M { f } = 0; + │ ^^^^ + │ │ + │ Unexpected module identifier. A module identifier is not a valid type + │ Expected a module name + +error[E04005]: expected a single type + ┌─ tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.move:10:9 + │ + 2 │ fun foo() { + │ --- Expected a single type, but found expression list type: '()' + · +10 │ foo().M { f } = 0; + │ ^^^^^ Invalid dot access + +error[E04009]: expected specific type + ┌─ tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.move:10:9 + │ + 2 │ fun foo() { + │ --- Expected a struct type in the current module but got: '()' + · +10 │ foo().M { f } = 0; + │ ^^^^^^^ Unbound field 'M' + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.move:10:17 + │ +10 │ foo().M { f } = 0; + │ ^ + │ │ + │ Unexpected '{' + │ Expected ';' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.move index c14d9e1d4ad45..bd97ff9b5f421 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_lhs_mdot_no_addr.move @@ -1,12 +1,12 @@ module 0x42::M { fun foo() { - let f = 0; + let _f = 0; false::M { f } = 0; - let f = 0; + let _f = 0; 0::M { f } = 0; - let f = 0; + let _f = 0; foo().M { f } = 0; } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.exp index e2308b941d716..84e464e2f8437 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.exp @@ -1,10 +1,22 @@ -warning[W09001]: unused alias - ┌─ tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.move:6:14 +error[E03003]: unbound module member + ┌─ tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.move:9:9 │ -6 │ use 0x2::X; - │ ^ Unused 'use' of alias 'X'. Consider removing it +9 │ X::S () = 0; + │ ^^^^ Invalid module access. Unbound struct 'S' in module '0x2::X' + +error[E13001]: feature is not supported in specified edition + ┌─ tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.move:9:9 + │ +9 │ X::S () = 0; + │ ^^^^^^^ Positional fields are not supported by current edition 'legacy', only '2024.alpha' and '2024.beta' support this feature │ - = This warning can be suppressed with '#[allow(unused_use)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + = You can update the edition in the 'Move.toml', or via command line flag if invoking the compiler directly. + +error[E03003]: unbound module member + ┌─ tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.move:11:9 + │ +11 │ X::S 0 = 0; + │ ^^^^ Invalid module access. Unbound constant 'S' in module '0x2::X' error[E01002]: unexpected token ┌─ tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.move:11:14 @@ -15,3 +27,15 @@ error[E01002]: unexpected token │ Unexpected '0' │ Expected ';' +error[E03003]: unbound module member + ┌─ tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.move:13:9 + │ +13 │ X::S { 0 } = 0; + │ ^^^^ Invalid module access. Unbound struct 'S' in module '0x2::X' + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/invalid_unpack_assign_rhs_not_fields.move:13:16 + │ +13 │ X::S { 0 } = 0; + │ ^ Expected a field expression + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/less_than_space.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/less_than_space.exp index 6c5ab1beb867d..524f093c372b5 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/less_than_space.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/less_than_space.exp @@ -2,7 +2,22 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/less_than_space.move:5:16 │ 5 │ if (v< 10) return v; - │ - ^^ Expected '::' after the anonymous address in this module access chain - │ │ - │ Perhaps you need a blank space before this '<' operator? + │ ^^ Expected '::' after the anonymous address in this module access chain + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/less_than_space.move:5:28 + │ +5 │ if (v< 10) return v; + │ - ^ Expected '>' + │ │ + │ To match this '<' + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/less_than_space.move:5:28 + │ +5 │ if (v< 10) return v; + │ ^ + │ │ + │ Unexpected ';' + │ Expected ')' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_fields.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_fields.exp index e3e56c91561b3..6607552c3cce0 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_fields.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_fields.exp @@ -1,3 +1,9 @@ +error[E04016]: too few arguments + ┌─ tests/move_check/parser/let_binding_missing_fields.move:6:13 + │ +6 │ let Generic = g; // Test a type name with no field bindings + │ ^^^^^^^^^^^^ Missing binding for field 'g' in '0x42::M::Generic' + error[E01002]: unexpected token ┌─ tests/move_check/parser/let_binding_missing_fields.move:6:26 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_fields.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_fields.move index 63dee50a86262..296863ef62526 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_fields.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_fields.move @@ -1,5 +1,5 @@ module 0x42::M { - struct Generic { + struct Generic has drop { g: T } fun g(g: Generic) { diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_paren.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_paren.exp index 642075d24b477..d1c18c1d26b9b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_paren.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_paren.exp @@ -1,8 +1,17 @@ error[E01002]: unexpected token - ┌─ tests/move_check/parser/let_binding_missing_paren.move:3:21 + ┌─ tests/move_check/parser/let_binding_missing_paren.move:3:23 │ -3 │ let (x1, x2 = (1, 2); // Test a missing right parenthesis - │ - ^ Expected ')' - │ │ +3 │ let (_x1, _x2 = (1, 2); // Test a missing right parenthesis + │ ^ + │ │ + │ Unexpected '=' + │ Expected ',' or ')' + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/let_binding_missing_paren.move:3:31 + │ +3 │ let (_x1, _x2 = (1, 2); // Test a missing right parenthesis + │ - ^ Expected ')' + │ │ │ To match this '(' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_paren.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_paren.move index 6b45cccc964fa..4b3fd6eba07c9 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_paren.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/let_binding_missing_paren.move @@ -1,5 +1,5 @@ module 0x42::M { fun f() { - let (x1, x2 = (1, 2); // Test a missing right parenthesis + let (_x1, _x2 = (1, 2); // Test a missing right parenthesis } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/missing_angle_brace_close.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/missing_angle_brace_close.exp index 1cbfa3ebe9f88..5feef5f969bd2 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/missing_angle_brace_close.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/missing_angle_brace_close.exp @@ -1,3 +1,17 @@ +warning[W09002]: unused variable + ┌─ tests/move_check/parser/missing_angle_brace_close.move:3:13 + │ +3 │ let x = t' │ │ │ To match this '<' - │ Perhaps you need a blank space before this '<' operator? diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid.exp index 0325355a0c018..5498f2024d28b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid.exp @@ -1,3 +1,9 @@ +error[E03009]: unbound variable + ┌─ tests/move_check/parser/named_blocks_invalid.move:4:9 + │ +4 │ name: { + │ ^^^^ Unbound variable 'name' + error[E01002]: unexpected token ┌─ tests/move_check/parser/named_blocks_invalid.move:4:13 │ diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid.move index 47542d464a64e..7b255497770f2 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid.move @@ -1,6 +1,6 @@ module 0x42::m { - fun t0(cond: bool): u64 { + fun t0(_cond: bool) { name: { if (cond) { return 'name 10 }; 20 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_2.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_2.move index eb68cf153ca11..23a4aa7aa8c58 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_2.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_2.move @@ -1,6 +1,6 @@ module 0x42::m { - fun t0(cond: bool): u64 { + fun t0(_cond: bool) { 'name { if (cond) { return 'name 10 }; 20 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_3.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_3.move index f1d37bdeb9424..e6130ec3e412d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_3.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/named_blocks_invalid_3.move @@ -1,19 +1,19 @@ module 0x42::m { - fun t0(cond: bool): u64 { + fun t0(_cond: bool) { 'name: { if (cond) { return 'name 10 }; 20 } } - fun t1(cond: bool): u64 { + fun t1(_cond: bool) { loop 'name: { if (cond) { break 'name 10 }; } } - fun t2(cond: bool): u64 { + fun t2(_cond: bool) { loop 'outer: { loop 'inner: { if (cond) { break 'outer 10 }; @@ -22,7 +22,7 @@ module 0x42::m { } } - fun t3(cond: bool) { + fun t3(_cond: bool) { while (cond) 'outer: { while (cond) 'inner: { if (cond) { break 'outer }; @@ -31,7 +31,7 @@ module 0x42::m { } } - fun t4(cond: bool) { + fun t4(_cond: bool) { while (cond) 'outer: { let _x = 'inner: { if (cond) { break 'outer }; diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_invalid_keyword.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_invalid_keyword.exp index fb059a72c1127..47cd292affa23 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_invalid_keyword.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_invalid_keyword.exp @@ -1,8 +1,17 @@ +warning[W09006]: unused struct type parameter + ┌─ tests/move_check/parser/phantom_param_invalid_keyword.move:2:18 + │ +2 │ struct S { + │ ^^^^^^ Unused type parameter 'phatom'. Consider declaring it as phantom + │ + = This warning can be suppressed with '#[allow(unused_type_parameter)]' applied to the 'module' or module member ('const', 'fun', or 'struct') + error[E01002]: unexpected token ┌─ tests/move_check/parser/phantom_param_invalid_keyword.move:2:25 │ 2 │ struct S { - │ - ^ Expected '>' - │ │ - │ To match this '<' + │ ^^ + │ │ + │ Unexpected 'T2' + │ Expected ',' or '>' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_missing_type_var.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_missing_type_var.exp index 24719de8bcd91..ab8cb2f0e6d34 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_missing_type_var.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_missing_type_var.exp @@ -1,9 +1,9 @@ error[E01002]: unexpected token - ┌─ tests/move_check/parser/phantom_param_missing_type_var.move:2:25 + ┌─ tests/move_check/parser/phantom_param_missing_type_var.move:2:33 │ -2 │ struct S { - │ ^ - │ │ - │ Unexpected '>' - │ Expected an identifier +2 │ struct S { + │ ^ + │ │ + │ Unexpected '>' + │ Expected an identifier diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_missing_type_var.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_missing_type_var.move index 7b608bde71175..d7a905180d021 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_missing_type_var.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/phantom_param_missing_type_var.move @@ -1,5 +1,5 @@ module 0x42::M { - struct S { + struct S { f1: u64 } } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_fields_keyword_field.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_fields_keyword_field.exp index 7a6b91b2ef696..67ee81c08f3fd 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_fields_keyword_field.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/positional_struct_fields_keyword_field.exp @@ -26,10 +26,7 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/positional_struct_fields_keyword_field.move:4:23 │ 4 │ public struct Foo(fun) - │ ^^^ - │ │ - │ Unexpected 'fun' - │ Expected a type name + │ ^ Expected a type error[E01002]: unexpected token ┌─ tests/move_check/parser/positional_struct_fields_keyword_field.move:4:26 diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/recovery_parse_member_no_token.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/recovery_parse_member_no_token.move index a8e8807d554e7..c2b2868637284 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/recovery_parse_member_no_token.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/recovery_parse_member_no_token.move @@ -1,7 +1,7 @@ // there is a parsing error and the following program text does not contain a token (due to missing // quote) but the following function should still parse (fail during typing) module 0x42::M { - public fun missing_quote(): vector { + public fun missing_quote() { x"abcd } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_old_fun_fail.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_old_fun_fail.exp index 3c40dfd5b6b04..84f0970b2b51b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_old_fun_fail.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_old_fun_fail.exp @@ -7,12 +7,12 @@ error[E01002]: unexpected token │ Unexpected 'fun' │ Expected only 'spec', drop the 'fun' keyword -error[E01002]: unexpected token - ┌─ tests/move_check/parser/spec_parsing_old_fun_fail.move:5:29 - │ -5 │ spec fun with_aborts_if { - │ ^ - │ │ - │ Unexpected '{' - │ Expected '(' +warning[W00001]: DEPRECATED. will be removed + ┌─ tests/move_check/parser/spec_parsing_old_fun_fail.move:5:10 + │ +5 │ spec fun with_aborts_if { + │ ╭──────────^ +6 │ │ aborts_if x == 0; +7 │ │ } + │ ╰─────^ Specification blocks are deprecated and are no longer used diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_old_fun_fail.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_old_fun_fail.move index 8622c620f791b..9afe8c97c1ead 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_old_fun_fail.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/spec_parsing_old_fun_fail.move @@ -5,7 +5,7 @@ module 0x8675309::M { spec fun with_aborts_if { aborts_if x == 0; } - fun with_aborts_if(x: u64): u64 { + fun with_aborts(x: u64): u64 { x } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_native_missing_semicolon.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_native_missing_semicolon.exp index 1330d54a86651..0d81766b4838f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_native_missing_semicolon.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_native_missing_semicolon.exp @@ -2,8 +2,14 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/struct_native_missing_semicolon.move:3:1 │ 3 │ } + │ ^ Unexpected '}'. Expected struct fields, 'has' to start abilities declaration, or ';' for a native struct + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/struct_native_missing_semicolon.move:4:1 + │ +4 │ │ ^ - │ │ - │ Unexpected '}' - │ Expected ';' + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_native_with_fields.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_native_with_fields.exp index af199ee8e65f2..1691e149ce6cf 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_native_with_fields.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_native_with_fields.exp @@ -7,3 +7,12 @@ error[E01002]: unexpected token │ Unexpected '{' │ Expected ';' +error[E01002]: unexpected token + ┌─ tests/move_check/parser/struct_native_with_fields.move:5:1 + │ +5 │ + │ ^ + │ + │ Unexpected end-of-file + │ Expected a module member: 'spec', 'use', 'friend', 'const', 'fun', or 'struct' + diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.exp index 61702f1202c66..33597ab4dda3e 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.exp @@ -1,6 +1,6 @@ error[E01002]: unexpected token ┌─ tests/move_check/parser/struct_type_extra_comma.move:2:14 │ -2 │ struct S<,T> { } // Test a comma before the first type parameter +2 │ struct S<,T> { f: T } // Test a comma before the first type parameter │ ^ Expected a type parameter diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.move index 6dac114b5a2a8..91bf592554a14 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_extra_comma.move @@ -1,3 +1,3 @@ module 0x42::M { - struct S<,T> { } // Test a comma before the first type parameter + struct S<,T> { f: T } // Test a comma before the first type parameter } diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_missing_angle.exp b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_missing_angle.exp index 820d61672bc46..c12379804e1c6 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_missing_angle.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_missing_angle.exp @@ -1,8 +1,8 @@ error[E01002]: unexpected token - ┌─ tests/move_check/parser/struct_type_missing_angle.move:3:21 + ┌─ tests/move_check/parser/struct_type_missing_angle.move:3:37 │ -3 │ struct S' - │ │ +3 │ struct S' + │ │ │ To match this '<' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_missing_angle.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_missing_angle.move index 142dda22a10c7..63e7ee001a39d 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_missing_angle.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/struct_type_missing_angle.move @@ -1,4 +1,4 @@ module 0x42::M { // Test a missing ">" after the type parameters. - struct S' - │ │ - │ To match this '<' - │ Perhaps you need a blank space before this '<' operator? +4 │ let _v = vector' + │ │ + │ To match this '<' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/parser/vector_literal_unclosed_type_args.move b/external-crates/move/crates/move-compiler/tests/move_check/parser/vector_literal_unclosed_type_args.move index 0d9abe4500f65..84556920fa56b 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/parser/vector_literal_unclosed_type_args.move +++ b/external-crates/move/crates/move-compiler/tests/move_check/parser/vector_literal_unclosed_type_args.move @@ -1,6 +1,6 @@ module 0x42::Test { fun t() { // test missing > - let v = vector' + │ │ + │ To match this '<' + +error[E01002]: unexpected token + ┌─ tests/move_check/parser/vector_space_after_less.move:4:29 + │ +4 │ let a = vector < 100; + │ ^ + │ │ + │ Unexpected ';' + │ Expected '[' diff --git a/external-crates/move/crates/move-compiler/tests/move_check/typing/type_variable_join_single_pack.exp b/external-crates/move/crates/move-compiler/tests/move_check/typing/type_variable_join_single_pack.exp index c38f8adae5f26..f2a43e550371f 100644 --- a/external-crates/move/crates/move-compiler/tests/move_check/typing/type_variable_join_single_pack.exp +++ b/external-crates/move/crates/move-compiler/tests/move_check/typing/type_variable_join_single_pack.exp @@ -2,32 +2,52 @@ error[E01002]: unexpected token ┌─ tests/move_check/typing/type_variable_join_single_pack.move:2:19 │ 2 │ struct Box copy, drop { f1: T, f2: T } - │ ^^^^ - │ │ - │ Unexpected 'copy' - │ Expected '{' + │ ^^^^ Unexpected 'copy'. Expected struct fields, 'has' to start abilities declaration, or ';' for a native struct -error[E03004]: unbound type - ┌─ tests/move_check/typing/type_variable_join_single_pack.move:5:17 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_check/typing/type_variable_join_single_pack.move:6:9 │ -5 │ let b = Box { f1: 0, f2: 1 }; - │ ^^^ Unbound type 'Box' in current scope +2 │ struct Box copy, drop { f1: T, f2: T } + │ --- To satisfy the constraint, the 'drop' ability would need to be added here + · +6 │ (*&b: Box); + │ ^^^^^^^^^^^^^^^ + │ │ │ + │ │ The type '0x42::M::Box' does not have the ability 'drop' + │ Cannot ignore values without the 'drop' ability. The value must be used -error[E03004]: unbound type - ┌─ tests/move_check/typing/type_variable_join_single_pack.move:6:15 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_check/typing/type_variable_join_single_pack.move:6:10 │ +2 │ struct Box copy, drop { f1: T, f2: T } + │ --- To satisfy the constraint, the 'copy' ability would need to be added here + · +5 │ let b = Box { f1: 0, f2: 1 }; + │ -------------------- The type '0x42::M::Box' does not have the ability 'copy' 6 │ (*&b: Box); - │ ^^^ Unbound type 'Box' in current scope + │ ^^^ Invalid dereference. Dereference requires the 'copy' ability -error[E03004]: unbound type - ┌─ tests/move_check/typing/type_variable_join_single_pack.move:7:18 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_check/typing/type_variable_join_single_pack.move:7:28 │ +2 │ struct Box copy, drop { f1: T, f2: T } + │ --- To satisfy the constraint, the 'copy' ability would need to be added here + · +5 │ let b = Box { f1: 0, f2: 1 }; + │ -------------------- The type '0x42::M::Box' does not have the ability 'copy' +6 │ (*&b: Box); 7 │ let b2 = Box { f1: *&b, f2: b }; - │ ^^^ Unbound type 'Box' in current scope + │ ^^^ Invalid dereference. Dereference requires the 'copy' ability -error[E03004]: unbound type - ┌─ tests/move_check/typing/type_variable_join_single_pack.move:8:14 +error[E05001]: ability constraint not satisfied + ┌─ tests/move_check/typing/type_variable_join_single_pack.move:8:9 │ +2 │ struct Box copy, drop { f1: T, f2: T } + │ --- To satisfy the constraint, the 'drop' ability would need to be added here + · 8 │ (b2: Box>); - │ ^^^ Unbound type 'Box' in current scope + │ ^^^^^^^^^^^^^^^^^^^ + │ │ │ + │ │ The type '0x42::M::Box<0x42::M::Box>' does not have the ability 'drop' + │ Cannot ignore values without the 'drop' ability. The value must be used