mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Merge pull request #19265 from Shourya742/2025-03-01-add-dangling-dyn-diagnostic
feat: Add diagnostic for dangling dyn and impl
This commit is contained in:
commit
3c394c61b8
@ -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,18 +341,35 @@ 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()?;
|
||||
let bounds_count = tbl.bounds().count();
|
||||
|
||||
if tbl.bounds().count() > 1 {
|
||||
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 potential_parenthesis =
|
||||
let preceding_token =
|
||||
algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?;
|
||||
let kind = potential_parenthesis.kind();
|
||||
if !matches!(kind, T!['('] | T![<] | T![=]) {
|
||||
|
||||
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(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec<SyntaxError>) {
|
||||
if let Some(vis) = mac.visibility() {
|
||||
|
@ -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
|
@ -0,0 +1 @@
|
||||
fn f(_: &dyn) {}
|
23
crates/syntax/test_data/parser/validation/dangling_impl.rast
Normal file
23
crates/syntax/test_data/parser/validation/dangling_impl.rast
Normal file
@ -0,0 +1,23 @@
|
||||
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 " "
|
||||
IMPL_TRAIT_TYPE@8..12
|
||||
IMPL_KW@8..12 "impl"
|
||||
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 8..12: At least one trait must be specified
|
@ -0,0 +1 @@
|
||||
fn f(_: impl) {}
|
@ -0,0 +1,25 @@
|
||||
SOURCE_FILE@0..17
|
||||
FN@0..17
|
||||
FN_KW@0..2 "fn"
|
||||
WHITESPACE@2..3 " "
|
||||
NAME@3..4
|
||||
IDENT@3..4 "f"
|
||||
PARAM_LIST@4..14
|
||||
L_PAREN@4..5 "("
|
||||
PARAM@5..13
|
||||
WILDCARD_PAT@5..6
|
||||
UNDERSCORE@5..6 "_"
|
||||
COLON@6..7 ":"
|
||||
WHITESPACE@7..8 " "
|
||||
REF_TYPE@8..13
|
||||
AMP@8..9 "&"
|
||||
IMPL_TRAIT_TYPE@9..13
|
||||
IMPL_KW@9..13 "impl"
|
||||
TYPE_BOUND_LIST@13..13
|
||||
R_PAREN@13..14 ")"
|
||||
WHITESPACE@14..15 " "
|
||||
BLOCK_EXPR@15..17
|
||||
STMT_LIST@15..17
|
||||
L_CURLY@15..16 "{"
|
||||
R_CURLY@16..17 "}"
|
||||
error 9..13: At least one trait must be specified
|
@ -0,0 +1 @@
|
||||
fn f(_: &impl) {}
|
Loading…
x
Reference in New Issue
Block a user