Fallout from removing a_is_expected
This commit is contained in:
parent
04e22627f5
commit
b1536568db
12 changed files with 46 additions and 127 deletions
|
@ -160,8 +160,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let cause = ObligationCause::dummy_with_span(self.span());
|
let cause = ObligationCause::dummy_with_span(self.span());
|
||||||
let obligations =
|
let obligations = infcx.handle_opaque_type(a, b, &cause, self.param_env())?.obligations;
|
||||||
infcx.handle_opaque_type(a, b, true, &cause, self.param_env())?.obligations;
|
|
||||||
self.register_obligations(obligations);
|
self.register_obligations(obligations);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -330,10 +329,6 @@ impl<'bccx, 'tcx> TypeRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> {
|
||||||
"nll::subtype"
|
"nll::subtype"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a_is_expected(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(self, info), level = "trace", ret)]
|
#[instrument(skip(self, info), level = "trace", ret)]
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -2654,10 +2654,6 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
|
||||||
"SameTypeModuloInfer"
|
"SameTypeModuloInfer"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a_is_expected(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn relate_with_variance<T: relate::Relate<'tcx>>(
|
fn relate_with_variance<T: relate::Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_variance: ty::Variance,
|
_variance: ty::Variance,
|
||||||
|
|
|
@ -78,9 +78,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
span,
|
span,
|
||||||
});
|
});
|
||||||
obligations.extend(
|
obligations.extend(
|
||||||
self.handle_opaque_type(ty, ty_var, true, &cause, param_env)
|
self.handle_opaque_type(ty, ty_var, &cause, param_env).unwrap().obligations,
|
||||||
.unwrap()
|
|
||||||
.obligations,
|
|
||||||
);
|
);
|
||||||
ty_var
|
ty_var
|
||||||
}
|
}
|
||||||
|
@ -94,14 +92,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
&self,
|
&self,
|
||||||
a: Ty<'tcx>,
|
a: Ty<'tcx>,
|
||||||
b: Ty<'tcx>,
|
b: Ty<'tcx>,
|
||||||
a_is_expected: bool,
|
|
||||||
cause: &ObligationCause<'tcx>,
|
cause: &ObligationCause<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> InferResult<'tcx, ()> {
|
) -> InferResult<'tcx, ()> {
|
||||||
if a.references_error() || b.references_error() {
|
if a.references_error() || b.references_error() {
|
||||||
return Ok(InferOk { value: (), obligations: vec![] });
|
return Ok(InferOk { value: (), obligations: vec![] });
|
||||||
}
|
}
|
||||||
let (a, b) = if a_is_expected { (a, b) } else { (b, a) };
|
|
||||||
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
|
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
|
||||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
|
ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => {
|
||||||
let def_id = def_id.expect_local();
|
let def_id = def_id.expect_local();
|
||||||
|
|
|
@ -144,10 +144,6 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstHigherRankedOutlives<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a_is_expected(&self) -> bool {
|
|
||||||
true
|
|
||||||
} // irrelevant
|
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self))]
|
#[instrument(level = "trace", skip(self))]
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -17,12 +17,6 @@
|
||||||
//!
|
//!
|
||||||
//! On success, the LUB/GLB operations return the appropriate bound. The
|
//! On success, the LUB/GLB operations return the appropriate bound. The
|
||||||
//! return value of `Equate` or `Sub` shouldn't really be used.
|
//! return value of `Equate` or `Sub` shouldn't really be used.
|
||||||
//!
|
|
||||||
//! ## Contravariance
|
|
||||||
//!
|
|
||||||
//! We explicitly track which argument is expected using
|
|
||||||
//! [TypeRelation::a_is_expected], so when dealing with contravariance
|
|
||||||
//! this should be correctly updated.
|
|
||||||
|
|
||||||
use super::glb::Glb;
|
use super::glb::Glb;
|
||||||
use super::lub::Lub;
|
use super::lub::Lub;
|
||||||
|
@ -57,7 +51,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
where
|
where
|
||||||
R: ObligationEmittingRelation<'tcx>,
|
R: ObligationEmittingRelation<'tcx>,
|
||||||
{
|
{
|
||||||
let a_is_expected = relation.a_is_expected();
|
|
||||||
debug_assert!(!a.has_escaping_bound_vars());
|
debug_assert!(!a.has_escaping_bound_vars());
|
||||||
debug_assert!(!b.has_escaping_bound_vars());
|
debug_assert!(!b.has_escaping_bound_vars());
|
||||||
|
|
||||||
|
@ -68,20 +61,20 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.int_unification_table()
|
.int_unification_table()
|
||||||
.unify_var_var(a_id, b_id)
|
.unify_var_var(a_id, b_id)
|
||||||
.map_err(|e| int_unification_error(a_is_expected, e))?;
|
.map_err(|e| int_unification_error(true, e))?;
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
(&ty::Infer(ty::IntVar(v_id)), &ty::Int(v)) => {
|
(&ty::Infer(ty::IntVar(v_id)), &ty::Int(v)) => {
|
||||||
self.unify_integral_variable(a_is_expected, v_id, IntType(v))
|
self.unify_integral_variable(true, v_id, IntType(v))
|
||||||
}
|
}
|
||||||
(&ty::Int(v), &ty::Infer(ty::IntVar(v_id))) => {
|
(&ty::Int(v), &ty::Infer(ty::IntVar(v_id))) => {
|
||||||
self.unify_integral_variable(!a_is_expected, v_id, IntType(v))
|
self.unify_integral_variable(false, v_id, IntType(v))
|
||||||
}
|
}
|
||||||
(&ty::Infer(ty::IntVar(v_id)), &ty::Uint(v)) => {
|
(&ty::Infer(ty::IntVar(v_id)), &ty::Uint(v)) => {
|
||||||
self.unify_integral_variable(a_is_expected, v_id, UintType(v))
|
self.unify_integral_variable(true, v_id, UintType(v))
|
||||||
}
|
}
|
||||||
(&ty::Uint(v), &ty::Infer(ty::IntVar(v_id))) => {
|
(&ty::Uint(v), &ty::Infer(ty::IntVar(v_id))) => {
|
||||||
self.unify_integral_variable(!a_is_expected, v_id, UintType(v))
|
self.unify_integral_variable(false, v_id, UintType(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relate floating-point variables to other types
|
// Relate floating-point variables to other types
|
||||||
|
@ -90,14 +83,14 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.float_unification_table()
|
.float_unification_table()
|
||||||
.unify_var_var(a_id, b_id)
|
.unify_var_var(a_id, b_id)
|
||||||
.map_err(|e| float_unification_error(a_is_expected, e))?;
|
.map_err(|e| float_unification_error(true, e))?;
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
(&ty::Infer(ty::FloatVar(v_id)), &ty::Float(v)) => {
|
(&ty::Infer(ty::FloatVar(v_id)), &ty::Float(v)) => {
|
||||||
self.unify_float_variable(a_is_expected, v_id, v)
|
self.unify_float_variable(true, v_id, v)
|
||||||
}
|
}
|
||||||
(&ty::Float(v), &ty::Infer(ty::FloatVar(v_id))) => {
|
(&ty::Float(v), &ty::Infer(ty::FloatVar(v_id))) => {
|
||||||
self.unify_float_variable(!a_is_expected, v_id, v)
|
self.unify_float_variable(false, v_id, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
|
// We don't expect `TyVar` or `Fresh*` vars at this point with lazy norm.
|
||||||
|
@ -130,7 +123,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
|
|
||||||
// All other cases of inference are errors
|
// All other cases of inference are errors
|
||||||
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
|
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
|
||||||
Err(TypeError::Sorts(ty::relate::expected_found(relation, a, b)))
|
Err(TypeError::Sorts(ty::relate::expected_found(a, b)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// During coherence, opaque types should be treated as *possibly*
|
// During coherence, opaque types should be treated as *possibly*
|
||||||
|
@ -228,12 +221,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
|
(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
|
||||||
self.instantiate_const_var(relation, relation.a_is_expected(), vid, b)?;
|
self.instantiate_const_var(relation, true, vid, b)?;
|
||||||
Ok(b)
|
Ok(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
|
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
|
||||||
self.instantiate_const_var(relation, !relation.a_is_expected(), vid, a)?;
|
self.instantiate_const_var(relation, false, vid, a)?;
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,8 +243,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
{
|
{
|
||||||
match relation.structurally_relate_aliases() {
|
match relation.structurally_relate_aliases() {
|
||||||
StructurallyRelateAliases::No => {
|
StructurallyRelateAliases::No => {
|
||||||
let (a, b) = if relation.a_is_expected() { (a, b) } else { (b, a) };
|
|
||||||
|
|
||||||
relation.register_predicates([if self.next_trait_solver() {
|
relation.register_predicates([if self.next_trait_solver() {
|
||||||
ty::PredicateKind::AliasRelate(
|
ty::PredicateKind::AliasRelate(
|
||||||
a.into(),
|
a.into(),
|
||||||
|
|
|
@ -130,7 +130,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
// instantiate_ty_var(?b, A) # expected and variance flipped
|
// instantiate_ty_var(?b, A) # expected and variance flipped
|
||||||
// A rel A'
|
// A rel A'
|
||||||
// ```
|
// ```
|
||||||
if target_is_expected == relation.a_is_expected() {
|
if target_is_expected {
|
||||||
relation.relate(generalized_ty, source_ty)?;
|
relation.relate(generalized_ty, source_ty)?;
|
||||||
} else {
|
} else {
|
||||||
debug!("flip relation");
|
debug!("flip relation");
|
||||||
|
@ -204,9 +204,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
.const_unification_table()
|
.const_unification_table()
|
||||||
.union_value(target_vid, ConstVariableValue::Known { value: generalized_ct });
|
.union_value(target_vid, ConstVariableValue::Known { value: generalized_ct });
|
||||||
|
|
||||||
// HACK: make sure that we `a_is_expected` continues to be
|
// Make sure that the order is correct when relating the
|
||||||
// correct when relating the generalized type with the source.
|
// generalized const and the source.
|
||||||
if target_is_expected == relation.a_is_expected() {
|
if target_is_expected {
|
||||||
relation.relate_with_variance(
|
relation.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Variance::Invariant,
|
||||||
ty::VarianceDiagInfo::default(),
|
ty::VarianceDiagInfo::default(),
|
||||||
|
@ -398,10 +398,6 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
|
||||||
"Generalizer"
|
"Generalizer"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a_is_expected(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn relate_item_args(
|
fn relate_item_args(
|
||||||
&mut self,
|
&mut self,
|
||||||
item_def_id: DefId,
|
item_def_id: DefId,
|
||||||
|
|
|
@ -30,10 +30,6 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
|
||||||
self.fields.tcx()
|
self.fields.tcx()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a_is_expected(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
variance: ty::Variance,
|
variance: ty::Variance,
|
||||||
|
|
|
@ -116,9 +116,7 @@ where
|
||||||
&& !this.infcx().next_trait_solver() =>
|
&& !this.infcx().next_trait_solver() =>
|
||||||
{
|
{
|
||||||
this.register_obligations(
|
this.register_obligations(
|
||||||
infcx
|
infcx.handle_opaque_type(a, b, this.cause(), this.param_env())?.obligations,
|
||||||
.handle_opaque_type(a, b, this.a_is_expected(), this.cause(), this.param_env())?
|
|
||||||
.obligations,
|
|
||||||
);
|
);
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,10 +30,6 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
|
||||||
self.fields.tcx()
|
self.fields.tcx()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a_is_expected(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
variance: ty::Variance,
|
variance: ty::Variance,
|
||||||
|
|
|
@ -35,10 +35,6 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
|
||||||
self.fields.infcx.tcx
|
self.fields.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a_is_expected(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
variance: ty::Variance,
|
variance: ty::Variance,
|
||||||
|
@ -139,7 +135,7 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
|
||||||
{
|
{
|
||||||
self.fields.obligations.extend(
|
self.fields.obligations.extend(
|
||||||
infcx
|
infcx
|
||||||
.handle_opaque_type(a, b, true, &self.fields.trace.cause, self.param_env())?
|
.handle_opaque_type(a, b, &self.fields.trace.cause, self.param_env())?
|
||||||
.obligations,
|
.obligations,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -158,10 +154,6 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
|
||||||
b: ty::Region<'tcx>,
|
b: ty::Region<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
) -> RelateResult<'tcx, ty::Region<'tcx>> {
|
||||||
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
|
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
|
||||||
|
|
||||||
// FIXME -- we have more fine-grained information available
|
|
||||||
// from the "cause" field, we could perhaps give more tailored
|
|
||||||
// error messages.
|
|
||||||
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
|
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
|
||||||
|
|
||||||
match self.ambient_variance {
|
match self.ambient_variance {
|
||||||
|
@ -184,7 +176,6 @@ impl<'tcx> TypeRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
|
||||||
.make_subregion(origin, a, b);
|
.make_subregion(origin, a, b);
|
||||||
}
|
}
|
||||||
ty::Invariant => {
|
ty::Invariant => {
|
||||||
// The order of `make_eqregion` apparently matters.
|
|
||||||
self.fields
|
self.fields
|
||||||
.infcx
|
.infcx
|
||||||
.inner
|
.inner
|
||||||
|
|
|
@ -37,10 +37,6 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn a_is_expected(&self) -> bool {
|
|
||||||
true
|
|
||||||
} // irrelevant
|
|
||||||
|
|
||||||
fn relate_with_variance<T: Relate<'tcx>>(
|
fn relate_with_variance<T: Relate<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
_: ty::Variance,
|
_: ty::Variance,
|
||||||
|
@ -75,7 +71,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
|
||||||
) => Ok(a),
|
) => Ok(a),
|
||||||
|
|
||||||
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
|
(&ty::Infer(_), _) | (_, &ty::Infer(_)) => {
|
||||||
Err(TypeError::Sorts(relate::expected_found(self, a, b)))
|
Err(TypeError::Sorts(relate::expected_found(a, b)))
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.tcx(), guar)),
|
(&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(Ty::new_error(self.tcx(), guar)),
|
||||||
|
@ -100,7 +96,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
|
(ty::ConstKind::Infer(_), _) | (_, ty::ConstKind::Infer(_)) => {
|
||||||
return Err(TypeError::ConstMismatch(relate::expected_found(self, a, b)));
|
return Err(TypeError::ConstMismatch(relate::expected_found(a, b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -15,21 +15,12 @@ use std::iter;
|
||||||
|
|
||||||
pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>;
|
pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum Cause {
|
|
||||||
ExistentialRegionBound, // relating an existential region bound
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait TypeRelation<'tcx>: Sized {
|
pub trait TypeRelation<'tcx>: Sized {
|
||||||
fn tcx(&self) -> TyCtxt<'tcx>;
|
fn tcx(&self) -> TyCtxt<'tcx>;
|
||||||
|
|
||||||
/// Returns a static string we can use for printouts.
|
/// Returns a static string we can use for printouts.
|
||||||
fn tag(&self) -> &'static str;
|
fn tag(&self) -> &'static str;
|
||||||
|
|
||||||
/// Returns `true` if the value `a` is the "expected" type in the
|
|
||||||
/// relation. Just affects error messages.
|
|
||||||
fn a_is_expected(&self) -> bool;
|
|
||||||
|
|
||||||
/// Generic relation routine suitable for most anything.
|
/// Generic relation routine suitable for most anything.
|
||||||
fn relate<T: Relate<'tcx>>(&mut self, a: T, b: T) -> RelateResult<'tcx, T> {
|
fn relate<T: Relate<'tcx>>(&mut self, a: T, b: T) -> RelateResult<'tcx, T> {
|
||||||
Relate::relate(self, a, b)
|
Relate::relate(self, a, b)
|
||||||
|
@ -171,11 +162,7 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
|
||||||
let tcx = relation.tcx();
|
let tcx = relation.tcx();
|
||||||
|
|
||||||
if a.c_variadic != b.c_variadic {
|
if a.c_variadic != b.c_variadic {
|
||||||
return Err(TypeError::VariadicMismatch(expected_found(
|
return Err(TypeError::VariadicMismatch(expected_found(a.c_variadic, b.c_variadic)));
|
||||||
relation,
|
|
||||||
a.c_variadic,
|
|
||||||
b.c_variadic,
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
let unsafety = relation.relate(a.unsafety, b.unsafety)?;
|
let unsafety = relation.relate(a.unsafety, b.unsafety)?;
|
||||||
let abi = relation.relate(a.abi, b.abi)?;
|
let abi = relation.relate(a.abi, b.abi)?;
|
||||||
|
@ -220,39 +207,31 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> Relate<'tcx> for ty::BoundConstness {
|
impl<'tcx> Relate<'tcx> for ty::BoundConstness {
|
||||||
fn relate<R: TypeRelation<'tcx>>(
|
fn relate<R: TypeRelation<'tcx>>(
|
||||||
relation: &mut R,
|
_relation: &mut R,
|
||||||
a: ty::BoundConstness,
|
a: ty::BoundConstness,
|
||||||
b: ty::BoundConstness,
|
b: ty::BoundConstness,
|
||||||
) -> RelateResult<'tcx, ty::BoundConstness> {
|
) -> RelateResult<'tcx, ty::BoundConstness> {
|
||||||
if a != b {
|
if a != b { Err(TypeError::ConstnessMismatch(expected_found(a, b))) } else { Ok(a) }
|
||||||
Err(TypeError::ConstnessMismatch(expected_found(relation, a, b)))
|
|
||||||
} else {
|
|
||||||
Ok(a)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Relate<'tcx> for hir::Unsafety {
|
impl<'tcx> Relate<'tcx> for hir::Unsafety {
|
||||||
fn relate<R: TypeRelation<'tcx>>(
|
fn relate<R: TypeRelation<'tcx>>(
|
||||||
relation: &mut R,
|
_relation: &mut R,
|
||||||
a: hir::Unsafety,
|
a: hir::Unsafety,
|
||||||
b: hir::Unsafety,
|
b: hir::Unsafety,
|
||||||
) -> RelateResult<'tcx, hir::Unsafety> {
|
) -> RelateResult<'tcx, hir::Unsafety> {
|
||||||
if a != b {
|
if a != b { Err(TypeError::UnsafetyMismatch(expected_found(a, b))) } else { Ok(a) }
|
||||||
Err(TypeError::UnsafetyMismatch(expected_found(relation, a, b)))
|
|
||||||
} else {
|
|
||||||
Ok(a)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Relate<'tcx> for abi::Abi {
|
impl<'tcx> Relate<'tcx> for abi::Abi {
|
||||||
fn relate<R: TypeRelation<'tcx>>(
|
fn relate<R: TypeRelation<'tcx>>(
|
||||||
relation: &mut R,
|
_relation: &mut R,
|
||||||
a: abi::Abi,
|
a: abi::Abi,
|
||||||
b: abi::Abi,
|
b: abi::Abi,
|
||||||
) -> RelateResult<'tcx, abi::Abi> {
|
) -> RelateResult<'tcx, abi::Abi> {
|
||||||
if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(expected_found(relation, a, b))) }
|
if a == b { Ok(a) } else { Err(TypeError::AbiMismatch(expected_found(a, b))) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +242,7 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
|
||||||
b: ty::AliasTy<'tcx>,
|
b: ty::AliasTy<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::AliasTy<'tcx>> {
|
) -> RelateResult<'tcx, ty::AliasTy<'tcx>> {
|
||||||
if a.def_id != b.def_id {
|
if a.def_id != b.def_id {
|
||||||
Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id)))
|
Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id)))
|
||||||
} else {
|
} else {
|
||||||
let args = match relation.tcx().def_kind(a.def_id) {
|
let args = match relation.tcx().def_kind(a.def_id) {
|
||||||
DefKind::OpaqueTy => relate_args_with_variances(
|
DefKind::OpaqueTy => relate_args_with_variances(
|
||||||
|
@ -291,7 +270,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
|
||||||
b: ty::ExistentialProjection<'tcx>,
|
b: ty::ExistentialProjection<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> {
|
) -> RelateResult<'tcx, ty::ExistentialProjection<'tcx>> {
|
||||||
if a.def_id != b.def_id {
|
if a.def_id != b.def_id {
|
||||||
Err(TypeError::ProjectionMismatched(expected_found(relation, a.def_id, b.def_id)))
|
Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id)))
|
||||||
} else {
|
} else {
|
||||||
let term = relation.relate_with_variance(
|
let term = relation.relate_with_variance(
|
||||||
ty::Invariant,
|
ty::Invariant,
|
||||||
|
@ -318,7 +297,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
|
||||||
) -> RelateResult<'tcx, ty::TraitRef<'tcx>> {
|
) -> RelateResult<'tcx, ty::TraitRef<'tcx>> {
|
||||||
// Different traits cannot be related.
|
// Different traits cannot be related.
|
||||||
if a.def_id != b.def_id {
|
if a.def_id != b.def_id {
|
||||||
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
|
Err(TypeError::Traits(expected_found(a.def_id, b.def_id)))
|
||||||
} else {
|
} else {
|
||||||
let args = relate_args_invariantly(relation, a.args, b.args)?;
|
let args = relate_args_invariantly(relation, a.args, b.args)?;
|
||||||
Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args))
|
Ok(ty::TraitRef::new(relation.tcx(), a.def_id, args))
|
||||||
|
@ -334,7 +313,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
|
||||||
) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>> {
|
) -> RelateResult<'tcx, ty::ExistentialTraitRef<'tcx>> {
|
||||||
// Different traits cannot be related.
|
// Different traits cannot be related.
|
||||||
if a.def_id != b.def_id {
|
if a.def_id != b.def_id {
|
||||||
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
|
Err(TypeError::Traits(expected_found(a.def_id, b.def_id)))
|
||||||
} else {
|
} else {
|
||||||
let args = relate_args_invariantly(relation, a.args, b.args)?;
|
let args = relate_args_invariantly(relation, a.args, b.args)?;
|
||||||
Ok(ty::ExistentialTraitRef { def_id: a.def_id, args })
|
Ok(ty::ExistentialTraitRef { def_id: a.def_id, args })
|
||||||
|
@ -510,9 +489,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
|
||||||
let sz_b = sz_b.try_to_target_usize(tcx);
|
let sz_b = sz_b.try_to_target_usize(tcx);
|
||||||
|
|
||||||
match (sz_a, sz_b) {
|
match (sz_a, sz_b) {
|
||||||
(Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => Err(
|
(Some(sz_a_val), Some(sz_b_val)) if sz_a_val != sz_b_val => {
|
||||||
TypeError::FixedArraySize(expected_found(relation, sz_a_val, sz_b_val)),
|
Err(TypeError::FixedArraySize(expected_found(sz_a_val, sz_b_val)))
|
||||||
),
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,9 +510,9 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
|
||||||
iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)),
|
iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)),
|
||||||
)?)
|
)?)
|
||||||
} else if !(as_.is_empty() || bs.is_empty()) {
|
} else if !(as_.is_empty() || bs.is_empty()) {
|
||||||
Err(TypeError::TupleSize(expected_found(relation, as_.len(), bs.len())))
|
Err(TypeError::TupleSize(expected_found(as_.len(), bs.len())))
|
||||||
} else {
|
} else {
|
||||||
Err(TypeError::Sorts(expected_found(relation, a, b)))
|
Err(TypeError::Sorts(expected_found(a, b)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -554,7 +533,7 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
|
||||||
Ok(Ty::new_alias(tcx, a_kind, alias_ty))
|
Ok(Ty::new_alias(tcx, a_kind, alias_ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => Err(TypeError::Sorts(expected_found(relation, a, b))),
|
_ => Err(TypeError::Sorts(expected_found(a, b))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,13 +631,13 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>(
|
||||||
let related_args = tcx.mk_const_list(&related_args);
|
let related_args = tcx.mk_const_list(&related_args);
|
||||||
Expr::FunctionCall(func, related_args)
|
Expr::FunctionCall(func, related_args)
|
||||||
}
|
}
|
||||||
_ => return Err(TypeError::ConstMismatch(expected_found(r, a, b))),
|
_ => return Err(TypeError::ConstMismatch(expected_found(a, b))),
|
||||||
};
|
};
|
||||||
return Ok(ty::Const::new_expr(tcx, expr, a.ty()));
|
return Ok(ty::Const::new_expr(tcx, expr, a.ty()));
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) }
|
if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(a, b))) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
|
impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
|
||||||
|
@ -680,7 +659,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
|
||||||
b_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
|
b_v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder()));
|
||||||
b_v.dedup();
|
b_v.dedup();
|
||||||
if a_v.len() != b_v.len() {
|
if a_v.len() != b_v.len() {
|
||||||
return Err(TypeError::ExistentialMismatch(expected_found(relation, a, b)));
|
return Err(TypeError::ExistentialMismatch(expected_found(a, b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| {
|
let v = iter::zip(a_v, b_v).map(|(ep_a, ep_b)| {
|
||||||
|
@ -692,7 +671,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
|
||||||
relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
|
relation.relate(ep_a.rebind(a), ep_b.rebind(b))?.skip_binder(),
|
||||||
))),
|
))),
|
||||||
(AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))),
|
(AutoTrait(a), AutoTrait(b)) if a == b => Ok(ep_a.rebind(AutoTrait(a))),
|
||||||
_ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))),
|
_ => Err(TypeError::ExistentialMismatch(expected_found(a, b))),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tcx.mk_poly_existential_predicates_from_iter(v)
|
tcx.mk_poly_existential_predicates_from_iter(v)
|
||||||
|
@ -792,15 +771,11 @@ impl<'tcx> Relate<'tcx> for GenericArg<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> Relate<'tcx> for ty::ImplPolarity {
|
impl<'tcx> Relate<'tcx> for ty::ImplPolarity {
|
||||||
fn relate<R: TypeRelation<'tcx>>(
|
fn relate<R: TypeRelation<'tcx>>(
|
||||||
relation: &mut R,
|
_relation: &mut R,
|
||||||
a: ty::ImplPolarity,
|
a: ty::ImplPolarity,
|
||||||
b: ty::ImplPolarity,
|
b: ty::ImplPolarity,
|
||||||
) -> RelateResult<'tcx, ty::ImplPolarity> {
|
) -> RelateResult<'tcx, ty::ImplPolarity> {
|
||||||
if a != b {
|
if a != b { Err(TypeError::PolarityMismatch(expected_found(a, b))) } else { Ok(a) }
|
||||||
Err(TypeError::PolarityMismatch(expected_found(relation, a, b)))
|
|
||||||
} else {
|
|
||||||
Ok(a)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,9 +809,6 @@ impl<'tcx> Relate<'tcx> for Term<'tcx> {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Error handling
|
// Error handling
|
||||||
|
|
||||||
pub fn expected_found<'tcx, R, T>(relation: &mut R, a: T, b: T) -> ExpectedFound<T>
|
pub fn expected_found<T>(a: T, b: T) -> ExpectedFound<T> {
|
||||||
where
|
ExpectedFound::new(true, a, b)
|
||||||
R: TypeRelation<'tcx>,
|
|
||||||
{
|
|
||||||
ExpectedFound::new(relation.a_is_expected(), a, b)
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue