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 };
|
||||||
// S { x, y: 32, };
|
// S { x, y: 32, };
|
||||||
// S { x, y: 32, ..Default::default() };
|
// S { x, y: 32, ..Default::default() };
|
||||||
|
// S { x, y: 32, .. };
|
||||||
|
// S { .. };
|
||||||
// S { x: ::default() };
|
// S { x: ::default() };
|
||||||
// TupleStruct { 0: 1 };
|
// TupleStruct { 0: 1 };
|
||||||
// }
|
// }
|
||||||
@ -709,6 +711,8 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
|
|||||||
// fn main() {
|
// fn main() {
|
||||||
// S { field ..S::default() }
|
// S { field ..S::default() }
|
||||||
// S { 0 ..S::default() }
|
// S { 0 ..S::default() }
|
||||||
|
// S { field .. }
|
||||||
|
// S { 0 .. }
|
||||||
// }
|
// }
|
||||||
name_ref_or_index(p);
|
name_ref_or_index(p);
|
||||||
p.error("expected `:`");
|
p.error("expected `:`");
|
||||||
@ -739,7 +743,13 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
|
|||||||
// S { .. } = S {};
|
// 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!['}']) {
|
if !p.at(T!['}']) {
|
||||||
expr(p);
|
expr(p);
|
||||||
|
|
||||||
@ -750,6 +760,12 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
|
|||||||
// S { ..x, a: 0 }
|
// 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.
|
// Do not bump, so we can support additional fields after this comma.
|
||||||
p.error("cannot use a comma after the base struct");
|
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);
|
name(p);
|
||||||
p.expect(T![:]);
|
p.expect(T![:]);
|
||||||
types::type_(p);
|
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);
|
m.complete(p, RECORD_FIELD);
|
||||||
} else {
|
} else {
|
||||||
m.abandon(p);
|
m.abandon(p);
|
||||||
|
@ -482,6 +482,10 @@ mod ok {
|
|||||||
run_and_expect_no_errors("test_data/parser/inline/ok/record_field_attrs.rs");
|
run_and_expect_no_errors("test_data/parser/inline/ok/record_field_attrs.rs");
|
||||||
}
|
}
|
||||||
#[test]
|
#[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() {
|
fn record_field_list() {
|
||||||
run_and_expect_no_errors("test_data/parser/inline/ok/record_field_list.rs");
|
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");
|
run_and_expect_no_errors("test_data/parser/inline/ok/stmt_postfix_expr_ambiguity.rs");
|
||||||
}
|
}
|
||||||
#[test]
|
#[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"); }
|
fn struct_item() { run_and_expect_no_errors("test_data/parser/inline/ok/struct_item.rs"); }
|
||||||
#[test]
|
#[test]
|
||||||
fn trait_alias() { run_and_expect_no_errors("test_data/parser/inline/ok/trait_alias.rs"); }
|
fn trait_alias() { run_and_expect_no_errors("test_data/parser/inline/ok/trait_alias.rs"); }
|
||||||
@ -719,6 +727,10 @@ mod err {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
#[test]
|
#[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() {
|
fn crate_visibility_empty_recover() {
|
||||||
run_and_expect_errors("test_data/parser/inline/err/crate_visibility_empty_recover.rs");
|
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 " "
|
WHITESPACE " "
|
||||||
R_CURLY "}"
|
R_CURLY "}"
|
||||||
WHITESPACE "\n "
|
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
|
RECORD_EXPR
|
||||||
PATH
|
PATH
|
||||||
PATH_SEGMENT
|
PATH_SEGMENT
|
||||||
@ -58,20 +108,6 @@ SOURCE_FILE
|
|||||||
INT_NUMBER "0"
|
INT_NUMBER "0"
|
||||||
WHITESPACE " "
|
WHITESPACE " "
|
||||||
DOT2 ".."
|
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 " "
|
WHITESPACE " "
|
||||||
R_CURLY "}"
|
R_CURLY "}"
|
||||||
WHITESPACE "\n"
|
WHITESPACE "\n"
|
||||||
@ -82,3 +118,9 @@ error 25: expected COMMA
|
|||||||
error 42: expected SEMICOLON
|
error 42: expected SEMICOLON
|
||||||
error 52: expected `:`
|
error 52: expected `:`
|
||||||
error 52: expected COMMA
|
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() {
|
fn main() {
|
||||||
S { field ..S::default() }
|
S { field ..S::default() }
|
||||||
S { 0 ..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 "}"
|
R_CURLY "}"
|
||||||
SEMICOLON ";"
|
SEMICOLON ";"
|
||||||
WHITESPACE "\n "
|
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
|
EXPR_STMT
|
||||||
RECORD_EXPR
|
RECORD_EXPR
|
||||||
PATH
|
PATH
|
||||||
|
@ -3,6 +3,8 @@ fn foo() {
|
|||||||
S { x };
|
S { x };
|
||||||
S { x, y: 32, };
|
S { x, y: 32, };
|
||||||
S { x, y: 32, ..Default::default() };
|
S { x, y: 32, ..Default::default() };
|
||||||
|
S { x, y: 32, .. };
|
||||||
|
S { .. };
|
||||||
S { x: ::default() };
|
S { x: ::default() };
|
||||||
TupleStruct { 0: 1 };
|
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 =
|
RecordField =
|
||||||
Attr* Visibility?
|
Attr* Visibility?
|
||||||
Name ':' Type
|
Name ':' Type ('=' Expr)?
|
||||||
|
|
||||||
TupleFieldList =
|
TupleFieldList =
|
||||||
'(' fields:(TupleField (',' TupleField)* ','?)? ')'
|
'(' fields:(TupleField (',' TupleField)* ','?)? ')'
|
||||||
|
@ -1538,10 +1538,14 @@ impl ast::HasDocComments for RecordField {}
|
|||||||
impl ast::HasName for RecordField {}
|
impl ast::HasName for RecordField {}
|
||||||
impl ast::HasVisibility for RecordField {}
|
impl ast::HasVisibility for RecordField {}
|
||||||
impl RecordField {
|
impl RecordField {
|
||||||
|
#[inline]
|
||||||
|
pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
|
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)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user