From cd064e764d576f962a56b80e1a434cf160de060e Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 24 Apr 2025 07:34:04 +0200 Subject: [PATCH 1/2] fix: Fix type argument mismatch incorrectly triggering on inferred trait args --- .../rust-analyzer/crates/hir-ty/src/infer/path.rs | 2 +- src/tools/rust-analyzer/crates/hir-ty/src/lower.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/lower/path.rs | 7 +++++-- .../src/handlers/incorrect_generics_len.rs | 12 ++++++++++++ 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index bdaec615ac8c..88638d1ae915 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -207,7 +207,7 @@ impl InferenceContext<'_> { (TypeNs::TraitId(trait_), true) => { let self_ty = self.table.new_type_var(); let trait_ref = - path_ctx.lower_trait_ref_from_resolved_path(trait_, self_ty); + path_ctx.lower_trait_ref_from_resolved_path(trait_, self_ty, true); drop_ctx(ctx, no_diagnostics); self.resolve_trait_assoc_item(trait_ref, last_segment, id) } diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index eecca3224051..740882521cd1 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -538,7 +538,7 @@ impl<'a> TyLoweringContext<'a> { TypeNs::TraitId(tr) => tr, _ => return None, }; - Some((ctx.lower_trait_ref_from_resolved_path(resolved, explicit_self_ty), ctx)) + Some((ctx.lower_trait_ref_from_resolved_path(resolved, explicit_self_ty, false), ctx)) } fn lower_trait_ref( diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index d3ca438d6e1b..6b71e98b0323 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs @@ -166,6 +166,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { let trait_ref = self.lower_trait_ref_from_resolved_path( trait_, TyKind::Error.intern(Interner), + infer_args, ); self.skip_resolved_segment(); @@ -830,8 +831,9 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { &mut self, resolved: TraitId, explicit_self_ty: Ty, + infer_args: bool, ) -> TraitRef { - let substs = self.trait_ref_substs_from_path(resolved, explicit_self_ty); + let substs = self.trait_ref_substs_from_path(resolved, explicit_self_ty, infer_args); TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs } } @@ -839,8 +841,9 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { &mut self, resolved: TraitId, explicit_self_ty: Ty, + infer_args: bool, ) -> Substitution { - self.substs_from_path_segment(resolved.into(), false, Some(explicit_self_ty), false) + self.substs_from_path_segment(resolved.into(), infer_args, Some(explicit_self_ty), false) } pub(super) fn assoc_type_bindings_from_type_bound<'c>( diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs index 8244f303d964..17c7f75880c9 100644 --- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs +++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/incorrect_generics_len.rs @@ -172,4 +172,16 @@ fn foo = bool>>() {} "#, ); } + + #[test] + fn regression_19669() { + check_diagnostics( + r#" +//- minicore: from +fn main() { + let _: i32 = Into::into(0); +} +"#, + ); + } } From de082127d8d2e50f0df29e44ce4921d5bd404ec9 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 24 Apr 2025 09:06:04 +0300 Subject: [PATCH 2/2] Correctly set `infer_args = true` in more places Previously this being incorrect wasn't a problem, it just meant we put an error type that then changed to infer type, so exactly what rustc does at the end. But now there is a diagnostic. --- src/tools/rust-analyzer/crates/hir-ty/src/infer.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/infer/path.rs | 2 +- src/tools/rust-analyzer/crates/hir-ty/src/lower.rs | 2 +- .../rust-analyzer/crates/hir-ty/src/lower/path.rs | 12 +++++++----- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 38807b6f7207..228e67a60f41 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -1675,7 +1675,7 @@ impl<'a> InferenceContext<'a> { // `lower_partly_resolved_path()` returns `None` as type namespace unless // `remaining_segments` is empty, which is never the case here. We don't know // which namespace the new `ty` is in until normalized anyway. - (ty, _) = path_ctx.lower_partly_resolved_path(resolution, false); + (ty, _) = path_ctx.lower_partly_resolved_path(resolution, true); tried_resolving_once = true; ty = self.table.insert_type_vars(ty); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs index 88638d1ae915..9d4bbe53464d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/path.rs @@ -177,7 +177,7 @@ impl InferenceContext<'_> { let ty = self.table.normalize_associated_types_in(ty); path_ctx.ignore_last_segment(); - let (ty, _) = path_ctx.lower_ty_relative_path(ty, orig_ns); + let (ty, _) = path_ctx.lower_ty_relative_path(ty, orig_ns, true); drop_ctx(ctx, no_diagnostics); let ty = self.table.insert_type_vars(ty); let ty = self.table.normalize_associated_types_in(ty); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs index 740882521cd1..34524668499a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower.rs @@ -508,7 +508,7 @@ impl<'a> TyLoweringContext<'a> { if let Some(type_ref) = path.type_anchor() { let (ty, res) = self.lower_ty_ext(type_ref); let mut ctx = self.at_path(path_id); - return ctx.lower_ty_relative_path(ty, res); + return ctx.lower_ty_relative_path(ty, res, false); } let mut ctx = self.at_path(path_id); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs index 6b71e98b0323..e01e8ea0ba1a 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/lower/path.rs @@ -137,12 +137,13 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { ty: Ty, // We need the original resolution to lower `Self::AssocTy` correctly res: Option, + infer_args: bool, ) -> (Ty, Option) { match self.segments.len() - self.current_segment_idx { 0 => (ty, res), 1 => { // resolve unselected assoc types - (self.select_associated_type(res), None) + (self.select_associated_type(res, infer_args), None) } _ => { // FIXME report error (ambiguous associated type) @@ -182,7 +183,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { // this point (`trait_ref.substitution`). let substitution = self.substs_from_path_segment( associated_ty.into(), - false, + infer_args, None, true, ); @@ -277,7 +278,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { }; self.skip_resolved_segment(); - self.lower_ty_relative_path(ty, Some(resolution)) + self.lower_ty_relative_path(ty, Some(resolution), infer_args) } fn handle_type_ns_resolution(&mut self, resolution: &TypeNs) { @@ -473,7 +474,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { Some(res) } - fn select_associated_type(&mut self, res: Option) -> Ty { + fn select_associated_type(&mut self, res: Option, infer_args: bool) -> Ty { let Some(res) = res else { return TyKind::Error.intern(Interner); }; @@ -507,7 +508,8 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> { // generic params. It's inefficient to splice the `Substitution`s, so we may want // that method to optionally take parent `Substitution` as we already know them at // this point (`t.substitution`). - let substs = self.substs_from_path_segment(associated_ty.into(), false, None, true); + let substs = + self.substs_from_path_segment(associated_ty.into(), infer_args, None, true); let substs = Substitution::from_iter( Interner,