Skip to content

Commit d793d80

Browse files
(almost) Always use ObligationCtxt when dealing with canonical queries
1 parent 0da281b commit d793d80

File tree

8 files changed

+104
-111
lines changed

8 files changed

+104
-111
lines changed

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

+18-23
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ use rustc_infer::infer::region_constraints::Constraint;
55
use rustc_infer::infer::region_constraints::RegionConstraintData;
66
use rustc_infer::infer::RegionVariableOrigin;
77
use rustc_infer::infer::{InferCtxt, RegionResolutionError, SubregionOrigin, TyCtxtInferExt as _};
8-
use rustc_infer::traits::{Normalized, ObligationCause, TraitEngine, TraitEngineExt};
8+
use rustc_infer::traits::ObligationCause;
99
use rustc_middle::ty::error::TypeError;
1010
use rustc_middle::ty::RegionVid;
1111
use rustc_middle::ty::UniverseIndex;
1212
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
1313
use rustc_span::Span;
1414
use rustc_trait_selection::traits::query::type_op;
15-
use rustc_trait_selection::traits::{SelectionContext, TraitEngineExt as _};
15+
use rustc_trait_selection::traits::ObligationCtxt;
1616
use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_cause};
1717

1818
use std::fmt;
@@ -240,9 +240,9 @@ impl<'tcx> TypeOpInfo<'tcx> for PredicateQuery<'tcx> {
240240
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
241241
let (ref infcx, key, _) =
242242
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
243-
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
244-
type_op_prove_predicate_with_cause(infcx, &mut *fulfill_cx, key, cause);
245-
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
243+
let ocx = ObligationCtxt::new(infcx);
244+
type_op_prove_predicate_with_cause(&ocx, key, cause);
245+
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
246246
}
247247
}
248248

@@ -281,9 +281,7 @@ where
281281
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
282282
let (ref infcx, key, _) =
283283
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
284-
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
285-
286-
let mut selcx = SelectionContext::new(infcx);
284+
let ocx = ObligationCtxt::new(infcx);
287285

288286
// FIXME(lqd): Unify and de-duplicate the following with the actual
289287
// `rustc_traits::type_op::type_op_normalize` query to allow the span we need in the
@@ -292,11 +290,9 @@ where
292290
// to normalize the `nll/relate_tys/impl-fn-ignore-binder-via-bottom.rs` test. Check
293291
// after #85499 lands to see if its fixes have erased this difference.
294292
let (param_env, value) = key.into_parts();
295-
let Normalized { value: _, obligations } =
296-
rustc_trait_selection::traits::normalize(&mut selcx, param_env, cause, value.value);
297-
fulfill_cx.register_predicate_obligations(infcx, obligations);
293+
let _ = ocx.normalize(cause, param_env, value.value);
298294

299-
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
295+
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
300296
}
301297
}
302298

@@ -329,9 +325,9 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
329325
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
330326
let (ref infcx, key, _) =
331327
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
332-
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
333-
type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(cause.span)).ok()?;
334-
try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
328+
let ocx = ObligationCtxt::new(infcx);
329+
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
330+
try_extract_error_from_fulfill_cx(&ocx, placeholder_region, error_region)
335331
}
336332
}
337333

@@ -372,25 +368,24 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
372368
}
373369
}
374370

375-
#[instrument(skip(fulfill_cx, infcx), level = "debug")]
371+
#[instrument(skip(ocx), level = "debug")]
376372
fn try_extract_error_from_fulfill_cx<'tcx>(
377-
mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>,
378-
infcx: &InferCtxt<'tcx>,
373+
ocx: &ObligationCtxt<'_, 'tcx>,
379374
placeholder_region: ty::Region<'tcx>,
380375
error_region: Option<ty::Region<'tcx>>,
381376
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
382377
// We generally shouldn't have errors here because the query was
383378
// already run, but there's no point using `delay_span_bug`
384379
// when we're going to emit an error here anyway.
385-
let _errors = fulfill_cx.select_all_or_error(infcx);
386-
let region_constraints = infcx.with_region_constraints(|r| r.clone());
380+
let _errors = ocx.select_all_or_error();
381+
let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
387382
try_extract_error_from_region_constraints(
388-
infcx,
383+
ocx.infcx,
389384
placeholder_region,
390385
error_region,
391386
&region_constraints,
392-
|vid| infcx.region_var_origin(vid),
393-
|vid| infcx.universe_of_region(infcx.tcx.mk_region(ty::ReVar(vid))),
387+
|vid| ocx.infcx.region_var_origin(vid),
388+
|vid| ocx.infcx.universe_of_region(ocx.infcx.tcx.mk_region(ty::ReVar(vid))),
394389
)
395390
}
396391

