diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index 2dc86411e4..0377e7c0e6 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs @@ -315,10 +315,21 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec) { - if let Some(ast::Type::DynTraitType(ty)) = ty.ty() { - if let Some(err) = validate_trait_object_ty(ty) { - errors.push(err); + match ty.ty() { + Some(ast::Type::DynTraitType(ty)) => { + if let Some(err) = validate_trait_object_ty(ty) { + 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(), + )); + } + } + _ => {} } } diff --git a/crates/syntax/test_data/parser/validation/dangling_impl.rast b/crates/syntax/test_data/parser/validation/dangling_impl.rast new file mode 100644 index 0000000000..dbe6535ac6 --- /dev/null +++ b/crates/syntax/test_data/parser/validation/dangling_impl.rast @@ -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 diff --git a/crates/syntax/test_data/parser/validation/dangling_impl.rs b/crates/syntax/test_data/parser/validation/dangling_impl.rs new file mode 100644 index 0000000000..0b440b4c5a --- /dev/null +++ b/crates/syntax/test_data/parser/validation/dangling_impl.rs @@ -0,0 +1 @@ +fn f(_: &impl) {} \ No newline at end of file