Skip to content

Commit 9a8968f

Browse files
authored
Merge pull request rust-lang#19265 from Shourya742/2025-03-01-add-dangling-dyn-diagnostic
feat: Add diagnostic for dangling dyn and impl
2 parents d137fee + c2a630e commit 9a8968f

File tree

7 files changed

+103
-9
lines changed

7 files changed

+103
-9
lines changed

src/tools/rust-analyzer/crates/syntax/src/validation.rs

+27-9
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ pub(crate) fn validate(root: &SyntaxNode, errors: &mut Vec<SyntaxError>) {
3737
ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, errors),
3838
ast::MacroRules(it) => validate_macro_rules(it, errors),
3939
ast::LetExpr(it) => validate_let_expr(it, errors),
40+
ast::ImplTraitType(it) => validate_impl_object_ty(it, errors),
4041
_ => (),
4142
}
4243
}
@@ -340,17 +341,34 @@ fn validate_trait_object_fn_ptr_ret_ty(ty: ast::FnPtrType, errors: &mut Vec<Synt
340341

341342
fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> {
342343
let tbl = ty.type_bound_list()?;
343-
344-
if tbl.bounds().count() > 1 {
345-
let dyn_token = ty.dyn_token()?;
346-
let potential_parenthesis =
347-
algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?;
348-
let kind = potential_parenthesis.kind();
349-
if !matches!(kind, T!['('] | T![<] | T![=]) {
350-
return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range()));
344+
let bounds_count = tbl.bounds().count();
345+
346+
match bounds_count {
347+
0 => Some(SyntaxError::new(
348+
"At least one trait is required for an object type",
349+
ty.syntax().text_range(),
350+
)),
351+
_ if bounds_count > 1 => {
352+
let dyn_token = ty.dyn_token()?;
353+
let preceding_token =
354+
algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?;
355+
356+
if !matches!(preceding_token.kind(), T!['('] | T![<] | T![=]) {
357+
return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range()));
358+
}
359+
None
351360
}
361+
_ => None,
362+
}
363+
}
364+
365+
fn validate_impl_object_ty(ty: ast::ImplTraitType, errors: &mut Vec<SyntaxError>) {
366+
if ty.type_bound_list().map_or(0, |tbl| tbl.bounds().count()) == 0 {
367+
errors.push(SyntaxError::new(
368+
"At least one trait must be specified",
369+
ty.syntax().text_range(),
370+
));
352371
}
353-
None
354372
}
355373

356374
fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec<SyntaxError>) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn f(_: &dyn) {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn f(_: impl) {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn f(_: &impl) {}

0 commit comments

Comments
 (0)