diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 6a34bd4884d73..16c6fed9e9a42 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -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::*; @@ -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( + 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( + 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( + 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( + self, + cause: &ObligationCause<'tcx>, + param_env: ParamEnv<'tcx>, + define_opaque_types: DefineOpaqueTypes, + trace: TypeTrace<'tcx>, + expected: T, + actual: T, + ) -> InferResult<'tcx, ()> + where + T: Relate>, + { + 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( + 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( + 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>>, + ) -> 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> + Copy { @@ -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( self, define_opaque_types: DefineOpaqueTypes, @@ -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( self, define_opaque_types: DefineOpaqueTypes, @@ -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( self, define_opaque_types: DefineOpaqueTypes, @@ -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( self, define_opaque_types: DefineOpaqueTypes, @@ -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( self, define_opaque_types: DefineOpaqueTypes, @@ -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(self, expected: T, actual: T) -> InferResult<'tcx, T> where T: ToTrace<'tcx>, @@ -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>>,