Skip to content

Commit 07d9cd2

Browse files
authored
Rollup merge of rust-lang#64302 - nnethercote:shrink-ObligationCauseCode, r=zackmdavis
Shrink `ObligationCauseCode` These commits reduce the size of `ObligationCauseCode` from 56 bytes to 32 bytes on 64-bit. This reduces instruction counts on various benchmarks by up to 1%, due to less `memcpy`ing.
2 parents 2834212 + 2e3b079 commit 07d9cd2

File tree

7 files changed

+75
-48
lines changed

7 files changed

+75
-48
lines changed

src/librustc/infer/error_reporting/mod.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ 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::{IfExpressionCause, MatchExpressionArmCause, ObligationCause};
59+
use crate::traits::{ObligationCauseCode};
5960
use crate::ty::error::TypeError;
6061
use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable};
6162
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
@@ -624,13 +625,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
624625
}
625626
}
626627
}
627-
ObligationCauseCode::MatchExpressionArm {
628+
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
628629
source,
629630
ref prior_arms,
630631
last_ty,
631632
discrim_hir_id,
632633
..
633-
} => match source {
634+
}) => match source {
634635
hir::MatchSource::IfLetDesugar { .. } => {
635636
let msg = "`if let` arms have incompatible types";
636637
err.span_label(cause.span, msg);
@@ -681,7 +682,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
681682
}
682683
}
683684
},
684-
ObligationCauseCode::IfExpression { then, outer, semicolon } => {
685+
ObligationCauseCode::IfExpression(box IfExpressionCause { then, outer, semicolon }) => {
685686
err.span_label(then, "expected because of this");
686687
outer.map(|sp| err.span_label(sp, "if and else have incompatible types"));
687688
if let Some(sp) = semicolon {
@@ -1622,13 +1623,15 @@ impl<'tcx> ObligationCause<'tcx> {
16221623
use crate::traits::ObligationCauseCode::*;
16231624
match self.code {
16241625
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-
}),
1626+
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) =>
1627+
Error0308(match source {
1628+
hir::MatchSource::IfLetDesugar { .. } =>
1629+
"`if let` arms have incompatible types",
1630+
hir::MatchSource::TryDesugar => {
1631+
"try expression alternatives have incompatible types"
1632+
}
1633+
_ => "match arms have incompatible types",
1634+
}),
16321635
IfExpression { .. } => Error0308("if and else have incompatible types"),
16331636
IfExpressionWithNoElse => Error0317("if may be missing an else clause"),
16341637
MainFunctionType => Error0580("main function has wrong type"),
@@ -1656,7 +1659,7 @@ impl<'tcx> ObligationCause<'tcx> {
16561659
match self.code {
16571660
CompareImplMethodObligation { .. } => "method type is compatible with trait",
16581661
ExprAssignable => "expression is assignable",
1659-
MatchExpressionArm { source, .. } => match source {
1662+
MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source {
16601663
hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
16611664
_ => "match arms have compatible types",
16621665
},

src/librustc/traits/fulfill.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ pub struct PendingPredicateObligation<'tcx> {
6868
pub stalled_on: Vec<Ty<'tcx>>,
6969
}
7070

71+
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
72+
#[cfg(target_arch = "x86_64")]
73+
static_assert_size!(PendingPredicateObligation<'_>, 136);
74+
7175
impl<'a, 'tcx> FulfillmentContext<'tcx> {
7276
/// Creates a new fulfillment context.
7377
pub fn new() -> FulfillmentContext<'tcx> {

src/librustc/traits/mod.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ pub struct Obligation<'tcx, T> {
123123
pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
124124
pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
125125

126+
// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
127+
#[cfg(target_arch = "x86_64")]
128+
static_assert_size!(PredicateObligation<'_>, 112);
129+
126130
/// The reason why we incurred this obligation; used for error reporting.
127131
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
128132
pub struct ObligationCause<'tcx> {
@@ -147,7 +151,8 @@ impl<'tcx> ObligationCause<'tcx> {
147151
ObligationCauseCode::StartFunctionType => {
148152
tcx.sess.source_map().def_span(self.span)
149153
}
150-
ObligationCauseCode::MatchExpressionArm { arm_span, .. } => arm_span,
154+
ObligationCauseCode::MatchExpressionArm(
155+
box MatchExpressionArmCause { arm_span, .. }) => arm_span,
151156
_ => self.span,
152157
}
153158
}
@@ -223,23 +228,13 @@ pub enum ObligationCauseCode<'tcx> {
223228
ExprAssignable,
224229

225230
/// Computing common supertype in the arms of a match expression
226-
MatchExpressionArm {
227-
arm_span: Span,
228-
source: hir::MatchSource,
229-
prior_arms: Vec<Span>,
230-
last_ty: Ty<'tcx>,
231-
discrim_hir_id: hir::HirId,
232-
},
231+
MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),
233232

234233
/// Computing common supertype in the pattern guard for the arms of a match expression
235234
MatchExpressionArmPattern { span: Span, ty: Ty<'tcx> },
236235

237236
/// Computing common supertype in an if expression
238-
IfExpression {
239-
then: Span,
240-
outer: Option<Span>,
241-
semicolon: Option<Span>,
242-
},
237+
IfExpression(Box<IfExpressionCause>),
243238

244239
/// Computing common supertype of an if expression with no else counter-part
245240
IfExpressionWithNoElse,
@@ -269,6 +264,26 @@ pub enum ObligationCauseCode<'tcx> {
269264
TrivialBound,
270265
}
271266

267+
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
268+
#[cfg(target_arch = "x86_64")]
269+
static_assert_size!(ObligationCauseCode<'_>, 32);
270+
271+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
272+
pub struct MatchExpressionArmCause<'tcx> {
273+
pub arm_span: Span,
274+
pub source: hir::MatchSource,
275+
pub prior_arms: Vec<Span>,
276+
pub last_ty: Ty<'tcx>,
277+
pub discrim_hir_id: hir::HirId,
278+
}
279+
280+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
281+
pub struct IfExpressionCause {
282+
pub then: Span,
283+
pub outer: Option<Span>,
284+
pub semicolon: Option<Span>,
285+
}
286+
272287
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
273288
pub struct DerivedObligationCause<'tcx> {
274289
/// The trait reference of the parent obligation that led to the

src/librustc/traits/structural_impls.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -508,31 +508,33 @@ 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 } => {
529529
tcx.lift(&ty).map(|ty| super::MatchExpressionArmPattern { span, ty })
530530
}
531-
super::IfExpression { then, outer, semicolon } => Some(super::IfExpression {
532-
then,
533-
outer,
534-
semicolon,
535-
}),
531+
super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => {
532+
Some(super::IfExpression(box super::IfExpressionCause {
533+
then,
534+
outer,
535+
semicolon,
536+
}))
537+
}
536538
super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
537539
super::MainFunctionType => Some(super::MainFunctionType),
538540
super::StartFunctionType => Some(super::StartFunctionType),

src/librustc_typeck/check/_match.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ 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::{IfExpressionCause, MatchExpressionArmCause, ObligationCause};
6+
use rustc::traits::{ObligationCauseCode};
67
use rustc::ty::Ty;
78
use syntax_pos::Span;
89

@@ -146,13 +147,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
146147
// The reason for the first arm to fail is not that the match arms diverge,
147148
// but rather that there's a prior obligation that doesn't hold.
148149
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-
}),
150+
_ => (expr.span,
151+
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
152+
arm_span,
153+
source: match_src,
154+
prior_arms: other_arms.clone(),
155+
last_ty: prior_arm_ty.unwrap(),
156+
discrim_hir_id: discrim.hir_id,
157+
})
158+
),
156159
};
157160
let cause = self.cause(span, code);
158161
coercion.coerce(self, &cause, &arm.body, arm_ty);
@@ -345,11 +348,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
345348
};
346349

