Skip to content

Commit 9413ad3

Browse files
committed
minor: Simplify impl-ty parse validation
1 parent 749fde9 commit 9413ad3

File tree

1 file changed

+52
-42
lines changed

1 file changed

+52
-42
lines changed

Diff for: crates/syntax/src/validation.rs

+52-42
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ pub(crate) fn validate(root: &SyntaxNode, errors: &mut Vec<SyntaxError>) {
3737
ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, errors),
3838
ast::MacroRules(it) => validate_macro_rules(it, errors),
3939
ast::LetExpr(it) => validate_let_expr(it, errors),
40-
ast::ImplTraitType(it) => validate_impl_object_ty(it, errors),
4140
_ => (),
4241
}
4342
}
@@ -316,26 +315,50 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro
316315
}
317316

318317
fn validate_trait_object_ref_ty(ty: ast::RefType, errors: &mut Vec<SyntaxError>) {
319-
if let Some(ast::Type::DynTraitType(ty)) = ty.ty() {
320-
if let Some(err) = validate_trait_object_ty(ty) {
321-
errors.push(err);
318+
match ty.ty() {
319+
Some(ast::Type::DynTraitType(ty)) => {
320+
if let Some(err) = validate_trait_object_ty(ty) {
321+
errors.push(err);
322+
}
323+
}
324+
Some(ast::Type::ImplTraitType(ty)) => {
325+
if let Some(err) = validate_impl_object_ty(ty) {
326+
errors.push(err);
327+
}
322328
}
329+
_ => (),
323330
}
324331
}
325332

326333
fn validate_trait_object_ptr_ty(ty: ast::PtrType, errors: &mut Vec<SyntaxError>) {
327-
if let Some(ast::Type::DynTraitType(ty)) = ty.ty() {
328-
if let Some(err) = validate_trait_object_ty(ty) {
329-
errors.push(err);
334+
match ty.ty() {
335+
Some(ast::Type::DynTraitType(ty)) => {
336+
if let Some(err) = validate_trait_object_ty(ty) {
337+
errors.push(err);
338+
}
330339
}
340+
Some(ast::Type::ImplTraitType(ty)) => {
341+
if let Some(err) = validate_impl_object_ty(ty) {
342+
errors.push(err);
343+
}
344+
}
345+
_ => (),
331346
}
332347
}
333348

334349
fn validate_trait_object_fn_ptr_ret_ty(ty: ast::FnPtrType, errors: &mut Vec<SyntaxError>) {
335-
if let Some(ast::Type::DynTraitType(ty)) = ty.ret_type().and_then(|ty| ty.ty()) {
336-
if let Some(err) = validate_trait_object_ty(ty) {
337-
errors.push(err);
350+
match ty.ret_type().and_then(|ty| ty.ty()) {
351+
Some(ast::Type::DynTraitType(ty)) => {
352+
if let Some(err) = validate_trait_object_ty(ty) {
353+
errors.push(err);
354+
}
355+
}
356+
Some(ast::Type::ImplTraitType(ty)) => {
357+
if let Some(err) = validate_impl_object_ty(ty) {
358+
errors.push(err);
359+
}
338360
}
361+
_ => (),
339362
}
340363
}
341364

@@ -353,6 +376,7 @@ fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> {
353376
let preceding_token =
354377
algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?;
355378

379+
// FIXME: This is not a validation error, this is a context dependent parse error
356380
if !matches!(preceding_token.kind(), T!['('] | T![<] | T![=]) {
357381
return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range()));
358382
}
@@ -362,41 +386,27 @@ fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> {
362386
}
363387
}
364388

365-
fn validate_impl_object_ty(ty: ast::ImplTraitType, errors: &mut Vec<SyntaxError>) {
366-
let Some(bound_list) = ty.type_bound_list() else {
367-
errors.push(SyntaxError::new(
368-
"At least one trait must be specified",
369-
ty.syntax().text_range(),
370-
));
371-
return;
372-
};
373-
374-
let bounds: Vec<_> = bound_list.bounds().collect();
389+
fn validate_impl_object_ty(ty: ast::ImplTraitType) -> Option<SyntaxError> {
390+
let tbl = ty.type_bound_list()?;
391+
let bounds_count = tbl.bounds().count();
375392

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",
393+
match bounds_count {
394+
0 => Some(SyntaxError::new(
395+
"At least one trait is required for an object type",
379396
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-
};
397+
)),
398+
_ if bounds_count > 1 => {
399+
let impl_token = ty.impl_token()?;
400+
let preceding_token =
401+
algo::skip_trivia_token(impl_token.prev_token()?, Direction::Prev)?;
395402

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()));
403+
// FIXME: This is not a validation error, this is a context dependent parse error
404+
if !matches!(preceding_token.kind(), T!['('] | T![<] | T![=]) {
405+
return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range()));
406+
}
407+
None
408+
}
409+
_ => None,
400410
}
401411
}
402412

0 commit comments

Comments
 (0)