Skip to content

Commit

Permalink
Auto merge of #44743 - arielb1:size-rollback, r=eddyb
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Sep 24, 2017
2 parents 647aecc + b6bce56 commit 1ed7d41
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
13 changes: 11 additions & 2 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
GenericBoundFailure(..) => true,
};

if errors.iter().all(|e| is_bound_failure(e)) {

let mut errors = if errors.iter().all(|e| is_bound_failure(e)) {
errors.clone()
} else {
errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect()
}
};

// sort the errors by span, for better error message stability.
errors.sort_by_key(|u| match *u {
ConcreteFailure(ref sro, _, _) => sro.span(),
GenericBoundFailure(ref sro, _, _) => sro.span(),
SubSupConflict(ref rvo, _, _, _, _) => rvo.span(),
});
errors
}

/// Adds a note if the types come from similarly named crates
Expand Down
6 changes: 5 additions & 1 deletion src/librustc_typeck/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,11 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
}

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

0 comments on commit 1ed7d41

Please sign in to comment.