Skip to content

Document normalization methods At::{normalize,query_normalize} #105144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ pub struct InferOk<'tcx, T> {
}
pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;

pub type Bound<T> = Option<T>;
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result"

Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::util::impl_subject_and_oblig;
use crate::traits::SkipLeakCheck;
use crate::traits::{
self, Normalized, Obligation, ObligationCause, ObligationCtxt, PredicateObligation,
PredicateObligations, SelectionContext,
self, Obligation, ObligationCause, ObligationCtxt, PredicateObligation, PredicateObligations,
SelectionContext,
};
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::Diagnostic;
Expand All @@ -30,6 +30,8 @@ use std::fmt::Debug;
use std::iter;
use std::ops::ControlFlow;

use super::NormalizeExt;

/// Whether we do the orphan check relative to this crate or
/// to some remote crate.
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -128,8 +130,8 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates,
};

let Normalized { value: mut header, obligations } =
traits::normalize(selcx, param_env, ObligationCause::dummy(), header);
let InferOk { value: mut header, obligations } =
selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(header);

header.predicates.extend(obligations.into_iter().map(|o| o.predicate));
header
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ pub use self::object_safety::astconv_object_safety_violations;
pub use self::object_safety::is_vtable_safe_method;
pub use self::object_safety::MethodViolationCode;
pub use self::object_safety::ObjectSafetyViolation;
pub(crate) use self::project::{normalize, normalize_to};
pub use self::project::{normalize_projection_type, NormalizeExt};
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
Expand Down
40 changes: 7 additions & 33 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,18 @@ pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>>
pub(super) struct InProgress;

pub trait NormalizeExt<'tcx> {
/// Normalize a value using the `AssocTypeNormalizer`.
///
/// This normalization should be used when the type contains inference variables or the
/// projection may be fallible.
fn normalize<T: TypeFoldable<'tcx>>(&self, t: T) -> InferOk<'tcx, T>;
}

impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
fn normalize<T: TypeFoldable<'tcx>>(&self, value: T) -> InferOk<'tcx, T> {
let mut selcx = SelectionContext::new(self.infcx);
let Normalized { value, obligations } =
normalize(&mut selcx, self.param_env, self.cause.clone(), value);
normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
InferOk { value, obligations }
}
}
Expand Down Expand Up @@ -303,37 +307,6 @@ fn project_and_unify_type<'cx, 'tcx>(
}
}

/// Normalizes any associated type projections in `value`, replacing
/// them with a fully resolved type where possible. The return value
/// combines the normalized result and any additional obligations that
/// were incurred as result.
pub(crate) fn normalize<'a, 'b, 'tcx, T>(
selcx: &'a mut SelectionContext<'b, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
cause: ObligationCause<'tcx>,
value: T,
) -> Normalized<'tcx, T>
where
T: TypeFoldable<'tcx>,
{
let mut obligations = Vec::new();
let value = normalize_to(selcx, param_env, cause, value, &mut obligations);
Normalized { value, obligations }
}

pub(crate) fn normalize_to<'a, 'b, 'tcx, T>(
selcx: &'a mut SelectionContext<'b, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
cause: ObligationCause<'tcx>,
value: T,
obligations: &mut Vec<PredicateObligation<'tcx>>,
) -> T
where
T: TypeFoldable<'tcx>,
{
normalize_with_depth_to(selcx, param_env, cause, 0, value, obligations)
}

/// As `normalize`, but with a custom depth.
pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>(
selcx: &'a mut SelectionContext<'b, 'tcx>,
Expand Down Expand Up @@ -2324,10 +2297,11 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
},
));

let ty = super::normalize_to(
let ty = normalize_with_depth_to(
selcx,
obligation.param_env,
cause.clone(),
obligation.recursion_depth + 1,
tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
.map_bound(|tys| {
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.item_def_id])
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_trait_selection/src/traits/query/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ use super::NoSolution;
pub use rustc_middle::traits::query::NormalizationResult;

pub trait QueryNormalizeExt<'tcx> {
/// Normalize a value using the `QueryNormalizer`.
///
/// This normalization should *only* be used when the projection does not
/// have possible ambiguity or may not be well-formed.
///
/// After codegen, when lifetimes do not matter, it is preferable to instead
/// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
where
T: TypeFoldable<'tcx>;
Expand Down