diff options
| author | bit-aloo <sshourya17@gmail.com> | 2025-03-02 19:41:39 +0530 |
|---|---|---|
| committer | bit-aloo <sshourya17@gmail.com> | 2025-03-02 19:41:39 +0530 |
| commit | 2f9e5586a07f8cfa3e533668d0bf7885178659ed (patch) | |
| tree | 10573598f05f3405158d19955fab6582d56e5858 | |
| parent | da06b7c1bbf3b10aafbee635418e5afad12468c1 (diff) | |
| download | rust-2f9e5586a07f8cfa3e533668d0bf7885178659ed.tar.gz rust-2f9e5586a07f8cfa3e533668d0bf7885178659ed.zip | |
add diagnostic for dangling dyn
3 files changed, 43 insertions, 9 deletions
diff --git a/src/tools/rust-analyzer/crates/syntax/src/validation.rs b/src/tools/rust-analyzer/crates/syntax/src/validation.rs index 13d352d3c69..2dc86411e42 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/validation.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/validation.rs @@ -340,17 +340,25 @@ fn validate_trait_object_fn_ptr_ret_ty(ty: ast::FnPtrType, errors: &mut Vec<Synt fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> { let tbl = ty.type_bound_list()?; - - if tbl.bounds().count() > 1 { - let dyn_token = ty.dyn_token()?; - let potential_parenthesis = - algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?; - let kind = potential_parenthesis.kind(); - if !matches!(kind, T!['('] | T![<] | T![=]) { - return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range())); + let bounds_count = tbl.bounds().count(); + + match bounds_count { + 0 => Some(SyntaxError::new( + "At least one trait is required for an object type", + ty.syntax().text_range(), + )), + _ if bounds_count > 1 => { + let dyn_token = ty.dyn_token()?; + let preceding_token = + algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?; + + if !matches!(preceding_token.kind(), T!['('] | T![<] | T![=]) { + return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range())); + } + None } + _ => None, } - None } fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec<SyntaxError>) { diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast new file mode 100644 index 00000000000..b31af5fbc6a --- /dev/null +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast @@ -0,0 +1,25 @@ +SOURCE_FILE@0..16 + FN@0..16 + FN_KW@0..2 "fn" + WHITESPACE@2..3 " " + NAME@3..4 + IDENT@3..4 "f" + PARAM_LIST@4..13 + L_PAREN@4..5 "(" + PARAM@5..12 + WILDCARD_PAT@5..6 + UNDERSCORE@5..6 "_" + COLON@6..7 ":" + WHITESPACE@7..8 " " + REF_TYPE@8..12 + AMP@8..9 "&" + DYN_TRAIT_TYPE@9..12 + DYN_KW@9..12 "dyn" + TYPE_BOUND_LIST@12..12 + R_PAREN@12..13 ")" + WHITESPACE@13..14 " " + BLOCK_EXPR@14..16 + STMT_LIST@14..16 + L_CURLY@14..15 "{" + R_CURLY@15..16 "}" +error 9..12: At least one trait is required for an object type diff --git a/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs new file mode 100644 index 00000000000..2fdbb42846b --- /dev/null +++ b/src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs @@ -0,0 +1 @@ +fn f(_: &dyn) {} \ No newline at end of file |
