about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbit-aloo <sshourya17@gmail.com>2025-03-02 19:41:39 +0530
committerbit-aloo <sshourya17@gmail.com>2025-03-02 19:41:39 +0530
commit2f9e5586a07f8cfa3e533668d0bf7885178659ed (patch)
tree10573598f05f3405158d19955fab6582d56e5858
parentda06b7c1bbf3b10aafbee635418e5afad12468c1 (diff)
downloadrust-2f9e5586a07f8cfa3e533668d0bf7885178659ed.tar.gz
rust-2f9e5586a07f8cfa3e533668d0bf7885178659ed.zip
add diagnostic for dangling dyn
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/validation.rs26
-rw-r--r--src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast25
-rw-r--r--src/tools/rust-analyzer/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs1
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