From 041121a18434023982b88b0d60f92ee904df4f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gammels=C3=A6ter?= Date: Wed, 13 Apr 2022 17:46:29 +0200 Subject: [PATCH 1/2] Optimize relate_substs by extracting match There was no need to keep doing the match inside the iterator. --- compiler/rustc_middle/src/ty/relate.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index d9b55563996ba..b1cfa3fa96433 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -142,11 +142,12 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>( b_subst: SubstsRef<'tcx>, ) -> RelateResult<'tcx, SubstsRef<'tcx>> { let tcx = relation.tcx(); - let mut cached_ty = None; - let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| { - let (variance, variance_info) = match variances { - Some((ty_def_id, variances)) => { + 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 @@ -155,14 +156,13 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>( } else { ty::VarianceDiagInfo::default() }; - (variance, variance_info) - } - None => (ty::Invariant, ty::VarianceDiagInfo::default()), - }; - relation.relate_with_variance(variance, variance_info, a, b) - }); - - tcx.mk_substs(params) + 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) + })), + } } impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { From 19dedf3a4b6cfd42ec46949b1d0c4416dd80d11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gammels=C3=A6ter?= Date: Sun, 17 Apr 2022 11:04:58 +0200 Subject: [PATCH 2/2] Split relate_substs into two functions One for the case with variances, and one without. All callers use an explicit Option for the variable anyway. --- compiler/rustc_infer/src/infer/combine.rs | 10 +++- compiler/rustc_infer/src/infer/equate.rs | 2 +- compiler/rustc_middle/src/ty/relate.rs | 61 ++++++++++++----------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 86229dbfad746..0ca0fe33614f8 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -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, + ) } } diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 65c0eba4b3d5c..ef6d464d3c6f1 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -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>( diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index b1cfa3fa96433..4c1160e21fec2 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -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`. @@ -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> { @@ -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 }) } } @@ -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 }) } } @@ -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)) } @@ -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 }) } } @@ -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 }) } } @@ -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) } }