Skip to content

Commit

Permalink
Split relate_substs into two functions
Browse files Browse the repository at this point in the history
One for the case with variances, and one without.
All callers use an explicit Option for the variable anyway.
  • Loading branch information
martingms committed Apr 17, 2022
1 parent 041121a commit 19dedf3
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 31 deletions.
10 changes: 8 additions & 2 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -567,11 +567,17 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
// Avoid fetching the variance if we are in an invariant
// context; no need, and it can induce dependency cycles
// (e.g., #41849).
relate::relate_substs(self, None, a_subst, b_subst)
relate::relate_substs(self, a_subst, b_subst)
} else {
let tcx = self.tcx();
let opt_variances = tcx.variances_of(item_def_id);
relate::relate_substs(self, Some((item_def_id, &opt_variances)), a_subst, b_subst)
relate::relate_substs_with_variances(
self,
item_def_id,
&opt_variances,
a_subst,
b_subst,
)
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/equate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
// performing trait matching (which then performs equality
// unification).

relate::relate_substs(self, None, a_subst, b_subst)
relate::relate_substs(self, a_subst, b_subst)
}

fn relate_with_variance<T: Relate<'tcx>>(
Expand Down
61 changes: 33 additions & 28 deletions compiler/rustc_middle/src/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub trait TypeRelation<'tcx>: Sized {

let tcx = self.tcx();
let opt_variances = tcx.variances_of(item_def_id);
relate_substs(self, Some((item_def_id, opt_variances)), a_subst, b_subst)
relate_substs_with_variances(self, item_def_id, opt_variances, a_subst, b_subst)
}

/// Switch variance for the purpose of relating `a` and `b`.
Expand Down Expand Up @@ -135,34 +135,39 @@ pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
}
}

#[inline]
pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
variances: Option<(DefId, &[ty::Variance])>,
a_subst: SubstsRef<'tcx>,
b_subst: SubstsRef<'tcx>,
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
relation.tcx().mk_substs(iter::zip(a_subst, b_subst).map(|(a, b)| {
relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)
}))
}

pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
ty_def_id: DefId,
variances: &[ty::Variance],
a_subst: SubstsRef<'tcx>,
b_subst: SubstsRef<'tcx>,
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
let tcx = relation.tcx();

let zipped = iter::zip(a_subst, b_subst);
match variances {
Some((ty_def_id, variances)) => {
let mut cached_ty = None;
tcx.mk_substs(zipped.enumerate().map(|(i, (a, b))| {
let variance = variances[i];
let variance_info = if variance == ty::Invariant {
let ty = *cached_ty
.get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst));
ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
} else {
ty::VarianceDiagInfo::default()
};
relation.relate_with_variance(variance, variance_info, a, b)
}))
}
None => tcx.mk_substs(zipped.map(|(a, b)| {
relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)
})),
}
let mut cached_ty = None;
let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| {
let variance = variances[i];
let variance_info = if variance == ty::Invariant {
let ty = *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst));
ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
} else {
ty::VarianceDiagInfo::default()
};
relation.relate_with_variance(variance, variance_info, a, b)
});

tcx.mk_substs(params)
}

impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
Expand Down Expand Up @@ -318,7 +323,7 @@ impl<'tcx> Relate<'tcx> for ty::TraitRef<'tcx> {
if a.def_id != b.def_id {
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
} else {
let substs = relate_substs(relation, None, a.substs, b.substs)?;
let substs = relate_substs(relation, a.substs, b.substs)?;
Ok(ty::TraitRef { def_id: a.def_id, substs })
}
}
Expand All @@ -334,7 +339,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
if a.def_id != b.def_id {
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
} else {
let substs = relate_substs(relation, None, a.substs, b.substs)?;
let substs = relate_substs(relation, a.substs, b.substs)?;
Ok(ty::ExistentialTraitRef { def_id: a.def_id, substs })
}
}
Expand Down Expand Up @@ -554,7 +559,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
(&ty::Opaque(a_def_id, a_substs), &ty::Opaque(b_def_id, b_substs))
if a_def_id == b_def_id =>
{
let substs = relate_substs(relation, None, a_substs, b_substs)?;
let substs = relate_substs(relation, a_substs, b_substs)?;
Ok(tcx.mk_opaque(a_def_id, substs))
}

Expand Down Expand Up @@ -742,7 +747,7 @@ impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
a: ty::ClosureSubsts<'tcx>,
b: ty::ClosureSubsts<'tcx>,
) -> RelateResult<'tcx, ty::ClosureSubsts<'tcx>> {
let substs = relate_substs(relation, None, a.substs, b.substs)?;
let substs = relate_substs(relation, a.substs, b.substs)?;
Ok(ty::ClosureSubsts { substs })
}
}
Expand All @@ -753,7 +758,7 @@ impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> {
a: ty::GeneratorSubsts<'tcx>,
b: ty::GeneratorSubsts<'tcx>,
) -> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>> {
let substs = relate_substs(relation, None, a.substs, b.substs)?;
let substs = relate_substs(relation, a.substs, b.substs)?;
Ok(ty::GeneratorSubsts { substs })
}
}
Expand All @@ -764,7 +769,7 @@ impl<'tcx> Relate<'tcx> for SubstsRef<'tcx> {
a: SubstsRef<'tcx>,
b: SubstsRef<'tcx>,
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
relate_substs(relation, None, a, b)
relate_substs(relation, a, b)
}
}

Expand Down

0 comments on commit 19dedf3

Please sign in to comment.