Skip to content

Commit ed7e25a

Browse files
authored
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
2 parents fbad4e6 + df56707 commit ed7e25a

File tree

5 files changed

+99
-1
lines changed

5 files changed

+99
-1
lines changed

crates/syntax/src/validation.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,40 @@ fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> {
363363
}
364364

365365
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 {
366+
let Some(bound_list) = ty.type_bound_list() else {
367367
errors.push(SyntaxError::new(
368368
"At least one trait must be specified",
369369
ty.syntax().text_range(),
370370
));
371+
return;
372+
};
373+
374+
let bounds: Vec<_> = bound_list.bounds().collect();
375+
376+
if !bounds.iter().any(|b| !matches!(b.kind(), ast::TypeBoundKind::Lifetime(_))) {
377+
errors.push(SyntaxError::new(
378+
"At least one trait must be specified",
379+
ty.syntax().text_range(),
380+
));
381+
return;
382+
}
383+
384+
if bounds.len() == 1 {
385+
return;
386+
}
387+
388+
let Some(preceding_token) = ty
389+
.impl_token()
390+
.and_then(|token| token.prev_token())
391+
.and_then(|prev| algo::skip_trivia_token(prev, Direction::Prev))
392+
else {
393+
return;
394+
};
395+
396+
if !matches!(preceding_token.kind(), T!['('] | T![<] | T![=])
397+
&& matches!(preceding_token.kind(), T![&])
398+
{
399+
errors.push(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range()));
371400
}
372401
}
373402

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
SOURCE_FILE@0..28
2+
FN@0..28
3+
FN_KW@0..2 "fn"
4+
WHITESPACE@2..3 " "
5+
NAME@3..4
6+
IDENT@3..4 "f"
7+
PARAM_LIST@4..25
8+
L_PAREN@4..5 "("
9+
PARAM@5..24
10+
WILDCARD_PAT@5..6
11+
UNDERSCORE@5..6 "_"
12+
COLON@6..7 ":"
13+
WHITESPACE@7..8 " "
14+
REF_TYPE@8..24
15+
AMP@8..9 "&"
16+
IMPL_TRAIT_TYPE@9..24
17+
IMPL_KW@9..13 "impl"
18+
WHITESPACE@13..14 " "
19+
TYPE_BOUND_LIST@14..24
20+
TYPE_BOUND@14..16
21+
LIFETIME@14..16
22+
LIFETIME_IDENT@14..16 "'a"
23+
WHITESPACE@16..17 " "
24+
PLUS@17..18 "+"
25+
WHITESPACE@18..19 " "
26+
TYPE_BOUND@19..24
27+
PATH_TYPE@19..24
28+
PATH@19..24
29+
PATH_SEGMENT@19..24
30+
NAME_REF@19..24
31+
IDENT@19..24 "Sized"
32+
R_PAREN@24..25 ")"
33+
WHITESPACE@25..26 " "
34+
BLOCK_EXPR@26..28
35+
STMT_LIST@26..28
36+
L_CURLY@26..27 "{"
37+
R_CURLY@27..28 "}"
38+
error 9..24: ambiguous `+` in a type
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn f(_: &impl 'a + Sized) {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
SOURCE_FILE@0..20
2+
FN@0..20
3+
FN_KW@0..2 "fn"
4+
WHITESPACE@2..3 " "
5+
NAME@3..4
6+
IDENT@3..4 "f"
7+
PARAM_LIST@4..17
8+
L_PAREN@4..5 "("
9+
PARAM@5..16
10+
WILDCARD_PAT@5..6
11+
UNDERSCORE@5..6 "_"
12+
COLON@6..7 ":"
13+
WHITESPACE@7..8 " "
14+
REF_TYPE@8..16
15+
AMP@8..9 "&"
16+
IMPL_TRAIT_TYPE@9..16
17+
IMPL_KW@9..13 "impl"
18+
WHITESPACE@13..14 " "
19+
TYPE_BOUND_LIST@14..16
20+
TYPE_BOUND@14..16
21+
LIFETIME@14..16
22+
LIFETIME_IDENT@14..16 "'a"
23+
R_PAREN@16..17 ")"
24+
WHITESPACE@17..18 " "
25+
BLOCK_EXPR@18..20
26+
STMT_LIST@18..20
27+
L_CURLY@18..19 "{"
28+
R_CURLY@19..20 "}"
29+
error 9..16: At least one trait must be specified
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn f(_: &impl 'a) {}

0 commit comments

Comments
 (0)