Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/parser/src/grammar/types.rs14
-rw-r--r--crates/parser/test_data/generated/runner.rs4
-rw-r--r--crates/parser/test_data/parser/inline/err/macro_as_type_bound.rast67
-rw-r--r--crates/parser/test_data/parser/inline/err/macro_as_type_bound.rs1
-rw-r--r--crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast62
5 files changed, 113 insertions, 35 deletions
diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs
index db0185331c..26b53fab9f 100644
--- a/crates/parser/src/grammar/types.rs
+++ b/crates/parser/src/grammar/types.rs
@@ -393,14 +393,20 @@ pub(super) fn opt_type_bounds_as_dyn_trait_type(
p: &mut Parser<'_>,
type_marker: CompletedMarker,
) -> CompletedMarker {
- assert!(matches!(
- type_marker.kind(),
- SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_TYPE
- ));
+ assert!(matches!(type_marker.kind(), PATH_TYPE | FOR_TYPE | MACRO_TYPE));
if !p.at(T![+]) {
return type_marker;
}
+ // test_err macro_as_type_bound
+ // fn main() { let x: foo!() + bar!() + baz!(); }
+
+ // `foo!() + ...` is invalid syntax for type bounds,
+ // gracefully exit and let the caller handle the error
+ if type_marker.kind() == MACRO_TYPE {
+ return type_marker;
+ }
+
// First create a TYPE_BOUND from the completed PATH_TYPE
let m = type_marker.precede(p).complete(p, TYPE_BOUND);
diff --git a/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs
index 4901ece9ca..8104d28baf 100644
--- a/crates/parser/test_data/generated/runner.rs
+++ b/crates/parser/test_data/generated/runner.rs
@@ -882,6 +882,10 @@ mod err {
run_and_expect_errors("test_data/parser/inline/err/let_else_right_curly_brace.rs");
}
#[test]
+ fn macro_as_type_bound() {
+ run_and_expect_errors("test_data/parser/inline/err/macro_as_type_bound.rs");
+ }
+ #[test]
fn macro_rules_as_macro_name() {
run_and_expect_errors("test_data/parser/inline/err/macro_rules_as_macro_name.rs");
}
diff --git a/crates/parser/test_data/parser/inline/err/macro_as_type_bound.rast b/crates/parser/test_data/parser/inline/err/macro_as_type_bound.rast
new file mode 100644
index 0000000000..df223efbe9
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/macro_as_type_bound.rast
@@ -0,0 +1,67 @@
+SOURCE_FILE
+ FN
+ FN_KW "fn"
+ WHITESPACE " "
+ NAME
+ IDENT "main"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE " "
+ LET_STMT
+ LET_KW "let"
+ WHITESPACE " "
+ IDENT_PAT
+ NAME
+ IDENT "x"
+ COLON ":"
+ WHITESPACE " "
+ MACRO_TYPE
+ MACRO_CALL
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "foo"
+ BANG "!"
+ TOKEN_TREE
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ ERROR
+ PLUS "+"
+ WHITESPACE " "
+ EXPR_STMT
+ BIN_EXPR
+ MACRO_EXPR
+ MACRO_CALL
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "bar"
+ BANG "!"
+ TOKEN_TREE
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ PLUS "+"
+ WHITESPACE " "
+ MACRO_EXPR
+ MACRO_CALL
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "baz"
+ BANG "!"
+ TOKEN_TREE
+ L_PAREN "("
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE " "
+ R_CURLY "}"
+ WHITESPACE "\n"
+error 25: expected SEMICOLON
+error 26: expected expression, item or let statement
diff --git a/crates/parser/test_data/parser/inline/err/macro_as_type_bound.rs b/crates/parser/test_data/parser/inline/err/macro_as_type_bound.rs
new file mode 100644
index 0000000000..67094ff414
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/macro_as_type_bound.rs
@@ -0,0 +1 @@
+fn main() { let x: foo!() + bar!() + baz!(); }
diff --git a/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast b/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast
index 4722beb619..89128b21e8 100644
--- a/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast
+++ b/crates/parser/test_data/parser/inline/err/type_bounds_macro_call_recovery.rast
@@ -74,39 +74,39 @@ SOURCE_FILE
GENERIC_ARG_LIST
L_ANGLE "<"
TYPE_ARG
- DYN_TRAIT_TYPE
- TYPE_BOUND_LIST
- TYPE_BOUND
- MACRO_TYPE
- MACRO_CALL
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "T"
- BANG "!"
- WHITESPACE " "
- PLUS "+"
- WHITESPACE " "
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "T"
- ERROR
- BANG "!"
- TOKEN_TREE
- L_CURLY "{"
- R_CURLY "}"
- R_ANGLE ">"
- WHITESPACE " "
- BLOCK_EXPR
- STMT_LIST
- L_CURLY "{"
- R_CURLY "}"
+ MACRO_TYPE
+ MACRO_CALL
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ BANG "!"
+ WHITESPACE " "
+ ERROR
+ PLUS "+"
+ WHITESPACE " "
+ MACRO_CALL
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ BANG "!"
+ TOKEN_TREE
+ L_CURLY "{"
+ R_CURLY "}"
+ ERROR
+ R_ANGLE ">"
+ WHITESPACE " "
+ ERROR
+ L_CURLY "{"
+ R_CURLY "}"
WHITESPACE "\n"
error 12: unexpected `!` in type path, macro calls are not allowed here
error 21: unexpected `!` in type path, macro calls are not allowed here
error 28: unexpected `!` in type path, macro calls are not allowed here
error 43: expected `{`, `[`, `(`
-error 48: unexpected `!` in type path, macro calls are not allowed here
+error 43: expected R_ANGLE
+error 43: expected a block
+error 44: expected an item
+error 50: expected an item
+error 52: expected an item