diff options
| author | bors <bors@rust-lang.org> | 2017-09-24 15:41:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-09-24 15:41:13 +0000 |
| commit | 1ed7d41d8849d930f0622eaf54049f66fff0ca2a (patch) | |
| tree | 9c7a836c7396376c382ed8aa8c672114b8a65c78 | |
| parent | 647aecc281f0defdd96bc807f2b98ec3090857a2 (diff) | |
| parent | b6bce56ac718a6343e44b37110e6c273ab9b6189 (diff) | |
| download | rust-1ed7d41d8849d930f0622eaf54049f66fff0ca2a.tar.gz rust-1ed7d41d8849d930f0622eaf54049f66fff0ca2a.zip | |
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
| -rw-r--r-- | src/librustc/infer/error_reporting/mod.rs | 13 | ||||
| -rw-r--r-- | src/librustc_typeck/check/coercion.rs | 6 |
2 files changed, 16 insertions, 3 deletions
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index a88e90caee3..b24c9690a46 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -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 diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index cfcdbcc1195..94422f93e59 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -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; |
