diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs index 06686b6a16..5c06234fa0 100644 --- a/crates/hir-ty/src/lower/path.rs +++ b/crates/hir-ty/src/lower/path.rs @@ -1018,8 +1018,12 @@ fn check_generic_args_len( } let lifetime_args_len = def_generics.len_lifetimes_self(); - if provided_lifetimes_count == 0 && lifetime_args_len > 0 && !lowering_assoc_type_generics { - // In generic associated types, we never allow inferring the lifetimes. + if provided_lifetimes_count == 0 + && lifetime_args_len > 0 + && (!lowering_assoc_type_generics || infer_args) + { + // In generic associated types, we never allow inferring the lifetimes, but only in type context, that is + // when `infer_args == false`. In expression/pattern context we always allow inferring them, even for GATs. match lifetime_elision { &LifetimeElisionKind::AnonymousCreateParameter { report_in_path } => { ctx.report_elided_lifetimes_in_path(def, lifetime_args_len as u32, report_in_path); diff --git a/crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs b/crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs index 06f3575942..7402133f74 100644 --- a/crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs +++ b/crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs @@ -183,4 +183,28 @@ fn main() { "#, ); } + + #[test] + fn generic_assoc_type_infer_lifetime_in_expr_position() { + check_diagnostics( + r#" +//- minicore: sized +struct Player; + +struct Foo<'c, C> { + _v: &'c C, +} +trait WithSignals: Sized { + type SignalCollection<'c, C>; + fn __signals_from_external(&self) -> Self::SignalCollection<'_, Self>; +} +impl WithSignals for Player { + type SignalCollection<'c, C> = Foo<'c, C>; + fn __signals_from_external(&self) -> Self::SignalCollection<'_, Self> { + Self::SignalCollection { _v: self } + } +} + "#, + ); + } }