diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 5883be6e26883..ab24b3f2f059f 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -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::{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}; @@ -624,13 +625,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } } - ObligationCauseCode::MatchExpressionArm { + ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { source, ref prior_arms, last_ty, discrim_hir_id, .. - } => match source { + }) => match source { hir::MatchSource::IfLetDesugar { .. } => { let msg = "`if let` arms have incompatible types"; err.span_label(cause.span, msg); @@ -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 { @@ -1622,13 +1623,15 @@ impl<'tcx> ObligationCause<'tcx> { use crate::traits::ObligationCauseCode::*; match self.code { CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"), - MatchExpressionArm { source, .. } => Error0308(match source { - hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have incompatible types", - hir::MatchSource::TryDesugar => { - "try expression alternatives have incompatible types" - } - _ => "match arms have incompatible types", - }), + MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => + Error0308(match source { + hir::MatchSource::IfLetDesugar { .. } => + "`if let` arms have incompatible types", + hir::MatchSource::TryDesugar => { + "try expression alternatives have incompatible types" + } + _ => "match arms have incompatible types", + }), IfExpression { .. } => Error0308("if and else have incompatible types"), IfExpressionWithNoElse => Error0317("if may be missing an else clause"), MainFunctionType => Error0580("main function has wrong type"), @@ -1656,7 +1659,7 @@ impl<'tcx> ObligationCause<'tcx> { match self.code { CompareImplMethodObligation { .. } => "method type is compatible with trait", ExprAssignable => "expression is assignable", - MatchExpressionArm { source, .. } => match source { + MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source { hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types", _ => "match arms have compatible types", }, diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index c1de4939c1d91..4494c034d51e2 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -68,6 +68,10 @@ pub struct PendingPredicateObligation<'tcx> { pub stalled_on: Vec>, } +// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger. +#[cfg(target_arch = "x86_64")] +static_assert_size!(PendingPredicateObligation<'_>, 136); + impl<'a, 'tcx> FulfillmentContext<'tcx> { /// Creates a new fulfillment context. pub fn new() -> FulfillmentContext<'tcx> { diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 1ca92d79fa5f6..d2683090add40 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -123,6 +123,10 @@ pub struct Obligation<'tcx, T> { pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>; 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<'_>, 112); + /// The reason why we incurred this obligation; used for error reporting. #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct ObligationCause<'tcx> { @@ -147,7 +151,8 @@ impl<'tcx> ObligationCause<'tcx> { ObligationCauseCode::StartFunctionType => { tcx.sess.source_map().def_span(self.span) } - ObligationCauseCode::MatchExpressionArm { arm_span, .. } => arm_span, + ObligationCauseCode::MatchExpressionArm( + box MatchExpressionArmCause { arm_span, .. }) => arm_span, _ => self.span, } } @@ -223,23 +228,13 @@ pub enum ObligationCauseCode<'tcx> { ExprAssignable, /// Computing common supertype in the arms of a match expression - MatchExpressionArm { - arm_span: Span, - source: hir::MatchSource, - prior_arms: Vec, - last_ty: Ty<'tcx>, - discrim_hir_id: hir::HirId, - }, + MatchExpressionArm(Box>), /// Computing common supertype in the pattern guard for the arms of a match expression MatchExpressionArmPattern { span: Span, ty: Ty<'tcx> }, /// Computing common supertype in an if expression - IfExpression { - then: Span, - outer: Option, - semicolon: Option, - }, + IfExpression(Box), /// Computing common supertype of an if expression with no else counter-part IfExpressionWithNoElse, @@ -269,6 +264,26 @@ pub enum ObligationCauseCode<'tcx> { TrivialBound, } +// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. +#[cfg(target_arch = "x86_64")] +static_assert_size!(ObligationCauseCode<'_>, 32); + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct MatchExpressionArmCause<'tcx> { + pub arm_span: Span, + pub source: hir::MatchSource, + pub prior_arms: Vec, + pub last_ty: Ty<'tcx>, + pub discrim_hir_id: hir::HirId, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct IfExpressionCause { + pub then: Span, + pub outer: Option, + pub semicolon: Option, +} + #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct DerivedObligationCause<'tcx> { /// The trait reference of the parent obligation that led to the diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 05b698eb4c4ea..6930c9368282b 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -508,31 +508,33 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> { trait_item_def_id, }), super::ExprAssignable => Some(super::ExprAssignable), - super::MatchExpressionArm { + super::MatchExpressionArm(box super::MatchExpressionArmCause { arm_span, source, ref prior_arms, last_ty, discrim_hir_id, - } => { + }) => { tcx.lift(&last_ty).map(|last_ty| { - super::MatchExpressionArm { + super::MatchExpressionArm(box super::MatchExpressionArmCause { arm_span, source, prior_arms: prior_arms.clone(), last_ty, discrim_hir_id, - } + }) }) } 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), diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 7427ae9ce8de3..308a3d8ebc2cf 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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::{ObligationCause, ObligationCauseCode}; +use rustc::traits::{IfExpressionCause, MatchExpressionArmCause, ObligationCause}; +use rustc::traits::{ObligationCauseCode}; use rustc::ty::Ty; use syntax_pos::Span; @@ -146,13 +147,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The reason for the first arm to fail is not that the match arms diverge, // but rather that there's a prior obligation that doesn't hold. 0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)), - _ => (expr.span, ObligationCauseCode::MatchExpressionArm { - arm_span, - source: match_src, - prior_arms: other_arms.clone(), - last_ty: prior_arm_ty.unwrap(), - discrim_hir_id: discrim.hir_id, - }), + _ => (expr.span, + ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause { + arm_span, + source: match_src, + prior_arms: other_arms.clone(), + last_ty: prior_arm_ty.unwrap(), + discrim_hir_id: discrim.hir_id, + }) + ), }; let cause = self.cause(span, code); coercion.coerce(self, &cause, &arm.body, arm_ty); @@ -345,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( diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index e9370429f3f55..d626bff150020 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -529,11 +529,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); // recreated from (*) above // Check that E' = S'. - let cause = &self.misc(hir_ty.span); + let cause = self.misc(hir_ty.span); let InferOk { value: (), obligations, - } = self.at(cause, self.param_env) + } = self.at(&cause, self.param_env) .eq(*expected_ty, supplied_ty)?; all_obligations.extend(obligations); @@ -549,7 +549,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); all_obligations.push( Obligation::new( - cause.clone(), + cause, self.param_env, ty::Predicate::TypeOutlives( ty::Binder::dummy( diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 8e187b7e05b51..74ea93fc44270 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -308,7 +308,7 @@ fn compare_predicate_entailment<'tcx>( let cause = ObligationCause { span: impl_err_span, - ..cause.clone() + ..cause }; let mut diag = struct_span_err!(tcx.sess,