Skip to content

Commit 1ed7d41

Browse files
committed
Auto merge of #44743 - arielb1:size-rollback, r=eddyb
typeck::check::coercion - roll back failed unsizing type vars This wraps unsizing coercions within an additional level of `commit_if_ok`, which rolls back type variables if the unsizing coercion fails. This prevents a large amount of type-variables from accumulating while type-checking a large function, e.g. shaving 2GB off one of the 4GB peaks in #36799. This is a performance-sensitive PR so please don't roll it up. r? @eddyb cc @nikomatsakis
2 parents 647aecc + b6bce56 commit 1ed7d41

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

src/librustc/infer/error_reporting/mod.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -333,11 +333,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
333333
GenericBoundFailure(..) => true,
334334
};
335335

336-
if errors.iter().all(|e| is_bound_failure(e)) {
336+
337+
let mut errors = if errors.iter().all(|e| is_bound_failure(e)) {
337338
errors.clone()
338339
} else {
339340
errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect()
340-
}
341+
};
342+
343+
// sort the errors by span, for better error message stability.
344+
errors.sort_by_key(|u| match *u {
345+
ConcreteFailure(ref sro, _, _) => sro.span(),
346+
GenericBoundFailure(ref sro, _, _) => sro.span(),
347+
SubSupConflict(ref rvo, _, _, _, _) => rvo.span(),
348+
});
349+
errors
341350
}
342351

343352
/// Adds a note if the types come from similarly named crates

src/librustc_typeck/check/coercion.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,11 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
187187
}
188188

189189
// Consider coercing the subtype to a DST
190-
let unsize = self.coerce_unsized(a, b);
190+
//
191+
// NOTE: this is wrapped in a `commit_if_ok` because it creates
192+
// a "spurious" type variable, and we don't want to have that
193+
// type variable in memory if the coercion fails.
194+
let unsize = self.commit_if_ok(|_| self.coerce_unsized(a, b));
191195
if unsize.is_ok() {
192196
debug!("coerce: unsize successful");
193197
return unsize;

0 commit comments

Comments
 (0)