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
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 @@ + [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] "'a" + [email protected] " " + [email protected] "+" + [email protected] " " + [email protected] "Sized" + [email protected] ")" + [email protected] " " + [email protected] "{" + [email protected] "}" +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 @@ + [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] "'a" + [email protected] ")" + [email protected] " " + [email protected] "{" + [email protected] "}" +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 |