1
Fork 0

(almost) Always use ObligationCtxt when dealing with canonical queries

This commit is contained in:
Michael Goulet 2022-10-26 18:00:18 +00:00
parent 0da281b606
commit d793d80cf7
8 changed files with 104 additions and 111 deletions

View file

@ -5,14 +5,14 @@ use rustc_infer::infer::region_constraints::Constraint;
use rustc_infer::infer::region_constraints::RegionConstraintData;
use rustc_infer::infer::RegionVariableOrigin;
use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt};
use rustc_infer::traits::ObligationCause;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::RegionVid;
use rustc_middle::ty::UniverseIndex;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc_span::Span;
use rustc_trait_selection::traits::query::type_op;
use rustc_trait_selection::traits::{SelectionContext, TraitEngineExt as _};
use rustc_trait_selection::traits::ObligationCtxt;
use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause};
use std::fmt;
@ -240,9 +240,9 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (ref infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause);
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
let ocx = ObligationCtxt::new(infcx);
type_op_prove_predicate_with_cause(&ocx, key, cause);
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
}
}
@ -281,9 +281,7 @@ where
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (ref infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
let mut selcx = SelectionContext::new(infcx);
let ocx = ObligationCtxt::new(infcx);
// FIXME(lqd): Unify and de-duplicate the following with the actual
// `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the
@ -292,11 +290,9 @@ where
// to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. Check
// after #85499 lands to see if its fixes have erased this difference.
let (param_env, value) = key.into_parts();
let Normalized { value: _, obligations } =
rustc_trait_selection::traits::normalize(&mut selcx, param_env, cause, value.value);
fulfill_cx.register_predicate_obligations(infcx, obligations);
let _ = ocx.normalize(cause, param_env, value.value);
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
}
}
@ -329,9 +325,9 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
let (ref infcx, key, _) =
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span)).ok()?;
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
let ocx = ObligationCtxt::new(infcx);
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
}
}
@ -372,25 +368,24 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
}
}
#[instrument(skip(fulfill_cx, infcx), level = "debug")]
#[instrument(skip(ocx), level = "debug")]
fn try_extract_error_from_fulfill_cx<'tcx>(
mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>,
infcx: &InferCtxt<'tcx>,
ocx: &ObligationCtxt<'_, 'tcx>,
placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
// We generally shouldn't have errors here because the query was
// already run, but there's no point using `delay_span_bug`
// when we're going to emit an error here anyway.
let _errors = fulfill_cx.select_all_or_error(infcx);
let region_constraints = infcx.with_region_constraints(|r| r.clone());
let _errors = ocx.select_all_or_error();
let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
try_extract_error_from_region_constraints(
infcx,
ocx.infcx,
placeholder_region,
error_region,
&region_constraints,
|vid| infcx.region_var_origin(vid),
|vid| infcx.universe_of_region(infcx.tcx.mk_region(ty::ReVar(vid))),
|vid| ocx.infcx.region_var_origin(vid),
|vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_region(ty::ReVar(vid))),
)
}