1
Fork 0

Add cycle errors to ScrubbedTraitError to remove a couple more calls to new_with_diagnostics

This commit is contained in:
Michael Goulet 2024-06-02 18:36:11 -04:00
parent 27f5eccd1f
commit 1e72c7f536
14 changed files with 42 additions and 64 deletions

View file

@ -1,9 +1,5 @@
use crate::solve::NextSolverError;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use crate::traits::{
self, FromSolverError, Obligation, ObligationCause, ObligationCtxt, OldSolverError,
SelectionContext,
};
use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt, SelectionContext};
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
@ -124,21 +120,19 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
/// bound for the closure and in part because it is convenient to
/// have `'tcx` be free on this function so that we can talk about
/// `K: TypeFoldable<TyCtxt<'tcx>>`.)
fn enter_canonical_trait_query<K, R, E>(
fn enter_canonical_trait_query<K, R>(
self,
canonical_key: &Canonical<'tcx, K>,
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx, E>, K) -> Result<R, NoSolution>,
operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result<R, NoSolution>,
) -> Result<CanonicalQueryResponse<'tcx, R>, NoSolution>
where
K: TypeFoldable<TyCtxt<'tcx>>,
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
E: FromSolverError<'tcx, NextSolverError<'tcx>>
+ FromSolverError<'tcx, OldSolverError<'tcx>>,
{
let (infcx, key, canonical_inference_vars) =
self.build_with_canonical(DUMMY_SP, canonical_key);
let ocx = ObligationCtxt::new_generic(&infcx);
let ocx = ObligationCtxt::new(&infcx);
let value = operation(&ocx, key)?;
ocx.make_canonicalized_query_response(canonical_inference_vars, value)
}

View file

@ -28,7 +28,7 @@ impl<'tcx> InferCtxt<'tcx> {
),
ty,
)
.map_err(|_: Vec<ScrubbedTraitError>| NoSolution)
.map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution)
} else {
Ok(ty)
}

View file

@ -225,7 +225,7 @@ impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for FulfillmentError<'tc
}
}
impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for ScrubbedTraitError {
impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for ScrubbedTraitError<'tcx> {
fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: NextSolverError<'tcx>) -> Self {
match error {
NextSolverError::TrueError(_) => ScrubbedTraitError::TrueError,

View file

@ -253,7 +253,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_,
ty,
vec![None; ty.outer_exclusive_binder().as_usize()],
)
.unwrap_or_else(|_: Vec<ScrubbedTraitError>| ty.super_fold_with(self))
.unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ty.super_fold_with(self))
}
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
@ -262,6 +262,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_,
ct,
vec![None; ct.outer_exclusive_binder().as_usize()],
)
.unwrap_or_else(|_: Vec<ScrubbedTraitError>| ct.super_fold_with(self))
.unwrap_or_else(|_: Vec<ScrubbedTraitError<'tcx>>| ct.super_fold_with(self))
}
}

View file

@ -54,7 +54,7 @@ impl<
/// Used if you want to have pleasant experience when dealing
/// with obligations outside of hir or mir typeck.
pub struct ObligationCtxt<'a, 'tcx, E = ScrubbedTraitError> {
pub struct ObligationCtxt<'a, 'tcx, E = ScrubbedTraitError<'tcx>> {
pub infcx: &'a InferCtxt<'tcx>,
engine: RefCell<Box<dyn TraitEngine<'tcx, E>>>,
}
@ -65,21 +65,12 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>> {
}
}
impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, ScrubbedTraitError> {
impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, ScrubbedTraitError<'tcx>> {
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'tcx, _>>::new(infcx)) }
}
}
impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E>
where
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
{
pub fn new_generic(infcx: &'a InferCtxt<'tcx>) -> Self {
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'tcx, _>>::new(infcx)) }
}
}
impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E>
where
E: FulfillmentErrorLike<'tcx>,

View file

@ -856,16 +856,15 @@ impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for FulfillmentError<'tcx
}
}
impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError {
impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError<'tcx> {
fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self {
match error.error {
FulfillmentErrorCode::Select(_)
| FulfillmentErrorCode::Project(_)
| FulfillmentErrorCode::Subtype(_, _)
| FulfillmentErrorCode::ConstEquate(_, _) => ScrubbedTraitError::TrueError,
FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => {
ScrubbedTraitError::Ambiguity
}
FulfillmentErrorCode::Ambiguity { overflow: _ } => ScrubbedTraitError::Ambiguity,
FulfillmentErrorCode::Cycle(cycle) => ScrubbedTraitError::Cycle(cycle),
}
}
}

View file

@ -77,24 +77,26 @@ pub use rustc_infer::traits::*;
/// error itself (except for if it's an ambiguity or true error).
///
/// use [`ObligationCtxt::new_with_diagnostics`] to get a [`FulfillmentError`].
#[derive(Copy, Clone, Debug)]
pub enum ScrubbedTraitError {
#[derive(Clone, Debug)]
pub enum ScrubbedTraitError<'tcx> {
/// A real error. This goal definitely does not hold.
TrueError,
/// An ambiguity. This goal may hold if further inference is done.
Ambiguity,
/// An old-solver-style cycle error, which will fatal.
Cycle(Vec<PredicateObligation<'tcx>>),
}
impl ScrubbedTraitError {
impl<'tcx> ScrubbedTraitError<'tcx> {
fn is_true_error(&self) -> bool {
match self {
ScrubbedTraitError::TrueError => true,
ScrubbedTraitError::Ambiguity => false,
ScrubbedTraitError::Ambiguity | ScrubbedTraitError::Cycle(_) => false,
}
}
}
impl<'tcx> FulfillmentErrorLike<'tcx> for ScrubbedTraitError {
impl<'tcx> FulfillmentErrorLike<'tcx> for ScrubbedTraitError<'tcx> {
fn is_true_error(&self) -> bool {
self.is_true_error()
}

View file

@ -76,7 +76,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> {
};
if self.infcx.next_trait_solver() {
match crate::solve::deeply_normalize_with_skipped_universes::<_, ScrubbedTraitError>(
match crate::solve::deeply_normalize_with_skipped_universes::<_, ScrubbedTraitError<'tcx>>(
self, value, universes,
) {
Ok(value) => return Ok(Normalized { value, obligations: vec![] }),

View file

@ -267,7 +267,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
ocx.infcx.at(&ObligationCause::dummy(), param_env),
ty_a,
)
.map_err(|_errs: Vec<ScrubbedTraitError>| NoSolution)?;
.map_err(|_errs: Vec<ScrubbedTraitError<'tcx>>| NoSolution)?;
}
let mut components = smallvec![];
push_outlives_components(tcx, ty_a, &mut components);