Parse for<'a> [const]

And also refactor parsing of HRTB.
This commit is contained in:
Chayim Refael Friedman 2025-07-22 16:24:42 +03:00
parent 0d4f56de04
commit c7ceb39f67
28 changed files with 465 additions and 354 deletions

View file

@ -960,37 +960,28 @@ impl ExprCollector<'_> {
impl_trait_lower_fn: ImplTraitLowerFn<'_>,
) -> TypeBound {
match node.kind() {
ast::TypeBoundKind::PathType(path_type) => {
let m = match node.question_mark_token() {
Some(_) => TraitBoundModifier::Maybe,
None => TraitBoundModifier::None,
};
self.lower_path_type(&path_type, impl_trait_lower_fn)
.map(|p| {
TypeBound::Path(self.alloc_path(p, AstPtr::new(&path_type).upcast()), m)
})
.unwrap_or(TypeBound::Error)
}
ast::TypeBoundKind::ForType(for_type) => {
let lt_refs = match for_type.generic_param_list() {
ast::TypeBoundKind::PathType(binder, path_type) => {
let binder = match binder.and_then(|it| it.generic_param_list()) {
Some(gpl) => gpl
.lifetime_params()
.flat_map(|lp| lp.lifetime().map(|lt| Name::new_lifetime(&lt.text())))
.collect(),
None => ThinVec::default(),
};
let path = for_type.ty().and_then(|ty| match &ty {
ast::Type::PathType(path_type) => {
self.lower_path_type(path_type, impl_trait_lower_fn).map(|p| (p, ty))
}
_ => None,
});
match path {
Some((p, ty)) => {
TypeBound::ForLifetime(lt_refs, self.alloc_path(p, AstPtr::new(&ty)))
}
None => TypeBound::Error,
}
let m = match node.question_mark_token() {
Some(_) => TraitBoundModifier::Maybe,
None => TraitBoundModifier::None,
};
self.lower_path_type(&path_type, impl_trait_lower_fn)
.map(|p| {
let path = self.alloc_path(p, AstPtr::new(&path_type).upcast());
if binder.is_empty() {
TypeBound::Path(path, m)
} else {
TypeBound::ForLifetime(binder, path)
}
})
.unwrap_or(TypeBound::Error)
}
ast::TypeBoundKind::Use(gal) => TypeBound::Use(
gal.use_bound_generic_args()

View file

@ -180,17 +180,18 @@ impl GenericParamsCollector {
continue;
};
let lifetimes: Option<Box<_>> = pred.generic_param_list().map(|param_list| {
// Higher-Ranked Trait Bounds
param_list
.lifetime_params()
.map(|lifetime_param| {
lifetime_param
.lifetime()
.map_or_else(Name::missing, |lt| Name::new_lifetime(&lt.text()))
})
.collect()
});
let lifetimes: Option<Box<_>> =
pred.for_binder().and_then(|it| it.generic_param_list()).map(|param_list| {
// Higher-Ranked Trait Bounds
param_list
.lifetime_params()
.map(|lifetime_param| {
lifetime_param
.lifetime()
.map_or_else(Name::missing, |lt| Name::new_lifetime(&lt.text()))
})
.collect()
});
for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
self.lower_type_bound_as_predicate(ec, bound, lifetimes.as_deref(), target);
}