From c3ac2c93fb446329b09882ef452fd6820290bfc5 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 12 Jan 2020 10:19:17 -0500 Subject: Allow attributes before function arguments This adds support for function calls of the form: ```rust ( #[attr(...)] 1.2, #[attr_one(...)] #[attr_two(...)] 1.5, ... etc ... ) ``` Closes https://github.com/rust-analyzer/rust-analyzer/issues/2801 --- crates/ra_parser/src/grammar/expressions.rs | 11 +++ .../test_data/parser/inline/ok/0152_arg_list.rs | 9 ++ .../test_data/parser/inline/ok/0152_arg_list.txt | 106 +++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.rs create mode 100644 crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.txt (limited to 'crates') diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 81d4f75f9..7caed66a0 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -535,11 +535,22 @@ fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { m.complete(p, CAST_EXPR) } +// test arg_list +// fn assert_float(s: &str, n: f64) {} +// fn foo() { +// assert_float( +// "1.797693134862315708e+308L", +// #[allow(clippy::excessive_precision)] +// #[allow(dead_code)] +// 1.797_693_134_862_315_730_8e+308, +// ); +// } fn arg_list(p: &mut Parser) { assert!(p.at(T!['('])); let m = p.start(); p.bump(T!['(']); while !p.at(T![')']) && !p.at(EOF) { + attributes::outer_attributes(p); if !p.at_ts(EXPR_FIRST) { p.error("expected expression"); break; diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.rs b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.rs new file mode 100644 index 000000000..a4009b392 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.rs @@ -0,0 +1,9 @@ +fn assert_float(s: &str, n: f64) {} +fn foo() { + assert_float( + "1.797693134862315708e+308L", + #[allow(clippy::excessive_precision)] + #[allow(dead_code)] + 1.797_693_134_862_315_730_8e+308, + ); +} diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.txt b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.txt new file mode 100644 index 000000000..6b1992dac --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.txt @@ -0,0 +1,106 @@ +SOURCE_FILE@[0; 228) + FN_DEF@[0; 35) + FN_KW@[0; 2) "fn" + WHITESPACE@[2; 3) " " + NAME@[3; 15) + IDENT@[3; 15) "assert_float" + PARAM_LIST@[15; 32) + L_PAREN@[15; 16) "(" + PARAM@[16; 23) + BIND_PAT@[16; 17) + NAME@[16; 17) + IDENT@[16; 17) "s" + COLON@[17; 18) ":" + WHITESPACE@[18; 19) " " + REFERENCE_TYPE@[19; 23) + AMP@[19; 20) "&" + PATH_TYPE@[20; 23) + PATH@[20; 23) + PATH_SEGMENT@[20; 23) + NAME_REF@[20; 23) + IDENT@[20; 23) "str" + COMMA@[23; 24) "," + WHITESPACE@[24; 25) " " + PARAM@[25; 31) + BIND_PAT@[25; 26) + NAME@[25; 26) + IDENT@[25; 26) "n" + COLON@[26; 27) ":" + WHITESPACE@[27; 28) " " + PATH_TYPE@[28; 31) + PATH@[28; 31) + PATH_SEGMENT@[28; 31) + NAME_REF@[28; 31) + IDENT@[28; 31) "f64" + R_PAREN@[31; 32) ")" + WHITESPACE@[32; 33) " " + BLOCK_EXPR@[33; 35) + BLOCK@[33; 35) + L_CURLY@[33; 34) "{" + R_CURLY@[34; 35) "}" + WHITESPACE@[35; 36) "\n" + FN_DEF@[36; 227) + FN_KW@[36; 38) "fn" + WHITESPACE@[38; 39) " " + NAME@[39; 42) + IDENT@[39; 42) "foo" + PARAM_LIST@[42; 44) + L_PAREN@[42; 43) "(" + R_PAREN@[43; 44) ")" + WHITESPACE@[44; 45) " " + BLOCK_EXPR@[45; 227) + BLOCK@[45; 227) + L_CURLY@[45; 46) "{" + WHITESPACE@[46; 51) "\n " + EXPR_STMT@[51; 225) + CALL_EXPR@[51; 224) + PATH_EXPR@[51; 63) + PATH@[51; 63) + PATH_SEGMENT@[51; 63) + NAME_REF@[51; 63) + IDENT@[51; 63) "assert_float" + ARG_LIST@[63; 224) + L_PAREN@[63; 64) "(" + WHITESPACE@[64; 73) "\n " + LITERAL@[73; 101) + STRING@[73; 101) "\"1.797693134862315708 ..." + COMMA@[101; 102) "," + WHITESPACE@[102; 111) "\n " + ATTR@[111; 148) + POUND@[111; 112) "#" + L_BRACK@[112; 113) "[" + PATH@[113; 118) + PATH_SEGMENT@[113; 118) + NAME_REF@[113; 118) + IDENT@[113; 118) "allow" + TOKEN_TREE@[118; 147) + L_PAREN@[118; 119) "(" + IDENT@[119; 125) "clippy" + COLON@[125; 126) ":" + COLON@[126; 127) ":" + IDENT@[127; 146) "excessive_precision" + R_PAREN@[146; 147) ")" + R_BRACK@[147; 148) "]" + WHITESPACE@[148; 157) "\n " + ATTR@[157; 176) + POUND@[157; 158) "#" + L_BRACK@[158; 159) "[" + PATH@[159; 164) + PATH_SEGMENT@[159; 164) + NAME_REF@[159; 164) + IDENT@[159; 164) "allow" + TOKEN_TREE@[164; 175) + L_PAREN@[164; 165) "(" + IDENT@[165; 174) "dead_code" + R_PAREN@[174; 175) ")" + R_BRACK@[175; 176) "]" + WHITESPACE@[176; 185) "\n " + LITERAL@[185; 217) + FLOAT_NUMBER@[185; 217) "1.797_693_134_862_315 ..." + COMMA@[217; 218) "," + WHITESPACE@[218; 223) "\n " + R_PAREN@[223; 224) ")" + SEMI@[224; 225) ";" + WHITESPACE@[225; 226) "\n" + R_CURLY@[226; 227) "}" + WHITESPACE@[227; 228) "\n" -- cgit v1.2.3 From a24dcd7babc7212a23eb5c8d7c73bede0d6465aa Mon Sep 17 00:00:00 2001 From: Veetaha Date: Wed, 15 Jan 2020 23:29:55 +0200 Subject: fix(ra_parser.typo): amend 'format language' to 'formal language' --- crates/ra_parser/src/grammar.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index 22f64a9f4..a46e11e1d 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs @@ -1,7 +1,7 @@ //! This is the actual "grammar" of the Rust language. //! //! Each function in this module and its children corresponds -//! to a production of the format grammar. Submodules roughly +//! to a production of the formal grammar. Submodules roughly //! correspond to different *areas* of the grammar. By convention, //! each submodule starts with `use super::*` import and exports //! "public" productions via `pub(super)`. -- cgit v1.2.3 From c78e34968ff24bf8b195ea02be54835a09f53abd Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Wed, 15 Jan 2020 19:12:56 -0500 Subject: shrink inline tes --- crates/ra_parser/src/grammar/expressions.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'crates') diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 7caed66a0..d8105c382 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -535,15 +535,9 @@ fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { m.complete(p, CAST_EXPR) } -// test arg_list -// fn assert_float(s: &str, n: f64) {} -// fn foo() { -// assert_float( -// "1.797693134862315708e+308L", -// #[allow(clippy::excessive_precision)] -// #[allow(dead_code)] -// 1.797_693_134_862_315_730_8e+308, -// ); +// test arg_with_attr +// fn main() { +// foo(#[attr] 92) // } fn arg_list(p: &mut Parser) { assert!(p.at(T!['('])); -- cgit v1.2.3 From f077d5c303ecc4f38471b37be985bb0c5ab2f68c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 16 Jan 2020 22:20:17 -0500 Subject: move inline function closer to relevant code also updates generated inline tests --- crates/ra_parser/src/grammar/expressions.rs | 8 +- .../test_data/parser/inline/ok/0152_arg_list.rs | 9 -- .../test_data/parser/inline/ok/0152_arg_list.txt | 106 --------------------- .../parser/inline/ok/0152_arg_with_attr.rs | 3 + .../parser/inline/ok/0152_arg_with_attr.txt | 37 +++++++ 5 files changed, 44 insertions(+), 119 deletions(-) delete mode 100644 crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.rs delete mode 100644 crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.txt create mode 100644 crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.rs create mode 100644 crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt (limited to 'crates') diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index d8105c382..95564b602 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -535,15 +535,15 @@ fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { m.complete(p, CAST_EXPR) } -// test arg_with_attr -// fn main() { -// foo(#[attr] 92) -// } fn arg_list(p: &mut Parser) { assert!(p.at(T!['('])); let m = p.start(); p.bump(T!['(']); while !p.at(T![')']) && !p.at(EOF) { + // test arg_with_attr + // fn main() { + // foo(#[attr] 92) + // } attributes::outer_attributes(p); if !p.at_ts(EXPR_FIRST) { p.error("expected expression"); diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.rs b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.rs deleted file mode 100644 index a4009b392..000000000 --- a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn assert_float(s: &str, n: f64) {} -fn foo() { - assert_float( - "1.797693134862315708e+308L", - #[allow(clippy::excessive_precision)] - #[allow(dead_code)] - 1.797_693_134_862_315_730_8e+308, - ); -} diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.txt b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.txt deleted file mode 100644 index 6b1992dac..000000000 --- a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_list.txt +++ /dev/null @@ -1,106 +0,0 @@ -SOURCE_FILE@[0; 228) - FN_DEF@[0; 35) - FN_KW@[0; 2) "fn" - WHITESPACE@[2; 3) " " - NAME@[3; 15) - IDENT@[3; 15) "assert_float" - PARAM_LIST@[15; 32) - L_PAREN@[15; 16) "(" - PARAM@[16; 23) - BIND_PAT@[16; 17) - NAME@[16; 17) - IDENT@[16; 17) "s" - COLON@[17; 18) ":" - WHITESPACE@[18; 19) " " - REFERENCE_TYPE@[19; 23) - AMP@[19; 20) "&" - PATH_TYPE@[20; 23) - PATH@[20; 23) - PATH_SEGMENT@[20; 23) - NAME_REF@[20; 23) - IDENT@[20; 23) "str" - COMMA@[23; 24) "," - WHITESPACE@[24; 25) " " - PARAM@[25; 31) - BIND_PAT@[25; 26) - NAME@[25; 26) - IDENT@[25; 26) "n" - COLON@[26; 27) ":" - WHITESPACE@[27; 28) " " - PATH_TYPE@[28; 31) - PATH@[28; 31) - PATH_SEGMENT@[28; 31) - NAME_REF@[28; 31) - IDENT@[28; 31) "f64" - R_PAREN@[31; 32) ")" - WHITESPACE@[32; 33) " " - BLOCK_EXPR@[33; 35) - BLOCK@[33; 35) - L_CURLY@[33; 34) "{" - R_CURLY@[34; 35) "}" - WHITESPACE@[35; 36) "\n" - FN_DEF@[36; 227) - FN_KW@[36; 38) "fn" - WHITESPACE@[38; 39) " " - NAME@[39; 42) - IDENT@[39; 42) "foo" - PARAM_LIST@[42; 44) - L_PAREN@[42; 43) "(" - R_PAREN@[43; 44) ")" - WHITESPACE@[44; 45) " " - BLOCK_EXPR@[45; 227) - BLOCK@[45; 227) - L_CURLY@[45; 46) "{" - WHITESPACE@[46; 51) "\n " - EXPR_STMT@[51; 225) - CALL_EXPR@[51; 224) - PATH_EXPR@[51; 63) - PATH@[51; 63) - PATH_SEGMENT@[51; 63) - NAME_REF@[51; 63) - IDENT@[51; 63) "assert_float" - ARG_LIST@[63; 224) - L_PAREN@[63; 64) "(" - WHITESPACE@[64; 73) "\n " - LITERAL@[73; 101) - STRING@[73; 101) "\"1.797693134862315708 ..." - COMMA@[101; 102) "," - WHITESPACE@[102; 111) "\n " - ATTR@[111; 148) - POUND@[111; 112) "#" - L_BRACK@[112; 113) "[" - PATH@[113; 118) - PATH_SEGMENT@[113; 118) - NAME_REF@[113; 118) - IDENT@[113; 118) "allow" - TOKEN_TREE@[118; 147) - L_PAREN@[118; 119) "(" - IDENT@[119; 125) "clippy" - COLON@[125; 126) ":" - COLON@[126; 127) ":" - IDENT@[127; 146) "excessive_precision" - R_PAREN@[146; 147) ")" - R_BRACK@[147; 148) "]" - WHITESPACE@[148; 157) "\n " - ATTR@[157; 176) - POUND@[157; 158) "#" - L_BRACK@[158; 159) "[" - PATH@[159; 164) - PATH_SEGMENT@[159; 164) - NAME_REF@[159; 164) - IDENT@[159; 164) "allow" - TOKEN_TREE@[164; 175) - L_PAREN@[164; 165) "(" - IDENT@[165; 174) "dead_code" - R_PAREN@[174; 175) ")" - R_BRACK@[175; 176) "]" - WHITESPACE@[176; 185) "\n " - LITERAL@[185; 217) - FLOAT_NUMBER@[185; 217) "1.797_693_134_862_315 ..." - COMMA@[217; 218) "," - WHITESPACE@[218; 223) "\n " - R_PAREN@[223; 224) ")" - SEMI@[224; 225) ";" - WHITESPACE@[225; 226) "\n" - R_CURLY@[226; 227) "}" - WHITESPACE@[227; 228) "\n" diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.rs b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.rs new file mode 100644 index 000000000..5daf1d7b0 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.rs @@ -0,0 +1,3 @@ +fn main() { + foo(#[attr] 92) +} diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt new file mode 100644 index 000000000..6b80ca8d0 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt @@ -0,0 +1,37 @@ +SOURCE_FILE@[0; 34) + FN_DEF@[0; 33) + FN_KW@[0; 2) "fn" + WHITESPACE@[2; 3) " " + NAME@[3; 7) + IDENT@[3; 7) "main" + PARAM_LIST@[7; 9) + L_PAREN@[7; 8) "(" + R_PAREN@[8; 9) ")" + WHITESPACE@[9; 10) " " + BLOCK_EXPR@[10; 33) + BLOCK@[10; 33) + L_CURLY@[10; 11) "{" + WHITESPACE@[11; 16) "\n " + CALL_EXPR@[16; 31) + PATH_EXPR@[16; 19) + PATH@[16; 19) + PATH_SEGMENT@[16; 19) + NAME_REF@[16; 19) + IDENT@[16; 19) "foo" + ARG_LIST@[19; 31) + L_PAREN@[19; 20) "(" + ATTR@[20; 27) + POUND@[20; 21) "#" + L_BRACK@[21; 22) "[" + PATH@[22; 26) + PATH_SEGMENT@[22; 26) + NAME_REF@[22; 26) + IDENT@[22; 26) "attr" + R_BRACK@[26; 27) "]" + WHITESPACE@[27; 28) " " + LITERAL@[28; 30) + INT_NUMBER@[28; 30) "92" + R_PAREN@[30; 31) ")" + WHITESPACE@[31; 32) "\n" + R_CURLY@[32; 33) "}" + WHITESPACE@[33; 34) "\n" -- cgit v1.2.3 From b7c45fba57224a013fbc926abd2e8e9f8f3c77d4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 17 Jan 2020 11:44:40 +0100 Subject: Extract expr_with_attrs --- crates/ra_parser/src/grammar/expressions.rs | 20 ++++++++++++++++++ crates/ra_parser/src/grammar/expressions/atom.rs | 15 ++------------ .../test_data/parser/err/0022_bad_exprs.txt | 24 +++++++++++++--------- 3 files changed, 36 insertions(+), 23 deletions(-) (limited to 'crates') diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index a31a7a08d..3cf619e38 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -19,6 +19,26 @@ pub(super) fn expr(p: &mut Parser) -> (Option, BlockLike) { expr_bp(p, r, 1) } +pub(super) fn expr_with_attrs(p: &mut Parser) -> bool { + let m = p.start(); + let has_attrs = p.at(T![#]); + attributes::outer_attributes(p); + + let (cm, _block_like) = expr(p); + let success = cm.is_some(); + + match (has_attrs, cm) { + (true, Some(cm)) => { + let kind = cm.kind(); + cm.undo_completion(p).abandon(p); + m.complete(p, kind); + } + _ => m.abandon(p), + } + + success +} + pub(super) fn expr_stmt(p: &mut Parser) -> (Option, BlockLike) { let r = Restrictions { forbid_structs: false, prefer_stmt: true }; expr_bp(p, r, 1) diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index a98a2a3ef..2cc321473 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs @@ -191,19 +191,8 @@ fn array_expr(p: &mut Parser) -> CompletedMarker { // test array_attrs // const A: &[i64] = &[1, #[cfg(test)] 2]; - let m = p.start(); - let has_attrs = p.at(T![#]); - attributes::outer_attributes(p); - - let cm = expr(p).0; - - match (has_attrs, cm) { - (true, Some(cm)) => { - let kind = cm.kind(); - cm.undo_completion(p).abandon(p); - m.complete(p, kind); - } - _ => m.abandon(p), + if !expr_with_attrs(p) { + break; } if n_exprs == 1 && p.eat(T![;]) { diff --git a/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt b/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt index 310a82464..2237eb413 100644 --- a/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt +++ b/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt @@ -12,8 +12,8 @@ SOURCE_FILE@[0; 112) BLOCK@[7; 33) L_CURLY@[7; 8) "{" WHITESPACE@[8; 9) " " - EXPR_STMT@[9; 26) - ARRAY_EXPR@[9; 26) + EXPR_STMT@[9; 17) + ARRAY_EXPR@[9; 17) L_BRACK@[9; 10) "[" LITERAL@[10; 11) INT_NUMBER@[10; 11) "1" @@ -25,10 +25,13 @@ SOURCE_FILE@[0; 112) WHITESPACE@[15; 16) " " ERROR@[16; 17) AT@[16; 17) "@" + EXPR_STMT@[17; 18) + ERROR@[17; 18) COMMA@[17; 18) "," - WHITESPACE@[18; 19) " " - ERROR@[19; 25) - STRUCT_KW@[19; 25) "struct" + WHITESPACE@[18; 19) " " + STRUCT_DEF@[19; 26) + STRUCT_KW@[19; 25) "struct" + ERROR@[25; 26) COMMA@[25; 26) "," WHITESPACE@[26; 27) " " LET_STMT@[27; 31) @@ -148,11 +151,12 @@ SOURCE_FILE@[0; 112) R_CURLY@[110; 111) "}" WHITESPACE@[111; 112) "\n" error 16: expected expression -error 19: expected expression -error 26: expected expression -error 26: expected COMMA -error 26: expected R_BRACK -error 26: expected SEMI +error 17: expected R_BRACK +error 17: expected SEMI +error 17: expected expression +error 18: expected SEMI +error 25: expected a name +error 26: expected `;`, `{`, or `(` error 30: expected pattern error 31: expected SEMI error 52: expected expression -- cgit v1.2.3 From 3a859e587f3bcf9f49293bd1f2b2d19cdfd2be4b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 17 Jan 2020 11:47:07 +0100 Subject: Nest attrs into exprs in function args --- crates/ra_parser/src/grammar/expressions.rs | 5 +--- .../test_data/parser/err/0022_bad_exprs.txt | 30 +++++++++------------- .../parser/inline/ok/0152_arg_with_attr.txt | 20 +++++++-------- 3 files changed, 23 insertions(+), 32 deletions(-) (limited to 'crates') diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index 3cf619e38..06c92645e 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs @@ -564,12 +564,9 @@ fn arg_list(p: &mut Parser) { // fn main() { // foo(#[attr] 92) // } - attributes::outer_attributes(p); - if !p.at_ts(EXPR_FIRST) { - p.error("expected expression"); + if !expr_with_attrs(p) { break; } - expr(p); if !p.at(T![')']) && !p.expect(T![,]) { break; } diff --git a/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt b/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt index 2237eb413..cb45eb2fc 100644 --- a/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt +++ b/crates/ra_syntax/test_data/parser/err/0022_bad_exprs.txt @@ -54,14 +54,14 @@ SOURCE_FILE@[0; 112) BLOCK@[41; 68) L_CURLY@[41; 42) "{" WHITESPACE@[42; 43) " " - EXPR_STMT@[43; 52) - CALL_EXPR@[43; 52) + EXPR_STMT@[43; 54) + CALL_EXPR@[43; 54) PATH_EXPR@[43; 46) PATH@[43; 46) PATH_SEGMENT@[43; 46) NAME_REF@[43; 46) IDENT@[43; 46) "foo" - ARG_LIST@[46; 52) + ARG_LIST@[46; 54) L_PAREN@[46; 47) "(" LITERAL@[47; 48) INT_NUMBER@[47; 48) "1" @@ -70,10 +70,9 @@ SOURCE_FILE@[0; 112) LITERAL@[50; 51) INT_NUMBER@[50; 51) "2" COMMA@[51; 52) "," - WHITESPACE@[52; 53) " " - EXPR_STMT@[53; 54) - ERROR@[53; 54) - AT@[53; 54) "@" + WHITESPACE@[52; 53) " " + ERROR@[53; 54) + AT@[53; 54) "@" EXPR_STMT@[54; 55) ERROR@[54; 55) COMMA@[54; 55) "," @@ -104,8 +103,8 @@ SOURCE_FILE@[0; 112) BLOCK@[76; 111) L_CURLY@[76; 77) "{" WHITESPACE@[77; 78) " " - EXPR_STMT@[78; 91) - METHOD_CALL_EXPR@[78; 91) + EXPR_STMT@[78; 93) + METHOD_CALL_EXPR@[78; 93) PATH_EXPR@[78; 81) PATH@[78; 81) PATH_SEGMENT@[78; 81) @@ -114,7 +113,7 @@ SOURCE_FILE@[0; 112) DOT@[81; 82) "." NAME_REF@[82; 85) IDENT@[82; 85) "bar" - ARG_LIST@[85; 91) + ARG_LIST@[85; 93) L_PAREN@[85; 86) "(" LITERAL@[86; 87) INT_NUMBER@[86; 87) "1" @@ -123,10 +122,9 @@ SOURCE_FILE@[0; 112) LITERAL@[89; 90) INT_NUMBER@[89; 90) "2" COMMA@[90; 91) "," - WHITESPACE@[91; 92) " " - EXPR_STMT@[92; 93) - ERROR@[92; 93) - AT@[92; 93) "@" + WHITESPACE@[91; 92) " " + ERROR@[92; 93) + AT@[92; 93) "@" EXPR_STMT@[93; 94) ERROR@[93; 94) COMMA@[93; 94) "," @@ -159,8 +157,6 @@ error 25: expected a name error 26: expected `;`, `{`, or `(` error 30: expected pattern error 31: expected SEMI -error 52: expected expression -error 52: expected SEMI error 53: expected expression error 54: expected SEMI error 54: expected expression @@ -172,8 +168,6 @@ error 61: expected SEMI error 65: expected pattern error 65: expected SEMI error 65: expected expression -error 91: expected expression -error 91: expected SEMI error 92: expected expression error 93: expected SEMI error 93: expected expression diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt index 6b80ca8d0..8092d7009 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0152_arg_with_attr.txt @@ -20,16 +20,16 @@ SOURCE_FILE@[0; 34) IDENT@[16; 19) "foo" ARG_LIST@[19; 31) L_PAREN@[19; 20) "(" - ATTR@[20; 27) - POUND@[20; 21) "#" - L_BRACK@[21; 22) "[" - PATH@[22; 26) - PATH_SEGMENT@[22; 26) - NAME_REF@[22; 26) - IDENT@[22; 26) "attr" - R_BRACK@[26; 27) "]" - WHITESPACE@[27; 28) " " - LITERAL@[28; 30) + LITERAL@[20; 30) + ATTR@[20; 27) + POUND@[20; 21) "#" + L_BRACK@[21; 22) "[" + PATH@[22; 26) + PATH_SEGMENT@[22; 26) + NAME_REF@[22; 26) + IDENT@[22; 26) "attr" + R_BRACK@[26; 27) "]" + WHITESPACE@[27; 28) " " INT_NUMBER@[28; 30) "92" R_PAREN@[30; 31) ")" WHITESPACE@[31; 32) "\n" -- cgit v1.2.3 From 33d637f2ddb5e5eab6d5dfaf75042dfc1a58d241 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 17 Jan 2020 16:59:02 +0100 Subject: Fix inference for shift operators Fixes #2602. --- crates/ra_hir_ty/src/infer/expr.rs | 4 ++-- crates/ra_hir_ty/src/op.rs | 15 ++++++++++++--- crates/ra_hir_ty/src/tests/simple.rs | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 5 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index d6a17e469..31259a01d 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -386,11 +386,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); // FIXME: find implementation of trait corresponding to operation // symbol and resolve associated `Output` type - let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty); + let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone()); let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation)); // FIXME: similar as above, return ty is often associated trait type - op::binary_op_return_ty(*op, rhs_ty) + op::binary_op_return_ty(*op, lhs_ty, rhs_ty) } _ => Ty::Unknown, }, diff --git a/crates/ra_hir_ty/src/op.rs b/crates/ra_hir_ty/src/op.rs index 09c47a76d..ae253ca04 100644 --- a/crates/ra_hir_ty/src/op.rs +++ b/crates/ra_hir_ty/src/op.rs @@ -1,13 +1,21 @@ -//! FIXME: write short doc here -use hir_def::expr::{BinaryOp, CmpOp}; +//! Helper functions for binary operator type inference. +use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; use super::{InferTy, Ty, TypeCtor}; use crate::ApplicationTy; -pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty { +pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { match op { BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool), BinaryOp::Assignment { .. } => Ty::unit(), + BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { + Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { + TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, + _ => Ty::Unknown, + }, + Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, + _ => Ty::Unknown, + }, BinaryOp::ArithOp(_) => match rhs_ty { Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty, @@ -36,6 +44,7 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { _ => Ty::Unknown, } } + BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown, BinaryOp::CmpOp(CmpOp::Ord { .. }) | BinaryOp::Assignment { op: Some(_) } | BinaryOp::ArithOp(_) => match lhs_ty { diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs index f7e042c12..b7204ec00 100644 --- a/crates/ra_hir_ty/src/tests/simple.rs +++ b/crates/ra_hir_ty/src/tests/simple.rs @@ -613,6 +613,27 @@ fn test() -> bool { ); } +#[test] +fn infer_shift_op() { + assert_snapshot!( + infer(r#" +fn test() { + 1u32 << 5u8; + 1u32 >> 5u8; +} +"#), + @r###" + [11; 48) '{ ...5u8; }': () + [17; 21) '1u32': u32 + [17; 28) '1u32 << 5u8': u32 + [25; 28) '5u8': u8 + [34; 38) '1u32': u32 + [34; 45) '1u32 >> 5u8': u32 + [42; 45) '5u8': u8 + "### + ); +} + #[test] fn infer_field_autoderef() { assert_snapshot!( -- cgit v1.2.3 From 18ec4e3403854995d44841a066ff3b190d8115e6 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 18 Jan 2020 13:40:32 +0100 Subject: Improve parameter hints a bit & add emacs support - just include the name, not e.g. `mut` - don't return empty hints (or `_`) --- crates/ra_ide/src/display/function_signature.rs | 19 ++++++++++++++++--- crates/ra_ide/src/inlay_hints.rs | 23 +++++++++-------------- 2 files changed, 25 insertions(+), 17 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs index ddc53a52b..1e4a472b4 100644 --- a/crates/ra_ide/src/display/function_signature.rs +++ b/crates/ra_ide/src/display/function_signature.rs @@ -169,9 +169,22 @@ impl From<&'_ ast::FnDef> for FunctionSignature { res.push(self_param.syntax().text().to_string()) } - res.extend(param_list.params().map(|param| { - param.pat().map(|pat| pat.syntax().text().to_string()).unwrap_or_default() - })); + res.extend( + param_list + .params() + .map(|param| { + Some( + param + .pat()? + .syntax() + .descendants() + .find_map(ast::Name::cast)? + .text() + .to_string(), + ) + }) + .map(|param| param.unwrap_or_default()), + ); } res } diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index 1b631c7cd..236557541 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs @@ -116,7 +116,7 @@ fn get_param_name_hints( let hints = parameters .zip(args) .filter_map(|(param, arg)| { - if arg.syntax().kind() == SyntaxKind::LITERAL { + if arg.syntax().kind() == SyntaxKind::LITERAL && !param.is_empty() { Some((arg.syntax().text_range(), param)) } else { None @@ -683,12 +683,12 @@ fn main() { struct Test {} impl Test { - fn method(&self, param: i32) -> i32 { + fn method(&self, mut param: i32) -> i32 { param * 2 } } -fn test_func(foo: i32, bar: i32, msg: &str, _: i32, last: i32) -> i32 { +fn test_func(mut foo: i32, bar: i32, msg: &str, _: i32, last: i32) -> i32 { foo + bar } @@ -704,37 +704,32 @@ fn main() { assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" [ InlayHint { - range: [207; 218), + range: [215; 226), kind: TypeHint, label: "i32", }, InlayHint { - range: [251; 252), + range: [259; 260), kind: ParameterHint, label: "foo", }, InlayHint { - range: [254; 255), + range: [262; 263), kind: ParameterHint, label: "bar", }, InlayHint { - range: [257; 264), + range: [265; 272), kind: ParameterHint, label: "msg", }, InlayHint { - range: [266; 267), - kind: ParameterHint, - label: "_", - }, - InlayHint { - range: [323; 326), + range: [331; 334), kind: ParameterHint, label: "param", }, InlayHint { - range: [350; 354), + range: [358; 362), kind: ParameterHint, label: "param", }, -- cgit v1.2.3