diff options
| author | Bastian Kauschke <bastian_kauschke@hotmail.de> | 2020-06-03 23:59:30 +0200 |
|---|---|---|
| committer | Bastian Kauschke <bastian_kauschke@hotmail.de> | 2020-06-07 00:08:24 +0200 |
| commit | af7fbecf7f2e1e3c8a9680b20b67e58ed34bf49f (patch) | |
| tree | a6b855acacdd8e98189bf7041d470f7f10dc7dc6 /src/librustc_middle | |
| parent | 3d5d0f898c2f3998e50c2180c6202f193c3acdbc (diff) | |
| download | rust-af7fbecf7f2e1e3c8a9680b20b67e58ed34bf49f.tar.gz rust-af7fbecf7f2e1e3c8a9680b20b67e58ed34bf49f.zip | |
store `ObligationCause` on the heap
Diffstat (limited to 'src/librustc_middle')
| -rw-r--r-- | src/librustc_middle/traits/mod.rs | 52 | ||||
| -rw-r--r-- | src/librustc_middle/traits/structural_impls.rs | 6 |
2 files changed, 48 insertions, 10 deletions
diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs index 9afab5a4d2f..113ddc42b41 100644 --- a/src/librustc_middle/traits/mod.rs +++ b/src/librustc_middle/traits/mod.rs @@ -20,7 +20,8 @@ use rustc_span::{Span, DUMMY_SP}; use smallvec::SmallVec; use std::borrow::Cow; -use std::fmt::Debug; +use std::fmt; +use std::ops::Deref; use std::rc::Rc; pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache}; @@ -80,8 +81,40 @@ pub enum Reveal { } /// The reason why we incurred this obligation; used for error reporting. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +/// +/// As the happy path does not care about this struct, storing this on the heap +/// ends up increasing performance. +/// +/// We do not want to intern this as there are a lot of obligation causes which +/// only live for a short period of time. +#[derive(Clone, PartialEq, Eq, Hash)] pub struct ObligationCause<'tcx> { + data: Rc<ObligationCauseData<'tcx>>, +} + +// A dummy obligation. As the parralel compiler does not share `Obligation`s between +// threads, we use a `thread_local` here so we can keep using an `Rc` inside of `ObligationCause`. +thread_local! { + static DUMMY_OBLIGATION_CAUSE: ObligationCause<'static> = ObligationCause::new(DUMMY_SP, hir::CRATE_HIR_ID, MiscObligation); +} + +// Correctly format `ObligationCause::dummy`. +impl<'tcx> fmt::Debug for ObligationCause<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ObligationCauseData::fmt(self, f) + } +} + +impl Deref for ObligationCause<'tcx> { + type Target = ObligationCauseData<'tcx>; + + fn deref(&self) -> &Self::Target { + &self.data + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ObligationCauseData<'tcx> { pub span: Span, /// The ID of the fn body that triggered this obligation. This is @@ -102,15 +135,24 @@ impl<'tcx> ObligationCause<'tcx> { body_id: hir::HirId, code: ObligationCauseCode<'tcx>, ) -> ObligationCause<'tcx> { - ObligationCause { span, body_id, code } + ObligationCause { data: Rc::new(ObligationCauseData { span, body_id, code }) } } pub fn misc(span: Span, body_id: hir::HirId) -> ObligationCause<'tcx> { - ObligationCause { span, body_id, code: MiscObligation } + ObligationCause::new(span, body_id, MiscObligation) } + pub fn dummy_with_span(span: Span) -> ObligationCause<'tcx> { + ObligationCause::new(span, hir::CRATE_HIR_ID, MiscObligation) + } + + #[inline(always)] pub fn dummy() -> ObligationCause<'tcx> { - ObligationCause { span: DUMMY_SP, body_id: hir::CRATE_HIR_ID, code: MiscObligation } + DUMMY_OBLIGATION_CAUSE.with(Clone::clone) + } + + pub fn make_mut(&mut self) -> &mut ObligationCauseData<'tcx> { + Rc::make_mut(&mut self.data) } pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span { diff --git a/src/librustc_middle/traits/structural_impls.rs b/src/librustc_middle/traits/structural_impls.rs index 74f74415294..a9a370615ed 100644 --- a/src/librustc_middle/traits/structural_impls.rs +++ b/src/librustc_middle/traits/structural_impls.rs @@ -232,11 +232,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::DerivedObligationCause<'a> { impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCause<'a> { type Lifted = traits::ObligationCause<'tcx>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { - tcx.lift(&self.code).map(|code| traits::ObligationCause { - span: self.span, - body_id: self.body_id, - code, - }) + tcx.lift(&self.code).map(|code| traits::ObligationCause::new(self.span, self.body_id, code)) } } |
