Rollup merge of #125664 - compiler-errors:trace-tweaks, r=lcnr
Tweak relations to no longer rely on `TypeTrace` Remove `At::trace`, and inline all of the `Trace::equate`,etc methods into `At`. The only nontrivial change is that we use `AliasTerm` to relate two unevaluated consts in the old-solver impl of `ConstEquate`, since `AliasTerm` does implement `ToTrace` and will relate the args structurally (shallowly). r? lcnr
This commit is contained in:
commit
4c1228276b
8 changed files with 96 additions and 149 deletions
|
@ -1158,7 +1158,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let (a_sig, b_sig) = self.normalize(new.span, (a_sig, b_sig));
|
let (a_sig, b_sig) = self.normalize(new.span, (a_sig, b_sig));
|
||||||
let sig = self
|
let sig = self
|
||||||
.at(cause, self.param_env)
|
.at(cause, self.param_env)
|
||||||
.trace(prev_ty, new_ty)
|
|
||||||
.lub(DefineOpaqueTypes::Yes, a_sig, b_sig)
|
.lub(DefineOpaqueTypes::Yes, a_sig, b_sig)
|
||||||
.map(|ok| self.register_infer_ok_obligations(ok))?;
|
.map(|ok| self.register_infer_ok_obligations(ok))?;
|
||||||
|
|
||||||
|
|
|
@ -48,11 +48,6 @@ pub struct At<'a, 'tcx> {
|
||||||
pub param_env: ty::ParamEnv<'tcx>,
|
pub param_env: ty::ParamEnv<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Trace<'a, 'tcx> {
|
|
||||||
at: At<'a, 'tcx>,
|
|
||||||
trace: TypeTrace<'tcx>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> InferCtxt<'tcx> {
|
impl<'tcx> InferCtxt<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn at<'a>(
|
pub fn at<'a>(
|
||||||
|
@ -109,9 +104,6 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
||||||
/// call like `foo(x)`, where `foo: fn(i32)`, you might have
|
/// call like `foo(x)`, where `foo: fn(i32)`, you might have
|
||||||
/// `sup(i32, x)`, since the "expected" type is the type that
|
/// `sup(i32, x)`, since the "expected" type is the type that
|
||||||
/// appears in the signature.
|
/// appears in the signature.
|
||||||
///
|
|
||||||
/// See [`At::trace`] and [`Trace::sub`] for a version of
|
|
||||||
/// this method that only requires `T: Relate<'tcx>`
|
|
||||||
pub fn sup<T>(
|
pub fn sup<T>(
|
||||||
self,
|
self,
|
||||||
define_opaque_types: DefineOpaqueTypes,
|
define_opaque_types: DefineOpaqueTypes,
|
||||||
|
@ -121,13 +113,19 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
||||||
where
|
where
|
||||||
T: ToTrace<'tcx>,
|
T: ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
self.trace(expected, actual).sup(define_opaque_types, expected, actual)
|
let mut fields = CombineFields::new(
|
||||||
|
self.infcx,
|
||||||
|
ToTrace::to_trace(self.cause, true, expected, actual),
|
||||||
|
self.param_env,
|
||||||
|
define_opaque_types,
|
||||||
|
);
|
||||||
|
fields
|
||||||
|
.sup()
|
||||||
|
.relate(expected, actual)
|
||||||
|
.map(|_| InferOk { value: (), obligations: fields.obligations })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes `expected <: actual`.
|
/// Makes `expected <: actual`.
|
||||||
///
|
|
||||||
/// See [`At::trace`] and [`Trace::sub`] for a version of
|
|
||||||
/// this method that only requires `T: Relate<'tcx>`
|
|
||||||
pub fn sub<T>(
|
pub fn sub<T>(
|
||||||
self,
|
self,
|
||||||
define_opaque_types: DefineOpaqueTypes,
|
define_opaque_types: DefineOpaqueTypes,
|
||||||
|
@ -137,13 +135,19 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
||||||
where
|
where
|
||||||
T: ToTrace<'tcx>,
|
T: ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
self.trace(expected, actual).sub(define_opaque_types, expected, actual)
|
let mut fields = CombineFields::new(
|
||||||
|
self.infcx,
|
||||||
|
ToTrace::to_trace(self.cause, true, expected, actual),
|
||||||
|
self.param_env,
|
||||||
|
define_opaque_types,
|
||||||
|
);
|
||||||
|
fields
|
||||||
|
.sub()
|
||||||
|
.relate(expected, actual)
|
||||||
|
.map(|_| InferOk { value: (), obligations: fields.obligations })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes `expected <: actual`.
|
/// Makes `expected == actual`.
|
||||||
///
|
|
||||||
/// See [`At::trace`] and [`Trace::eq`] for a version of
|
|
||||||
/// this method that only requires `T: Relate<'tcx>`
|
|
||||||
pub fn eq<T>(
|
pub fn eq<T>(
|
||||||
self,
|
self,
|
||||||
define_opaque_types: DefineOpaqueTypes,
|
define_opaque_types: DefineOpaqueTypes,
|
||||||
|
@ -153,7 +157,40 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
||||||
where
|
where
|
||||||
T: ToTrace<'tcx>,
|
T: ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
self.trace(expected, actual).eq(define_opaque_types, expected, actual)
|
let mut fields = CombineFields::new(
|
||||||
|
self.infcx,
|
||||||
|
ToTrace::to_trace(self.cause, true, expected, actual),
|
||||||
|
self.param_env,
|
||||||
|
define_opaque_types,
|
||||||
|
);
|
||||||
|
fields
|
||||||
|
.equate(StructurallyRelateAliases::No)
|
||||||
|
.relate(expected, actual)
|
||||||
|
.map(|_| InferOk { value: (), obligations: fields.obligations })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Equates `expected` and `found` while structurally relating aliases.
|
||||||
|
/// This should only be used inside of the next generation trait solver
|
||||||
|
/// when relating rigid aliases.
|
||||||
|
pub fn eq_structurally_relating_aliases<T>(
|
||||||
|
self,
|
||||||
|
expected: T,
|
||||||
|
actual: T,
|
||||||
|
) -> InferResult<'tcx, ()>
|
||||||
|
where
|
||||||
|
T: ToTrace<'tcx>,
|
||||||
|
{
|
||||||
|
assert!(self.infcx.next_trait_solver());
|
||||||
|
let mut fields = CombineFields::new(
|
||||||
|
self.infcx,
|
||||||
|
ToTrace::to_trace(self.cause, true, expected, actual),
|
||||||
|
self.param_env,
|
||||||
|
DefineOpaqueTypes::Yes,
|
||||||
|
);
|
||||||
|
fields
|
||||||
|
.equate(StructurallyRelateAliases::Yes)
|
||||||
|
.relate(expected, actual)
|
||||||
|
.map(|_| InferOk { value: (), obligations: fields.obligations })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn relate<T>(
|
pub fn relate<T>(
|
||||||
|
@ -185,9 +222,6 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
||||||
/// this can result in an error (e.g., if asked to compute LUB of
|
/// 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
|
/// u32 and i32), it is meaningful to call one of them the
|
||||||
/// "expected type".
|
/// "expected type".
|
||||||
///
|
|
||||||
/// See [`At::trace`] and [`Trace::lub`] for a version of
|
|
||||||
/// this method that only requires `T: Relate<'tcx>`
|
|
||||||
pub fn lub<T>(
|
pub fn lub<T>(
|
||||||
self,
|
self,
|
||||||
define_opaque_types: DefineOpaqueTypes,
|
define_opaque_types: DefineOpaqueTypes,
|
||||||
|
@ -197,15 +231,21 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
||||||
where
|
where
|
||||||
T: ToTrace<'tcx>,
|
T: ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
self.trace(expected, actual).lub(define_opaque_types, expected, actual)
|
let mut fields = CombineFields::new(
|
||||||
|
self.infcx,
|
||||||
|
ToTrace::to_trace(self.cause, true, expected, actual),
|
||||||
|
self.param_env,
|
||||||
|
define_opaque_types,
|
||||||
|
);
|
||||||
|
fields
|
||||||
|
.lub()
|
||||||
|
.relate(expected, actual)
|
||||||
|
.map(|value| InferOk { value, obligations: fields.obligations })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the greatest-lower-bound, or mutual subtype, of two
|
/// Computes the greatest-lower-bound, or mutual subtype, of two
|
||||||
/// values. As with `lub` order doesn't matter, except for error
|
/// values. As with `lub` order doesn't matter, except for error
|
||||||
/// cases.
|
/// cases.
|
||||||
///
|
|
||||||
/// See [`At::trace`] and [`Trace::glb`] for a version of
|
|
||||||
/// this method that only requires `T: Relate<'tcx>`
|
|
||||||
pub fn glb<T>(
|
pub fn glb<T>(
|
||||||
self,
|
self,
|
||||||
define_opaque_types: DefineOpaqueTypes,
|
define_opaque_types: DefineOpaqueTypes,
|
||||||
|
@ -215,105 +255,16 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
||||||
where
|
where
|
||||||
T: ToTrace<'tcx>,
|
T: ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
self.trace(expected, actual).glb(define_opaque_types, expected, actual)
|
let mut fields = CombineFields::new(
|
||||||
}
|
self.infcx,
|
||||||
|
ToTrace::to_trace(self.cause, true, expected, actual),
|
||||||
/// Sets the "trace" values that will be used for
|
self.param_env,
|
||||||
/// error-reporting, but doesn't actually perform any operation
|
define_opaque_types,
|
||||||
/// yet (this is useful when you want to set the trace using
|
);
|
||||||
/// distinct values from those you wish to operate upon).
|
|
||||||
pub fn trace<T>(self, expected: T, actual: T) -> Trace<'a, 'tcx>
|
|
||||||
where
|
|
||||||
T: ToTrace<'tcx>,
|
|
||||||
{
|
|
||||||
let trace = ToTrace::to_trace(self.cause, true, expected, actual);
|
|
||||||
Trace { at: self, trace }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> Trace<'a, 'tcx> {
|
|
||||||
/// Makes `a <: b`.
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
|
||||||
pub fn sub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
|
|
||||||
where
|
|
||||||
T: Relate<'tcx>,
|
|
||||||
{
|
|
||||||
let Trace { at, trace } = self;
|
|
||||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
|
|
||||||
fields
|
|
||||||
.sub()
|
|
||||||
.relate(a, b)
|
|
||||||
.map(move |_| InferOk { value: (), obligations: fields.obligations })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Makes `a :> b`.
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
|
||||||
pub fn sup<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
|
|
||||||
where
|
|
||||||
T: Relate<'tcx>,
|
|
||||||
{
|
|
||||||
let Trace { at, trace } = self;
|
|
||||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
|
|
||||||
fields
|
|
||||||
.sup()
|
|
||||||
.relate(a, b)
|
|
||||||
.map(move |_| InferOk { value: (), obligations: fields.obligations })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Makes `a == b`.
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
|
||||||
pub fn eq<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, ()>
|
|
||||||
where
|
|
||||||
T: Relate<'tcx>,
|
|
||||||
{
|
|
||||||
let Trace { at, trace } = self;
|
|
||||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
|
|
||||||
fields
|
|
||||||
.equate(StructurallyRelateAliases::No)
|
|
||||||
.relate(a, b)
|
|
||||||
.map(move |_| InferOk { value: (), obligations: fields.obligations })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Equates `a` and `b` while structurally relating aliases. This should only
|
|
||||||
/// be used inside of the next generation trait solver when relating rigid aliases.
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
|
||||||
pub fn eq_structurally_relating_aliases<T>(self, a: T, b: T) -> InferResult<'tcx, ()>
|
|
||||||
where
|
|
||||||
T: Relate<'tcx>,
|
|
||||||
{
|
|
||||||
let Trace { at, trace } = self;
|
|
||||||
debug_assert!(at.infcx.next_trait_solver());
|
|
||||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, DefineOpaqueTypes::Yes);
|
|
||||||
fields
|
|
||||||
.equate(StructurallyRelateAliases::Yes)
|
|
||||||
.relate(a, b)
|
|
||||||
.map(move |_| InferOk { value: (), obligations: fields.obligations })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
|
||||||
pub fn lub<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, T>
|
|
||||||
where
|
|
||||||
T: Relate<'tcx>,
|
|
||||||
{
|
|
||||||
let Trace { at, trace } = self;
|
|
||||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
|
|
||||||
fields
|
|
||||||
.lub()
|
|
||||||
.relate(a, b)
|
|
||||||
.map(move |t| InferOk { value: t, obligations: fields.obligations })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
|
||||||
pub fn glb<T>(self, define_opaque_types: DefineOpaqueTypes, a: T, b: T) -> InferResult<'tcx, T>
|
|
||||||
where
|
|
||||||
T: Relate<'tcx>,
|
|
||||||
{
|
|
||||||
let Trace { at, trace } = self;
|
|
||||||
let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
|
|
||||||
fields
|
fields
|
||||||
.glb()
|
.glb()
|
||||||
.relate(a, b)
|
.relate(expected, actual)
|
||||||
.map(move |t| InferOk { value: t, obligations: fields.obligations })
|
.map(|value| InferOk { value, obligations: fields.obligations })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -836,21 +836,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn combine_fields<'a>(
|
|
||||||
&'a self,
|
|
||||||
trace: TypeTrace<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
define_opaque_types: DefineOpaqueTypes,
|
|
||||||
) -> CombineFields<'a, 'tcx> {
|
|
||||||
CombineFields {
|
|
||||||
infcx: self,
|
|
||||||
trace,
|
|
||||||
param_env,
|
|
||||||
obligations: PredicateObligations::new(),
|
|
||||||
define_opaque_types,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, expected: T, actual: T) -> bool
|
pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, expected: T, actual: T) -> bool
|
||||||
where
|
where
|
||||||
T: at::ToTrace<'tcx>,
|
T: at::ToTrace<'tcx>,
|
||||||
|
|
|
@ -42,6 +42,17 @@ pub struct CombineFields<'infcx, 'tcx> {
|
||||||
pub define_opaque_types: DefineOpaqueTypes,
|
pub define_opaque_types: DefineOpaqueTypes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
||||||
|
pub fn new(
|
||||||
|
infcx: &'infcx InferCtxt<'tcx>,
|
||||||
|
trace: TypeTrace<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
define_opaque_types: DefineOpaqueTypes,
|
||||||
|
) -> Self {
|
||||||
|
Self { infcx, trace, param_env, define_opaque_types, obligations: vec![] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> InferCtxt<'tcx> {
|
impl<'tcx> InferCtxt<'tcx> {
|
||||||
pub fn super_combine_tys<R>(
|
pub fn super_combine_tys<R>(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -363,7 +363,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||||
for (&orig, response) in iter::zip(original_values, var_values.var_values) {
|
for (&orig, response) in iter::zip(original_values, var_values.var_values) {
|
||||||
let InferOk { value: (), obligations } = infcx
|
let InferOk { value: (), obligations } = infcx
|
||||||
.at(&cause, param_env)
|
.at(&cause, param_env)
|
||||||
.trace(orig, response)
|
|
||||||
.eq_structurally_relating_aliases(orig, response)
|
.eq_structurally_relating_aliases(orig, response)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(obligations.is_empty());
|
assert!(obligations.is_empty());
|
||||||
|
|
|
@ -776,7 +776,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||||
let InferOk { value: (), obligations } = self
|
let InferOk { value: (), obligations } = self
|
||||||
.infcx
|
.infcx
|
||||||
.at(&ObligationCause::dummy(), param_env)
|
.at(&ObligationCause::dummy(), param_env)
|
||||||
.trace(term, ctor_term)
|
|
||||||
.eq_structurally_relating_aliases(term, ctor_term)?;
|
.eq_structurally_relating_aliases(term, ctor_term)?;
|
||||||
debug_assert!(obligations.is_empty());
|
debug_assert!(obligations.is_empty());
|
||||||
self.relate(param_env, alias, variance, rigid_ctor)
|
self.relate(param_env, alias, variance, rigid_ctor)
|
||||||
|
@ -796,11 +795,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||||
rhs: T,
|
rhs: T,
|
||||||
) -> Result<(), NoSolution> {
|
) -> Result<(), NoSolution> {
|
||||||
let cause = ObligationCause::dummy();
|
let cause = ObligationCause::dummy();
|
||||||
let InferOk { value: (), obligations } = self
|
let InferOk { value: (), obligations } =
|
||||||
.infcx
|
self.infcx.at(&cause, param_env).eq_structurally_relating_aliases(lhs, rhs)?;
|
||||||
.at(&cause, param_env)
|
|
||||||
.trace(lhs, rhs)
|
|
||||||
.eq_structurally_relating_aliases(lhs, rhs)?;
|
|
||||||
assert!(obligations.is_empty());
|
assert!(obligations.is_empty());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -566,10 +566,13 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
if let Ok(new_obligations) = infcx
|
if let Ok(new_obligations) = infcx
|
||||||
.at(&obligation.cause, obligation.param_env)
|
.at(&obligation.cause, obligation.param_env)
|
||||||
.trace(c1, c2)
|
|
||||||
// Can define opaque types as this is only reachable with
|
// Can define opaque types as this is only reachable with
|
||||||
// `generic_const_exprs`
|
// `generic_const_exprs`
|
||||||
.eq(DefineOpaqueTypes::Yes, a.args, b.args)
|
.eq(
|
||||||
|
DefineOpaqueTypes::Yes,
|
||||||
|
ty::AliasTerm::from(a),
|
||||||
|
ty::AliasTerm::from(b),
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return ProcessResult::Changed(mk_pending(
|
return ProcessResult::Changed(mk_pending(
|
||||||
new_obligations.into_obligations(),
|
new_obligations.into_obligations(),
|
||||||
|
|
|
@ -910,10 +910,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
if let Ok(InferOk { obligations, value: () }) = self
|
if let Ok(InferOk { obligations, value: () }) = self
|
||||||
.infcx
|
.infcx
|
||||||
.at(&obligation.cause, obligation.param_env)
|
.at(&obligation.cause, obligation.param_env)
|
||||||
.trace(c1, c2)
|
|
||||||
// Can define opaque types as this is only reachable with
|
// Can define opaque types as this is only reachable with
|
||||||
// `generic_const_exprs`
|
// `generic_const_exprs`
|
||||||
.eq(DefineOpaqueTypes::Yes, a.args, b.args)
|
.eq(
|
||||||
|
DefineOpaqueTypes::Yes,
|
||||||
|
ty::AliasTerm::from(a),
|
||||||
|
ty::AliasTerm::from(b),
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return self.evaluate_predicates_recursively(
|
return self.evaluate_predicates_recursively(
|
||||||
previous_stack,
|
previous_stack,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue