mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-04 13:38:31 +00:00 
			
		
		
		
	Merge pull request #19723 from Veykril/push-skswknpxtzlz
fix: Improve parser recovery a bit
This commit is contained in:
		
						commit
						5d66d45005
					
				
					 15 changed files with 86 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -285,8 +285,6 @@ fn main() {
 | 
			
		|||
    /* parse error: expected expression */
 | 
			
		||||
builtin #format_args (x = );
 | 
			
		||||
    /* parse error: expected expression */
 | 
			
		||||
/* parse error: expected R_PAREN */
 | 
			
		||||
/* parse error: expected expression, item or let statement */
 | 
			
		||||
builtin #format_args (x = , x = 2);
 | 
			
		||||
    /* parse error: expected expression */
 | 
			
		||||
builtin #format_args ("{}", x = );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -661,9 +661,8 @@ fn expected_type_and_name(
 | 
			
		|||
                            ))
 | 
			
		||||
                        } else {
 | 
			
		||||
                            cov_mark::hit!(expected_type_struct_field_without_leading_char);
 | 
			
		||||
                            let expr_field = token.prev_sibling_or_token()?
 | 
			
		||||
                                .into_node()
 | 
			
		||||
                                .and_then(ast::RecordExprField::cast)?;
 | 
			
		||||
                            cov_mark::hit!(expected_type_struct_field_followed_by_comma);
 | 
			
		||||
                            let expr_field = previous_non_trivia_token(token.clone())?.parent().and_then(ast::RecordExprField::cast)?;
 | 
			
		||||
                            let (_, _, ty) = sema.resolve_record_field(&expr_field)?;
 | 
			
		||||
                            Some((
 | 
			
		||||
                                Some(ty),
 | 
			
		||||
| 
						 | 
				
			
			@ -681,7 +680,6 @@ fn expected_type_and_name(
 | 
			
		|||
                            .or_else(|| sema.type_of_expr(&expr).map(TypeInfo::original));
 | 
			
		||||
                        (ty, field_name)
 | 
			
		||||
                    } else {
 | 
			
		||||
                        cov_mark::hit!(expected_type_struct_field_followed_by_comma);
 | 
			
		||||
                        (field_ty, field_name)
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ use crate::grammar::attributes::ATTRIBUTE_FIRST;
 | 
			
		|||
 | 
			
		||||
use super::*;
 | 
			
		||||
 | 
			
		||||
pub(super) use atom::{LITERAL_FIRST, literal};
 | 
			
		||||
pub(super) use atom::{EXPR_RECOVERY_SET, LITERAL_FIRST, literal};
 | 
			
		||||
pub(crate) use atom::{block_expr, match_arm_list};
 | 
			
		||||
 | 
			
		||||
#[derive(PartialEq, Eq)]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,6 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
 | 
			
		|||
        T!['['],
 | 
			
		||||
        T![|],
 | 
			
		||||
        T![async],
 | 
			
		||||
        T![box],
 | 
			
		||||
        T![break],
 | 
			
		||||
        T![const],
 | 
			
		||||
        T![continue],
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +67,8 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
 | 
			
		|||
        LIFETIME_IDENT,
 | 
			
		||||
    ]));
 | 
			
		||||
 | 
			
		||||
pub(super) const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[T![')'], T![']']]);
 | 
			
		||||
pub(in crate::grammar) const EXPR_RECOVERY_SET: TokenSet =
 | 
			
		||||
    TokenSet::new(&[T!['}'], T![')'], T![']'], T![,]]);
 | 
			
		||||
 | 
			
		||||
