Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/expr_store/lower.rs')
-rw-r--r--crates/hir-def/src/expr_store/lower.rs38
1 files changed, 28 insertions, 10 deletions
diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs
index 5cbcfe5f23..181312bc0f 100644
--- a/crates/hir-def/src/expr_store/lower.rs
+++ b/crates/hir-def/src/expr_store/lower.rs
@@ -26,8 +26,8 @@ use stdx::never;
use syntax::{
AstNode, AstPtr, SyntaxNodePtr,
ast::{
- self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasAttrs, HasGenericArgs,
- HasGenericParams, HasLoopBody, HasName, HasTypeBounds, IsString, RangeItem,
+ self, ArrayExprKind, AstChildren, BlockExpr, ForBinder, HasArgList, HasAttrs,
+ HasGenericArgs, HasGenericParams, HasLoopBody, HasName, HasTypeBounds, IsString, RangeItem,
SlicePatComponents,
},
};
@@ -465,6 +465,8 @@ pub struct ExprCollector<'db> {
is_lowering_coroutine: bool,
+ for_type_binder: Option<ThinVec<Name>>,
+
/// Legacy (`macro_rules!`) macros can have multiple definitions and shadow each other,
/// and we need to find the current definition. So we track the number of definitions we saw.
current_block_legacy_macro_defs_count: FxHashMap<Name, usize>,
@@ -636,6 +638,7 @@ impl<'db> ExprCollector<'db> {
krate,
name_generator_index: 0,
named_lifetime_store: NamedLifetimeStore::default(),
+ for_type_binder: None,
};
result.store.inference_roots = Some(SmallVec::new());
result
@@ -758,16 +761,23 @@ impl<'db> ExprCollector<'db> {
let abi = inner.abi().map(lower_abi).unwrap_or(ExternAbi::Rust);
params.push((None, ret_ty));
+
+ let binder = self.for_type_binder.take().map(|b| b.into());
TypeRef::Fn(Box::new(FnType {
is_varargs,
is_unsafe: inner.unsafe_token().is_some(),
abi,
params: params.into_boxed_slice(),
+ binder,
}))
}
// for types are close enough for our purposes to the inner type for now...
ast::Type::ForType(inner) => {
- return self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn);
+ let binder = self.lower_for_binder_opt(inner.for_binder());
+ let old_for_binder = self.for_type_binder.replace(binder);
+ let ty = self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn);
+ self.for_type_binder = old_for_binder;
+ return ty;
}
ast::Type::ImplTraitType(inner) => {
if self.outer_impl_trait {
@@ -1245,13 +1255,7 @@ impl<'db> ExprCollector<'db> {
let Some(kind) = node.kind() else { return TypeBound::Error };
match kind {
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 binder = self.lower_for_binder_opt(binder);
let m = match node.question_mark_token() {
Some(_) => TraitBoundModifier::Maybe,
None => TraitBoundModifier::None,
@@ -1283,6 +1287,20 @@ impl<'db> ExprCollector<'db> {
}
}
+ fn lower_for_binder_opt(&mut self, binder: Option<ForBinder>) -> ThinVec<Name> {
+ binder.map(|b| self.lower_for_binder(b)).unwrap_or_default()
+ }
+
+ fn lower_for_binder(&mut self, binder: ForBinder) -> ThinVec<Name> {
+ match binder.generic_param_list() {
+ Some(gpl) => gpl
+ .lifetime_params()
+ .flat_map(|lp| lp.lifetime().map(|lt| Name::new_lifetime(&lt.text())))
+ .collect(),
+ None => ThinVec::default(),
+ }
+ }
+
fn lower_const_arg_opt(&mut self, arg: Option<ast::ConstArg>) -> ConstRef {
ConstRef {
expr: self.with_fresh_binding_expr_root(|this| {