/// only live for a short period of time.
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct ObligationCause<'tcx> {
- data: Rc<ObligationCauseData<'tcx>>,
+ /// `None` for `ObligationCause::dummy`, `Some` otherwise.
+ data: Option<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);
-}
+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> {
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)
}
}
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> {
#[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 {