Skip to content

Commit

Permalink
Remove unnecessary VarianceTerm
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Dec 28, 2024
1 parent 4ea29d6 commit 0e50c3c
Showing 1 changed file with 31 additions and 74 deletions.
105 changes: 31 additions & 74 deletions src/tools/rust-analyzer/crates/hir-ty/src/variance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,21 +170,6 @@ impl Variance {
#[derive(Copy, Clone, Debug)]
struct InferredIndex(usize);

#[derive(Clone)]
enum VarianceTerm {
ConstantTerm(Variance),
TransformTerm(Box<VarianceTerm>, Box<VarianceTerm>),
}

impl fmt::Debug for VarianceTerm {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
VarianceTerm::ConstantTerm(c1) => write!(f, "{c1:?}"),
VarianceTerm::TransformTerm(v1, v2) => write!(f, "({v1:?} \u{00D7} {v2:?})"),
}
}
}

struct Context<'db> {
db: &'db dyn HirDatabase,
def: GenericDefId,
Expand All @@ -200,7 +185,7 @@ struct Context<'db> {
#[derive(Clone)]
struct Constraint {
inferred: InferredIndex,
variance: VarianceTerm,
variance: Variance,
}

impl Context<'_> {
Expand All @@ -213,7 +198,7 @@ impl Context<'_> {
for (_, field) in db.field_types(variant).iter() {
self.add_constraints_from_ty(
&field.clone().substitute(Interner, &subst),
&VarianceTerm::ConstantTerm(Variance::Covariant),
Variance::Covariant,
);
}
};
Expand All @@ -235,37 +220,22 @@ impl Context<'_> {
.callable_item_signature(f.into())
.substitute(Interner, &subst)
.params_and_return,
&VarianceTerm::ConstantTerm(Variance::Covariant),
Variance::Covariant,
);
}
_ => {}
}
}

fn contravariant(&mut self, variance: &VarianceTerm) -> VarianceTerm {
self.xform(variance, &VarianceTerm::ConstantTerm(Variance::Contravariant))
fn contravariant(&mut self, variance: Variance) -> Variance {
variance.xform(Variance::Contravariant)
}

fn invariant(&mut self, variance: &VarianceTerm) -> VarianceTerm {
self.xform(variance, &VarianceTerm::ConstantTerm(Variance::Invariant))
fn invariant(&mut self, variance: Variance) -> Variance {
variance.xform(Variance::Invariant)
}

fn xform(&mut self, v1: &VarianceTerm, v2: &VarianceTerm) -> VarianceTerm {
match (v1, v2) {
// Applying a "covariant" transform is always a no-op
(_, VarianceTerm::ConstantTerm(Variance::Covariant)) => v1.clone(),
(VarianceTerm::ConstantTerm(c1), VarianceTerm::ConstantTerm(c2)) => {
VarianceTerm::ConstantTerm(c1.xform(*c2))
}
_ => VarianceTerm::TransformTerm(Box::new(v1.clone()), Box::new(v2.clone())),
}
}

fn add_constraints_from_invariant_args(
&mut self,
args: &[GenericArg],
variance: &VarianceTerm,
) {
fn add_constraints_from_invariant_args(&mut self, args: &[GenericArg], variance: Variance) {
tracing::debug!(
"add_constraints_from_invariant_args(args={:?}, variance={:?})",
args,
Expand All @@ -275,17 +245,17 @@ impl Context<'_> {

for k in args {
match k.data(Interner) {
GenericArgData::Lifetime(lt) => self.add_constraints_from_region(lt, &variance_i),
GenericArgData::Ty(ty) => self.add_constraints_from_ty(ty, &variance_i),
GenericArgData::Const(val) => self.add_constraints_from_const(val, &variance_i),
GenericArgData::Lifetime(lt) => self.add_constraints_from_region(lt, variance_i),
GenericArgData::Ty(ty) => self.add_constraints_from_ty(ty, variance_i),
GenericArgData::Const(val) => self.add_constraints_from_const(val, variance_i),
}
}
}

/// Adds constraints appropriate for an instance of `ty` appearing
/// in a context with the generics defined in `generics` and
/// ambient variance `variance`
fn add_constraints_from_ty(&mut self, ty: &Ty, variance: &VarianceTerm) {
fn add_constraints_from_ty(&mut self, ty: &Ty, variance: Variance) {
tracing::debug!("add_constraints_from_ty(ty={:?}, variance={:?})", ty, variance);
match ty.kind(Interner) {
TyKind::Scalar(_) | TyKind::Never | TyKind::Str | TyKind::Foreign(..) => {
Expand Down Expand Up @@ -390,7 +360,7 @@ impl Context<'_> {
InferredIndex(self.len_self + index)
};
tracing::debug!("add_constraint(index={:?}, variance={:?})", inferred, variance);
self.constraints.push(Constraint { inferred, variance: variance.clone() });
self.constraints.push(Constraint { inferred, variance });
}
TyKind::Function(f) => {
self.add_constraints_from_sig(f, variance);
Expand All @@ -413,7 +383,7 @@ impl Context<'_> {
&mut self,
def_id: GenericDefId,
args: &[GenericArg],
variance: &VarianceTerm,
variance: Variance,
) {
tracing::debug!(
"add_constraints_from_args(def_id={:?}, args={:?}, variance={:?})",
Expand All @@ -429,13 +399,13 @@ impl Context<'_> {
if def_id == self.def {
// HACK: Workaround for the trivial cycle salsa case (see
// recursive_one_bivariant_more_non_bivariant_params test)
let variance_i = self.xform(variance, &VarianceTerm::ConstantTerm(Variance::Bivariant));
let variance_i = variance.xform(Variance::Bivariant);
for k in args {
match k.data(Interner) {
GenericArgData::Lifetime(lt) => {
self.add_constraints_from_region(lt, &variance_i)
self.add_constraints_from_region(lt, variance_i)
}
GenericArgData::Ty(ty) => self.add_constraints_from_ty(ty, &variance_i),
GenericArgData::Ty(ty) => self.add_constraints_from_ty(ty, variance_i),
GenericArgData::Const(val) => self.add_constraints_from_const(val, variance),
}
}
Expand All @@ -445,13 +415,12 @@ impl Context<'_> {
};

for (i, k) in args.iter().enumerate() {
let variance_decl = &VarianceTerm::ConstantTerm(variances[i]);
let variance_i = self.xform(variance, variance_decl);
let variance_i = variance.xform(variances[i]);
match k.data(Interner) {
GenericArgData::Lifetime(lt) => {
self.add_constraints_from_region(lt, &variance_i)
self.add_constraints_from_region(lt, variance_i)
}
GenericArgData::Ty(ty) => self.add_constraints_from_ty(ty, &variance_i),
GenericArgData::Ty(ty) => self.add_constraints_from_ty(ty, variance_i),
GenericArgData::Const(val) => self.add_constraints_from_const(val, variance),
}
}
Expand All @@ -460,7 +429,7 @@ impl Context<'_> {

/// Adds constraints appropriate for a const expression `val`
/// in a context with ambient variance `variance`
fn add_constraints_from_const(&mut self, c: &Const, variance: &VarianceTerm) {
fn add_constraints_from_const(&mut self, c: &Const, variance: Variance) {
match &c.data(Interner).value {
chalk_ir::ConstValue::Concrete(c) => {
if let ConstScalar::UnevaluatedConst(_, subst) = &c.interned {
Expand All @@ -473,27 +442,27 @@ impl Context<'_> {

/// Adds constraints appropriate for a function with signature
/// `sig` appearing in a context with ambient variance `variance`
fn add_constraints_from_sig(&mut self, sig: &FnPointer, variance: &VarianceTerm) {
fn add_constraints_from_sig(&mut self, sig: &FnPointer, variance: Variance) {
let contra = self.contravariant(variance);
let mut tys = sig.substitution.0.iter(Interner).filter_map(move |p| p.ty(Interner));
self.add_constraints_from_ty(tys.next_back().unwrap(), variance);
for input in tys {
self.add_constraints_from_ty(input, &contra);
self.add_constraints_from_ty(input, contra);
}
}

fn add_constraints_from_sig2(&mut self, sig: &[Ty], variance: &VarianceTerm) {
fn add_constraints_from_sig2(&mut self, sig: &[Ty], variance: Variance) {
let contra = self.contravariant(variance);
let mut tys = sig.iter();
self.add_constraints_from_ty(tys.next_back().unwrap(), variance);
for input in tys {
self.add_constraints_from_ty(input, &contra);
self.add_constraints_from_ty(input, contra);
}
}

/// Adds constraints appropriate for a region appearing in a
/// context with ambient variance `variance`
fn add_constraints_from_region(&mut self, region: &Lifetime, variance: &VarianceTerm) {
fn add_constraints_from_region(&mut self, region: &Lifetime, variance: Variance) {
match region.data(Interner) {
// FIXME: chalk has no params?
LifetimeData::Placeholder(index) => {
Expand Down Expand Up @@ -532,11 +501,11 @@ impl Context<'_> {

/// Adds constraints appropriate for a mutability-type pair
/// appearing in a context with ambient variance `variance`
fn add_constraints_from_mt(&mut self, ty: &Ty, mt: Mutability, variance: &VarianceTerm) {
fn add_constraints_from_mt(&mut self, ty: &Ty, mt: Mutability, variance: Variance) {
match mt {
Mutability::Mut => {
let invar = self.invariant(variance);
self.add_constraints_from_ty(ty, &invar);
self.add_constraints_from_ty(ty, invar);
}

Mutability::Not => {
Expand All @@ -559,13 +528,12 @@ impl Context<'_> {
changed = false;

for constraint in &self.constraints {
let Constraint { inferred, variance: term } = constraint;
let &Constraint { inferred, variance } = constraint;
let InferredIndex(inferred) = inferred;
let variance = Self::evaluate(term);
let old_value = solutions[*inferred];
let old_value = solutions[inferred];
let new_value = variance.glb(old_value);
if old_value != new_value {
solutions[*inferred] = new_value;
solutions[inferred] = new_value;
changed = true;
}
}
Expand All @@ -590,17 +558,6 @@ impl Context<'_> {

solutions
}

fn evaluate(term: &VarianceTerm) -> Variance {
match term {
VarianceTerm::ConstantTerm(v) => *v,
VarianceTerm::TransformTerm(t1, t2) => {
let v1 = Self::evaluate(t1);
let v2 = Self::evaluate(t2);
v1.xform(v2)
}
}
}
}

#[cfg(test)]
Expand Down

0 comments on commit 0e50c3c

Please sign in to comment.