Add dangling impl

- Adds dangling impl diagnostics
- Rename validation test from dangling_impl to dangling_iml_ref
This commit is contained in:
bit-aloo 2025-03-03 15:58:33 +05:30
parent 0b97ae26bf
commit af959f9031
No known key found for this signature in database
GPG key ID: 02911B24FDAE81DA
5 changed files with 54 additions and 31 deletions

View file

@ -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::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, errors),
ast::MacroRules(it) => validate_macro_rules(it, errors), ast::MacroRules(it) => validate_macro_rules(it, errors),
ast::LetExpr(it) => validate_let_expr(it, errors), ast::LetExpr(it) => validate_let_expr(it, errors),
ast::ImplTraitType(it) => validate_impl_object_ty(it, errors),
_ => (), _ => (),
} }
} }
@ -315,21 +316,10 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro
} }
fn validate_trait_object_ref_ty(ty: ast::RefType, errors: &mut Vec<SyntaxError>) { fn validate_trait_object_ref_ty(ty: ast::RefType, errors: &mut Vec<SyntaxError>) {
match ty.ty() { if let Some(ast::Type::DynTraitType(ty)) = ty.ty() {
Some(ast::Type::DynTraitType(ty)) => { if let Some(err) = validate_trait_object_ty(ty) {
if let Some(err) = validate_trait_object_ty(ty) { errors.push(err);
errors.push(err);
}
} }
Some(ast::Type::ImplTraitType(ty)) => {
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(),
));
}
}
_ => {}
} }
} }
@ -372,6 +362,15 @@ 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 {
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>) { fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec<SyntaxError>) {
if let Some(vis) = mac.visibility() { if let Some(vis) = mac.visibility() {
errors.push(SyntaxError::new( errors.push(SyntaxError::new(

View file

@ -1,25 +1,23 @@
SOURCE_FILE@0..17 SOURCE_FILE@0..16
FN@0..17 FN@0..16
FN_KW@0..2 "fn" FN_KW@0..2 "fn"
WHITESPACE@2..3 " " WHITESPACE@2..3 " "
NAME@3..4 NAME@3..4
IDENT@3..4 "f" IDENT@3..4 "f"
PARAM_LIST@4..14 PARAM_LIST@4..13
L_PAREN@4..5 "(" L_PAREN@4..5 "("
PARAM@5..13 PARAM@5..12
WILDCARD_PAT@5..6 WILDCARD_PAT@5..6
UNDERSCORE@5..6 "_" UNDERSCORE@5..6 "_"
COLON@6..7 ":" COLON@6..7 ":"
WHITESPACE@7..8 " " WHITESPACE@7..8 " "
REF_TYPE@8..13 IMPL_TRAIT_TYPE@8..12
AMP@8..9 "&" IMPL_KW@8..12 "impl"
IMPL_TRAIT_TYPE@9..13 TYPE_BOUND_LIST@12..12
IMPL_KW@9..13 "impl" R_PAREN@12..13 ")"
TYPE_BOUND_LIST@13..13 WHITESPACE@13..14 " "
R_PAREN@13..14 ")" BLOCK_EXPR@14..16
WHITESPACE@14..15 " " STMT_LIST@14..16
BLOCK_EXPR@15..17 L_CURLY@14..15 "{"
STMT_LIST@15..17 R_CURLY@15..16 "}"
L_CURLY@15..16 "{" error 8..12: At least one trait must be specified
R_CURLY@16..17 "}"
error 9..13: At least one trait must be specified

View file

@ -1 +1 @@
fn f(_: &impl) {} fn f(_: impl) {}

View file

@ -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

View file

@ -0,0 +1 @@
fn f(_: &impl) {}