use enum to represent ObligationCause::dummy without allocating

This commit is contained in:
Bastian Kauschke 2020-06-06 21:47:32 +02:00
parent af7fbecf7f
commit ea668d9c54
1 changed files with 9 additions and 10 deletions

View File

@ -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<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> {
@ -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 {