Skip to content

Commit dcabe2b

Browse files
authored
Merge pull request #20787 from ChayimFriedman2/fix-type-alias-enum
fix: Fix erroneous diagnostic incorrect_generics_len when there are generics on enum variant used through type alias
2 parents 378ea41 + 797ba9c commit dcabe2b

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

crates/hir-ty/src/infer/path.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,23 @@ impl<'db> InferenceContext<'_, 'db> {
9595
return Some(ValuePathResolution::NonGeneric(ty));
9696
};
9797

98-
let substs = self.with_body_ty_lowering(|ctx| {
99-
let mut path_ctx = ctx.at_path(path, id);
100-
let last_segment = path.segments().len().checked_sub(1);
101-
if let Some(last_segment) = last_segment {
102-
path_ctx.set_current_segment(last_segment)
103-
}
104-
path_ctx.substs_from_path(value_def, true, false)
105-
});
98+
let substs = if self_subst.is_some_and(|it| !it.is_empty())
99+
&& matches!(value_def, ValueTyDefId::EnumVariantId(_))
100+
{
101+
// This is something like `TypeAlias::<Args>::EnumVariant`. Do not call `substs_from_path()`,
102+
// as it'll try to re-lower the previous segment assuming it refers to the enum, but it refers
103+
// to the type alias and they may have different generics.
104+
self.types.empty_args
105+
} else {
106+
self.with_body_ty_lowering(|ctx| {
107+
let mut path_ctx = ctx.at_path(path, id);
108+
let last_segment = path.segments().len().checked_sub(1);
109+
if let Some(last_segment) = last_segment {
110+
path_ctx.set_current_segment(last_segment)
111+
}
112+
path_ctx.substs_from_path(value_def, true, false)
113+
})
114+
};
106115

107116
let parent_substs_len = self_subst.map_or(0, |it| it.len());
108117
let substs = GenericArgs::fill_rest(

crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,23 @@ impl WithSignals for Player {
203203
fn __signals_from_external(&self) -> Self::SignalCollection<'_, Self> {
204204
Self::SignalCollection { _v: self }
205205
}
206+
}
207+
"#,
208+
);
209+
}
210+
211+
#[test]
212+
fn enum_type_alias_default_param() {
213+
check_diagnostics(
214+
r#"
215+
//- minicore: result
216+
217+
struct Error;
218+
219+
type Result<T, E = Error> = core::result::Result<T, E>;
220+
221+
fn main() {
222+
let _ = Result::<()>::Ok(());
206223
}
207224
"#,
208225
);

0 commit comments

Comments
 (0)