Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/method_resolution/confirm.rs')
| -rw-r--r-- | crates/hir-ty/src/method_resolution/confirm.rs | 91 |
1 files changed, 52 insertions, 39 deletions
diff --git a/crates/hir-ty/src/method_resolution/confirm.rs b/crates/hir-ty/src/method_resolution/confirm.rs index 94c70c29f7..c425e69dc5 100644 --- a/crates/hir-ty/src/method_resolution/confirm.rs +++ b/crates/hir-ty/src/method_resolution/confirm.rs @@ -2,9 +2,10 @@ //! is valid and registering all obligations. use hir_def::{ - FunctionId, GenericDefId, GenericParamId, ItemContainerId, TraitId, + FunctionId, GenericDefId, GenericParamId, TraitId, expr_store::path::{GenericArg as HirGenericArg, GenericArgs as HirGenericArgs}, hir::{ExprId, generics::GenericParamDataRef}, + type_ref::TypeRefId, }; use rustc_type_ir::{ TypeFoldable, @@ -15,9 +16,9 @@ use tracing::debug; use crate::{ Adjust, Adjustment, AutoBorrow, IncorrectGenericsLenKind, InferenceDiagnostic, - LifetimeElisionKind, PointerCast, + LifetimeElisionKind, PointerCast, Span, db::HirDatabase, - infer::{AllowTwoPhase, AutoBorrowMutability, InferenceContext, TypeMismatch}, + infer::{AllowTwoPhase, AutoBorrowMutability, InferenceContext}, lower::{ GenericPredicates, path::{GenericArgsLowerer, TypeLikeConst, substs_from_args_and_bindings}, @@ -26,7 +27,7 @@ use crate::{ next_solver::{ Binder, Clause, ClauseKind, Const, DbInterner, EarlyParamRegion, ErrorGuaranteed, FnSig, GenericArg, GenericArgs, ParamConst, PolyExistentialTraitRef, PolyTraitRef, Region, - TraitRef, Ty, TyKind, + TraitRef, Ty, TyKind, Unnormalized, infer::{ BoundRegionConversionTime, InferCtxt, traits::{ObligationCause, PredicateObligation}, @@ -38,7 +39,7 @@ use crate::{ struct ConfirmContext<'a, 'b, 'db> { ctx: &'a mut InferenceContext<'b, 'db>, candidate: FunctionId, - expr: ExprId, + call_expr: ExprId, } #[derive(Debug)] @@ -73,9 +74,9 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { fn new( ctx: &'a mut InferenceContext<'b, 'db>, candidate: FunctionId, - expr: ExprId, + call_expr: ExprId, ) -> ConfirmContext<'a, 'b, 'db> { - ConfirmContext { ctx, candidate, expr } + ConfirmContext { ctx, candidate, call_expr } } #[inline] @@ -136,7 +137,8 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { ); let illegal_sized_bound = self.predicates_require_illegal_sized_bound( GenericPredicates::query_all(self.db(), self.candidate.into()) - .iter_instantiated(self.interner(), filler_args.as_slice()), + .iter_instantiated(self.interner(), filler_args.as_slice()) + .map(Unnormalized::skip_norm_wip), ); // Unify the (adjusted) self type with what the method expects. @@ -180,7 +182,8 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { ) -> (Ty<'db>, Box<[Adjustment]>) { // Commit the autoderefs by calling `autoderef` again, but this // time writing the results into the various typeck results. - let mut autoderef = self.ctx.table.autoderef_with_tracking(unadjusted_self_ty); + let mut autoderef = + self.ctx.table.autoderef_with_tracking(unadjusted_self_ty, self.call_expr.into()); let Some((mut target, n)) = autoderef.nth(pick.autoderefs) else { return (Ty::new_error(self.interner(), ErrorGuaranteed), Box::new([])); }; @@ -190,7 +193,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { self.ctx.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok()); match pick.autoref_or_ptr_adjustment { Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, unsize }) => { - let region = self.infcx().next_region_var(); + let region = self.infcx().next_region_var(self.call_expr.into()); // Type we're wrapping in a reference, used later for unsizing let base_ty = target; @@ -254,7 +257,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { ) -> GenericArgs<'db> { match pick.kind { probe::InherentImplPick(impl_def_id) => { - self.infcx().fresh_args_for_item(impl_def_id.into()) + self.infcx().fresh_args_for_item(self.call_expr.into(), impl_def_id.into()) } probe::ObjectPick(trait_def_id) => { @@ -296,7 +299,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { // the process we will unify the transformed-self-type // of the method with the actual type in order to // unify some of these variables. - self.infcx().fresh_args_for_item(trait_def_id.into()) + self.infcx().fresh_args_for_item(self.call_expr.into(), trait_def_id.into()) } probe::WhereClausePick(poly_trait_ref) => { @@ -316,12 +319,11 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { // yield an object-type (e.g., `&Object` or `Box<Object>` // etc). - let mut autoderef = self.ctx.table.autoderef(self_ty); + let mut autoderef = self.ctx.table.autoderef(self_ty, self.call_expr.into()); // We don't need to gate this behind arbitrary self types // per se, but it does make things a bit more gated. - if self.ctx.unstable_features.arbitrary_self_types - || self.ctx.unstable_features.arbitrary_self_types_pointers + if self.ctx.features.arbitrary_self_types || self.ctx.features.arbitrary_self_types_pointers { autoderef = autoderef.use_receiver_trait(); } @@ -401,8 +403,8 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { let GenericParamId::ConstParamId(const_id) = param_id else { unreachable!("non-const param ID for const param"); }; - let const_ty = self.ctx.db.const_param_ty_ns(const_id); - self.ctx.make_body_const(*konst, const_ty).into() + let const_ty = self.ctx.db.const_param_ty(const_id); + self.ctx.create_body_anon_const(konst.expr, const_ty, false).into() } _ => unreachable!("unmatching param kinds were passed to `provided_kind()`"), } @@ -410,12 +412,13 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { fn provided_type_like_const( &mut self, - const_ty: Ty<'db>, + _type_ref: TypeRefId, + _const_ty: Ty<'db>, arg: TypeLikeConst<'_>, ) -> Const<'db> { match arg { - TypeLikeConst::Path(path) => self.ctx.make_path_as_body_const(path, const_ty), - TypeLikeConst::Infer => self.ctx.table.next_const_var(), + TypeLikeConst::Path(path) => self.ctx.make_path_as_body_const(path), + TypeLikeConst::Infer => self.ctx.table.next_const_var(Span::Dummy), } } @@ -424,12 +427,15 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { _def: GenericDefId, param_id: GenericParamId, _param: GenericParamDataRef<'_>, - _infer_args: bool, + infer_args: bool, _preceding_args: &[GenericArg<'db>], + had_count_error: bool, ) -> GenericArg<'db> { // Always create an inference var, even when `infer_args == false`. This helps with diagnostics, // and I think it's also required in the presence of `impl Trait` (that must be inferred). - self.ctx.table.next_var_for_param(param_id) + let span = + if !infer_args || had_count_error { Span::Dummy } else { self.expr.into() }; + self.ctx.table.var_for_def(param_id, span) } fn parent_arg(&mut self, param_idx: u32, _param_id: GenericParamId) -> GenericArg<'db> { @@ -463,7 +469,11 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { LifetimeElisionKind::Infer, false, None, - &mut LowererCtx { ctx: self.ctx, expr: self.expr, parent_args: parent_args.as_slice() }, + &mut LowererCtx { + ctx: self.ctx, + expr: self.call_expr, + parent_args: parent_args.as_slice(), + }, ) } @@ -477,17 +487,14 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { "unify_receivers: self_ty={:?} method_self_ty={:?} pick={:?}", self_ty, method_self_ty, pick ); - let cause = ObligationCause::new(); + let cause = ObligationCause::new(self.call_expr); match self.ctx.table.at(&cause).sup(method_self_ty, self_ty) { Ok(infer_ok) => { self.ctx.table.register_infer_ok(infer_ok); } Err(_) => { - if self.ctx.unstable_features.arbitrary_self_types { - self.ctx.result.type_mismatches.get_or_insert_default().insert( - self.expr.into(), - TypeMismatch { expected: method_self_ty.store(), actual: self_ty.store() }, - ); + if self.ctx.features.arbitrary_self_types { + self.ctx.emit_type_mismatch(self.call_expr.into(), method_self_ty, self_ty); } } } @@ -509,13 +516,17 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { let def_id = self.candidate; let method_predicates = clauses_as_obligations( GenericPredicates::query_all(self.db(), def_id.into()) - .iter_instantiated(self.interner(), all_args), - ObligationCause::new(), + .iter_instantiated(self.interner(), all_args) + .map(Unnormalized::skip_norm_wip), + ObligationCause::new(self.call_expr), self.ctx.table.param_env, ); - let sig = - self.db().callable_item_signature(def_id.into()).instantiate(self.interner(), all_args); + let sig = self + .db() + .callable_item_signature(def_id.into()) + .instantiate(self.interner(), all_args) + .skip_norm_wip(); debug!("type scheme instantiated, sig={:?}", sig); let sig = self.instantiate_binder_with_fresh_vars(sig); @@ -536,13 +547,13 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { // this is a projection from a trait reference, so we have to // make sure that the trait reference inputs are well-formed. - self.ctx.table.add_wf_bounds(all_args); + self.ctx.table.add_wf_bounds(self.call_expr.into(), all_args); // the function type must also be well-formed (this is not // implied by the args being well-formed because of inherent // impls and late-bound regions - see issue #28609). for ty in sig.inputs_and_output { - self.ctx.table.register_wf_obligation(ty.into(), ObligationCause::new()); + self.ctx.table.register_wf_obligation(ty.into(), ObligationCause::new(self.call_expr)); } } @@ -570,9 +581,7 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { fn check_for_illegal_method_calls(&self) { // Disallow calls to the method `drop` defined in the `Drop` trait. - if let ItemContainerId::TraitId(trait_def_id) = self.candidate.loc(self.db()).container - && self.ctx.lang_items.Drop.is_some_and(|drop_trait| drop_trait == trait_def_id) - { + if self.ctx.lang_items.Drop_drop.is_some_and(|drop_fn| drop_fn == self.candidate) { // FIXME: Report an error. } } @@ -610,6 +619,10 @@ impl<'a, 'b, 'db> ConfirmContext<'a, 'b, 'db> { where T: TypeFoldable<DbInterner<'db>> + Copy, { - self.infcx().instantiate_binder_with_fresh_vars(BoundRegionConversionTime::FnCall, value) + self.infcx().instantiate_binder_with_fresh_vars( + self.call_expr.into(), + BoundRegionConversionTime::FnCall, + value, + ) } } |