Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #19347 from Shourya742/2025-03-13-add-diagnostic-for-dnagling-impl-with-lifetime
Add diagnostic for missing ambiguity error for impl trait
Lukas Wirth 2025-03-25
parent fbad4e6 · parent df56707 · commit ed7e25a
-rw-r--r--crates/syntax/src/validation.rs31
-rw-r--r--crates/syntax/test_data/parser/validation/0261_dangling_impl_undeclared_lifetime.rast38
-rw-r--r--crates/syntax/test_data/parser/validation/0261_dangling_impl_undeclared_lifetime.rs1
-rw-r--r--crates/syntax/test_data/parser/validation/impl_trait_lifetime_only.rast29
-rw-r--r--crates/syntax/test_data/parser/validation/impl_trait_lifetime_only.rs1
5 files changed, 99 insertions, 1 deletions
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs
index 14df485a9d..12894a2bda 100644
--- a/crates/syntax/src/validation.rs
+++ b/crates/syntax/src/validation.rs
@@ -363,11 +363,40 @@ fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> {
}
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 {
+ let Some(bound_list) = ty.type_bound_list() else {
errors.push(SyntaxError::new(
"At least one trait must be specified",
ty.syntax().text_range(),
));
+ return;
+ };
+
+ let bounds: Vec<_> = bound_list.bounds().collect();
+
+ if !bounds.iter().any(|b| !matches!(b.kind(), ast::TypeBoundKind::Lifetime(_))) {
+ errors.push(SyntaxError::new(
+ "At least one trait must be specified",
+ ty.syntax().text_range(),
+ ));
+ return;
+ }
+
+ if bounds.len() == 1 {
+ return;
+ }
+
+ let Some(preceding_token) = ty
+ .impl_token()
+ .and_then(|token| token.prev_token())
+ .and_then(|prev| algo::skip_trivia_token(prev, Direction::Prev))
+ else {
+ return;
+ };
+
+ if !matches!(preceding_token.kind(), T!['('] | T![<] | T![=])
+ && matches!(preceding_token.kind(), T![&])
+ {
+ errors.push(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range()));
}
}
diff --git a/crates/syntax/test_data/parser/validation/0261_dangling_impl_undeclared_lifetime.rast b/crates/syntax/test_data/parser/validation/0261_dangling_impl_undeclared_lifetime.rast
new file mode 100644
index 0000000000..bd71c61cad
--- /dev/null
+++ b/crates/syntax/test_data/parser/validation/0261_dangling_impl_undeclared_lifetime.rast
@@ -0,0 +1,38 @@
+error 9..24: ambiguous `+` in a type
diff --git a/crates/syntax/test_data/parser/validation/0261_dangling_impl_undeclared_lifetime.rs b/crates/syntax/test_data/parser/validation/0261_dangling_impl_undeclared_lifetime.rs
new file mode 100644
index 0000000000..670a6f0ea7
--- /dev/null
+++ b/crates/syntax/test_data/parser/validation/0261_dangling_impl_undeclared_lifetime.rs
@@ -0,0 +1 @@
+fn f(_: &impl 'a + Sized) {} \ No newline at end of file
diff --git a/crates/syntax/test_data/parser/validation/impl_trait_lifetime_only.rast b/crates/syntax/test_data/parser/validation/impl_trait_lifetime_only.rast
new file mode 100644
index 0000000000..98aa862bc8
--- /dev/null
+++ b/crates/syntax/test_data/parser/validation/impl_trait_lifetime_only.rast
@@ -0,0 +1,29 @@
+error 9..16: At least one trait must be specified
diff --git a/crates/syntax/test_data/parser/validation/impl_trait_lifetime_only.rs b/crates/syntax/test_data/parser/validation/impl_trait_lifetime_only.rs
new file mode 100644
index 0000000000..5b18a54ef5
--- /dev/null
+++ b/crates/syntax/test_data/parser/validation/impl_trait_lifetime_only.rs
@@ -0,0 +1 @@
+fn f(_: &impl 'a) {} \ No newline at end of file