1
Fork 0

Auto merge of #54270 - GuillaumeGomez:rollup, r=GuillaumeGomez

Rollup of 5 pull requests

Successful merges:

 - #53941 (rustdoc: Sort implementors)
 - #54181 (Suggest && and || instead of 'and' and 'or')
 - #54209 (Partially revert 674a5db "Fix undesirable fallout [from macro modularization]")
 - #54213 (De-overlap the lifetimes of `flow_inits` and `flow_{un,ever_}inits`.)
 - #54244 (Add a small search box to seach Rust's standary library)

Failed merges:

r? @ghost
This commit is contained in:
bors 2018-09-16 15:42:02 +00:00
commit d3cba9b4b4
8 changed files with 285 additions and 73 deletions

View file

@ -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 with explanations of how to use various things, as well as example code for
accomplishing various tasks. accomplishing various tasks.
<div>
<form action="std/index.html" method="get">
<input type="search" name="search"/>
<button>Search</button>
</form>
</div>
## The Rustc Book ## The Rustc Book
[The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`. [The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`.

View file

@ -177,24 +177,6 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
MaybeInitializedPlaces::new(tcx, mir, &mdpe), MaybeInitializedPlaces::new(tcx, mir, &mdpe),
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]), |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) { let locals_are_invalidated_at_exit = match tcx.hir.body_owner_kind(id) {
hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => false, hir::BodyOwnerKind::Const | hir::BodyOwnerKind::Static(_) => false,
@ -216,6 +198,12 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
&borrow_set, &borrow_set,
&mut errors_buffer, &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 regioncx = Rc::new(regioncx);
let flow_borrows = FlowAtLocation::new(do_dataflow( 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), Borrows::new(tcx, mir, regioncx.clone(), def_id, body_id, &borrow_set),
|rs, i| DebugFormatted::new(&rs.location(i)), |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) { let movable_generator = match tcx.hir.get(id) {
Node::Expr(&hir::Expr { Node::Expr(&hir::Expr {

View file

@ -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) { 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 // 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 // count leading zeroes
let after_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 // sort leading zeroes last
let num_zeroes = after_zeroes - split; let num_zeroes = after_zeroes - split;
match name[split..].parse() { match name[split..end].parse() {
Ok(n) => (&name[..split], n, num_zeroes), Ok(n) => (&name[..split], n, num_zeroes),
Err(_) => (name, 0, num_zeroes), Err(_) => (name, 0, num_zeroes),
} }
@ -2702,6 +2706,14 @@ fn bounds(t_bounds: &[clean::GenericBound]) -> String {
bounds 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( fn item_trait(
w: &mut fmt::Formatter, w: &mut fmt::Formatter,
cx: &Context, cx: &Context,
@ -2905,9 +2917,12 @@ fn item_trait(
.map_or(true, |d| cache.paths.contains_key(&d))); .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); .partition(|i| i.inner_impl().synthetic);
synthetic.sort_by(compare_impl);
concrete.sort_by(compare_impl);
if !foreign.is_empty() { if !foreign.is_empty() {
write!(w, " write!(w, "
<h2 id='foreign-impls' class='small-section-header'> <h2 id='foreign-impls' class='small-section-header'>
@ -4716,6 +4731,7 @@ fn test_name_sorting() {
"Fruit1", "Fruit01", "Fruit1", "Fruit01",
"Fruit2", "Fruit02", "Fruit2", "Fruit02",
"Fruit20", "Fruit20",
"Fruit30x",
"Fruit100", "Fruit100",
"Pear"]; "Pear"];
let mut sorted = names.to_owned(); let mut sorted = names.to_owned();

View file

@ -732,6 +732,22 @@ impl<'a> Parser<'a> {
format!("expected {} here", expect))) format!("expected {} here", expect)))
}; };
let mut err = self.fatal(&msg_exp); let mut err = self.fatal(&msg_exp);
if self.token.is_ident_named("and") {
err.span_suggestion_short_with_applicability(
self.span,
"use `&&` instead of `and` for the boolean operator",
"&&".to_string(),
Applicability::MaybeIncorrect,
);
}
if self.token.is_ident_named("or") {
err.span_suggestion_short_with_applicability(
self.span,
"use `||` instead of `or` for the boolean operator",
"||".to_string(),
Applicability::MaybeIncorrect,
);
}
let sp = if self.token == token::Token::Eof { let sp = if self.token == token::Token::Eof {
// This is EOF, don't want to point at the following char, but rather the last token // This is EOF, don't want to point at the following char, but rather the last token
self.prev_span self.prev_span
@ -4751,6 +4767,23 @@ impl<'a> Parser<'a> {
e.span_label(sp, "expected `{`"); e.span_label(sp, "expected `{`");
} }
if self.token.is_ident_named("and") {
e.span_suggestion_short_with_applicability(
self.span,
"use `&&` instead of `and` for the boolean operator",
"&&".to_string(),
Applicability::MaybeIncorrect,
);
}
if self.token.is_ident_named("or") {
e.span_suggestion_short_with_applicability(
self.span,
"use `||` instead of `or` for the boolean operator",
"||".to_string(),
Applicability::MaybeIncorrect,
);
}
// Check to see if the user has written something like // Check to see if the user has written something like
// //
// if (cond) // if (cond)

View file

@ -0,0 +1,30 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub trait MyIterator {
}
pub struct MyStruct<T>(T);
macro_rules! array_impls {
($($N:expr)+) => {
$(
impl<'a, T> MyIterator for &'a MyStruct<[T; $N]> {
}
)+
}
}
// @has issue_53812/trait.MyIterator.html '//*[@id="implementors-list"]//h3[1]' 'MyStruct<[T; 0]>'
// @has - '//*[@id="implementors-list"]//h3[2]' 'MyStruct<[T; 1]>'
// @has - '//*[@id="implementors-list"]//h3[3]' 'MyStruct<[T; 2]>'
// @has - '//*[@id="implementors-list"]//h3[4]' 'MyStruct<[T; 3]>'
// @has - '//*[@id="implementors-list"]//h3[5]' 'MyStruct<[T; 10]>'
array_impls! { 10 3 2 1 0 }

View file

@ -0,0 +1,66 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn test_and() {
let a = true;
let b = false;
if a and b {
//~^ ERROR expected `{`, found `and`
println!("both");
}
}
fn test_or() {
let a = true;
let b = false;
if a or b {
//~^ ERROR expected `{`, found `or`
println!("both");
}
}
fn test_and_par() {
let a = true;
let b = false;
if (a and b) {
//~^ ERROR expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `and`
println!("both");
}
}
fn test_or_par() {
let a = true;
let b = false;
if (a or b) {
//~^ ERROR expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or`
println!("both");
}
}
fn test_while_and() {
let a = true;
let b = false;
while a and b {
//~^ ERROR expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and`
println!("both");
}
}
fn test_while_or() {
let a = true;
let b = false;
while a or b {
//~^ ERROR expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or`
println!("both");
}
}
fn main() {
}

View file

@ -0,0 +1,54 @@
error: expected `{`, found `and`
--> $DIR/issue-54109-and_instead_of_ampersands.rs:14:10
|
LL | if a and b {
| -- ^^^ help: use `&&` instead of `and` for the boolean operator
| |
| this `if` statement has a condition, but no block
error: expected `{`, found `or`
--> $DIR/issue-54109-and_instead_of_ampersands.rs:23:10
|
LL | if a or b {
| -- ^^ help: use `||` instead of `or` for the boolean operator
| |
| this `if` statement has a condition, but no block
error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `and`
--> $DIR/issue-54109-and_instead_of_ampersands.rs:32:11
|
LL | if (a and b) {
| ^^^
| |
| expected one of 8 possible tokens here
| help: use `&&` instead of `and` for the boolean operator
error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or`
--> $DIR/issue-54109-and_instead_of_ampersands.rs:41:11
|
LL | if (a or b) {
| ^^
| |
| expected one of 8 possible tokens here
| help: use `||` instead of `or` for the boolean operator
error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and`
--> $DIR/issue-54109-and_instead_of_ampersands.rs:50:13
|
LL | while a and b {
| ^^^
| |
| expected one of `!`, `.`, `::`, `?`, `{`, or an operator here
| help: use `&&` instead of `and` for the boolean operator
error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or`
--> $DIR/issue-54109-and_instead_of_ampersands.rs:59:13
|
LL | while a or b {
| ^^
| |
| expected one of `!`, `.`, `::`, `?`, `{`, or an operator here
| help: use `||` instead of `or` for the boolean operator
error: aborting due to 6 previous errors

View file

@ -62,30 +62,30 @@ fn assert_ne() {
#[test] #[test]
fn cfg() { fn cfg() {
cfg!(pants); let _ = cfg!(pants);
cfg!(pants,); let _ = cfg!(pants,);
cfg!(pants = "pants"); let _ = cfg!(pants = "pants");
cfg!(pants = "pants",); let _ = cfg!(pants = "pants",);
cfg!(all(pants)); let _ = cfg!(all(pants));
cfg!(all(pants),); let _ = cfg!(all(pants),);
cfg!(all(pants,)); let _ = cfg!(all(pants,));
cfg!(all(pants,),); let _ = cfg!(all(pants,),);
} }
#[test] #[test]
fn column() { fn column() {
column!(); let _ = column!();
} }
// compile_error! is in a companion to this test in compile-fail // compile_error! is in a companion to this test in compile-fail
#[test] #[test]
fn concat() { fn concat() {
concat!(); let _ = concat!();
concat!("hello"); let _ = concat!("hello");
concat!("hello",); let _ = concat!("hello",);
concat!("hello", " world"); let _ = concat!("hello", " world");
concat!("hello", " world",); let _ = concat!("hello", " world",);
} }
#[test] #[test]
@ -131,10 +131,10 @@ fn debug_assert_ne() {
#[test] #[test]
fn env() { fn env() {
env!("PATH"); let _ = env!("PATH");
env!("PATH",); let _ = env!("PATH",);
env!("PATH", "not found"); let _ = env!("PATH", "not found");
env!("PATH", "not found",); let _ = env!("PATH", "not found",);
} }
#[cfg(std)] #[cfg(std)]
@ -158,58 +158,58 @@ fn eprintln() {
#[test] #[test]
fn file() { fn file() {
file!(); let _ = file!();
} }
#[cfg(std)] #[cfg(std)]
#[test] #[test]
fn format() { fn format() {
format!("hello"); let _ = format!("hello");
format!("hello",); let _ = format!("hello",);
format!("hello {}", "world"); let _ = format!("hello {}", "world");
format!("hello {}", "world",); let _ = format!("hello {}", "world",);
} }
#[test] #[test]
fn format_args() { fn format_args() {
format_args!("hello"); let _ = format_args!("hello");
format_args!("hello",); let _ = format_args!("hello",);
format_args!("hello {}", "world"); let _ = format_args!("hello {}", "world");
format_args!("hello {}", "world",); let _ = format_args!("hello {}", "world",);
} }
#[test] #[test]
fn include() { fn include() {
include!("auxiliary/macro-comma-support.rs"); let _ = include!("auxiliary/macro-comma-support.rs");
include!("auxiliary/macro-comma-support.rs",); let _ = include!("auxiliary/macro-comma-support.rs",);
} }
#[test] #[test]
fn include_bytes() { fn include_bytes() {
include_bytes!("auxiliary/macro-comma-support.rs"); let _ = include_bytes!("auxiliary/macro-comma-support.rs");
include_bytes!("auxiliary/macro-comma-support.rs",); let _ = include_bytes!("auxiliary/macro-comma-support.rs",);
} }
#[test] #[test]
fn include_str() { fn include_str() {
include_str!("auxiliary/macro-comma-support.rs"); let _ = include_str!("auxiliary/macro-comma-support.rs");
include_str!("auxiliary/macro-comma-support.rs",); let _ = include_str!("auxiliary/macro-comma-support.rs",);
} }
#[test] #[test]
fn line() { fn line() {
line!(); let _ = line!();
} }
#[test] #[test]
fn module_path() { fn module_path() {
module_path!(); let _ = module_path!();
} }
#[test] #[test]
fn option_env() { fn option_env() {
option_env!("PATH"); let _ = option_env!("PATH");
option_env!("PATH",); let _ = option_env!("PATH",);
} }
#[test] #[test]
@ -309,10 +309,10 @@ fn unreachable() {
#[test] #[test]
fn vec() { fn vec() {
let _: Vec<()> = vec![]; let _: Vec<()> = vec![];
vec![0]; let _ = vec![0];
vec![0,]; let _ = vec![0,];
vec![0, 1]; let _ = vec![0, 1];
vec![0, 1,]; let _ = vec![0, 1,];
} }
// give a test body access to a fmt::Formatter, which seems // give a test body access to a fmt::Formatter, which seems
@ -340,21 +340,21 @@ macro_rules! test_with_formatter {
test_with_formatter! { test_with_formatter! {
#[test] #[test]
fn write(f: &mut fmt::Formatter) { fn write(f: &mut fmt::Formatter) {
write!(f, "hello"); let _ = write!(f, "hello");
write!(f, "hello",); let _ = write!(f, "hello",);
write!(f, "hello {}", "world"); let _ = write!(f, "hello {}", "world");
write!(f, "hello {}", "world",); let _ = write!(f, "hello {}", "world",);
} }
} }
test_with_formatter! { test_with_formatter! {
#[test] #[test]
fn writeln(f: &mut fmt::Formatter) { fn writeln(f: &mut fmt::Formatter) {
writeln!(f); let _ = writeln!(f);
writeln!(f,); let _ = writeln!(f,);
writeln!(f, "hello"); let _ = writeln!(f, "hello");
writeln!(f, "hello",); let _ = writeln!(f, "hello",);
writeln!(f, "hello {}", "world"); let _ = writeln!(f, "hello {}", "world");
writeln!(f, "hello {}", "world",); let _ = writeln!(f, "hello {}", "world",);
} }
} }