Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #19265 from Shourya742/2025-03-01-add-dangling-dyn-diagnostic
feat: Add diagnostic for dangling dyn and impl
7 files changed, 103 insertions, 9 deletions
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index 13d352d3c6..85eefac734 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs @@ -37,6 +37,7 @@ pub(crate) fn validate(root: &SyntaxNode, errors: &mut Vec<SyntaxError>) { ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, errors), ast::MacroRules(it) => validate_macro_rules(it, errors), ast::LetExpr(it) => validate_let_expr(it, errors), + ast::ImplTraitType(it) => validate_impl_object_ty(it, errors), _ => (), } } @@ -340,17 +341,34 @@ 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, + } +} + +fn validate_impl_object_ty(ty: ast::ImplTraitType, errors: &mut Vec<SyntaxError>) { + if ty.type_bound_list().map_or(0, |tbl| tbl.bounds().count()) == 0 { + errors.push(SyntaxError::new( + "At least one trait must be specified", + ty.syntax().text_range(), + )); } - None } fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec<SyntaxError>) { diff --git a/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast b/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast new file mode 100644 index 0000000000..b31af5fbc6 --- /dev/null +++ b/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rast @@ -0,0 +1,25 @@ + [email protected] "fn" + [email protected] " " + [email protected] "f" + [email protected] "(" + [email protected] "_" + [email protected] ":" + [email protected] " " + [email protected] "&" + [email protected] "dyn" + [email protected] ")" + [email protected] " " + [email protected] "{" + [email protected] "}" +error 9..12: At least one trait is required for an object type diff --git a/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs b/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs new file mode 100644 index 0000000000..2fdbb42846 --- /dev/null +++ b/crates/syntax/test_data/parser/validation/0224_dangling_dyn.rs @@ -0,0 +1 @@ +fn f(_: &dyn) {}
\ No newline at end of file diff --git a/crates/syntax/test_data/parser/validation/dangling_impl.rast b/crates/syntax/test_data/parser/validation/dangling_impl.rast new file mode 100644 index 0000000000..2db07ae12a --- /dev/null +++ b/crates/syntax/test_data/parser/validation/dangling_impl.rast @@ -0,0 +1,23 @@ + [email protected] "fn" + [email protected] " " + [email protected] "f" + [email protected] "(" + [email protected] "_" + [email protected] ":" + [email protected] " " + [email protected] "impl" + [email protected] ")" + [email protected] " " + [email protected] "{" + [email protected] "}" +error 8..12: At least one trait must be specified diff --git a/crates/syntax/test_data/parser/validation/dangling_impl.rs b/crates/syntax/test_data/parser/validation/dangling_impl.rs new file mode 100644 index 0000000000..61706d9e41 --- /dev/null +++ b/crates/syntax/test_data/parser/validation/dangling_impl.rs @@ -0,0 +1 @@ +fn f(_: impl) {}
\ No newline at end of file diff --git a/crates/syntax/test_data/parser/validation/dangling_impl_reference.rast b/crates/syntax/test_data/parser/validation/dangling_impl_reference.rast new file mode 100644 index 0000000000..dbe6535ac6 --- /dev/null +++ b/crates/syntax/test_data/parser/validation/dangling_impl_reference.rast @@ -0,0 +1,25 @@ + [email protected] "fn" + [email protected] " " + [email protected] "f" + [email protected] "(" + [email protected] "_" + [email protected] ":" + [email protected] " " + [email protected] "&" + [email protected] "impl" + [email protected] ")" + [email protected] " " + [email protected] "{" + [email protected] "}" +error 9..13: At least one trait must be specified diff --git a/crates/syntax/test_data/parser/validation/dangling_impl_reference.rs b/crates/syntax/test_data/parser/validation/dangling_impl_reference.rs new file mode 100644 index 0000000000..0b440b4c5a --- /dev/null +++ b/crates/syntax/test_data/parser/validation/dangling_impl_reference.rs @@ -0,0 +1 @@ +fn f(_: &impl) {}
\ No newline at end of file |