Skip to content

Commit f8d8ffa

Browse files
committed
Auto merge of #111029 - Nilstrieb:when-the-errs-are-too-big, r=petrochenkov
Shrink `SelectionError` a lot `SelectionError` used to be 80 bytes (on 64 bit). That's quite big. Especially because the selection cache contained `Result<_, SelectionError>. The Ok type is only 32 bytes, so the 80 bytes significantly inflate the size of the cache. Most variants of the `SelectionError` seem to be hard errors, only `Unimplemented` shows up in practice (for cranelift-codegen, it occupies 23.4% of all cache entries). We can just box away the biggest variant, `OutputTypeParameterMismatch`, to get the size down to 16 bytes, well within the size of the Ok type inside the cache.
2 parents 4d941cd + e8ab648 commit f8d8ffa

File tree

5 files changed

+32
-14
lines changed

5 files changed

+32
-14
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
278278
span: Span,
279279
) -> bool {
280280
if let traits::FulfillmentErrorCode::CodeSelectionError(
281-
traits::SelectionError::OutputTypeParameterMismatch(_, expected, _),
281+
traits::SelectionError::OutputTypeParameterMismatch(box traits::SelectionOutputTypeParameterMismatch{
282+
expected_trait_ref, ..
283+
}),
282284
) = error.code
283-
&& let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected.skip_binder().self_ty().kind()
285+
&& let ty::Closure(def_id, _) | ty::Generator(def_id, ..) = expected_trait_ref.skip_binder().self_ty().kind()
284286
&& span.overlaps(self.tcx.def_span(*def_id))
285287
{
286288
true

compiler/rustc_hir_typeck/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#![feature(let_chains)]
33
#![feature(try_blocks)]
44
#![feature(never_type)]
5+
#![feature(box_patterns)]
56
#![feature(min_specialization)]
67
#![feature(control_flow_enum)]
78
#![feature(drain_filter)]

compiler/rustc_middle/src/traits/mod.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -580,11 +580,7 @@ pub enum SelectionError<'tcx> {
580580
/// After a closure impl has selected, its "outputs" were evaluated
581581
/// (which for closures includes the "input" type params) and they
582582
/// didn't resolve. See `confirm_poly_trait_refs` for more.
583-
OutputTypeParameterMismatch(
584-
ty::PolyTraitRef<'tcx>,
585-
ty::PolyTraitRef<'tcx>,
586-
ty::error::TypeError<'tcx>,
587-
),
583+
OutputTypeParameterMismatch(Box<SelectionOutputTypeParameterMismatch<'tcx>>),
588584
/// The trait pointed by `DefId` is not object safe.
589585
TraitNotObjectSafe(DefId),
590586
/// A given constant couldn't be evaluated.
@@ -596,6 +592,13 @@ pub enum SelectionError<'tcx> {
596592
ErrorReporting,
597593
}
598594

595+
#[derive(Clone, Debug, TypeVisitable, Lift)]
596+
pub struct SelectionOutputTypeParameterMismatch<'tcx> {
597+
pub found_trait_ref: ty::PolyTraitRef<'tcx>,
598+
pub expected_trait_ref: ty::PolyTraitRef<'tcx>,
599+
pub terr: ty::error::TypeError<'tcx>,
600+
}
601+
599602
/// When performing resolution, it is typically the case that there
600603
/// can be one of three outcomes:
601604
///

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use rustc_hir::{GenericParam, Item, Node};
2828
use rustc_infer::infer::error_reporting::TypeErrCtxt;
2929
use rustc_infer::infer::{InferOk, TypeTrace};
3030
use rustc_middle::traits::select::OverflowError;
31+
use rustc_middle::traits::SelectionOutputTypeParameterMismatch;
3132
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
3233
use rustc_middle::ty::error::{ExpectedFound, TypeError};
3334
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
@@ -1087,17 +1088,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
10871088
}
10881089
}
10891090

1090-
OutputTypeParameterMismatch(
1091+
OutputTypeParameterMismatch(box SelectionOutputTypeParameterMismatch {
10911092
found_trait_ref,
10921093
expected_trait_ref,
1093-
terr @ TypeError::CyclicTy(_),
1094-
) => self.report_type_parameter_mismatch_cyclic_type_error(
1094+
terr: terr @ TypeError::CyclicTy(_),
1095+
}) => self.report_type_parameter_mismatch_cyclic_type_error(
10951096
&obligation,
10961097
found_trait_ref,
10971098
expected_trait_ref,
10981099
terr,
10991100
),
1100-
OutputTypeParameterMismatch(found_trait_ref, expected_trait_ref, _) => {
1101+
OutputTypeParameterMismatch(box SelectionOutputTypeParameterMismatch {
1102+
found_trait_ref,
1103+
expected_trait_ref,
1104+
terr: _,
1105+
}) => {
11011106
match self.report_type_parameter_mismatch_error(
11021107
&obligation,
11031108
span,

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
1010
use rustc_hir::lang_items::LangItem;
1111
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
1212
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
13+
use rustc_middle::traits::SelectionOutputTypeParameterMismatch;
1314
use rustc_middle::ty::{
1415
self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate,
1516
TraitRef, Ty, TyCtxt, TypeVisitableExt,
@@ -811,7 +812,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
811812
fn confirm_poly_trait_refs(
812813
&mut self,
813814
obligation: &TraitObligation<'tcx>,
814-
expected_trait_ref: ty::PolyTraitRef<'tcx>,
815+
self_ty_trait_ref: ty::PolyTraitRef<'tcx>,
815816
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
816817
let obligation_trait_ref = obligation.predicate.to_poly_trait_ref();
817818
// Normalize the obligation and expected trait refs together, because why not
@@ -822,7 +823,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
822823
obligation.param_env,
823824
obligation.cause.clone(),
824825
obligation.recursion_depth + 1,
825-
(obligation_trait_ref, expected_trait_ref),
826+
(obligation_trait_ref, self_ty_trait_ref),
826827
)
827828
});
828829

@@ -834,7 +835,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
834835
obligations.extend(nested);
835836
obligations
836837
})
837-
.map_err(|e| OutputTypeParameterMismatch(expected_trait_ref, obligation_trait_ref, e))
838+
.map_err(|terr| {
839+
OutputTypeParameterMismatch(Box::new(SelectionOutputTypeParameterMismatch {
840+
expected_trait_ref: obligation_trait_ref,
841+
found_trait_ref: expected_trait_ref,
842+
terr,
843+
}))
844+
})
838845
}
839846

840847
fn confirm_trait_upcasting_unsize_candidate(

0 commit comments

Comments
 (0)