Use ErrorGuaranteed more in MIR type ops
This commit is contained in:
parent
cade26637f
commit
91525a4324
8 changed files with 104 additions and 107 deletions
|
@ -1,8 +1,8 @@
|
|||
use crate::infer::InferCtxt;
|
||||
use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput};
|
||||
use crate::traits::query::NoSolution;
|
||||
use crate::traits::{ObligationCause, ObligationCtxt};
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
||||
use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt};
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
|
@ -69,16 +69,12 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
|
|||
}
|
||||
|
||||
let span = self.tcx.def_span(body_id);
|
||||
let result = param_env
|
||||
let result: Result<_, ErrorGuaranteed> = param_env
|
||||
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
|
||||
.fully_perform(self);
|
||||
.fully_perform(self, span);
|
||||
let result = match result {
|
||||
Ok(r) => r,
|
||||
Err(NoSolution) => {
|
||||
self.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
"implied_outlives_bounds failed to solve all obligations",
|
||||
);
|
||||
Err(_) => {
|
||||
return vec![];
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,9 +3,10 @@ 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;
|
||||
|
||||
|
@ -35,12 +36,16 @@ 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)?.0)
|
||||
Ok(scrape_region_constraints(infcx, self.closure, self.description, span)?.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +60,9 @@ impl<F> fmt::Debug for CustomTypeOp<F> {
|
|||
pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Fallible<R>,
|
||||
) -> Fallible<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>)> {
|
||||
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
|
||||
|
@ -70,16 +77,17 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>(
|
|||
|
||||
let value = infcx.commit_if_ok(|_| {
|
||||
let ocx = ObligationCtxt::new_in_snapshot(infcx);
|
||||
let value = op(&ocx)?;
|
||||
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 {
|
||||
infcx.tcx.sess.delay_span_bug(
|
||||
Err(infcx.tcx.sess.delay_span_bug(
|
||||
DUMMY_SP,
|
||||
format!("errors selecting obligation during MIR typeck: {:?}", errors),
|
||||
);
|
||||
Err(NoSolution)
|
||||
))
|
||||
}
|
||||
})?;
|
||||
|
||||
|
|
|
@ -4,11 +4,12 @@ use crate::infer::canonical::{
|
|||
use crate::infer::{InferCtxt, InferOk};
|
||||
use crate::traits::query::Fallible;
|
||||
use crate::traits::ObligationCause;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_infer::infer::canonical::Certainty;
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::traits::PredicateObligations;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::{ParamEnvAnd, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
use std::fmt;
|
||||
|
||||
pub mod ascribe_user_type;
|
||||
|
@ -32,7 +33,11 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug {
|
|||
/// 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>;
|
||||
}
|
||||
|
||||
/// The output from performing a type op
|
||||
|
@ -120,10 +125,16 @@ where
|
|||
type Output = Q::QueryResponse;
|
||||
type ErrorInfo = Canonical<'tcx, ParamEnvAnd<'tcx, Q>>;
|
||||
|
||||
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> {
|
||||
let mut region_constraints = QueryRegionConstraints::default();
|
||||
let (output, error_info, mut obligations, _) =
|
||||
Q::fully_perform_into(self, infcx, &mut region_constraints)?;
|
||||
Q::fully_perform_into(self, infcx, &mut region_constraints).map_err(|_| {
|
||||
infcx.tcx.sess.delay_span_bug(span, format!("error performing {self:?}"))
|
||||
})?;
|
||||
|
||||
// Typically, instantiating NLL query results does not
|
||||
// create obligations. However, in some cases there
|
||||
|
@ -151,7 +162,10 @@ where
|
|||
}
|
||||
}
|
||||
if !progress {
|
||||
return Err(NoSolution);
|
||||
return Err(infcx.tcx.sess.delay_span_bug(
|
||||
span,
|
||||
format!("ambiguity processing {obligations:?} from {self:?}"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue