Skip to content

Commit 4421dd1

Browse files
matthewjasperlqd
authored andcommitted
Return the canonicalized query from type ops
1 parent 842f059 commit 4421dd1

File tree

6 files changed

+53
-39
lines changed

6 files changed

+53
-39
lines changed

compiler/rustc_mir/src/borrow_check/type_check/free_region_relations.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt};
1111
use rustc_span::DUMMY_SP;
1212
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
1313
use std::rc::Rc;
14+
use type_op::TypeOpOutput;
1415

1516
use crate::borrow_check::{
1617
nll::ToRegionVid,
@@ -255,7 +256,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
255256
let constraint_sets: Vec<_> = unnormalized_input_output_tys
256257
.flat_map(|ty| {
257258
debug!("build: input_or_output={:?}", ty);
258-
let (ty, constraints1) = self
259+
let TypeOpOutput { output: ty, constraints: constraints1, .. } = self
259260
.param_env
260261
.and(type_op::normalize::Normalize::new(ty))
261262
.fully_perform(self.infcx)
@@ -264,7 +265,11 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
264265
.tcx
265266
.sess
266267
.delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty));
267-
(self.infcx.tcx.ty_error(), None)
268+
TypeOpOutput {
269+
output: self.infcx.tcx.ty_error(),
270+
constraints: None,
271+
canonicalized_query: None,
272+
}
268273
});
269274
let constraints2 = self.add_implied_bounds(ty);
270275
normalized_inputs_and_output.push(ty);
@@ -317,7 +322,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
317322
/// from this local.
318323
fn add_implied_bounds(&mut self, ty: Ty<'tcx>) -> Option<Rc<QueryRegionConstraints<'tcx>>> {
319324
debug!("add_implied_bounds(ty={:?})", ty);
320-
let (bounds, constraints) = self
325+
let TypeOpOutput { output: bounds, constraints, .. } = self
321326
.param_env
322327
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
323328
.fully_perform(self.infcx)

compiler/rustc_mir/src/borrow_check/type_check/liveness/trace.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
55
use rustc_middle::ty::{Ty, TypeFoldable};
66
use rustc_trait_selection::traits::query::dropck_outlives::DropckOutlivesResult;
77
use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives;
8-
use rustc_trait_selection::traits::query::type_op::TypeOp;
8+
use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
99
use std::rc::Rc;
1010

1111
use crate::dataflow::impls::MaybeInitializedPlaces;
@@ -519,9 +519,9 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
519519
debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,);
520520

521521
let param_env = typeck.param_env;
522-
let (dropck_result, region_constraint_data) =
522+
let TypeOpOutput { output, constraints, .. } =
523523
param_env.and(DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx).unwrap();
524524

525-
DropData { dropck_result, region_constraint_data }
525+
DropData { dropck_result: output, region_constraint_data: constraints }
526526
}
527527
}

compiler/rustc_mir/src/borrow_check/type_check/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use rustc_trait_selection::traits::query::type_op;
4040
use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
4141
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
4242
use rustc_trait_selection::traits::{self, ObligationCause, PredicateObligations};
43+
use type_op::TypeOpOutput;
4344

4445
use crate::dataflow::impls::MaybeInitializedPlaces;
4546
use crate::dataflow::move_paths::MoveData;
@@ -1113,13 +1114,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
11131114
category: ConstraintCategory,
11141115
op: impl type_op::TypeOp<'tcx, Output = R>,
11151116
) -> Fallible<R> {
1116-
let (r, opt_data) = op.fully_perform(self.infcx)?;
1117+
let TypeOpOutput { output, constraints, .. } = op.fully_perform(self.infcx)?;
11171118

1118-
if let Some(data) = &opt_data {
1119+
if let Some(data) = &constraints {
11191120
self.push_region_constraints(locations, category, data);
11201121
}
11211122

1122-
Ok(r)
1123+
Ok(output)
11231124
}
11241125

11251126
fn push_region_constraints(

compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
use crate::infer::{InferCtxt, InferOk};
2-
use crate::traits::query::Fallible;
3-
use std::fmt;
4-
51
use crate::infer::canonical::query_response;
6-
use crate::infer::canonical::QueryRegionConstraints;
2+
use crate::infer::{InferCtxt, InferOk};
73
use crate::traits::engine::TraitEngineExt as _;
4+
use crate::traits::query::type_op::TypeOpOutput;
5+
use crate::traits::query::Fallible;
86
use crate::traits::{ObligationCause, TraitEngine};
97
use rustc_infer::traits::TraitEngineExt as _;
108
use rustc_span::source_map::DUMMY_SP;
9+
10+
use std::fmt;
1111
use std::rc::Rc;
1212

1313
pub struct CustomTypeOp<F, G> {
@@ -35,10 +35,7 @@ where
3535
/// Processes the operation and all resulting obligations,
3636
/// returning the final result along with any region constraints
3737
/// (they will be given over to the NLL region solver).
38-
fn fully_perform(
39-
self,
40-
infcx: &InferCtxt<'_, 'tcx>,
41-
) -> Fallible<(Self::Output, Option<Rc<QueryRegionConstraints<'tcx>>>)> {
38+
fn fully_perform(self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
4239
if cfg!(debug_assertions) {
4340
info!("fully_perform({:?})", self);
4441
}
@@ -58,10 +55,10 @@ where
5855

5956
/// Executes `op` and then scrapes out all the "old style" region
6057
/// constraints that result, creating query-region-constraints.
61-
fn scrape_region_constraints<'tcx, R>(
58+
fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
6259
infcx: &InferCtxt<'_, 'tcx>,
6360
op: impl FnOnce() -> Fallible<InferOk<'tcx, R>>,
64-
) -> Fallible<(R, Option<Rc<QueryRegionConstraints<'tcx>>>)> {
61+
) -> Fallible<TypeOpOutput<'tcx, Op>> {
6562
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(infcx.tcx);
6663
let dummy_body_id = ObligationCause::dummy().body_id;
6764

@@ -101,8 +98,12 @@ fn scrape_region_constraints<'tcx, R>(
10198
);
10299

103100
if region_constraints.is_empty() {
104-
Ok((value, None))
101+
Ok(TypeOpOutput { output: value, constraints: None, canonicalized_query: None })
105102
} else {
106-
Ok((value, Some(Rc::new(region_constraints))))
103+
Ok(TypeOpOutput {
104+
output: value,
105+
constraints: Some(Rc::new(region_constraints)),
106+
canonicalized_query: None,
107+
})
107108
}
108109
}

compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::traits::query::outlives_bounds::OutlivesBound;
33
use crate::traits::query::Fallible;
44
use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
55

6-
#[derive(Clone, Debug, HashStable, TypeFoldable, Lift)]
6+
#[derive(Copy, Clone, Debug, HashStable, TypeFoldable, Lift)]
77
pub struct ImpliedOutlivesBounds<'tcx> {
88
pub ty: Ty<'tcx>,
99
}

compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::infer::canonical::{
44
use crate::infer::{InferCtxt, InferOk};
55
use crate::traits::query::Fallible;
66
use crate::traits::ObligationCause;
7+
use rustc_infer::infer::canonical::Canonical;
78
use rustc_middle::ty::fold::TypeFoldable;
89
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
910
use std::fmt;
@@ -30,10 +31,18 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug {
3031
/// Processes the operation and all resulting obligations,
3132
/// returning the final result along with any region constraints
3233
/// (they will be given over to the NLL region solver).
33-
fn fully_perform(
34-
self,
35-
infcx: &InferCtxt<'_, 'tcx>,
36-
) -> Fallible<(Self::Output, Option<Rc<QueryRegionConstraints<'tcx>>>)>;
34+
fn fully_perform(self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>>;
35+
}
36+
37+
/// The output from performing a type op
38+
pub struct TypeOpOutput<'tcx, Op: TypeOp<'tcx>> {
39+
/// The output from the type op.
40+
pub output: Op::Output,
41+
/// Any region constraints from performing the type op.
42+
pub constraints: Option<Rc<QueryRegionConstraints<'tcx>>>,
43+
/// The canonicalized form of the query.
44+
/// This for error reporting to be able to rerun the query.
45+
pub canonicalized_query: Option<Canonical<'tcx, Op>>,
3746
}
3847

3948
/// "Query type ops" are type ops that are implemented using a
@@ -45,7 +54,7 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug {
4554
/// which produces the resulting query region constraints.
4655
///
4756
/// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
48-
pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx {
57+
pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<'tcx> + 'tcx {
4958
type QueryResponse: TypeFoldable<'tcx>;
5059

5160
/// Give query the option for a simple fast path that never
@@ -71,9 +80,9 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx {
7180
query_key: ParamEnvAnd<'tcx, Self>,
7281
infcx: &InferCtxt<'_, 'tcx>,
7382
output_query_region_constraints: &mut QueryRegionConstraints<'tcx>,
74-
) -> Fallible<Self::QueryResponse> {
83+
) -> Fallible<(Self::QueryResponse, Option<Canonical<'tcx, ParamEnvAnd<'tcx, Self>>>)> {
7584
if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) {
76-
return Ok(result);
85+
return Ok((result, None));
7786
}
7887

7988
// FIXME(#33684) -- We need to use
@@ -101,14 +110,14 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Sized + TypeFoldable<'tcx> + 'tcx {
101110
// create obligations. In that case, we have to go
102111
// fulfill them. We do this via a (recursive) query.
103112
for obligation in obligations {
104-
let () = ProvePredicate::fully_perform_into(
113+
let ((), _) = ProvePredicate::fully_perform_into(
105114
obligation.param_env.and(ProvePredicate::new(obligation.predicate)),
106115
infcx,
107116
output_query_region_constraints,
108117
)?;
109118
}
110119

111-
Ok(value)
120+
Ok((value, Some(canonical_self)))
112121
}
113122
}
114123

@@ -118,18 +127,16 @@ where
118127
{
119128
type Output = Q::QueryResponse;
120129

121-
fn fully_perform(
122-
self,
123-
infcx: &InferCtxt<'_, 'tcx>,
124-
) -> Fallible<(Self::Output, Option<Rc<QueryRegionConstraints<'tcx>>>)> {
130+
fn fully_perform(self, infcx: &InferCtxt<'_, 'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
125131
let mut region_constraints = QueryRegionConstraints::default();
126-
let r = Q::fully_perform_into(self, infcx, &mut region_constraints)?;
132+
let (output, canonicalized_query) =
133+
Q::fully_perform_into(self, infcx, &mut region_constraints)?;
127134

128135
// Promote the final query-region-constraints into a
129136
// (optional) ref-counted vector:
130-
let opt_qrc =
137+
let region_constraints =
131138
if region_constraints.is_empty() { None } else { Some(Rc::new(region_constraints)) };
132139

133-
Ok((r, opt_qrc))
140+
Ok(TypeOpOutput { output, constraints: region_constraints, canonicalized_query })
134141
}
135142
}

0 commit comments

Comments
 (0)