Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-def/src/expr_store/lower.rs3
-rw-r--r--crates/hir-def/src/expr_store/tests/signatures.rs12
-rw-r--r--crates/syntax/src/ast/node_ext.rs11
3 files changed, 21 insertions, 5 deletions
diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs
index 0b2af134c8..e72de6d682 100644
--- a/crates/hir-def/src/expr_store/lower.rs
+++ b/crates/hir-def/src/expr_store/lower.rs
@@ -949,7 +949,8 @@ impl<'db> ExprCollector<'db> {
node: ast::TypeBound,
impl_trait_lower_fn: ImplTraitLowerFn<'_>,
) -> TypeBound {
- match node.kind() {
+ 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
diff --git a/crates/hir-def/src/expr_store/tests/signatures.rs b/crates/hir-def/src/expr_store/tests/signatures.rs
index 2dac4e7fc8..f1db00cf6a 100644
--- a/crates/hir-def/src/expr_store/tests/signatures.rs
+++ b/crates/hir-def/src/expr_store/tests/signatures.rs
@@ -197,3 +197,15 @@ fn allowed3(baz: impl Baz<Assoc = Qux<impl Foo>>) {}
"#]],
);
}
+
+#[test]
+fn regression_21138() {
+ lower_and_print(
+ r#"
+fn foo(v: for<'a> Trait1 + Trait2) {}
+ "#,
+ expect![[r#"
+ fn foo(dyn for<'a> Trait1 + Trait2) {...}
+ "#]],
+ );
+}
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 901d17bb14..b872221bf7 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -813,13 +813,16 @@ pub enum TypeBoundKind {
}
impl ast::TypeBound {
- pub fn kind(&self) -> TypeBoundKind {
+ pub fn kind(&self) -> Option<TypeBoundKind> {
if let Some(path_type) = support::children(self.syntax()).next() {
- TypeBoundKind::PathType(self.for_binder(), path_type)
+ Some(TypeBoundKind::PathType(self.for_binder(), path_type))
+ } else if let Some(for_binder) = support::children::<ast::ForType>(&self.syntax).next() {
+ let Some(ast::Type::PathType(path_type)) = for_binder.ty() else { return None };
+ Some(TypeBoundKind::PathType(for_binder.for_binder(), path_type))
} else if let Some(args) = self.use_bound_generic_args() {
- TypeBoundKind::Use(args)
+ Some(TypeBoundKind::Use(args))
} else if let Some(lifetime) = self.lifetime() {
- TypeBoundKind::Lifetime(lifetime)
+ Some(TypeBoundKind::Lifetime(lifetime))
} else {
unreachable!()
}