Make TraitEngines generic over error

This commit is contained in:
Michael Goulet
2024-06-01 14:12:34 -04:00
parent 084ccd2390
commit 54b2b7d460
23 changed files with 253 additions and 157 deletions

View File

@@ -1,23 +1,29 @@
use std::marker::PhantomData;
use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt};
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{BoundVarReplacer, PlaceholderReplacer};
use crate::traits::{BoundVarReplacer, FulfillmentError, PlaceholderReplacer};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_infer::infer::at::At;
use rustc_infer::infer::InferCtxt;
use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine};
use rustc_infer::traits::{FromSolverError, FulfillmentErrorLike, Obligation, TraitEngine};
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{self, Ty, TyCtxt, UniverseIndex};
use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
use super::FulfillmentCtxt;
use super::{FulfillmentCtxt, NextSolverError};
/// Deeply normalize all aliases in `value`. This does not handle inference and expects
/// its input to be already fully resolved.
pub fn deeply_normalize<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
pub fn deeply_normalize<
'tcx,
T: TypeFoldable<TyCtxt<'tcx>>,
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
>(
at: At<'_, 'tcx>,
value: T,
) -> Result<T, Vec<FulfillmentError<'tcx>>> {
) -> Result<T, Vec<E>> {
assert!(!value.has_escaping_bound_vars());
deeply_normalize_with_skipped_universes(at, value, vec![])
}
@@ -28,29 +34,32 @@ pub fn deeply_normalize<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
/// Additionally takes a list of universes which represents the binders which have been
/// entered before passing `value` to the function. This is currently needed for
/// `normalize_erasing_regions`, which skips binders as it walks through a type.
pub fn deeply_normalize_with_skipped_universes<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
pub fn deeply_normalize_with_skipped_universes<
'tcx,
T: TypeFoldable<TyCtxt<'tcx>>,
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
>(
at: At<'_, 'tcx>,
value: T,
universes: Vec<Option<UniverseIndex>>,
) -> Result<T, Vec<FulfillmentError<'tcx>>> {
) -> Result<T, Vec<E>> {
let fulfill_cx = FulfillmentCtxt::new(at.infcx);
let mut folder = NormalizationFolder { at, fulfill_cx, depth: 0, universes };
let mut folder =
NormalizationFolder { at, fulfill_cx, depth: 0, universes, _errors: PhantomData };
value.try_fold_with(&mut folder)
}
struct NormalizationFolder<'me, 'tcx> {
struct NormalizationFolder<'me, 'tcx, E: FulfillmentErrorLike<'tcx>> {
at: At<'me, 'tcx>,
fulfill_cx: FulfillmentCtxt<'tcx>,
fulfill_cx: FulfillmentCtxt<'tcx, E>,
depth: usize,
universes: Vec<Option<UniverseIndex>>,
_errors: PhantomData<E>,
}
impl<'tcx> NormalizationFolder<'_, 'tcx> {
fn normalize_alias_ty(
&mut self,
alias_ty: Ty<'tcx>,
) -> Result<Ty<'tcx>, Vec<FulfillmentError<'tcx>>> {
impl<'tcx, E: FromSolverError<'tcx, NextSolverError<'tcx>>> NormalizationFolder<'_, 'tcx, E> {
fn normalize_alias_ty(&mut self, alias_ty: Ty<'tcx>) -> Result<Ty<'tcx>, Vec<E>> {
assert!(matches!(alias_ty.kind(), ty::Alias(..)));
let infcx = self.at.infcx;
@@ -101,7 +110,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
&mut self,
ty: Ty<'tcx>,
uv: ty::UnevaluatedConst<'tcx>,
) -> Result<ty::Const<'tcx>, Vec<FulfillmentError<'tcx>>> {
) -> Result<ty::Const<'tcx>, Vec<E>> {
let infcx = self.at.infcx;
let tcx = infcx.tcx;
let recursion_limit = tcx.recursion_limit();
@@ -141,8 +150,10 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
}
}
impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
type Error = Vec<FulfillmentError<'tcx>>;
impl<'tcx, E: FromSolverError<'tcx, NextSolverError<'tcx>>> FallibleTypeFolder<TyCtxt<'tcx>>
for NormalizationFolder<'_, 'tcx, E>
{
type Error = Vec<E>;
fn interner(&self) -> TyCtxt<'tcx> {
self.at.infcx.tcx
@@ -242,7 +253,8 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_,
ty,
vec![None; ty.outer_exclusive_binder().as_usize()],
)
.unwrap_or_else(|_| ty.super_fold_with(self))
// TODO:
.unwrap_or_else(|_: Vec<FulfillmentError<'tcx>>| ty.super_fold_with(self))
}
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
@@ -251,6 +263,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for DeeplyNormalizeForDiagnosticsFolder<'_,
ct,
vec![None; ct.outer_exclusive_binder().as_usize()],
)
.unwrap_or_else(|_| ct.super_fold_with(self))
// TODO:
.unwrap_or_else(|_: Vec<FulfillmentError<'tcx>>| ct.super_fold_with(self))
}
}