mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
feat: Implement default-field-values
only in parser
This commit is contained in:
parent
be3307450f
commit
461ee092bf
@ -678,6 +678,8 @@ fn path_expr(p: &mut Parser<'_>, r: Restrictions) -> (CompletedMarker, BlockLike
|
||||
// S { x };
|
||||
// S { x, y: 32, };
|
||||
// S { x, y: 32, ..Default::default() };
|
||||
// S { x, y: 32, .. };
|
||||
// S { .. };
|
||||
// S { x: ::default() };
|
||||
// TupleStruct { 0: 1 };
|
||||
// }
|
||||
@ -709,6 +711,8 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
|
||||
// fn main() {
|
||||
// S { field ..S::default() }
|
||||
// S { 0 ..S::default() }
|
||||
// S { field .. }
|
||||
// S { 0 .. }
|
||||
// }
|
||||
name_ref_or_index(p);
|
||||
p.error("expected `:`");
|
||||
@ -739,7 +743,13 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
|
||||
// S { .. } = S {};
|
||||
// }
|
||||
|
||||
// We permit `.. }` on the left-hand side of a destructuring assignment.
|
||||
// test struct_initializer_with_defaults
|
||||
// fn foo() {
|
||||
// let _s = S { .. };
|
||||
// }
|
||||
|
||||
// We permit `.. }` on the left-hand side of a destructuring assignment
|
||||
// or defaults values.
|
||||
if !p.at(T!['}']) {
|
||||
expr(p);
|
||||
|
||||
@ -750,6 +760,12 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
|
||||
// S { ..x, a: 0 }
|
||||
// }
|
||||
|
||||
// test_err comma_after_default_values_syntax
|
||||
// fn foo() {
|
||||
// S { .., };
|
||||
// S { .., a: 0 }
|
||||
// }
|
||||
|
||||
// Do not bump, so we can support additional fields after this comma.
|
||||
p.error("cannot use a comma after the base struct");
|
||||
}
|
||||
|
@ -135,6 +135,11 @@ pub(crate) fn record_field_list(p: &mut Parser<'_>) {
|
||||
name(p);
|
||||
p.expect(T![:]);
|
||||
types::type_(p);
|
||||
// test record_field_default_values
|
||||
// struct S { f: f32 = 0.0 }
|
||||
if p.eat(T![=]) {
|
||||
expressions::expr(p);
|
||||
}
|
||||
m.complete(p, RECORD_FIELD);
|
||||
} else {
|
||||
m.abandon(p);
|
||||
|
@ -482,6 +482,10 @@ mod ok {
|
||||
run_and_expect_no_errors("test_data/parser/inline/ok/record_field_attrs.rs");
|
||||
}
|
||||
#[test]
|
||||
fn record_field_default_values() {
|
||||
run_and_expect_no_errors("test_data/parser/inline/ok/record_field_default_values.rs");
|
||||
}
|
||||
#[test]
|
||||
fn record_field_list() {
|
||||
run_and_expect_no_errors("test_data/parser/inline/ok/record_field_list.rs");
|
||||
}
|
||||
@ -544,6 +548,10 @@ mod ok {
|
||||
run_and_expect_no_errors("test_data/parser/inline/ok/stmt_postfix_expr_ambiguity.rs");
|
||||
}
|
||||
#[test]
|
||||
fn struct_initializer_with_defaults() {
|
||||
run_and_expect_no_errors("test_data/parser/inline/ok/struct_initializer_with_defaults.rs");
|
||||
}
|
||||
#[test]
|
||||
fn struct_item() { run_and_expect_no_errors("test_data/parser/inline/ok/struct_item.rs"); }
|
||||
#[test]
|
||||
fn trait_alias() { run_and_expect_no_errors("test_data/parser/inline/ok/trait_alias.rs"); }
|
||||
@ -719,6 +727,10 @@ mod err {
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn comma_after_default_values_syntax() {
|
||||
run_and_expect_errors("test_data/parser/inline/err/comma_after_default_values_syntax.rs");
|
||||
}
|
||||
#[test]
|
||||
fn crate_visibility_empty_recover() {
|
||||
run_and_expect_errors("test_data/parser/inline/err/crate_visibility_empty_recover.rs");
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
SOURCE_FILE
|
||||
FN
|
||||
FN_KW "fn"
|
||||
WHITESPACE " "
|
||||
NAME
|
||||
IDENT "foo"
|
||||
PARAM_LIST
|
||||
L_PAREN "("
|
||||
R_PAREN ")"
|
||||
WHITESPACE " "
|
||||
BLOCK_EXPR
|
||||
STMT_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE "\n "
|
||||
EXPR_STMT
|
||||
RECORD_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE " "
|
||||
DOT2 ".."
|
||||
ERROR
|
||||
COMMA ","
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
SEMICOLON ";"
|
||||
WHITESPACE "\n "
|
||||
RECORD_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE " "
|
||||
DOT2 ".."
|
||||
ERROR
|
||||
COMMA ","
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD
|
||||
NAME_REF
|
||||
IDENT "a"
|
||||
COLON ":"
|
||||
WHITESPACE " "
|
||||
LITERAL
|
||||
INT_NUMBER "0"
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n"
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n"
|
||||
error 21: expected expression
|
||||
error 36: expected expression
|
||||
error 37: expected COMMA
|
@ -0,0 +1,4 @@
|
||||
fn foo() {
|
||||
S { .., };
|
||||
S { .., a: 0 }
|
||||
}
|
@ -44,6 +44,56 @@ SOURCE_FILE
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n "
|
||||
EXPR_STMT
|
||||
RECORD_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD
|
||||
NAME_REF
|
||||
INT_NUMBER "0"
|
||||
WHITESPACE " "
|
||||
DOT2 ".."
|
||||
CALL_EXPR
|
||||
PATH_EXPR
|
||||
PATH
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
COLON2 "::"
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "default"
|
||||
ARG_LIST
|
||||
L_PAREN "("
|
||||
R_PAREN ")"
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n "
|
||||
EXPR_STMT
|
||||
RECORD_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD
|
||||
NAME_REF
|
||||
IDENT "field"
|
||||
WHITESPACE " "
|
||||
DOT2 ".."
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n "
|
||||
RECORD_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
@ -58,20 +108,6 @@ SOURCE_FILE
|
||||
INT_NUMBER "0"
|
||||
WHITESPACE " "
|
||||
DOT2 ".."
|
||||
CALL_EXPR
|
||||
PATH_EXPR
|
||||
PATH
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
COLON2 "::"
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "default"
|
||||
ARG_LIST
|
||||
L_PAREN "("
|
||||
R_PAREN ")"
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n"
|
||||
@ -82,3 +118,9 @@ error 25: expected COMMA
|
||||
error 42: expected SEMICOLON
|
||||
error 52: expected `:`
|
||||
error 52: expected COMMA
|
||||
error 69: expected SEMICOLON
|
||||
error 83: expected `:`
|
||||
error 83: expected COMMA
|
||||
error 88: expected SEMICOLON
|
||||
error 98: expected `:`
|
||||
error 98: expected COMMA
|
||||
|
@ -1,4 +1,6 @@
|
||||
fn main() {
|
||||
S { field ..S::default() }
|
||||
S { 0 ..S::default() }
|
||||
S { field .. }
|
||||
S { 0 .. }
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
SOURCE_FILE
|
||||
STRUCT
|
||||
STRUCT_KW "struct"
|
||||
WHITESPACE " "
|
||||
NAME
|
||||
IDENT "S"
|
||||
WHITESPACE " "
|
||||
RECORD_FIELD_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE " "
|
||||
RECORD_FIELD
|
||||
NAME
|
||||
IDENT "f"
|
||||
COLON ":"
|
||||
WHITESPACE " "
|
||||
PATH_TYPE
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "f32"
|
||||
WHITESPACE " "
|
||||
EQ "="
|
||||
WHITESPACE " "
|
||||
LITERAL
|
||||
FLOAT_NUMBER "0.0"
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n"
|
@ -0,0 +1 @@
|
||||
struct S { f: f32 = 0.0 }
|
@ -120,6 +120,53 @@ SOURCE_FILE
|
||||
R_CURLY "}"
|
||||
SEMICOLON ";"
|
||||
WHITESPACE "\n "
|
||||
EXPR_STMT
|
||||
RECORD_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD
|
||||
PATH_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "x"
|
||||
COMMA ","
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD
|
||||
NAME_REF
|
||||
IDENT "y"
|
||||
COLON ":"
|
||||
WHITESPACE " "
|
||||
LITERAL
|
||||
INT_NUMBER "32"
|
||||
COMMA ","
|
||||
WHITESPACE " "
|
||||
DOT2 ".."
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
SEMICOLON ";"
|
||||
WHITESPACE "\n "
|
||||
EXPR_STMT
|
||||
RECORD_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE " "
|
||||
DOT2 ".."
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
SEMICOLON ";"
|
||||
WHITESPACE "\n "
|
||||
EXPR_STMT
|
||||
RECORD_EXPR
|
||||
PATH
|
||||
|
@ -3,6 +3,8 @@ fn foo() {
|
||||
S { x };
|
||||
S { x, y: 32, };
|
||||
S { x, y: 32, ..Default::default() };
|
||||
S { x, y: 32, .. };
|
||||
S { .. };
|
||||
S { x: ::default() };
|
||||
TupleStruct { 0: 1 };
|
||||
}
|
||||
|
@ -0,0 +1,39 @@
|
||||
SOURCE_FILE
|
||||
FN
|
||||
FN_KW "fn"
|
||||
WHITESPACE " "
|
||||
NAME
|
||||
IDENT "foo"
|
||||
PARAM_LIST
|
||||
L_PAREN "("
|
||||
R_PAREN ")"
|
||||
WHITESPACE " "
|
||||
BLOCK_EXPR
|
||||
STMT_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE "\n "
|
||||
LET_STMT
|
||||
LET_KW "let"
|
||||
WHITESPACE " "
|
||||
IDENT_PAT
|
||||
NAME
|
||||
IDENT "_s"
|
||||
WHITESPACE " "
|
||||
EQ "="
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "S"
|
||||
WHITESPACE " "
|
||||
RECORD_EXPR_FIELD_LIST
|
||||
L_CURLY "{"
|
||||
WHITESPACE " "
|
||||
DOT2 ".."
|
||||
WHITESPACE " "
|
||||
R_CURLY "}"
|
||||
SEMICOLON ";"
|
||||
WHITESPACE "\n"
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n"
|
@ -0,0 +1,3 @@
|
||||
fn foo() {
|
||||
let _s = S { .. };
|
||||
}
|
@ -241,7 +241,7 @@ RecordFieldList =
|
||||
|
||||
RecordField =
|
||||
Attr* Visibility?
|
||||
Name ':' Type
|
||||
Name ':' Type ('=' Expr)?
|
||||
|
||||
TupleFieldList =
|
||||
'(' fields:(TupleField (',' TupleField)* ','?)? ')'
|
||||
|
@ -1538,10 +1538,14 @@ impl ast::HasDocComments for RecordField {}
|
||||
impl ast::HasName for RecordField {}
|
||||
impl ast::HasVisibility for RecordField {}
|
||||
impl RecordField {
|
||||
#[inline]
|
||||
pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
|
||||
#[inline]
|
||||
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
||||
#[inline]
|
||||
pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
|
||||
#[inline]
|
||||
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user