From d9046fe9f4ca62a1767ce1ef368fb463e8aa210d Mon Sep 17 00:00:00 2001 From: Shoyu Vanilla Date: Sun, 19 Apr 2026 21:14:46 +0900 Subject: [PATCH] Sync function call args check fudging with rustc --- .../crates/hir-ty/src/infer/expr.rs | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index 06615cb691ab..e494fa813f51 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -35,7 +35,8 @@ lower::{GenericPredicates, lower_mutability}, method_resolution::{self, CandidateId, MethodCallee, MethodError}, next_solver::{ - ErrorGuaranteed, FnSig, GenericArg, GenericArgs, TraitRef, Ty, TyKind, TypeError, + ClauseKind, ErrorGuaranteed, FnSig, GenericArg, GenericArgs, TraitRef, Ty, TyKind, + TypeError, infer::{ BoundRegionConversionTime, InferOk, traits::{Obligation, ObligationCause}, @@ -1898,6 +1899,15 @@ pub(in super::super) fn check_call_arguments( // Whether the function is variadic, for example when imported from C c_variadic: bool, ) { + let formal_input_tys: Vec<_> = formal_input_tys + .iter() + .map(|&ty| { + let generalized_ty = self.table.next_ty_var(); + let _ = self.demand_eqtype(call_expr.into(), ty, generalized_ty); + generalized_ty + }) + .collect(); + // First, let's unify the formal method signature with the expectation eagerly. // We use this to guide coercion inference; it's output is "fudged" which means // any remaining type variables are assigned to new, unrelated variables. This @@ -1917,18 +1927,23 @@ pub(in super::super) fn check_call_arguments( // No argument expectations are produced if unification fails. let origin = ObligationCause::new(); ocx.sup(&origin, self.table.param_env, expected_output, formal_output)?; + + for &ty in &formal_input_tys { + ocx.register_obligation(Obligation::new( + self.interner(), + ObligationCause::new(), + self.table.param_env, + ClauseKind::WellFormed(ty.into()), + )); + } + if !ocx.try_evaluate_obligations().is_empty() { return Err(TypeError::Mismatch); } // Record all the argument types, with the args // produced from the above subtyping unification. - Ok(Some( - formal_input_tys - .iter() - .map(|&ty| self.table.infer_ctxt.resolve_vars_if_possible(ty)) - .collect(), - )) + Ok(Some(formal_input_tys.clone())) }) .ok() }) @@ -1939,7 +1954,7 @@ pub(in super::super) fn check_call_arguments( assert_eq!(expected_input_tys.len(), formal_input_tys.len()); expected_input_tys } else { - formal_input_tys + &formal_input_tys }; let minimum_input_count = expected_input_tys.len();