mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
review
This commit is contained in:
parent
a2dfed6711
commit
412c6e0b07
@ -83,6 +83,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// version (resolve_vars_if_possible), this version will
|
||||
/// also select obligations if it seems useful, in an effort
|
||||
/// to get more type information.
|
||||
// FIXME(-Ztrait-solver=next): A lot of the calls to this method should
|
||||
// probably be `try_structurally_resolve_type` or `structurally_resolve_type` instead.
|
||||
pub(in super::super) fn resolve_vars_with_obligations(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.resolve_vars_with_obligations_and_mutate_fulfillment(ty, |_| {})
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::traits::error_reporting::TypeErrCtxtExt;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use crate::traits::{needs_normalization, TraitEngineExt as _};
|
||||
use crate::traits::{BoundVarReplacer, PlaceholderReplacer};
|
||||
use crate::traits::{needs_normalization, BoundVarReplacer, PlaceholderReplacer};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_infer::infer::at::At;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
@ -13,22 +12,23 @@ use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex};
|
||||
use rustc_middle::ty::{FallibleTypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
|
||||
|
||||
use super::FulfillmentCtxt;
|
||||
|
||||
/// Deeply normalize all aliases in `value`. This does not handle inference and expects
|
||||
/// its input to be already fully resolved.
|
||||
pub(crate) fn deeply_normalize<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
at: At<'_, 'tcx>,
|
||||
value: T,
|
||||
) -> Result<T, Vec<FulfillmentError<'tcx>>> {
|
||||
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(&at.infcx);
|
||||
let mut folder =
|
||||
NormalizationFolder { at, fulfill_cx: &mut *fulfill_cx, depth: 0, universes: Vec::new() };
|
||||
let fulfill_cx = FulfillmentCtxt::new();
|
||||
let mut folder = NormalizationFolder { at, fulfill_cx, depth: 0, universes: Vec::new() };
|
||||
|
||||
value.try_fold_with(&mut folder)
|
||||
}
|
||||
|
||||
struct NormalizationFolder<'me, 'tcx> {
|
||||
at: At<'me, 'tcx>,
|
||||
fulfill_cx: &'me mut dyn TraitEngine<'tcx>,
|
||||
fulfill_cx: FulfillmentCtxt<'tcx>,
|
||||
depth: usize,
|
||||
universes: Vec<Option<UniverseIndex>>,
|
||||
}
|
||||
@ -163,16 +163,14 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
|
||||
return Ok(ty);
|
||||
}
|
||||
|
||||
let (kind, data) = match *ty.kind() {
|
||||
ty::Alias(kind, alias_ty) => (kind, alias_ty),
|
||||
_ => return ty.try_super_fold_with(self),
|
||||
};
|
||||
|
||||
// We don't normalize opaque types unless we have
|
||||
// `Reveal::All`, even if we're in the defining scope.
|
||||
if matches!(kind, ty::Opaque) && reveal == Reveal::UserFacing {
|
||||
return ty.try_super_fold_with(self);
|
||||
let data = match *ty.kind() {
|
||||
ty::Alias(kind, alias_ty) if kind != ty::Opaque || reveal == Reveal::UserFacing => {
|
||||
alias_ty
|
||||
}
|
||||
_ => return ty.try_super_fold_with(self),
|
||||
};
|
||||
|
||||
if data.has_escaping_bound_vars() {
|
||||
let (data, mapped_regions, mapped_types, mapped_consts) =
|
||||
|
@ -409,7 +409,12 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||
)
|
||||
}
|
||||
|
||||
/// Normalize a type and process all resulting obligations, returning any errors
|
||||
/// Normalize a type and process all resulting obligations, returning any errors.
|
||||
///
|
||||
/// FIXME(-Ztrait-solver=next): This should be replaced by `At::deeply_normalize`
|
||||
/// which has the same behavior with the new solver. Because using a separate
|
||||
/// fulfillment context worsens caching in the old solver, `At::deeply_normalize`
|
||||
/// is still lazy with the old solver as it otherwise negatively impacts perf.
|
||||
#[instrument(skip_all)]
|
||||
pub fn fully_normalize<'tcx, T>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
|
@ -58,12 +58,18 @@ pub trait NormalizeExt<'tcx> {
|
||||
|
||||
/// Deeply normalizes `value`, replacing all aliases which can by normalized in
|
||||
/// the current environment. In the new solver this errors in case normalization
|
||||
/// fails or is ambiguous. This only normalize opaque types with `Reveal::All`.
|
||||
/// fails or is ambiguous. This only normalizes opaque types with `Reveal::All`.
|
||||
///
|
||||
/// In the old solver this simply uses `normalizes` and adds the nested obligations
|
||||
/// to the `fulfill_cx`. This is necessary as we otherwise end up recomputing the
|
||||
/// same goals in both a temporary and the shared context which negatively impacts
|
||||
/// performance as these don't share caching.
|
||||
///
|
||||
/// FIXME(-Ztrait-solver=next): This has the same behavior as `traits::fully_normalize`
|
||||
/// in the new solver, but because of performance reasons, we currently reuse an
|
||||
/// existing fulfillment context in the old solver. Once we also eagerly prove goals with
|
||||
/// the old solver or have removed the old solver, remove `traits::fully_normalize` and
|
||||
/// rename this function to `At::fully_normalize`.
|
||||
fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
self,
|
||||
value: T,
|
||||
|
Loading…
Reference in New Issue
Block a user