pub(super) fn atom_expr(
 | 
			
		||||
    p: &mut Parser<'_>,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,9 @@ pub(super) const ITEM_RECOVERY_SET: TokenSet = TokenSet::new(&[
 | 
			
		|||
    T![impl],
 | 
			
		||||
    T![trait],
 | 
			
		||||
    T![const],
 | 
			
		||||
    T![async],
 | 
			
		||||
    T![unsafe],
 | 
			
		||||
    T![extern],
 | 
			
		||||
    T![static],
 | 
			
		||||
    T![let],
 | 
			
		||||
    T![mod],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ fn path_for_qualifier(
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
const EXPR_PATH_SEGMENT_RECOVERY_SET: TokenSet =
 | 
			
		||||
    items::ITEM_RECOVERY_SET.union(TokenSet::new(&[T![')'], T![,], T![let]]));
 | 
			
		||||
    expressions::EXPR_RECOVERY_SET.union(items::ITEM_RECOVERY_SET);
 | 
			
		||||
const TYPE_PATH_SEGMENT_RECOVERY_SET: TokenSet = types::TYPE_RECOVERY_SET;
 | 
			
		||||
 | 
			
		||||
fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option<CompletedMarker> {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -199,8 +199,19 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const PAT_RECOVERY_SET: TokenSet =
 | 
			
		||||
    TokenSet::new(&[T![let], T![if], T![while], T![loop], T![match], T![')'], T![,], T![=]]);
 | 
			
		||||
const PAT_RECOVERY_SET: TokenSet = TokenSet::new(&[
 | 
			
		||||
    T![let],
 | 
			
		||||
    T![if],
 | 
			
		||||
    T![while],
 | 
			
		||||
    T![loop],
 | 
			
		||||
    T![match],
 | 
			
		||||
    T![')'],
 | 
			
		||||
    T![']'],
 | 
			
		||||
    T!['}'],
 | 
			
		||||
    T![,],
 | 
			
		||||
    T![=],
 | 
			
		||||
    T![&],
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
fn atom_pat(p: &mut Parser<'_>, recovery_set: TokenSet) -> Option<CompletedMarker> {
 | 
			
		||||
    let m = match p.current() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,10 +20,15 @@ pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(TokenSet::new(&[
 | 
			
		|||
 | 
			
		||||
pub(super) const TYPE_RECOVERY_SET: TokenSet = TokenSet::new(&[
 | 
			
		||||
    T![')'],
 | 
			
		||||
    // test_err type_in_array_recover
 | 
			
		||||
    // const _: [&];
 | 
			
		||||
    T![']'],
 | 
			
		||||
    T!['}'],
 | 
			
		||||
    T![>],
 | 
			
		||||
    T![,],
 | 
			
		||||
    // test_err struct_field_recover
 | 
			
		||||
    // struct S { f pub g: () }
 | 
			
		||||
    // struct S { f: pub g: () }
 | 
			
		||||
    T![pub],
 | 
			
		||||
]);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -870,6 +870,10 @@ mod err {
 | 
			
		|||
        run_and_expect_errors("test_data/parser/inline/err/tuple_pat_leading_comma.rs");
 | 
			
		||||
    }
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn type_in_array_recover() {
 | 
			
		||||
        run_and_expect_errors("test_data/parser/inline/err/type_in_array_recover.rs");
 | 
			
		||||
    }
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn unsafe_block_in_mod() {
 | 
			
		||||
        run_and_expect_errors("test_data/parser/inline/err/unsafe_block_in_mod.rs");
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,7 +149,8 @@ error 17: expected expression, item or let statement
 | 
			
		|||
error 25: expected a name
 | 
			
		||||
error 26: expected `;`, `{`, or `(`
 | 
			
		||||
error 30: expected pattern
 | 
			
		||||
error 31: expected SEMICOLON
 | 
			
		||||
error 30: expected SEMICOLON
 | 
			
		||||
error 30: expected expression, item or let statement
 | 
			
		||||
error 53: expected expression
 | 
			
		||||
error 54: expected R_PAREN
 | 
			
		||||
error 54: expected SEMICOLON
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,6 @@ SOURCE_FILE
 | 
			
		|||
              L_CURLY "{"
 | 
			
		||||
              WHITESPACE " "
 | 
			
		||||
              DOT2 ".."
 | 
			
		||||
              ERROR
 | 
			
		||||
              COMMA ","
 | 
			
		||||
              WHITESPACE " "
 | 
			
		||||
              R_CURLY "}"
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +38,6 @@ SOURCE_FILE
 | 
			
		|||
            L_CURLY "{"
 | 
			
		||||
            WHITESPACE " "
 | 
			
		||||
            DOT2 ".."
 | 
			
		||||
            ERROR
 | 
			
		||||
            COMMA ","
 | 
			
		||||
            WHITESPACE " "
 | 
			
		||||
            RECORD_EXPR_FIELD
 | 
			
		||||
| 
						 | 
				
			
			@ -55,5 +53,6 @@ SOURCE_FILE
 | 
			
		|||
        R_CURLY "}"
 | 
			
		||||
  WHITESPACE "\n"
 | 
			
		||||
error 21: expected expression
 | 
			
		||||
error 21: cannot use a comma after the base struct
 | 
			
		||||
error 36: expected expression
 | 
			
		||||
error 37: expected COMMA
 | 
			
		||||
error 36: cannot use a comma after the base struct
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,6 +26,36 @@ SOURCE_FILE
 | 
			
		|||
      WHITESPACE " "
 | 
			
		||||
      R_CURLY "}"
 | 
			
		||||
  WHITESPACE "\n"
 | 
			
		||||
  STRUCT
 | 
			
		||||
    STRUCT_KW "struct"
 | 
			
		||||
    WHITESPACE " "
 | 
			
		||||
    NAME
 | 
			
		||||
      IDENT "S"
 | 
			
		||||
    WHITESPACE " "
 | 
			
		||||
    RECORD_FIELD_LIST
 | 
			
		||||
      L_CURLY "{"
 | 
			
		||||
      WHITESPACE " "
 | 
			
		||||
      RECORD_FIELD
 | 
			
		||||
        NAME
 | 
			
		||||
          IDENT "f"
 | 
			
		||||
        COLON ":"
 | 
			
		||||
      WHITESPACE " "
 | 
			
		||||
      RECORD_FIELD
 | 
			
		||||
        VISIBILITY
 | 
			
		||||
          PUB_KW "pub"
 | 
			
		||||
        WHITESPACE " "
 | 
			
		||||
        NAME
 | 
			
		||||
          IDENT "g"
 | 
			
		||||
        COLON ":"
 | 
			
		||||
        WHITESPACE " "
 | 
			
		||||
        TUPLE_TYPE
 | 
			
		||||
          L_PAREN "("
 | 
			
		||||
          R_PAREN ")"
 | 
			
		||||
      WHITESPACE " "
 | 
			
		||||
      R_CURLY "}"
 | 
			
		||||
  WHITESPACE "\n"
 | 
			
		||||
error 12: expected COLON
 | 
			
		||||
error 12: expected type
 | 
			
		||||
error 12: expected COMMA
 | 
			
		||||
error 38: expected type
 | 
			
		||||
error 38: expected COMMA
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1,2 @@
 | 
			
		|||
struct S { f pub g: () }
 | 
			
		||||
struct S { f: pub g: () }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,15 @@
 | 
			
		|||
SOURCE_FILE
 | 
			
		||||
  CONST
 | 
			
		||||
    CONST_KW "const"
 | 
			
		||||
    WHITESPACE " "
 | 
			
		||||
    UNDERSCORE "_"
 | 
			
		||||
    COLON ":"
 | 
			
		||||
    WHITESPACE " "
 | 
			
		||||
    SLICE_TYPE
 | 
			
		||||
      L_BRACK "["
 | 
			
		||||
      REF_TYPE
 | 
			
		||||
        AMP "&"
 | 
			
		||||
      R_BRACK "]"
 | 
			
		||||
    SEMICOLON ";"
 | 
			
		||||
  WHITESPACE "\n"
 | 
			
		||||
error 11: expected type
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
const _: [&];
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue