From 3a5bf11dab2d23f6f63c098a5e52286f9c75470d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 19 Nov 2022 06:02:51 +0000 Subject: [PATCH 1/2] Fast-path some relations via strict equality --- .../rustc_hir_analysis/src/check/dropck.rs | 4 ++++ compiler/rustc_infer/src/infer/combine.rs | 8 +++++++ compiler/rustc_infer/src/infer/equate.rs | 4 ++++ .../src/infer/error_reporting/mod.rs | 4 ++++ compiler/rustc_infer/src/infer/glb.rs | 4 ++++ compiler/rustc_infer/src/infer/lub.rs | 4 ++++ .../rustc_infer/src/infer/nll_relate/mod.rs | 8 +++++++ .../src/infer/outlives/test_type_match.rs | 3 +++ compiler/rustc_infer/src/infer/sub.rs | 4 ++++ compiler/rustc_middle/src/ty/_match.rs | 3 +++ compiler/rustc_middle/src/ty/relate.rs | 23 +++++++++++++++++-- 11 files changed, 67 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index a74016e220e62..4747921cfb683 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -248,6 +248,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> { self.param_env } + fn fast_equate_combine(&self) -> bool { + true + } + fn tag(&self) -> &'static str { "dropck::SimpleEqRelation" } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 37f071a19acd6..6aa8207f1c8da 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -525,6 +525,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { self.param_env } + fn fast_equate_combine(&self) -> bool { + false + } + fn tag(&self) -> &'static str { "Generalizer" } @@ -802,6 +806,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { self.param_env } + fn fast_equate_combine(&self) -> bool { + false + } + fn tag(&self) -> &'static str { "ConstInferUnifier" } diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 59728148a84c4..d49a1b3b5681f 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -32,6 +32,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { self.fields.tcx() } + fn fast_equate_combine(&self) -> bool { + true + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 22f32251f6df0..323f16cecdba7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2945,6 +2945,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { "SameTypeModuloInfer" } + fn fast_equate_combine(&self) -> bool { + true + } + fn a_is_expected(&self) -> bool { true } diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 6ffefcb7a286a..00669840ed18e 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -34,6 +34,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> { self.fields.tcx() } + fn fast_equate_combine(&self) -> bool { + true + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index d6e56fcb7fd27..ff60cde8f4133 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -34,6 +34,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> { self.fields.tcx() } + fn fast_equate_combine(&self) -> bool { + true + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 600f94f095eac..a42414ff88c4b 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -535,6 +535,10 @@ where self.delegate.param_env() } + fn fast_equate_combine(&self) -> bool { + false + } + fn tag(&self) -> &'static str { "nll::subtype" } @@ -901,6 +905,10 @@ where self.delegate.param_env() } + fn fast_equate_combine(&self) -> bool { + false + } + fn tag(&self) -> &'static str { "nll::generalizer" } diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index a5c21f0fb9b50..16ec8d8652cd7 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -142,6 +142,9 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } + fn fast_equate_combine(&self) -> bool { + false + } fn a_is_expected(&self) -> bool { true } // irrelevant diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 8c8445a4d9eb8..c0b3deb41a1ab 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -43,6 +43,10 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { self.fields.param_env } + fn fast_equate_combine(&self) -> bool { + true + } + fn a_is_expected(&self) -> bool { self.a_is_expected } diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index e6aab30a150de..b279616b0de62 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -39,6 +39,9 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } + fn fast_equate_combine(&self) -> bool { + false + } fn a_is_expected(&self) -> bool { true } // irrelevant diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index c083a405e3cfb..472f5cbbd1767 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -28,6 +28,9 @@ pub trait TypeRelation<'tcx>: Sized { /// Returns a static string we can use for printouts. fn tag(&self) -> &'static str; + /// Returns whether or not structural equality can be used to fast-path this relation + fn fast_equate_combine(&self) -> bool; + /// Returns `true` if the value `a` is the "expected" type in the /// relation. Just affects error messages. fn a_is_expected(&self) -> bool; @@ -140,6 +143,10 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>( a_subst: SubstsRef<'tcx>, b_subst: SubstsRef<'tcx>, ) -> RelateResult<'tcx, SubstsRef<'tcx>> { + if relation.fast_equate_combine() && a_subst == b_subst { + return Ok(a_subst); + } + relation.tcx().mk_substs(iter::zip(a_subst, b_subst).map(|(a, b)| { relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b) })) @@ -152,6 +159,10 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>( a_subst: SubstsRef<'tcx>, b_subst: SubstsRef<'tcx>, ) -> RelateResult<'tcx, SubstsRef<'tcx>> { + if relation.fast_equate_combine() && a_subst == b_subst { + return Ok(a_subst); + } + let tcx = relation.tcx(); let mut cached_ty = None; @@ -345,7 +356,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> { } } -#[derive(Copy, Debug, Clone, TypeFoldable, TypeVisitable)] +#[derive(Copy, Debug, Clone, PartialEq, Eq, TypeFoldable, TypeVisitable)] struct GeneratorWitness<'tcx>(&'tcx ty::List>); impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> { @@ -354,6 +365,10 @@ impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> { a: GeneratorWitness<'tcx>, b: GeneratorWitness<'tcx>, ) -> RelateResult<'tcx, GeneratorWitness<'tcx>> { + if relation.fast_equate_combine() && a == b { + return Ok(a); + } + assert_eq!(a.0.len(), b.0.len()); let tcx = relation.tcx(); let types = tcx.mk_type_list(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?; @@ -655,6 +670,10 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List RelateResult<'tcx, Self> { + if relation.fast_equate_combine() && a == b { + return Ok(a); + } + let tcx = relation.tcx(); // FIXME: this is wasteful, but want to do a perf run to see how slow it is. @@ -799,9 +818,9 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> { b: ty::TraitPredicate<'tcx>, ) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> { Ok(ty::TraitPredicate { - trait_ref: relation.relate(a.trait_ref, b.trait_ref)?, constness: relation.relate(a.constness, b.constness)?, polarity: relation.relate(a.polarity, b.polarity)?, + trait_ref: relation.relate(a.trait_ref, b.trait_ref)?, }) } } From d1ed286efcd4b8f0e0ce0eaf4baab85194c9c1d8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 19 Nov 2022 18:41:12 +0000 Subject: [PATCH 2/2] rename, add inline --- compiler/rustc_hir_analysis/src/check/dropck.rs | 3 ++- compiler/rustc_infer/src/infer/combine.rs | 6 ++++-- compiler/rustc_infer/src/infer/equate.rs | 3 ++- compiler/rustc_infer/src/infer/error_reporting/mod.rs | 3 ++- compiler/rustc_infer/src/infer/glb.rs | 3 ++- compiler/rustc_infer/src/infer/lub.rs | 3 ++- compiler/rustc_infer/src/infer/nll_relate/mod.rs | 6 ++++-- .../rustc_infer/src/infer/outlives/test_type_match.rs | 3 ++- compiler/rustc_infer/src/infer/sub.rs | 3 ++- compiler/rustc_middle/src/ty/_match.rs | 3 ++- compiler/rustc_middle/src/ty/relate.rs | 10 +++++----- 11 files changed, 29 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index 4747921cfb683..a3336ee1f88c1 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -248,7 +248,8 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> { self.param_env } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { true } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index 6aa8207f1c8da..181562722c379 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -525,7 +525,8 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { self.param_env } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { false } @@ -806,7 +807,8 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { self.param_env } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { false } diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index d49a1b3b5681f..f7ae6d3882547 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -32,7 +32,8 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { self.fields.tcx() } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { true } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 323f16cecdba7..92f79a1c070a9 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2945,7 +2945,8 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { "SameTypeModuloInfer" } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { true } diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 00669840ed18e..3ea012d7c05c0 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -34,7 +34,8 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> { self.fields.tcx() } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { true } diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index ff60cde8f4133..30414a742b086 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -34,7 +34,8 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> { self.fields.tcx() } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { true } diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index a42414ff88c4b..01133271568bb 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -535,7 +535,8 @@ where self.delegate.param_env() } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { false } @@ -905,7 +906,8 @@ where self.delegate.param_env() } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { false } diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index 16ec8d8652cd7..25acaf0343876 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -142,7 +142,8 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { false } fn a_is_expected(&self) -> bool { diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index c0b3deb41a1ab..da2b792e71624 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -43,7 +43,8 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { self.fields.param_env } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { true } diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index b279616b0de62..00a1918041608 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -39,7 +39,8 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } - fn fast_equate_combine(&self) -> bool { + #[inline] + fn fast_equate(&self) -> bool { false } fn a_is_expected(&self) -> bool { diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 472f5cbbd1767..a939099a5c2c9 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -29,7 +29,7 @@ pub trait TypeRelation<'tcx>: Sized { fn tag(&self) -> &'static str; /// Returns whether or not structural equality can be used to fast-path this relation - fn fast_equate_combine(&self) -> bool; + fn fast_equate(&self) -> bool; /// Returns `true` if the value `a` is the "expected" type in the /// relation. Just affects error messages. @@ -143,7 +143,7 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>( a_subst: SubstsRef<'tcx>, b_subst: SubstsRef<'tcx>, ) -> RelateResult<'tcx, SubstsRef<'tcx>> { - if relation.fast_equate_combine() && a_subst == b_subst { + if relation.fast_equate() && a_subst == b_subst { return Ok(a_subst); } @@ -159,7 +159,7 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>( a_subst: SubstsRef<'tcx>, b_subst: SubstsRef<'tcx>, ) -> RelateResult<'tcx, SubstsRef<'tcx>> { - if relation.fast_equate_combine() && a_subst == b_subst { + if relation.fast_equate() && a_subst == b_subst { return Ok(a_subst); } @@ -365,7 +365,7 @@ impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> { a: GeneratorWitness<'tcx>, b: GeneratorWitness<'tcx>, ) -> RelateResult<'tcx, GeneratorWitness<'tcx>> { - if relation.fast_equate_combine() && a == b { + if relation.fast_equate() && a == b { return Ok(a); } @@ -670,7 +670,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List RelateResult<'tcx, Self> { - if relation.fast_equate_combine() && a == b { + if relation.fast_equate() && a == b { return Ok(a); }