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, "

@@ -4716,6 +4731,7 @@ fn test_name_sorting() { "Fruit1", "Fruit01", "Fruit2", "Fruit02", "Fruit20", + "Fruit30x", "Fruit100", "Pear"]; let mut sorted = names.to_owned(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f57fca2cfcf60..48e034b117f18 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -732,6 +732,22 @@ impl<'a> Parser<'a> { format!("expected {} here", expect))) }; 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 { // This is EOF, don't want to point at the following char, but rather the last token self.prev_span @@ -4751,6 +4767,23 @@ impl<'a> Parser<'a> { 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 // // if (cond) diff --git a/src/test/rustdoc/issue-53812.rs b/src/test/rustdoc/issue-53812.rs new file mode 100644 index 0000000000000..60d19fbcd1a20 --- /dev/null +++ b/src/test/rustdoc/issue-53812.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait MyIterator { +} + +pub struct MyStruct(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 } diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs new file mode 100644 index 0000000000000..d053b11772cd0 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs @@ -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 or the MIT license +// , 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() { +} diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr new file mode 100644 index 0000000000000..22845775aed13 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr @@ -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 + diff --git a/src/test/ui/run-pass/macros/macro-comma-support.rs b/src/test/ui/run-pass/macros/macro-comma-support.rs index 9186974f0a378..f674123aac7a2 100644 --- a/src/test/ui/run-pass/macros/macro-comma-support.rs +++ b/src/test/ui/run-pass/macros/macro-comma-support.rs @@ -62,30 +62,30 @@ fn assert_ne() { #[test] fn cfg() { - cfg!(pants); - cfg!(pants,); - cfg!(pants = "pants"); - cfg!(pants = "pants",); - cfg!(all(pants)); - cfg!(all(pants),); - cfg!(all(pants,)); - cfg!(all(pants,),); + let _ = cfg!(pants); + let _ = cfg!(pants,); + let _ = cfg!(pants = "pants"); + let _ = cfg!(pants = "pants",); + let _ = cfg!(all(pants)); + let _ = cfg!(all(pants),); + let _ = cfg!(all(pants,)); + let _ = cfg!(all(pants,),); } #[test] fn column() { - column!(); + let _ = column!(); } // compile_error! is in a companion to this test in compile-fail #[test] fn concat() { - concat!(); - concat!("hello"); - concat!("hello",); - concat!("hello", " world"); - concat!("hello", " world",); + let _ = concat!(); + let _ = concat!("hello"); + let _ = concat!("hello",); + let _ = concat!("hello", " world"); + let _ = concat!("hello", " world",); } #[test] @@ -131,10 +131,10 @@ fn debug_assert_ne() { #[test] fn env() { - env!("PATH"); - env!("PATH",); - env!("PATH", "not found"); - env!("PATH", "not found",); + let _ = env!("PATH"); + let _ = env!("PATH",); + let _ = env!("PATH", "not found"); + let _ = env!("PATH", "not found",); } #[cfg(std)] @@ -158,58 +158,58 @@ fn eprintln() { #[test] fn file() { - file!(); + let _ = file!(); } #[cfg(std)] #[test] fn format() { - format!("hello"); - format!("hello",); - format!("hello {}", "world"); - format!("hello {}", "world",); + let _ = format!("hello"); + let _ = format!("hello",); + let _ = format!("hello {}", "world"); + let _ = format!("hello {}", "world",); } #[test] fn format_args() { - format_args!("hello"); - format_args!("hello",); - format_args!("hello {}", "world"); - format_args!("hello {}", "world",); + let _ = format_args!("hello"); + let _ = format_args!("hello",); + let _ = format_args!("hello {}", "world"); + let _ = format_args!("hello {}", "world",); } #[test] fn include() { - include!("auxiliary/macro-comma-support.rs"); - include!("auxiliary/macro-comma-support.rs",); + let _ = include!("auxiliary/macro-comma-support.rs"); + let _ = include!("auxiliary/macro-comma-support.rs",); } #[test] fn include_bytes() { - include_bytes!("auxiliary/macro-comma-support.rs"); - include_bytes!("auxiliary/macro-comma-support.rs",); + let _ = include_bytes!("auxiliary/macro-comma-support.rs"); + let _ = include_bytes!("auxiliary/macro-comma-support.rs",); } #[test] fn include_str() { - include_str!("auxiliary/macro-comma-support.rs"); - include_str!("auxiliary/macro-comma-support.rs",); + let _ = include_str!("auxiliary/macro-comma-support.rs"); + let _ = include_str!("auxiliary/macro-comma-support.rs",); } #[test] fn line() { - line!(); + let _ = line!(); } #[test] fn module_path() { - module_path!(); + let _ = module_path!(); } #[test] fn option_env() { - option_env!("PATH"); - option_env!("PATH",); + let _ = option_env!("PATH"); + let _ = option_env!("PATH",); } #[test] @@ -309,10 +309,10 @@ fn unreachable() { #[test] fn vec() { let _: Vec<()> = vec![]; - vec![0]; - vec![0,]; - vec![0, 1]; - vec![0, 1,]; + let _ = vec![0]; + let _ = vec![0,]; + let _ = vec![0, 1]; + let _ = vec![0, 1,]; } // give a test body access to a fmt::Formatter, which seems @@ -340,21 +340,21 @@ macro_rules! test_with_formatter { test_with_formatter! { #[test] fn write(f: &mut fmt::Formatter) { - write!(f, "hello"); - write!(f, "hello",); - write!(f, "hello {}", "world"); - write!(f, "hello {}", "world",); + let _ = write!(f, "hello"); + let _ = write!(f, "hello",); + let _ = write!(f, "hello {}", "world"); + let _ = write!(f, "hello {}", "world",); } } test_with_formatter! { #[test] fn writeln(f: &mut fmt::Formatter) { - writeln!(f); - writeln!(f,); - writeln!(f, "hello"); - writeln!(f, "hello",); - writeln!(f, "hello {}", "world"); - writeln!(f, "hello {}", "world",); + let _ = writeln!(f); + let _ = writeln!(f,); + let _ = writeln!(f, "hello"); + let _ = writeln!(f, "hello",); + let _ = writeln!(f, "hello {}", "world"); + let _ = writeln!(f, "hello {}", "world",); } }