run rustfmt on librustc_typeck/variance folder
This commit is contained in:
parent
95abee1a68
commit
765eaac000
5 changed files with 145 additions and 152 deletions
|
@ -49,8 +49,7 @@ pub struct Constraint<'a> {
|
|||
}
|
||||
|
||||
pub fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>)
|
||||
-> ConstraintContext<'a, 'tcx>
|
||||
{
|
||||
-> ConstraintContext<'a, 'tcx> {
|
||||
let tcx = terms_cx.tcx;
|
||||
let covariant = terms_cx.arena.alloc(ConstantTerm(ty::Covariant));
|
||||
let contravariant = terms_cx.arena.alloc(ConstantTerm(ty::Contravariant));
|
||||
|
@ -80,7 +79,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
|
|||
debug!("visit_item item={}", tcx.map.node_to_string(item.id));
|
||||
|
||||
match item.node {
|
||||
hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) => {
|
||||
hir::ItemEnum(..) |
|
||||
hir::ItemStruct(..) |
|
||||
hir::ItemUnion(..) => {
|
||||
let scheme = tcx.lookup_item_type(did);
|
||||
|
||||
// Not entirely obvious: constraints on structs/enums do not
|
||||
|
@ -111,8 +112,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
|
|||
hir::ItemForeignMod(..) |
|
||||
hir::ItemTy(..) |
|
||||
hir::ItemImpl(..) |
|
||||
hir::ItemDefaultImpl(..) => {
|
||||
}
|
||||
hir::ItemDefaultImpl(..) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +120,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
|
|||
/// Is `param_id` a lifetime according to `map`?
|
||||
fn is_lifetime(map: &hir_map::Map, param_id: ast::NodeId) -> bool {
|
||||
match map.find(param_id) {
|
||||
Some(hir_map::NodeLifetime(..)) => true, _ => false
|
||||
Some(hir_map::NodeLifetime(..)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,8 +144,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
let tcx = self.terms_cx.tcx;
|
||||
assert!(is_lifetime(&tcx.map, param_id));
|
||||
match tcx.named_region_map.defs.get(¶m_id) {
|
||||
Some(&rl::DefEarlyBoundRegion(_, lifetime_decl_id))
|
||||
=> lifetime_decl_id,
|
||||
Some(&rl::DefEarlyBoundRegion(_, lifetime_decl_id)) => lifetime_decl_id,
|
||||
Some(_) => bug!("should not encounter non early-bound cases"),
|
||||
|
||||
// The lookup should only fail when `param_id` is
|
||||
|
@ -169,8 +169,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
// Currently only called on lifetimes; double-checking that.
|
||||
assert!(is_lifetime(&tcx.map, param_id));
|
||||
let parent_id = tcx.map.get_parent(decl_id);
|
||||
let parent = tcx.map.find(parent_id).unwrap_or_else(
|
||||
|| bug!("tcx.map missing entry for id: {}", parent_id));
|
||||
let parent = tcx.map
|
||||
.find(parent_id)
|
||||
.unwrap_or_else(|| bug!("tcx.map missing entry for id: {}", parent_id));
|
||||
|
||||
let is_inferred;
|
||||
macro_rules! cannot_happen { () => { {
|
||||
|
@ -230,21 +231,18 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
fn add_constraint(&mut self,
|
||||
InferredIndex(index): InferredIndex,
|
||||
variance: VarianceTermPtr<'a>) {
|
||||
debug!("add_constraint(index={}, variance={:?})",
|
||||
index, variance);
|
||||
self.constraints.push(Constraint { inferred: InferredIndex(index),
|
||||
variance: variance });
|
||||
debug!("add_constraint(index={}, variance={:?})", index, variance);
|
||||
self.constraints.push(Constraint {
|
||||
inferred: InferredIndex(index),
|
||||
variance: variance,
|
||||
});
|
||||
}
|
||||
|
||||
fn contravariant(&mut self,
|
||||
variance: VarianceTermPtr<'a>)
|
||||
-> VarianceTermPtr<'a> {
|
||||
fn contravariant(&mut self, variance: VarianceTermPtr<'a>) -> VarianceTermPtr<'a> {
|
||||
self.xform(variance, self.contravariant)
|
||||
}
|
||||
|
||||
fn invariant(&mut self,
|
||||
variance: VarianceTermPtr<'a>)
|
||||
-> VarianceTermPtr<'a> {
|
||||
fn invariant(&mut self, variance: VarianceTermPtr<'a>) -> VarianceTermPtr<'a> {
|
||||
self.xform(variance, self.invariant)
|
||||
}
|
||||
|
||||
|
@ -257,23 +255,16 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn xform(&mut self,
|
||||
v1: VarianceTermPtr<'a>,
|
||||
v2: VarianceTermPtr<'a>)
|
||||
-> VarianceTermPtr<'a> {
|
||||
fn xform(&mut self, v1: VarianceTermPtr<'a>, v2: VarianceTermPtr<'a>) -> VarianceTermPtr<'a> {
|
||||
match (*v1, *v2) {
|
||||
(_, ConstantTerm(ty::Covariant)) => {
|
||||
// Applying a "covariant" transform is always a no-op
|
||||
v1
|
||||
}
|
||||
|
||||
(ConstantTerm(c1), ConstantTerm(c2)) => {
|
||||
self.constant_term(c1.xform(c2))
|
||||
}
|
||||
(ConstantTerm(c1), ConstantTerm(c2)) => self.constant_term(c1.xform(c2)),
|
||||
|
||||
_ => {
|
||||
&*self.terms_cx.arena.alloc(TransformTerm(v1, v2))
|
||||
}
|
||||
_ => &*self.terms_cx.arena.alloc(TransformTerm(v1, v2)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,8 +283,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
// README.md for a discussion on dep-graph management.
|
||||
self.tcx().dep_graph.read(ItemVariances::to_dep_node(&trait_ref.def_id));
|
||||
|
||||
self.add_constraints_from_substs(
|
||||
generics,
|
||||
self.add_constraints_from_substs(generics,
|
||||
trait_ref.def_id,
|
||||
&trait_def.generics.types,
|
||||
&trait_def.generics.regions,
|
||||
|
@ -313,13 +303,13 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
variance);
|
||||
|
||||
match ty.sty {
|
||||
ty::TyBool |
|
||||
ty::TyChar | ty::TyInt(_) | ty::TyUint(_) |
|
||||
ty::TyFloat(_) | ty::TyStr | ty::TyNever => {
|
||||
/* leaf type -- noop */
|
||||
ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) |
|
||||
ty::TyStr | ty::TyNever => {
|
||||
// leaf type -- noop
|
||||
}
|
||||
|
||||
ty::TyClosure(..) | ty::TyAnon(..) => {
|
||||
ty::TyClosure(..) |
|
||||
ty::TyAnon(..) => {
|
||||
bug!("Unexpected closure type in variance computation");
|
||||
}
|
||||
|
||||
|
@ -329,11 +319,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
self.add_constraints_from_mt(generics, mt, variance);
|
||||
}
|
||||
|
||||
ty::TyBox(typ) | ty::TyArray(typ, _) | ty::TySlice(typ) => {
|
||||
ty::TyBox(typ) |
|
||||
ty::TyArray(typ, _) |
|
||||
ty::TySlice(typ) => {
|
||||
self.add_constraints_from_ty(generics, typ, variance);
|
||||
}
|
||||
|
||||
|
||||
ty::TyRawPtr(ref mt) => {
|
||||
self.add_constraints_from_mt(generics, mt, variance);
|
||||
}
|
||||
|
@ -352,8 +343,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
// README.md for a discussion on dep-graph management.
|
||||
self.tcx().dep_graph.read(ItemVariances::to_dep_node(&def.did));
|
||||
|
||||
self.add_constraints_from_substs(
|
||||
generics,
|
||||
self.add_constraints_from_substs(generics,
|
||||
def.did,
|
||||
&item_type.generics.types,
|
||||
&item_type.generics.regions,
|
||||
|
@ -370,8 +360,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
// README.md for a discussion on dep-graph management.
|
||||
self.tcx().dep_graph.read(ItemVariances::to_dep_node(&trait_ref.def_id));
|
||||
|
||||
self.add_constraints_from_substs(
|
||||
generics,
|
||||
self.add_constraints_from_substs(generics,
|
||||
trait_ref.def_id,
|
||||
&trait_def.generics.types,
|
||||
&trait_def.generics.regions,
|
||||
|
@ -384,8 +373,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
let contra = self.contravariant(variance);
|
||||
self.add_constraints_from_region(generics, data.region_bound, contra);
|
||||
|
||||
let poly_trait_ref =
|
||||
data.principal.with_self_ty(self.tcx(), self.tcx().types.err);
|
||||
let poly_trait_ref = data.principal.with_self_ty(self.tcx(), self.tcx().types.err);
|
||||
self.add_constraints_from_trait_ref(generics, poly_trait_ref.0, variance);
|
||||
|
||||
for projection in &data.projection_bounds {
|
||||
|
@ -425,7 +413,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
|
||||
ty::TyInfer(..) => {
|
||||
bug!("unexpected type encountered in \
|
||||
variance inference: {}", ty);
|
||||
variance inference: {}",
|
||||
ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -445,18 +434,17 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
variance);
|
||||
|
||||
for p in type_param_defs {
|
||||
let variance_decl =
|
||||
self.declared_variance(p.def_id, def_id, p.index as usize);
|
||||
let variance_decl = self.declared_variance(p.def_id, def_id, p.index as usize);
|
||||
let variance_i = self.xform(variance, variance_decl);
|
||||
let substs_ty = substs.type_for_def(p);
|
||||
debug!("add_constraints_from_substs: variance_decl={:?} variance_i={:?}",
|
||||
variance_decl, variance_i);
|
||||
variance_decl,
|
||||
variance_i);
|
||||
self.add_constraints_from_ty(generics, substs_ty, variance_i);
|
||||
}
|
||||
|
||||
for p in region_param_defs {
|
||||
let variance_decl =
|
||||
self.declared_variance(p.def_id, def_id, p.index as usize);
|
||||
let variance_decl = self.declared_variance(p.def_id, def_id, p.index as usize);
|
||||
let variance_i = self.xform(variance, variance_decl);
|
||||
let substs_r = substs.region_for_def(p);
|
||||
self.add_constraints_from_region(generics, substs_r, variance_i);
|
||||
|
@ -501,8 +489,12 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
// methods or in fn types.
|
||||
}
|
||||
|
||||
ty::ReFree(..) | ty::ReScope(..) | ty::ReVar(..) |
|
||||
ty::ReSkolemized(..) | ty::ReEmpty | ty::ReErased => {
|
||||
ty::ReFree(..) |
|
||||
ty::ReScope(..) |
|
||||
ty::ReVar(..) |
|
||||
ty::ReSkolemized(..) |
|
||||
ty::ReEmpty |
|
||||
ty::ReErased => {
|
||||
// We don't expect to see anything but 'static or bound
|
||||
// regions when visiting member types or method types.
|
||||
bug!("unexpected region encountered in variance \
|
||||
|
|
|
@ -34,4 +34,3 @@ pub fn infer_variance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
solve::solve_constraints(constraints_cx);
|
||||
tcx.variance_computed.set(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,21 +28,21 @@ struct SolveContext<'a, 'tcx: 'a> {
|
|||
constraints: Vec<Constraint<'a>>,
|
||||
|
||||
// Maps from an InferredIndex to the inferred value for that variable.
|
||||
solutions: Vec<ty::Variance>
|
||||
solutions: Vec<ty::Variance>,
|
||||
}
|
||||
|
||||
pub fn solve_constraints(constraints_cx: ConstraintContext) {
|
||||
let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
|
||||
|
||||
let solutions =
|
||||
terms_cx.inferred_infos.iter()
|
||||
let solutions = terms_cx.inferred_infos
|
||||
.iter()
|
||||
.map(|ii| ii.initial_variance)
|
||||
.collect();
|
||||
|
||||
let mut solutions_cx = SolveContext {
|
||||
terms_cx: terms_cx,
|
||||
constraints: constraints,
|
||||
solutions: solutions
|
||||
solutions: solutions,
|
||||
};
|
||||
solutions_cx.solve();
|
||||
solutions_cx.write();
|
||||
|
@ -114,36 +114,40 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
|||
let info = &inferred_infos[index];
|
||||
let variance = solutions[index];
|
||||
debug!("Index {} Info {} Variance {:?}",
|
||||
index, info.index, variance);
|
||||
index,
|
||||
info.index,
|
||||
variance);
|
||||
|
||||
assert_eq!(item_variances.len(), info.index);
|
||||
item_variances.push(variance);
|
||||
index += 1;
|
||||
}
|
||||
|
||||
debug!("item_id={} item_variances={:?}",
|
||||
item_id,
|
||||
item_variances);
|
||||
debug!("item_id={} item_variances={:?}", item_id, item_variances);
|
||||
|
||||
let item_def_id = tcx.map.local_def_id(item_id);
|
||||
|
||||
// For unit testing: check for a special "rustc_variance"
|
||||
// attribute and report an error with various results if found.
|
||||
if tcx.has_attr(item_def_id, "rustc_variance") {
|
||||
span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{:?}", item_variances);
|
||||
span_err!(tcx.sess,
|
||||
tcx.map.span(item_id),
|
||||
E0208,
|
||||
"{:?}",
|
||||
item_variances);
|
||||
}
|
||||
|
||||
let newly_added = tcx.item_variance_map.borrow_mut()
|
||||
.insert(item_def_id, Rc::new(item_variances)).is_none();
|
||||
let newly_added = tcx.item_variance_map
|
||||
.borrow_mut()
|
||||
.insert(item_def_id, Rc::new(item_variances))
|
||||
.is_none();
|
||||
assert!(newly_added);
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate(&self, term: VarianceTermPtr<'a>) -> ty::Variance {
|
||||
match *term {
|
||||
ConstantTerm(v) => {
|
||||
v
|
||||
}
|
||||
ConstantTerm(v) => v,
|
||||
|
||||
TransformTerm(t1, t2) => {
|
||||
let v1 = self.evaluate(t1);
|
||||
|
@ -151,9 +155,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
|
|||
v1.xform(v2)
|
||||
}
|
||||
|
||||
InferredTerm(InferredIndex(index)) => {
|
||||
self.solutions[index]
|
||||
}
|
||||
InferredTerm(InferredIndex(index)) => self.solutions[index],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,12 @@ impl<'a> fmt::Debug for VarianceTerm<'a> {
|
|||
match *self {
|
||||
ConstantTerm(c1) => write!(f, "{:?}", c1),
|
||||
TransformTerm(v1, v2) => write!(f, "({:?} \u{00D7} {:?})", v1, v2),
|
||||
InferredTerm(id) => write!(f, "[{}]", { let InferredIndex(i) = id; i })
|
||||
InferredTerm(id) => {
|
||||
write!(f, "[{}]", {
|
||||
let InferredIndex(i) = id;
|
||||
i
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,11 +92,9 @@ pub struct InferredInfo<'a> {
|
|||
pub initial_variance: ty::Variance,
|
||||
}
|
||||
|
||||
pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
arena: &'a mut TypedArena<VarianceTerm<'a>>)
|
||||
-> TermsContext<'a, 'tcx>
|
||||
{
|
||||
-> TermsContext<'a, 'tcx> {
|
||||
let mut terms_cx = TermsContext {
|
||||
tcx: tcx,
|
||||
arena: arena,
|
||||
|
@ -102,12 +105,11 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
|
|||
|
||||
// cache and share the variance struct used for items with
|
||||
// no type/region parameters
|
||||
empty_variances: Rc::new(vec![])
|
||||
empty_variances: Rc::new(vec![]),
|
||||
};
|
||||
|
||||
// See README.md for a discussion on dep-graph management.
|
||||
tcx.visit_all_items_in_krate(|def_id| ItemVariances::to_dep_node(&def_id),
|
||||
&mut terms_cx);
|
||||
tcx.visit_all_items_in_krate(|def_id| ItemVariances::to_dep_node(&def_id), &mut terms_cx);
|
||||
|
||||
terms_cx
|
||||
}
|
||||
|
@ -138,15 +140,13 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
|
|||
fn add_inferreds_for_item(&mut self,
|
||||
item_id: ast::NodeId,
|
||||
has_self: bool,
|
||||
generics: &hir::Generics)
|
||||
{
|
||||
/*!
|
||||
* Add "inferreds" for the generic parameters declared on this
|
||||
* item. This has a lot of annoying parameters because we are
|
||||
* trying to drive this from the AST, rather than the
|
||||
* ty::Generics, so that we can get span info -- but this
|
||||
* means we must accommodate syntactic distinctions.
|
||||
*/
|
||||
generics: &hir::Generics) {
|
||||
//! Add "inferreds" for the generic parameters declared on this
|
||||
//! item. This has a lot of annoying parameters because we are
|
||||
//! trying to drive this from the AST, rather than the
|
||||
//! ty::Generics, so that we can get span info -- but this
|
||||
//! means we must accommodate syntactic distinctions.
|
||||
//!
|
||||
|
||||
// NB: In the code below for writing the results back into the
|
||||
// tcx, we rely on the fact that all inferreds for a particular
|
||||
|
@ -178,26 +178,26 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
|
|||
// parameters".
|
||||
if self.num_inferred() == inferreds_on_entry {
|
||||
let item_def_id = self.tcx.map.local_def_id(item_id);
|
||||
let newly_added =
|
||||
self.tcx.item_variance_map.borrow_mut().insert(
|
||||
item_def_id,
|
||||
self.empty_variances.clone()).is_none();
|
||||
let newly_added = self.tcx
|
||||
.item_variance_map
|
||||
.borrow_mut()
|
||||
.insert(item_def_id, self.empty_variances.clone())
|
||||
.is_none();
|
||||
assert!(newly_added);
|
||||
}
|
||||
}
|
||||
|
||||
fn add_inferred(&mut self,
|
||||
item_id: ast::NodeId,
|
||||
index: usize,
|
||||
param_id: ast::NodeId) {
|
||||
fn add_inferred(&mut self, item_id: ast::NodeId, index: usize, param_id: ast::NodeId) {
|
||||
let inf_index = InferredIndex(self.inferred_infos.len());
|
||||
let term = self.arena.alloc(InferredTerm(inf_index));
|
||||
let initial_variance = self.pick_initial_variance(item_id, index);
|
||||
self.inferred_infos.push(InferredInfo { item_id: item_id,
|
||||
self.inferred_infos.push(InferredInfo {
|
||||
item_id: item_id,
|
||||
index: index,
|
||||
param_id: param_id,
|
||||
term: term,
|
||||
initial_variance: initial_variance });
|
||||
initial_variance: initial_variance,
|
||||
});
|
||||
let newly_added = self.inferred_map.insert(param_id, inf_index).is_none();
|
||||
assert!(newly_added);
|
||||
|
||||
|
@ -208,18 +208,17 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
|
|||
inf_index={:?}, \
|
||||
initial_variance={:?})",
|
||||
self.tcx.item_path_str(self.tcx.map.local_def_id(item_id)),
|
||||
item_id, index, param_id, inf_index,
|
||||
item_id,
|
||||
index,
|
||||
param_id,
|
||||
inf_index,
|
||||
initial_variance);
|
||||
}
|
||||
|
||||
fn pick_initial_variance(&self,
|
||||
item_id: ast::NodeId,
|
||||
index: usize)
|
||||
-> ty::Variance
|
||||
{
|
||||
fn pick_initial_variance(&self, item_id: ast::NodeId, index: usize) -> ty::Variance {
|
||||
match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
|
||||
Some(&(_, ref variances)) => variances[index],
|
||||
None => ty::Bivariant
|
||||
None => ty::Bivariant,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +229,8 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
|
|||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
|
||||
fn visit_item(&mut self, item: &hir::Item) {
|
||||
debug!("add_inferreds for item {}", self.tcx.map.node_to_string(item.id));
|
||||
debug!("add_inferreds for item {}",
|
||||
self.tcx.map.node_to_string(item.id));
|
||||
|
||||
match item.node {
|
||||
hir::ItemEnum(_, ref generics) |
|
||||
|
@ -254,9 +254,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
|
|||
hir::ItemFn(..) |
|
||||
hir::ItemMod(..) |
|
||||
hir::ItemForeignMod(..) |
|
||||
hir::ItemTy(..) => {
|
||||
hir::ItemTy(..) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ pub fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
|
|||
// - +
|
||||
// o
|
||||
match (v1, v2) {
|
||||
(ty::Invariant, _) | (_, ty::Invariant) => ty::Invariant,
|
||||
(ty::Invariant, _) |
|
||||
(_, ty::Invariant) => ty::Invariant,
|
||||
|
||||
(ty::Covariant, ty::Contravariant) => ty::Invariant,
|
||||
(ty::Contravariant, ty::Covariant) => ty::Invariant,
|
||||
|
@ -56,6 +57,7 @@ pub fn glb(v1: ty::Variance, v2: ty::Variance) -> ty::Variance {
|
|||
|
||||
(ty::Contravariant, ty::Contravariant) => ty::Contravariant,
|
||||
|
||||
(x, ty::Bivariant) | (ty::Bivariant, x) => x,
|
||||
(x, ty::Bivariant) |
|
||||
(ty::Bivariant, x) => x,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue