diff --git a/crates/ra_syntax/src/grammar/items/traits.rs b/crates/ra_syntax/src/grammar/items/traits.rs index c21cfb1a9b..5dfdb470ca 100644 --- a/crates/ra_syntax/src/grammar/items/traits.rs +++ b/crates/ra_syntax/src/grammar/items/traits.rs @@ -55,9 +55,9 @@ pub(super) fn impl_item(p: &mut Parser) { // test impl_item_neg // impl !Send for X {} p.eat(EXCL); - types::type_(p); + impl_type(p); if p.eat(FOR_KW) { - types::type_(p); + impl_type(p); } type_params::opt_where_clause(p); if p.at(L_CURLY) { @@ -115,3 +115,17 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool { (p.nth(1) == LIFETIME || p.nth(1) == IDENT) && (p.nth(2) == R_ANGLE || p.nth(2) == COMMA || p.nth(2) == COLON || p.nth(2) == EQ) } + +// test impl_type +// impl Type {} +// impl Trait1 for T {} +// impl impl NotType {} +// impl Trait2 for impl NotType {} +pub(crate) fn impl_type(p: &mut Parser) { + if p.at(IMPL_KW) { + p.error("expected trait or type"); + return; + } + types::type_(p); +} + diff --git a/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.rs b/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.rs new file mode 100644 index 0000000000..829ca1c4be --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.rs @@ -0,0 +1,2 @@ +impl +impl OnceCell {} diff --git a/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt b/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt new file mode 100644 index 0000000000..9e26f58a08 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0026_imp_recovery.txt @@ -0,0 +1,47 @@ +ROOT@[0; 38) + IMPL_ITEM@[0; 14) + IMPL_KW@[0; 4) + TYPE_PARAM_LIST@[4; 14) + L_ANGLE@[4; 5) + TYPE_PARAM@[5; 13) + NAME@[5; 6) + IDENT@[5; 6) "T" + COLON@[6; 7) + WHITESPACE@[7; 8) + PATH_TYPE@[8; 13) + PATH@[8; 13) + PATH_SEGMENT@[8; 13) + NAME_REF@[8; 13) + IDENT@[8; 13) "Clone" + R_ANGLE@[13; 14) + err: `expected trait or type` + err: `expected `{`` + WHITESPACE@[14; 15) + IMPL_ITEM@[15; 37) + IMPL_KW@[15; 19) + TYPE_PARAM_LIST@[19; 22) + L_ANGLE@[19; 20) + TYPE_PARAM@[20; 21) + NAME@[20; 21) + IDENT@[20; 21) "T" + R_ANGLE@[21; 22) + WHITESPACE@[22; 23) + PATH_TYPE@[23; 34) + PATH@[23; 34) + PATH_SEGMENT@[23; 34) + NAME_REF@[23; 31) + IDENT@[23; 31) "OnceCell" + TYPE_ARG_LIST@[31; 34) + L_ANGLE@[31; 32) + TYPE_ARG@[32; 33) + PATH_TYPE@[32; 33) + PATH@[32; 33) + PATH_SEGMENT@[32; 33) + NAME_REF@[32; 33) + IDENT@[32; 33) "T" + R_ANGLE@[33; 34) + WHITESPACE@[34; 35) + ITEM_LIST@[35; 37) + L_CURLY@[35; 36) + R_CURLY@[36; 37) + WHITESPACE@[37; 38) diff --git a/crates/ra_syntax/tests/data/parser/inline/0111_impl_type.rs b/crates/ra_syntax/tests/data/parser/inline/0111_impl_type.rs new file mode 100644 index 0000000000..b8c7b65e31 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0111_impl_type.rs @@ -0,0 +1,4 @@ +impl Type {} +impl Trait1 for T {} +impl impl NotType {} +impl Trait2 for impl NotType {} diff --git a/crates/ra_syntax/tests/data/parser/inline/0111_impl_type.txt b/crates/ra_syntax/tests/data/parser/inline/0111_impl_type.txt new file mode 100644 index 0000000000..a2907b060c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0111_impl_type.txt @@ -0,0 +1,79 @@ +ROOT@[0; 87) + IMPL_ITEM@[0; 12) + IMPL_KW@[0; 4) + WHITESPACE@[4; 5) + PATH_TYPE@[5; 9) + PATH@[5; 9) + PATH_SEGMENT@[5; 9) + NAME_REF@[5; 9) + IDENT@[5; 9) "Type" + WHITESPACE@[9; 10) + ITEM_LIST@[10; 12) + L_CURLY@[10; 11) + R_CURLY@[11; 12) + WHITESPACE@[12; 13) + IMPL_ITEM@[13; 33) + IMPL_KW@[13; 17) + WHITESPACE@[17; 18) + PATH_TYPE@[18; 24) + PATH@[18; 24) + PATH_SEGMENT@[18; 24) + NAME_REF@[18; 24) + IDENT@[18; 24) "Trait1" + WHITESPACE@[24; 25) + FOR_KW@[25; 28) + WHITESPACE@[28; 29) + PATH_TYPE@[29; 30) + PATH@[29; 30) + PATH_SEGMENT@[29; 30) + NAME_REF@[29; 30) + IDENT@[29; 30) "T" + WHITESPACE@[30; 31) + ITEM_LIST@[31; 33) + L_CURLY@[31; 32) + R_CURLY@[32; 33) + WHITESPACE@[33; 34) + IMPL_ITEM@[34; 38) + IMPL_KW@[34; 38) + err: `expected trait or type` + err: `expected `{`` + WHITESPACE@[38; 39) + IMPL_ITEM@[39; 54) + IMPL_KW@[39; 43) + WHITESPACE@[43; 44) + PATH_TYPE@[44; 51) + PATH@[44; 51) + PATH_SEGMENT@[44; 51) + NAME_REF@[44; 51) + IDENT@[44; 51) "NotType" + WHITESPACE@[51; 52) + ITEM_LIST@[52; 54) + L_CURLY@[52; 53) + R_CURLY@[53; 54) + WHITESPACE@[54; 55) + IMPL_ITEM@[55; 70) + IMPL_KW@[55; 59) + WHITESPACE@[59; 60) + PATH_TYPE@[60; 66) + PATH@[60; 66) + PATH_SEGMENT@[60; 66) + NAME_REF@[60; 66) + IDENT@[60; 66) "Trait2" + WHITESPACE@[66; 67) + FOR_KW@[67; 70) + err: `expected trait or type` + err: `expected `{`` + WHITESPACE@[70; 71) + IMPL_ITEM@[71; 86) + IMPL_KW@[71; 75) + WHITESPACE@[75; 76) + PATH_TYPE@[76; 83) + PATH@[76; 83) + PATH_SEGMENT@[76; 83) + NAME_REF@[76; 83) + IDENT@[76; 83) "NotType" + WHITESPACE@[83; 84) + ITEM_LIST@[84; 86) + L_CURLY@[84; 85) + R_CURLY@[85; 86) + WHITESPACE@[86; 87)