Rollup merge of #126354 - compiler-errors:variance, r=lcnr
Use `Variance` glob imported variants everywhere Fully commit to using the globbed variance. Could be convinced the other way, and change this PR to not use the globbed variants anywhere, but I'd rather we do one or the other. r? lcnr
This commit is contained in:
commit
335e320baa
20 changed files with 74 additions and 111 deletions
|
@ -328,7 +328,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
if let Some(annotation_index) = constant.user_ty {
|
if let Some(annotation_index) = constant.user_ty {
|
||||||
if let Err(terr) = self.cx.relate_type_and_user_type(
|
if let Err(terr) = self.cx.relate_type_and_user_type(
|
||||||
constant.const_.ty(),
|
constant.const_.ty(),
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
||||||
locations,
|
locations,
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::Boring,
|
||||||
|
@ -451,7 +451,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
|
|
||||||
if let Err(terr) = self.cx.relate_type_and_user_type(
|
if let Err(terr) = self.cx.relate_type_and_user_type(
|
||||||
ty,
|
ty,
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
user_ty,
|
user_ty,
|
||||||
Locations::All(*span),
|
Locations::All(*span),
|
||||||
ConstraintCategory::TypeAnnotation,
|
ConstraintCategory::TypeAnnotation,
|
||||||
|
@ -1095,7 +1095,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
) -> Result<(), NoSolution> {
|
) -> Result<(), NoSolution> {
|
||||||
// Use this order of parameters because the sup type is usually the
|
// Use this order of parameters because the sup type is usually the
|
||||||
// "expected" type in diagnostics.
|
// "expected" type in diagnostics.
|
||||||
self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category)
|
self.relate_types(sup, ty::Contravariant, sub, locations, category)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self, category), level = "debug")]
|
#[instrument(skip(self, category), level = "debug")]
|
||||||
|
@ -1106,7 +1106,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
locations: Locations,
|
locations: Locations,
|
||||||
category: ConstraintCategory<'tcx>,
|
category: ConstraintCategory<'tcx>,
|
||||||
) -> Result<(), NoSolution> {
|
) -> Result<(), NoSolution> {
|
||||||
self.relate_types(expected, ty::Variance::Invariant, found, locations, category)
|
self.relate_types(expected, ty::Invariant, found, locations, category)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
|
@ -1146,7 +1146,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
trace!(?curr_projected_ty);
|
trace!(?curr_projected_ty);
|
||||||
|
|
||||||
let ty = curr_projected_ty.ty;
|
let ty = curr_projected_ty.ty;
|
||||||
self.relate_types(ty, v.xform(ty::Variance::Contravariant), a, locations, category)?;
|
self.relate_types(ty, v.xform(ty::Contravariant), a, locations, category)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1248,7 +1248,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
if let Some(annotation_index) = self.rvalue_user_ty(rv) {
|
if let Some(annotation_index) = self.rvalue_user_ty(rv) {
|
||||||
if let Err(terr) = self.relate_type_and_user_type(
|
if let Err(terr) = self.relate_type_and_user_type(
|
||||||
rv_ty,
|
rv_ty,
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
&UserTypeProjection { base: annotation_index, projs: vec![] },
|
||||||
location.to_locations(),
|
location.to_locations(),
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::Boring,
|
||||||
|
|
|
@ -50,13 +50,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
locations: Locations,
|
locations: Locations,
|
||||||
category: ConstraintCategory<'tcx>,
|
category: ConstraintCategory<'tcx>,
|
||||||
) -> Result<(), NoSolution> {
|
) -> Result<(), NoSolution> {
|
||||||
NllTypeRelating::new(
|
NllTypeRelating::new(self, locations, category, UniverseInfo::other(), ty::Invariant)
|
||||||
self,
|
|
||||||
locations,
|
|
||||||
category,
|
|
||||||
UniverseInfo::other(),
|
|
||||||
ty::Variance::Invariant,
|
|
||||||
)
|
|
||||||
.relate(a, b)?;
|
.relate(a, b)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -106,15 +100,15 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> {
|
||||||
|
|
||||||
fn ambient_covariance(&self) -> bool {
|
fn ambient_covariance(&self) -> bool {
|
||||||
match self.ambient_variance {
|
match self.ambient_variance {
|
||||||
ty::Variance::Covariant | ty::Variance::Invariant => true,
|
ty::Covariant | ty::Invariant => true,
|
||||||
ty::Variance::Contravariant | ty::Variance::Bivariant => false,
|
ty::Contravariant | ty::Bivariant => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ambient_contravariance(&self) -> bool {
|
fn ambient_contravariance(&self) -> bool {
|
||||||
match self.ambient_variance {
|
match self.ambient_variance {
|
||||||
ty::Variance::Contravariant | ty::Variance::Invariant => true,
|
ty::Contravariant | ty::Invariant => true,
|
||||||
ty::Variance::Covariant | ty::Variance::Bivariant => false,
|
ty::Covariant | ty::Bivariant => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,11 +330,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
||||||
|
|
||||||
debug!(?self.ambient_variance);
|
debug!(?self.ambient_variance);
|
||||||
// In a bivariant context this always succeeds.
|
// In a bivariant context this always succeeds.
|
||||||
let r = if self.ambient_variance == ty::Variance::Bivariant {
|
let r = if self.ambient_variance == ty::Bivariant { Ok(a) } else { self.relate(a, b) };
|
||||||
Ok(a)
|
|
||||||
} else {
|
|
||||||
self.relate(a, b)
|
|
||||||
};
|
|
||||||
|
|
||||||
self.ambient_variance = old_ambient_variance;
|
self.ambient_variance = old_ambient_variance;
|
||||||
|
|
||||||
|
@ -474,7 +464,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.ambient_variance {
|
match self.ambient_variance {
|
||||||
ty::Variance::Covariant => {
|
ty::Covariant => {
|
||||||
// Covariance, so we want `for<..> A <: for<..> B` --
|
// Covariance, so we want `for<..> A <: for<..> B` --
|
||||||
// therefore we compare any instantiation of A (i.e., A
|
// therefore we compare any instantiation of A (i.e., A
|
||||||
// instantiated with existentials) against every
|
// instantiated with existentials) against every
|
||||||
|
@ -489,7 +479,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Variance::Contravariant => {
|
ty::Contravariant => {
|
||||||
// Contravariance, so we want `for<..> A :> for<..> B` --
|
// Contravariance, so we want `for<..> A :> for<..> B` --
|
||||||
// therefore we compare every instantiation of A (i.e., A
|
// therefore we compare every instantiation of A (i.e., A
|
||||||
// instantiated with universals) against any
|
// instantiated with universals) against any
|
||||||
|
@ -504,7 +494,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Variance::Invariant => {
|
ty::Invariant => {
|
||||||
// Invariant, so we want `for<..> A == for<..> B` --
|
// Invariant, so we want `for<..> A == for<..> B` --
|
||||||
// therefore we want `exists<..> A == for<..> B` and
|
// therefore we want `exists<..> A == for<..> B` and
|
||||||
// `exists<..> B == for<..> A`.
|
// `exists<..> B == for<..> A`.
|
||||||
|
@ -525,7 +515,7 @@ impl<'bccx, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'bccx, 'tcx
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Variance::Bivariant => {}
|
ty::Bivariant => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(a)
|
Ok(a)
|
||||||
|
@ -584,23 +574,23 @@ impl<'bccx, 'tcx> PredicateEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx,
|
||||||
|
|
||||||
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>) {
|
||||||
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
|
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
|
||||||
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
|
ty::Covariant => ty::PredicateKind::AliasRelate(
|
||||||
a.into(),
|
a.into(),
|
||||||
b.into(),
|
b.into(),
|
||||||
ty::AliasRelationDirection::Subtype,
|
ty::AliasRelationDirection::Subtype,
|
||||||
),
|
),
|
||||||
// a :> b is b <: a
|
// a :> b is b <: a
|
||||||
ty::Variance::Contravariant => ty::PredicateKind::AliasRelate(
|
ty::Contravariant => ty::PredicateKind::AliasRelate(
|
||||||
b.into(),
|
b.into(),
|
||||||
a.into(),
|
a.into(),
|
||||||
ty::AliasRelationDirection::Subtype,
|
ty::AliasRelationDirection::Subtype,
|
||||||
),
|
),
|
||||||
ty::Variance::Invariant => ty::PredicateKind::AliasRelate(
|
ty::Invariant => ty::PredicateKind::AliasRelate(
|
||||||
a.into(),
|
a.into(),
|
||||||
b.into(),
|
b.into(),
|
||||||
ty::AliasRelationDirection::Equate,
|
ty::AliasRelationDirection::Equate,
|
||||||
),
|
),
|
||||||
ty::Variance::Bivariant => {
|
ty::Bivariant => {
|
||||||
unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)")
|
unreachable!("cannot defer an alias-relate goal with Bivariant variance (yet?)")
|
||||||
}
|
}
|
||||||
})]);
|
})]);
|
||||||
|
|
|
@ -212,16 +212,16 @@ impl<'a, 'tcx> At<'a, 'tcx> {
|
||||||
T: ToTrace<'tcx>,
|
T: ToTrace<'tcx>,
|
||||||
{
|
{
|
||||||
match variance {
|
match variance {
|
||||||
ty::Variance::Covariant => self.sub(define_opaque_types, expected, actual),
|
ty::Covariant => self.sub(define_opaque_types, expected, actual),
|
||||||
ty::Variance::Invariant => self.eq(define_opaque_types, expected, actual),
|
ty::Invariant => self.eq(define_opaque_types, expected, actual),
|
||||||
ty::Variance::Contravariant => self.sup(define_opaque_types, expected, actual),
|
ty::Contravariant => self.sup(define_opaque_types, expected, actual),
|
||||||
|
|
||||||
// We could make this make sense but it's not readily
|
// We could make this make sense but it's not readily
|
||||||
// exposed and I don't feel like dealing with it. Note
|
// exposed and I don't feel like dealing with it. Note
|
||||||
// that bivariance in general does a bit more than just
|
// that bivariance in general does a bit more than just
|
||||||
// *nothing*, it checks that the types are the same
|
// *nothing*, it checks that the types are the same
|
||||||
// "modulo variance" basically.
|
// "modulo variance" basically.
|
||||||
ty::Variance::Bivariant => panic!("Bivariant given to `relate()`"),
|
ty::Bivariant => panic!("Bivariant given to `relate()`"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -345,7 +345,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(i, _)| variances[*i] == ty::Variance::Invariant)
|
.filter(|(i, _)| variances[*i] == ty::Invariant)
|
||||||
.filter_map(|(_, arg)| match arg.unpack() {
|
.filter_map(|(_, arg)| match arg.unpack() {
|
||||||
GenericArgKind::Lifetime(r) => Some(r),
|
GenericArgKind::Lifetime(r) => Some(r),
|
||||||
GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
|
GenericArgKind::Type(_) | GenericArgKind::Const(_) => None,
|
||||||
|
@ -441,7 +441,7 @@ where
|
||||||
let variances = self.tcx.variances_of(*def_id);
|
let variances = self.tcx.variances_of(*def_id);
|
||||||
|
|
||||||
for (v, s) in std::iter::zip(variances, args.iter()) {
|
for (v, s) in std::iter::zip(variances, args.iter()) {
|
||||||
if *v != ty::Variance::Bivariant {
|
if *v != ty::Bivariant {
|
||||||
s.visit_with(self);
|
s.visit_with(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,9 +102,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
for (idx, s) in args.iter().enumerate() {
|
for (idx, s) in args.iter().enumerate() {
|
||||||
if variances.map(|variances| variances[idx])
|
if variances.map(|variances| variances[idx]) != Some(ty::Bivariant) {
|
||||||
!= Some(ty::Variance::Bivariant)
|
|
||||||
{
|
|
||||||
s.visit_with(self);
|
s.visit_with(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,16 +83,16 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
// mention `?0`.
|
// mention `?0`.
|
||||||
if self.next_trait_solver() {
|
if self.next_trait_solver() {
|
||||||
let (lhs, rhs, direction) = match instantiation_variance {
|
let (lhs, rhs, direction) = match instantiation_variance {
|
||||||
ty::Variance::Invariant => {
|
ty::Invariant => {
|
||||||
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate)
|
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Equate)
|
||||||
}
|
}
|
||||||
ty::Variance::Covariant => {
|
ty::Covariant => {
|
||||||
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Subtype)
|
(generalized_ty.into(), source_ty.into(), AliasRelationDirection::Subtype)
|
||||||
}
|
}
|
||||||
ty::Variance::Contravariant => {
|
ty::Contravariant => {
|
||||||
(source_ty.into(), generalized_ty.into(), AliasRelationDirection::Subtype)
|
(source_ty.into(), generalized_ty.into(), AliasRelationDirection::Subtype)
|
||||||
}
|
}
|
||||||
ty::Variance::Bivariant => unreachable!("bivariant generalization"),
|
ty::Bivariant => unreachable!("bivariant generalization"),
|
||||||
};
|
};
|
||||||
|
|
||||||
relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]);
|
relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]);
|
||||||
|
@ -192,7 +192,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
relation.span(),
|
relation.span(),
|
||||||
relation.structurally_relate_aliases(),
|
relation.structurally_relate_aliases(),
|
||||||
target_vid,
|
target_vid,
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
source_ct,
|
source_ct,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -210,14 +210,14 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
// generalized const and the source.
|
// generalized const and the source.
|
||||||
if target_is_expected {
|
if target_is_expected {
|
||||||
relation.relate_with_variance(
|
relation.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
ty::VarianceDiagInfo::default(),
|
ty::VarianceDiagInfo::default(),
|
||||||
generalized_ct,
|
generalized_ct,
|
||||||
source_ct,
|
source_ct,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
relation.relate_with_variance(
|
relation.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
ty::VarianceDiagInfo::default(),
|
ty::VarianceDiagInfo::default(),
|
||||||
source_ct,
|
source_ct,
|
||||||
generalized_ct,
|
generalized_ct,
|
||||||
|
@ -411,7 +411,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
|
||||||
a_arg: ty::GenericArgsRef<'tcx>,
|
a_arg: ty::GenericArgsRef<'tcx>,
|
||||||
b_arg: ty::GenericArgsRef<'tcx>,
|
b_arg: ty::GenericArgsRef<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
|
) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
|
||||||
if self.ambient_variance == ty::Variance::Invariant {
|
if self.ambient_variance == ty::Invariant {
|
||||||
// Avoid fetching the variance if we are in an invariant
|
// Avoid fetching the variance if we are in an invariant
|
||||||
// context; no need, and it can induce dependency cycles
|
// context; no need, and it can induce dependency cycles
|
||||||
// (e.g., #41849).
|
// (e.g., #41849).
|
||||||
|
@ -667,7 +667,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
|
||||||
// structural.
|
// structural.
|
||||||
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
|
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
|
||||||
let args = self.relate_with_variance(
|
let args = self.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
ty::VarianceDiagInfo::default(),
|
ty::VarianceDiagInfo::default(),
|
||||||
args,
|
args,
|
||||||
args,
|
args,
|
||||||
|
|
|
@ -94,12 +94,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Glb<'_, '_, 'tcx> {
|
||||||
// When higher-ranked types are involved, computing the GLB is
|
// When higher-ranked types are involved, computing the GLB is
|
||||||
// very challenging, switch to invariance. This is obviously
|
// very challenging, switch to invariance. This is obviously
|
||||||
// overly conservative but works ok in practice.
|
// overly conservative but works ok in practice.
|
||||||
self.relate_with_variance(
|
self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
|
||||||
ty::Variance::Invariant,
|
|
||||||
ty::VarianceDiagInfo::default(),
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
)?;
|
|
||||||
Ok(a)
|
Ok(a)
|
||||||
} else {
|
} else {
|
||||||
Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
|
Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
|
||||||
|
|
|
@ -94,12 +94,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Lub<'_, '_, 'tcx> {
|
||||||
// When higher-ranked types are involved, computing the LUB is
|
// When higher-ranked types are involved, computing the LUB is
|
||||||
// very challenging, switch to invariance. This is obviously
|
// very challenging, switch to invariance. This is obviously
|
||||||
// overly conservative but works ok in practice.
|
// overly conservative but works ok in practice.
|
||||||
self.relate_with_variance(
|
self.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)?;
|
||||||
ty::Variance::Invariant,
|
|
||||||
ty::VarianceDiagInfo::default(),
|
|
||||||
a,
|
|
||||||
b,
|
|
||||||
)?;
|
|
||||||
Ok(a)
|
Ok(a)
|
||||||
} else {
|
} else {
|
||||||
Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
|
Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for TypeRelating<'_, '_, 'tcx> {
|
||||||
a_arg: ty::GenericArgsRef<'tcx>,
|
a_arg: ty::GenericArgsRef<'tcx>,
|
||||||
b_arg: ty::GenericArgsRef<'tcx>,
|
b_arg: ty::GenericArgsRef<'tcx>,
|
||||||
) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
|
) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
|
||||||
if self.ambient_variance == ty::Variance::Invariant {
|
if self.ambient_variance == ty::Invariant {
|
||||||
// Avoid fetching the variance if we are in an invariant
|
// Avoid fetching the variance if we are in an invariant
|
||||||
// context; no need, and it can induce dependency cycles
|
// context; no need, and it can induce dependency cycles
|
||||||
// (e.g., #41849).
|
// (e.g., #41849).
|
||||||
|
@ -325,23 +325,23 @@ impl<'tcx> PredicateEmittingRelation<'tcx> for TypeRelating<'_, '_, 'tcx> {
|
||||||
|
|
||||||
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>) {
|
||||||
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
|
self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
|
||||||
ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
|
ty::Covariant => ty::PredicateKind::AliasRelate(
|
||||||
a.into(),
|
a.into(),
|
||||||
b.into(),
|
b.into(),
|
||||||
ty::AliasRelationDirection::Subtype,
|
ty::AliasRelationDirection::Subtype,
|
||||||
),
|
),
|
||||||
// a :> b is b <: a
|
// a :> b is b <: a
|
||||||
ty::Variance::Contravariant => ty::PredicateKind::AliasRelate(
|
ty::Contravariant => ty::PredicateKind::AliasRelate(
|
||||||
b.into(),
|
b.into(),
|
||||||
a.into(),
|
a.into(),
|
||||||
ty::AliasRelationDirection::Subtype,
|
ty::AliasRelationDirection::Subtype,
|
||||||
),
|
),
|
||||||
ty::Variance::Invariant => ty::PredicateKind::AliasRelate(
|
ty::Invariant => ty::PredicateKind::AliasRelate(
|
||||||
a.into(),
|
a.into(),
|
||||||
b.into(),
|
b.into(),
|
||||||
ty::AliasRelationDirection::Equate,
|
ty::AliasRelationDirection::Equate,
|
||||||
),
|
),
|
||||||
ty::Variance::Bivariant => {
|
ty::Bivariant => {
|
||||||
unreachable!("Expected bivariance to be handled in relate_with_variance")
|
unreachable!("Expected bivariance to be handled in relate_with_variance")
|
||||||
}
|
}
|
||||||
})]);
|
})]);
|
||||||
|
|
|
@ -16,7 +16,6 @@ pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeV
|
||||||
pub use self::AssocItemContainer::*;
|
pub use self::AssocItemContainer::*;
|
||||||
pub use self::BorrowKind::*;
|
pub use self::BorrowKind::*;
|
||||||
pub use self::IntVarValue::*;
|
pub use self::IntVarValue::*;
|
||||||
pub use self::Variance::*;
|
|
||||||
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
|
use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason};
|
||||||
use crate::metadata::ModChild;
|
use crate::metadata::ModChild;
|
||||||
use crate::middle::privacy::EffectiveVisibilities;
|
use crate::middle::privacy::EffectiveVisibilities;
|
||||||
|
|
|
@ -142,7 +142,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for &[ty::Variance] {
|
||||||
&& let Some(def_id) = frame.query.def_id
|
&& let Some(def_id) = frame.query.def_id
|
||||||
{
|
{
|
||||||
let n = tcx.generics_of(def_id).own_params.len();
|
let n = tcx.generics_of(def_id).own_params.len();
|
||||||
vec![ty::Variance::Bivariant; n].leak()
|
vec![ty::Bivariant; n].leak()
|
||||||
} else {
|
} else {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
cycle_error.usage.as_ref().unwrap().0,
|
cycle_error.usage.as_ref().unwrap().0,
|
||||||
|
|
|
@ -699,7 +699,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||||
// exactly `T` (i.e., with invariance). The variance field, in
|
// exactly `T` (i.e., with invariance). The variance field, in
|
||||||
// contrast, is intended to be used to relate `T` to the type of
|
// contrast, is intended to be used to relate `T` to the type of
|
||||||
// `<expr>`.
|
// `<expr>`.
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -92,7 +92,7 @@ impl<'tcx> Cx<'tcx> {
|
||||||
kind: PatKind::AscribeUserType {
|
kind: PatKind::AscribeUserType {
|
||||||
ascription: Ascription {
|
ascription: Ascription {
|
||||||
annotation,
|
annotation,
|
||||||
variance: ty::Variance::Covariant,
|
variance: ty::Covariant,
|
||||||
},
|
},
|
||||||
subpattern: pattern,
|
subpattern: pattern,
|
||||||
},
|
},
|
||||||
|
|
|
@ -525,7 +525,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
kind = PatKind::AscribeUserType {
|
kind = PatKind::AscribeUserType {
|
||||||
subpattern: Box::new(Pat { span, ty, kind }),
|
subpattern: Box::new(Pat { span, ty, kind }),
|
||||||
ascription: Ascription { annotation, variance: ty::Variance::Covariant },
|
ascription: Ascription { annotation, variance: ty::Covariant },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,7 +612,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
annotation,
|
annotation,
|
||||||
// Note that use `Contravariant` here. See the
|
// Note that use `Contravariant` here. See the
|
||||||
// `variance` field documentation for details.
|
// `variance` field documentation for details.
|
||||||
variance: ty::Variance::Contravariant,
|
variance: ty::Contravariant,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ty: const_.ty(),
|
ty: const_.ty(),
|
||||||
|
|
|
@ -225,13 +225,8 @@ impl<'tcx> Inliner<'tcx> {
|
||||||
// Normally, this shouldn't be required, but trait normalization failure can create a
|
// Normally, this shouldn't be required, but trait normalization failure can create a
|
||||||
// validation ICE.
|
// validation ICE.
|
||||||
let output_type = callee_body.return_ty();
|
let output_type = callee_body.return_ty();
|
||||||
if !util::relate_types(
|
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, output_type, destination_ty)
|
||||||
self.tcx,
|
{
|
||||||
self.param_env,
|
|
||||||
ty::Variance::Covariant,
|
|
||||||
output_type,
|
|
||||||
destination_ty,
|
|
||||||
) {
|
|
||||||
trace!(?output_type, ?destination_ty);
|
trace!(?output_type, ?destination_ty);
|
||||||
return Err("failed to normalize return type");
|
return Err("failed to normalize return type");
|
||||||
}
|
}
|
||||||
|
@ -261,13 +256,8 @@ impl<'tcx> Inliner<'tcx> {
|
||||||
self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
|
self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
|
||||||
{
|
{
|
||||||
let input_type = callee_body.local_decls[input].ty;
|
let input_type = callee_body.local_decls[input].ty;
|
||||||
if !util::relate_types(
|
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
|
||||||
self.tcx,
|
{
|
||||||
self.param_env,
|
|
||||||
ty::Variance::Covariant,
|
|
||||||
input_type,
|
|
||||||
arg_ty,
|
|
||||||
) {
|
|
||||||
trace!(?arg_ty, ?input_type);
|
trace!(?arg_ty, ?input_type);
|
||||||
return Err("failed to normalize tuple argument type");
|
return Err("failed to normalize tuple argument type");
|
||||||
}
|
}
|
||||||
|
@ -276,13 +266,8 @@ impl<'tcx> Inliner<'tcx> {
|
||||||
for (arg, input) in args.iter().zip(callee_body.args_iter()) {
|
for (arg, input) in args.iter().zip(callee_body.args_iter()) {
|
||||||
let input_type = callee_body.local_decls[input].ty;
|
let input_type = callee_body.local_decls[input].ty;
|
||||||
let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx);
|
let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx);
|
||||||
if !util::relate_types(
|
if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
|
||||||
self.tcx,
|
{
|
||||||
self.param_env,
|
|
||||||
ty::Variance::Covariant,
|
|
||||||
input_type,
|
|
||||||
arg_ty,
|
|
||||||
) {
|
|
||||||
trace!(?arg_ty, ?input_type);
|
trace!(?arg_ty, ?input_type);
|
||||||
return Err("failed to normalize argument type");
|
return Err("failed to normalize argument type");
|
||||||
}
|
}
|
||||||
|
|
|
@ -866,10 +866,10 @@ impl<'tcx> Stable<'tcx> for ty::Variance {
|
||||||
type T = stable_mir::mir::Variance;
|
type T = stable_mir::mir::Variance;
|
||||||
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
fn stable(&self, _: &mut Tables<'_>) -> Self::T {
|
||||||
match self {
|
match self {
|
||||||
ty::Variance::Bivariant => stable_mir::mir::Variance::Bivariant,
|
ty::Bivariant => stable_mir::mir::Variance::Bivariant,
|
||||||
ty::Variance::Contravariant => stable_mir::mir::Variance::Contravariant,
|
ty::Contravariant => stable_mir::mir::Variance::Contravariant,
|
||||||
ty::Variance::Covariant => stable_mir::mir::Variance::Covariant,
|
ty::Covariant => stable_mir::mir::Variance::Covariant,
|
||||||
ty::Variance::Invariant => stable_mir::mir::Variance::Invariant,
|
ty::Invariant => stable_mir::mir::Variance::Invariant,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||||
trace!(?lhs, ?rhs);
|
trace!(?lhs, ?rhs);
|
||||||
|
|
||||||
let variance = match direction {
|
let variance = match direction {
|
||||||
ty::AliasRelationDirection::Equate => ty::Variance::Invariant,
|
ty::AliasRelationDirection::Equate => ty::Invariant,
|
||||||
ty::AliasRelationDirection::Subtype => ty::Variance::Covariant,
|
ty::AliasRelationDirection::Subtype => ty::Covariant,
|
||||||
};
|
};
|
||||||
match (lhs.to_alias_term(), rhs.to_alias_term()) {
|
match (lhs.to_alias_term(), rhs.to_alias_term()) {
|
||||||
(None, None) => {
|
(None, None) => {
|
||||||
|
@ -78,7 +78,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||||
self.relate_rigid_alias_non_alias(
|
self.relate_rigid_alias_non_alias(
|
||||||
param_env,
|
param_env,
|
||||||
alias,
|
alias,
|
||||||
variance.xform(ty::Variance::Contravariant),
|
variance.xform(ty::Contravariant),
|
||||||
lhs,
|
lhs,
|
||||||
)?;
|
)?;
|
||||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
|
|
|
@ -40,7 +40,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
|
||||||
Ok(res) => Ok(res),
|
Ok(res) => Ok(res),
|
||||||
Err(NoSolution) => {
|
Err(NoSolution) => {
|
||||||
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
|
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
|
||||||
self.relate_rigid_alias_non_alias(param_env, alias, ty::Variance::Invariant, term)?;
|
self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
|
||||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ pub use DynKind::*;
|
||||||
pub use InferTy::*;
|
pub use InferTy::*;
|
||||||
pub use RegionKind::*;
|
pub use RegionKind::*;
|
||||||
pub use TyKind::*;
|
pub use TyKind::*;
|
||||||
|
pub use Variance::*;
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
/// A [De Bruijn index][dbi] is a standard means of representing
|
/// A [De Bruijn index][dbi] is a standard means of representing
|
||||||
|
|
|
@ -128,7 +128,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>(
|
||||||
b_arg: I::GenericArgs,
|
b_arg: I::GenericArgs,
|
||||||
) -> RelateResult<I, I::GenericArgs> {
|
) -> RelateResult<I, I::GenericArgs> {
|
||||||
relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| {
|
relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| {
|
||||||
relation.relate_with_variance(ty::Variance::Invariant, VarianceDiagInfo::default(), a, b)
|
relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>(
|
||||||
let mut cached_ty = None;
|
let mut cached_ty = None;
|
||||||
let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| {
|
let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| {
|
||||||
let variance = variances[i];
|
let variance = variances[i];
|
||||||
let variance_info = if variance == ty::Variance::Invariant && fetch_ty_for_diag {
|
let variance_info = if variance == ty::Invariant && fetch_ty_for_diag {
|
||||||
let ty =
|
let ty =
|
||||||
*cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, &a_arg));
|
*cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, &a_arg));
|
||||||
VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
|
VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
|
||||||
|
@ -191,7 +191,7 @@ impl<I: Interner> Relate<I> for ty::FnSig<I> {
|
||||||
relation.relate(a, b)
|
relation.relate(a, b)
|
||||||
} else {
|
} else {
|
||||||
relation.relate_with_variance(
|
relation.relate_with_variance(
|
||||||
ty::Variance::Contravariant,
|
ty::Contravariant,
|
||||||
VarianceDiagInfo::default(),
|
VarianceDiagInfo::default(),
|
||||||
a,
|
a,
|
||||||
b,
|
b,
|
||||||
|
@ -311,13 +311,13 @@ impl<I: Interner> Relate<I> for ty::ExistentialProjection<I> {
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
let term = relation.relate_with_variance(
|
let term = relation.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
VarianceDiagInfo::default(),
|
VarianceDiagInfo::default(),
|
||||||
a.term,
|
a.term,
|
||||||
b.term,
|
b.term,
|
||||||
)?;
|
)?;
|
||||||
let args = relation.relate_with_variance(
|
let args = relation.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
VarianceDiagInfo::default(),
|
VarianceDiagInfo::default(),
|
||||||
a.args,
|
a.args,
|
||||||
b.args,
|
b.args,
|
||||||
|
@ -466,9 +466,9 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let (variance, info) = match a_mutbl {
|
let (variance, info) = match a_mutbl {
|
||||||
Mutability::Not => (ty::Variance::Covariant, VarianceDiagInfo::None),
|
Mutability::Not => (ty::Covariant, VarianceDiagInfo::None),
|
||||||
Mutability::Mut => {
|
Mutability::Mut => {
|
||||||
(ty::Variance::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
|
(ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -483,9 +483,9 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let (variance, info) = match a_mutbl {
|
let (variance, info) = match a_mutbl {
|
||||||
Mutability::Not => (ty::Variance::Covariant, VarianceDiagInfo::None),
|
Mutability::Not => (ty::Covariant, VarianceDiagInfo::None),
|
||||||
Mutability::Mut => {
|
Mutability::Mut => {
|
||||||
(ty::Variance::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
|
(ty::Invariant, VarianceDiagInfo::Invariant { ty: a, param_index: 0 })
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -612,7 +612,7 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let args = relation.relate_with_variance(
|
let args = relation.relate_with_variance(
|
||||||
ty::Variance::Invariant,
|
ty::Invariant,
|
||||||
VarianceDiagInfo::default(),
|
VarianceDiagInfo::default(),
|
||||||
au.args,
|
au.args,
|
||||||
bu.args,
|
bu.args,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue