diff --git a/Cargo.lock b/Cargo.lock index 5253c819ca2c9..4ed8818cbad97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -356,7 +356,7 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.1" +version = "0.1.2" dependencies = [ "serde", ] @@ -1723,9 +1723,9 @@ checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" [[package]] name = "jobserver" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "972f5ae5d1cb9c6ae417789196c803205313edde988685da5e3aae0827b9e7fd" +checksum = "f5ca711fd837261e14ec9e674f092cbb931d3fa1482b017ae59328ddc6f3212b" dependencies = [ "libc", ] diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 84dd69ebd9634..fcc70b2e4c5ff 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -1287,9 +1287,6 @@ pub fn init_env_logger(env: &str) { .with_indent_lines(true) .with_ansi(color_logs) .with_targets(true) - .with_wraparound(10) - .with_verbose_exit(true) - .with_verbose_entry(true) .with_indent_amount(2); #[cfg(parallel_compiler)] let layer = layer.with_thread_ids(true).with_thread_names(true); diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index 9a96c03cd3c80..b970c9e4911fa 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -60,6 +60,9 @@ pub enum EscapeError { /// After a line ending with '\', the next line contains whitespace /// characters that are not skipped. UnskippedWhitespaceWarning, + + /// After a line ending with '\', multiple lines are skipped. + MultipleSkippedLinesWarning, } impl EscapeError { @@ -67,6 +70,7 @@ impl EscapeError { pub fn is_fatal(&self) -> bool { match self { EscapeError::UnskippedWhitespaceWarning => false, + EscapeError::MultipleSkippedLinesWarning => false, _ => true, } } @@ -315,12 +319,17 @@ where where F: FnMut(Range, Result), { - let str = chars.as_str(); - let first_non_space = str + let tail = chars.as_str(); + let first_non_space = tail .bytes() .position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r') - .unwrap_or(str.len()); - let tail = &str[first_non_space..]; + .unwrap_or(tail.len()); + if tail[1..first_non_space].contains('\n') { + // The +1 accounts for the escaping slash. + let end = start + first_non_space + 1; + callback(start..end, Err(EscapeError::MultipleSkippedLinesWarning)); + } + let tail = &tail[first_non_space..]; if let Some(c) = tail.chars().nth(0) { // For error reporting, we would like the span to contain the character that was not // skipped. The +1 is necessary to account for the leading \ that started the escape. diff --git a/compiler/rustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs index 1f4dbb20f4e98..fa61554afde6c 100644 --- a/compiler/rustc_lexer/src/unescape/tests.rs +++ b/compiler/rustc_lexer/src/unescape/tests.rs @@ -106,6 +106,10 @@ fn test_unescape_str_warn() { assert_eq!(unescaped, expected); } + // Check we can handle escaped newlines at the end of a file. + check("\\\n", &[]); + check("\\\n ", &[]); + check( "\\\n \u{a0} x", &[ @@ -115,6 +119,7 @@ fn test_unescape_str_warn() { (6..7, Ok('x')), ], ); + check("\\\n \n x", &[(0..7, Err(EscapeError::MultipleSkippedLinesWarning)), (7..8, Ok('x'))]); } #[test] diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 4e95cdc0efa5f..aa6b424ce2b57 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -280,6 +280,11 @@ pub(crate) fn emit_unescape_error( format!("non-ASCII whitespace symbol '{}' is not skipped", c.escape_unicode()); handler.struct_span_warn(span, &msg).span_label(char_span, &msg).emit(); } + EscapeError::MultipleSkippedLinesWarning => { + let msg = "multiple lines skipped by escaped newline"; + let bottom_msg = "skipping everything up to and including this point"; + handler.struct_span_warn(span, msg).span_label(span, bottom_msg).emit(); + } } } diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 7f87ead6feed6..aa91346851f9d 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -360,3 +360,61 @@ impl Extend<()> for () { } fn extend_one(&mut self, _item: ()) {} } + +#[stable(feature = "extend_for_tuple", since = "1.56.0")] +impl Extend<(A, B)> for (ExtendA, ExtendB) +where + ExtendA: Extend, + ExtendB: Extend, +{ + /// Allows to `extend` a tuple of collections that also implement `Extend`. + /// + /// See also: [`Iterator::unzip`] + /// + /// # Examples + /// ``` + /// let mut tuple = (vec![0], vec![1]); + /// tuple.extend(vec![(2, 3), (4, 5), (6, 7)]); + /// assert_eq!(tuple.0, vec![0, 2, 4, 6]); + /// assert_eq!(tuple.1, vec![1, 3, 5, 7]); + /// + /// // also allows for arbitrarily nested tuples + /// let mut nested_tuple = (vec![(1, -1)], vec![(2, -2)]); + /// nested_tuple.extend(vec![((3, -3), (4, -4)), ((5, -5), (6, -6))]); + /// + /// assert_eq!(nested_tuple.0, vec![(1, -1), (3, -3), (5, -5)]); + /// assert_eq!(nested_tuple.1, vec![(2, -2), (4, -4), (6, -6)]); + /// ``` + fn extend>(&mut self, into_iter: T) { + let (a, b) = self; + let iter = into_iter.into_iter(); + + fn extend<'a, A, B>( + a: &'a mut impl Extend, + b: &'a mut impl Extend, + ) -> impl FnMut((), (A, B)) + 'a { + move |(), (t, u)| { + a.extend_one(t); + b.extend_one(u); + } + } + + let (lower_bound, _) = iter.size_hint(); + if lower_bound > 0 { + a.extend_reserve(lower_bound); + b.extend_reserve(lower_bound); + } + + iter.fold((), extend(a, b)); + } + + fn extend_one(&mut self, item: (A, B)) { + self.0.extend_one(item.0); + self.1.extend_one(item.1); + } + + fn extend_reserve(&mut self, additional: usize) { + self.0.extend_reserve(additional); + self.1.extend_reserve(additional); + } +} diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 6b24d33bebca3..524d8f857e2a5 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2841,6 +2841,14 @@ pub trait Iterator { /// /// assert_eq!(left, [1, 3]); /// assert_eq!(right, [2, 4]); + /// + /// // you can also unzip multiple nested tuples at once + /// let a = [(1, (2, 3)), (4, (5, 6))]; + /// + /// let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.iter().cloned().unzip(); + /// assert_eq!(x, [1, 4]); + /// assert_eq!(y, [2, 5]); + /// assert_eq!(z, [3, 6]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn unzip(self) -> (FromA, FromB) @@ -2849,28 +2857,9 @@ pub trait Iterator { FromB: Default + Extend, Self: Sized + Iterator, { - fn extend<'a, A, B>( - ts: &'a mut impl Extend, - us: &'a mut impl Extend, - ) -> impl FnMut((), (A, B)) + 'a { - move |(), (t, u)| { - ts.extend_one(t); - us.extend_one(u); - } - } - - let mut ts: FromA = Default::default(); - let mut us: FromB = Default::default(); - - let (lower_bound, _) = self.size_hint(); - if lower_bound > 0 { - ts.extend_reserve(lower_bound); - us.extend_reserve(lower_bound); - } - - self.fold((), extend(&mut ts, &mut us)); - - (ts, us) + let mut unzipped: (FromA, FromB) = Default::default(); + unzipped.extend(self); + unzipped } /// Creates an iterator which copies all of its elements. diff --git a/src/doc/book b/src/doc/book index a07036f864b37..7e49659102f09 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit a07036f864b37896b31eb996cd7aedb489f69a1f +Subproject commit 7e49659102f0977d9142190e1ba23345c0f00eb1 diff --git a/src/doc/embedded-book b/src/doc/embedded-book index 09986cd352404..4f9fcaa30d11b 160000 --- a/src/doc/embedded-book +++ b/src/doc/embedded-book @@ -1 +1 @@ -Subproject commit 09986cd352404eb4659db44613b27cac9aa652fc +Subproject commit 4f9fcaa30d11ba52b641e6fd5206536d65838af9 diff --git a/src/doc/nomicon b/src/doc/nomicon index f51734eb5566c..0c7e5bd1428e7 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit f51734eb5566c826b471977747ea3d7d6915bbe9 +Subproject commit 0c7e5bd1428e7838252bb57b7f0fbfda4ec82f02 diff --git a/src/doc/reference b/src/doc/reference index 3b7be075af5d6..4884fe45c14f8 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 3b7be075af5d6e402a18efff672a8a265b4596fd +Subproject commit 4884fe45c14f8b22121760fb117181bb4da8dfe0 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index 09343d6f921d2..c4644b427cbda 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit 09343d6f921d2a07c66f8c41ec3d65bf1fa52556 +Subproject commit c4644b427cbdaafc7a87be0ccdf5d8aaa07ac35f diff --git a/src/etc/pre-commit.sh b/src/etc/pre-commit.sh old mode 100644 new mode 100755 diff --git a/src/test/ui/fmt/format-string-error-2.rs b/src/test/ui/fmt/format-string-error-2.rs index 69fed2cb69ad8..1f7f0d8f6be6a 100644 --- a/src/test/ui/fmt/format-string-error-2.rs +++ b/src/test/ui/fmt/format-string-error-2.rs @@ -5,7 +5,7 @@ fn main() { a"); //~^ ERROR invalid format string format!("{ \ - + \ b"); //~^ ERROR invalid format string format!(r#"{ \ @@ -38,12 +38,12 @@ fn main() { { \ \ b \ - + \ "); //~^^^ ERROR invalid format string format!(r#" raw { \ - + \ c"#); //~^^^ ERROR invalid format string format!(r#" diff --git a/src/test/ui/fmt/format-string-error-2.stderr b/src/test/ui/fmt/format-string-error-2.stderr index c421fe49ef0a4..76cdfbb93bf24 100644 --- a/src/test/ui/fmt/format-string-error-2.stderr +++ b/src/test/ui/fmt/format-string-error-2.stderr @@ -19,7 +19,7 @@ error: invalid format string: expected `'}'`, found `'b'` | LL | format!("{ \ | - because of this opening brace -LL | +LL | \ LL | b"); | ^ expected `}` in format string | diff --git a/src/test/ui/str/str-escape.rs b/src/test/ui/str/str-escape.rs new file mode 100644 index 0000000000000..0264632fd24a1 --- /dev/null +++ b/src/test/ui/str/str-escape.rs @@ -0,0 +1,11 @@ +// check-pass +fn main() { + let s = "\ + + "; + //~^^^ WARNING multiple lines skipped by escaped newline + let s = "foo\ +   bar + "; + //~^^^ WARNING non-ASCII whitespace symbol '\u{a0}' is not skipped +} diff --git a/src/test/ui/str/str-escape.stderr b/src/test/ui/str/str-escape.stderr new file mode 100644 index 0000000000000..b2501f1a2145f --- /dev/null +++ b/src/test/ui/str/str-escape.stderr @@ -0,0 +1,21 @@ +warning: multiple lines skipped by escaped newline + --> $DIR/str-escape.rs:3:14 + | +LL | let s = "\ + | ______________^ +LL | | +LL | | "; + | |_____________^ skipping everything up to and including this point + +warning: non-ASCII whitespace symbol '\u{a0}' is not skipped + --> $DIR/str-escape.rs:7:17 + | +LL | let s = "foo\ + | _________________^ +LL | |   bar + | | ^ non-ASCII whitespace symbol '\u{a0}' is not skipped + | |___| + | + +warning: 2 warnings emitted + diff --git a/src/tools/cargo b/src/tools/cargo index cc17afbb0067b..b51439fd8b505 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit cc17afbb0067b1f57d8882640f63b2168d5b7624 +Subproject commit b51439fd8b505d4800a257acfecf3c69f81e35cf diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index ea105f9396a9d..5664a2b0b3140 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit ea105f9396a9dab68e71efb06016b7c76c83ba7c +Subproject commit 5664a2b0b31403024ce5ab927760d630d5ddc9a4