Skip to content
Merged
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
151 changes: 150 additions & 1 deletion compiler/rustc_infer/src/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

use relate::lattice::{LatticeOp, LatticeOpKind};
use rustc_middle::ty::relate::solver_relating::RelateExt as NextSolverRelate;
use rustc_middle::ty::{Const, TypingMode};
use rustc_middle::ty::{Const, ParamEnv, TypingMode};
use rustc_span::bug;

use super::*;
Expand Down Expand Up @@ -124,6 +124,143 @@ impl<'tcx> InferCtxt<'tcx> {
forked.inner.borrow_mut().projection_cache().clear();
forked
}

/// Makes `actual <: expected`. For example, if type-checking a
/// call like `foo(x)`, where `foo: fn(i32)`, you might have
/// `sup(i32, x)`, since the "expected" type is the type that
/// appears in the signature.
///
/// If possible, prefer the wrapper methods on `ObligationCtxt`,
/// `FnCtxt`, or `TypeChecker`.
pub fn sup_raw<T>(
self,
cause: &ObligationCause<'tcx>,
param_env: ParamEnv<'tcx>,
define_opaque_types: DefineOpaqueTypes,
expected: T,
actual: T,
) -> InferResult<'tcx, ()>
where
T: ToTrace<'tcx>,
{
self.at(cause, param_env).sup(define_opaque_types, expected, actual)
}

/// Makes `expected <: actual`.
///
/// If possible, prefer the wrapper methods on `ObligationCtxt`,
/// `FnCtxt`, or `TypeChecker`.
pub fn sub_raw<T>(
self,
cause: &ObligationCause<'tcx>,
param_env: ParamEnv<'tcx>,
define_opaque_types: DefineOpaqueTypes,
expected: T,
actual: T,
) -> InferResult<'tcx, ()>
where
T: ToTrace<'tcx>,
{
self.at(cause, param_env).sub(define_opaque_types, expected, actual)
}

/// Makes `expected == actual`.
///
/// If possible, prefer the wrapper methods on `ObligationCtxt`,
/// `FnCtxt`, or `TypeChecker`.
pub fn eq_raw<T>(
self,
cause: &ObligationCause<'tcx>,
param_env: ParamEnv<'tcx>,
define_opaque_types: DefineOpaqueTypes,
expected: T,
actual: T,
) -> InferResult<'tcx, ()>
where
T: ToTrace<'tcx>,
{
self.eq_trace_raw(
cause,
param_env,
define_opaque_types,
ToTrace::to_trace(cause, expected, actual),
expected,
actual,
)
}

/// Makes `expected == actual`.
///
/// If possible, prefer the wrapper methods on `ObligationCtxt`,
/// `FnCtxt`, or `TypeChecker`.
pub fn eq_trace_raw<T>(
self,
cause: &ObligationCause<'tcx>,
param_env: ParamEnv<'tcx>,
define_opaque_types: DefineOpaqueTypes,
trace: TypeTrace<'tcx>,
expected: T,
actual: T,
) -> InferResult<'tcx, ()>
where
T: Relate<TyCtxt<'tcx>>,
{
self.at(cause, param_env).eq_trace(define_opaque_types, trace, expected, actual)
}

/// If possible, prefer the wrapper methods on `ObligationCtxt`,
/// `FnCtxt`, or `TypeChecker`.
pub fn relate_raw<T>(
self,
cause: &ObligationCause<'tcx>,
param_env: ParamEnv<'tcx>,
define_opaque_types: DefineOpaqueTypes,
expected: T,
variance: ty::Variance,
actual: T,
) -> InferResult<'tcx, ()>
where
T: ToTrace<'tcx>,
{
self.at(cause, param_env).relate(define_opaque_types, expected, variance, actual)
}

/// Computes the least-upper-bound, or mutual supertype, of two
/// values. The order of the arguments doesn't matter, but since
/// this can result in an error (e.g., if asked to compute LUB of
/// u32 and i32), it is meaningful to call one of them the
/// "expected type".
///
/// If possible, prefer the wrapper methods on `ObligationCtxt`,
/// `FnCtxt`, or `TypeChecker`.
pub fn lub_raw<T>(
self,
cause: &ObligationCause<'tcx>,
param_env: ParamEnv<'tcx>,
expected: T,
actual: T,
) -> InferResult<'tcx, T>
where
T: ToTrace<'tcx>,
{
self.at(cause, param_env).lub(expected, actual)
}

pub fn goals_to_obligations(
&self,
cause: &ObligationCause<'tcx>,
goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
) -> InferOk<'tcx, ()> {
InferOk {
value: (),
obligations: goals
.into_iter()
.map(|goal| {
Obligation::new(self.tcx, cause.clone(), goal.param_env, goal.predicate)
})
.collect(),
}
}
}

pub trait ToTrace<'tcx>: Relate<TyCtxt<'tcx>> + Copy {
Expand All @@ -135,6 +272,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
/// call like `foo(x)`, where `foo: fn(i32)`, you might have
/// `sup(i32, x)`, since the "expected" type is the type that
/// appears in the signature.
///
/// FIXME: To be removed in favor of the [`InferCtxt::sup_raw`] method instead.
pub fn sup<T>(
self,
define_opaque_types: DefineOpaqueTypes,
Expand Down Expand Up @@ -168,6 +307,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
}

/// Makes `expected <: actual`.
///
/// FIXME: To be removed in favor of the [`InferCtxt::sub_raw`] method instead.
pub fn sub<T>(
self,
define_opaque_types: DefineOpaqueTypes,
Expand Down Expand Up @@ -201,6 +342,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
}

/// Makes `expected == actual`.
///
/// FIXME: To be removed in favor of the [`InferCtxt::eq_raw`] method instead.
pub fn eq<T>(
self,
define_opaque_types: DefineOpaqueTypes,
Expand All @@ -219,6 +362,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
}

/// Makes `expected == actual`.
///
/// FIXME: To be removed in favor of the [`InferCtxt::eq_trace_raw`] method instead.
pub fn eq_trace<T>(
self,
define_opaque_types: DefineOpaqueTypes,
Expand Down Expand Up @@ -252,6 +397,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
}
}

/// FIXME: To be removed in favor of the [`InferCtxt::relate_raw`] method instead.
pub fn relate<T>(
self,
define_opaque_types: DefineOpaqueTypes,
Expand Down Expand Up @@ -281,6 +427,8 @@ impl<'a, 'tcx> At<'a, 'tcx> {
/// this can result in an error (e.g., if asked to compute LUB of
/// u32 and i32), it is meaningful to call one of them the
/// "expected type".
///
/// FIXME: To be removed in favor of the [`InferCtxt::lub_raw`] method instead.
pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
where
T: ToTrace<'tcx>,
Expand All @@ -295,6 +443,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
Ok(InferOk { value, obligations: op.into_obligations() })
}

/// FIXME: To be removed in favor of the [`InferCtxt::goals_to_obligations`] method instead.
fn goals_to_obligations(
&self,
goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
Expand Down
Loading