347350
// Finally construct the cause:
348-
self.cause(error_sp, ObligationCauseCode::IfExpression {
351+
self.cause(error_sp, ObligationCauseCode::IfExpression(box IfExpressionCause {
349352
then: then_sp,
350353
outer: outer_sp,
351354
semicolon: remove_semicolon,
352-
})
355+
}))
353356
}
354357

355358
fn demand_discriminant_type(

src/librustc_typeck/check/closure.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -529,11 +529,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
529529
); // recreated from (*) above
530530

531531
// Check that E' = S'.
532-
let cause = &self.misc(hir_ty.span);
532+
let cause = self.misc(hir_ty.span);
533533
let InferOk {
534534
value: (),
535535
obligations,
536-
} = self.at(cause, self.param_env)
536+
} = self.at(&cause, self.param_env)
537537
.eq(*expected_ty, supplied_ty)?;
538538
all_obligations.extend(obligations);
539539

@@ -549,7 +549,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
549549
);
550550
all_obligations.push(
551551
Obligation::new(
552-
cause.clone(),
552+
cause,
553553
self.param_env,
554554
ty::Predicate::TypeOutlives(
555555
ty::Binder::dummy(

src/librustc_typeck/check/compare_method.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ fn compare_predicate_entailment<'tcx>(
309309

310310
let cause = ObligationCause {
311311
span: impl_err_span,
312-
..cause.clone()
312+
..cause
313313
};
314314

315315
let mut diag = struct_span_err!(tcx.sess,

0 commit comments

Comments
 (0)