compiler/rustc_infer/src/infer/canonical/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl<'tcx> InferCtxt<'tcx> {
4343
///
4444
/// This is only meant to be invoked as part of constructing an
4545
/// inference context at the start of a query (see
46-
/// `InferCtxtBuilder::enter_with_canonical`). It basically
46+
/// `InferCtxtBuilder::build_with_canonical`). It basically
4747
/// brings the canonical value "into scope" within your new infcx.
4848
///
4949
/// At the end of processing, the substitution S (once

compiler/rustc_trait_selection/src/infer.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
2-
use crate::traits::{self, TraitEngine, TraitEngineExt};
2+
use crate::traits::{self, ObligationCtxt};
33

44
use rustc_hir::def_id::DefId;
55
use rustc_hir::lang_items::LangItem;
@@ -142,7 +142,7 @@ pub trait InferCtxtBuilderExt<'tcx> {
142142
fn enter_canonical_trait_query<K, R>(
143143
&mut self,
144144
canonical_key: &Canonical<'tcx, K>,
145-
operation: impl FnOnce(&InferCtxt<'tcx>, &mut dyn TraitEngine<'tcx>, K) -> Fallible<R>,
145+
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible<R>,
146146
) -> Fallible<CanonicalizedQueryResponse<'tcx, R>>
147147
where
148148
K: TypeFoldable<'tcx>,
@@ -170,17 +170,17 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> {
170170
fn enter_canonical_trait_query<K, R>(
171171
&mut self,
172172
canonical_key: &Canonical<'tcx, K>,
173-
operation: impl FnOnce(&InferCtxt<'tcx>, &mut dyn TraitEngine<'tcx>, K) -> Fallible<R>,
173+
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible<R>,
174174
) -> Fallible<CanonicalizedQueryResponse<'tcx, R>>
175175
where
176176
K: TypeFoldable<'tcx>,
177177
R: Debug + TypeFoldable<'tcx>,
178178
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
179179
{
180-
let (ref infcx, key, canonical_inference_vars) =
180+
let (infcx, key, canonical_inference_vars) =
181181
self.build_with_canonical(DUMMY_SP, canonical_key);
182-
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
183-
let value = operation(infcx, &mut *fulfill_cx, key)?;
184-
infcx.make_canonicalized_query_response(canonical_inference_vars, value, &mut *fulfill_cx)
182+
let ocx = ObligationCtxt::new(&infcx);
183+
let value = operation(&ocx, key)?;
184+
ocx.make_canonicalized_query_response(canonical_inference_vars, value)
185185
}
186186
}

compiler/rustc_trait_selection/src/traits/engine.rs

+22
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
use std::cell::RefCell;
2+
use std::fmt::Debug;
23

34
use super::TraitEngine;
45
use super::{ChalkFulfillmentContext, FulfillmentContext};
56
use crate::infer::InferCtxtExt;
67
use rustc_data_structures::fx::FxHashSet;
78
use rustc_hir::def_id::{DefId, LocalDefId};
9+
use rustc_infer::infer::canonical::{
10+
Canonical, CanonicalVarValues, CanonicalizedQueryResponse, QueryResponse,
11+
};
812
use rustc_infer::infer::{InferCtxt, InferOk};
13+
use rustc_infer::traits::query::Fallible;
914
use rustc_infer::traits::{
1015
FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _,
1116
};
17+
use rustc_middle::arena::ArenaAllocatable;
1218
use rustc_middle::ty::error::TypeError;
1319
use rustc_middle::ty::ToPredicate;
1420
use rustc_middle::ty::TypeFoldable;
@@ -154,4 +160,20 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
154160
}
155161
implied_bounds
156162
}
163+
164+
pub fn make_canonicalized_query_response<T>(
165+
&self,
166+
inference_vars: CanonicalVarValues<'tcx>,
167+
answer: T,
168+
) -> Fallible<CanonicalizedQueryResponse<'tcx, T>>
169+
where
170+
T: Debug + TypeFoldable<'tcx>,
171+
Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
172+
{
173+
self.infcx.make_canonicalized_query_response(
174+
inference_vars,
175+
answer,
176+
&mut **self.engine.borrow_mut(),
177+
)
178+
}
157179
}

compiler/rustc_traits/src/implied_outlives_bounds.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ fn implied_outlives_bounds<'tcx>(
2828
&'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
2929
NoSolution,
3030
> {
31-
tcx.infer_ctxt().enter_canonical_trait_query(&goal, |infcx, _fulfill_cx, key| {
31+
tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
3232
let (param_env, ty) = key.into_parts();
33-
compute_implied_outlives_bounds(&infcx, param_env, ty)
33+
compute_implied_outlives_bounds(&ocx.infcx, param_env, ty)
3434
})
3535
}
3636

compiler/rustc_traits/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
44
#![deny(rustc::untranslatable_diagnostic)]
55
#![deny(rustc::diagnostic_outside_of_impl)]
6+
#![feature(let_chains)]
67
#![recursion_limit = "256"]
78

89
#[macro_use]

compiler/rustc_traits/src/normalize_projection_ty.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
22
use rustc_infer::infer::TyCtxtInferExt;
3-
use rustc_infer::traits::TraitEngineExt as _;
43
use rustc_middle::ty::query::Providers;
54
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
65
use rustc_trait_selection::infer::InferCtxtBuilderExt;
@@ -23,8 +22,8 @@ fn normalize_projection_ty<'tcx>(
2322
tcx.sess.perf_stats.normalize_projection_ty.fetch_add(1, Ordering::Relaxed);
2423
tcx.infer_ctxt().enter_canonical_trait_query(
2524
&goal,
26-
|infcx, fulfill_cx, ParamEnvAnd { param_env, value: goal }| {
27-
let selcx = &mut SelectionContext::new(infcx);
25+
|ocx, ParamEnvAnd { param_env, value: goal }| {
26+
let selcx = &mut SelectionContext::new(ocx.infcx);
2827
let cause = ObligationCause::dummy();
2928
let mut obligations = vec![];
3029
let answer = traits::normalize_projection_type(
@@ -35,7 +34,7 @@ fn normalize_projection_ty<'tcx>(
3534
0,
3635
&mut obligations,
3736
);
38-
fulfill_cx.register_predicate_obligations(infcx, obligations);
37+
ocx.register_obligations(obligations);
3938
// FIXME(associated_const_equality): All users of normalize_projection_ty expected
4039
// a type, but there is the possibility it could've been a const now. Maybe change
4140
// it to a Term later?

0 commit comments

Comments
 (0)