From ea668d9c548d4490ae9e8ea9b4e8942bae02a8fe Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 6 Jun 2020 21:47:32 +0200 Subject: [PATCH] use enum to represent ObligationCause::dummy without allocating --- src/librustc_middle/traits/mod.rs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs index 113ddc42b41f1..917c6b3191645 100644 --- a/src/librustc_middle/traits/mod.rs +++ b/src/librustc_middle/traits/mod.rs @@ -89,14 +89,12 @@ pub enum Reveal { /// only live for a short period of time. #[derive(Clone, PartialEq, Eq, Hash)] pub struct ObligationCause<'tcx> { - data: Rc>, + /// `None` for `ObligationCause::dummy`, `Some` otherwise. + data: Option>>, } -// 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); -} +const DUMMY_OBLIGATION_CAUSE_DATA: ObligationCauseData<'static> = + ObligationCauseData { span: DUMMY_SP, body_id: hir::CRATE_HIR_ID, code: MiscObligation }; // Correctly format `ObligationCause::dummy`. impl<'tcx> fmt::Debug for ObligationCause<'tcx> { @@ -108,8 +106,9 @@ impl<'tcx> fmt::Debug for ObligationCause<'tcx> { impl Deref for ObligationCause<'tcx> { type Target = ObligationCauseData<'tcx>; + #[inline(always)] fn deref(&self) -> &Self::Target { - &self.data + self.data.as_deref().unwrap_or(&DUMMY_OBLIGATION_CAUSE_DATA) } } @@ -135,7 +134,7 @@ impl<'tcx> ObligationCause<'tcx> { body_id: hir::HirId, code: ObligationCauseCode<'tcx>, ) -> ObligationCause<'tcx> { - ObligationCause { data: Rc::new(ObligationCauseData { span, body_id, code }) } + ObligationCause { data: Some(Rc::new(ObligationCauseData { span, body_id, code })) } } pub fn misc(span: Span, body_id: hir::HirId) -> ObligationCause<'tcx> { @@ -148,11 +147,11 @@ impl<'tcx> ObligationCause<'tcx> { #[inline(always)] pub fn dummy() -> ObligationCause<'tcx> { - DUMMY_OBLIGATION_CAUSE.with(Clone::clone) + ObligationCause { data: None } } pub fn make_mut(&mut self) -> &mut ObligationCauseData<'tcx> { - Rc::make_mut(&mut self.data) + Rc::make_mut(self.data.get_or_insert_with(|| Rc::new(DUMMY_OBLIGATION_CAUSE_DATA))) } pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span {