diff options
| author | bors <bors@rust-lang.org> | 2022-03-28 00:01:01 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-03-28 00:01:01 +0000 |
| commit | 3badf5c51c33f15c3934ea0e91d27f60c8605024 (patch) | |
| tree | 1d2111cfa50c2d735f722b01169332ed3573f4c4 | |
| parent | 62523045ec681ee8c2ecb8d395fbcaccf336284b (diff) | |
| parent | bd51f174ed6b6e1e668207cb5999e46189dcfaa3 (diff) | |
| download | rust-3badf5c51c33f15c3934ea0e91d27f60c8605024.tar.gz rust-3badf5c51c33f15c3934ea0e91d27f60c8605024.zip | |
Auto merge of #95333 - GuillaumeGomez:auto-trait-perf-issue, r=oli-obk
Fix perf issue for auto trait selection Follow-up of https://github.com/rust-lang/rust/pull/95069 which fixes the perf issue introduced by it. r? `@oli-obk`
| -rw-r--r-- | compiler/rustc_middle/src/ty/sty.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/auto_trait.rs | 22 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/mod.rs | 28 |
3 files changed, 31 insertions, 28 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..ee9983ee8b8 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -87,7 +87,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let trait_pred = ty::Binder::dummy(trait_ref); let bail_out = tcx.infer_ctxt().enter(|infcx| { - let mut selcx = SelectionContext::with_negative(&infcx, true); + let mut selcx = SelectionContext::new(&infcx); let result = selcx.select(&Obligation::new( ObligationCause::dummy(), orig_env, @@ -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, @@ -277,7 +295,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { fresh_preds.insert(self.clean_pred(infcx, predicate)); } - let mut select = SelectionContext::with_negative(&infcx, true); + let mut select = SelectionContext::new(&infcx); let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new(); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6d232d86d8a..72d156067a1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -119,11 +119,6 @@ pub struct SelectionContext<'cx, 'tcx> { intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>, - /// Controls whether or not to filter out negative impls when selecting. - /// This is used in librustdoc to distinguish between the lack of an impl - /// and a negative impl - allow_negative_impls: bool, - /// The mode that trait queries run in, which informs our error handling /// policy. In essence, canonicalized queries need their errors propagated /// rather than immediately reported because we do not have accurate spans. @@ -215,7 +210,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { freshener: infcx.freshener_keep_static(), intercrate: false, intercrate_ambiguity_causes: None, - allow_negative_impls: false, query_mode: TraitQueryMode::Standard, } } @@ -226,22 +220,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { freshener: infcx.freshener_keep_static(), intercrate: true, intercrate_ambiguity_causes: None, - allow_negative_impls: false, - query_mode: TraitQueryMode::Standard, - } - } - - pub fn with_negative( - infcx: &'cx InferCtxt<'cx, 'tcx>, - allow_negative_impls: bool, - ) -> SelectionContext<'cx, 'tcx> { - debug!(?allow_negative_impls, "with_negative"); - SelectionContext { - infcx, - freshener: infcx.freshener_keep_static(), - intercrate: false, - intercrate_ambiguity_causes: None, - allow_negative_impls, query_mode: TraitQueryMode::Standard, } } @@ -256,7 +234,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { freshener: infcx.freshener_keep_static(), intercrate: false, intercrate_ambiguity_causes: None, - allow_negative_impls: false, query_mode, } } @@ -1192,7 +1169,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if let ImplCandidate(def_id) = candidate { if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id) || obligation.polarity() == tcx.impl_polarity(def_id) - || self.allow_negative_impls { result.push(candidate); } @@ -1272,7 +1248,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 +1265,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(); |
