Shrink ObligationCauseCode by boxing IfExpression.
The reduction in `memcpy` calls outweighs the cost of the extra allocations, for a net performance win.
This commit is contained in:
parent
b972ac818c
commit
2e3b079836
5 changed files with 25 additions and 18 deletions
|
|
@ -55,7 +55,8 @@ use crate::hir::def_id::DefId;
|
|||
use crate::hir::Node;
|
||||
use crate::infer::opaque_types;
|
||||
use crate::middle::region;
|
||||
use crate::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
|
||||
use crate::traits::{IfExpressionCause, MatchExpressionArmCause, ObligationCause};
|
||||
use crate::traits::{ObligationCauseCode};
|
||||
use crate::ty::error::TypeError;
|
||||
use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable};
|
||||
use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
|
||||
|
|
@ -681,7 +682,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
},
|
||||
ObligationCauseCode::IfExpression { then, outer, semicolon } => {
|
||||
ObligationCauseCode::IfExpression(box IfExpressionCause { then, outer, semicolon }) => {
|
||||
err.span_label(then, "expected because of this");
|
||||
outer.map(|sp| err.span_label(sp, "if and else have incompatible types"));
|
||||
if let Some(sp) = semicolon {
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ pub struct PendingPredicateObligation<'tcx> {
|
|||
|
||||
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static_assert_size!(PendingPredicateObligation<'_>, 144);
|
||||
static_assert_size!(PendingPredicateObligation<'_>, 136);
|
||||
|
||||
impl<'a, 'tcx> FulfillmentContext<'tcx> {
|
||||
/// Creates a new fulfillment context.
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
|
|||
|
||||
// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static_assert_size!(PredicateObligation<'_>, 120);
|
||||
static_assert_size!(PredicateObligation<'_>, 112);
|
||||
|
||||
/// The reason why we incurred this obligation; used for error reporting.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
|
|
@ -234,11 +234,7 @@ pub enum ObligationCauseCode<'tcx> {
|
|||
MatchExpressionArmPattern { span: Span, ty: Ty<'tcx> },
|
||||
|
||||
/// Computing common supertype in an if expression
|
||||
IfExpression {
|
||||
then: Span,
|
||||
outer: Option<Span>,
|
||||
semicolon: Option<Span>,
|
||||
},
|
||||
IfExpression(Box<IfExpressionCause>),
|
||||
|
||||
/// Computing common supertype of an if expression with no else counter-part
|
||||
IfExpressionWithNoElse,
|
||||
|
|
@ -270,7 +266,7 @@ pub enum ObligationCauseCode<'tcx> {
|
|||
|
||||
// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static_assert_size!(ObligationCauseCode<'_>, 40);
|
||||
static_assert_size!(ObligationCauseCode<'_>, 32);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct MatchExpressionArmCause<'tcx> {
|
||||
|
|
@ -281,6 +277,13 @@ pub struct MatchExpressionArmCause<'tcx> {
|
|||
pub discrim_hir_id: hir::HirId,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct IfExpressionCause {
|
||||
pub then: Span,
|
||||
pub outer: Option<Span>,
|
||||
pub semicolon: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct DerivedObligationCause<'tcx> {
|
||||
/// The trait reference of the parent obligation that led to the
|
||||
|
|
|
|||
|
|
@ -528,11 +528,13 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
|
|||
super::MatchExpressionArmPattern { span, ty } => {
|
||||
tcx.lift(&ty).map(|ty| super::MatchExpressionArmPattern { span, ty })
|
||||
}
|
||||
super::IfExpression { then, outer, semicolon } => Some(super::IfExpression {
|
||||
then,
|
||||
outer,
|
||||
semicolon,
|
||||
}),
|
||||
super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => {
|
||||
Some(super::IfExpression(box super::IfExpressionCause {
|
||||
then,
|
||||
outer,
|
||||
semicolon,
|
||||
}))
|
||||
}
|
||||
super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
|
||||
super::MainFunctionType => Some(super::MainFunctionType),
|
||||
super::StartFunctionType => Some(super::StartFunctionType),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use crate::check::{FnCtxt, Expectation, Diverges, Needs};
|
|||
use crate::check::coercion::CoerceMany;
|
||||
use rustc::hir::{self, ExprKind};
|
||||
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
|
||||
use rustc::traits::{IfExpressionCause, MatchExpressionArmCause, ObligationCause};
|
||||
use rustc::traits::{ObligationCauseCode};
|
||||
use rustc::ty::Ty;
|
||||
use syntax_pos::Span;
|
||||
|
||||
|
|
@ -347,11 +348,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
};
|
||||
|
||||
// Finally construct the cause:
|
||||
self.cause(error_sp, ObligationCauseCode::IfExpression {
|
||||
self.cause(error_sp, ObligationCauseCode::IfExpression(box IfExpressionCause {
|
||||
then: then_sp,
|
||||
outer: outer_sp,
|
||||
semicolon: remove_semicolon,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
fn demand_discriminant_type(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue