diff --git a/src/doc/index.md b/src/doc/index.md
index 11313ba99e1a6..b1788d8c32f02 100644
--- a/src/doc/index.md
+++ b/src/doc/index.md
@@ -43,6 +43,13 @@ Rust's standard library has [extensive API documentation](std/index.html),
with explanations of how to use various things, as well as example code for
accomplishing various tasks.
+
+
+
+
## The Rustc Book
[The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`.
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 60aeb92d91a6f..3c694fe7b4e58 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -177,24 +177,6 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
MaybeInitializedPlaces::new(tcx, mir, &mdpe),
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
));
- let flow_uninits = FlowAtLocation::new(do_dataflow(
- tcx,
- mir,
- id,
- &attributes,
- &dead_unwinds,
- MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
- |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
- ));
- let flow_ever_inits = FlowAtLocation::new(do_dataflow(
- tcx,
- mir,
- id,
- &attributes,
- &dead_unwinds,
- EverInitializedPlaces::new(tcx, mir, &mdpe),
- |bd, i| DebugFormatted::new(&bd.move_data().inits[i]),
- ));
let locals_are_invalidated_at_exit = match tcx.hir.body_owner_kind(id) {
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => false,
@@ -216,6 +198,12 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
&borrow_set,
&mut errors_buffer,
);
+
+ // The various `flow_*` structures can be large. We drop `flow_inits` here
+ // so it doesn't overlap with the others below. This reduces peak memory
+ // usage significantly on some benchmarks.
+ drop(flow_inits);
+
let regioncx = Rc::new(regioncx);
let flow_borrows = FlowAtLocation::new(do_dataflow(
@@ -227,6 +215,24 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
Borrows::new(tcx, mir, regioncx.clone(), def_id, body_id, &borrow_set),
|rs, i| DebugFormatted::new(&rs.location(i)),
));
+ let flow_uninits = FlowAtLocation::new(do_dataflow(
+ tcx,
+ mir,
+ id,
+ &attributes,
+ &dead_unwinds,
+ MaybeUninitializedPlaces::new(tcx, mir, &mdpe),
+ |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
+ ));
+ let flow_ever_inits = FlowAtLocation::new(do_dataflow(
+ tcx,
+ mir,
+ id,
+ &attributes,
+ &dead_unwinds,
+ EverInitializedPlaces::new(tcx, mir, &mdpe),
+ |bd, i| DebugFormatted::new(&bd.move_data().inits[i]),
+ ));
let movable_generator = match tcx.hir.get(id) {
Node::Expr(&hir::Expr {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index d4e22dd91d7d5..75311d938516f 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2301,17 +2301,21 @@ fn document_non_exhaustive(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::R
}
fn name_key(name: &str) -> (&str, u64, usize) {
+ let end = name.bytes()
+ .rposition(|b| b.is_ascii_digit()).map_or(name.len(), |i| i + 1);
+
// find number at end
- let split = name.bytes().rposition(|b| b < b'0' || b'9' < b).map_or(0, |s| s + 1);
+ let split = name[0..end].bytes()
+ .rposition(|b| !b.is_ascii_digit()).map_or(0, |i| i + 1);
// count leading zeroes
let after_zeroes =
- name[split..].bytes().position(|b| b != b'0').map_or(name.len(), |extra| split + extra);
+ name[split..end].bytes().position(|b| b != b'0').map_or(name.len(), |extra| split + extra);
// sort leading zeroes last
let num_zeroes = after_zeroes - split;
- match name[split..].parse() {
+ match name[split..end].parse() {
Ok(n) => (&name[..split], n, num_zeroes),
Err(_) => (name, 0, num_zeroes),
}
@@ -2702,6 +2706,14 @@ fn bounds(t_bounds: &[clean::GenericBound]) -> String {
bounds
}
+fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering {
+ let lhs = format!("{}", lhs.inner_impl());
+ let rhs = format!("{}", rhs.inner_impl());
+
+ // lhs and rhs are formatted as HTML, which may be unnecessary
+ name_key(&lhs).cmp(&name_key(&rhs))
+}
+
fn item_trait(
w: &mut fmt::Formatter,
cx: &Context,
@@ -2905,9 +2917,12 @@ fn item_trait(
.map_or(true, |d| cache.paths.contains_key(&d)));
- let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter()
+ let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter()
.partition(|i| i.inner_impl().synthetic);
+ synthetic.sort_by(compare_impl);
+ concrete.sort_by(compare_impl);
+
if !foreign.is_empty() {
write!(w, "