summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs')
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs68
1 files changed, 38 insertions, 30 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
index 8f1b05c11..6d8d2103f 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs
@@ -1,32 +1,32 @@
use crate::infer::canonical::query_response;
-use crate::infer::{InferCtxt, InferOk};
+use crate::infer::InferCtxt;
use crate::traits::query::type_op::TypeOpOutput;
-use crate::traits::query::Fallible;
use crate::traits::ObligationCtxt;
+use rustc_errors::ErrorGuaranteed;
use rustc_infer::infer::region_constraints::RegionConstraintData;
+use rustc_middle::traits::query::NoSolution;
use rustc_span::source_map::DUMMY_SP;
+use rustc_span::Span;
use std::fmt;
-pub struct CustomTypeOp<F, G> {
+pub struct CustomTypeOp<F> {
closure: F,
- description: G,
+ description: &'static str,
}
-impl<F, G> CustomTypeOp<F, G> {
- pub fn new<'tcx, R>(closure: F, description: G) -> Self
+impl<F> CustomTypeOp<F> {
+ pub fn new<'tcx, R>(closure: F, description: &'static str) -> Self
where
- F: FnOnce(&InferCtxt<'tcx>) -> Fallible<InferOk<'tcx, R>>,
- G: Fn() -> String,
+ F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
{
CustomTypeOp { closure, description }
}
}
-impl<'tcx, F, R: fmt::Debug, G> super::TypeOp<'tcx> for CustomTypeOp<F, G>
+impl<'tcx, F, R: fmt::Debug> super::TypeOp<'tcx> for CustomTypeOp<F>
where
- F: for<'a, 'cx> FnOnce(&'a InferCtxt<'tcx>) -> Fallible<InferOk<'tcx, R>>,
- G: Fn() -> String,
+ F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
{
type Output = R;
/// We can't do any custom error reporting for `CustomTypeOp`, so
@@ -36,21 +36,22 @@ where
/// Processes the operation and all resulting obligations,
/// returning the final result along with any region constraints
/// (they will be given over to the NLL region solver).
- fn fully_perform(self, infcx: &InferCtxt<'tcx>) -> Fallible<TypeOpOutput<'tcx, Self>> {
+ fn fully_perform(
+ self,
+ infcx: &InferCtxt<'tcx>,
+ span: Span,
+ ) -> Result<TypeOpOutput<'tcx, Self>, ErrorGuaranteed> {
if cfg!(debug_assertions) {
info!("fully_perform({:?})", self);
}
- Ok(scrape_region_constraints(infcx, || (self.closure)(infcx))?.0)
+ Ok(scrape_region_constraints(infcx, self.closure, self.description, span)?.0)
}
}
-impl<F, G> fmt::Debug for CustomTypeOp<F, G>
-where
- G: Fn() -> String,
-{
+impl<F> fmt::Debug for CustomTypeOp<F> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", (self.description)())
+ self.description.fmt(f)
}
}
@@ -58,8 +59,10 @@ where
/// constraints that result, creating query-region-constraints.
pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
infcx: &InferCtxt<'tcx>,
- op: impl FnOnce() -> Fallible<InferOk<'tcx, R>>,
-) -> Fallible<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>)> {
+ op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result<R, NoSolution>,
+ name: &'static str,
+ span: Span,
+) -> Result<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>), ErrorGuaranteed> {
// During NLL, we expect that nobody will register region
// obligations **except** as part of a custom type op (and, at the
// end of each custom type op, we scrape out the region
@@ -72,16 +75,21 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
pre_obligations,
);
- let InferOk { value, obligations } = infcx.commit_if_ok(|_| op())?;
- let ocx = ObligationCtxt::new(infcx);
- ocx.register_obligations(obligations);
- let errors = ocx.select_all_or_error();
- if !errors.is_empty() {
- infcx.tcx.sess.diagnostic().delay_span_bug(
- DUMMY_SP,
- &format!("errors selecting obligation during MIR typeck: {:?}", errors),
- );
- }
+ let value = infcx.commit_if_ok(|_| {
+ let ocx = ObligationCtxt::new_in_snapshot(infcx);
+ let value = op(&ocx).map_err(|_| {
+ infcx.tcx.sess.delay_span_bug(span, format!("error performing operation: {name}"))
+ })?;
+ let errors = ocx.select_all_or_error();
+ if errors.is_empty() {
+ Ok(value)
+ } else {
+ Err(infcx.tcx.sess.delay_span_bug(
+ DUMMY_SP,
+ format!("errors selecting obligation during MIR typeck: {:?}", errors),
+ ))
+ }
+ })?;
let region_obligations = infcx.take_registered_region_obligations();
let region_constraint_data = infcx.take_and_reset_region_constraints();