Skip to content

Commit a2678e1

Browse files
Replace RelationDir with Variance
1 parent 41501c7 commit a2678e1

File tree

4 files changed

+29
-63
lines changed

4 files changed

+29
-63
lines changed

compiler/rustc_infer/src/infer/combine.rs

+20-57
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,6 @@ pub struct CombineFields<'infcx, 'tcx> {
4848
pub define_opaque_types: DefineOpaqueTypes,
4949
}
5050

51-
#[derive(Copy, Clone, Debug)]
52-
pub enum RelationDir {
53-
SubtypeOf,
54-
SupertypeOf,
55-
EqTo,
56-
}
57-
5851
impl<'tcx> InferCtxt<'tcx> {
5952
pub fn super_combine_tys<R>(
6053
&self,
@@ -378,12 +371,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
378371
pub fn instantiate(
379372
&mut self,
380373
a_ty: Ty<'tcx>,
381-
dir: RelationDir,
374+
ambient_variance: ty::Variance,
382375
b_vid: ty::TyVid,
383376
a_is_expected: bool,
384377
) -> RelateResult<'tcx, ()> {
385-
use self::RelationDir::*;
386-
387378
// Get the actual variable that b_vid has been inferred to
388379
debug_assert!(self.infcx.inner.borrow_mut().type_variables().probe(b_vid).is_unknown());
389380

@@ -398,7 +389,18 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
398389
// `'?2` and `?3` are fresh region/type inference
399390
// variables. (Down below, we will relate `a_ty <: b_ty`,
400391
// adding constraints like `'x: '?2` and `?1 <: ?3`.)
401-
let Generalization { value: b_ty, needs_wf } = self.generalize(a_ty, b_vid, dir)?;
392+
let Generalization { value: b_ty, needs_wf } = generalize::generalize(
393+
self.infcx,
394+
&mut CombineDelegate {
395+
infcx: self.infcx,
396+
param_env: self.param_env,
397+
span: self.trace.span(),
398+
},
399+
a_ty,
400+
b_vid,
401+
ambient_variance,
402+
)?;
403+
402404
debug!(?b_ty);
403405
self.infcx.inner.borrow_mut().type_variables().instantiate(b_vid, b_ty);
404406

@@ -417,62 +419,23 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
417419
// relations wind up attributed to the same spans. We need
418420
// to associate causes/spans with each of the relations in
419421
// the stack to get this right.
420-
match dir {
421-
EqTo => self.equate(a_is_expected).relate(a_ty, b_ty),
422-
SubtypeOf => self.sub(a_is_expected).relate(a_ty, b_ty),
423-
SupertypeOf => self.sub(a_is_expected).relate_with_variance(
422+
match ambient_variance {
423+
ty::Variance::Invariant => self.equate(a_is_expected).relate(a_ty, b_ty),
424+
ty::Variance::Covariant => self.sub(a_is_expected).relate(a_ty, b_ty),
425+
ty::Variance::Contravariant => self.sub(a_is_expected).relate_with_variance(
424426
ty::Contravariant,
425427
ty::VarianceDiagInfo::default(),
426428
a_ty,
427429
b_ty,
428430
),
431+
ty::Variance::Bivariant => {
432+
unreachable!("no code should be generalizing bivariantly (currently)")
433+
}
429434
}?;
430435

431436
Ok(())
432437
}
433438

434-
/// Attempts to generalize `ty` for the type variable `for_vid`.
435-
/// This checks for cycle -- that is, whether the type `ty`
436-
/// references `for_vid`. The `dir` is the "direction" for which we
437-
/// a performing the generalization (i.e., are we producing a type
438-
/// that can be used as a supertype etc).
439-
///
440-
/// Preconditions:
441-
///
442-
/// - `for_vid` is a "root vid"
443-
#[instrument(skip(self), level = "trace", ret)]
444-
fn generalize(
445-
&mut self,
446-
ty: Ty<'tcx>,
447-
for_vid: ty::TyVid,
448-
dir: RelationDir,
449-
) -> RelateResult<'tcx, Generalization<Ty<'tcx>>> {
450-
// Determine the ambient variance within which `ty` appears.
451-
// The surrounding equation is:
452-
//
453-
// ty [op] ty2
454-
//
455-
// where `op` is either `==`, `<:`, or `:>`. This maps quite
456-
// naturally.
457-
let ambient_variance = match dir {
458-
RelationDir::EqTo => ty::Invariant,
459-
RelationDir::SubtypeOf => ty::Covariant,
460-
RelationDir::SupertypeOf => ty::Contravariant,
461-
};
462-
463-
generalize::generalize(
464-
self.infcx,
465-
&mut CombineDelegate {
466-
infcx: self.infcx,
467-
param_env: self.param_env,
468-
span: self.trace.span(),
469-
},
470-
ty,
471-
for_vid,
472-
ambient_variance,
473-
)
474-
}
475-
476439
pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
477440
self.obligations.extend(obligations.into_iter());
478441
}

compiler/rustc_infer/src/infer/equate.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::infer::DefineOpaqueTypes;
22
use crate::traits::PredicateObligations;
33

4-
use super::combine::{CombineFields, ObligationEmittingRelation, RelationDir};
4+
use super::combine::{CombineFields, ObligationEmittingRelation};
55
use super::Subtype;
66

77
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
@@ -88,11 +88,11 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
8888
}
8989

9090
(&ty::Infer(TyVar(a_id)), _) => {
91-
self.fields.instantiate(b, RelationDir::EqTo, a_id, self.a_is_expected)?;
91+
self.fields.instantiate(b, ty::Invariant, a_id, self.a_is_expected)?;
9292
}
9393

9494
(_, &ty::Infer(TyVar(b_id))) => {
95-
self.fields.instantiate(a, RelationDir::EqTo, b_id, self.a_is_expected)?;
95+
self.fields.instantiate(a, ty::Invariant, b_id, self.a_is_expected)?;
9696
}
9797

9898
(

compiler/rustc_infer/src/infer/generalize.rs

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ use crate::infer::nll_relate::TypeRelatingDelegate;
1010
use crate::infer::type_variable::TypeVariableValue;
1111
use crate::infer::{InferCtxt, RegionVariableOrigin};
1212

13+
/// Attempts to generalize `term` for the type variable `for_vid`.
14+
/// This checks for cycles -- that is, whether the type `term`
15+
/// references `for_vid`.
1316
pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
1417
infcx: &InferCtxt<'tcx>,
1518
delegate: &mut D,

compiler/rustc_infer/src/infer/sub.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::combine::{CombineFields, RelationDir};
1+
use super::combine::CombineFields;
22
use super::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin};
33

44
use crate::traits::{Obligation, PredicateObligations};
@@ -108,11 +108,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
108108
Ok(a)
109109
}
110110
(&ty::Infer(TyVar(a_id)), _) => {
111-
self.fields.instantiate(b, RelationDir::SupertypeOf, a_id, !self.a_is_expected)?;
111+
self.fields.instantiate(b, ty::Contravariant, a_id, !self.a_is_expected)?;
112112
Ok(a)
113113
}
114114
(_, &ty::Infer(TyVar(b_id))) => {
115-
self.fields.instantiate(a, RelationDir::SubtypeOf, b_id, self.a_is_expected)?;
115+
self.fields.instantiate(a, ty::Covariant, b_id, self.a_is_expected)?;
116116
Ok(a)
117117
}
118118

0 commit comments

Comments
 (0)