Recover from missing associated items and generic const defaults

This commit is contained in:
Ryo Yoshida 2023-07-04 20:34:55 +09:00
parent 45d4ebcf19
commit 49b039f1d1
No known key found for this signature in database
GPG Key ID: E25698A930586171
6 changed files with 113 additions and 3 deletions

View File

@ -32,6 +32,9 @@ const GENERIC_ARG_FIRST: TokenSet = TokenSet::new(&[
])
.union(types::TYPE_FIRST);
// Despite its name, it can also be used for generic param list.
const GENERIC_ARG_RECOVERY_SET: TokenSet = TokenSet::new(&[T![>], T![,]]);
// test generic_arg
// type T = S<i32>;
fn generic_arg(p: &mut Parser<'_>) -> bool {
@ -55,6 +58,15 @@ fn generic_arg(p: &mut Parser<'_>) -> bool {
// test assoc_type_eq
// type T = StreamingIterator<Item<'a> = &'a T>;
types::type_(p);
} else if p.at_ts(GENERIC_ARG_RECOVERY_SET) {
// Although `const_arg()` recovers as expected, we want to
// handle those here to give the following message because
// we don't know whether this associated item is a type or
// const at this point.
// test_err recover_from_missing_assoc_item_binding
// fn f() -> impl Iterator<Item = , Item = > {}
p.error("missing associated item binding");
} else {
// test assoc_const_eq
// fn foo<F: Foo<N=3>>() {}
@ -141,12 +153,17 @@ pub(super) fn const_arg_expr(p: &mut Parser<'_>) {
expressions::literal(p);
lm.complete(p, PREFIX_EXPR);
}
_ => {
_ if paths::is_use_path_start(p) => {
// This shouldn't be hit by `const_arg`
let lm = p.start();
paths::use_path(p);
lm.complete(p, PATH_EXPR);
}
_ => {
// test_err recover_from_missing_const_default
// struct A<const N: i32 = , const M: i32 =>;
p.err_recover("expected a generic const argument", GENERIC_ARG_RECOVERY_SET);
}
}
}

View File

@ -79,10 +79,9 @@ fn const_param(p: &mut Parser<'_>, m: Marker) {
p.error("missing type for const parameter");
}
if p.at(T![=]) {
if p.eat(T![=]) {
// test const_param_default_literal
// struct A<const N: i32 = -1>;
p.bump(T![=]);
// test const_param_default_expression
// struct A<const N: i32 = { 1 }>;

View File

@ -0,0 +1,48 @@
SOURCE_FILE
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "f"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
RET_TYPE
THIN_ARROW "->"
WHITESPACE " "
IMPL_TRAIT_TYPE
IMPL_KW "impl"
WHITESPACE " "
TYPE_BOUND_LIST
TYPE_BOUND
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "Iterator"
GENERIC_ARG_LIST
L_ANGLE "<"
ASSOC_TYPE_ARG
NAME_REF
IDENT "Item"
WHITESPACE " "
EQ "="
WHITESPACE " "
COMMA ","
WHITESPACE " "
ASSOC_TYPE_ARG
NAME_REF
IDENT "Item"
WHITESPACE " "
EQ "="
WHITESPACE " "
R_ANGLE ">"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
R_CURLY "}"
WHITESPACE "\n"
error 30: missing associated item binding
error 39: missing associated item binding

View File

@ -0,0 +1 @@
fn f() -> impl Iterator<Item = , Item = > {}

View File

@ -0,0 +1,44 @@
SOURCE_FILE
STRUCT
STRUCT_KW "struct"
WHITESPACE " "
NAME
IDENT "A"
GENERIC_PARAM_LIST
L_ANGLE "<"
CONST_PARAM
CONST_KW "const"
WHITESPACE " "
NAME
IDENT "N"
COLON ":"
WHITESPACE " "
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "i32"
WHITESPACE " "
EQ "="
WHITESPACE " "
COMMA ","
WHITESPACE " "
CONST_PARAM
CONST_KW "const"
WHITESPACE " "
NAME
IDENT "M"
COLON ":"
WHITESPACE " "
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "i32"
WHITESPACE " "
EQ "="
R_ANGLE ">"
SEMICOLON ";"
WHITESPACE "\n"
error 23: expected a generic const argument
error 40: expected a generic const argument

View File

@ -0,0 +1 @@
struct A<const N: i32 = , const M: i32 =>;