Rollup merge of #136066 - compiler-errors:local-spans, r=lcnr

Pass spans to `perform_locally_in_new_solver`

Nothing changes yet, but we may be able to use these spans in the future once we start dealing w the response region constraints better.

r? lcnr
This commit is contained in:
Matthias Krüger 2025-01-28 18:17:25 +01:00 committed by GitHub
commit 9f22f35876
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 34 additions and 20 deletions

View file

@ -310,7 +310,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
let (infcx, key, _) = let (infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query); mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?; type_op_ascribe_user_type_with_span(&ocx, key, cause.span).ok()?;
let diag = try_extract_error_from_fulfill_cx( let diag = try_extract_error_from_fulfill_cx(
&ocx, &ocx,
mbcx.mir_def_id(), mbcx.mir_def_id(),

View file

@ -90,6 +90,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
pub fn compute_dropck_outlives_inner<'tcx>( pub fn compute_dropck_outlives_inner<'tcx>(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
goal: ParamEnvAnd<'tcx, DropckOutlives<'tcx>>, goal: ParamEnvAnd<'tcx, DropckOutlives<'tcx>>,
span: Span,
) -> Result<DropckOutlivesResult<'tcx>, NoSolution> { ) -> Result<DropckOutlivesResult<'tcx>, NoSolution> {
let tcx = ocx.infcx.tcx; let tcx = ocx.infcx.tcx;
let ParamEnvAnd { param_env, value: DropckOutlives { dropped_ty } } = goal; let ParamEnvAnd { param_env, value: DropckOutlives { dropped_ty } } = goal;
@ -135,7 +136,7 @@ pub fn compute_dropck_outlives_inner<'tcx>(
// Set used to detect infinite recursion. // Set used to detect infinite recursion.
let mut ty_set = FxHashSet::default(); let mut ty_set = FxHashSet::default();
let cause = ObligationCause::dummy(); let cause = ObligationCause::dummy_with_span(span);
let mut constraints = DropckConstraint::empty(); let mut constraints = DropckConstraint::empty();
while let Some((ty, depth)) = ty_stack.pop() { while let Some((ty, depth)) = ty_stack.pop() {
debug!( debug!(

View file

@ -30,8 +30,9 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
fn perform_locally_with_next_solver( fn perform_locally_with_next_solver(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>, key: ParamEnvAnd<'tcx, Self>,
span: Span,
) -> Result<Self::QueryResponse, NoSolution> { ) -> Result<Self::QueryResponse, NoSolution> {
type_op_ascribe_user_type_with_span(ocx, key, None) type_op_ascribe_user_type_with_span(ocx, key, span)
} }
} }
@ -41,11 +42,10 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
pub fn type_op_ascribe_user_type_with_span<'tcx>( pub fn type_op_ascribe_user_type_with_span<'tcx>(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, AscribeUserType<'tcx>>, key: ParamEnvAnd<'tcx, AscribeUserType<'tcx>>,
span: Option<Span>, span: Span,
) -> Result<(), NoSolution> { ) -> Result<(), NoSolution> {
let (param_env, AscribeUserType { mir_ty, user_ty }) = key.into_parts(); let (param_env, AscribeUserType { mir_ty, user_ty }) = key.into_parts();
debug!("type_op_ascribe_user_type: mir_ty={:?} user_ty={:?}", mir_ty, user_ty); debug!("type_op_ascribe_user_type: mir_ty={:?} user_ty={:?}", mir_ty, user_ty);
let span = span.unwrap_or(DUMMY_SP);
match user_ty.kind { match user_ty.kind {
UserTypeKind::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?, UserTypeKind::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?,
UserTypeKind::TypeOf(def_id, user_args) => { UserTypeKind::TypeOf(def_id, user_args) => {

View file

@ -5,7 +5,7 @@ use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds;
use rustc_middle::infer::canonical::CanonicalQueryResponse; use rustc_middle::infer::canonical::CanonicalQueryResponse;
use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt}; use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt};
use rustc_span::DUMMY_SP; use rustc_span::Span;
use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::def_id::CRATE_DEF_ID;
use rustc_type_ir::outlives::{Component, push_outlives_components}; use rustc_type_ir::outlives::{Component, push_outlives_components};
use smallvec::{SmallVec, smallvec}; use smallvec::{SmallVec, smallvec};
@ -45,11 +45,12 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
fn perform_locally_with_next_solver( fn perform_locally_with_next_solver(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>, key: ParamEnvAnd<'tcx, Self>,
span: Span,
) -> Result<Self::QueryResponse, NoSolution> { ) -> Result<Self::QueryResponse, NoSolution> {
if ocx.infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat { if ocx.infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat {
compute_implied_outlives_bounds_inner(ocx, key.param_env, key.value.ty) compute_implied_outlives_bounds_inner(ocx, key.param_env, key.value.ty, span)
} else { } else {
compute_implied_outlives_bounds_compat_inner(ocx, key.param_env, key.value.ty) compute_implied_outlives_bounds_compat_inner(ocx, key.param_env, key.value.ty, span)
} }
} }
} }
@ -58,13 +59,14 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
span: Span,
) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> { ) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
let normalize_op = |ty| -> Result<_, NoSolution> { let normalize_op = |ty| -> Result<_, NoSolution> {
// We must normalize the type so we can compute the right outlives components. // We must normalize the type so we can compute the right outlives components.
// for example, if we have some constrained param type like `T: Trait<Out = U>`, // for example, if we have some constrained param type like `T: Trait<Out = U>`,
// and we know that `&'a T::Out` is WF, then we want to imply `U: 'a`. // and we know that `&'a T::Out` is WF, then we want to imply `U: 'a`.
let ty = ocx let ty = ocx
.deeply_normalize(&ObligationCause::dummy(), param_env, ty) .deeply_normalize(&ObligationCause::dummy_with_span(span), param_env, ty)
.map_err(|_| NoSolution)?; .map_err(|_| NoSolution)?;
if !ocx.select_all_or_error().is_empty() { if !ocx.select_all_or_error().is_empty() {
return Err(NoSolution); return Err(NoSolution);
@ -142,6 +144,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
span: Span,
) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> { ) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
let tcx = ocx.infcx.tcx; let tcx = ocx.infcx.tcx;
@ -171,8 +174,8 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
// FIXME(@lcnr): It's not really "always fine", having fewer implied // FIXME(@lcnr): It's not really "always fine", having fewer implied
// bounds can be backward incompatible, e.g. #101951 was caused by // bounds can be backward incompatible, e.g. #101951 was caused by
// us not dealing with inference vars in `TypeOutlives` predicates. // us not dealing with inference vars in `TypeOutlives` predicates.
let obligations = wf::obligations(ocx.infcx, param_env, CRATE_DEF_ID, 0, arg, DUMMY_SP) let obligations =
.unwrap_or_default(); wf::obligations(ocx.infcx, param_env, CRATE_DEF_ID, 0, arg, span).unwrap_or_default();
for obligation in obligations { for obligation in obligations {
debug!(?obligation); debug!(?obligation);
@ -255,7 +258,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
// Need to manually normalize in the new solver as `wf::obligations` does not. // Need to manually normalize in the new solver as `wf::obligations` does not.
if ocx.infcx.next_trait_solver() { if ocx.infcx.next_trait_solver() {
ty_a = ocx ty_a = ocx
.deeply_normalize(&ObligationCause::dummy(), param_env, ty_a) .deeply_normalize(&ObligationCause::dummy_with_span(span), param_env, ty_a)
.map_err(|_| NoSolution)?; .map_err(|_| NoSolution)?;
} }
let mut components = smallvec![]; let mut components = smallvec![];

View file

@ -92,6 +92,7 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
fn perform_locally_with_next_solver( fn perform_locally_with_next_solver(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>, key: ParamEnvAnd<'tcx, Self>,
span: Span,
) -> Result<Self::QueryResponse, NoSolution>; ) -> Result<Self::QueryResponse, NoSolution>;
fn fully_perform_into( fn fully_perform_into(
@ -152,7 +153,7 @@ where
if infcx.next_trait_solver() { if infcx.next_trait_solver() {
return Ok(scrape_region_constraints( return Ok(scrape_region_constraints(
infcx, infcx,
|ocx| QueryTypeOp::perform_locally_with_next_solver(ocx, self), |ocx| QueryTypeOp::perform_locally_with_next_solver(ocx, self, span),
"query type op", "query type op",
span, span,
)? )?

View file

@ -5,6 +5,7 @@ use rustc_middle::traits::query::NoSolution;
pub use rustc_middle::traits::query::type_op::Normalize; pub use rustc_middle::traits::query::type_op::Normalize;
use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::Span;
use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
use crate::traits::ObligationCtxt; use crate::traits::ObligationCtxt;
@ -29,9 +30,10 @@ where
fn perform_locally_with_next_solver( fn perform_locally_with_next_solver(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>, key: ParamEnvAnd<'tcx, Self>,
span: Span,
) -> Result<Self::QueryResponse, NoSolution> { ) -> Result<Self::QueryResponse, NoSolution> {
// FIXME(-Znext-solver): shouldn't be using old normalizer // FIXME(-Znext-solver): shouldn't be using old normalizer
Ok(ocx.normalize(&ObligationCause::dummy(), key.param_env, key.value.value)) Ok(ocx.normalize(&ObligationCause::dummy_with_span(span), key.param_env, key.value.value))
} }
} }

View file

@ -1,5 +1,6 @@
use rustc_middle::traits::query::{DropckOutlivesResult, NoSolution}; use rustc_middle::traits::query::{DropckOutlivesResult, NoSolution};
use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
use rustc_span::Span;
use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
use crate::traits::ObligationCtxt; use crate::traits::ObligationCtxt;
@ -28,7 +29,8 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
fn perform_locally_with_next_solver( fn perform_locally_with_next_solver(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>, key: ParamEnvAnd<'tcx, Self>,
span: Span,
) -> Result<Self::QueryResponse, NoSolution> { ) -> Result<Self::QueryResponse, NoSolution> {
compute_dropck_outlives_inner(ocx, key.param_env.and(key.value)) compute_dropck_outlives_inner(ocx, key.param_env.and(key.value), span)
} }
} }

View file

@ -4,6 +4,7 @@ use rustc_middle::traits::ObligationCause;
use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::query::NoSolution;
pub use rustc_middle::traits::query::type_op::ProvePredicate; pub use rustc_middle::traits::query::type_op::ProvePredicate;
use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt}; use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt};
use rustc_span::Span;
use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse}; use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
use crate::traits::ObligationCtxt; use crate::traits::ObligationCtxt;
@ -57,10 +58,11 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
fn perform_locally_with_next_solver( fn perform_locally_with_next_solver(
ocx: &ObligationCtxt<'_, 'tcx>, ocx: &ObligationCtxt<'_, 'tcx>,
key: ParamEnvAnd<'tcx, Self>, key: ParamEnvAnd<'tcx, Self>,
span: Span,
) -> Result<Self::QueryResponse, NoSolution> { ) -> Result<Self::QueryResponse, NoSolution> {
ocx.register_obligation(Obligation::new( ocx.register_obligation(Obligation::new(
ocx.infcx.tcx, ocx.infcx.tcx,
ObligationCause::dummy(), ObligationCause::dummy_with_span(span),
key.param_env, key.param_env,
key.value.predicate, key.value.predicate,
)); ));

View file

@ -6,6 +6,7 @@ use rustc_middle::bug;
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult}; use rustc_middle::traits::query::{DropckConstraint, DropckOutlivesResult};
use rustc_middle::ty::{self, GenericArgs, TyCtxt}; use rustc_middle::ty::{self, GenericArgs, TyCtxt};
use rustc_span::DUMMY_SP;
use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::infer::InferCtxtBuilderExt;
use rustc_trait_selection::traits::query::dropck_outlives::{ use rustc_trait_selection::traits::query::dropck_outlives::{
compute_dropck_outlives_inner, dtorck_constraint_for_ty_inner, compute_dropck_outlives_inner, dtorck_constraint_for_ty_inner,
@ -24,7 +25,7 @@ fn dropck_outlives<'tcx>(
debug!("dropck_outlives(goal={:#?})", canonical_goal); debug!("dropck_outlives(goal={:#?})", canonical_goal);
tcx.infer_ctxt().enter_canonical_trait_query(&canonical_goal, |ocx, goal| { tcx.infer_ctxt().enter_canonical_trait_query(&canonical_goal, |ocx, goal| {
compute_dropck_outlives_inner(ocx, goal) compute_dropck_outlives_inner(ocx, goal, DUMMY_SP)
}) })
} }

View file

@ -8,6 +8,7 @@ use rustc_infer::traits::query::OutlivesBound;
use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds; use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds;
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_span::DUMMY_SP;
use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::infer::InferCtxtBuilderExt;
use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::{ use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::{
compute_implied_outlives_bounds_compat_inner, compute_implied_outlives_bounds_inner, compute_implied_outlives_bounds_compat_inner, compute_implied_outlives_bounds_inner,
@ -28,7 +29,7 @@ fn implied_outlives_bounds_compat<'tcx>(
> { > {
tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts(); let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts();
compute_implied_outlives_bounds_compat_inner(ocx, param_env, ty) compute_implied_outlives_bounds_compat_inner(ocx, param_env, ty, DUMMY_SP)
}) })
} }
@ -41,6 +42,6 @@ fn implied_outlives_bounds<'tcx>(
> { > {
tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| { tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts(); let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts();
compute_implied_outlives_bounds_inner(ocx, param_env, ty) compute_implied_outlives_bounds_inner(ocx, param_env, ty, DUMMY_SP)
}) })
} }

View file

@ -5,6 +5,7 @@ use rustc_infer::infer::canonical::{Canonical, CanonicalQueryInput, QueryRespons
use rustc_middle::query::Providers; use rustc_middle::query::Providers;
use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::{Clause, FnSig, ParamEnvAnd, PolyFnSig, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{Clause, FnSig, ParamEnvAnd, PolyFnSig, Ty, TyCtxt, TypeFoldable};
use rustc_span::DUMMY_SP;
use rustc_trait_selection::infer::InferCtxtBuilderExt; use rustc_trait_selection::infer::InferCtxtBuilderExt;
use rustc_trait_selection::traits::query::type_op::ascribe_user_type::{ use rustc_trait_selection::traits::query::type_op::ascribe_user_type::{
AscribeUserType, type_op_ascribe_user_type_with_span, AscribeUserType, type_op_ascribe_user_type_with_span,
@ -30,7 +31,7 @@ fn type_op_ascribe_user_type<'tcx>(
canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>, canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>,
) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> {
tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| { tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| {
type_op_ascribe_user_type_with_span(ocx, key, None) type_op_ascribe_user_type_with_span(ocx, key, DUMMY_SP)
}) })
} }