summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-05-15 17:00:16 +0000
committerMichael Goulet <michael@errs.io>2023-05-15 17:00:16 +0000
commita2678e15e559bb7d779fd1e04d73d8ae3b9093e3 (patch)
tree6e45a5ae01e2814a385428f4bdc3ce474efb7fda /compiler
parent41501c74490570c24b38f55484981f22eebf0d39 (diff)
downloadrust-a2678e15e559bb7d779fd1e04d73d8ae3b9093e3.tar.gz
Replace RelationDir with Variance
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs77
-rw-r--r--compiler/rustc_infer/src/infer/equate.rs6
-rw-r--r--compiler/rustc_infer/src/infer/generalize.rs3
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs6
4 files changed, 29 insertions, 63 deletions
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 9559bfab6da..79fc02c6c79 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -48,13 +48,6 @@ pub struct CombineFields<'infcx, 'tcx> {
pub define_opaque_types: DefineOpaqueTypes,
}
-#[derive(Copy, Clone, Debug)]
-pub enum RelationDir {
- SubtypeOf,
- SupertypeOf,
- EqTo,
-}
-
impl<'tcx> InferCtxt<'tcx> {
pub fn super_combine_tys<R>(
&self,
@@ -378,12 +371,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
pub fn instantiate(
&mut self,
a_ty: Ty<'tcx>,
- dir: RelationDir,
+ ambient_variance: ty::Variance,
b_vid: ty::TyVid,
a_is_expected: bool,
) -> RelateResult<'tcx, ()> {
- use self::RelationDir::*;
-
// Get the actual variable that b_vid has been inferred to
debug_assert!(self.infcx.inner.borrow_mut().type_variables().probe(b_vid).is_unknown());
@@ -398,7 +389,18 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
// `'?2` and `?3` are fresh region/type inference
// variables. (Down below, we will relate `a_ty <: b_ty`,
// adding constraints like `'x: '?2` and `?1 <: ?3`.)
- let Generalization { value: b_ty, needs_wf } = self.generalize(a_ty, b_vid, dir)?;
+ let Generalization { value: b_ty, needs_wf } = generalize::generalize(
+ self.infcx,
+ &mut CombineDelegate {
+ infcx: self.infcx,
+ param_env: self.param_env,
+ span: self.trace.span(),
+ },
+ a_ty,
+ b_vid,
+ ambient_variance,
+ )?;
+
debug!(?b_ty);
self.infcx.inner.borrow_mut().type_variables().instantiate(b_vid, b_ty);
@@ -417,62 +419,23 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
// relations wind up attributed to the same spans. We need
// to associate causes/spans with each of the relations in
// the stack to get this right.
- match dir {
- EqTo => self.equate(a_is_expected).relate(a_ty, b_ty),
- SubtypeOf => self.sub(a_is_expected).relate(a_ty, b_ty),
- SupertypeOf => self.sub(a_is_expected).relate_with_variance(
+ match ambient_variance {
+ ty::Variance::Invariant => self.equate(a_is_expected).relate(a_ty, b_ty),
+ ty::Variance::Covariant => self.sub(a_is_expected).relate(a_ty, b_ty),
+ ty::Variance::Contravariant => self.sub(a_is_expected).relate_with_variance(
ty::Contravariant,
ty::VarianceDiagInfo::default(),
a_ty,
b_ty,
),
+ ty::Variance::Bivariant => {
+ unreachable!("no code should be generalizing bivariantly (currently)")
+ }
}?;
Ok(())
}
- /// Attempts to generalize `ty` for the type variable `for_vid`.
- /// This checks for cycle -- that is, whether the type `ty`
- /// references `for_vid`. The `dir` is the "direction" for which we
- /// a performing the generalization (i.e., are we producing a type
- /// that can be used as a supertype etc).
- ///
- /// Preconditions:
- ///
- /// - `for_vid` is a "root vid"
- #[instrument(skip(self), level = "trace", ret)]
- fn generalize(
- &mut self,
- ty: Ty<'tcx>,
- for_vid: ty::TyVid,
- dir: RelationDir,
- ) -> RelateResult<'tcx, Generalization<Ty<'tcx>>> {
- // Determine the ambient variance within which `ty` appears.
- // The surrounding equation is:
- //
- // ty [op] ty2
- //
- // where `op` is either `==`, `<:`, or `:>`. This maps quite
- // naturally.
- let ambient_variance = match dir {
- RelationDir::EqTo => ty::Invariant,
- RelationDir::SubtypeOf => ty::Covariant,
- RelationDir::SupertypeOf => ty::Contravariant,
- };
-
- generalize::generalize(
- self.infcx,
- &mut CombineDelegate {
- infcx: self.infcx,
- param_env: self.param_env,
- span: self.trace.span(),
- },
- ty,
- for_vid,
- ambient_variance,
- )
- }
-
pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
self.obligations.extend(obligations.into_iter());
}
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index f90f7674b55..793505e4ab2 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
@@ -1,7 +1,7 @@
use crate::infer::DefineOpaqueTypes;
use crate::traits::PredicateObligations;
-use super::combine::{CombineFields, ObligationEmittingRelation, RelationDir};
+use super::combine::{CombineFields, ObligationEmittingRelation};
use super::Subtype;
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
@@ -88,11 +88,11 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
}
(&ty::Infer(TyVar(a_id)), _) => {
- self.fields.instantiate(b, RelationDir::EqTo, a_id, self.a_is_expected)?;
+ self.fields.instantiate(b, ty::Invariant, a_id, self.a_is_expected)?;
}
(_, &ty::Infer(TyVar(b_id))) => {
- self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?;
+ self.fields.instantiate(a, ty::Invariant, b_id, self.a_is_expected)?;
}
(
diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/generalize.rs
index 3eeb55ae744..d4a1dacde10 100644
--- a/compiler/rustc_infer/src/infer/generalize.rs
+++ b/compiler/rustc_infer/src/infer/generalize.rs
@@ -10,6 +10,9 @@ use crate::infer::nll_relate::TypeRelatingDelegate;
use crate::infer::type_variable::TypeVariableValue;
use crate::infer::{InferCtxt, RegionVariableOrigin};
+/// Attempts to generalize `term` for the type variable `for_vid`.
+/// This checks for cycles -- that is, whether the type `term`
+/// references `for_vid`.
pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
infcx: &InferCtxt<'tcx>,
delegate: &mut D,
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index 3766c250a9c..e0f29a8de8f 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -1,4 +1,4 @@
-use super::combine::{CombineFields, RelationDir};
+use super::combine::CombineFields;
use super::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin};
use crate::traits::{Obligation, PredicateObligations};
@@ -108,11 +108,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
Ok(a)
}
(&ty::Infer(TyVar(a_id)), _) => {
- self.fields.instantiate(b, RelationDir::SupertypeOf, a_id, !self.a_is_expected)?;
+ self.fields.instantiate(b, ty::Contravariant, a_id, !self.a_is_expected)?;
Ok(a)
}
(_, &ty::Infer(TyVar(b_id))) => {
- self.fields.instantiate(a, RelationDir::SubtypeOf, b_id, self.a_is_expected)?;
+ self.fields.instantiate(a, ty::Covariant, b_id, self.a_is_expected)?;
Ok(a)
}