Skip to content

Commit a25aee1

Browse files
Perform MIR type ops locally in new solver
1 parent 19ed0aa commit a25aee1

File tree

8 files changed

+94
-1
lines changed

8 files changed

+94
-1
lines changed

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

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2+
use crate::traits::ObligationCtxt;
23
use rustc_middle::traits::query::NoSolution;
34
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
45

@@ -20,4 +21,11 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
2021
) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
2122
tcx.type_op_ascribe_user_type(canonicalized)
2223
}
24+
25+
fn perform_locally_in_new_solver(
26+
_ocx: &ObligationCtxt<'_, 'tcx>,
27+
_key: ParamEnvAnd<'tcx, Self>,
28+
) -> Result<Self::QueryResponse, NoSolution> {
29+
todo!()
30+
}
2331
}

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

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2+
use crate::traits::ObligationCtxt;
23
use rustc_middle::traits::query::NoSolution;
4+
use rustc_middle::traits::ObligationCause;
35
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
46

57
pub use rustc_middle::traits::query::type_op::Eq;
@@ -20,4 +22,12 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> {
2022
) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
2123
tcx.type_op_eq(canonicalized)
2224
}
25+
26+
fn perform_locally_in_new_solver(
27+
ocx: &ObligationCtxt<'_, 'tcx>,
28+
key: ParamEnvAnd<'tcx, Self>,
29+
) -> Result<Self::QueryResponse, NoSolution> {
30+
ocx.eq(&ObligationCause::dummy(), key.param_env, key.value.a, key.value.b)?;
31+
Ok(())
32+
}
2333
}

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

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2+
use crate::traits::ObligationCtxt;
23
use rustc_infer::traits::query::OutlivesBound;
34
use rustc_middle::traits::query::NoSolution;
45
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt};
@@ -39,4 +40,11 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
3940

4041
tcx.implied_outlives_bounds(canonicalized)
4142
}
43+
44+
fn perform_locally_in_new_solver(
45+
_ocx: &ObligationCtxt<'_, 'tcx>,
46+
_key: ParamEnvAnd<'tcx, Self>,
47+
) -> Result<Self::QueryResponse, NoSolution> {
48+
todo!()
49+
}
4250
}

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

+24-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::infer::canonical::{
22
Canonical, CanonicalQueryResponse, OriginalQueryValues, QueryRegionConstraints,
33
};
44
use crate::infer::{InferCtxt, InferOk};
5-
use crate::traits::ObligationCause;
5+
use crate::traits::{ObligationCause, ObligationCtxt};
66
use rustc_errors::ErrorGuaranteed;
77
use rustc_infer::infer::canonical::Certainty;
88
use rustc_infer::traits::PredicateObligations;
@@ -23,6 +23,8 @@ pub mod subtype;
2323

2424
pub use rustc_middle::traits::query::type_op::*;
2525

26+
use self::custom::scrape_region_constraints;
27+
2628
/// "Type ops" are used in NLL to perform some particular action and
2729
/// extract out the resulting region constraints (or an error if it
2830
/// cannot be completed).
@@ -81,6 +83,17 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 't
8183
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>,
8284
) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution>;
8385

86+
/// In the new trait solver, we already do caching in the solver itself,
87+
/// so there's no need to canonicalize and cache via the query system.
88+
/// Additionally, even if we were to canonicalize, we'd still need to
89+
/// make sure to feed it predefined opaque types and the defining anchor
90+
/// and that would require duplicating all of the tcx queries. Instead,
91+
/// just perform these ops locally.
92+
fn perform_locally_in_new_solver(
93+
ocx: &ObligationCtxt<'_, 'tcx>,
94+
key: ParamEnvAnd<'tcx, Self>,
95+
) -> Result<Self::QueryResponse, NoSolution>;
96+
8497
fn fully_perform_into(
8598
query_key: ParamEnvAnd<'tcx, Self>,
8699
infcx: &InferCtxt<'tcx>,
@@ -133,6 +146,16 @@ where
133146
infcx: &InferCtxt<'tcx>,
134147
span: Span,
135148
) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
149+
if infcx.tcx.trait_solver_next() {
150+
return Ok(scrape_region_constraints(
151+
infcx,
152+
|ocx| QueryTypeOp::perform_locally_in_new_solver(ocx, self),
153+
"query type op",
154+
span,
155+
)?
156+
.0);
157+
}
158+
136159
let mut region_constraints = QueryRegionConstraints::default();
137160
let (output, error_info, mut obligations, _) =
138161
Q::fully_perform_into(self, infcx, &mut region_constraints).map_err(|_| {

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

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2+
use crate::traits::ObligationCtxt;
23
use rustc_middle::traits::query::NoSolution;
4+
use rustc_middle::traits::ObligationCause;
35
use rustc_middle::ty::fold::TypeFoldable;
46
use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt};
57
use std::fmt;
@@ -22,6 +24,14 @@ where
2224
) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
2325
T::type_op_method(tcx, canonicalized)
2426
}
27+
28+
fn perform_locally_in_new_solver(
29+
ocx: &ObligationCtxt<'_, 'tcx>,
30+
key: ParamEnvAnd<'tcx, Self>,
31+
) -> Result<Self::QueryResponse, NoSolution> {
32+
// FIXME(-Ztrait-solver=next): shouldn't be using old normalizer
33+
Ok(ocx.normalize(&ObligationCause::dummy(), key.param_env, key.value.value))
34+
}
2535
}
2636

2737
pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx> + Copy {

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

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
22
use crate::traits::query::dropck_outlives::{trivial_dropck_outlives, DropckOutlivesResult};
3+
use crate::traits::ObligationCtxt;
34
use rustc_middle::traits::query::NoSolution;
45
use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
56

@@ -48,4 +49,11 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> {
4849

4950
tcx.dropck_outlives(canonicalized)
5051
}
52+
53+
fn perform_locally_in_new_solver(
54+
_ocx: &ObligationCtxt<'_, 'tcx>,
55+
_key: ParamEnvAnd<'tcx, Self>,
56+
) -> Result<Self::QueryResponse, NoSolution> {
57+
todo!()
58+
}
5159
}

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

+16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2+
use crate::traits::ObligationCtxt;
3+
use rustc_infer::traits::Obligation;
24
use rustc_middle::traits::query::NoSolution;
5+
use rustc_middle::traits::ObligationCause;
36
use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt};
47

58
pub use rustc_middle::traits::query::type_op::ProvePredicate;
@@ -36,4 +39,17 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
3639
) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
3740
tcx.type_op_prove_predicate(canonicalized)
3841
}
42+
43+
fn perform_locally_in_new_solver(
44+
ocx: &ObligationCtxt<'_, 'tcx>,
45+
key: ParamEnvAnd<'tcx, Self>,
46+
) -> Result<Self::QueryResponse, NoSolution> {
47+
ocx.register_obligation(Obligation::new(
48+
ocx.infcx.tcx,
49+
ObligationCause::dummy(),
50+
key.param_env,
51+
key.value.predicate,
52+
));
53+
Ok(())
54+
}
3955
}

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

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::infer::canonical::{Canonical, CanonicalQueryResponse};
2+
use crate::traits::ObligationCtxt;
23
use rustc_middle::traits::query::NoSolution;
4+
use rustc_middle::traits::ObligationCause;
35
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
46

57
pub use rustc_middle::traits::query::type_op::Subtype;
@@ -17,4 +19,12 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> {
1719
) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
1820
tcx.type_op_subtype(canonicalized)
1921
}
22+
23+
fn perform_locally_in_new_solver(
24+
ocx: &ObligationCtxt<'_, 'tcx>,
25+
key: ParamEnvAnd<'tcx, Self>,
26+
) -> Result<Self::QueryResponse, NoSolution> {
27+
ocx.sub(&ObligationCause::dummy(), key.param_env, key.value.sub, key.value.sup)?;
28+
Ok(())
29+
}
2030
}

0 commit comments

Comments
 (0)