mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
Auto merge of #131343 - compiler-errors:remove-combine-fields, r=lcnr
Remove `CombineFields` This conflicts with #131263, but if this one lands first then perhaps #131263 could then go ahead and remove all the branching on solver in `TypeRelating`. We could perhaps then rename `TypeRelating` to `OldSolverRelating` or something, idk. r? lcnr
This commit is contained in:
commit
3ae715c8c6
@ -141,7 +141,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
|||||||
let at = self.at(&self.cause, self.fcx.param_env);
|
let at = self.at(&self.cause, self.fcx.param_env);
|
||||||
|
|
||||||
let res = if self.use_lub {
|
let res = if self.use_lub {
|
||||||
at.lub(DefineOpaqueTypes::Yes, b, a)
|
at.lub(b, a)
|
||||||
} else {
|
} else {
|
||||||
at.sup(DefineOpaqueTypes::Yes, b, a)
|
at.sup(DefineOpaqueTypes::Yes, b, a)
|
||||||
.map(|InferOk { value: (), obligations }| InferOk { value: b, obligations })
|
.map(|InferOk { value: (), obligations }| InferOk { value: b, obligations })
|
||||||
@ -1190,13 +1190,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
(ty::FnDef(..), ty::FnDef(..)) => {
|
(ty::FnDef(..), ty::FnDef(..)) => {
|
||||||
// Don't reify if the function types have a LUB, i.e., they
|
// Don't reify if the function types have a LUB, i.e., they
|
||||||
// are the same function and their parameters have a LUB.
|
// are the same function and their parameters have a LUB.
|
||||||
match self.commit_if_ok(|_| {
|
match self
|
||||||
self.at(cause, self.param_env).lub(
|
.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
|
||||||
DefineOpaqueTypes::Yes,
|
{
|
||||||
prev_ty,
|
|
||||||
new_ty,
|
|
||||||
)
|
|
||||||
}) {
|
|
||||||
// We have a LUB of prev_ty and new_ty, just return it.
|
// We have a LUB of prev_ty and new_ty, just return it.
|
||||||
Ok(ok) => return Ok(self.register_infer_ok_obligations(ok)),
|
Ok(ok) => return Ok(self.register_infer_ok_obligations(ok)),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@ -1239,7 +1235,7 @@ 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)
|
||||||
.lub(DefineOpaqueTypes::Yes, a_sig, b_sig)
|
.lub(a_sig, b_sig)
|
||||||
.map(|ok| self.register_infer_ok_obligations(ok))?;
|
.map(|ok| self.register_infer_ok_obligations(ok))?;
|
||||||
|
|
||||||
// Reify both sides and return the reified fn pointer type.
|
// Reify both sides and return the reified fn pointer type.
|
||||||
@ -1330,9 +1326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return Err(self
|
return Err(self
|
||||||
.commit_if_ok(|_| {
|
.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
|
||||||
self.at(cause, self.param_env).lub(DefineOpaqueTypes::Yes, prev_ty, new_ty)
|
|
||||||
})
|
|
||||||
.unwrap_err());
|
.unwrap_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1344,13 +1338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
Err(e)
|
Err(e)
|
||||||
} else {
|
} else {
|
||||||
Err(self
|
Err(self
|
||||||
.commit_if_ok(|_| {
|
.commit_if_ok(|_| self.at(cause, self.param_env).lub(prev_ty, new_ty))
|
||||||
self.at(cause, self.param_env).lub(
|
|
||||||
DefineOpaqueTypes::Yes,
|
|
||||||
prev_ty,
|
|
||||||
new_ty,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.unwrap_err())
|
.unwrap_err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,13 @@
|
|||||||
//! sometimes useful when the types of `c` and `d` are not traceable
|
//! sometimes useful when the types of `c` and `d` are not traceable
|
||||||
//! things. (That system should probably be refactored.)
|
//! things. (That system should probably be refactored.)
|
||||||
|
|
||||||
|
use relate::lattice::{LatticeOp, LatticeOpKind};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::{Const, ImplSubject};
|
use rustc_middle::ty::{Const, ImplSubject};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::infer::relate::type_relating::TypeRelating;
|
||||||
use crate::infer::relate::{Relate, StructurallyRelateAliases, TypeRelation};
|
use crate::infer::relate::{Relate, StructurallyRelateAliases, TypeRelation};
|
||||||
use crate::traits::Obligation;
|
|
||||||
|
|
||||||
/// Whether we should define opaque types or just treat them opaquely.
|
/// Whether we should define opaque types or just treat them opaquely.
|
||||||
///
|
///
|
||||||
@ -108,14 +109,16 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
|||||||
where
|
where
|
||||||
T: ToTrace<'tcx>,
|
T: ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
let mut fields = CombineFields::new(
|
let mut op = TypeRelating::new(
|
||||||
self.infcx,
|
self.infcx,
|
||||||
ToTrace::to_trace(self.cause, expected, actual),
|
ToTrace::to_trace(self.cause, expected, actual),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
define_opaque_types,
|
define_opaque_types,
|
||||||
|
StructurallyRelateAliases::No,
|
||||||
|
ty::Contravariant,
|
||||||
);
|
);
|
||||||
fields.sup().relate(expected, actual)?;
|
op.relate(expected, actual)?;
|
||||||
Ok(InferOk { value: (), obligations: fields.into_obligations() })
|
Ok(InferOk { value: (), obligations: op.into_obligations() })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes `expected <: actual`.
|
/// Makes `expected <: actual`.
|
||||||
@ -128,14 +131,16 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
|||||||
where
|
where
|
||||||
T: ToTrace<'tcx>,
|
T: ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
let mut fields = CombineFields::new(
|
let mut op = TypeRelating::new(
|
||||||
self.infcx,
|
self.infcx,
|
||||||
ToTrace::to_trace(self.cause, expected, actual),
|
ToTrace::to_trace(self.cause, expected, actual),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
define_opaque_types,
|
define_opaque_types,
|
||||||
|
StructurallyRelateAliases::No,
|
||||||
|
ty::Covariant,
|
||||||
);
|
);
|
||||||
fields.sub().relate(expected, actual)?;
|
op.relate(expected, actual)?;
|
||||||
Ok(InferOk { value: (), obligations: fields.into_obligations() })
|
Ok(InferOk { value: (), obligations: op.into_obligations() })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes `expected == actual`.
|
/// Makes `expected == actual`.
|
||||||
@ -167,45 +172,16 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
|||||||
where
|
where
|
||||||
T: Relate<TyCtxt<'tcx>>,
|
T: Relate<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
let mut fields = CombineFields::new(self.infcx, trace, self.param_env, define_opaque_types);
|
let mut op = TypeRelating::new(
|
||||||
fields.equate(StructurallyRelateAliases::No).relate(expected, actual)?;
|
|
||||||
Ok(InferOk {
|
|
||||||
value: (),
|
|
||||||
obligations: fields
|
|
||||||
.goals
|
|
||||||
.into_iter()
|
|
||||||
.map(|goal| {
|
|
||||||
Obligation::new(
|
|
||||||
self.infcx.tcx,
|
|
||||||
fields.trace.cause.clone(),
|
|
||||||
goal.param_env,
|
|
||||||
goal.predicate,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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,
|
self.infcx,
|
||||||
ToTrace::to_trace(self.cause, expected, actual),
|
trace,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
DefineOpaqueTypes::Yes,
|
define_opaque_types,
|
||||||
|
StructurallyRelateAliases::No,
|
||||||
|
ty::Invariant,
|
||||||
);
|
);
|
||||||
fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?;
|
op.relate(expected, actual)?;
|
||||||
Ok(InferOk { value: (), obligations: fields.into_obligations() })
|
Ok(InferOk { value: (), obligations: op.into_obligations() })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn relate<T>(
|
pub fn relate<T>(
|
||||||
@ -242,19 +218,16 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
|||||||
where
|
where
|
||||||
T: Relate<TyCtxt<'tcx>>,
|
T: Relate<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
let mut fields = CombineFields::new(
|
let mut op = TypeRelating::new(
|
||||||
self.infcx,
|
self.infcx,
|
||||||
TypeTrace::dummy(self.cause),
|
TypeTrace::dummy(self.cause),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
DefineOpaqueTypes::Yes,
|
DefineOpaqueTypes::Yes,
|
||||||
);
|
StructurallyRelateAliases::No,
|
||||||
fields.sub().relate_with_variance(
|
|
||||||
variance,
|
variance,
|
||||||
ty::VarianceDiagInfo::default(),
|
);
|
||||||
expected,
|
op.relate(expected, actual)?;
|
||||||
actual,
|
Ok(op.into_obligations().into_iter().map(|o| o.into()).collect())
|
||||||
)?;
|
|
||||||
Ok(fields.goals)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Used in the new solver since we don't care about tracking an `ObligationCause`.
|
/// Used in the new solver since we don't care about tracking an `ObligationCause`.
|
||||||
@ -266,14 +239,16 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
|||||||
where
|
where
|
||||||
T: Relate<TyCtxt<'tcx>>,
|
T: Relate<TyCtxt<'tcx>>,
|
||||||
{
|
{
|
||||||
let mut fields = CombineFields::new(
|
let mut op = TypeRelating::new(
|
||||||
self.infcx,
|
self.infcx,
|
||||||
TypeTrace::dummy(self.cause),
|
TypeTrace::dummy(self.cause),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
DefineOpaqueTypes::Yes,
|
DefineOpaqueTypes::Yes,
|
||||||
|
StructurallyRelateAliases::Yes,
|
||||||
|
ty::Invariant,
|
||||||
);
|
);
|
||||||
fields.equate(StructurallyRelateAliases::Yes).relate(expected, actual)?;
|
op.relate(expected, actual)?;
|
||||||
Ok(fields.goals)
|
Ok(op.into_obligations().into_iter().map(|o| o.into()).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the least-upper-bound, or mutual supertype, of two
|
/// Computes the least-upper-bound, or mutual supertype, of two
|
||||||
@ -281,45 +256,18 @@ 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".
|
||||||
pub fn lub<T>(
|
pub fn lub<T>(self, expected: T, actual: T) -> InferResult<'tcx, T>
|
||||||
self,
|
|
||||||
define_opaque_types: DefineOpaqueTypes,
|
|
||||||
expected: T,
|
|
||||||
actual: T,
|
|
||||||
) -> InferResult<'tcx, T>
|
|
||||||
where
|
where
|
||||||
T: ToTrace<'tcx>,
|
T: ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
let mut fields = CombineFields::new(
|
let mut op = LatticeOp::new(
|
||||||
self.infcx,
|
self.infcx,
|
||||||
ToTrace::to_trace(self.cause, expected, actual),
|
ToTrace::to_trace(self.cause, expected, actual),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
define_opaque_types,
|
LatticeOpKind::Lub,
|
||||||
);
|
);
|
||||||
let value = fields.lub().relate(expected, actual)?;
|
let value = op.relate(expected, actual)?;
|
||||||
Ok(InferOk { value, obligations: fields.into_obligations() })
|
Ok(InferOk { value, obligations: op.into_obligations() })
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the greatest-lower-bound, or mutual subtype, of two
|
|
||||||
/// values. As with `lub` order doesn't matter, except for error
|
|
||||||
/// cases.
|
|
||||||
pub fn glb<T>(
|
|
||||||
self,
|
|
||||||
define_opaque_types: DefineOpaqueTypes,
|
|
||||||
expected: T,
|
|
||||||
actual: T,
|
|
||||||
) -> InferResult<'tcx, T>
|
|
||||||
where
|
|
||||||
T: ToTrace<'tcx>,
|
|
||||||
{
|
|
||||||
let mut fields = CombineFields::new(
|
|
||||||
self.infcx,
|
|
||||||
ToTrace::to_trace(self.cause, expected, actual),
|
|
||||||
self.param_env,
|
|
||||||
define_opaque_types,
|
|
||||||
);
|
|
||||||
let value = fields.glb().relate(expected, actual)?;
|
|
||||||
Ok(InferOk { value, obligations: fields.into_obligations() })
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ use region_constraints::{
|
|||||||
GenericKind, RegionConstraintCollector, RegionConstraintStorage, VarInfos, VerifyBound,
|
GenericKind, RegionConstraintCollector, RegionConstraintStorage, VarInfos, VerifyBound,
|
||||||
};
|
};
|
||||||
pub use relate::StructurallyRelateAliases;
|
pub use relate::StructurallyRelateAliases;
|
||||||
use relate::combine::CombineFields;
|
|
||||||
pub use relate::combine::PredicateEmittingRelation;
|
pub use relate::combine::PredicateEmittingRelation;
|
||||||
use rustc_data_structures::captures::Captures;
|
use rustc_data_structures::captures::Captures;
|
||||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//! There are four type combiners: [TypeRelating], `Lub`, and `Glb`,
|
//! There are four type combiners: `TypeRelating`, `Lub`, and `Glb`,
|
||||||
//! and `NllTypeRelating` in rustc_borrowck, which is only used for NLL.
|
//! and `NllTypeRelating` in rustc_borrowck, which is only used for NLL.
|
||||||
//!
|
//!
|
||||||
//! Each implements the trait [TypeRelation] and contains methods for
|
//! Each implements the trait [TypeRelation] and contains methods for
|
||||||
@ -20,56 +20,13 @@
|
|||||||
|
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::infer::unify_key::EffectVarValue;
|
use rustc_middle::infer::unify_key::EffectVarValue;
|
||||||
use rustc_middle::traits::solve::Goal;
|
|
||||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||||
use rustc_middle::ty::{self, InferConst, IntType, Ty, TyCtxt, TypeVisitableExt, UintType, Upcast};
|
use rustc_middle::ty::{self, InferConst, IntType, Ty, TypeVisitableExt, UintType};
|
||||||
pub use rustc_next_trait_solver::relate::combine::*;
|
pub use rustc_next_trait_solver::relate::combine::*;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use super::lattice::{LatticeOp, LatticeOpKind};
|
|
||||||
use super::type_relating::TypeRelating;
|
|
||||||
use super::{RelateResult, StructurallyRelateAliases};
|
use super::{RelateResult, StructurallyRelateAliases};
|
||||||
use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace, relate};
|
use crate::infer::{InferCtxt, relate};
|
||||||
use crate::traits::{Obligation, PredicateObligation};
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub(crate) struct CombineFields<'infcx, 'tcx> {
|
|
||||||
pub infcx: &'infcx InferCtxt<'tcx>,
|
|
||||||
// Immutable fields
|
|
||||||
pub trace: TypeTrace<'tcx>,
|
|
||||||
pub param_env: ty::ParamEnv<'tcx>,
|
|
||||||
pub define_opaque_types: DefineOpaqueTypes,
|
|
||||||
// Mutable fields
|
|
||||||
//
|
|
||||||
// Adding any additional field likely requires
|
|
||||||
// changes to the cache of `TypeRelating`.
|
|
||||||
pub goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
|
||||||
pub(crate) 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, goals: vec![] }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn into_obligations(self) -> Vec<PredicateObligation<'tcx>> {
|
|
||||||
self.goals
|
|
||||||
.into_iter()
|
|
||||||
.map(|goal| {
|
|
||||||
Obligation::new(
|
|
||||||
self.infcx.tcx,
|
|
||||||
self.trace.cause.clone(),
|
|
||||||
goal.param_env,
|
|
||||||
goal.predicate,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> InferCtxt<'tcx> {
|
impl<'tcx> InferCtxt<'tcx> {
|
||||||
pub fn super_combine_tys<R>(
|
pub fn super_combine_tys<R>(
|
||||||
@ -281,50 +238,3 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
val
|
val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
|
||||||
pub(crate) fn tcx(&self) -> TyCtxt<'tcx> {
|
|
||||||
self.infcx.tcx
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn equate<'a>(
|
|
||||||
&'a mut self,
|
|
||||||
structurally_relate_aliases: StructurallyRelateAliases,
|
|
||||||
) -> TypeRelating<'a, 'infcx, 'tcx> {
|
|
||||||
TypeRelating::new(self, structurally_relate_aliases, ty::Invariant)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn sub<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
|
|
||||||
TypeRelating::new(self, StructurallyRelateAliases::No, ty::Covariant)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn sup<'a>(&'a mut self) -> TypeRelating<'a, 'infcx, 'tcx> {
|
|
||||||
TypeRelating::new(self, StructurallyRelateAliases::No, ty::Contravariant)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn lub<'a>(&'a mut self) -> LatticeOp<'a, 'infcx, 'tcx> {
|
|
||||||
LatticeOp::new(self, LatticeOpKind::Lub)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn glb<'a>(&'a mut self) -> LatticeOp<'a, 'infcx, 'tcx> {
|
|
||||||
LatticeOp::new(self, LatticeOpKind::Glb)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn register_obligations(
|
|
||||||
&mut self,
|
|
||||||
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
|
|
||||||
) {
|
|
||||||
self.goals.extend(obligations);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn register_predicates(
|
|
||||||
&mut self,
|
|
||||||
obligations: impl IntoIterator<Item: Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
|
|
||||||
) {
|
|
||||||
self.goals.extend(
|
|
||||||
obligations
|
|
||||||
.into_iter()
|
|
||||||
.map(|to_pred| Goal::new(self.infcx.tcx, self.param_env, to_pred)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -24,8 +24,9 @@ use rustc_span::Span;
|
|||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
use super::StructurallyRelateAliases;
|
use super::StructurallyRelateAliases;
|
||||||
use super::combine::{CombineFields, PredicateEmittingRelation};
|
use super::combine::PredicateEmittingRelation;
|
||||||
use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
|
use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin, TypeTrace};
|
||||||
|
use crate::traits::{Obligation, PredicateObligation};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub(crate) enum LatticeOpKind {
|
pub(crate) enum LatticeOpKind {
|
||||||
@ -43,23 +44,34 @@ impl LatticeOpKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A greatest lower bound" (common subtype) or least upper bound (common supertype).
|
/// A greatest lower bound" (common subtype) or least upper bound (common supertype).
|
||||||
pub(crate) struct LatticeOp<'combine, 'infcx, 'tcx> {
|
pub(crate) struct LatticeOp<'infcx, 'tcx> {
|
||||||
fields: &'combine mut CombineFields<'infcx, 'tcx>,
|
infcx: &'infcx InferCtxt<'tcx>,
|
||||||
|
// Immutable fields
|
||||||
|
trace: TypeTrace<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
// Mutable fields
|
||||||
kind: LatticeOpKind,
|
kind: LatticeOpKind,
|
||||||
|
obligations: Vec<PredicateObligation<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'combine, 'infcx, 'tcx> LatticeOp<'combine, 'infcx, 'tcx> {
|
impl<'infcx, 'tcx> LatticeOp<'infcx, 'tcx> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
fields: &'combine mut CombineFields<'infcx, 'tcx>,
|
infcx: &'infcx InferCtxt<'tcx>,
|
||||||
|
trace: TypeTrace<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
kind: LatticeOpKind,
|
kind: LatticeOpKind,
|
||||||
) -> LatticeOp<'combine, 'infcx, 'tcx> {
|
) -> LatticeOp<'infcx, 'tcx> {
|
||||||
LatticeOp { fields, kind }
|
LatticeOp { infcx, trace, param_env, kind, obligations: vec![] }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn into_obligations(self) -> Vec<PredicateObligation<'tcx>> {
|
||||||
|
self.obligations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
|
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
|
||||||
fn cx(&self) -> TyCtxt<'tcx> {
|
fn cx(&self) -> TyCtxt<'tcx> {
|
||||||
self.fields.tcx()
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
|
fn relate_with_variance<T: Relate<TyCtxt<'tcx>>>(
|
||||||
@ -70,7 +82,15 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
|
|||||||
b: T,
|
b: T,
|
||||||
) -> RelateResult<'tcx, T> {
|
) -> RelateResult<'tcx, T> {
|
||||||
match variance {
|
match variance {
|
||||||
ty::Invariant => self.fields.equate(StructurallyRelateAliases::No).relate(a, b),
|
ty::Invariant => {
|
||||||
|
self.obligations.extend(
|
||||||
|
self.infcx
|
||||||
|
.at(&self.trace.cause, self.param_env)
|
||||||
|
.eq_trace(DefineOpaqueTypes::Yes, self.trace.clone(), a, b)?
|
||||||
|
.into_obligations(),
|
||||||
|
);
|
||||||
|
Ok(a)
|
||||||
|
}
|
||||||
ty::Covariant => self.relate(a, b),
|
ty::Covariant => self.relate(a, b),
|
||||||
// FIXME(#41044) -- not correct, need test
|
// FIXME(#41044) -- not correct, need test
|
||||||
ty::Bivariant => Ok(a),
|
ty::Bivariant => Ok(a),
|
||||||
@ -90,7 +110,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
|
|||||||
return Ok(a);
|
return Ok(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
let infcx = self.fields.infcx;
|
let infcx = self.infcx;
|
||||||
|
|
||||||
let a = infcx.shallow_resolve(a);
|
let a = infcx.shallow_resolve(a);
|
||||||
let b = infcx.shallow_resolve(b);
|
let b = infcx.shallow_resolve(b);
|
||||||
@ -115,12 +135,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
|
|||||||
// iterate on the subtype obligations that are returned, but I
|
// iterate on the subtype obligations that are returned, but I
|
||||||
// think this suffices. -nmatsakis
|
// think this suffices. -nmatsakis
|
||||||
(&ty::Infer(TyVar(..)), _) => {
|
(&ty::Infer(TyVar(..)), _) => {
|
||||||
let v = infcx.next_ty_var(self.fields.trace.cause.span);
|
let v = infcx.next_ty_var(self.trace.cause.span);
|
||||||
self.relate_bound(v, b, a)?;
|
self.relate_bound(v, b, a)?;
|
||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
(_, &ty::Infer(TyVar(..))) => {
|
(_, &ty::Infer(TyVar(..))) => {
|
||||||
let v = infcx.next_ty_var(self.fields.trace.cause.span);
|
let v = infcx.next_ty_var(self.trace.cause.span);
|
||||||
self.relate_bound(v, a, b)?;
|
self.relate_bound(v, a, b)?;
|
||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
@ -132,9 +152,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
|
|||||||
|
|
||||||
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
|
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
|
||||||
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
|
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
|
||||||
if self.fields.define_opaque_types == DefineOpaqueTypes::Yes
|
if def_id.is_local() && !infcx.next_trait_solver() =>
|
||||||
&& def_id.is_local()
|
|
||||||
&& !infcx.next_trait_solver() =>
|
|
||||||
{
|
{
|
||||||
self.register_goals(infcx.handle_opaque_type(
|
self.register_goals(infcx.handle_opaque_type(
|
||||||
a,
|
a,
|
||||||
@ -155,8 +173,8 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
|
|||||||
a: ty::Region<'tcx>,
|
a: ty::Region<'tcx>,
|
||||||
b: ty::Region<'tcx>,
|
b: ty::Region<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
|
let origin = SubregionOrigin::Subtype(Box::new(self.trace.clone()));
|
||||||
let mut inner = self.fields.infcx.inner.borrow_mut();
|
let mut inner = self.infcx.inner.borrow_mut();
|
||||||
let mut constraints = inner.unwrap_region_constraints();
|
let mut constraints = inner.unwrap_region_constraints();
|
||||||
Ok(match self.kind {
|
Ok(match self.kind {
|
||||||
// GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8
|
// GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8
|
||||||
@ -173,7 +191,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
|
|||||||
a: ty::Const<'tcx>,
|
a: ty::Const<'tcx>,
|
||||||
b: ty::Const<'tcx>,
|
b: ty::Const<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
||||||
self.fields.infcx.super_combine_consts(self, a, b)
|
self.infcx.super_combine_consts(self, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binders<T>(
|
fn binders<T>(
|
||||||
@ -202,7 +220,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'combine, 'infcx, 'tcx> LatticeOp<'combine, 'infcx, 'tcx> {
|
impl<'infcx, 'tcx> LatticeOp<'infcx, 'tcx> {
|
||||||
// Relates the type `v` to `a` and `b` such that `v` represents
|
// Relates the type `v` to `a` and `b` such that `v` represents
|
||||||
// the LUB/GLB of `a` and `b` as appropriate.
|
// the LUB/GLB of `a` and `b` as appropriate.
|
||||||
//
|
//
|
||||||
@ -210,24 +228,24 @@ impl<'combine, 'infcx, 'tcx> LatticeOp<'combine, 'infcx, 'tcx> {
|
|||||||
// relates `v` to `a` first, which may help us to avoid unnecessary
|
// relates `v` to `a` first, which may help us to avoid unnecessary
|
||||||
// type variable obligations. See caller for details.
|
// type variable obligations. See caller for details.
|
||||||
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
|
fn relate_bound(&mut self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
|
||||||
let mut sub = self.fields.sub();
|
let at = self.infcx.at(&self.trace.cause, self.param_env);
|
||||||
match self.kind {
|
match self.kind {
|
||||||
LatticeOpKind::Glb => {
|
LatticeOpKind::Glb => {
|
||||||
sub.relate(v, a)?;
|
self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, v, a)?.into_obligations());
|
||||||
sub.relate(v, b)?;
|
self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, v, b)?.into_obligations());
|
||||||
}
|
}
|
||||||
LatticeOpKind::Lub => {
|
LatticeOpKind::Lub => {
|
||||||
sub.relate(a, v)?;
|
self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, a, v)?.into_obligations());
|
||||||
sub.relate(b, v)?;
|
self.obligations.extend(at.sub(DefineOpaqueTypes::Yes, b, v)?.into_obligations());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx> {
|
impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for LatticeOp<'_, 'tcx> {
|
||||||
fn span(&self) -> Span {
|
fn span(&self) -> Span {
|
||||||
self.fields.trace.span()
|
self.trace.span()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
|
fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
|
||||||
@ -235,21 +253,27 @@ impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for LatticeOp<'_, '_, 'tcx
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.fields.param_env
|
self.param_env
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_predicates(
|
fn register_predicates(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligations: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
|
preds: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
|
||||||
) {
|
) {
|
||||||
self.fields.register_predicates(obligations);
|
self.obligations.extend(preds.into_iter().map(|pred| {
|
||||||
|
Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, pred)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_goals(
|
fn register_goals(&mut self, goals: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>) {
|
||||||
&mut self,
|
self.obligations.extend(goals.into_iter().map(|goal| {
|
||||||
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
|
Obligation::new(
|
||||||
) {
|
self.infcx.tcx,
|
||||||
self.fields.register_obligations(obligations);
|
self.trace.cause.clone(),
|
||||||
|
goal.param_env,
|
||||||
|
goal.predicate,
|
||||||
|
)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
|
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
|
||||||
|
@ -11,5 +11,5 @@ pub use self::combine::PredicateEmittingRelation;
|
|||||||
pub(super) mod combine;
|
pub(super) mod combine;
|
||||||
mod generalize;
|
mod generalize;
|
||||||
mod higher_ranked;
|
mod higher_ranked;
|
||||||
mod lattice;
|
pub(super) mod lattice;
|
||||||
mod type_relating;
|
pub(super) mod type_relating;
|
||||||
|
@ -7,29 +7,31 @@ use rustc_span::Span;
|
|||||||
use rustc_type_ir::data_structures::DelayedSet;
|
use rustc_type_ir::data_structures::DelayedSet;
|
||||||
use tracing::{debug, instrument};
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
use super::combine::CombineFields;
|
|
||||||
use crate::infer::BoundRegionConversionTime::HigherRankedType;
|
use crate::infer::BoundRegionConversionTime::HigherRankedType;
|
||||||
use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
|
use crate::infer::relate::{PredicateEmittingRelation, StructurallyRelateAliases};
|
||||||
use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
|
use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin, TypeTrace};
|
||||||
|
use crate::traits::{Obligation, PredicateObligation};
|
||||||
|
|
||||||
/// Enforce that `a` is equal to or a subtype of `b`.
|
/// Enforce that `a` is equal to or a subtype of `b`.
|
||||||
pub(crate) struct TypeRelating<'combine, 'a, 'tcx> {
|
pub(crate) struct TypeRelating<'infcx, 'tcx> {
|
||||||
// Immutable except for the `InferCtxt` and the
|
infcx: &'infcx InferCtxt<'tcx>,
|
||||||
// resulting nested `goals`.
|
|
||||||
fields: &'combine mut CombineFields<'a, 'tcx>,
|
|
||||||
|
|
||||||
// Immutable field.
|
// Immutable fields
|
||||||
|
trace: TypeTrace<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
define_opaque_types: DefineOpaqueTypes,
|
||||||
structurally_relate_aliases: StructurallyRelateAliases,
|
structurally_relate_aliases: StructurallyRelateAliases,
|
||||||
// Mutable field.
|
|
||||||
ambient_variance: ty::Variance,
|
|
||||||
|
|
||||||
|
// Mutable fields.
|
||||||
|
ambient_variance: ty::Variance,
|
||||||
|
obligations: Vec<PredicateObligation<'tcx>>,
|
||||||
/// The cache only tracks the `ambient_variance` as it's the
|
/// The cache only tracks the `ambient_variance` as it's the
|
||||||
/// only field which is mutable and which meaningfully changes
|
/// only field which is mutable and which meaningfully changes
|
||||||
/// the result when relating types.
|
/// the result when relating types.
|
||||||
///
|
///
|
||||||
/// The cache does not track whether the state of the
|
/// The cache does not track whether the state of the
|
||||||
/// `InferCtxt` has been changed or whether we've added any
|
/// `InferCtxt` has been changed or whether we've added any
|
||||||
/// obligations to `self.fields.goals`. Whether a goal is added
|
/// obligations to `self.goals`. Whether a goal is added
|
||||||
/// once or multiple times is not really meaningful.
|
/// once or multiple times is not really meaningful.
|
||||||
///
|
///
|
||||||
/// Changes in the inference state may delay some type inference to
|
/// Changes in the inference state may delay some type inference to
|
||||||
@ -48,24 +50,35 @@ pub(crate) struct TypeRelating<'combine, 'a, 'tcx> {
|
|||||||
cache: DelayedSet<(ty::Variance, Ty<'tcx>, Ty<'tcx>)>,
|
cache: DelayedSet<(ty::Variance, Ty<'tcx>, Ty<'tcx>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'combine, 'infcx, 'tcx> TypeRelating<'combine, 'infcx, 'tcx> {
|
impl<'infcx, 'tcx> TypeRelating<'infcx, 'tcx> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
f: &'combine mut CombineFields<'infcx, 'tcx>,
|
infcx: &'infcx InferCtxt<'tcx>,
|
||||||
|
trace: TypeTrace<'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
define_opaque_types: DefineOpaqueTypes,
|
||||||
structurally_relate_aliases: StructurallyRelateAliases,
|
structurally_relate_aliases: StructurallyRelateAliases,
|
||||||
ambient_variance: ty::Variance,
|
ambient_variance: ty::Variance,
|
||||||
) -> TypeRelating<'combine, 'infcx, 'tcx> {
|
) -> TypeRelating<'infcx, 'tcx> {
|
||||||
TypeRelating {
|
TypeRelating {
|
||||||
fields: f,
|
infcx,
|
||||||
|
trace,
|
||||||
|
param_env,
|
||||||
|
define_opaque_types,
|
||||||
structurally_relate_aliases,
|
structurally_relate_aliases,
|
||||||
ambient_variance,
|
ambient_variance,
|
||||||
|
obligations: vec![],
|
||||||
cache: Default::default(),
|
cache: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn into_obligations(self) -> Vec<PredicateObligation<'tcx>> {
|
||||||
|
self.obligations
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
|
||||||
fn cx(&self) -> TyCtxt<'tcx> {
|
fn cx(&self) -> TyCtxt<'tcx> {
|
||||||
self.fields.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relate_item_args(
|
fn relate_item_args(
|
||||||
@ -109,7 +122,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||||||
return Ok(a);
|
return Ok(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
let infcx = self.fields.infcx;
|
let infcx = self.infcx;
|
||||||
let a = infcx.shallow_resolve(a);
|
let a = infcx.shallow_resolve(a);
|
||||||
let b = infcx.shallow_resolve(b);
|
let b = infcx.shallow_resolve(b);
|
||||||
|
|
||||||
@ -123,9 +136,10 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||||||
ty::Covariant => {
|
ty::Covariant => {
|
||||||
// can't make progress on `A <: B` if both A and B are
|
// can't make progress on `A <: B` if both A and B are
|
||||||
// type variables, so record an obligation.
|
// type variables, so record an obligation.
|
||||||
self.fields.goals.push(Goal::new(
|
self.obligations.push(Obligation::new(
|
||||||
self.cx(),
|
self.cx(),
|
||||||
self.fields.param_env,
|
self.trace.cause.clone(),
|
||||||
|
self.param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
|
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
|
||||||
a_is_expected: true,
|
a_is_expected: true,
|
||||||
a,
|
a,
|
||||||
@ -136,9 +150,10 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||||||
ty::Contravariant => {
|
ty::Contravariant => {
|
||||||
// can't make progress on `B <: A` if both A and B are
|
// can't make progress on `B <: A` if both A and B are
|
||||||
// type variables, so record an obligation.
|
// type variables, so record an obligation.
|
||||||
self.fields.goals.push(Goal::new(
|
self.obligations.push(Obligation::new(
|
||||||
self.cx(),
|
self.cx(),
|
||||||
self.fields.param_env,
|
self.trace.cause.clone(),
|
||||||
|
self.param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
|
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
|
||||||
a_is_expected: false,
|
a_is_expected: false,
|
||||||
a: b,
|
a: b,
|
||||||
@ -182,14 +197,14 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||||||
|
|
||||||
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
|
(&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
|
||||||
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
|
| (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
|
||||||
if self.fields.define_opaque_types == DefineOpaqueTypes::Yes
|
if self.define_opaque_types == DefineOpaqueTypes::Yes
|
||||||
&& def_id.is_local()
|
&& def_id.is_local()
|
||||||
&& !infcx.next_trait_solver() =>
|
&& !infcx.next_trait_solver() =>
|
||||||
{
|
{
|
||||||
self.fields.goals.extend(infcx.handle_opaque_type(
|
self.register_goals(infcx.handle_opaque_type(
|
||||||
a,
|
a,
|
||||||
b,
|
b,
|
||||||
self.fields.trace.cause.span,
|
self.trace.cause.span,
|
||||||
self.param_env(),
|
self.param_env(),
|
||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
@ -210,13 +225,12 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||||||
a: ty::Region<'tcx>,
|
a: ty::Region<'tcx>,
|
||||||
b: ty::Region<'tcx>,
|
b: ty::Region<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
|
let origin = SubregionOrigin::Subtype(Box::new(self.trace.clone()));
|
||||||
|
|
||||||
match self.ambient_variance {
|
match self.ambient_variance {
|
||||||
// Subtype(&'a u8, &'b u8) => Outlives('a: 'b) => SubRegion('b, 'a)
|
// Subtype(&'a u8, &'b u8) => Outlives('a: 'b) => SubRegion('b, 'a)
|
||||||
ty::Covariant => {
|
ty::Covariant => {
|
||||||
self.fields
|
self.infcx
|
||||||
.infcx
|
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.unwrap_region_constraints()
|
.unwrap_region_constraints()
|
||||||
@ -224,16 +238,14 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||||||
}
|
}
|
||||||
// Suptype(&'a u8, &'b u8) => Outlives('b: 'a) => SubRegion('a, 'b)
|
// Suptype(&'a u8, &'b u8) => Outlives('b: 'a) => SubRegion('a, 'b)
|
||||||
ty::Contravariant => {
|
ty::Contravariant => {
|
||||||
self.fields
|
self.infcx
|
||||||
.infcx
|
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.unwrap_region_constraints()
|
.unwrap_region_constraints()
|
||||||
.make_subregion(origin, a, b);
|
.make_subregion(origin, a, b);
|
||||||
}
|
}
|
||||||
ty::Invariant => {
|
ty::Invariant => {
|
||||||
self.fields
|
self.infcx
|
||||||
.infcx
|
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.unwrap_region_constraints()
|
.unwrap_region_constraints()
|
||||||
@ -253,7 +265,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||||||
a: ty::Const<'tcx>,
|
a: ty::Const<'tcx>,
|
||||||
b: ty::Const<'tcx>,
|
b: ty::Const<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
) -> RelateResult<'tcx, ty::Const<'tcx>> {
|
||||||
self.fields.infcx.super_combine_consts(self, a, b)
|
self.infcx.super_combine_consts(self, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn binders<T>(
|
fn binders<T>(
|
||||||
@ -271,8 +283,8 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||||||
{
|
{
|
||||||
self.relate(a, b)?;
|
self.relate(a, b)?;
|
||||||
} else {
|
} else {
|
||||||
let span = self.fields.trace.cause.span;
|
let span = self.trace.cause.span;
|
||||||
let infcx = self.fields.infcx;
|
let infcx = self.infcx;
|
||||||
|
|
||||||
match self.ambient_variance {
|
match self.ambient_variance {
|
||||||
// Checks whether `for<..> sub <: for<..> sup` holds.
|
// Checks whether `for<..> sub <: for<..> sup` holds.
|
||||||
@ -335,13 +347,13 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for TypeRelating<'_, 'tcx> {
|
||||||
fn span(&self) -> Span {
|
fn span(&self) -> Span {
|
||||||
self.fields.trace.span()
|
self.trace.span()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||||
self.fields.param_env
|
self.param_env
|
||||||
}
|
}
|
||||||
|
|
||||||
fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
|
fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
|
||||||
@ -350,16 +362,22 @@ impl<'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for TypeRelating<'_, '_, '
|
|||||||
|
|
||||||
fn register_predicates(
|
fn register_predicates(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligations: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
|
preds: impl IntoIterator<Item: ty::Upcast<TyCtxt<'tcx>, ty::Predicate<'tcx>>>,
|
||||||
) {
|
) {
|
||||||
self.fields.register_predicates(obligations);
|
self.obligations.extend(preds.into_iter().map(|pred| {
|
||||||
|
Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, pred)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_goals(
|
fn register_goals(&mut self, goals: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>) {
|
||||||
&mut self,
|
self.obligations.extend(goals.into_iter().map(|goal| {
|
||||||
obligations: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
|
Obligation::new(
|
||||||
) {
|
self.infcx.tcx,
|
||||||
self.fields.register_obligations(obligations);
|
self.trace.cause.clone(),
|
||||||
|
goal.param_env,
|
||||||
|
goal.predicate,
|
||||||
|
)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
|
fn register_alias_relate_predicate(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
|
||||||
|
Loading…
Reference in New Issue
Block a user