diff options
| author | Guillaume Gomez <guillaume.gomez@huawei.com> | 2022-03-26 14:58:19 +0100 |
|---|---|---|
| committer | Guillaume Gomez <guillaume.gomez@huawei.com> | 2022-03-26 14:58:19 +0100 |
| commit | ad887322541b1c255b210cf87fae675072d1027f (patch) | |
| tree | bd876f2d03dee317945b74bed25d539f39848af0 | |
| parent | 3fe3b89cd57229343eeca753fdd8c63d9b03c65c (diff) | |
| download | rust-ad887322541b1c255b210cf87fae675072d1027f.tar.gz rust-ad887322541b1c255b210cf87fae675072d1027f.zip | |
Fix perf issue for auto trait selection
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/auto_trait.rs | 18 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 4 |
3 files changed, 29 insertions, 2 deletions
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 93ece753728..dc16460ca43 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -999,6 +999,15 @@ impl<'tcx> PolyTraitRef<'tcx> { polarity: ty::ImplPolarity::Positive, }) } + + /// Same as [`PolyTraitRef::to_poly_trait_predicate`] but sets a negative polarity instead. + pub fn to_poly_trait_predicate_negative_polarity(&self) -> ty::PolyTraitPredicate<'tcx> { + self.map_bound(|trait_ref| ty::TraitPredicate { + trait_ref, + constness: ty::BoundConstness::NotConst, + polarity: ty::ImplPolarity::Negative, + }) + } } /// An existential reference to a trait, where `Self` is erased. diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index c9398d746d7..6f6f21aa788 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -101,6 +101,24 @@ impl<'tcx> AutoTraitFinder<'tcx> { manual impl found, bailing out", trait_ref ); + return true; + } + _ => {} + } + + let result = selcx.select(&Obligation::new( + ObligationCause::dummy(), + orig_env, + trait_pred.to_poly_trait_predicate_negative_polarity(), + )); + + match result { + Ok(Some(ImplSource::UserDefined(_))) => { + debug!( + "find_auto_trait_generics({:?}): \ + manual impl found, bailing out", + trait_ref + ); true } _ => false, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6d232d86d8a..4704d841012 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1272,7 +1272,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // the master cache. Since coherence executes pretty quickly, // it's not worth going to more trouble to increase the // hit-rate, I don't think. - if self.intercrate || self.allow_negative_impls { + if self.intercrate { return false; } @@ -1289,7 +1289,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // mode, so don't do any caching. In particular, we might // re-use the same `InferCtxt` with both an intercrate // and non-intercrate `SelectionContext` - if self.intercrate || self.allow_negative_impls { + if self.intercrate { return None; } let tcx = self.tcx(); |
