Skip to content

Commit b972ac8

Browse files
committed
Shrink ObligationCauseCode by boxing MatchExpressionArm.
The reduction in `memcpy` calls greatly outweighs the cost of the extra allocations, for a net performance win.
1 parent c1b9a46 commit b972ac8

File tree

5 files changed

+42
-34
lines changed

5 files changed

+42
-34
lines changed

src/librustc/infer/error_reporting/mod.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use crate::hir::def_id::DefId;
5555
use crate::hir::Node;
5656
use crate::infer::opaque_types;
5757
use crate::middle::region;
58-
use crate::traits::{ObligationCause, ObligationCauseCode};
58+
use crate::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
5959
use crate::ty::error::TypeError;
6060
use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable};
6161
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
@@ -624,13 +624,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
624624
}
625625
}
626626
}
627-
ObligationCauseCode::MatchExpressionArm {
627+
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
628628
source,
629629
ref prior_arms,
630630
last_ty,
631631
discrim_hir_id,
632632
..
633-
} => match source {
633+
}) => match source {
634634
hir::MatchSource::IfLetDesugar { .. } => {
635635
let msg = "`if let` arms have incompatible types";
636636
err.span_label(cause.span, msg);
@@ -1622,13 +1622,15 @@ impl<'tcx> ObligationCause<'tcx> {
16221622
use crate::traits::ObligationCauseCode::*;
16231623
match self.code {
16241624
CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
1625-
MatchExpressionArm { source, .. } => Error0308(match source {
1626-
hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have incompatible types",
1627-
hir::MatchSource::TryDesugar => {
1628-
"try expression alternatives have incompatible types"
1629-
}
1630-
_ => "match arms have incompatible types",
1631-
}),
1625+
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) =>
1626+
Error0308(match source {
1627+
hir::MatchSource::IfLetDesugar { .. } =>
1628+
"`if let` arms have incompatible types",
1629+
hir::MatchSource::TryDesugar => {
1630+
"try expression alternatives have incompatible types"
1631+
}
1632+
_ => "match arms have incompatible types",
1633+
}),
16321634
IfExpression { .. } => Error0308("if and else have incompatible types"),
16331635
IfExpressionWithNoElse => Error0317("if may be missing an else clause"),
16341636
MainFunctionType => Error0580("main function has wrong type"),
@@ -1656,7 +1658,7 @@ impl<'tcx> ObligationCause<'tcx> {
16561658
match self.code {
16571659
CompareImplMethodObligation { .. } => "method type is compatible with trait",
16581660
ExprAssignable => "expression is assignable",
1659-
MatchExpressionArm { source, .. } => match source {
1661+
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source {
16601662
hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
16611663
_ => "match arms have compatible types",
16621664
},

src/librustc/traits/fulfill.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub struct PendingPredicateObligation<'tcx> {
7070

7171
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
7272
#[cfg(target_arch = "x86_64")]
73-
static_assert_size!(PendingPredicateObligation<'_>, 160);
73+
static_assert_size!(PendingPredicateObligation<'_>, 144);
7474

7575
impl<'a, 'tcx> FulfillmentContext<'tcx> {
7676
/// Creates a new fulfillment context.

src/librustc/traits/mod.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
125125

126126
// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
127127
#[cfg(target_arch = "x86_64")]
128-
static_assert_size!(PredicateObligation<'_>, 136);
128+
static_assert_size!(PredicateObligation<'_>, 120);
129129

130130
/// The reason why we incurred this obligation; used for error reporting.
131131
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -151,7 +151,8 @@ impl<'tcx> ObligationCause<'tcx> {
151151
ObligationCauseCode::StartFunctionType => {
152152
tcx.sess.source_map().def_span(self.span)
153153
}
154-
ObligationCauseCode::MatchExpressionArm { arm_span, .. } => arm_span,
154+
ObligationCauseCode::MatchExpressionArm(
155+
box MatchExpressionArmCause { arm_span, .. }) => arm_span,
155156
_ => self.span,
156157
}
157158
}
@@ -227,13 +228,7 @@ pub enum ObligationCauseCode<'tcx> {
227228
ExprAssignable,
228229

229230
/// Computing common supertype in the arms of a match expression
230-
MatchExpressionArm {
231-
arm_span: Span,
232-
source: hir::MatchSource,
233-
prior_arms: Vec<Span>,
234-
last_ty: Ty<'tcx>,
235-
discrim_hir_id: hir::HirId,
236-
},
231+
MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),
237232

238233
/// Computing common supertype in the pattern guard for the arms of a match expression
239234
MatchExpressionArmPattern { span: Span, ty: Ty<'tcx> },
@@ -275,7 +270,16 @@ pub enum ObligationCauseCode<'tcx> {
275270

276271
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
277272
#[cfg(target_arch = "x86_64")]
278-
static_assert_size!(ObligationCauseCode<'_>, 56);
273+
static_assert_size!(ObligationCauseCode<'_>, 40);
274+
275+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
276+
pub struct MatchExpressionArmCause<'tcx> {
277+
pub arm_span: Span,
278+
pub source: hir::MatchSource,
279+
pub prior_arms: Vec<Span>,
280+
pub last_ty: Ty<'tcx>,
281+
pub discrim_hir_id: hir::HirId,
282+
}
279283

280284
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
281285
pub struct DerivedObligationCause<'tcx> {

src/librustc/traits/structural_impls.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -508,21 +508,21 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
508508
trait_item_def_id,
509509
}),
510510
super::ExprAssignable => Some(super::ExprAssignable),
511-
super::MatchExpressionArm {
511+
super::MatchExpressionArm(box super::MatchExpressionArmCause {
512512
arm_span,
513513
source,
514514
ref prior_arms,
515515
last_ty,
516516
discrim_hir_id,
517-
} => {
517+
}) => {
518518
tcx.lift(&last_ty).map(|last_ty| {
519-
super::MatchExpressionArm {
519+
super::MatchExpressionArm(box super::MatchExpressionArmCause {
520520
arm_span,
521521
source,
522522
prior_arms: prior_arms.clone(),
523523
last_ty,
524524
discrim_hir_id,
525-
}
525+
})
526526
})
527527
}
528528
super::MatchExpressionArmPattern { span, ty } => {

src/librustc_typeck/check/_match.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::check::{FnCtxt, Expectation, Diverges, Needs};
22
use crate::check::coercion::CoerceMany;
33
use rustc::hir::{self, ExprKind};
44
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
5-
use rustc::traits::{ObligationCause, ObligationCauseCode};
5+
use rustc::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
66
use rustc::ty::Ty;
77
use syntax_pos::Span;
88

@@ -146,13 +146,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
146146
// The reason for the first arm to fail is not that the match arms diverge,
147147
// but rather that there's a prior obligation that doesn't hold.
148148
0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
149-
_ => (expr.span, ObligationCauseCode::MatchExpressionArm {
150-
arm_span,
151-
source: match_src,
152-
prior_arms: other_arms.clone(),
153-
last_ty: prior_arm_ty.unwrap(),
154-
discrim_hir_id: discrim.hir_id,
155-
}),
149+
_ => (expr.span,
150+
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
151+
arm_span,
152+
source: match_src,
153+
prior_arms: other_arms.clone(),
154+
last_ty: prior_arm_ty.unwrap(),
155+
discrim_hir_id: discrim.hir_id,
156+
})
157+
),
156158
};
157159
let cause = self.cause(span, code);
158160
coercion.coerce(self, &cause, &arm.body, arm_ty);

0 commit comments

Comments
 (0)