diff options
205 files changed, 2675 insertions, 1579 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 7e3ae7f2cc9..0caf2d9b6db 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -443,7 +443,6 @@ impl<'a> Builder<'a> { dist::Rustc, dist::DebuggerScripts, dist::Std, - dist::RustcDev, dist::Analysis, dist::Src, dist::PlainSourceTarball, diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e5a43dcb29f..d9dff77a30e 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -637,28 +637,6 @@ impl Step for DebuggerScripts { } } -fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool { - // The only true set of target libraries came from the build triple, so - // let's reduce redundant work by only producing archives from that host. - if compiler.host != builder.config.build { - builder.info("\tskipping, not a build host"); - true - } else { - false - } -} - -/// Copy stamped files into an image's `target/lib` directory. -fn copy_target_libs(builder: &Builder<'_>, target: &str, image: &Path, stamp: &Path) { - let dst = image.join("lib/rustlib").join(target).join("lib"); - t!(fs::create_dir_all(&dst)); - for (path, host) in builder.read_stamp_file(stamp) { - if !host || builder.config.build == target { - builder.copy(&path, &dst.join(path.file_name().unwrap())); - } - } -} - #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] pub struct Std { pub compiler: Compiler, @@ -689,19 +667,44 @@ impl Step for Std { let target = self.target; let name = pkgname(builder, "rust-std"); - let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target)); - if skip_host_target_lib(builder, compiler) { - return archive; + + // The only true set of target libraries came from the build triple, so + // let's reduce redundant work by only producing archives from that host. + if compiler.host != builder.config.build { + builder.info("\tskipping, not a build host"); + return distdir(builder).join(format!("{}-{}.tar.gz", name, target)); } - builder.ensure(compile::Std { compiler, target }); + // We want to package up as many target libraries as possible + // for the `rust-std` package, so if this is a host target we + // depend on librustc and otherwise we just depend on libtest. + if builder.hosts.iter().any(|t| t == target) { + builder.ensure(compile::Rustc { compiler, target }); + } else { + builder.ensure(compile::Std { compiler, target }); + } let image = tmpdir(builder).join(format!("{}-{}-image", name, target)); let _ = fs::remove_dir_all(&image); - let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); - let stamp = compile::libstd_stamp(builder, compiler_to_use, target); - copy_target_libs(builder, &target, &image, &stamp); + let dst = image.join("lib/rustlib").join(target); + t!(fs::create_dir_all(&dst)); + let mut src = builder.sysroot_libdir(compiler, target).to_path_buf(); + src.pop(); // Remove the trailing /lib folder from the sysroot_libdir + builder.cp_filtered(&src, &dst, &|path| { + if let Some(name) = path.file_name().and_then(|s| s.to_str()) { + if name == builder.config.rust_codegen_backends_dir.as_str() { + return false + } + if name == "bin" { + return false + } + if name.contains("LLVM") { + return false + } + } + true + }); let mut cmd = rust_installer(builder); cmd.arg("generate") @@ -720,73 +723,7 @@ impl Step for Std { let _time = timeit(builder); builder.run(&mut cmd); builder.remove_dir(&image); - archive - } -} - -#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] -pub struct RustcDev { - pub compiler: Compiler, - pub target: Interned<String>, -} - -impl Step for RustcDev { - type Output = PathBuf; - const DEFAULT: bool = true; - const ONLY_HOSTS: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("rustc-dev") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(RustcDev { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.build, - run.target, - ), - target: run.target, - }); - } - - fn run(self, builder: &Builder<'_>) -> PathBuf { - let compiler = self.compiler; - let target = self.target; - - let name = pkgname(builder, "rustc-dev"); - let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target)); - if skip_host_target_lib(builder, compiler) { - return archive; - } - - builder.ensure(compile::Rustc { compiler, target }); - - let image = tmpdir(builder).join(format!("{}-{}-image", name, target)); - let _ = fs::remove_dir_all(&image); - - let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); - let stamp = compile::librustc_stamp(builder, compiler_to_use, target); - copy_target_libs(builder, &target, &image, &stamp); - - let mut cmd = rust_installer(builder); - cmd.arg("generate") - .arg("--product-name=Rust") - .arg("--rel-manifest-dir=rustlib") - .arg("--success-message=Rust-is-ready-to-develop.") - .arg("--image-dir").arg(&image) - .arg("--work-dir").arg(&tmpdir(builder)) - .arg("--output-dir").arg(&distdir(builder)) - .arg(format!("--package-name={}-{}", name, target)) - .arg(format!("--component-name=rustc-dev-{}", target)) - .arg("--legacy-manifest-dirs=rustlib,cargo"); - - builder.info(&format!("Dist rustc-dev stage{} ({} -> {})", - compiler.stage, &compiler.host, target)); - let _time = timeit(builder); - builder.run(&mut cmd); - builder.remove_dir(&image); - archive + distdir(builder).join(format!("{}-{}.tar.gz", name, target)) } } diff --git a/src/doc/rustc/src/lints/listing/deny-by-default.md b/src/doc/rustc/src/lints/listing/deny-by-default.md index 6574267f185..5688e90ada1 100644 --- a/src/doc/rustc/src/lints/listing/deny-by-default.md +++ b/src/doc/rustc/src/lints/listing/deny-by-default.md @@ -222,3 +222,28 @@ error: invalid `crate_type` value | ^^^^^^^^^^^^^^^^^^^^ | ``` + +## const-err + +This lint detects expressions that will always panic at runtime and would be an +error in a `const` context. + +```rust,ignore +let _ = [0; 4][4]; +``` + +This will produce: + +```text +error: index out of bounds: the len is 4 but the index is 4 + --> src/lib.rs:1:9 + | +1 | let _ = [0; 4][4]; + | ^^^^^^^^^ + | +``` + +## order-dependent-trait-objects + +This lint detects a trait coherency violation that would allow creating two +trait impls for the same dynamic trait object involving marker traits. diff --git a/src/doc/unstable-book/src/compiler-flags/report-time.md b/src/doc/unstable-book/src/compiler-flags/report-time.md new file mode 100644 index 00000000000..ed4e9c6b568 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/report-time.md @@ -0,0 +1,80 @@ +# `report-time` + +The tracking issue for this feature is: [#64888] + +[#64888]: https://github.com/rust-lang/rust/issues/64888 + +------------------------ + +The `report-time` feature adds a possibility to report execution time of the +tests generated via `libtest`. + +This is unstable feature, so you have to provide `-Zunstable-options` to get +this feature working. + +Sample usage command: + +```sh +./test_executable -Zunstable-options --report-time +``` + +Available options: + +```sh +--report-time [plain|colored] + Show execution time of each test. Awailable values: + plain = do not colorize the execution time (default); + colored = colorize output according to the `color` + parameter value; + Threshold values for colorized output can be + configured via + `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION` + and + `RUST_TEST_TIME_DOCTEST` environment variables. + Expected format of environment variable is + `VARIABLE=WARN_TIME,CRITICAL_TIME`. + Not available for --format=terse +--ensure-time + Treat excess of the test execution time limit as + error. + Threshold values for this option can be configured via + `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION` + and + `RUST_TEST_TIME_DOCTEST` environment variables. + Expected format of environment variable is + `VARIABLE=WARN_TIME,CRITICAL_TIME`. + `CRITICAL_TIME` here means the limit that should not be + exceeded by test. +``` + +Example of the environment variable format: + +```sh +RUST_TEST_TIME_UNIT=100,200 +``` + +where 100 stands for warn time, and 200 stands for critical time. + +## Examples + +```sh +cargo test --tests -- -Zunstable-options --report-time + Finished dev [unoptimized + debuginfo] target(s) in 0.02s + Running target/debug/deps/example-27fb188025bec02c + +running 3 tests +test tests::unit_test_quick ... ok <0.000s> +test tests::unit_test_warn ... ok <0.055s> +test tests::unit_test_critical ... ok <0.110s> + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out + + Running target/debug/deps/tests-cedb06f6526d15d9 + +running 3 tests +test unit_test_quick ... ok <0.000s> +test unit_test_warn ... ok <0.550s> +test unit_test_critical ... ok <1.100s> + +test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out +``` diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index a4a0fbb194d..0bf573f5e25 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -10,8 +10,8 @@ use core::array::LengthAtMost32; use core::cmp::{self, Ordering}; use core::fmt; -use core::iter::{repeat_with, FromIterator, FusedIterator}; -use core::mem; +use core::iter::{once, repeat_with, FromIterator, FusedIterator}; +use core::mem::{self, replace}; use core::ops::Bound::{Excluded, Included, Unbounded}; use core::ops::{Index, IndexMut, RangeBounds, Try}; use core::ptr::{self, NonNull}; @@ -57,11 +57,88 @@ pub struct VecDeque<T> { buf: RawVec<T>, } +/// PairSlices pairs up equal length slice parts of two deques +/// +/// For example, given deques "A" and "B" with the following division into slices: +/// +/// A: [0 1 2] [3 4 5] +/// B: [a b] [c d e] +/// +/// It produces the following sequence of matching slices: +/// +/// ([0 1], [a b]) +/// ([2], [c]) +/// ([3 4], [d e]) +/// +/// and the uneven remainder of either A or B is skipped. +struct PairSlices<'a, 'b, T> { + a0: &'a mut [T], + a1: &'a mut [T], + b0: &'b [T], + b1: &'b [T], +} + +impl<'a, 'b, T> PairSlices<'a, 'b, T> { + fn from(to: &'a mut VecDeque<T>, from: &'b VecDeque<T>) -> Self { + let (a0, a1) = to.as_mut_slices(); + let (b0, b1) = from.as_slices(); + PairSlices { a0, a1, b0, b1 } + } + + fn has_remainder(&self) -> bool { + !self.b0.is_empty() + } + + fn remainder(self) -> impl Iterator<Item=&'b [T]> { + once(self.b0).chain(once(self.b1)) + } +} + +impl<'a, 'b, T> Iterator for PairSlices<'a, 'b, T> +{ + type Item = (&'a mut [T], &'b [T]); + fn next(&mut self) -> Option<Self::Item> { + // Get next part length + let part = cmp::min(self.a0.len(), self.b0.len()); + if part == 0 { + return None; + } + let (p0, p1) = replace(&mut self.a0, &mut []).split_at_mut(part); + let (q0, q1) = self.b0.split_at(part); + + // Move a1 into a0, if it's empty (and b1, b0 the same way). + self.a0 = p1; + self.b0 = q1; + if self.a0.is_empty() { + self.a0 = replace(&mut self.a1, &mut []); + } + if self.b0.is_empty() { + self.b0 = replace(&mut self.b1, &[]); + } + Some((p0, q0)) + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<T: Clone> Clone for VecDeque<T> { fn clone(&self) -> VecDeque<T> { self.iter().cloned().collect() } + + fn clone_from(&mut self, other: &Self) { + self.truncate(other.len()); + + let mut iter = PairSlices::from(self, other); + while let Some((dst, src)) = iter.next() { + dst.clone_from_slice(&src); + } + + if iter.has_remainder() { + for remainder in iter.remainder() { + self.extend(remainder.iter().cloned()); + } + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -2209,6 +2286,16 @@ impl<'a, T> Iterator for Iter<'a, T> { final_res } + fn nth(&mut self, n: usize) -> Option<Self::Item> { + if n >= count(self.tail, self.head, self.ring.len()) { + self.tail = self.head; + None + } else { + self.tail = wrap_index(self.tail.wrapping_add(n), self.ring.len()); + self.next() + } + } + #[inline] fn last(mut self) -> Option<&'a T> { self.next_back() @@ -2327,6 +2414,16 @@ impl<'a, T> Iterator for IterMut<'a, T> { back.iter_mut().fold(accum, &mut f) } + fn nth(&mut self, n: usize) -> Option<Self::Item> { + if n >= count(self.tail, self.head, self.ring.len()) { + self.tail = self.head; + None + } else { + self.tail = wrap_index(self.tail.wrapping_add(n), self.ring.len()); + self.next() + } + } + #[inline] fn last(mut self) -> Option<&'a mut T> { self.next_back() diff --git a/src/liballoc/collections/vec_deque/tests.rs b/src/liballoc/collections/vec_deque/tests.rs index d2535239979..d578ee0dac4 100644 --- a/src/liballoc/collections/vec_deque/tests.rs +++ b/src/liballoc/collections/vec_deque/tests.rs @@ -362,6 +362,29 @@ fn test_vec_from_vecdeque() { } #[test] +fn test_clone_from() { + let m = vec![1; 8]; + let n = vec![2; 12]; + for pfv in 0..8 { + for pfu in 0..8 { + for longer in 0..2 { + let (vr, ur) = if longer == 0 { (&m, &n) } else { (&n, &m) }; + let mut v = VecDeque::from(vr.clone()); + for _ in 0..pfv { + v.push_front(1); + } + let mut u = VecDeque::from(ur.clone()); + for _ in 0..pfu { + u.push_front(2); + } + v.clone_from(&u); + assert_eq!(&v, &u); + } + } + } +} + +#[test] fn issue_53529() { use crate::boxed::Box; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index e6b174beaae..3684162d8b1 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -153,7 +153,7 @@ mod boxed { #[cfg(test)] mod tests; pub mod collections; -#[cfg(all(target_has_atomic = "ptr", target_has_atomic = "cas"))] +#[cfg(target_has_atomic = "ptr")] pub mod sync; pub mod rc; pub mod raw_vec; diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index a28c6d22abb..b0651f16484 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -773,7 +773,7 @@ impl<T: Clone> Rc<T> { /// referred to as clone-on-write. /// /// If there are no other `Rc` pointers to this value, then [`Weak`] - /// pointers to this value will be dissassociated. + /// pointers to this value will be disassociated. /// /// See also [`get_mut`], which will fail rather than cloning. /// @@ -799,7 +799,7 @@ impl<T: Clone> Rc<T> { /// assert_eq!(*other_data, 12); /// ``` /// - /// [`Weak`] pointers will be dissassociated: + /// [`Weak`] pointers will be disassociated: /// /// ``` /// use std::rc::Rc; diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 85b59162620..f75b7a45443 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -2,14 +2,14 @@ //! of any `'static` type through runtime reflection. //! //! `Any` itself can be used to get a `TypeId`, and has more features when used -//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and -//! `downcast_ref` methods, to test if the contained value is of a given type, -//! and to get a reference to the inner value as a type. As `&mut Any`, there +//! as a trait object. As `&dyn Any` (a borrowed trait object), it has the `is` +//! and `downcast_ref` methods, to test if the contained value is of a given type, +//! and to get a reference to the inner value as a type. As `&mut dyn Any`, there //! is also the `downcast_mut` method, for getting a mutable reference to the -//! inner value. `Box<Any>` adds the `downcast` method, which attempts to +//! inner value. `Box<dyn Any>` adds the `downcast` method, which attempts to //! convert to a `Box<T>`. See the [`Box`] documentation for the full details. //! -//! Note that &Any is limited to testing whether a value is of a specified +//! Note that `&dyn Any` is limited to testing whether a value is of a specified //! concrete type, and cannot be used to test whether a type implements a trait. //! //! [`Box`]: ../../std/boxed/struct.Box.html diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs index a69eb0f6d4b..971d89e0044 100644 --- a/src/libcore/char/methods.rs +++ b/src/libcore/char/methods.rs @@ -116,9 +116,9 @@ impl char { // the code is split up here to improve execution speed for cases where // the `radix` is constant and 10 or smaller - let val = if radix <= 10 { + let val = if radix <= 10 { match self { - '0' ..= '9' => self as u32 - '0' as u32, + '0'..='9' => self as u32 - '0' as u32, _ => return None, } } else { @@ -130,8 +130,11 @@ impl char { } }; - if val < radix { Some(val) } - else { None } + if val < radix { + Some(val) + } else { + None + } } /// Returns an iterator that yields the hexadecimal Unicode escape of a @@ -303,8 +306,8 @@ impl char { '\r' => EscapeDefaultState::Backslash('r'), '\n' => EscapeDefaultState::Backslash('n'), '\\' | '\'' | '"' => EscapeDefaultState::Backslash(self), - '\x20' ..= '\x7e' => EscapeDefaultState::Char(self), - _ => EscapeDefaultState::Unicode(self.escape_unicode()) + '\x20'..='\x7e' => EscapeDefaultState::Char(self), + _ => EscapeDefaultState::Unicode(self.escape_unicode()), }; EscapeDefault { state: init_state } } @@ -436,30 +439,31 @@ impl char { pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str { let code = self as u32; unsafe { - let len = - if code < MAX_ONE_B && !dst.is_empty() { + let len = if code < MAX_ONE_B && !dst.is_empty() { *dst.get_unchecked_mut(0) = code as u8; 1 } else if code < MAX_TWO_B && dst.len() >= 2 { *dst.get_unchecked_mut(0) = (code >> 6 & 0x1F) as u8 | TAG_TWO_B; *dst.get_unchecked_mut(1) = (code & 0x3F) as u8 | TAG_CONT; 2 - } else if code < MAX_THREE_B && dst.len() >= 3 { + } else if code < MAX_THREE_B && dst.len() >= 3 { *dst.get_unchecked_mut(0) = (code >> 12 & 0x0F) as u8 | TAG_THREE_B; - *dst.get_unchecked_mut(1) = (code >> 6 & 0x3F) as u8 | TAG_CONT; + *dst.get_unchecked_mut(1) = (code >> 6 & 0x3F) as u8 | TAG_CONT; *dst.get_unchecked_mut(2) = (code & 0x3F) as u8 | TAG_CONT; 3 } else if dst.len() >= 4 { *dst.get_unchecked_mut(0) = (code >> 18 & 0x07) as u8 | TAG_FOUR_B; *dst.get_unchecked_mut(1) = (code >> 12 & 0x3F) as u8 | TAG_CONT; - *dst.get_unchecked_mut(2) = (code >> 6 & 0x3F) as u8 | TAG_CONT; + *dst.get_unchecked_mut(2) = (code >> 6 & 0x3F) as u8 | TAG_CONT; *dst.get_unchecked_mut(3) = (code & 0x3F) as u8 | TAG_CONT; 4 } else { - panic!("encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}", + panic!( + "encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}", from_u32_unchecked(code).len_utf8(), code, - dst.len()) + dst.len(), + ) }; from_utf8_unchecked_mut(dst.get_unchecked_mut(..len)) } @@ -515,15 +519,24 @@ impl char { *dst.get_unchecked_mut(1) = 0xDC00 | ((code as u16) & 0x3FF); slice::from_raw_parts_mut(dst.as_mut_ptr(), 2) } else { - panic!("encode_utf16: need {} units to encode U+{:X}, but the buffer has {}", + panic!( + "encode_utf16: need {} units to encode U+{:X}, but the buffer has {}", from_u32_unchecked(code).len_utf16(), code, - dst.len()) + dst.len(), + ) } } } - /// Returns `true` if this `char` is an alphabetic code point, and false if not. + /// Returns `true` if this `char` has the `Alphabetic` property. + /// + /// `Alphabetic` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and + /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`]. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt /// /// # Examples /// @@ -547,10 +560,14 @@ impl char { } } - /// Returns `true` if this `char` is lowercase. + /// Returns `true` if this `char` has the `Lowercase` property. /// - /// 'Lowercase' is defined according to the terms of the Unicode Derived Core - /// Property `Lowercase`. + /// `Lowercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and + /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`]. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt /// /// # Examples /// @@ -575,10 +592,14 @@ impl char { } } - /// Returns `true` if this `char` is uppercase. + /// Returns `true` if this `char` has the `Uppercase` property. + /// + /// `Uppercase` is described in Chapter 4 (Character Properties) of the [Unicode Standard] and + /// specified in the [Unicode Character Database][ucd] [`DerivedCoreProperties.txt`]. /// - /// 'Uppercase' is defined according to the terms of the Unicode Derived Core - /// Property `Uppercase`. + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt /// /// # Examples /// @@ -603,10 +624,12 @@ impl char { } } - /// Returns `true` if this `char` is whitespace. + /// Returns `true` if this `char` has the `White_Space` property. /// - /// 'Whitespace' is defined according to the terms of the Unicode Derived Core - /// Property `White_Space`. + /// `White_Space` is specified in the [Unicode Character Database][ucd] [`PropList.txt`]. + /// + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`PropList.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt /// /// # Examples /// @@ -630,10 +653,10 @@ impl char { } } - /// Returns `true` if this `char` is alphanumeric. + /// Returns `true` if this `char` satisfies either [`is_alphabetic()`] or [`is_numeric()`]. /// - /// 'Alphanumeric'-ness is defined in terms of the Unicode General Categories - /// `Nd`, `Nl`, `No` and the Derived Core Property `Alphabetic`. + /// [`is_alphabetic()`]: #method.is_alphabetic + /// [`is_numeric()`]: #method.is_numeric /// /// # Examples /// @@ -655,10 +678,15 @@ impl char { self.is_alphabetic() || self.is_numeric() } - /// Returns `true` if this `char` is a control code point. + /// Returns `true` if this `char` has the general category for control codes. + /// + /// Control codes (code points with the general category of `Cc`) are described in Chapter 4 + /// (Character Properties) of the [Unicode Standard] and specified in the [Unicode Character + /// Database][ucd] [`UnicodeData.txt`]. /// - /// 'Control code point' is defined in terms of the Unicode General - /// Category `Cc`. + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt /// /// # Examples /// @@ -675,19 +703,29 @@ impl char { general_category::Cc(self) } - /// Returns `true` if this `char` is an extended grapheme character. + /// Returns `true` if this `char` has the `Grapheme_Extend` property. /// - /// 'Extended grapheme character' is defined in terms of the Unicode Shaping and Rendering - /// Category `Grapheme_Extend`. + /// `Grapheme_Extend` is described in [Unicode Standard Annex #29 (Unicode Text + /// Segmentation)][uax29] and specified in the [Unicode Character Database][ucd] + /// [`DerivedCoreProperties.txt`]. + /// + /// [uax29]: https://www.unicode.org/reports/tr29/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt #[inline] pub(crate) fn is_grapheme_extended(self) -> bool { derived_property::Grapheme_Extend(self) } - /// Returns `true` if this `char` is numeric. + /// Returns `true` if this `char` has one of the general categories for numbers. + /// + /// The general categories for numbers (`Nd` for decimal digits, `Nl` for letter-like numeric + /// characters, and `No` for other numeric characters) are specified in the [Unicode Character + /// Database][ucd] [`UnicodeData.txt`]. /// - /// 'Numeric'-ness is defined in terms of the Unicode General Categories - /// `Nd`, `Nl`, `No`. + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt /// /// # Examples /// @@ -713,25 +751,29 @@ impl char { } } - /// Returns an iterator that yields the lowercase equivalent of a `char` - /// as one or more `char`s. + /// Returns an iterator that yields the lowercase mapping of this `char` as one or more + /// `char`s. /// - /// If a character does not have a lowercase equivalent, the same character - /// will be returned back by the iterator. + /// If this `char` does not have a lowercase mapping, the iterator yields the same `char`. /// - /// This performs complex unconditional mappings with no tailoring: it maps - /// one Unicode character to its lowercase equivalent according to the - /// [Unicode database] and the additional complex mappings - /// [`SpecialCasing.txt`]. Conditional mappings (based on context or - /// language) are not considered here. + /// If this `char` has a one-to-one lowercase mapping given by the [Unicode Character + /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`. /// - /// For a full reference, see [here][reference]. + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt /// - /// [Unicode database]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt + /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields + /// the `char`(s) given by [`SpecialCasing.txt`]. /// - /// [`SpecialCasing.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt + /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt /// - /// [reference]: http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 + /// This operation performs an unconditional mapping without tailoring. That is, the conversion + /// is independent of context and language. + /// + /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in + /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion. + /// + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ /// /// # Examples /// @@ -774,25 +816,29 @@ impl char { ToLowercase(CaseMappingIter::new(conversions::to_lower(self))) } - /// Returns an iterator that yields the uppercase equivalent of a `char` - /// as one or more `char`s. + /// Returns an iterator that yields the uppercase mapping of this `char` as one or more + /// `char`s. + /// + /// If this `char` does not have a uppercase mapping, the iterator yields the same `char`. + /// + /// If this `char` has a one-to-one uppercase mapping given by the [Unicode Character + /// Database][ucd] [`UnicodeData.txt`], the iterator yields that `char`. /// - /// If a character does not have an uppercase equivalent, the same character - /// will be returned back by the iterator. + /// [ucd]: https://www.unicode.org/reports/tr44/ + /// [`UnicodeData.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt /// - /// This performs complex unconditional mappings with no tailoring: it maps - /// one Unicode character to its uppercase equivalent according to the - /// [Unicode database] and the additional complex mappings - /// [`SpecialCasing.txt`]. Conditional mappings (based on context or - /// language) are not considered here. + /// If this `char` requires special considerations (e.g. multiple `char`s) the iterator yields + /// the `char`(s) given by [`SpecialCasing.txt`]. /// - /// For a full reference, see [here][reference]. + /// [`SpecialCasing.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/SpecialCasing.txt /// - /// [Unicode database]: ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt + /// This operation performs an unconditional mapping without tailoring. That is, the conversion + /// is independent of context and language. /// - /// [`SpecialCasing.txt`]: ftp://ftp.unicode.org/Public/UNIDATA/SpecialCasing.txt + /// In the [Unicode Standard], Chapter 4 (Character Properties) discusses case mapping in + /// general and Chapter 3 (Conformance) discusses the default algorithm for case conversion. /// - /// [reference]: http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 + /// [Unicode Standard]: https://www.unicode.org/versions/latest/ /// /// # Examples /// diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index ebde82de834..998c8f81652 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1058,7 +1058,7 @@ $EndFeature, " #[inline] pub fn saturating_mul(self, rhs: Self) -> Self { self.checked_mul(rhs).unwrap_or_else(|| { - if (self < 0 && rhs < 0) || (self > 0 && rhs > 0) { + if (self < 0) == (rhs < 0) { Self::max_value() } else { Self::min_value() diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index c9ccef972c2..73d5abf1aed 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -18,11 +18,11 @@ //! //! Each method takes an [`Ordering`] which represents the strength of //! the memory barrier for that operation. These orderings are the -//! same as [LLVM atomic orderings][1]. For more information see the [nomicon][2]. +//! same as the [C++20 atomic orderings][1]. For more information see the [nomicon][2]. //! //! [`Ordering`]: enum.Ordering.html //! -//! [1]: https://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations +//! [1]: https://en.cppreference.com/w/cpp/atomic/memory_order //! [2]: ../../../nomicon/atomics.html //! //! Atomic variables are safe to share between threads (they implement [`Sync`]) @@ -113,8 +113,8 @@ //! ``` #![stable(feature = "rust1", since = "1.0.0")] -#![cfg_attr(not(target_has_atomic = "8"), allow(dead_code))] -#![cfg_attr(not(target_has_atomic = "8"), allow(unused_imports))] +#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))] +#![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))] use self::Ordering::*; @@ -160,14 +160,14 @@ pub fn spin_loop_hint() { /// This type has the same in-memory representation as a [`bool`]. /// /// [`bool`]: ../../../std/primitive.bool.html -#[cfg(target_has_atomic = "8")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] #[stable(feature = "rust1", since = "1.0.0")] #[repr(C, align(1))] pub struct AtomicBool { v: UnsafeCell<u8>, } -#[cfg(target_has_atomic = "8")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] #[stable(feature = "rust1", since = "1.0.0")] impl Default for AtomicBool { /// Creates an `AtomicBool` initialized to `false`. @@ -177,14 +177,14 @@ impl Default for AtomicBool { } // Send is implicitly implemented for AtomicBool. -#[cfg(target_has_atomic = "8")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] #[stable(feature = "rust1", since = "1.0.0")] unsafe impl Sync for AtomicBool {} /// A raw pointer type which can be safely shared between threads. /// /// This type has the same in-memory representation as a `*mut T`. -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(target_pointer_width = "16", repr(C, align(2)))] #[cfg_attr(target_pointer_width = "32", repr(C, align(4)))] @@ -193,7 +193,7 @@ pub struct AtomicPtr<T> { p: UnsafeCell<*mut T>, } -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[stable(feature = "rust1", since = "1.0.0")] impl<T> Default for AtomicPtr<T> { /// Creates a null `AtomicPtr<T>`. @@ -202,10 +202,10 @@ impl<T> Default for AtomicPtr<T> { } } -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<T> Send for AtomicPtr<T> {} -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[stable(feature = "rust1", since = "1.0.0")] unsafe impl<T> Sync for AtomicPtr<T> {} @@ -217,8 +217,8 @@ unsafe impl<T> Sync for AtomicPtr<T> {} /// operations synchronize other memory while additionally preserving a total order of such /// operations across all threads. /// -/// Rust's memory orderings are [the same as -/// LLVM's](https://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations). +/// Rust's memory orderings are [the same as those of +/// C++20](https://en.cppreference.com/w/cpp/atomic/memory_order). /// /// For more information see the [nomicon]. /// @@ -231,9 +231,9 @@ unsafe impl<T> Sync for AtomicPtr<T> {} pub enum Ordering { /// No ordering constraints, only atomic operations. /// - /// Corresponds to LLVM's [`Monotonic`] ordering. + /// Corresponds to [`memory_order_relaxed`] in C++20. /// - /// [`Monotonic`]: https://llvm.org/docs/Atomics.html#monotonic + /// [`memory_order_relaxed`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Relaxed_ordering #[stable(feature = "rust1", since = "1.0.0")] Relaxed, /// When coupled with a store, all previous operations become ordered @@ -246,11 +246,12 @@ pub enum Ordering { /// /// This ordering is only applicable for operations that can perform a store. /// - /// Corresponds to LLVM's [`Release`] ordering. + /// Corresponds to [`memory_order_release`] in C++20. /// - /// [`Release`]: https://llvm.org/docs/Atomics.html#release - /// [`Acquire`]: https://llvm.org/docs/Atomics.html#acquire - /// [`Relaxed`]: https://llvm.org/docs/Atomics.html#monotonic + /// [`Release`]: #variant.Release + /// [`Acquire`]: #variant.Acquire + /// [`Relaxed`]: #variant.Relaxed + /// [`memory_order_release`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering #[stable(feature = "rust1", since = "1.0.0")] Release, /// When coupled with a load, if the loaded value was written by a store operation with @@ -263,11 +264,12 @@ pub enum Ordering { /// /// This ordering is only applicable for operations that can perform a load. /// - /// Corresponds to LLVM's [`Acquire`] ordering. + /// Corresponds to [`memory_order_acquire`] in C++20. /// - /// [`Acquire`]: https://llvm.org/docs/Atomics.html#acquire - /// [`Release`]: https://llvm.org/docs/Atomics.html#release - /// [`Relaxed`]: https://llvm.org/docs/Atomics.html#monotonic + /// [`Acquire`]: #variant.Acquire + /// [`Release`]: #variant.Release + /// [`Relaxed`]: #variant.Relaxed + /// [`memory_order_acquire`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering #[stable(feature = "rust1", since = "1.0.0")] Acquire, /// Has the effects of both [`Acquire`] and [`Release`] together: @@ -275,28 +277,28 @@ pub enum Ordering { /// /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up /// not performing any store and hence it has just [`Acquire`] ordering. However, - /// [`AcqRel`][`AcquireRelease`] will never perform [`Relaxed`] accesses. + /// `AcqRel` will never perform [`Relaxed`] accesses. /// /// This ordering is only applicable for operations that combine both loads and stores. /// - /// Corresponds to LLVM's [`AcquireRelease`] ordering. + /// Corresponds to [`memory_order_acq_rel`] in C++20. /// - /// [`AcquireRelease`]: https://llvm.org/docs/Atomics.html#acquirerelease - /// [`Acquire`]: https://llvm.org/docs/Atomics.html#acquire - /// [`Release`]: https://llvm.org/docs/Atomics.html#release - /// [`Relaxed`]: https://llvm.org/docs/Atomics.html#monotonic + /// [`memory_order_acq_rel`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release-Acquire_ordering + /// [`Acquire`]: #variant.Acquire + /// [`Release`]: #variant.Release + /// [`Relaxed`]: #variant.Relaxed #[stable(feature = "rust1", since = "1.0.0")] AcqRel, /// Like [`Acquire`]/[`Release`]/[`AcqRel`] (for load, store, and load-with-store /// operations, respectively) with the additional guarantee that all threads see all /// sequentially consistent operations in the same order. /// - /// Corresponds to LLVM's [`SequentiallyConsistent`] ordering. + /// Corresponds to [`memory_order_seq_cst`] in C++20. /// - /// [`SequentiallyConsistent`]: https://llvm.org/docs/Atomics.html#sequentiallyconsistent - /// [`Acquire`]: https://llvm.org/docs/Atomics.html#acquire - /// [`Release`]: https://llvm.org/docs/Atomics.html#release - /// [`AcqRel`]: https://llvm.org/docs/Atomics.html#acquirerelease + /// [`memory_order_seq_cst`]: https://en.cppreference.com/w/cpp/atomic/memory_order#Sequentially-consistent_ordering + /// [`Acquire`]: #variant.Acquire + /// [`Release`]: #variant.Release + /// [`AcqRel`]: #variant.AcqRel #[stable(feature = "rust1", since = "1.0.0")] SeqCst, } @@ -304,7 +306,7 @@ pub enum Ordering { /// An [`AtomicBool`] initialized to `false`. /// /// [`AtomicBool`]: struct.AtomicBool.html -#[cfg(target_has_atomic = "8")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_deprecated( since = "1.34.0", @@ -313,7 +315,7 @@ pub enum Ordering { )] pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false); -#[cfg(target_has_atomic = "8")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] impl AtomicBool { /// Creates a new `AtomicBool`. /// @@ -462,7 +464,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "8")] pub fn swap(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 } } @@ -500,7 +502,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "8")] pub fn compare_and_swap(&self, current: bool, new: bool, order: Ordering) -> bool { match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { Ok(x) => x, @@ -551,7 +553,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "8")] pub fn compare_exchange(&self, current: bool, new: bool, @@ -607,7 +609,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "8")] pub fn compare_exchange_weak(&self, current: bool, new: bool, @@ -658,7 +660,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "8")] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } } @@ -700,7 +702,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "8")] pub fn fetch_nand(&self, val: bool, order: Ordering) -> bool { // We can't use atomic_nand here because it can result in a bool with // an invalid value. This happens because the atomic operation is done @@ -753,7 +755,7 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "8")] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } } @@ -794,13 +796,13 @@ impl AtomicBool { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "8")] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } } } -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] impl<T> AtomicPtr<T> { /// Creates a new `AtomicPtr`. /// @@ -951,7 +953,7 @@ impl<T> AtomicPtr<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "ptr")] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T } } @@ -987,7 +989,7 @@ impl<T> AtomicPtr<T> { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "ptr")] pub fn compare_and_swap(&self, current: *mut T, new: *mut T, order: Ordering) -> *mut T { match self.compare_exchange(current, new, order, strongest_failure_ordering(order)) { Ok(x) => x, @@ -1029,7 +1031,7 @@ impl<T> AtomicPtr<T> { /// ``` #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "ptr")] pub fn compare_exchange(&self, current: *mut T, new: *mut T, @@ -1089,7 +1091,7 @@ impl<T> AtomicPtr<T> { /// ``` #[inline] #[stable(feature = "extended_compare_and_swap", since = "1.10.0")] - #[cfg(target_has_atomic = "cas")] + #[cfg(target_has_atomic = "ptr")] pub fn compare_exchange_weak(&self, current: *mut T, new: *mut T, @@ -1110,7 +1112,7 @@ impl<T> AtomicPtr<T> { } } -#[cfg(target_has_atomic = "8")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] #[stable(feature = "atomic_bool_from", since = "1.24.0")] impl From<bool> for AtomicBool { /// Converts a `bool` into an `AtomicBool`. @@ -1126,16 +1128,17 @@ impl From<bool> for AtomicBool { fn from(b: bool) -> Self { Self::new(b) } } -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[stable(feature = "atomic_from", since = "1.23.0")] impl<T> From<*mut T> for AtomicPtr<T> { #[inline] fn from(p: *mut T) -> Self { Self::new(p) } } -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] macro_rules! atomic_int { - ($stable:meta, + ($cfg_cas:meta, + $stable:meta, $stable_cxchg:meta, $stable_debug:meta, $stable_access:meta, @@ -1356,7 +1359,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); ```"), #[inline] #[$stable] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { atomic_swap(self.v.get(), val, order) } } @@ -1396,7 +1399,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); ```"), #[inline] #[$stable] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn compare_and_swap(&self, current: $int_type, new: $int_type, @@ -1454,7 +1457,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); ```"), #[inline] #[$stable_cxchg] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn compare_exchange(&self, current: $int_type, new: $int_type, @@ -1506,7 +1509,7 @@ loop { ```"), #[inline] #[$stable_cxchg] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn compare_exchange_weak(&self, current: $int_type, new: $int_type, @@ -1544,7 +1547,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); ```"), #[inline] #[$stable] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { atomic_add(self.v.get(), val, order) } } @@ -1576,7 +1579,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); ```"), #[inline] #[$stable] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { atomic_sub(self.v.get(), val, order) } } @@ -1611,7 +1614,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b100001); ```"), #[inline] #[$stable] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { atomic_and(self.v.get(), val, order) } } @@ -1647,7 +1650,7 @@ assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31)); ```"), #[inline] #[$stable_nand] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { atomic_nand(self.v.get(), val, order) } } @@ -1682,7 +1685,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b111111); ```"), #[inline] #[$stable] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { atomic_or(self.v.get(), val, order) } } @@ -1717,7 +1720,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110); ```"), #[inline] #[$stable] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { atomic_xor(self.v.get(), val, order) } } @@ -1767,7 +1770,7 @@ assert_eq!(x.load(Ordering::SeqCst), 9); #[unstable(feature = "no_more_cas", reason = "no more CAS loops in user code", issue = "48655")] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn fetch_update<F>(&self, mut f: F, fetch_order: Ordering, @@ -1828,7 +1831,7 @@ assert!(max_foo == 42); #[unstable(feature = "atomic_min_max", reason = "easier and faster min/max than writing manual CAS loop", issue = "48655")] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { $max_fn(self.v.get(), val, order) } } @@ -1880,7 +1883,7 @@ assert_eq!(min_foo, 12); #[unstable(feature = "atomic_min_max", reason = "easier and faster min/max than writing manual CAS loop", issue = "48655")] - #[cfg(target_has_atomic = "cas")] + #[$cfg_cas] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { unsafe { $min_fn(self.v.get(), val, order) } } @@ -1890,8 +1893,9 @@ assert_eq!(min_foo, 12); } } -#[cfg(target_has_atomic = "8")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] atomic_int! { + cfg(target_has_atomic = "8"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -1906,8 +1910,9 @@ atomic_int! { "AtomicI8::new(0)", i8 AtomicI8 ATOMIC_I8_INIT } -#[cfg(target_has_atomic = "8")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] atomic_int! { + cfg(target_has_atomic = "8"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -1922,8 +1927,9 @@ atomic_int! { "AtomicU8::new(0)", u8 AtomicU8 ATOMIC_U8_INIT } -#[cfg(target_has_atomic = "16")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "16"))] atomic_int! { + cfg(target_has_atomic = "16"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -1938,8 +1944,9 @@ atomic_int! { "AtomicI16::new(0)", i16 AtomicI16 ATOMIC_I16_INIT } -#[cfg(target_has_atomic = "16")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "16"))] atomic_int! { + cfg(target_has_atomic = "16"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -1954,8 +1961,9 @@ atomic_int! { "AtomicU16::new(0)", u16 AtomicU16 ATOMIC_U16_INIT } -#[cfg(target_has_atomic = "32")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "32"))] atomic_int! { + cfg(target_has_atomic = "32"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -1970,8 +1978,9 @@ atomic_int! { "AtomicI32::new(0)", i32 AtomicI32 ATOMIC_I32_INIT } -#[cfg(target_has_atomic = "32")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "32"))] atomic_int! { + cfg(target_has_atomic = "32"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -1986,8 +1995,12 @@ atomic_int! { "AtomicU32::new(0)", u32 AtomicU32 ATOMIC_U32_INIT } -#[cfg(target_has_atomic = "64")] +#[cfg(any( + all(bootstrap, target_has_atomic = "64"), + target_has_atomic_load_store = "64" +))] atomic_int! { + cfg(target_has_atomic = "64"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -2002,8 +2015,12 @@ atomic_int! { "AtomicI64::new(0)", i64 AtomicI64 ATOMIC_I64_INIT } -#[cfg(target_has_atomic = "64")] +#[cfg(any( + all(bootstrap, target_has_atomic = "64"), + target_has_atomic_load_store = "64" +))] atomic_int! { + cfg(target_has_atomic = "64"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), stable(feature = "integer_atomics_stable", since = "1.34.0"), @@ -2018,8 +2035,9 @@ atomic_int! { "AtomicU64::new(0)", u64 AtomicU64 ATOMIC_U64_INIT } -#[cfg(target_has_atomic = "128")] +#[cfg(target_has_atomic_load_store = "128")] atomic_int! { + cfg(target_has_atomic = "128"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), @@ -2034,8 +2052,9 @@ atomic_int! { "AtomicI128::new(0)", i128 AtomicI128 ATOMIC_I128_INIT } -#[cfg(target_has_atomic = "128")] +#[cfg(target_has_atomic_load_store = "128")] atomic_int! { + cfg(target_has_atomic = "128"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), @@ -2050,20 +2069,24 @@ atomic_int! { "AtomicU128::new(0)", u128 AtomicU128 ATOMIC_U128_INIT } +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[cfg(target_pointer_width = "16")] macro_rules! ptr_width { () => { 2 } } +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[cfg(target_pointer_width = "32")] macro_rules! ptr_width { () => { 4 } } +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[cfg(target_pointer_width = "64")] macro_rules! ptr_width { () => { 8 } } -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] atomic_int!{ + cfg(target_has_atomic = "ptr"), stable(feature = "rust1", since = "1.0.0"), stable(feature = "extended_compare_and_swap", since = "1.10.0"), stable(feature = "atomic_debug", since = "1.3.0"), @@ -2078,8 +2101,9 @@ atomic_int!{ "AtomicIsize::new(0)", isize AtomicIsize ATOMIC_ISIZE_INIT } -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] atomic_int!{ + cfg(target_has_atomic = "ptr"), stable(feature = "rust1", since = "1.0.0"), stable(feature = "extended_compare_and_swap", since = "1.10.0"), stable(feature = "atomic_debug", since = "1.3.0"), @@ -2096,7 +2120,7 @@ atomic_int!{ } #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] fn strongest_failure_ordering(order: Ordering) -> Ordering { match order { Release => Relaxed, @@ -2130,7 +2154,7 @@ unsafe fn atomic_load<T>(dst: *const T, order: Ordering) -> T { } #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_xchg_acq(dst, val), @@ -2143,7 +2167,7 @@ unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T { /// Returns the previous value (like __sync_fetch_and_add). #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_xadd_acq(dst, val), @@ -2156,7 +2180,7 @@ unsafe fn atomic_add<T>(dst: *mut T, val: T, order: Ordering) -> T { /// Returns the previous value (like __sync_fetch_and_sub). #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_xsub_acq(dst, val), @@ -2168,7 +2192,7 @@ unsafe fn atomic_sub<T>(dst: *mut T, val: T, order: Ordering) -> T { } #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_compare_exchange<T>(dst: *mut T, old: T, new: T, @@ -2193,7 +2217,7 @@ unsafe fn atomic_compare_exchange<T>(dst: *mut T, } #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T, old: T, new: T, @@ -2218,7 +2242,7 @@ unsafe fn atomic_compare_exchange_weak<T>(dst: *mut T, } #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_and_acq(dst, val), @@ -2230,7 +2254,7 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T { } #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_nand_acq(dst, val), @@ -2242,7 +2266,7 @@ unsafe fn atomic_nand<T>(dst: *mut T, val: T, order: Ordering) -> T { } #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_or_acq(dst, val), @@ -2254,7 +2278,7 @@ unsafe fn atomic_or<T>(dst: *mut T, val: T, order: Ordering) -> T { } #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_xor_acq(dst, val), @@ -2267,7 +2291,7 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T { /// returns the max value (signed comparison) #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_max<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_max_acq(dst, val), @@ -2280,7 +2304,7 @@ unsafe fn atomic_max<T>(dst: *mut T, val: T, order: Ordering) -> T { /// returns the min value (signed comparison) #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_min<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_min_acq(dst, val), @@ -2293,7 +2317,7 @@ unsafe fn atomic_min<T>(dst: *mut T, val: T, order: Ordering) -> T { /// returns the max value (signed comparison) #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_umax<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_umax_acq(dst, val), @@ -2306,7 +2330,7 @@ unsafe fn atomic_umax<T>(dst: *mut T, val: T, order: Ordering) -> T { /// returns the min value (signed comparison) #[inline] -#[cfg(target_has_atomic = "cas")] +#[cfg(target_has_atomic = "8")] unsafe fn atomic_umin<T>(dst: *mut T, val: T, order: Ordering) -> T { match order { Acquire => intrinsics::atomic_umin_acq(dst, val), @@ -2504,7 +2528,7 @@ pub fn compiler_fence(order: Ordering) { } -#[cfg(target_has_atomic = "8")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "8"))] #[stable(feature = "atomic_debug", since = "1.3.0")] impl fmt::Debug for AtomicBool { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -2512,7 +2536,7 @@ impl fmt::Debug for AtomicBool { } } -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[stable(feature = "atomic_debug", since = "1.3.0")] impl<T> fmt::Debug for AtomicPtr<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -2520,7 +2544,7 @@ impl<T> fmt::Debug for AtomicPtr<T> { } } -#[cfg(target_has_atomic = "ptr")] +#[cfg(any(bootstrap, target_has_atomic_load_store = "ptr"))] #[stable(feature = "atomic_pointer", since = "1.24.0")] impl<T> fmt::Pointer for AtomicPtr<T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 65e29364287..6f841bd2adf 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -217,7 +217,7 @@ impl fmt::Debug for Context<'_> { /// This handle encapsulates a [`RawWaker`] instance, which defines the /// executor-specific wakeup behavior. /// -/// Implements [`Clone`], [`trait@Send`], and [`trait@Sync`]. +/// Implements [`Clone`], [`Send`], and [`Sync`]. /// /// [`RawWaker`]: struct.RawWaker.html #[repr(transparent)] diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index 50b6ef57b55..3d501cacf6f 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -2005,6 +2005,24 @@ a (non-transparent) struct containing a single float, while `Grams` is a transparent wrapper around a float. This can make a difference for the ABI. "##, +E0697: r##" +A closure has been used as `static`. + +Erroneous code example: + +```compile_fail,E0697 +fn main() { + static || {}; // used as `static` +} +``` + +Closures cannot be used as `static`. They "save" the environment, +and as such a static closure would save only a static environment +which would consist only of variables with a static lifetime. Given +this it would be better to use a proper function. The easiest fix +is to remove the `static` keyword. +"##, + E0698: r##" When using generators (or async) all type variables must be bound so a generator can be constructed. @@ -2191,7 +2209,6 @@ See [RFC 2091] for details on this and other limitations. E0657, // `impl Trait` can only capture lifetimes bound at the fn level E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders - E0697, // closures cannot be static // E0707, // multiple elided lifetimes used in arguments of `async fn` E0708, // `async` non-`move` closures with parameters are not currently // supported diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index f1192c7ce10..f6068855e63 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -200,7 +200,7 @@ impl<'tcx> TyCtxt<'tcx> { { sp = param.span; } - (format!("the lifetime {} as defined on", br.name), sp) + (format!("the lifetime `{}` as defined on", br.name), sp) } ty::ReFree(ty::FreeRegion { bound_region: ty::BoundRegion::BrNamed(_, name), @@ -213,7 +213,7 @@ impl<'tcx> TyCtxt<'tcx> { { sp = param.span; } - (format!("the lifetime {} as defined on", name), sp) + (format!("the lifetime `{}` as defined on", name), sp) } ty::ReFree(ref fr) => match fr.bound_region { ty::BrAnon(idx) => ( @@ -221,7 +221,7 @@ impl<'tcx> TyCtxt<'tcx> { self.hir().span(node), ), _ => ( - format!("the lifetime {} as defined on", region), + format!("the lifetime `{}` as defined on", region), cm.def_span(self.hir().span(node)), ), }, diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 5ca474a8b1d..983e3a9922e 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -21,7 +21,8 @@ declare_lint! { declare_lint! { pub CONST_ERR, Deny, - "constant evaluation detected erroneous expression" + "constant evaluation detected erroneous expression", + report_in_external_macro: true } declare_lint! { diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 313b2a5d50a..265ac975ed7 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -386,6 +386,7 @@ impl<'tcx> CodegenUnit<'tcx> { tcx.hir().as_local_hir_id(def_id) } InstanceDef::VtableShim(..) | + InstanceDef::ReifyShim(..) | InstanceDef::Intrinsic(..) | InstanceDef::FnPtrShim(..) | InstanceDef::Virtual(..) | diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 25e68e6408d..0facf30b627 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1513,22 +1513,25 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { } for &i in &[8, 16, 32, 64, 128] { if i >= min_atomic_width && i <= max_atomic_width { - let s = i.to_string(); - ret.insert(( - sym::target_has_atomic, - Some(Symbol::intern(&s)), - )); - if &s == wordsz { + let mut insert_atomic = |s| { ret.insert(( - sym::target_has_atomic, - Some(Symbol::intern("ptr")), + sym::target_has_atomic_load_store, + Some(Symbol::intern(s)), )); + if atomic_cas { + ret.insert(( + sym::target_has_atomic, + Some(Symbol::intern(s)) + )); + } + }; + let s = i.to_string(); + insert_atomic(&s); + if &s == wordsz { + insert_atomic("ptr"); } } } - if atomic_cas { - ret.insert((sym::target_has_atomic, Some(Symbol::intern("cas")))); - } if sess.opts.debug_assertions { ret.insert((Symbol::intern("debug_assertions"), None)); } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 9d60221fa3d..fa2902e4f0e 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fingerprint::Fingerprint; use crate::lint; use crate::lint::builtin::BuiltinLintDiagnostics; -use crate::session::config::{OutputType, PrintRequest, SwitchWithOptPath}; +use crate::session::config::{OutputType, PrintRequest, Sanitizer, SwitchWithOptPath}; use crate::session::search_paths::{PathKind, SearchPath}; use crate::util::nodemap::{FxHashMap, FxHashSet}; use crate::util::common::{duration_to_secs_str, ErrorReported}; @@ -626,6 +626,14 @@ impl Session { .output_types .contains_key(&OutputType::LlvmAssembly) || self.opts.output_types.contains_key(&OutputType::Bitcode); + + // Address sanitizer and memory sanitizer use alloca name when reporting an issue. + let more_names = match self.opts.debugging_opts.sanitizer { + Some(Sanitizer::Address) => true, + Some(Sanitizer::Memory) => true, + _ => more_names, + }; + self.opts.debugging_opts.fewer_names || !more_names } diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 93a8341e746..5139c8085a5 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -1,3 +1,4 @@ +use crate::hir::CodegenFnAttrFlags; use crate::hir::Unsafety; use crate::hir::def::Namespace; use crate::hir::def_id::DefId; @@ -25,6 +26,14 @@ pub enum InstanceDef<'tcx> { /// `<T as Trait>::method` where `method` receives unsizeable `self: Self`. VtableShim(DefId), + /// `fn()` pointer where the function itself cannot be turned into a pointer. + /// + /// One example in the compiler today is functions annotated with `#[track_caller]`, which + /// must have their implicit caller location argument populated for a call. Because this is a + /// required part of the function's ABI but can't be tracked as a property of the function + /// pointer, we create a single "caller location" at the site where the function is reified. + ReifyShim(DefId), + /// `<fn() as FnTrait>::call_*` /// `DefId` is `FnTrait::call_*` FnPtrShim(DefId, Ty<'tcx>), @@ -123,6 +132,7 @@ impl<'tcx> InstanceDef<'tcx> { match *self { InstanceDef::Item(def_id) | InstanceDef::VtableShim(def_id) | + InstanceDef::ReifyShim(def_id) | InstanceDef::FnPtrShim(def_id, _) | InstanceDef::Virtual(def_id, _) | InstanceDef::Intrinsic(def_id, ) | @@ -178,6 +188,9 @@ impl<'tcx> fmt::Display for Instance<'tcx> { InstanceDef::VtableShim(_) => { write!(f, " - shim(vtable)") } + InstanceDef::ReifyShim(_) => { + write!(f, " - shim(reify)") + } InstanceDef::Intrinsic(_) => { write!(f, " - intrinsic") } @@ -290,6 +303,30 @@ impl<'tcx> Instance<'tcx> { result } + pub fn resolve_for_fn_ptr( + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + def_id: DefId, + substs: SubstsRef<'tcx>, + ) -> Option<Instance<'tcx>> { + debug!("resolve(def_id={:?}, substs={:?})", def_id, substs); + Instance::resolve(tcx, param_env, def_id, substs).map(|resolved| { + let has_track_caller = |def| tcx.codegen_fn_attrs(def).flags + .contains(CodegenFnAttrFlags::TRACK_CALLER); + + match resolved.def { + InstanceDef::Item(def_id) if has_track_caller(def_id) => { + debug!(" => fn pointer created for function with #[track_caller]"); + Instance { + def: InstanceDef::ReifyShim(def_id), + substs, + } + }, + _ => resolved, + } + }) + } + pub fn resolve_for_vtable( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index cfd859c33c2..3692caada57 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3026,6 +3026,7 @@ impl<'tcx> TyCtxt<'tcx> { self.optimized_mir(did) } ty::InstanceDef::VtableShim(..) | + ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::Intrinsic(..) | ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::Virtual(..) | diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 5aa59cc309f..8945e1a1deb 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -761,6 +761,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { Some(ty::InstanceDef::Item(def_id)), ty::InstanceDef::VtableShim(def_id) => Some(ty::InstanceDef::VtableShim(def_id)), + ty::InstanceDef::ReifyShim(def_id) => + Some(ty::InstanceDef::ReifyShim(def_id)), ty::InstanceDef::Intrinsic(def_id) => Some(ty::InstanceDef::Intrinsic(def_id)), ty::InstanceDef::FnPtrShim(def_id, ref ty) => @@ -966,6 +968,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { def: match self.def { Item(did) => Item(did.fold_with(folder)), VtableShim(did) => VtableShim(did.fold_with(folder)), + ReifyShim(did) => ReifyShim(did.fold_with(folder)), Intrinsic(did) => Intrinsic(did.fold_with(folder)), FnPtrShim(did, ty) => FnPtrShim( did.fold_with(folder), @@ -994,7 +997,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { use crate::ty::InstanceDef::*; self.substs.visit_with(visitor) || match self.def { - Item(did) | VtableShim(did) | Intrinsic(did) | Virtual(did, _) => { + Item(did) | VtableShim(did) | ReifyShim(did) | Intrinsic(did) | Virtual(did, _) => { did.visit_with(visitor) }, FnPtrShim(did, ty) | CloneShim(did, ty) => { diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 22607476021..6a36a4a50cb 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -270,23 +270,12 @@ pub fn from_fn_attrs( // optimize based on this! false } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::UNWIND) { - // If a specific #[unwind] attribute is present, use that + // If a specific #[unwind] attribute is present, use that. true } else if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_ALLOCATOR_NOUNWIND) { - // Special attribute for allocator functions, which can't unwind + // Special attribute for allocator functions, which can't unwind. false - } else if let Some(_) = id { - // rust-lang/rust#64655, rust-lang/rust#63909: to minimize - // risk associated with changing cases where nounwind - // attribute is attached, this code is deliberately mimicking - // old control flow based on whether `id` is `Some` or `None`. - // - // However, in the long term we should either: - // - fold this into final else (i.e. stop inspecting `id`) - // - or, adopt Rust PR #63909. - // - // see also Rust RFC 2753. - + } else { let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig); if sig.abi == Abi::Rust || sig.abi == Abi::RustCall { // Any Rust method (or `extern "Rust" fn` or `extern @@ -312,15 +301,6 @@ pub fn from_fn_attrs( // In either case, we mark item as explicitly nounwind. false } - } else { - // assume this can possibly unwind, avoiding the application of a - // `nounwind` attribute below. - // - // (But: See comments in previous branch. Specifically, it is - // unclear whether there is real value in the assumption this - // can unwind. The conservatism here may just be papering over - // a real problem by making some UB a bit harder to hit.) - true }); // Always annotate functions with the target-cpu they are compiled for. diff --git a/src/librustc_codegen_ssa/callee.rs b/src/librustc_codegen_ssa/callee.rs index 4744dd6302f..6ba6774cbf8 100644 --- a/src/librustc_codegen_ssa/callee.rs +++ b/src/librustc_codegen_ssa/callee.rs @@ -18,6 +18,23 @@ pub fn resolve_and_get_fn<'tcx, Cx: CodegenMethods<'tcx>>( ) } +pub fn resolve_and_get_fn_for_ptr<'tcx, + Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx> +>( + cx: &Cx, + def_id: DefId, + substs: SubstsRef<'tcx>, +) -> Cx::Value { + cx.get_fn( + ty::Instance::resolve_for_fn_ptr( + cx.tcx(), + ty::ParamEnv::reveal_all(), + def_id, + substs + ).unwrap() + ) +} + pub fn resolve_and_get_fn_for_vtable<'tcx, Cx: Backend<'tcx> + MiscMethods<'tcx> + TypeMethods<'tcx> >( diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 6ffa561f3fe..978e7218aa7 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -190,7 +190,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("reifying a fn ptr that requires const arguments"); } OperandValue::Immediate( - callee::resolve_and_get_fn(bx.cx(), def_id, substs)) + callee::resolve_and_get_fn_for_ptr(bx.cx(), def_id, substs)) } _ => { bug!("{} cannot be reified to a fn ptr", operand.layout.ty) diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 1563a27250e..ed639e8eee7 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -1396,7 +1396,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { }; let place_ty = place.ty(body, tcx).ty; + let place_ty = self.normalize(place_ty, location); let rv_ty = rv.ty(body, tcx); + let rv_ty = self.normalize(rv_ty, location); if let Err(terr) = self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category) { @@ -1672,6 +1674,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { match *destination { Some((ref dest, _target_block)) => { let dest_ty = dest.ty(body, tcx).ty; + let dest_ty = self.normalize(dest_ty, term_location); let category = match *dest { Place { base: PlaceBase::Local(RETURN_PLACE), diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 8c35342d324..ffb70180bbb 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -502,24 +502,21 @@ macro_rules! unpack { }; } -fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool { - // Not callable from C, so we can safely unwind through these - if abi == Abi::Rust || abi == Abi::RustCall { return false; } - - // Validate `#[unwind]` syntax regardless of platform-specific panic strategy +fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, _abi: Abi) -> bool { + // Validate `#[unwind]` syntax regardless of platform-specific panic strategy. let attrs = &tcx.get_attrs(fn_def_id); let unwind_attr = attr::find_unwind_attr(Some(tcx.sess.diagnostic()), attrs); - // We never unwind, so it's not relevant to stop an unwind + // We never unwind, so it's not relevant to stop an unwind. if tcx.sess.panic_strategy() != PanicStrategy::Unwind { return false; } - // We cannot add landing pads, so don't add one + // We cannot add landing pads, so don't add one. if tcx.sess.no_landing_pads() { return false; } // This is a special case: some functions have a C abi but are meant to // unwind anyway. Don't stop them. match unwind_attr { - None => false, // FIXME(#58794) + None => false, // FIXME(#58794); should be `!(abi == Abi::Rust || abi == Abi::RustCall)` Some(UnwindAttr::Allowed) => false, Some(UnwindAttr::Aborts) => true, } diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index c521b735221..9bed4fb66ea 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -62,12 +62,13 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> { fn visit_local(&mut self, loc: &'tcx hir::Local) { intravisit::walk_local(self, loc); - self.check_irrefutable(&loc.pat, match loc.source { - hir::LocalSource::Normal => "local binding", - hir::LocalSource::ForLoopDesugar => "`for` loop binding", - hir::LocalSource::AsyncFn => "async fn binding", - hir::LocalSource::AwaitDesugar => "`await` future binding", - }); + let (msg, sp) = match loc.source { + hir::LocalSource::Normal => ("local binding", Some(loc.span)), + hir::LocalSource::ForLoopDesugar => ("`for` loop binding", None), + hir::LocalSource::AsyncFn => ("async fn binding", None), + hir::LocalSource::AwaitDesugar => ("`await` future binding", None), + }; + self.check_irrefutable(&loc.pat, msg, sp); // Check legality of move bindings and `@` patterns. self.check_patterns(false, &loc.pat); @@ -77,7 +78,7 @@ impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> { intravisit::walk_body(self, body); for param in &body.params { - self.check_irrefutable(¶m.pat, "function argument"); + self.check_irrefutable(¶m.pat, "function argument", None); self.check_patterns(false, ¶m.pat); } } @@ -242,7 +243,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { }) } - fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str) { + fn check_irrefutable(&self, pat: &'tcx Pat, origin: &str, sp: Option<Span>) { let module = self.tcx.hir().get_module_parent(pat.hir_id); MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| { let mut patcx = PatCtxt::new(self.tcx, @@ -266,18 +267,35 @@ impl<'tcx> MatchVisitor<'_, 'tcx> { "refutable pattern in {}: {} not covered", origin, joined_patterns ); - match &pat.kind { + let suggest_if_let = match &pat.kind { hir::PatKind::Path(hir::QPath::Resolved(None, path)) if path.segments.len() == 1 && path.segments[0].args.is_none() => { const_not_var(&mut err, cx.tcx, pat, path); + false } _ => { err.span_label( pat.span, pattern_not_covered_label(&witnesses, &joined_patterns), ); + true + } + }; + + if let (Some(span), true) = (sp, suggest_if_let) { + err.note("`let` bindings require an \"irrefutable pattern\", like a `struct` or \ + an `enum` with only one variant"); + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { + err.span_suggestion( + span, + "you might want to use `if let` to ignore the variant that isn't matched", + format!("if {} {{ /* */ }}", &snippet[..snippet.len() - 1]), + Applicability::HasPlaceholders, + ); } + err.note("for more information, visit \ + https://doc.rust-lang.org/book/ch18-02-refutability.html"); } adt_defined_here(cx, &mut err, pattern_ty, &witnesses); diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index d120412c901..9ab347957f9 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -44,7 +44,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if self.tcx.has_attr(def_id, sym::rustc_args_required_const) { bug!("reifying a fn ptr that requires const arguments"); } - let instance = self.resolve(def_id, substs)?; + + let instance = ty::Instance::resolve_for_fn_ptr( + *self.tcx, + self.param_env, + def_id, + substs, + ).ok_or_else(|| err_inval!(TooGeneric))?; + let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?; } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index ef6b7d626e7..11c7cd0d901 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -263,6 +263,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(()) } ty::InstanceDef::VtableShim(..) | + ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::DropGlue(..) | diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 8f8df395053..ee7452d3e8b 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -721,10 +721,12 @@ fn visit_fn_use<'tcx>( output: &mut Vec<MonoItem<'tcx>>, ) { if let ty::FnDef(def_id, substs) = ty.kind { - let instance = ty::Instance::resolve(tcx, - ty::ParamEnv::reveal_all(), - def_id, - substs).unwrap(); + let resolver = if is_direct_call { + ty::Instance::resolve + } else { + ty::Instance::resolve_for_fn_ptr + }; + let instance = resolver(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap(); visit_instance_use(tcx, instance, is_direct_call, output); } } @@ -747,6 +749,7 @@ fn visit_instance_use<'tcx>( } } ty::InstanceDef::VtableShim(..) | + ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::Virtual(..) | ty::InstanceDef::DropGlue(_, None) => { // don't need to emit shim if we are calling directly. @@ -773,6 +776,7 @@ fn should_monomorphize_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx let def_id = match instance.def { ty::InstanceDef::Item(def_id) => def_id, ty::InstanceDef::VtableShim(..) | + ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::Virtual(..) | ty::InstanceDef::FnPtrShim(..) | diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 6d9dae7214c..b9d38028b72 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -339,6 +339,7 @@ fn mono_item_visibility( // These are all compiler glue and such, never exported, always hidden. InstanceDef::VtableShim(..) | + InstanceDef::ReifyShim(..) | InstanceDef::FnPtrShim(..) | InstanceDef::Virtual(..) | InstanceDef::Intrinsic(..) | @@ -677,6 +678,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( let def_id = match instance.def { ty::InstanceDef::Item(def_id) => def_id, ty::InstanceDef::VtableShim(..) | + ty::InstanceDef::ReifyShim(..) | ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::Intrinsic(..) | diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 78008e2fcd3..f532a18072f 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -66,9 +66,12 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx Some(arg_tys) ) } - ty::InstanceDef::Virtual(def_id, _) => { - // We are generating a call back to our def-id, which the - // codegen backend knows to turn to an actual virtual call. + // We are generating a call back to our def-id, which the + // codegen backend knows to turn to an actual virtual call. + ty::InstanceDef::Virtual(def_id, _) | + // ...or we are generating a direct call to a function for which indirect calls must be + // codegen'd differently than direct ones (example: #[track_caller]) + ty::InstanceDef::ReifyShim(def_id) => { build_call_shim( tcx, def_id, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ff8f7fc7aa4..e3c272e12fe 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2379,26 +2379,38 @@ impl<'a> Resolver<'a> { let mut reported_spans = FxHashSet::default(); for &PrivacyError(dedup_span, ident, binding) in &self.privacy_errors { if reported_spans.insert(dedup_span) { - let mut err = struct_span_err!( - self.session, - ident.span, - E0603, - "{} `{}` is private", - binding.res().descr(), - ident.name, - ); - if let NameBindingKind::Res( + let session = &self.session; + let mk_struct_span_error = |is_constructor| { + struct_span_err!( + session, + ident.span, + E0603, + "{}{} `{}` is private", + binding.res().descr(), + if is_constructor { " constructor"} else { "" }, + ident.name, + ) + }; + + let mut err = if let NameBindingKind::Res( Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id), _ ) = binding.kind { let def_id = (&*self).parent(ctor_def_id).expect("no parent for a constructor"); if let Some(fields) = self.field_names.get(&def_id) { + let mut err = mk_struct_span_error(true); let first_field = fields.first().expect("empty field list in the map"); err.span_label( fields.iter().fold(first_field.span, |acc, field| acc.to(field.span)), - "a tuple struct constructor is private if any of its fields is private", + "a constructor is private if any of the fields is private", ); + err + } else { + mk_struct_span_error(false) } - } + } else { + mk_struct_span_error(false) + }; + err.emit(); } } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 434ead50e04..e57cc809c34 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -213,27 +213,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { segment, ); - let mut needs_mut = false; - if let ty::Ref(region, t_type, mutability) = self_ty.kind { - let trait_type = self.tcx.mk_ref(region, ty::TypeAndMut { - ty: t_type, - mutbl: mutability.invert(), - }); - match self.lookup_probe( - span, - segment.ident, - trait_type, - call_expr, - ProbeScope::TraitsInScope - ) { - Ok(ref new_pick) if *new_pick != pick => { - needs_mut = true; + if result.illegal_sized_bound { + let mut needs_mut = false; + if let ty::Ref(region, t_type, mutability) = self_ty.kind { + let trait_type = self.tcx.mk_ref(region, ty::TypeAndMut { + ty: t_type, + mutbl: mutability.invert(), + }); + // We probe again to see if there might be a borrow mutability discrepancy. + match self.lookup_probe( + span, + segment.ident, + trait_type, + call_expr, + ProbeScope::TraitsInScope + ) { + Ok(ref new_pick) if *new_pick != pick => { + needs_mut = true; + } + _ => {} } - _ => {} } - } - if result.illegal_sized_bound { // We probe again, taking all traits into account (not only those in scope). let candidates = match self.lookup_probe( span, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 6f805a949af..05e6f36c958 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -705,6 +705,7 @@ impl Tester for Collector { // compiler failures are test failures should_panic: testing::ShouldPanic::No, allow_fail: config.allow_fail, + test_type: testing::TestType::DocTest, }, testfn: testing::DynTestFn(box move || { let res = run_test( diff --git a/src/libstd/error.rs b/src/libstd/error.rs index 4a1bb75d588..6b9a35fccc4 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -269,8 +269,8 @@ impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> { - /// Converts a type of [`Error`] + [`trait@Send`] + [`trait@Sync`] into a box of - /// dyn [`Error`] + [`trait@Send`] + [`trait@Sync`]. + /// Converts a type of [`Error`] + [`Send`] + [`Sync`] into a box of + /// dyn [`Error`] + [`Send`] + [`Sync`]. /// /// [`Error`]: ../error/trait.Error.html /// @@ -313,7 +313,7 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + #[stable(feature = "rust1", since = "1.0.0")] impl From<String> for Box<dyn Error + Send + Sync> { - /// Converts a [`String`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`]. + /// Converts a [`String`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// /// [`Error`]: ../error/trait.Error.html /// @@ -377,7 +377,7 @@ impl From<String> for Box<dyn Error> { #[stable(feature = "rust1", since = "1.0.0")] impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> { - /// Converts a [`str`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`]. + /// Converts a [`str`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// /// [`Error`]: ../error/trait.Error.html /// @@ -420,7 +420,7 @@ impl From<&str> for Box<dyn Error> { #[stable(feature = "cow_box_error", since = "1.22.0")] impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> { - /// Converts a [`Cow`] into a box of dyn [`Error`] + [`trait@Send`] + [`trait@Sync`]. + /// Converts a [`Cow`] into a box of dyn [`Error`] + [`Send`] + [`Sync`]. /// /// [`Cow`]: ../borrow/enum.Cow.html /// [`Error`]: ../error/trait.Error.html diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index d7f4cc5d1fd..483f2ba52ec 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -919,7 +919,7 @@ impl Error for IntoStringError { "C string contained non-utf8 bytes" } - fn cause(&self) -> Option<&dyn Error> { + fn source(&self) -> Option<&(dyn Error + 'static)> { Some(&self.error) } } diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 1d4fd98dd75..24c693790e8 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -12,7 +12,9 @@ use crate::ops::{Deref, DerefMut}; use crate::panicking; use crate::ptr::{Unique, NonNull}; use crate::rc::Rc; -use crate::sync::{Arc, Mutex, RwLock, atomic}; +use crate::sync::{Arc, Mutex, RwLock}; +#[cfg(not(bootstrap))] +use crate::sync::atomic; use crate::task::{Context, Poll}; use crate::thread::Result; @@ -240,49 +242,49 @@ impl<T: ?Sized> RefUnwindSafe for Mutex<T> {} #[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")] impl<T: ?Sized> RefUnwindSafe for RwLock<T> {} -#[cfg(target_has_atomic = "ptr")] +#[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] impl RefUnwindSafe for atomic::AtomicIsize {} -#[cfg(target_has_atomic = "8")] +#[cfg(target_has_atomic_load_store = "8")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicI8 {} -#[cfg(target_has_atomic = "16")] +#[cfg(target_has_atomic_load_store = "16")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicI16 {} -#[cfg(target_has_atomic = "32")] +#[cfg(target_has_atomic_load_store = "32")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicI32 {} -#[cfg(target_has_atomic = "64")] +#[cfg(target_has_atomic_load_store = "64")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicI64 {} -#[cfg(target_has_atomic = "128")] +#[cfg(target_has_atomic_load_store = "128")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicI128 {} -#[cfg(target_has_atomic = "ptr")] +#[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] impl RefUnwindSafe for atomic::AtomicUsize {} -#[cfg(target_has_atomic = "8")] +#[cfg(target_hastarget_has_atomic_load_store_atomic = "8")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicU8 {} -#[cfg(target_has_atomic = "16")] +#[cfg(target_has_atomic_load_store = "16")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicU16 {} -#[cfg(target_has_atomic = "32")] +#[cfg(target_has_atomic_load_store = "32")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicU32 {} -#[cfg(target_has_atomic = "64")] +#[cfg(target_has_atomic_load_store = "64")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicU64 {} -#[cfg(target_has_atomic = "128")] +#[cfg(target_has_atomic_load_store = "128")] #[unstable(feature = "integer_atomics", issue = "32976")] impl RefUnwindSafe for atomic::AtomicU128 {} -#[cfg(target_has_atomic = "8")] +#[cfg(target_has_atomic_load_store = "8")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] impl RefUnwindSafe for atomic::AtomicBool {} -#[cfg(target_has_atomic = "ptr")] +#[cfg(target_has_atomic_load_store = "ptr")] #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] impl<T> RefUnwindSafe for atomic::AtomicPtr<T> {} diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 69ecd201063..c2884a28f3c 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -1581,10 +1581,6 @@ impl<T: Send> error::Error for SendError<T> { fn description(&self) -> &str { "sending on a closed channel" } - - fn cause(&self) -> Option<&dyn error::Error> { - None - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1624,10 +1620,6 @@ impl<T: Send> error::Error for TrySendError<T> { } } } - - fn cause(&self) -> Option<&dyn error::Error> { - None - } } #[stable(feature = "mpsc_error_conversions", since = "1.24.0")] @@ -1652,10 +1644,6 @@ impl error::Error for RecvError { fn description(&self) -> &str { "receiving on a closed channel" } - - fn cause(&self) -> Option<&dyn error::Error> { - None - } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1685,10 +1673,6 @@ impl error::Error for TryRecvError { } } } - - fn cause(&self) -> Option<&dyn error::Error> { - None - } } #[stable(feature = "mpsc_error_conversions", since = "1.24.0")] @@ -1726,10 +1710,6 @@ impl error::Error for RecvTimeoutError { } } } - - fn cause(&self) -> Option<&dyn error::Error> { - None - } } #[stable(feature = "mpsc_error_conversions", since = "1.24.0")] diff --git a/src/libstd/sys/vxworks/fs.rs b/src/libstd/sys/vxworks/fs.rs index 51fdb1c0e55..adb08d8005a 100644 --- a/src/libstd/sys/vxworks/fs.rs +++ b/src/libstd/sys/vxworks/fs.rs @@ -400,13 +400,27 @@ impl FromInner<c_int> for File { impl fmt::Debug for File { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fn get_path(_fd: c_int) -> Option<PathBuf> { - // FIXME(#:(): implement this for VxWorks - None + fn get_path(fd: c_int) -> Option<PathBuf> { + let mut buf = vec![0;libc::PATH_MAX as usize]; + let n = unsafe { libc::ioctl(fd, libc::FIOGETNAME, buf.as_ptr()) }; + if n == -1 { + return None; + } + let l = buf.iter().position(|&c| c == 0).unwrap(); + buf.truncate(l as usize); + Some(PathBuf::from(OsString::from_vec(buf))) } - fn get_mode(_fd: c_int) -> Option<(bool, bool)> { - // FIXME(#:(): implement this for VxWorks - None + fn get_mode(fd: c_int) -> Option<(bool, bool)> { + let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) }; + if mode == -1 { + return None; + } + match mode & libc::O_ACCMODE { + libc::O_RDONLY => Some((true, false)), + libc::O_RDWR => Some((true, true)), + libc::O_WRONLY => Some((false, true)), + _ => None + } } let fd = self.0.raw(); diff --git a/src/libsyntax/ext/mbe/macro_parser.rs b/src/libsyntax/ext/mbe/macro_parser.rs index d1c50fd8594..0cb5eff1ef2 100644 --- a/src/libsyntax/ext/mbe/macro_parser.rs +++ b/src/libsyntax/ext/mbe/macro_parser.rs @@ -76,7 +76,7 @@ use TokenTreeOrTokenTreeSlice::*; use crate::ast::{Ident, Name}; use crate::ext::mbe::{self, TokenTree}; -use crate::parse::{Directory, ParseSess}; +use crate::parse::{Directory, ParseSess, PResult}; use crate::parse::parser::{Parser, PathStyle}; use crate::parse::token::{self, DocComment, Nonterminal, Token}; use crate::print::pprust; @@ -893,26 +893,30 @@ fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal { } // check at the beginning and the parser checks after each bump p.process_potential_macro_variable(); - match name { - sym::item => match panictry!(p.parse_item()) { + match parse_nt_inner(p, sp, name) { + Ok(nt) => nt, + Err(mut err) => { + err.emit(); + FatalError.raise(); + } + } +} + +fn parse_nt_inner<'a>(p: &mut Parser<'a>, sp: Span, name: Symbol) -> PResult<'a, Nonterminal> { + Ok(match name { + sym::item => match p.parse_item()? { Some(i) => token::NtItem(i), - None => { - p.fatal("expected an item keyword").emit(); - FatalError.raise(); - } + None => return Err(p.fatal("expected an item keyword")), }, - sym::block => token::NtBlock(panictry!(p.parse_block())), - sym::stmt => match panictry!(p.parse_stmt()) { + sym::block => token::NtBlock(p.parse_block()?), + sym::stmt => match p.parse_stmt()? { Some(s) => token::NtStmt(s), - None => { - p.fatal("expected a statement").emit(); - FatalError.raise(); - } + None => return Err(p.fatal("expected a statement")), }, - sym::pat => token::NtPat(panictry!(p.parse_pat(None))), - sym::expr => token::NtExpr(panictry!(p.parse_expr())), - sym::literal => token::NtLiteral(panictry!(p.parse_literal_maybe_minus())), - sym::ty => token::NtTy(panictry!(p.parse_ty())), + sym::pat => token::NtPat(p.parse_pat(None)?), + sym::expr => token::NtExpr(p.parse_expr()?), + sym::literal => token::NtLiteral(p.parse_literal_maybe_minus()?), + sym::ty => token::NtTy(p.parse_ty()?), // this could be handled like a token, since it is one sym::ident => if let Some((name, is_raw)) = get_macro_name(&p.token) { let span = p.token.span; @@ -920,21 +924,19 @@ fn parse_nt(p: &mut Parser<'_>, sp: Span, name: Symbol) -> Nonterminal { token::NtIdent(Ident::new(name, span), is_raw) } else { let token_str = pprust::token_to_string(&p.token); - p.fatal(&format!("expected ident, found {}", &token_str)).emit(); - FatalError.raise() + return Err(p.fatal(&format!("expected ident, found {}", &token_str))); } - sym::path => token::NtPath(panictry!(p.parse_path(PathStyle::Type))), - sym::meta => token::NtMeta(panictry!(p.parse_attr_item())), - sym::vis => token::NtVis(panictry!(p.parse_visibility(true))), + sym::path => token::NtPath(p.parse_path(PathStyle::Type)?), + sym::meta => token::NtMeta(p.parse_attr_item()?), + sym::vis => token::NtVis(p.parse_visibility(true)?), sym::lifetime => if p.check_lifetime() { token::NtLifetime(p.expect_lifetime().ident) } else { let token_str = pprust::token_to_string(&p.token); - p.fatal(&format!("expected a lifetime, found `{}`", &token_str)).emit(); - FatalError.raise(); + return Err(p.fatal(&format!("expected a lifetime, found `{}`", &token_str))); } // this is not supposed to happen, since it has been checked // when compiling the macro. _ => p.span_bug(sp, "invalid fragment specifier"), - } + }) } diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs index ae23cc5cb93..ab1620b9524 100644 --- a/src/libsyntax/feature_gate/builtin_attrs.rs +++ b/src/libsyntax/feature_gate/builtin_attrs.rs @@ -29,6 +29,7 @@ const GATED_CFGS: &[(Symbol, Symbol, GateFn)] = &[ // (name in cfg, feature, function to check if the feature is enabled) (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), + (sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)), (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)), ]; diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 9e40b1a26ac..6008f8f3005 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -855,25 +855,19 @@ impl UnstableFeatures { pub fn is_nightly_build(&self) -> bool { match *self { UnstableFeatures::Allow | UnstableFeatures::Cheat => true, - _ => false, + UnstableFeatures::Disallow => false, } } } fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate, unstable: UnstableFeatures) { - let allow_features = match unstable { - UnstableFeatures::Allow => true, - UnstableFeatures::Disallow => false, - UnstableFeatures::Cheat => true - }; - if !allow_features { - for attr in &krate.attrs { - if attr.check_name(sym::feature) { - let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"); - span_err!(span_handler, attr.span, E0554, - "`#![feature]` may not be used on the {} release channel", - release_channel); - } + if !unstable.is_nightly_build() { + for attr in krate.attrs.iter().filter(|attr| attr.check_name(sym::feature)) { + span_err!( + span_handler, attr.span, E0554, + "`#![feature]` may not be used on the {} release channel", + option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)") + ); } } } diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 03b00188e25..09a47795a82 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -17,6 +17,7 @@ #![feature(proc_macro_internals)] #![feature(proc_macro_span)] #![feature(try_trait)] +#![feature(slice_patterns)] #![feature(unicode_internals)] #![recursion_limit="256"] diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs index df744e403d8..0bbd67589dd 100644 --- a/src/libsyntax/parse/diagnostics.rs +++ b/src/libsyntax/parse/diagnostics.rs @@ -2,7 +2,7 @@ use crate::ast::{ self, Param, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind, Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData, }; -use crate::feature_gate::{feature_err, UnstableFeatures}; +use crate::feature_gate::feature_err; use crate::parse::{SeqSep, PResult, Parser, ParseSess}; use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType, TokenExpectType}; use crate::parse::token::{self, TokenKind}; @@ -387,14 +387,17 @@ impl<'a> Parser<'a> { let next_pos = sm.lookup_char_pos(self.token.span.lo()); let op_pos = sm.lookup_char_pos(sp.hi()); + let allow_unstable = self.sess.unstable_features.is_nightly_build(); + if likely_path { err.span_suggestion( sp, "maybe write a path separator here", "::".to_string(), - match self.sess.unstable_features { - UnstableFeatures::Disallow => Applicability::MachineApplicable, - _ => Applicability::MaybeIncorrect, + if allow_unstable { + Applicability::MaybeIncorrect + } else { + Applicability::MachineApplicable }, ); } else if op_pos.line != next_pos.line && maybe_expected_semicolon { @@ -404,14 +407,13 @@ impl<'a> Parser<'a> { ";".to_string(), Applicability::MaybeIncorrect, ); - } else if let UnstableFeatures::Disallow = self.sess.unstable_features { - err.span_label(sp, "tried to parse a type due to this"); - } else { + } else if allow_unstable { err.span_label(sp, "tried to parse a type due to this type ascription"); + } else { + err.span_label(sp, "tried to parse a type due to this"); } - if let UnstableFeatures::Disallow = self.sess.unstable_features { + if allow_unstable { // Give extra information about type ascription only if it's a nightly compiler. - } else { err.note("`#![feature(type_ascription)]` lets you annotate an expression with a \ type: `<expr>: <type>`"); err.note("for more information, see \ diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs index fcd5b2782fd..56a79bfe5d5 100644 --- a/src/libsyntax/parse/literal.rs +++ b/src/libsyntax/parse/literal.rs @@ -426,15 +426,12 @@ fn integer_lit(symbol: Symbol, suffix: Option<Symbol>) -> Result<LitKind, LitErr let symbol = strip_underscores(symbol); let s = symbol.as_str(); - let mut base = 10; - if s.len() > 1 && s.as_bytes()[0] == b'0' { - match s.as_bytes()[1] { - b'x' => base = 16, - b'o' => base = 8, - b'b' => base = 2, - _ => {} - } - } + let base = match s.as_bytes() { + [b'0', b'x', ..] => 16, + [b'0', b'o', ..] => 8, + [b'0', b'b', ..] => 2, + _ => 10, + }; let ty = match suffix { Some(suf) => match suf { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a19380657fd..400bf0f3856 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -9,20 +9,19 @@ mod path; pub use path::PathStyle; mod stmt; mod generics; +use super::diagnostics::Error; use crate::ast::{ - self, DUMMY_NODE_ID, AttrStyle, Attribute, BindingMode, CrateSugar, Ident, - IsAsync, MacDelimiter, Mutability, Param, StrStyle, SelfKind, TyKind, Visibility, - VisibilityKind, Unsafety, + self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Ident, + IsAsync, MacDelimiter, Mutability, StrStyle, Visibility, VisibilityKind, Unsafety, }; use crate::parse::{ParseSess, PResult, Directory, DirectoryOwnership, SeqSep, literal, token}; -use crate::parse::diagnostics::{Error, dummy_arg}; use crate::parse::lexer::UnmatchedBrace; use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; use crate::parse::token::{Token, TokenKind, DelimToken}; use crate::print::pprust; use crate::ptr::P; -use crate::source_map::{self, respan}; +use crate::source_map::respan; use crate::symbol::{kw, sym, Symbol}; use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint}; use crate::ThinVec; @@ -56,17 +55,6 @@ crate enum BlockMode { Ignore, } -/// The parsing configuration used to parse a parameter list (see `parse_fn_params`). -struct ParamCfg { - /// Is `self` is allowed as the first parameter? - is_self_allowed: bool, - /// Is `...` allowed as the tail of the parameter list? - allow_c_variadic: bool, - /// `is_name_required` decides if, per-parameter, - /// the parameter must have a pattern or just a type. - is_name_required: fn(&token::Token) -> bool, -} - /// Like `maybe_whole_expr`, but for things other than expressions. #[macro_export] macro_rules! maybe_whole { @@ -1105,271 +1093,6 @@ impl<'a> Parser<'a> { res } - /// Parses the parameter list of a function, including the `(` and `)` delimiters. - fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec<Param>> { - let sp = self.token.span; - let is_trait_item = cfg.is_self_allowed; - let mut c_variadic = false; - // Parse the arguments, starting out with `self` being possibly allowed... - let (params, _) = self.parse_paren_comma_seq(|p| { - let param = p.parse_param_general(&cfg, is_trait_item); - // ...now that we've parsed the first argument, `self` is no longer allowed. - cfg.is_self_allowed = false; - - match param { - Ok(param) => Ok( - if let TyKind::CVarArgs = param.ty.kind { - c_variadic = true; - if p.token != token::CloseDelim(token::Paren) { - p.span_err( - p.token.span, - "`...` must be the last argument of a C-variadic function", - ); - // FIXME(eddyb) this should probably still push `CVarArgs`. - // Maybe AST validation/HIR lowering should emit the above error? - None - } else { - Some(param) - } - } else { - Some(param) - } - ), - Err(mut e) => { - e.emit(); - let lo = p.prev_span; - // Skip every token until next possible arg or end. - p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]); - // Create a placeholder argument for proper arg count (issue #34264). - let span = lo.to(p.prev_span); - Ok(Some(dummy_arg(Ident::new(kw::Invalid, span)))) - } - } - })?; - - let mut params: Vec<_> = params.into_iter().filter_map(|x| x).collect(); - - // Replace duplicated recovered params with `_` pattern to avoid unecessary errors. - self.deduplicate_recovered_params_names(&mut params); - - if c_variadic && params.len() <= 1 { - self.span_err( - sp, - "C-variadic function must be declared with at least one named argument", - ); - } - - Ok(params) - } - - /// Skips unexpected attributes and doc comments in this position and emits an appropriate - /// error. - /// This version of parse param doesn't necessarily require identifier names. - fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> { - let lo = self.token.span; - let attrs = self.parse_outer_attributes()?; - - // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here. - if let Some(mut param) = self.parse_self_param()? { - param.attrs = attrs.into(); - return if cfg.is_self_allowed { - Ok(param) - } else { - self.recover_bad_self_param(param, is_trait_item) - }; - } - - let is_name_required = match self.token.kind { - token::DotDotDot => false, - _ => (cfg.is_name_required)(&self.token), - }; - let (pat, ty) = if is_name_required || self.is_named_param() { - debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required); - - let pat = self.parse_fn_param_pat()?; - if let Err(mut err) = self.expect(&token::Colon) { - return if let Some(ident) = self.parameter_without_type( - &mut err, - pat, - is_name_required, - cfg.is_self_allowed, - is_trait_item, - ) { - err.emit(); - Ok(dummy_arg(ident)) - } else { - Err(err) - }; - } - - self.eat_incorrect_doc_comment_for_param_type(); - (pat, self.parse_ty_common(true, true, cfg.allow_c_variadic)?) - } else { - debug!("parse_param_general ident_to_pat"); - let parser_snapshot_before_ty = self.clone(); - self.eat_incorrect_doc_comment_for_param_type(); - let mut ty = self.parse_ty_common(true, true, cfg.allow_c_variadic); - if ty.is_ok() && self.token != token::Comma && - self.token != token::CloseDelim(token::Paren) { - // This wasn't actually a type, but a pattern looking like a type, - // so we are going to rollback and re-parse for recovery. - ty = self.unexpected(); - } - match ty { - Ok(ty) => { - let ident = Ident::new(kw::Invalid, self.prev_span); - let bm = BindingMode::ByValue(Mutability::Immutable); - let pat = self.mk_pat_ident(ty.span, bm, ident); - (pat, ty) - } - // If this is a C-variadic argument and we hit an error, return the error. - Err(err) if self.token == token::DotDotDot => return Err(err), - // Recover from attempting to parse the argument as a type without pattern. - Err(mut err) => { - err.cancel(); - mem::replace(self, parser_snapshot_before_ty); - self.recover_arg_parse()? - } - } - }; - - let span = lo.to(self.token.span); - - Ok(Param { - attrs: attrs.into(), - id: ast::DUMMY_NODE_ID, - is_placeholder: false, - pat, - span, - ty, - }) - } - - /// Returns the parsed optional self parameter and whether a self shortcut was used. - /// - /// See `parse_self_param_with_attrs` to collect attributes. - fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> { - // Extract an identifier *after* having confirmed that the token is one. - let expect_self_ident = |this: &mut Self| { - match this.token.kind { - // Preserve hygienic context. - token::Ident(name, _) => { - let span = this.token.span; - this.bump(); - Ident::new(name, span) - } - _ => unreachable!(), - } - }; - // Is `self` `n` tokens ahead? - let is_isolated_self = |this: &Self, n| { - this.is_keyword_ahead(n, &[kw::SelfLower]) - && this.look_ahead(n + 1, |t| t != &token::ModSep) - }; - // Is `mut self` `n` tokens ahead? - let is_isolated_mut_self = |this: &Self, n| { - this.is_keyword_ahead(n, &[kw::Mut]) - && is_isolated_self(this, n + 1) - }; - // Parse `self` or `self: TYPE`. We already know the current token is `self`. - let parse_self_possibly_typed = |this: &mut Self, m| { - let eself_ident = expect_self_ident(this); - let eself_hi = this.prev_span; - let eself = if this.eat(&token::Colon) { - SelfKind::Explicit(this.parse_ty()?, m) - } else { - SelfKind::Value(m) - }; - Ok((eself, eself_ident, eself_hi)) - }; - // Recover for the grammar `*self`, `*const self`, and `*mut self`. - let recover_self_ptr = |this: &mut Self| { - let msg = "cannot pass `self` by raw pointer"; - let span = this.token.span; - this.struct_span_err(span, msg) - .span_label(span, msg) - .emit(); - - Ok((SelfKind::Value(Mutability::Immutable), expect_self_ident(this), this.prev_span)) - }; - - // Parse optional `self` parameter of a method. - // Only a limited set of initial token sequences is considered `self` parameters; anything - // else is parsed as a normal function parameter list, so some lookahead is required. - let eself_lo = self.token.span; - let (eself, eself_ident, eself_hi) = match self.token.kind { - token::BinOp(token::And) => { - let eself = if is_isolated_self(self, 1) { - // `&self` - self.bump(); - SelfKind::Region(None, Mutability::Immutable) - } else if is_isolated_mut_self(self, 1) { - // `&mut self` - self.bump(); - self.bump(); - SelfKind::Region(None, Mutability::Mutable) - } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) { - // `&'lt self` - self.bump(); - let lt = self.expect_lifetime(); - SelfKind::Region(Some(lt), Mutability::Immutable) - } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) { - // `&'lt mut self` - self.bump(); - let lt = self.expect_lifetime(); - self.bump(); - SelfKind::Region(Some(lt), Mutability::Mutable) - } else { - // `¬_self` - return Ok(None); - }; - (eself, expect_self_ident(self), self.prev_span) - } - // `*self` - token::BinOp(token::Star) if is_isolated_self(self, 1) => { - self.bump(); - recover_self_ptr(self)? - } - // `*mut self` and `*const self` - token::BinOp(token::Star) if - self.look_ahead(1, |t| t.is_mutability()) - && is_isolated_self(self, 2) => - { - self.bump(); - self.bump(); - recover_self_ptr(self)? - } - // `self` and `self: TYPE` - token::Ident(..) if is_isolated_self(self, 0) => { - parse_self_possibly_typed(self, Mutability::Immutable)? - } - // `mut self` and `mut self: TYPE` - token::Ident(..) if is_isolated_mut_self(self, 0) => { - self.bump(); - parse_self_possibly_typed(self, Mutability::Mutable)? - } - _ => return Ok(None), - }; - - let eself = source_map::respan(eself_lo.to(eself_hi), eself); - Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident))) - } - - fn is_named_param(&self) -> bool { - let offset = match self.token.kind { - token::Interpolated(ref nt) => match **nt { - token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon), - _ => 0, - } - token::BinOp(token::And) | token::AndAnd => 1, - _ if self.token.is_keyword(kw::Mut) => 1, - _ => 0, - }; - - self.look_ahead(offset, |t| t.is_ident()) && - self.look_ahead(offset + 1, |t| t == &token::Colon) - } - fn is_crate_vis(&self) -> bool { self.token.is_keyword(kw::Crate) && self.look_ahead(1, |t| t != &token::ModSep) } diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index 3c60c88e2aa..08c624b5539 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -1,28 +1,23 @@ -use super::{Parser, PResult, PathStyle, SemiColonMode, BlockMode, ParamCfg}; - +use super::{Parser, PResult, PathStyle, SemiColonMode, BlockMode}; use crate::maybe_whole; use crate::ptr::P; -use crate::ast::{ - self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle, - Item, ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, - UseTree, UseTreeKind, PathSegment, - IsAuto, Constness, IsAsync, Unsafety, Defaultness, - Visibility, VisibilityKind, Mutability, FnDecl, FnHeader, MethodSig, Block, - ForeignItem, ForeignItemKind, - Ty, TyKind, Generics, GenericBounds, TraitRef, - EnumDef, VariantData, StructField, AnonConst, - Mac, MacDelimiter, -}; +use crate::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle, AnonConst, Item, ItemKind}; +use crate::ast::{ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind}; +use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness}; +use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind}; +use crate::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField}; +use crate::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, MethodSig, SelfKind, Param}; use crate::ext::base::DummyResult; use crate::parse::token; use crate::parse::parser::maybe_append; -use crate::parse::diagnostics::Error; +use crate::parse::diagnostics::{Error, dummy_arg}; use crate::tokenstream::{TokenTree, TokenStream}; -use crate::source_map::{respan, Span}; use crate::symbol::{kw, sym}; +use crate::source_map::{self, respan, Span}; +use crate::ThinVec; -use std::mem; use log::debug; +use std::mem; use rustc_target::spec::abi::Abi; use errors::{Applicability, DiagnosticBuilder, DiagnosticId, StashKey}; @@ -412,7 +407,7 @@ impl<'a> Parser<'a> { self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, vis) } - fn mk_item_with_info( + pub(super) fn mk_item_with_info( &self, attrs: Vec<Attribute>, lo: Span, @@ -425,16 +420,6 @@ impl<'a> Parser<'a> { Ok(Some(self.mk_item(span, ident, item, vis, attrs))) } - fn recover_first_param(&mut self) -> &'static str { - match self.parse_outer_attributes() - .and_then(|_| self.parse_self_param()) - .map_err(|mut e| e.cancel()) - { - Ok(Some(_)) => "method", - _ => "function", - } - } - /// This is the fall-through for parsing items. fn parse_macro_use_or_failure( &mut self, @@ -707,9 +692,11 @@ impl<'a> Parser<'a> { Ok(item) } - fn parse_impl_item_(&mut self, - at_end: &mut bool, - mut attrs: Vec<Attribute>) -> PResult<'a, ImplItem> { + fn parse_impl_item_( + &mut self, + at_end: &mut bool, + mut attrs: Vec<Attribute>, + ) -> PResult<'a, ImplItem> { let lo = self.token.span; let vis = self.parse_visibility(false)?; let defaultness = self.parse_defaultness(); @@ -722,8 +709,11 @@ impl<'a> Parser<'a> { (name, kind, generics) } else if self.is_const_item() { self.parse_impl_const()? + } else if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(&vis), at_end)? { + // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction! + (Ident::invalid(), ast::ImplItemKind::Macro(mac), Generics::default()) } else { - let (name, inner_attrs, generics, kind) = self.parse_impl_method(&vis, at_end)?; + let (name, inner_attrs, generics, kind) = self.parse_impl_method(at_end)?; attrs.extend(inner_attrs); (name, kind, generics) }; @@ -783,71 +773,6 @@ impl<'a> Parser<'a> { Ok((name, ImplItemKind::Const(typ, expr), Generics::default())) } - /// Parses a method or a macro invocation in a trait impl. - fn parse_impl_method( - &mut self, - vis: &Visibility, - at_end: &mut bool - ) -> PResult<'a, (Ident, Vec<Attribute>, Generics, ImplItemKind)> { - // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction! - if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? { - // method macro - Ok((Ident::invalid(), vec![], Generics::default(), ast::ImplItemKind::Macro(mac))) - } else { - let (ident, sig, generics) = self.parse_method_sig(|_| true)?; - *at_end = true; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(sig, body))) - } - } - - /// Parse the "signature", including the identifier, parameters, and generics - /// of a method. The body is not parsed as that differs between `trait`s and `impl`s. - fn parse_method_sig( - &mut self, - is_name_required: fn(&token::Token) -> bool, - ) -> PResult<'a, (Ident, MethodSig, Generics)> { - let header = self.parse_fn_front_matter()?; - let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { - is_self_allowed: true, - allow_c_variadic: false, - is_name_required, - })?; - Ok((ident, MethodSig { header, decl }, generics)) - } - - /// Parses all the "front matter" for a `fn` declaration, up to - /// and including the `fn` keyword: - /// - /// - `const fn` - /// - `unsafe fn` - /// - `const unsafe fn` - /// - `extern fn` - /// - etc. - fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> { - let is_const_fn = self.eat_keyword(kw::Const); - let const_span = self.prev_span; - let asyncness = self.parse_asyncness(); - if let IsAsync::Async { .. } = asyncness { - self.ban_async_in_2015(self.prev_span); - } - let asyncness = respan(self.prev_span, asyncness); - let unsafety = self.parse_unsafety(); - let (constness, unsafety, abi) = if is_const_fn { - (respan(const_span, Constness::Const), unsafety, Abi::Rust) - } else { - let abi = self.parse_extern_abi()?; - (respan(self.prev_span, Constness::NotConst), unsafety, abi) - }; - if !self.eat_keyword(kw::Fn) { - // It is possible for `expect_one_of` to recover given the contents of - // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't - // account for this. - if !self.expect_one_of(&[], &[])? { unreachable!() } - } - Ok(FnHeader { constness, unsafety, asyncness, abi }) - } - /// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`. fn parse_item_trait(&mut self, unsafety: Unsafety) -> PResult<'a, ItemInfo> { // Parse optional `auto` prefix. @@ -957,13 +882,7 @@ impl<'a> Parser<'a> { // trait item macro. (Ident::invalid(), TraitItemKind::Macro(mac), Generics::default()) } else { - // This is somewhat dubious; We don't want to allow - // argument names to be left off if there is a definition... - // - // We don't allow argument names to be left off in edition 2018. - let (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?; - let body = self.parse_trait_method_body(at_end, &mut attrs)?; - (ident, TraitItemKind::Method(sig, body), generics) + self.parse_trait_item_method(at_end, &mut attrs)? }; Ok(TraitItem { @@ -991,43 +910,6 @@ impl<'a> Parser<'a> { Ok((ident, TraitItemKind::Const(ty, default), Generics::default())) } - /// Parse the "body" of a method in a trait item definition. - /// This can either be `;` when there's no body, - /// or e.g. a block when the method is a provided one. - fn parse_trait_method_body( - &mut self, - at_end: &mut bool, - attrs: &mut Vec<Attribute>, - ) -> PResult<'a, Option<P<Block>>> { - Ok(match self.token.kind { - token::Semi => { - debug!("parse_trait_method_body(): parsing required method"); - self.bump(); - *at_end = true; - None - } - token::OpenDelim(token::Brace) => { - debug!("parse_trait_method_body(): parsing provided method"); - *at_end = true; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - attrs.extend(inner_attrs.iter().cloned()); - Some(body) - } - token::Interpolated(ref nt) => { - match **nt { - token::NtBlock(..) => { - *at_end = true; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - attrs.extend(inner_attrs.iter().cloned()); - Some(body) - } - _ => return self.expected_semi_or_open_brace(), - } - } - _ => return self.expected_semi_or_open_brace(), - }) - } - /// Parses the following grammar: /// /// TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty] @@ -1194,45 +1076,6 @@ impl<'a> Parser<'a> { Ok(ident) } - /// Parses an item-position function declaration. - fn parse_item_fn( - &mut self, - lo: Span, - vis: Visibility, - attrs: Vec<Attribute>, - header: FnHeader, - ) -> PResult<'a, Option<P<Item>>> { - let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { - is_self_allowed: false, - allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe, - is_name_required: |_| true, - })?; - let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; - let kind = ItemKind::Fn(decl, header, generics, body); - self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs))) - } - - /// Parse the "signature", including the identifier, parameters, and generics of a function. - fn parse_fn_sig(&mut self, cfg: ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> { - let ident = self.parse_ident()?; - let mut generics = self.parse_generics()?; - let decl = self.parse_fn_decl(cfg, true)?; - generics.where_clause = self.parse_where_clause()?; - Ok((ident, decl, generics)) - } - - /// Parses the parameter list and result type of a function declaration. - pub(super) fn parse_fn_decl( - &mut self, - cfg: ParamCfg, - ret_allow_plus: bool, - ) -> PResult<'a, P<FnDecl>> { - Ok(P(FnDecl { - inputs: self.parse_fn_params(cfg)?, - output: self.parse_ret_ty(ret_allow_plus)?, - })) - } - /// Parses `extern` for foreign ABIs modules. /// /// `extern` is expected to have been @@ -1344,32 +1187,6 @@ impl<'a> Parser<'a> { } } - /// Parses a function declaration from a foreign module. - fn parse_item_foreign_fn( - &mut self, - vis: ast::Visibility, - lo: Span, - attrs: Vec<Attribute>, - extern_sp: Span, - ) -> PResult<'a, ForeignItem> { - self.expect_keyword(kw::Fn)?; - let (ident, decl, generics) = self.parse_fn_sig(super::ParamCfg { - is_self_allowed: false, - allow_c_variadic: true, - is_name_required: |_| true, - })?; - let span = lo.to(self.token.span); - self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?; - Ok(ast::ForeignItem { - ident, - attrs, - kind: ForeignItemKind::Fn(decl, generics), - id: DUMMY_NODE_ID, - span, - vis, - }) - } - /// Parses a static item from a foreign module. /// Assumes that the `static` keyword is already parsed. fn parse_item_foreign_static(&mut self, vis: ast::Visibility, lo: Span, attrs: Vec<Attribute>) @@ -1910,3 +1727,466 @@ impl<'a> Parser<'a> { }) } } + +/// The parsing configuration used to parse a parameter list (see `parse_fn_params`). +pub(super) struct ParamCfg { + /// Is `self` is allowed as the first parameter? + pub is_self_allowed: bool, + /// Is `...` allowed as the tail of the parameter list? + pub allow_c_variadic: bool, + /// `is_name_required` decides if, per-parameter, + /// the parameter must have a pattern or just a type. + pub is_name_required: fn(&token::Token) -> bool, +} + +/// Parsing of functions and methods. +impl<'a> Parser<'a> { + /// Parses an item-position function declaration. + fn parse_item_fn( + &mut self, + lo: Span, + vis: Visibility, + attrs: Vec<Attribute>, + header: FnHeader, + ) -> PResult<'a, Option<P<Item>>> { + let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { + is_self_allowed: false, + allow_c_variadic: header.abi == Abi::C && header.unsafety == Unsafety::Unsafe, + is_name_required: |_| true, + })?; + let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; + let kind = ItemKind::Fn(decl, header, generics, body); + self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs))) + } + + /// Parses a function declaration from a foreign module. + fn parse_item_foreign_fn( + &mut self, + vis: ast::Visibility, + lo: Span, + attrs: Vec<Attribute>, + extern_sp: Span, + ) -> PResult<'a, ForeignItem> { + self.expect_keyword(kw::Fn)?; + let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { + is_self_allowed: false, + allow_c_variadic: true, + is_name_required: |_| true, + })?; + let span = lo.to(self.token.span); + self.parse_semi_or_incorrect_foreign_fn_body(&ident, extern_sp)?; + Ok(ast::ForeignItem { + ident, + attrs, + kind: ForeignItemKind::Fn(decl, generics), + id: DUMMY_NODE_ID, + span, + vis, + }) + } + + /// Parses a method or a macro invocation in a trait impl. + fn parse_impl_method( + &mut self, + at_end: &mut bool, + ) -> PResult<'a, (Ident, Vec<Attribute>, Generics, ImplItemKind)> { + let (ident, sig, generics) = self.parse_method_sig(|_| true)?; + *at_end = true; + let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; + Ok((ident, inner_attrs, generics, ast::ImplItemKind::Method(sig, body))) + } + + fn parse_trait_item_method( + &mut self, + at_end: &mut bool, + attrs: &mut Vec<Attribute>, + ) -> PResult<'a, (Ident, TraitItemKind, Generics)> { + // This is somewhat dubious; We don't want to allow + // argument names to be left off if there is a definition... + // + // We don't allow argument names to be left off in edition 2018. + let (ident, sig, generics) = self.parse_method_sig(|t| t.span.rust_2018())?; + let body = self.parse_trait_method_body(at_end, attrs)?; + Ok((ident, TraitItemKind::Method(sig, body), generics)) + } + + /// Parse the "body" of a method in a trait item definition. + /// This can either be `;` when there's no body, + /// or e.g. a block when the method is a provided one. + fn parse_trait_method_body( + &mut self, + at_end: &mut bool, + attrs: &mut Vec<Attribute>, + ) -> PResult<'a, Option<P<Block>>> { + Ok(match self.token.kind { + token::Semi => { + debug!("parse_trait_method_body(): parsing required method"); + self.bump(); + *at_end = true; + None + } + token::OpenDelim(token::Brace) => { + debug!("parse_trait_method_body(): parsing provided method"); + *at_end = true; + let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; + attrs.extend(inner_attrs.iter().cloned()); + Some(body) + } + token::Interpolated(ref nt) => { + match **nt { + token::NtBlock(..) => { + *at_end = true; + let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; + attrs.extend(inner_attrs.iter().cloned()); + Some(body) + } + _ => return self.expected_semi_or_open_brace(), + } + } + _ => return self.expected_semi_or_open_brace(), + }) + } + + /// Parse the "signature", including the identifier, parameters, and generics + /// of a method. The body is not parsed as that differs between `trait`s and `impl`s. + fn parse_method_sig( + &mut self, + is_name_required: fn(&token::Token) -> bool, + ) -> PResult<'a, (Ident, MethodSig, Generics)> { + let header = self.parse_fn_front_matter()?; + let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { + is_self_allowed: true, + allow_c_variadic: false, + is_name_required, + })?; + Ok((ident, MethodSig { header, decl }, generics)) + } + + /// Parses all the "front matter" for a `fn` declaration, up to + /// and including the `fn` keyword: + /// + /// - `const fn` + /// - `unsafe fn` + /// - `const unsafe fn` + /// - `extern fn` + /// - etc. + fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> { + let is_const_fn = self.eat_keyword(kw::Const); + let const_span = self.prev_span; + let asyncness = self.parse_asyncness(); + if let IsAsync::Async { .. } = asyncness { + self.ban_async_in_2015(self.prev_span); + } + let asyncness = respan(self.prev_span, asyncness); + let unsafety = self.parse_unsafety(); + let (constness, unsafety, abi) = if is_const_fn { + (respan(const_span, Constness::Const), unsafety, Abi::Rust) + } else { + let abi = self.parse_extern_abi()?; + (respan(self.prev_span, Constness::NotConst), unsafety, abi) + }; + if !self.eat_keyword(kw::Fn) { + // It is possible for `expect_one_of` to recover given the contents of + // `self.expected_tokens`, therefore, do not use `self.unexpected()` which doesn't + // account for this. + if !self.expect_one_of(&[], &[])? { unreachable!() } + } + Ok(FnHeader { constness, unsafety, asyncness, abi }) + } + + /// Parse the "signature", including the identifier, parameters, and generics of a function. + fn parse_fn_sig(&mut self, cfg: ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> { + let ident = self.parse_ident()?; + let mut generics = self.parse_generics()?; + let decl = self.parse_fn_decl(cfg, true)?; + generics.where_clause = self.parse_where_clause()?; + Ok((ident, decl, generics)) + } + + /// Parses the parameter list and result type of a function declaration. + pub(super) fn parse_fn_decl( + &mut self, + cfg: ParamCfg, + ret_allow_plus: bool, + ) -> PResult<'a, P<FnDecl>> { + Ok(P(FnDecl { + inputs: self.parse_fn_params(cfg)?, + output: self.parse_ret_ty(ret_allow_plus)?, + })) + } + + /// Parses the parameter list of a function, including the `(` and `)` delimiters. + fn parse_fn_params(&mut self, mut cfg: ParamCfg) -> PResult<'a, Vec<Param>> { + let sp = self.token.span; + let is_trait_item = cfg.is_self_allowed; + let mut c_variadic = false; + // Parse the arguments, starting out with `self` being possibly allowed... + let (params, _) = self.parse_paren_comma_seq(|p| { + let param = p.parse_param_general(&cfg, is_trait_item); + // ...now that we've parsed the first argument, `self` is no longer allowed. + cfg.is_self_allowed = false; + + match param { + Ok(param) => Ok( + if let TyKind::CVarArgs = param.ty.kind { + c_variadic = true; + if p.token != token::CloseDelim(token::Paren) { + p.span_err( + p.token.span, + "`...` must be the last argument of a C-variadic function", + ); + // FIXME(eddyb) this should probably still push `CVarArgs`. + // Maybe AST validation/HIR lowering should emit the above error? + None + } else { + Some(param) + } + } else { + Some(param) + } + ), + Err(mut e) => { + e.emit(); + let lo = p.prev_span; + // Skip every token until next possible arg or end. + p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(token::Paren)]); + // Create a placeholder argument for proper arg count (issue #34264). + let span = lo.to(p.prev_span); + Ok(Some(dummy_arg(Ident::new(kw::Invalid, span)))) + } + } + })?; + + let mut params: Vec<_> = params.into_iter().filter_map(|x| x).collect(); + + // Replace duplicated recovered params with `_` pattern to avoid unecessary errors. + self.deduplicate_recovered_params_names(&mut params); + + if c_variadic && params.len() <= 1 { + self.span_err( + sp, + "C-variadic function must be declared with at least one named argument", + ); + } + + Ok(params) + } + + /// Skips unexpected attributes and doc comments in this position and emits an appropriate + /// error. + /// This version of parse param doesn't necessarily require identifier names. + fn parse_param_general(&mut self, cfg: &ParamCfg, is_trait_item: bool) -> PResult<'a, Param> { + let lo = self.token.span; + let attrs = self.parse_outer_attributes()?; + + // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here. + if let Some(mut param) = self.parse_self_param()? { + param.attrs = attrs.into(); + return if cfg.is_self_allowed { + Ok(param) + } else { + self.recover_bad_self_param(param, is_trait_item) + }; + } + + let is_name_required = match self.token.kind { + token::DotDotDot => false, + _ => (cfg.is_name_required)(&self.token), + }; + let (pat, ty) = if is_name_required || self.is_named_param() { + debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required); + + let pat = self.parse_fn_param_pat()?; + if let Err(mut err) = self.expect(&token::Colon) { + return if let Some(ident) = self.parameter_without_type( + &mut err, + pat, + is_name_required, + cfg.is_self_allowed, + is_trait_item, + ) { + err.emit(); + Ok(dummy_arg(ident)) + } else { + Err(err) + }; + } + + self.eat_incorrect_doc_comment_for_param_type(); + (pat, self.parse_ty_common(true, true, cfg.allow_c_variadic)?) + } else { + debug!("parse_param_general ident_to_pat"); + let parser_snapshot_before_ty = self.clone(); + self.eat_incorrect_doc_comment_for_param_type(); + let mut ty = self.parse_ty_common(true, true, cfg.allow_c_variadic); + if ty.is_ok() && self.token != token::Comma && + self.token != token::CloseDelim(token::Paren) { + // This wasn't actually a type, but a pattern looking like a type, + // so we are going to rollback and re-parse for recovery. + ty = self.unexpected(); + } + match ty { + Ok(ty) => { + let ident = Ident::new(kw::Invalid, self.prev_span); + let bm = BindingMode::ByValue(Mutability::Immutable); + let pat = self.mk_pat_ident(ty.span, bm, ident); + (pat, ty) + } + // If this is a C-variadic argument and we hit an error, return the error. + Err(err) if self.token == token::DotDotDot => return Err(err), + // Recover from attempting to parse the argument as a type without pattern. + Err(mut err) => { + err.cancel(); + mem::replace(self, parser_snapshot_before_ty); + self.recover_arg_parse()? + } + } + }; + + let span = lo.to(self.token.span); + + Ok(Param { + attrs: attrs.into(), + id: ast::DUMMY_NODE_ID, + is_placeholder: false, + pat, + span, + ty, + }) + } + + /// Returns the parsed optional self parameter and whether a self shortcut was used. + /// + /// See `parse_self_param_with_attrs` to collect attributes. + fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> { + // Extract an identifier *after* having confirmed that the token is one. + let expect_self_ident = |this: &mut Self| { + match this.token.kind { + // Preserve hygienic context. + token::Ident(name, _) => { + let span = this.token.span; + this.bump(); + Ident::new(name, span) + } + _ => unreachable!(), + } + }; + // Is `self` `n` tokens ahead? + let is_isolated_self = |this: &Self, n| { + this.is_keyword_ahead(n, &[kw::SelfLower]) + && this.look_ahead(n + 1, |t| t != &token::ModSep) + }; + // Is `mut self` `n` tokens ahead? + let is_isolated_mut_self = |this: &Self, n| { + this.is_keyword_ahead(n, &[kw::Mut]) + && is_isolated_self(this, n + 1) + }; + // Parse `self` or `self: TYPE`. We already know the current token is `self`. + let parse_self_possibly_typed = |this: &mut Self, m| { + let eself_ident = expect_self_ident(this); + let eself_hi = this.prev_span; + let eself = if this.eat(&token::Colon) { + SelfKind::Explicit(this.parse_ty()?, m) + } else { + SelfKind::Value(m) + }; + Ok((eself, eself_ident, eself_hi)) + }; + // Recover for the grammar `*self`, `*const self`, and `*mut self`. + let recover_self_ptr = |this: &mut Self| { + let msg = "cannot pass `self` by raw pointer"; + let span = this.token.span; + this.struct_span_err(span, msg) + .span_label(span, msg) + .emit(); + + Ok((SelfKind::Value(Mutability::Immutable), expect_self_ident(this), this.prev_span)) + }; + + // Parse optional `self` parameter of a method. + // Only a limited set of initial token sequences is considered `self` parameters; anything + // else is parsed as a normal function parameter list, so some lookahead is required. + let eself_lo = self.token.span; + let (eself, eself_ident, eself_hi) = match self.token.kind { + token::BinOp(token::And) => { + let eself = if is_isolated_self(self, 1) { + // `&self` + self.bump(); + SelfKind::Region(None, Mutability::Immutable) + } else if is_isolated_mut_self(self, 1) { + // `&mut self` + self.bump(); + self.bump(); + SelfKind::Region(None, Mutability::Mutable) + } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) { + // `&'lt self` + self.bump(); + let lt = self.expect_lifetime(); + SelfKind::Region(Some(lt), Mutability::Immutable) + } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) { + // `&'lt mut self` + self.bump(); + let lt = self.expect_lifetime(); + self.bump(); + SelfKind::Region(Some(lt), Mutability::Mutable) + } else { + // `¬_self` + return Ok(None); + }; + (eself, expect_self_ident(self), self.prev_span) + } + // `*self` + token::BinOp(token::Star) if is_isolated_self(self, 1) => { + self.bump(); + recover_self_ptr(self)? + } + // `*mut self` and `*const self` + token::BinOp(token::Star) if + self.look_ahead(1, |t| t.is_mutability()) + && is_isolated_self(self, 2) => + { + self.bump(); + self.bump(); + recover_self_ptr(self)? + } + // `self` and `self: TYPE` + token::Ident(..) if is_isolated_self(self, 0) => { + parse_self_possibly_typed(self, Mutability::Immutable)? + } + // `mut self` and `mut self: TYPE` + token::Ident(..) if is_isolated_mut_self(self, 0) => { + self.bump(); + parse_self_possibly_typed(self, Mutability::Mutable)? + } + _ => return Ok(None), + }; + + let eself = source_map::respan(eself_lo.to(eself_hi), eself); + Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident))) + } + + fn is_named_param(&self) -> bool { + let offset = match self.token.kind { + token::Interpolated(ref nt) => match **nt { + token::NtPat(..) => return self.look_ahead(1, |t| t == &token::Colon), + _ => 0, + } + token::BinOp(token::And) | token::AndAnd => 1, + _ if self.token.is_keyword(kw::Mut) => 1, + _ => 0, + }; + + self.look_ahead(offset, |t| t.is_ident()) && + self.look_ahead(offset + 1, |t| t == &token::Colon) + } + + fn recover_first_param(&mut self) -> &'static str { + match self.parse_outer_attributes() + .and_then(|_| self.parse_self_param()) + .map_err(|mut e| e.cancel()) + { + Ok(Some(_)) => "method", + _ => "function", + } + } +} diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs index 018b5951e6e..e696ab0804d 100644 --- a/src/libsyntax/parse/parser/ty.rs +++ b/src/libsyntax/parse/parser/ty.rs @@ -1,4 +1,5 @@ use super::{Parser, PResult, PathStyle, PrevTokenKind, TokenType}; +use super::item::ParamCfg; use crate::{maybe_whole, maybe_recover_from_interpolated_ty_qpath}; use crate::ptr::P; @@ -281,7 +282,7 @@ impl<'a> Parser<'a> { let unsafety = self.parse_unsafety(); let abi = self.parse_extern_abi()?; self.expect_keyword(kw::Fn)?; - let cfg = super::ParamCfg { + let cfg = ParamCfg { is_self_allowed: false, allow_c_variadic: true, is_name_required: |_| false, diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs index 7d0d2392945..5e569f9dae3 100644 --- a/src/libsyntax/source_map.rs +++ b/src/libsyntax/source_map.rs @@ -878,25 +878,8 @@ impl SourceMap { // Returns the index of the `SourceFile` (in `self.files`) that contains `pos`. pub fn lookup_source_file_idx(&self, pos: BytePos) -> usize { - let files = self.files.borrow(); - let files = &files.source_files; - let count = files.len(); - - // Binary search for the `SourceFile`. - let mut a = 0; - let mut b = count; - while b - a > 1 { - let m = (a + b) / 2; - if files[m].start_pos > pos { - b = m; - } else { - a = m; - } - } - - assert!(a < count, "position {} does not resolve to a source location", pos.to_usize()); - - return a; + self.files.borrow().source_files.binary_search_by_key(&pos, |key| key.start_pos) + .unwrap_or_else(|p| p - 1) } pub fn count_lines(&self) -> usize { diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index 5d68a92579f..d4638c45473 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -106,6 +106,11 @@ pub fn expand_test_or_bench( cx.path(sp, vec![test_id, cx.ident_of("ShouldPanic", sp), cx.ident_of(name, sp)]) }; + // creates test::TestType::$name + let test_type_path = |name| { + cx.path(sp, vec![test_id, cx.ident_of("TestType", sp), cx.ident_of(name, sp)]) + }; + // creates $name: $expr let field = |name, expr| cx.field_imm(sp, cx.ident_of(name, sp), expr); @@ -181,6 +186,17 @@ pub fn expand_test_or_bench( cx.expr_path(should_panic_path("YesWithMessage")), vec![cx.expr_str(sp, sym)]), }), + // test_type: ... + field("test_type", match test_type(cx) { + // test::TestType::UnitTest + TestType::UnitTest => cx.expr_path(test_type_path("UnitTest")), + // test::TestType::IntegrationTest + TestType::IntegrationTest => cx.expr_path( + test_type_path("IntegrationTest") + ), + // test::TestPath::Unknown + TestType::Unknown => cx.expr_path(test_type_path("Unknown")), + }), // }, ])), // testfn: test::StaticTestFn(...) | test::StaticBenchFn(...) @@ -261,6 +277,34 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { } } +enum TestType { + UnitTest, + IntegrationTest, + Unknown, +} + +/// Attempts to determine the type of test. +/// Since doctests are created without macro expanding, only possible variants here +/// are `UnitTest`, `IntegrationTest` or `Unknown`. +fn test_type(cx: &ExtCtxt<'_>) -> TestType { + // Root path from context contains the topmost sources directory of the crate. + // I.e., for `project` with sources in `src` and tests in `tests` folders + // (no matter how many nested folders lie inside), + // there will be two different root paths: `/project/src` and `/project/tests`. + let crate_path = cx.root_path.as_path(); + + if crate_path.ends_with("src") { + // `/src` folder contains unit-tests. + TestType::UnitTest + } else if crate_path.ends_with("tests") { + // `/tests` folder contains integration tests. + TestType::IntegrationTest + } else { + // Crate layout doesn't match expected one, test type is unknown. + TestType::Unknown + } +} + fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic); let ref sd = cx.parse_sess.span_diagnostic; diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 2b005c3fc42..c37efde9923 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -658,6 +658,7 @@ symbols! { suggestion, target_feature, target_has_atomic, + target_has_atomic_load_store, target_thread_local, task, tbm_target_feature, diff --git a/src/libtest/formatters/json.rs b/src/libtest/formatters/json.rs index d9e4abf61c3..dcd733620bf 100644 --- a/src/libtest/formatters/json.rs +++ b/src/libtest/formatters/json.rs @@ -94,6 +94,15 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> { self.write_event("test", desc.name.as_slice(), "failed", exec_time, stdout, None) } + TrTimedFail => self.write_event( + "test", + desc.name.as_slice(), + "failed", + exec_time, + stdout, + Some(r#""reason": "time limit exceeded""#), + ), + TrFailedMsg(ref m) => self.write_event( "test", desc.name.as_slice(), diff --git a/src/libtest/formatters/pretty.rs b/src/libtest/formatters/pretty.rs index 184726c67d3..2935b4c99ce 100644 --- a/src/libtest/formatters/pretty.rs +++ b/src/libtest/formatters/pretty.rs @@ -3,6 +3,7 @@ use super::*; pub(crate) struct PrettyFormatter<T> { out: OutputLocation<T>, use_color: bool, + time_options: Option<TestTimeOptions>, /// Number of columns to fill when aligning names max_name_len: usize, @@ -16,12 +17,14 @@ impl<T: Write> PrettyFormatter<T> { use_color: bool, max_name_len: usize, is_multithreaded: bool, + time_options: Option<TestTimeOptions>, ) -> Self { PrettyFormatter { out, use_color, max_name_len, is_multithreaded, + time_options } } @@ -30,20 +33,24 @@ impl<T: Write> PrettyFormatter<T> { &self.out } - pub fn write_ok(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> { - self.write_short_result("ok", term::color::GREEN, exec_time) + pub fn write_ok(&mut self) -> io::Result<()> { + self.write_short_result("ok", term::color::GREEN) } - pub fn write_failed(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> { - self.write_short_result("FAILED", term::color::RED, exec_time) + pub fn write_failed(&mut self) -> io::Result<()> { + self.write_short_result("FAILED", term::color::RED) } - pub fn write_ignored(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> { - self.write_short_result("ignored", term::color::YELLOW, exec_time) + pub fn write_ignored(&mut self) -> io::Result<()> { + self.write_short_result("ignored", term::color::YELLOW) } - pub fn write_allowed_fail(&mut self, exec_time: Option<&TestExecTime>) -> io::Result<()> { - self.write_short_result("FAILED (allowed)", term::color::YELLOW, exec_time) + pub fn write_allowed_fail(&mut self) -> io::Result<()> { + self.write_short_result("FAILED (allowed)", term::color::YELLOW) + } + + pub fn write_time_failed(&mut self) -> io::Result<()> { + self.write_short_result("FAILED (time limit exceeded)", term::color::RED) } pub fn write_bench(&mut self) -> io::Result<()> { @@ -54,13 +61,8 @@ impl<T: Write> PrettyFormatter<T> { &mut self, result: &str, color: term::color::Color, - exec_time: Option<&TestExecTime>, ) -> io::Result<()> { - self.write_pretty(result, color)?; - if let Some(exec_time) = exec_time { - self.write_plain(format!(" {}", exec_time))?; - } - self.write_plain("\n") + self.write_pretty(result, color) } pub fn write_pretty(&mut self, word: &str, color: term::color::Color) -> io::Result<()> { @@ -88,12 +90,48 @@ impl<T: Write> PrettyFormatter<T> { self.out.flush() } - pub fn write_successes(&mut self, state: &ConsoleTestState) -> io::Result<()> { - self.write_plain("\nsuccesses:\n")?; - let mut successes = Vec::new(); + fn write_time( + &mut self, + desc: &TestDesc, + exec_time: Option<&TestExecTime> + ) -> io::Result<()> { + if let (Some(opts), Some(time)) = (self.time_options, exec_time) { + let time_str = format!(" <{}>", time); + + let color = if opts.colored { + if opts.is_critical(desc, time) { + Some(term::color::RED) + } else if opts.is_warn(desc, time) { + Some(term::color::YELLOW) + } else { + None + } + } else { + None + }; + + match color { + Some(color) => self.write_pretty(&time_str, color)?, + None => self.write_plain(&time_str)? + } + } + + Ok(()) + } + + fn write_results( + &mut self, + inputs: &Vec<(TestDesc, Vec<u8>)>, + results_type: &str + ) -> io::Result<()> { + let results_out_str = format!("\n{}:\n", results_type); + + self.write_plain(&results_out_str)?; + + let mut results = Vec::new(); let mut stdouts = String::new(); - for &(ref f, ref stdout) in &state.not_failures { - successes.push(f.name.to_string()); + for &(ref f, ref stdout) in inputs { + results.push(f.name.to_string()); if !stdout.is_empty() { stdouts.push_str(&format!("---- {} stdout ----\n", f.name)); let output = String::from_utf8_lossy(stdout); @@ -106,38 +144,24 @@ impl<T: Write> PrettyFormatter<T> { self.write_plain(&stdouts)?; } - self.write_plain("\nsuccesses:\n")?; - successes.sort(); - for name in &successes { + self.write_plain(&results_out_str)?; + results.sort(); + for name in &results { self.write_plain(&format!(" {}\n", name))?; } Ok(()) } + pub fn write_successes(&mut self, state: &ConsoleTestState) -> io::Result<()> { + self.write_results(&state.not_failures, "successes") + } + pub fn write_failures(&mut self, state: &ConsoleTestState) -> io::Result<()> { - self.write_plain("\nfailures:\n")?; - let mut failures = Vec::new(); - let mut fail_out = String::new(); - for &(ref f, ref stdout) in &state.failures { - failures.push(f.name.to_string()); - if !stdout.is_empty() { - fail_out.push_str(&format!("---- {} stdout ----\n", f.name)); - let output = String::from_utf8_lossy(stdout); - fail_out.push_str(&output); - fail_out.push_str("\n"); - } - } - if !fail_out.is_empty() { - self.write_plain("\n")?; - self.write_plain(&fail_out)?; - } + self.write_results(&state.failures, "failures") + } - self.write_plain("\nfailures:\n")?; - failures.sort(); - for name in &failures { - self.write_plain(&format!(" {}\n", name))?; - } - Ok(()) + pub fn write_time_failures(&mut self, state: &ConsoleTestState) -> io::Result<()> { + self.write_results(&state.time_failures, "failures (time limit exceeded)") } fn write_test_name(&mut self, desc: &TestDesc) -> io::Result<()> { @@ -179,15 +203,19 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> { } match *result { - TrOk => self.write_ok(exec_time), - TrFailed | TrFailedMsg(_) => self.write_failed(exec_time), - TrIgnored => self.write_ignored(exec_time), - TrAllowedFail => self.write_allowed_fail(exec_time), + TrOk => self.write_ok()?, + TrFailed | TrFailedMsg(_) => self.write_failed()?, + TrIgnored => self.write_ignored()?, + TrAllowedFail => self.write_allowed_fail()?, TrBench(ref bs) => { self.write_bench()?; - self.write_plain(&format!(": {}\n", fmt_bench_samples(bs))) + self.write_plain(&format!(": {}", fmt_bench_samples(bs)))?; } + TrTimedFail => self.write_time_failed()?, } + + self.write_time(desc, exec_time)?; + self.write_plain("\n") } fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> { @@ -207,7 +235,13 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> { } let success = state.failed == 0; if !success { - self.write_failures(state)?; + if !state.failures.is_empty() { + self.write_failures(state)?; + } + + if !state.time_failures.is_empty() { + self.write_time_failures(state)?; + } } self.write_plain("\ntest result: ")?; diff --git a/src/libtest/formatters/terse.rs b/src/libtest/formatters/terse.rs index 1812c20904c..8914e7b6b56 100644 --- a/src/libtest/formatters/terse.rs +++ b/src/libtest/formatters/terse.rs @@ -180,7 +180,7 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> { ) -> io::Result<()> { match *result { TrOk => self.write_ok(), - TrFailed | TrFailedMsg(_) => self.write_failed(), + TrFailed | TrFailedMsg(_) | TrTimedFail => self.write_failed(), TrIgnored => self.write_ignored(), TrAllowedFail => self.write_allowed_fail(), TrBench(ref bs) => { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 8b76080fc68..5a77413b2cb 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -56,6 +56,7 @@ use std::panic::{self, catch_unwind, AssertUnwindSafe, PanicInfo}; use std::path::PathBuf; use std::process; use std::process::{ExitStatus, Command, Termination}; +use std::str::FromStr; use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; use std::thread; @@ -75,13 +76,54 @@ const SECONDARY_TEST_INVOKER_VAR: &'static str = "__RUST_TEST_INVOKE"; const TR_OK: i32 = 50; const TR_FAILED: i32 = 51; +/// This small module contains constants used by `report-time` option. +/// Those constants values will be used if corresponding environment variables are not set. +/// +/// To override values for unit-tests, use a constant `RUST_TEST_TIME_UNIT`, +/// To override values for integration tests, use a constant `RUST_TEST_TIME_INTEGRATION`, +/// To override values for doctests, use a constant `RUST_TEST_TIME_DOCTEST`. +/// +/// Example of the expected format is `RUST_TEST_TIME_xxx=100,200`, where 100 means +/// warn time, and 200 means critical time. +pub mod time_constants { + use std::time::Duration; + use super::TEST_WARN_TIMEOUT_S; + + /// Environment variable for overriding default threshold for unit-tests. + pub const UNIT_ENV_NAME: &str = "RUST_TEST_TIME_UNIT"; + + // Unit tests are supposed to be really quick. + pub const UNIT_WARN: Duration = Duration::from_millis(50); + pub const UNIT_CRITICAL: Duration = Duration::from_millis(100); + + /// Environment variable for overriding default threshold for unit-tests. + pub const INTEGRATION_ENV_NAME: &str = "RUST_TEST_TIME_INTEGRATION"; + + // Integration tests may have a lot of work, so they can take longer to execute. + pub const INTEGRATION_WARN: Duration = Duration::from_millis(500); + pub const INTEGRATION_CRITICAL: Duration = Duration::from_millis(1000); + + /// Environment variable for overriding default threshold for unit-tests. + pub const DOCTEST_ENV_NAME: &str = "RUST_TEST_TIME_DOCTEST"; + + // Doctests are similar to integration tests, because they can include a lot of + // initialization code. + pub const DOCTEST_WARN: Duration = INTEGRATION_WARN; + pub const DOCTEST_CRITICAL: Duration = INTEGRATION_CRITICAL; + + // Do not suppose anything about unknown tests, base limits on the + // `TEST_WARN_TIMEOUT_S` constant. + pub const UNKNOWN_WARN: Duration = Duration::from_secs(TEST_WARN_TIMEOUT_S); + pub const UNKNOWN_CRITICAL: Duration = Duration::from_secs(TEST_WARN_TIMEOUT_S * 2); +} + // to be used by rustc to compile tests in libtest pub mod test { pub use crate::{ assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static, Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, RunIgnored, RunStrategy, ShouldPanic, StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName, - TestOpts, TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk, + TestOpts, TestTimeOptions, TestType, TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk, }; } @@ -97,6 +139,21 @@ pub enum Concurrent { No, } +/// Type of the test according to the [rust book](https://doc.rust-lang.org/cargo/guide/tests.html) +/// conventions. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum TestType { + /// Unit-tests are expected to be in the `src` folder of the crate. + UnitTest, + /// Integration-style tests are expected to be in the `tests` folder of the crate. + IntegrationTest, + /// Doctests are created by the `librustdoc` manually, so it's a different type of test. + DocTest, + /// Tests for the sources that don't follow the project layout convention + /// (e.g. tests in raw `main.rs` compiled by calling `rustc --test` directly). + Unknown, +} + // The name of a test. By convention this follows the rules for rust // paths; i.e., it should be a series of identifiers separated by double // colons. This way if some test runner wants to arrange the tests @@ -232,6 +289,7 @@ pub struct TestDesc { pub ignore: bool, pub should_panic: ShouldPanic, pub allow_fail: bool, + pub test_type: TestType, } #[derive(Debug)] @@ -403,6 +461,141 @@ pub enum RunIgnored { Only, } +/// Structure denoting time limits for test execution. +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] +pub struct TimeThreshold { + pub warn: Duration, + pub critical: Duration, +} + +impl TimeThreshold { + /// Creates a new `TimeThreshold` instance with provided durations. + pub fn new(warn: Duration, critical: Duration) -> Self { + Self { + warn, + critical, + } + } + + /// Attempts to create a `TimeThreshold` instance with values obtained + /// from the environment variable, and returns `None` if the variable + /// is not set. + /// Environment variable format is expected to match `\d+,\d+`. + /// + /// # Panics + /// + /// Panics if variable with provided name is set but contains inappropriate + /// value. + pub fn from_env_var(env_var_name: &str) -> Option<Self> { + let durations_str = env::var(env_var_name).ok()?; + + // Split string into 2 substrings by comma and try to parse numbers. + let mut durations = durations_str + .splitn(2, ',') + .map(|v| { + u64::from_str(v).unwrap_or_else(|_| { + panic!( + "Duration value in variable {} is expected to be a number, but got {}", + env_var_name, v + ) + }) + }); + + // Callback to be called if the environment variable has unexpected structure. + let panic_on_incorrect_value = || { + panic!( + "Duration variable {} expected to have 2 numbers separated by comma, but got {}", + env_var_name, durations_str + ); + }; + + let (warn, critical) = ( + durations.next().unwrap_or_else(panic_on_incorrect_value), + durations.next().unwrap_or_else(panic_on_incorrect_value) + ); + + if warn > critical { + panic!("Test execution warn time should be less or equal to the critical time"); + } + + Some(Self::new(Duration::from_millis(warn), Duration::from_millis(critical))) + } +} + +/// Structure with parameters for calculating test execution time. +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] +pub struct TestTimeOptions { + /// Denotes if the test critical execution time limit excess should be considered + /// a test failure. + pub error_on_excess: bool, + pub colored: bool, + pub unit_threshold: TimeThreshold, + pub integration_threshold: TimeThreshold, + pub doctest_threshold: TimeThreshold, +} + +impl TestTimeOptions { + pub fn new_from_env(error_on_excess: bool, colored: bool) -> Self { + let unit_threshold = + TimeThreshold::from_env_var(time_constants::UNIT_ENV_NAME) + .unwrap_or_else(Self::default_unit); + + let integration_threshold = + TimeThreshold::from_env_var(time_constants::INTEGRATION_ENV_NAME) + .unwrap_or_else(Self::default_integration); + + let doctest_threshold = + TimeThreshold::from_env_var(time_constants::DOCTEST_ENV_NAME) + .unwrap_or_else(Self::default_doctest); + + Self { + error_on_excess, + colored, + unit_threshold, + integration_threshold, + doctest_threshold, + } + } + + pub fn is_warn(&self, test: &TestDesc, exec_time: &TestExecTime) -> bool { + exec_time.0 >= self.warn_time(test) + } + + pub fn is_critical(&self, test: &TestDesc, exec_time: &TestExecTime) -> bool { + exec_time.0 >= self.critical_time(test) + } + + fn warn_time(&self, test: &TestDesc) -> Duration { + match test.test_type { + TestType::UnitTest => self.unit_threshold.warn, + TestType::IntegrationTest => self.integration_threshold.warn, + TestType::DocTest => self.doctest_threshold.warn, + TestType::Unknown => time_constants::UNKNOWN_WARN, + } + } + + fn critical_time(&self, test: &TestDesc) -> Duration { + match test.test_type { + TestType::UnitTest => self.unit_threshold.critical, + TestType::IntegrationTest => self.integration_threshold.critical, + TestType::DocTest => self.doctest_threshold.critical, + TestType::Unknown => time_constants::UNKNOWN_CRITICAL, + } + } + + fn default_unit() -> TimeThreshold { + TimeThreshold::new(time_constants::UNIT_WARN, time_constants::UNIT_CRITICAL) + } + + fn default_integration() -> TimeThreshold { + TimeThreshold::new(time_constants::INTEGRATION_WARN, time_constants::INTEGRATION_CRITICAL) + } + + fn default_doctest() -> TimeThreshold { + TimeThreshold::new(time_constants::DOCTEST_WARN, time_constants::DOCTEST_CRITICAL) + } +} + #[derive(Debug)] pub struct TestOpts { pub list: bool, @@ -418,12 +611,14 @@ pub struct TestOpts { pub format: OutputFormat, pub test_threads: Option<usize>, pub skip: Vec<String>, - pub report_time: bool, + pub time_options: Option<TestTimeOptions>, pub options: Options, } /// Result of parsing the options. pub type OptRes = Result<TestOpts, String>; +/// Result of parsing the option part. +type OptPartRes<T> = Result<Option<T>, String>; fn optgroups() -> getopts::Options { let mut opts = getopts::Options::new(); @@ -502,10 +697,35 @@ fn optgroups() -> getopts::Options { unstable-options = Allow use of experimental features", "unstable-options", ) - .optflag( + .optflagopt( "", "report-time", - "Show execution time of each test. Not available for --format=terse" + "Show execution time of each test. Awailable values: + plain = do not colorize the execution time (default); + colored = colorize output according to the `color` parameter value; + + Threshold values for colorized output can be configured via + `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION` and + `RUST_TEST_TIME_DOCTEST` environment variables. + + Expected format of environment variable is `VARIABLE=WARN_TIME,CRITICAL_TIME`. + + Not available for --format=terse", + "plain|colored" + ) + .optflag( + "", + "ensure-time", + "Treat excess of the test execution time limit as error. + + Threshold values for this option can be configured via + `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION` and + `RUST_TEST_TIME_DOCTEST` environment variables. + + Expected format of environment variable is `VARIABLE=WARN_TIME,CRITICAL_TIME`. + + `CRITICAL_TIME` here means the limit that should not be exceeded by test. + " ); return opts; } @@ -554,6 +774,45 @@ fn is_nightly() -> bool { bootstrap || !disable_unstable_features } +// Gets the option value and checks if unstable features are enabled. +macro_rules! unstable_optflag { + ($matches:ident, $allow_unstable:ident, $option_name:literal) => {{ + let opt = $matches.opt_present($option_name); + if !$allow_unstable && opt { + return Some(Err(format!( + "The \"{}\" flag is only accepted on the nightly compiler", + $option_name + ))); + } + + opt + }}; +} + +// Gets the CLI options assotiated with `report-time` feature. +fn get_time_options( + matches: &getopts::Matches, + allow_unstable: bool) +-> Option<OptPartRes<TestTimeOptions>> { + let report_time = unstable_optflag!(matches, allow_unstable, "report-time"); + let colored_opt_str = matches.opt_str("report-time"); + let mut report_time_colored = report_time && colored_opt_str == Some("colored".into()); + let ensure_test_time = unstable_optflag!(matches, allow_unstable, "ensure-time"); + + // If `ensure-test-time` option is provided, time output is enforced, + // so user won't be confused if any of tests will silently fail. + let options = if report_time || ensure_test_time { + if ensure_test_time && !report_time { + report_time_colored = true; + } + Some(TestTimeOptions::new_from_env(ensure_test_time, report_time_colored)) + } else { + None + }; + + Some(Ok(options)) +} + // Parses command line arguments into test options pub fn parse_opts(args: &[String]) -> Option<OptRes> { let mut allow_unstable = false; @@ -592,26 +851,9 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> { None }; - let exclude_should_panic = matches.opt_present("exclude-should-panic"); - if !allow_unstable && exclude_should_panic { - return Some(Err( - "The \"exclude-should-panic\" flag is only accepted on the nightly compiler".into(), - )); - } + let exclude_should_panic = unstable_optflag!(matches, allow_unstable, "exclude-should-panic"); - let include_ignored = matches.opt_present("include-ignored"); - if !allow_unstable && include_ignored { - return Some(Err( - "The \"include-ignored\" flag is only accepted on the nightly compiler".into(), - )); - } - - let report_time = matches.opt_present("report-time"); - if !allow_unstable && report_time { - return Some(Err( - "The \"report-time\" flag is only accepted on the nightly compiler".into(), - )); - } + let include_ignored = unstable_optflag!(matches, allow_unstable, "include-ignored"); let run_ignored = match (include_ignored, matches.opt_present("ignored")) { (true, true) => { @@ -641,6 +883,12 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> { }; } + let time_options = match get_time_options(&matches, allow_unstable) { + Some(Ok(val)) => val, + Some(Err(e)) => return Some(Err(e)), + None => panic!("Unexpected output from `get_time_options`"), + }; + let test_threads = match matches.opt_str("test-threads") { Some(n_str) => match n_str.parse::<usize>() { Ok(0) => return Some(Err("argument for --test-threads must not be 0".to_string())), @@ -706,20 +954,20 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> { format, test_threads, skip: matches.opt_strs("skip"), - report_time, + time_options, options: Options::new().display_output(matches.opt_present("show-output")), }; Some(Ok(test_opts)) } -#[derive(Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub struct BenchSamples { ns_iter_summ: stats::Summary, mb_s: usize, } -#[derive(Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub enum TestResult { TrOk, TrFailed, @@ -727,6 +975,7 @@ pub enum TestResult { TrIgnored, TrAllowedFail, TrBench(BenchSamples), + TrTimedFail, } unsafe impl Send for TestResult {} @@ -774,6 +1023,7 @@ struct ConsoleTestState { metrics: MetricMap, failures: Vec<(TestDesc, Vec<u8>)>, not_failures: Vec<(TestDesc, Vec<u8>)>, + time_failures: Vec<(TestDesc, Vec<u8>)>, options: Options, } @@ -796,6 +1046,7 @@ impl ConsoleTestState { metrics: MetricMap::new(), failures: Vec::new(), not_failures: Vec::new(), + time_failures: Vec::new(), options: opts.options, }) } @@ -831,11 +1082,12 @@ impl ConsoleTestState { TrIgnored => "ignored".to_owned(), TrAllowedFail => "failed (allowed)".to_owned(), TrBench(ref bs) => fmt_bench_samples(bs), + TrTimedFail => "failed (time limit exceeded)".to_owned(), }, test.name, ))?; if let Some(exec_time) = exec_time { - self.write_log(|| format!(" {}", exec_time))?; + self.write_log(|| format!(" <{}>", exec_time))?; } self.write_log(|| "\n") } @@ -993,6 +1245,10 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu stdout.extend_from_slice(format!("note: {}", msg).as_bytes()); st.failures.push((test, stdout)); } + TrTimedFail => { + st.failed += 1; + st.time_failures.push((test, stdout)); + } } Ok(()) } @@ -1018,6 +1274,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu use_color(opts), max_name_len, is_multithreaded, + opts.time_options, )), OutputFormat::Terse => Box::new(TerseFormatter::new( output, @@ -1487,22 +1744,35 @@ pub fn run_test( return; } + struct TestRunOpts { + pub strategy: RunStrategy, + pub nocapture: bool, + pub concurrency: Concurrent, + pub time: Option<TestTimeOptions>, + } + fn run_test_inner( desc: TestDesc, - nocapture: bool, - report_time: bool, - strategy: RunStrategy, monitor_ch: Sender<MonitorMsg>, testfn: Box<dyn FnOnce() + Send>, - concurrency: Concurrent, + opts: TestRunOpts, ) { + let concurrency = opts.concurrency; let name = desc.name.clone(); let runtest = move || { - match strategy { + match opts.strategy { RunStrategy::InProcess => - run_test_in_process(desc, nocapture, report_time, testfn, monitor_ch), - RunStrategy::SpawnPrimary => spawn_test_subprocess(desc, report_time, monitor_ch), + run_test_in_process( + desc, + opts.nocapture, + opts.time.is_some(), + testfn, + monitor_ch, + opts.time + ), + RunStrategy::SpawnPrimary => + spawn_test_subprocess(desc, opts.time.is_some(), monitor_ch, opts.time), } }; @@ -1518,6 +1788,13 @@ pub fn run_test( } } + let test_run_opts = TestRunOpts { + strategy, + nocapture: opts.nocapture, + concurrency, + time: opts.time_options + }; + match testfn { DynBenchFn(bencher) => { // Benchmarks aren't expected to panic, so we run them all in-process. @@ -1538,22 +1815,16 @@ pub fn run_test( }; run_test_inner( desc, - opts.nocapture, - opts.report_time, - strategy, monitor_ch, Box::new(move || __rust_begin_short_backtrace(f)), - concurrency + test_run_opts, ); } StaticTestFn(f) => run_test_inner( desc, - opts.nocapture, - opts.report_time, - strategy, monitor_ch, Box::new(move || __rust_begin_short_backtrace(f)), - concurrency, + test_run_opts, ), } } @@ -1564,10 +1835,13 @@ fn __rust_begin_short_backtrace<F: FnOnce()>(f: F) { f() } -fn calc_result<'a>(desc: &TestDesc, - task_result: Result<(), &'a (dyn Any + 'static + Send)>) --> TestResult { - match (&desc.should_panic, task_result) { +fn calc_result<'a>( + desc: &TestDesc, + task_result: Result<(), &'a (dyn Any + 'static + Send)>, + time_opts: &Option<TestTimeOptions>, + exec_time: &Option<TestExecTime> +) -> TestResult { + let result = match (&desc.should_panic, task_result) { (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TrOk, (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => { if err @@ -1589,23 +1863,59 @@ fn calc_result<'a>(desc: &TestDesc, (&ShouldPanic::Yes, Ok(())) => TrFailedMsg("test did not panic as expected".to_string()), _ if desc.allow_fail => TrAllowedFail, _ => TrFailed, + }; + + // If test is already failed (or allowed to fail), do not change the result. + if result != TrOk { + return result; } + + // Check if test is failed due to timeout. + if let (Some(opts), Some(time)) = (time_opts, exec_time) { + if opts.error_on_excess && opts.is_critical(desc, time) { + return TrTimedFail; + } + } + + result } -fn get_result_from_exit_code(desc: &TestDesc, code: i32) -> TestResult { - match (desc.allow_fail, code) { +fn get_result_from_exit_code( + desc: &TestDesc, + code: i32, + time_opts: &Option<TestTimeOptions>, + exec_time: &Option<TestExecTime>, +) -> TestResult { + let result = match (desc.allow_fail, code) { (_, TR_OK) => TrOk, (true, TR_FAILED) => TrAllowedFail, (false, TR_FAILED) => TrFailed, (_, _) => TrFailedMsg(format!("got unexpected return code {}", code)), + }; + + // If test is already failed (or allowed to fail), do not change the result. + if result != TrOk { + return result; } + + // Check if test is failed due to timeout. + if let (Some(opts), Some(time)) = (time_opts, exec_time) { + if opts.error_on_excess && opts.is_critical(desc, time) { + return TrTimedFail; + } + } + + result } -fn run_test_in_process(desc: TestDesc, - nocapture: bool, - report_time: bool, - testfn: Box<dyn FnOnce() + Send>, - monitor_ch: Sender<MonitorMsg>) { +fn run_test_in_process( + desc: TestDesc, + nocapture: bool, + report_time: bool, + testfn: Box<dyn FnOnce() + Send>, + monitor_ch: Sender<MonitorMsg>, + time_opts: Option<TestTimeOptions>, +) { // Buffer for capturing standard I/O let data = Arc::new(Mutex::new(Vec::new())); @@ -1635,14 +1945,19 @@ fn run_test_in_process(desc: TestDesc, } let test_result = match result { - Ok(()) => calc_result(&desc, Ok(())), - Err(e) => calc_result(&desc, Err(e.as_ref())), + Ok(()) => calc_result(&desc, Ok(()), &time_opts, &exec_time), + Err(e) => calc_result(&desc, Err(e.as_ref()), &time_opts, &exec_time), }; let stdout = data.lock().unwrap().to_vec(); monitor_ch.send((desc.clone(), test_result, exec_time, stdout)).unwrap(); } -fn spawn_test_subprocess(desc: TestDesc, report_time: bool, monitor_ch: Sender<MonitorMsg>) { +fn spawn_test_subprocess( + desc: TestDesc, + report_time: bool, + monitor_ch: Sender<MonitorMsg>, + time_opts: Option<TestTimeOptions>, +) { let (result, test_output, exec_time) = (|| { let args = env::args().collect::<Vec<_>>(); let current_exe = &args[0]; @@ -1673,7 +1988,7 @@ fn spawn_test_subprocess(desc: TestDesc, report_time: bool, monitor_ch: Sender<M let result = match (|| -> Result<TestResult, String> { let exit_code = get_exit_code(status)?; - Ok(get_result_from_exit_code(&desc, exit_code)) + Ok(get_result_from_exit_code(&desc, exit_code, &time_opts, &exec_time)) })() { Ok(r) => r, Err(e) => { @@ -1688,12 +2003,15 @@ fn spawn_test_subprocess(desc: TestDesc, report_time: bool, monitor_ch: Sender<M monitor_ch.send((desc.clone(), result, exec_time, test_output)).unwrap(); } -fn run_test_in_spawned_subprocess(desc: TestDesc, testfn: Box<dyn FnOnce() + Send>) -> ! { +fn run_test_in_spawned_subprocess( + desc: TestDesc, + testfn: Box<dyn FnOnce() + Send>, +) -> ! { let builtin_panic_hook = panic::take_hook(); let record_result = Arc::new(move |panic_info: Option<&'_ PanicInfo<'_>>| { let test_result = match panic_info { - Some(info) => calc_result(&desc, Err(info.payload())), - None => calc_result(&desc, Ok(())), + Some(info) => calc_result(&desc, Err(info.payload()), &None, &None), + None => calc_result(&desc, Ok(()), &None, &None), }; // We don't support serializing TrFailedMsg, so just diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 6577ec8ad23..aab8d012fdf 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -115,7 +115,7 @@ pub trait Stats { } /// Extracted collection of all the summary statistics of a sample set. -#[derive(Clone, PartialEq, Copy)] +#[derive(Debug, Clone, PartialEq, Copy)] #[allow(missing_docs)] pub struct Summary { pub sum: f64, diff --git a/src/libtest/tests.rs b/src/libtest/tests.rs index b95fb5df710..880d02a28ff 100644 --- a/src/libtest/tests.rs +++ b/src/libtest/tests.rs @@ -2,10 +2,11 @@ use super::*; use crate::test::{ filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored, RunStrategy, - ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailedMsg, - TrIgnored, TrOk, + ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TestTimeOptions, + TestType, TrFailedMsg, TrIgnored, TrOk, }; use std::sync::mpsc::channel; +use std::time::Duration; impl TestOpts { fn new() -> TestOpts { @@ -23,7 +24,7 @@ impl TestOpts { format: OutputFormat::Pretty, test_threads: None, skip: vec![], - report_time: false, + time_options: None, options: Options::new(), } } @@ -37,6 +38,7 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> { ignore: true, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(move || {})), }, @@ -46,6 +48,7 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> { ignore: false, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(move || {})), }, @@ -63,6 +66,7 @@ pub fn do_not_run_ignored_tests() { ignore: true, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(f)), }; @@ -81,6 +85,7 @@ pub fn ignored_tests_result_in_ignored() { ignore: true, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(f)), }; @@ -101,6 +106,7 @@ fn test_should_panic() { ignore: false, should_panic: ShouldPanic::Yes, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(f)), }; @@ -121,6 +127,7 @@ fn test_should_panic_good_message() { ignore: false, should_panic: ShouldPanic::YesWithMessage("error message"), allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(f)), }; @@ -143,6 +150,7 @@ fn test_should_panic_bad_message() { ignore: false, should_panic: ShouldPanic::YesWithMessage(expected), allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(f)), }; @@ -161,6 +169,7 @@ fn test_should_panic_but_succeeds() { ignore: false, should_panic: ShouldPanic::Yes, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(f)), }; @@ -178,11 +187,18 @@ fn report_time_test_template(report_time: bool) -> Option<TestExecTime> { ignore: false, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(f)), }; + let time_options = if report_time { + Some(TestTimeOptions::default()) + } else { + None + }; + let test_opts = TestOpts { - report_time, + time_options, ..TestOpts::new() }; let (tx, rx) = channel(); @@ -203,6 +219,97 @@ fn test_should_report_time() { assert!(exec_time.is_some()); } +fn time_test_failure_template(test_type: TestType) -> TestResult { + fn f() {} + let desc = TestDescAndFn { + desc: TestDesc { + name: StaticTestName("whatever"), + ignore: false, + should_panic: ShouldPanic::No, + allow_fail: false, + test_type + }, + testfn: DynTestFn(Box::new(f)), + }; + // `Default` will initialize all the thresholds to 0 milliseconds. + let mut time_options = TestTimeOptions::default(); + time_options.error_on_excess = true; + + let test_opts = TestOpts { + time_options: Some(time_options), + ..TestOpts::new() + }; + let (tx, rx) = channel(); + run_test(&test_opts, false, desc, RunStrategy::InProcess, tx, Concurrent::No); + let (_, result, _, _) = rx.recv().unwrap(); + + result +} + +#[test] +fn test_error_on_exceed() { + let types = [TestType::UnitTest, TestType::IntegrationTest, TestType::DocTest]; + + for test_type in types.into_iter() { + let result = time_test_failure_template(*test_type); + + assert_eq!(result, TestResult::TrTimedFail); + } + + // Check that for unknown tests thresholds aren't applied. + let result = time_test_failure_template(TestType::Unknown); + assert_eq!(result, TestResult::TrOk); +} + +fn typed_test_desc(test_type: TestType) -> TestDesc { + TestDesc { + name: StaticTestName("whatever"), + ignore: false, + should_panic: ShouldPanic::No, + allow_fail: false, + test_type + } +} + +fn test_exec_time(millis: u64) -> TestExecTime { + TestExecTime(Duration::from_millis(millis)) +} + +#[test] +fn test_time_options_threshold() { + let unit = TimeThreshold::new(Duration::from_millis(50), Duration::from_millis(100)); + let integration = TimeThreshold::new(Duration::from_millis(500), Duration::from_millis(1000)); + let doc = TimeThreshold::new(Duration::from_millis(5000), Duration::from_millis(10000)); + + let options = TestTimeOptions { + error_on_excess: false, + colored: false, + unit_threshold: unit.clone(), + integration_threshold: integration.clone(), + doctest_threshold: doc.clone(), + }; + + let test_vector = [ + (TestType::UnitTest, unit.warn.as_millis() - 1, false, false), + (TestType::UnitTest, unit.warn.as_millis(), true, false), + (TestType::UnitTest, unit.critical.as_millis(), true, true), + (TestType::IntegrationTest, integration.warn.as_millis() - 1, false, false), + (TestType::IntegrationTest, integration.warn.as_millis(), true, false), + (TestType::IntegrationTest, integration.critical.as_millis(), true, true), + (TestType::DocTest, doc.warn.as_millis() - 1, false, false), + (TestType::DocTest, doc.warn.as_millis(), true, false), + (TestType::DocTest, doc.critical.as_millis(), true, true), + ]; + + for (test_type, time, expected_warn, expected_critical) in test_vector.into_iter() { + let test_desc = typed_test_desc(*test_type); + let exec_time = test_exec_time(*time as u64); + + assert_eq!(options.is_warn(&test_desc, &exec_time), *expected_warn); + assert_eq!(options.is_critical(&test_desc, &exec_time), *expected_critical); + } +} + #[test] fn parse_ignored_flag() { let args = vec![ @@ -284,6 +391,7 @@ pub fn exclude_should_panic_option() { ignore: false, should_panic: ShouldPanic::Yes, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(move || {})), }); @@ -305,6 +413,7 @@ pub fn exact_filter_match() { ignore: false, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(move || {})), }) @@ -416,6 +525,7 @@ pub fn sort_tests() { ignore: false, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }, testfn: DynTestFn(Box::new(testfn)), }; @@ -492,6 +602,7 @@ pub fn test_bench_no_iter() { ignore: false, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }; crate::bench::benchmark(desc, tx, true, f); @@ -511,6 +622,7 @@ pub fn test_bench_iter() { ignore: false, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }; crate::bench::benchmark(desc, tx, true, f); @@ -524,6 +636,7 @@ fn should_sort_failures_before_printing_them() { ignore: false, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }; let test_b = TestDesc { @@ -531,9 +644,10 @@ fn should_sort_failures_before_printing_them() { ignore: false, should_panic: ShouldPanic::No, allow_fail: false, + test_type: TestType::Unknown, }; - let mut out = PrettyFormatter::new(Raw(Vec::new()), false, 10, false); + let mut out = PrettyFormatter::new(Raw(Vec::new()), false, 10, false, None); let st = ConsoleTestState { log_out: None, @@ -548,6 +662,7 @@ fn should_sort_failures_before_printing_them() { failures: vec![(test_b, Vec::new()), (test_a, Vec::new())], options: Options::new(), not_failures: Vec::new(), + time_failures: Vec::new(), }; out.write_failures(&st).unwrap(); diff --git a/src/test/codegen/extern-functions.rs b/src/test/codegen/extern-functions.rs deleted file mode 100644 index a935d886522..00000000000 --- a/src/test/codegen/extern-functions.rs +++ /dev/null @@ -1,19 +0,0 @@ -// compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] -#![feature(unwind_attributes)] - -extern { -// CHECK: Function Attrs: nounwind -// CHECK-NEXT: declare void @extern_fn - fn extern_fn(); -// CHECK-NOT: Function Attrs: nounwind -// CHECK: declare void @unwinding_extern_fn - #[unwind(allowed)] - fn unwinding_extern_fn(); -} - -pub unsafe fn force_declare() { - extern_fn(); - unwinding_extern_fn(); -} diff --git a/src/test/codegen/nounwind-extern.rs b/src/test/codegen/nounwind-extern.rs deleted file mode 100644 index 54d6a8d2794..00000000000 --- a/src/test/codegen/nounwind-extern.rs +++ /dev/null @@ -1,6 +0,0 @@ -// compile-flags: -O - -#![crate_type = "lib"] - -// CHECK: Function Attrs: norecurse nounwind -pub extern fn foo() {} diff --git a/src/test/codegen/unwind-extern-exports.rs b/src/test/codegen/unwind-extern-exports.rs new file mode 100644 index 00000000000..ddb3a4f6b4d --- /dev/null +++ b/src/test/codegen/unwind-extern-exports.rs @@ -0,0 +1,19 @@ +// compile-flags: -C opt-level=0 + +#![crate_type = "lib"] +#![feature(unwind_attributes)] + +// Make sure these all do *not* get the attribute. +// We disable optimizations to prevent LLVM from infering the attribute. +// CHECK-NOT: nounwind + +// "C" ABI +// pub extern fn foo() {} // FIXME right now we don't abort-on-panic but add `nounwind` nevertheless +#[unwind(allowed)] +pub extern fn foo_allowed() {} + +// "Rust" +// (`extern "Rust"` could be removed as all `fn` get it implicitly; we leave it in for clarity.) +pub extern "Rust" fn bar() {} +#[unwind(allowed)] +pub extern "Rust" fn bar_allowed() {} diff --git a/src/test/codegen/unwind-extern-imports.rs b/src/test/codegen/unwind-extern-imports.rs new file mode 100644 index 00000000000..485e8bbcd42 --- /dev/null +++ b/src/test/codegen/unwind-extern-imports.rs @@ -0,0 +1,41 @@ +// compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![feature(unwind_attributes)] + +extern { +// CHECK: Function Attrs:{{.*}}nounwind +// CHECK-NEXT: declare void @extern_fn + fn extern_fn(); +// CHECK-NOT: Function Attrs:{{.*}}nounwind +// CHECK: declare void @unwinding_extern_fn + #[unwind(allowed)] + fn unwinding_extern_fn(); +// CHECK-NOT: nounwind +// CHECK: declare void @aborting_extern_fn + #[unwind(aborts)] + fn aborting_extern_fn(); // FIXME: we want to have the attribute here +} + +extern "Rust" { +// CHECK-NOT: nounwind +// CHECK: declare void @rust_extern_fn + fn rust_extern_fn(); +// CHECK-NOT: nounwind +// CHECK: declare void @rust_unwinding_extern_fn + #[unwind(allowed)] + fn rust_unwinding_extern_fn(); +// CHECK-NOT: nounwind +// CHECK: declare void @rust_aborting_extern_fn + #[unwind(aborts)] + fn rust_aborting_extern_fn(); // FIXME: we want to have the attribute here +} + +pub unsafe fn force_declare() { + extern_fn(); + unwinding_extern_fn(); + aborting_extern_fn(); + rust_extern_fn(); + rust_unwinding_extern_fn(); + rust_aborting_extern_fn(); +} diff --git a/src/test/run-make-fulldeps/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile index 51d8a4a947a..3a377c32993 100644 --- a/src/test/run-make-fulldeps/sanitizer-address/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-address/Makefile @@ -24,4 +24,7 @@ endif all: $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) librustc_asan + # Verify that stack buffer overflow is detected: $(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow + # Verify that variable name is included in address sanitizer report: + $(TMPDIR)/overflow 2>&1 | $(CGREP) "'xs'" diff --git a/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile b/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile index c2eb4caea26..9868fc1d417 100644 --- a/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile +++ b/src/test/run-make-fulldeps/target-without-atomic-cas/Makefile @@ -2,4 +2,4 @@ # The target used below doesn't support atomic CAS operations. Verify that's the case all: - $(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v 'target_has_atomic="cas"' + $(RUSTC) --print cfg --target thumbv6m-none-eabi | $(CGREP) -v 'target_has_atomic="ptr"' diff --git a/src/test/ui/associated-const/associated-const-impl-wrong-lifetime.stderr b/src/test/ui/associated-const/associated-const-impl-wrong-lifetime.stderr index c213cfeeafa..2ceab394e95 100644 --- a/src/test/ui/associated-const/associated-const-impl-wrong-lifetime.stderr +++ b/src/test/ui/associated-const/associated-const-impl-wrong-lifetime.stderr @@ -6,7 +6,7 @@ LL | const NAME: &'a str = "unit"; | = note: expected type `&'static str` found type `&'a str` -note: the lifetime 'a as defined on the impl at 6:6... +note: the lifetime `'a` as defined on the impl at 6:6... --> $DIR/associated-const-impl-wrong-lifetime.rs:6:6 | LL | impl<'a> Foo for &'a () { diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr index 4309373f123..5ea98dcd4a9 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | bar(foo, x) | ^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 37:8... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 37:8... --> $DIR/project-fn-ret-contravariant.rs:37:8 | LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 { diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index b8b1a979c36..627609c4a9c 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | bar(foo, x) | ^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 44:8... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 44:8... --> $DIR/project-fn-ret-invariant.rs:44:8 | LL | fn baz<'a,'b>(x: Type<'a>) -> Type<'static> { diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr index 5099297fbeb..efec160588f 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.stderr +++ b/src/test/ui/async-await/issues/issue-63388-2.stderr @@ -15,12 +15,12 @@ LL | foo: &dyn Foo, bar: &'a dyn Foo LL | foo | --- this return type evaluates to the `'static` lifetime... | -note: ...can't outlive the lifetime '_ as defined on the method body at 11:14 +note: ...can't outlive the lifetime `'_` as defined on the method body at 11:14 --> $DIR/issue-63388-2.rs:11:14 | LL | foo: &dyn Foo, bar: &'a dyn Foo | ^ -help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 11:14 +help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'_` as defined on the method body at 11:14 | LL | foo + '_ | diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr index 4c7c0d1a0df..52d43eae658 100644 --- a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr +++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr @@ -24,12 +24,12 @@ LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d | = note: expected type `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'d>)` found type `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'d>)` -note: the lifetime 'c as defined on the method body at 27:24... +note: the lifetime `'c` as defined on the method body at 27:24... --> $DIR/regions-bound-missing-bound-in-impl.rs:27:24 | LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { | ^^ -note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 27:24 +note: ...does not necessarily outlive the lifetime `'c` as defined on the method body at 27:24 --> $DIR/regions-bound-missing-bound-in-impl.rs:27:24 | LL | fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) { diff --git a/src/test/ui/c-variadic/variadic-ffi-4.stderr b/src/test/ui/c-variadic/variadic-ffi-4.stderr index 3d552f88ba6..05535659161 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.stderr @@ -14,7 +14,7 @@ LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl< LL | | ap LL | | } | |_^ -note: ...does not necessarily outlive the lifetime 'f as defined on the function body at 7:37 +note: ...does not necessarily outlive the lifetime `'f` as defined on the function body at 7:37 --> $DIR/variadic-ffi-4.rs:7:37 | LL | pub unsafe extern "C" fn no_escape0<'f>(_: usize, ap: ...) -> VaListImpl<'f> { diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr index ac4666fe36d..8af7f882cc2 100644 --- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr +++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr @@ -11,7 +11,7 @@ note: the anonymous lifetime #2 defined on the body at 14:48... | LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {}); | ^^^^^^^^^^^^^^^^^^^^^^ -note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 11:36 +note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 11:36 --> $DIR/expect-fn-supply-fn.rs:11:36 | LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) { @@ -25,7 +25,7 @@ LL | with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {}); | = note: expected type `fn(&u32)` found type `fn(&'x u32)` -note: the lifetime 'x as defined on the function body at 11:36... +note: the lifetime `'x` as defined on the function body at 11:36... --> $DIR/expect-fn-supply-fn.rs:11:36 | LL | fn expect_free_supply_free_from_fn<'x>(x: &'x u32) { diff --git a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr index e3b623d5524..9f74738315a 100644 --- a/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr +++ b/src/test/ui/closures/closure-expected-type/expect-region-supply-region.stderr @@ -38,7 +38,7 @@ LL | | LL | | LL | | }); | |_____^ -note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 32:30 +note: ...does not necessarily outlive the lifetime `'x` as defined on the function body at 32:30 --> $DIR/expect-region-supply-region.rs:32:30 | LL | fn expect_bound_supply_named<'x>() { @@ -52,7 +52,7 @@ LL | closure_expecting_bound(|x: &'x u32| { | = note: expected type `&u32` found type `&'x u32` -note: the lifetime 'x as defined on the function body at 32:30... +note: the lifetime `'x` as defined on the function body at 32:30... --> $DIR/expect-region-supply-region.rs:32:30 | LL | fn expect_bound_supply_named<'x>() { diff --git a/src/test/ui/consts/auxiliary/external_macro.rs b/src/test/ui/consts/auxiliary/external_macro.rs new file mode 100644 index 00000000000..d260634c996 --- /dev/null +++ b/src/test/ui/consts/auxiliary/external_macro.rs @@ -0,0 +1,14 @@ +#![feature(allow_internal_unstable)] + +// Macro to help ensure CONST_ERR lint errors +// are not silenced in external macros. +// https://github.com/rust-lang/rust/issues/65300 + +#[macro_export] +#[allow_internal_unstable(type_ascription)] +macro_rules! static_assert { + ($test:expr) => { + #[allow(dead_code)] + const _: () = [()][!($test: bool) as usize]; + } +} diff --git a/src/test/ui/consts/const-external-macro-const-err.rs b/src/test/ui/consts/const-external-macro-const-err.rs new file mode 100644 index 00000000000..616d24f4a7b --- /dev/null +++ b/src/test/ui/consts/const-external-macro-const-err.rs @@ -0,0 +1,13 @@ +// edition:2018 +// aux-build:external_macro.rs + +// Ensure that CONST_ERR lint errors +// are not silenced in external macros. +// https://github.com/rust-lang/rust/issues/65300 + +extern crate external_macro; +use external_macro::static_assert; + +fn main() { + static_assert!(2 + 2 == 5); //~ ERROR +} diff --git a/src/test/ui/consts/const-external-macro-const-err.stderr b/src/test/ui/consts/const-external-macro-const-err.stderr new file mode 100644 index 00000000000..237c4d792c9 --- /dev/null +++ b/src/test/ui/consts/const-external-macro-const-err.stderr @@ -0,0 +1,11 @@ +error: any use of this value will cause an error + --> $DIR/const-external-macro-const-err.rs:12:5 + | +LL | static_assert!(2 + 2 == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the len is 1 but the index is 1 + | + = note: `#[deny(const_err)]` on by default + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/consts/const-match-check.eval1.stderr b/src/test/ui/consts/const-match-check.eval1.stderr index 24d2e3ce539..087cc3c86a6 100644 --- a/src/test/ui/consts/const-match-check.eval1.stderr +++ b/src/test/ui/consts/const-match-check.eval1.stderr @@ -3,6 +3,13 @@ error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1 | LL | A = { let 0 = 0; 0 }, | ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | A = { if let 0 = 0 { /* */ } 0 }, + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/const-match-check.eval2.stderr b/src/test/ui/consts/const-match-check.eval2.stderr index 5d59d06f798..80d9f794bc1 100644 --- a/src/test/ui/consts/const-match-check.eval2.stderr +++ b/src/test/ui/consts/const-match-check.eval2.stderr @@ -3,6 +3,13 @@ error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1 | LL | let x: [i32; { let 0 = 0; 0 }] = []; | ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | let x: [i32; { if let 0 = 0 { /* */ } 0 }] = []; + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/consts/const-match-check.matchck.stderr b/src/test/ui/consts/const-match-check.matchck.stderr index 6d74c26f9f7..e6b2f212bb4 100644 --- a/src/test/ui/consts/const-match-check.matchck.stderr +++ b/src/test/ui/consts/const-match-check.matchck.stderr @@ -3,24 +3,52 @@ error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1 | LL | const X: i32 = { let 0 = 0; 0 }; | ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | const X: i32 = { if let 0 = 0 { /* */ } 0 }; + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered --> $DIR/const-match-check.rs:8:23 | LL | static Y: i32 = { let 0 = 0; 0 }; | ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | static Y: i32 = { if let 0 = 0 { /* */ } 0 }; + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered --> $DIR/const-match-check.rs:13:26 | LL | const X: i32 = { let 0 = 0; 0 }; | ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | const X: i32 = { if let 0 = 0 { /* */ } 0 }; + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered --> $DIR/const-match-check.rs:19:26 | LL | const X: i32 = { let 0 = 0; 0 }; | ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | const X: i32 = { if let 0 = 0 { /* */ } 0 }; + | ^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr index 7d59d553d88..d865b59f0b9 100644 --- a/src/test/ui/empty/empty-never-array.stderr +++ b/src/test/ui/empty/empty-never-array.stderr @@ -11,6 +11,13 @@ LL | | } ... LL | let Helper::U(u) = Helper::T(t, []); | ^^^^^^^^^^^^ pattern `T(_, _)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Helper::U(u) = Helper::T(t, []) { /* */ } + | error[E0381]: use of possibly-uninitialized variable: `u` --> $DIR/empty-never-array.rs:12:5 diff --git a/src/test/ui/error-codes/E0005.stderr b/src/test/ui/error-codes/E0005.stderr index 56a4bcffc81..577c6e886d5 100644 --- a/src/test/ui/error-codes/E0005.stderr +++ b/src/test/ui/error-codes/E0005.stderr @@ -3,6 +3,13 @@ error[E0005]: refutable pattern in local binding: `None` not covered | LL | let Some(y) = x; | ^^^^^^^ pattern `None` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Some(y) = x { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0478.stderr b/src/test/ui/error-codes/E0478.stderr index 587125fdc33..1380840e0db 100644 --- a/src/test/ui/error-codes/E0478.stderr +++ b/src/test/ui/error-codes/E0478.stderr @@ -4,12 +4,12 @@ error[E0478]: lifetime bound not satisfied LL | child: Box<dyn Wedding<'kiss> + 'SnowWhite>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lifetime parameter instantiated with the lifetime 'SnowWhite as defined on the struct at 3:22 +note: lifetime parameter instantiated with the lifetime `'SnowWhite` as defined on the struct at 3:22 --> $DIR/E0478.rs:3:22 | LL | struct Prince<'kiss, 'SnowWhite> { | ^^^^^^^^^^ -note: but lifetime parameter must outlive the lifetime 'kiss as defined on the struct at 3:15 +note: but lifetime parameter must outlive the lifetime `'kiss` as defined on the struct at 3:15 --> $DIR/E0478.rs:3:15 | LL | struct Prince<'kiss, 'SnowWhite> { diff --git a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr index 4bf2d573d4f..cbd6422e5df 100644 --- a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr +++ b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr @@ -6,12 +6,12 @@ LL | Foo<'b,'a> | = note: expected type `Foo<'a, 'b>` found type `Foo<'b, 'a>` -note: the lifetime 'b as defined on the impl at 6:9... +note: the lifetime `'b` as defined on the impl at 6:9... --> $DIR/explicit-self-lifetime-mismatch.rs:6:9 | LL | impl<'a,'b> Foo<'a,'b> { | ^^ -note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 6:6 +note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 6:6 --> $DIR/explicit-self-lifetime-mismatch.rs:6:6 | LL | impl<'a,'b> Foo<'a,'b> { @@ -25,12 +25,12 @@ LL | Foo<'b,'a> | = note: expected type `Foo<'a, 'b>` found type `Foo<'b, 'a>` -note: the lifetime 'a as defined on the impl at 6:6... +note: the lifetime `'a` as defined on the impl at 6:6... --> $DIR/explicit-self-lifetime-mismatch.rs:6:6 | LL | impl<'a,'b> Foo<'a,'b> { | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 6:9 +note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 6:9 --> $DIR/explicit-self-lifetime-mismatch.rs:6:9 | LL | impl<'a,'b> Foo<'a,'b> { diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr new file mode 100644 index 00000000000..d77fbc1e823 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr @@ -0,0 +1,16 @@ +error[E0005]: refutable pattern in local binding: `Err(_)` not covered + --> $DIR/feature-gate-exhaustive-patterns.rs:7:9 + | +LL | let Ok(_x) = foo(); + | ^^^^^^ pattern `Err(_)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Ok(_x) = foo() { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr index dd4ca1f67e3..d77fbc1e823 100644 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.stderr @@ -3,6 +3,13 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered | LL | let Ok(_x) = foo(); | ^^^^^^ pattern `Err(_)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Ok(_x) = foo() { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr index 979f64fcd90..76d97dd2f58 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_inv_x_vs_free_inv_y.stderr @@ -10,7 +10,7 @@ LL | | fn(Inv<'y>)) } | = note: expected type `std::option::Option<fn(Inv<'y>)>` found type `std::option::Option<fn(Inv<'x>)>` -note: the lifetime 'x as defined on the function body at 32:20... +note: the lifetime `'x` as defined on the function body at 32:20... --> $DIR/hr-subtype.rs:32:20 | LL | fn subtype<'x,'y:'x,'z:'y>() { @@ -19,7 +19,7 @@ LL | fn subtype<'x,'y:'x,'z:'y>() { LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), LL | | fn(Inv<'y>)) } | |__________________________________________________- in this macro invocation -note: ...does not necessarily outlive the lifetime 'y as defined on the function body at 32:23 +note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 32:23 --> $DIR/hr-subtype.rs:32:23 | LL | fn subtype<'x,'y:'x,'z:'y>() { @@ -41,7 +41,7 @@ LL | | fn(Inv<'y>)) } | = note: expected type `std::option::Option<fn(Inv<'x>)>` found type `std::option::Option<fn(Inv<'y>)>` -note: the lifetime 'x as defined on the function body at 38:22... +note: the lifetime `'x` as defined on the function body at 38:22... --> $DIR/hr-subtype.rs:38:22 | LL | fn supertype<'x,'y:'x,'z:'y>() { @@ -50,7 +50,7 @@ LL | fn supertype<'x,'y:'x,'z:'y>() { LL | / check! { free_inv_x_vs_free_inv_y: (fn(Inv<'x>), LL | | fn(Inv<'y>)) } | |__________________________________________________- in this macro invocation -note: ...does not necessarily outlive the lifetime 'y as defined on the function body at 38:25 +note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 38:25 --> $DIR/hr-subtype.rs:38:25 | LL | fn supertype<'x,'y:'x,'z:'y>() { diff --git a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr index 3b6aff52169..74f4212b246 100644 --- a/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr +++ b/src/test/ui/hr-subtype/hr-subtype.free_x_vs_free_y.stderr @@ -10,7 +10,7 @@ LL | | fn(&'y u32)) } | = note: expected type `std::option::Option<fn(&'x u32)>` found type `std::option::Option<fn(&'y u32)>` -note: the lifetime 'x as defined on the function body at 38:22... +note: the lifetime `'x` as defined on the function body at 38:22... --> $DIR/hr-subtype.rs:38:22 | LL | fn supertype<'x,'y:'x,'z:'y>() { @@ -19,7 +19,7 @@ LL | fn supertype<'x,'y:'x,'z:'y>() { LL | / check! { free_x_vs_free_y: (fn(&'x u32), LL | | fn(&'y u32)) } | |__________________________________________- in this macro invocation -note: ...does not necessarily outlive the lifetime 'y as defined on the function body at 38:25 +note: ...does not necessarily outlive the lifetime `'y` as defined on the function body at 38:25 --> $DIR/hr-subtype.rs:38:25 | LL | fn supertype<'x,'y:'x,'z:'y>() { diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr index af120fa977c..5e80c673258 100644 --- a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr +++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | static_val(x); | ^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 19:26... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 19:26... --> $DIR/dyn-trait.rs:19:26 | LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) { diff --git a/src/test/ui/impl-trait/hidden-lifetimes.stderr b/src/test/ui/impl-trait/hidden-lifetimes.stderr index 650161753d1..956ac1f1a11 100644 --- a/src/test/ui/impl-trait/hidden-lifetimes.stderr +++ b/src/test/ui/impl-trait/hidden-lifetimes.stderr @@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { | ^^^^^^^^^^^^^^ | -note: hidden type `&'a mut &'b T` captures the lifetime 'b as defined on the function body at 28:17 +note: hidden type `&'a mut &'b T` captures the lifetime `'b` as defined on the function body at 28:17 --> $DIR/hidden-lifetimes.rs:28:17 | LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { @@ -16,7 +16,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a { | ^^^^^^^^^^^^^^ | -note: hidden type `std::rc::Rc<std::cell::RefCell<&'b T>>` captures the lifetime 'b as defined on the function body at 45:24 +note: hidden type `std::rc::Rc<std::cell::RefCell<&'b T>>` captures the lifetime `'b` as defined on the function body at 45:24 --> $DIR/hidden-lifetimes.rs:45:24 | LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a { diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index a6ea7837678..2ffb9434861 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -24,12 +24,12 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | | | this return type evaluates to the `'static` lifetime... | -note: ...can't outlive the lifetime 'a as defined on the function body at 6:13 +note: ...can't outlive the lifetime `'a` as defined on the function body at 6:13 --> $DIR/must_outlive_least_region_or_bound.rs:6:13 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | ^^ -help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the function body at 6:13 +help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 6:13 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^^^^^^^^^^^ @@ -42,12 +42,12 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | | | this return type evaluates to the `'static` lifetime... | -note: ...can't outlive the lifetime 'a as defined on the function body at 12:15 +note: ...can't outlive the lifetime `'a` as defined on the function body at 12:15 --> $DIR/must_outlive_least_region_or_bound.rs:12:15 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | ^^ -help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the function body at 12:15 +help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 12:15 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr index 5c8e322f712..894a65ff389 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.stderr +++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr @@ -4,7 +4,7 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea LL | fn foo(x: Cell<&'x u32>) -> impl Trait<'y> | ^^^^^^^^^^^^^^ | -note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime 'x as defined on the function body at 17:7 +note: hidden type `std::cell::Cell<&'x u32>` captures the lifetime `'x` as defined on the function body at 17:7 --> $DIR/region-escape-via-bound.rs:17:7 | LL | where 'x: 'y diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 0bc0180e78a..1d6b5f56aa0 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -30,12 +30,12 @@ LL | self.x.iter().map(|a| a.0) | | | ...but this borrow... | -note: ...can't outlive the lifetime 'a as defined on the method body at 10:20 +note: ...can't outlive the lifetime `'a` as defined on the method body at 10:20 --> $DIR/static-return-lifetime-infered.rs:10:20 | LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> { | ^^ -help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime 'a as defined on the method body at 10:20 +help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'a` as defined on the method body at 10:20 | LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr index a80ebaf8dd2..b5287f32a50 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.nll.stderr @@ -11,7 +11,7 @@ LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { LL | | x LL | | } | |_____^ -note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 9:32... +note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the method body at 9:32... --> $DIR/mismatched_trait_impl.rs:9:32 | LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr index 4dee83d6eef..734ca0819e4 100644 --- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr +++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr @@ -11,7 +11,7 @@ LL | / fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { LL | | x LL | | } | |_____^ -note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 9:32... +note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the method body at 9:32... --> $DIR/mismatched_trait_impl.rs:9:32 | LL | fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { diff --git a/src/test/ui/issues/issue-10291.stderr b/src/test/ui/issues/issue-10291.stderr index a836593e0da..4fff4ee866c 100644 --- a/src/test/ui/issues/issue-10291.stderr +++ b/src/test/ui/issues/issue-10291.stderr @@ -12,7 +12,7 @@ LL | drop::<Box<dyn for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { LL | | x LL | | })); | |_____^ -note: ...but the borrowed content is only valid for the lifetime 'x as defined on the function body at 1:9 +note: ...but the borrowed content is only valid for the lifetime `'x` as defined on the function body at 1:9 --> $DIR/issue-10291.rs:1:9 | LL | fn test<'x>(x: &'x isize) { diff --git a/src/test/ui/issues/issue-16683.stderr b/src/test/ui/issues/issue-16683.stderr index a047893a168..b663e213ed0 100644 --- a/src/test/ui/issues/issue-16683.stderr +++ b/src/test/ui/issues/issue-16683.stderr @@ -16,7 +16,7 @@ note: ...so that reference does not outlive borrowed content | LL | self.a(); | ^^^^ -note: but, the lifetime must be valid for the lifetime 'a as defined on the trait at 1:9... +note: but, the lifetime must be valid for the lifetime `'a` as defined on the trait at 1:9... --> $DIR/issue-16683.rs:1:9 | LL | trait T<'a> { diff --git a/src/test/ui/issues/issue-17740.stderr b/src/test/ui/issues/issue-17740.stderr index b8a0a067631..d392ea3c1b8 100644 --- a/src/test/ui/issues/issue-17740.stderr +++ b/src/test/ui/issues/issue-17740.stderr @@ -17,7 +17,7 @@ LL | | LL | | LL | | } | |_____^ -note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 5:7 +note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 5:7 --> $DIR/issue-17740.rs:5:7 | LL | impl <'a> Foo<'a>{ @@ -31,7 +31,7 @@ LL | fn bar(self: &mut Foo) { | = note: expected type `Foo<'a>` found type `Foo<'_>` -note: the lifetime 'a as defined on the impl at 5:7... +note: the lifetime `'a` as defined on the impl at 5:7... --> $DIR/issue-17740.rs:5:7 | LL | impl <'a> Foo<'a>{ diff --git a/src/test/ui/issues/issue-17758.stderr b/src/test/ui/issues/issue-17758.stderr index 28a1be59840..adcbb62e3d5 100644 --- a/src/test/ui/issues/issue-17758.stderr +++ b/src/test/ui/issues/issue-17758.stderr @@ -17,7 +17,7 @@ note: ...so that reference does not outlive borrowed content | LL | self.foo(); | ^^^^ -note: but, the lifetime must be valid for the lifetime 'a as defined on the trait at 4:11... +note: but, the lifetime must be valid for the lifetime `'a` as defined on the trait at 4:11... --> $DIR/issue-17758.rs:4:11 | LL | trait Foo<'a> { diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr index 585bc9c1488..04be62dc661 100644 --- a/src/test/ui/issues/issue-17905-2.stderr +++ b/src/test/ui/issues/issue-17905-2.stderr @@ -15,7 +15,7 @@ LL | | LL | | println!("{:?}", self); LL | | } | |_____^ -note: ...does not necessarily outlive the lifetime '_ as defined on the impl at 5:5 +note: ...does not necessarily outlive the lifetime `'_` as defined on the impl at 5:5 --> $DIR/issue-17905-2.rs:5:5 | LL | &str, @@ -29,7 +29,7 @@ LL | fn say(self: &Pair<&str, isize>) { | = note: expected type `Pair<&str, _>` found type `Pair<&str, _>` -note: the lifetime '_ as defined on the impl at 5:5... +note: the lifetime `'_` as defined on the impl at 5:5... --> $DIR/issue-17905-2.rs:5:5 | LL | &str, diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index dd895985c14..13c9c09461e 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -23,7 +23,7 @@ LL | | LL | | self.sub = t; LL | | } | |_____^ -note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 26:6 +note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 26:6 --> $DIR/issue-20831-debruijn.rs:26:6 | LL | impl<'a> Publisher<'a> for MyStruct<'a> { @@ -43,7 +43,7 @@ LL | | } | = note: expected type `'a` found type `'_` -note: the lifetime 'a as defined on the impl at 26:6... +note: the lifetime `'a` as defined on the impl at 26:6... --> $DIR/issue-20831-debruijn.rs:26:6 | LL | impl<'a> Publisher<'a> for MyStruct<'a> { @@ -83,7 +83,7 @@ LL | | LL | | self.sub = t; LL | | } | |_____^ -note: ...but the lifetime must also be valid for the lifetime 'a as defined on the impl at 26:6... +note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the impl at 26:6... --> $DIR/issue-20831-debruijn.rs:26:6 | LL | impl<'a> Publisher<'a> for MyStruct<'a> { diff --git a/src/test/ui/issues/issue-27942.stderr b/src/test/ui/issues/issue-27942.stderr index e03959598b8..d290b176161 100644 --- a/src/test/ui/issues/issue-27942.stderr +++ b/src/test/ui/issues/issue-27942.stderr @@ -11,7 +11,7 @@ note: the anonymous lifetime #1 defined on the method body at 5:5... | LL | fn select(&self) -> BufferViewHandle<R>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...does not necessarily outlive the lifetime 'a as defined on the trait at 3:18 +note: ...does not necessarily outlive the lifetime `'a` as defined on the trait at 3:18 --> $DIR/issue-27942.rs:3:18 | LL | pub trait Buffer<'a, R: Resources<'a>> { @@ -25,7 +25,7 @@ LL | fn select(&self) -> BufferViewHandle<R>; | = note: expected type `Resources<'_>` found type `Resources<'a>` -note: the lifetime 'a as defined on the trait at 3:18... +note: the lifetime `'a` as defined on the trait at 3:18... --> $DIR/issue-27942.rs:3:18 | LL | pub trait Buffer<'a, R: Resources<'a>> { diff --git a/src/test/ui/issues/issue-28848.stderr b/src/test/ui/issues/issue-28848.stderr index 5f0f202c0b2..726844a3184 100644 --- a/src/test/ui/issues/issue-28848.stderr +++ b/src/test/ui/issues/issue-28848.stderr @@ -4,12 +4,12 @@ error[E0478]: lifetime bound not satisfied LL | Foo::<'a, 'b>::xmute(u) | ^^^^^^^^^^^^^^^^^^^^ | -note: lifetime parameter instantiated with the lifetime 'b as defined on the function body at 9:16 +note: lifetime parameter instantiated with the lifetime `'b` as defined on the function body at 9:16 --> $DIR/issue-28848.rs:9:16 | LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { | ^^ -note: but lifetime parameter must outlive the lifetime 'a as defined on the function body at 9:12 +note: but lifetime parameter must outlive the lifetime `'a` as defined on the function body at 9:12 --> $DIR/issue-28848.rs:9:12 | LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { diff --git a/src/test/ui/issues/issue-31561.stderr b/src/test/ui/issues/issue-31561.stderr index 9ec26b024bc..d3c8e876b8a 100644 --- a/src/test/ui/issues/issue-31561.stderr +++ b/src/test/ui/issues/issue-31561.stderr @@ -12,6 +12,13 @@ LL | | } ... LL | let Thing::Foo(y) = Thing::Foo(1); | ^^^^^^^^^^^^^ patterns `Bar` and `Baz` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Thing::Foo(y) = Thing::Foo(1) { /* */ } + | error: aborting due to previous error diff --git a/src/test/ui/issues/issue-37884.stderr b/src/test/ui/issues/issue-37884.stderr index 9a5f659da16..8e75d7be066 100644 --- a/src/test/ui/issues/issue-37884.stderr +++ b/src/test/ui/issues/issue-37884.stderr @@ -21,7 +21,7 @@ LL | | { LL | | Some(&mut self.0) LL | | } | |_____^ -note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 3:6 +note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 3:6 --> $DIR/issue-37884.rs:3:6 | LL | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> { diff --git a/src/test/ui/issues/issue-52213.stderr b/src/test/ui/issues/issue-52213.stderr index 8d74b8ecb88..b79a5ddf3e1 100644 --- a/src/test/ui/issues/issue-52213.stderr +++ b/src/test/ui/issues/issue-52213.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | match (&t,) { | ^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 1:23... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 1:23... --> $DIR/issue-52213.rs:1:23 | LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { @@ -12,7 +12,7 @@ LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { = note: ...so that the types are compatible: expected (&&(T,),) found (&&'a (T,),) -note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 1:27... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 1:27... --> $DIR/issue-52213.rs:1:27 | LL | fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T { diff --git a/src/test/ui/issues/issue-55796.stderr b/src/test/ui/issues/issue-55796.stderr index 7cf597d3a98..7b910f5e3e5 100644 --- a/src/test/ui/issues/issue-55796.stderr +++ b/src/test/ui/issues/issue-55796.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | Box::new(self.out_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the trait at 5:17... --> $DIR/issue-55796.rs:5:17 | LL | pub trait Graph<'a> { @@ -25,7 +25,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | Box::new(self.in_edges(u).map(|e| e.target())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the trait at 5:17... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the trait at 5:17... --> $DIR/issue-55796.rs:5:17 | LL | pub trait Graph<'a> { diff --git a/src/test/ui/lifetimes/lifetime-bound-will-change-warning.stderr b/src/test/ui/lifetimes/lifetime-bound-will-change-warning.stderr index 35d63c17276..b4011990b68 100644 --- a/src/test/ui/lifetimes/lifetime-bound-will-change-warning.stderr +++ b/src/test/ui/lifetimes/lifetime-bound-will-change-warning.stderr @@ -6,7 +6,7 @@ LL | ref_obj(x) | = note: expected type `&std::boxed::Box<(dyn std::ops::Fn() + 'static)>` found type `&std::boxed::Box<(dyn std::ops::Fn() + 'a)>` -note: the lifetime 'a as defined on the function body at 32:10... +note: the lifetime `'a` as defined on the function body at 32:10... --> $DIR/lifetime-bound-will-change-warning.rs:32:10 | LL | fn test2<'a>(x: &'a Box<dyn Fn() + 'a>) { @@ -21,7 +21,7 @@ LL | lib::ref_obj(x) | = note: expected type `&std::boxed::Box<(dyn std::ops::Fn() + 'static)>` found type `&std::boxed::Box<(dyn std::ops::Fn() + 'a)>` -note: the lifetime 'a as defined on the function body at 37:12... +note: the lifetime `'a` as defined on the function body at 37:12... --> $DIR/lifetime-bound-will-change-warning.rs:37:12 | LL | fn test2cc<'a>(x: &'a Box<dyn Fn() + 'a>) { diff --git a/src/test/ui/lub-if.stderr b/src/test/ui/lub-if.stderr index 26f756c9183..0a4744013a6 100644 --- a/src/test/ui/lub-if.stderr +++ b/src/test/ui/lub-if.stderr @@ -5,7 +5,7 @@ LL | s | ^ | = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 23:17 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 23:17 --> $DIR/lub-if.rs:23:17 | LL | pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str { @@ -18,7 +18,7 @@ LL | s | ^ | = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 32:17 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 32:17 --> $DIR/lub-if.rs:32:17 | LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str { diff --git a/src/test/ui/lub-match.stderr b/src/test/ui/lub-match.stderr index 0cb0a23c6f2..168a3894469 100644 --- a/src/test/ui/lub-match.stderr +++ b/src/test/ui/lub-match.stderr @@ -5,7 +5,7 @@ LL | s | ^ | = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 25:17 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 25:17 --> $DIR/lub-match.rs:25:17 | LL | pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str { @@ -18,7 +18,7 @@ LL | s | ^ | = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 35:17 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 35:17 --> $DIR/lub-match.rs:35:17 | LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str { diff --git a/src/test/ui/match/match-ref-mut-invariance.stderr b/src/test/ui/match/match-ref-mut-invariance.stderr index 30bbb8d7800..0a020989d6f 100644 --- a/src/test/ui/match/match-ref-mut-invariance.stderr +++ b/src/test/ui/match/match-ref-mut-invariance.stderr @@ -6,12 +6,12 @@ LL | match self.0 { ref mut x => x } | = note: expected type `&'a mut &'a i32` found type `&'a mut &'b i32` -note: the lifetime 'a as defined on the method body at 9:12... +note: the lifetime `'a` as defined on the method body at 9:12... --> $DIR/match-ref-mut-invariance.rs:9:12 | LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 8:6 +note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 8:6 --> $DIR/match-ref-mut-invariance.rs:8:6 | LL | impl<'b> S<'b> { diff --git a/src/test/ui/match/match-ref-mut-let-invariance.stderr b/src/test/ui/match/match-ref-mut-let-invariance.stderr index 6ca222d9c2f..1bea9bce11e 100644 --- a/src/test/ui/match/match-ref-mut-let-invariance.stderr +++ b/src/test/ui/match/match-ref-mut-let-invariance.stderr @@ -6,12 +6,12 @@ LL | x | = note: expected type `&'a mut &'a i32` found type `&'a mut &'b i32` -note: the lifetime 'a as defined on the method body at 9:12... +note: the lifetime `'a` as defined on the method body at 9:12... --> $DIR/match-ref-mut-let-invariance.rs:9:12 | LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 8:6 +note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 8:6 --> $DIR/match-ref-mut-let-invariance.rs:8:6 | LL | impl<'b> S<'b> { diff --git a/src/test/ui/match/non-exhaustive-defined-here.stderr b/src/test/ui/match/non-exhaustive-defined-here.stderr index 25b8bbdab2d..e5f01174ac1 100644 --- a/src/test/ui/match/non-exhaustive-defined-here.stderr +++ b/src/test/ui/match/non-exhaustive-defined-here.stderr @@ -41,6 +41,13 @@ LL | | } ... LL | let E::A = e; | ^^^^ patterns `B` and `C` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let E::A = e { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0004]: non-exhaustive patterns: `&B` and `&C` not covered --> $DIR/non-exhaustive-defined-here.rs:40:11 @@ -85,6 +92,13 @@ LL | | } ... LL | let E::A = e; | ^^^^ patterns `&B` and `&C` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let E::A = e { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0004]: non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered --> $DIR/non-exhaustive-defined-here.rs:48:11 @@ -129,6 +143,13 @@ LL | | } ... LL | let E::A = e; | ^^^^ patterns `&&mut &B` and `&&mut &C` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let E::A = e { /* */ } + | error[E0004]: non-exhaustive patterns: `None` not covered --> $DIR/non-exhaustive-defined-here.rs:65:11 @@ -163,6 +184,13 @@ LL | | } ... LL | let Opt::Some(ref _x) = e; | ^^^^^^^^^^^^^^^^^ pattern `None` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Opt::Some(ref _x) = e { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 8 previous errors diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr index b19e3a9dfb3..74c33df37a0 100644 --- a/src/test/ui/nll/issue-50716.stderr +++ b/src/test/ui/nll/issue-50716.stderr @@ -6,7 +6,7 @@ LL | let _x = *s; | = note: expected type `std::marker::Sized` found type `std::marker::Sized` -note: the lifetime 'a as defined on the function body at 9:8... +note: the lifetime `'a` as defined on the function body at 9:8... --> $DIR/issue-50716.rs:9:8 | LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) diff --git a/src/test/ui/nll/issue-52742.stderr b/src/test/ui/nll/issue-52742.stderr index 90a35177f4c..0cdc2d94439 100644 --- a/src/test/ui/nll/issue-52742.stderr +++ b/src/test/ui/nll/issue-52742.stderr @@ -4,7 +4,7 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content... LL | self.y = b.z | ^^^ | -note: ...the reference is valid for the lifetime '_ as defined on the impl at 12:10... +note: ...the reference is valid for the lifetime `'_` as defined on the impl at 12:10... --> $DIR/issue-52742.rs:12:10 | LL | impl Foo<'_, '_> { diff --git a/src/test/ui/nll/issue-55394.stderr b/src/test/ui/nll/issue-55394.stderr index e00e6f36f1a..714a63b670c 100644 --- a/src/test/ui/nll/issue-55394.stderr +++ b/src/test/ui/nll/issue-55394.stderr @@ -16,7 +16,7 @@ note: ...so that reference does not outlive borrowed content | LL | Foo { bar } | ^^^ -note: but, the lifetime must be valid for the lifetime '_ as defined on the impl at 7:10... +note: but, the lifetime must be valid for the lifetime `'_` as defined on the impl at 7:10... --> $DIR/issue-55394.rs:7:10 | LL | impl Foo<'_> { diff --git a/src/test/ui/nll/issue-55401.stderr b/src/test/ui/nll/issue-55401.stderr index 4ec16ba055a..2dc7236cbc2 100644 --- a/src/test/ui/nll/issue-55401.stderr +++ b/src/test/ui/nll/issue-55401.stderr @@ -5,7 +5,7 @@ LL | *y | ^^ | = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 1:47 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 1:47 --> $DIR/issue-55401.rs:1:47 | LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/issue-63154-normalize.rs b/src/test/ui/nll/issue-63154-normalize.rs new file mode 100644 index 00000000000..484c12879d3 --- /dev/null +++ b/src/test/ui/nll/issue-63154-normalize.rs @@ -0,0 +1,34 @@ +// Regression test for rust-lang/rust#63154 +// +// Before, we would ICE after failing to normalize the destination type +// when checking call destinations and also when checking MIR +// assignment statements. + +// check-pass + +trait HasAssocType { + type Inner; +} + +impl HasAssocType for () { + type Inner = (); +} + +trait Tr<I, T>: Fn(I) -> Option<T> {} +impl<I, T, Q: Fn(I) -> Option<T>> Tr<I, T> for Q {} + +fn f<T: HasAssocType>() -> impl Tr<T, T::Inner> { + |_| None +} + +fn g<T, Y>(f: impl Tr<T, Y>) -> impl Tr<T, Y> { + f +} + +fn h() { + g(f())(()); +} + +fn main() { + h(); +} diff --git a/src/test/ui/nll/normalization-bounds-error.stderr b/src/test/ui/nll/normalization-bounds-error.stderr index 77a372d9cf5..3a152fbc6fc 100644 --- a/src/test/ui/nll/normalization-bounds-error.stderr +++ b/src/test/ui/nll/normalization-bounds-error.stderr @@ -4,12 +4,12 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'d` d LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'd as defined on the function body at 12:14... +note: first, the lifetime cannot outlive the lifetime `'d` as defined on the function body at 12:14... --> $DIR/normalization-bounds-error.rs:12:14 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} | ^^ -note: ...but the lifetime must also be valid for the lifetime 'a as defined on the function body at 12:18... +note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the function body at 12:18... --> $DIR/normalization-bounds-error.rs:12:18 | LL | fn visit_seq<'d, 'a: 'd>() -> <&'a () as Visitor<'d>>::Value {} diff --git a/src/test/ui/nll/trait-associated-constant.stderr b/src/test/ui/nll/trait-associated-constant.stderr index f39f668e232..ecf9748af9e 100644 --- a/src/test/ui/nll/trait-associated-constant.stderr +++ b/src/test/ui/nll/trait-associated-constant.stderr @@ -6,12 +6,12 @@ LL | const AC: Option<&'c str> = None; | = note: expected type `std::option::Option<&'b str>` found type `std::option::Option<&'c str>` -note: the lifetime 'c as defined on the impl at 20:18... +note: the lifetime `'c` as defined on the impl at 20:18... --> $DIR/trait-associated-constant.rs:20:18 | LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct { | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 20:14 +note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 20:14 --> $DIR/trait-associated-constant.rs:20:14 | LL | impl<'a: 'b, 'b, 'c> Anything<'a, 'b> for FailStruct { diff --git a/src/test/ui/nll/type-alias-free-regions.stderr b/src/test/ui/nll/type-alias-free-regions.stderr index 74651741752..6986389af88 100644 --- a/src/test/ui/nll/type-alias-free-regions.stderr +++ b/src/test/ui/nll/type-alias-free-regions.stderr @@ -14,7 +14,7 @@ LL | | } = note: ...so that the expression is assignable: expected std::boxed::Box<std::boxed::Box<&isize>> found std::boxed::Box<std::boxed::Box<&isize>> -note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 15:6... +note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 15:6... --> $DIR/type-alias-free-regions.rs:15:6 | LL | impl<'a> FromBox<'a> for C<'a> { @@ -39,7 +39,7 @@ LL | | } = note: ...so that the expression is assignable: expected std::boxed::Box<&isize> found std::boxed::Box<&isize> -note: but, the lifetime must be valid for the lifetime 'a as defined on the impl at 25:6... +note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 25:6... --> $DIR/type-alias-free-regions.rs:25:6 | LL | impl<'a> FromTuple<'a> for C<'a> { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr index f5657f9e4ea..4ebd9910788 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d LL | <Foo<'a>>::C | ^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 7:8... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 7:8... --> $DIR/constant-in-expr-inherent-1.rs:7:8 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr index 0a8ad4221c9..4c7adf75d2f 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr @@ -5,7 +5,7 @@ LL | <() as Foo<'a>>::C | ^^^^^^^^^^^^^^^^^^ | = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 17:8 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 17:8 --> $DIR/constant-in-expr-normalize.rs:17:8 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr index d596aaf098f..d01d022cba7 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr @@ -5,7 +5,7 @@ LL | <() as Foo<'a>>::C | ^^^^^^^^^^^^^^^^^^ | = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 9:8 --> $DIR/constant-in-expr-trait-item-1.rs:9:8 | LL | fn foo<'a>(_: &'a u32) -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr index 80ff9a043d4..dd294280b90 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr @@ -5,7 +5,7 @@ LL | <T as Foo<'a>>::C | ^^^^^^^^^^^^^^^^^ | = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 9:8 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 9:8 --> $DIR/constant-in-expr-trait-item-2.rs:9:8 | LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr index f7db4038b8a..d61659e7e9a 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-3.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d LL | T::C | ^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:8... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:8... --> $DIR/constant-in-expr-trait-item-3.rs:9:8 | LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 { diff --git a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr index 217e8504aa3..d66322c48ec 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-elision.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for automatic coercion due to LL | ss | ^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 54:10... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 54:10... --> $DIR/object-lifetime-default-elision.rs:54:10 | LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait { @@ -14,7 +14,7 @@ note: ...so that reference does not outlive borrowed content | LL | ss | ^^ -note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 54:13... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 54:13... --> $DIR/object-lifetime-default-elision.rs:54:13 | LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait { @@ -29,7 +29,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | ss | ^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 54:10... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 54:10... --> $DIR/object-lifetime-default-elision.rs:54:10 | LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait { @@ -39,7 +39,7 @@ note: ...so that the declared lifetime parameter bounds are satisfied | LL | ss | ^^ -note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 54:13... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 54:13... --> $DIR/object-lifetime-default-elision.rs:54:13 | LL | fn load3<'a,'b>(ss: &'a dyn SomeTrait) -> &'b dyn SomeTrait { diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.stderr index 4f9cef12c5e..99f0ce0602b 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-box-error.stderr @@ -6,7 +6,7 @@ LL | ss.t = t; | = note: expected type `&'a std::boxed::Box<(dyn Test + 'static)>` found type `&'a std::boxed::Box<(dyn Test + 'a)>` -note: the lifetime 'a as defined on the function body at 14:6... +note: the lifetime `'a` as defined on the function body at 14:6... --> $DIR/object-lifetime-default-from-rptr-box-error.rs:14:6 | LL | fn c<'a>(t: &'a Box<dyn Test+'a>, mut ss: SomeStruct<'a>) { diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.stderr index 3b7faee68aa..07d4d8c8ed4 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-rptr-struct-error.stderr @@ -6,7 +6,7 @@ LL | ss.t = t; | = note: expected type `&'a MyBox<(dyn Test + 'static)>` found type `&'a MyBox<(dyn Test + 'a)>` -note: the lifetime 'a as defined on the function body at 20:6... +note: the lifetime `'a` as defined on the function body at 20:6... --> $DIR/object-lifetime-default-from-rptr-struct-error.rs:20:6 | LL | fn c<'a>(t: &'a MyBox<dyn Test+'a>, mut ss: SomeStruct<'a>) { diff --git a/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr b/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr index 928b9201982..f825475b96b 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-mybox.stderr @@ -18,7 +18,7 @@ LL | load0(ss) | = note: expected type `&MyBox<(dyn SomeTrait + 'static)>` found type `&MyBox<(dyn SomeTrait + 'a)>` -note: the lifetime 'a as defined on the function body at 30:10... +note: the lifetime `'a` as defined on the function body at 30:10... --> $DIR/object-lifetime-default-mybox.rs:30:10 | LL | fn load2<'a>(ss: &MyBox<dyn SomeTrait + 'a>) -> MyBox<dyn SomeTrait + 'a> { diff --git a/src/test/ui/abi/abort-on-c-abi.rs b/src/test/ui/panics/abort-on-panic.rs index 2f08730ec61..c6e8dbf012c 100644 --- a/src/test/ui/abi/abort-on-c-abi.rs +++ b/src/test/ui/panics/abort-on-panic.rs @@ -14,11 +14,16 @@ use std::io::prelude::*; use std::io; use std::process::{Command, Stdio}; -#[unwind(aborts)] // FIXME(#58794) +#[unwind(aborts)] // FIXME(#58794) should work even without the attribute extern "C" fn panic_in_ffi() { panic!("Test"); } +#[unwind(aborts)] +extern "Rust" fn panic_in_rust_abi() { + panic!("TestRust"); +} + fn test() { let _ = panic::catch_unwind(|| { panic_in_ffi(); }); // The process should have aborted by now. @@ -26,15 +31,34 @@ fn test() { let _ = io::stdout().flush(); } +fn testrust() { + let _ = panic::catch_unwind(|| { panic_in_rust_abi(); }); + // The process should have aborted by now. + io::stdout().write(b"This should never be printed.\n"); + let _ = io::stdout().flush(); +} + fn main() { let args: Vec<String> = env::args().collect(); - if args.len() > 1 && args[1] == "test" { - return test(); + if args.len() > 1 { + // This is inside the self-executed command. + match &*args[1] { + "test" => return test(), + "testrust" => return testrust(), + _ => panic!("bad test"), + } } + // These end up calling the self-execution branches above. let mut p = Command::new(&args[0]) .stdout(Stdio::piped()) .stdin(Stdio::piped()) .arg("test").spawn().unwrap(); assert!(!p.wait().unwrap().success()); + + let mut p = Command::new(&args[0]) + .stdout(Stdio::piped()) + .stdin(Stdio::piped()) + .arg("testrust").spawn().unwrap(); + assert!(!p.wait().unwrap().success()); } diff --git a/src/test/ui/privacy/privacy5.rs b/src/test/ui/privacy/privacy5.rs index 741ba0be2c2..3dc26b1955c 100644 --- a/src/test/ui/privacy/privacy5.rs +++ b/src/test/ui/privacy/privacy5.rs @@ -48,31 +48,31 @@ mod a { } fn this_crate() { - let a = a::A(()); //~ ERROR tuple struct `A` is private - let b = a::B(2); //~ ERROR tuple struct `B` is private - let c = a::C(2, 3); //~ ERROR tuple struct `C` is private + let a = a::A(()); //~ ERROR tuple struct constructor `A` is private + let b = a::B(2); //~ ERROR tuple struct constructor `B` is private + let c = a::C(2, 3); //~ ERROR tuple struct constructor `C` is private let d = a::D(4); - let a::A(()) = a; //~ ERROR tuple struct `A` is private - let a::A(_) = a; //~ ERROR tuple struct `A` is private - match a { a::A(()) => {} } //~ ERROR tuple struct `A` is private - match a { a::A(_) => {} } //~ ERROR tuple struct `A` is private - - let a::B(_) = b; //~ ERROR tuple struct `B` is private - let a::B(_b) = b; //~ ERROR tuple struct `B` is private - match b { a::B(_) => {} } //~ ERROR tuple struct `B` is private - match b { a::B(_b) => {} } //~ ERROR tuple struct `B` is private - match b { a::B(1) => {} a::B(_) => {} } //~ ERROR tuple struct `B` is private - //~^ ERROR tuple struct `B` is private - - let a::C(_, _) = c; //~ ERROR tuple struct `C` is private - let a::C(_a, _) = c; //~ ERROR tuple struct `C` is private - let a::C(_, _b) = c; //~ ERROR tuple struct `C` is private - let a::C(_a, _b) = c; //~ ERROR tuple struct `C` is private - match c { a::C(_, _) => {} } //~ ERROR tuple struct `C` is private - match c { a::C(_a, _) => {} } //~ ERROR tuple struct `C` is private - match c { a::C(_, _b) => {} } //~ ERROR tuple struct `C` is private - match c { a::C(_a, _b) => {} } //~ ERROR tuple struct `C` is private + let a::A(()) = a; //~ ERROR tuple struct constructor `A` is private + let a::A(_) = a; //~ ERROR tuple struct constructor `A` is private + match a { a::A(()) => {} } //~ ERROR tuple struct constructor `A` is private + match a { a::A(_) => {} } //~ ERROR tuple struct constructor `A` is private + + let a::B(_) = b; //~ ERROR tuple struct constructor `B` is private + let a::B(_b) = b; //~ ERROR tuple struct constructor `B` is private + match b { a::B(_) => {} } //~ ERROR tuple struct constructor `B` is private + match b { a::B(_b) => {} } //~ ERROR tuple struct constructor `B` is private + match b { a::B(1) => {} a::B(_) => {} } //~ ERROR tuple struct constructor `B` is private + //~^ ERROR tuple struct constructor `B` is private + + let a::C(_, _) = c; //~ ERROR tuple struct constructor `C` is private + let a::C(_a, _) = c; //~ ERROR tuple struct constructor `C` is private + let a::C(_, _b) = c; //~ ERROR tuple struct constructor `C` is private + let a::C(_a, _b) = c; //~ ERROR tuple struct constructor `C` is private + match c { a::C(_, _) => {} } //~ ERROR tuple struct constructor `C` is private + match c { a::C(_a, _) => {} } //~ ERROR tuple struct constructor `C` is private + match c { a::C(_, _b) => {} } //~ ERROR tuple struct constructor `C` is private + match c { a::C(_a, _b) => {} } //~ ERROR tuple struct constructor `C` is private let a::D(_) = d; let a::D(_d) = d; @@ -80,38 +80,38 @@ fn this_crate() { match d { a::D(_d) => {} } match d { a::D(1) => {} a::D(_) => {} } - let a2 = a::A; //~ ERROR tuple struct `A` is private - let b2 = a::B; //~ ERROR tuple struct `B` is private - let c2 = a::C; //~ ERROR tuple struct `C` is private + let a2 = a::A; //~ ERROR tuple struct constructor `A` is private + let b2 = a::B; //~ ERROR tuple struct constructor `B` is private + let c2 = a::C; //~ ERROR tuple struct constructor `C` is private let d2 = a::D; } fn xcrate() { - let a = other::A(()); //~ ERROR tuple struct `A` is private - let b = other::B(2); //~ ERROR tuple struct `B` is private - let c = other::C(2, 3); //~ ERROR tuple struct `C` is private + let a = other::A(()); //~ ERROR tuple struct constructor `A` is private + let b = other::B(2); //~ ERROR tuple struct constructor `B` is private + let c = other::C(2, 3); //~ ERROR tuple struct constructor `C` is private let d = other::D(4); - let other::A(()) = a; //~ ERROR tuple struct `A` is private - let other::A(_) = a; //~ ERROR tuple struct `A` is private - match a { other::A(()) => {} } //~ ERROR tuple struct `A` is private - match a { other::A(_) => {} } //~ ERROR tuple struct `A` is private - - let other::B(_) = b; //~ ERROR tuple struct `B` is private - let other::B(_b) = b; //~ ERROR tuple struct `B` is private - match b { other::B(_) => {} } //~ ERROR tuple struct `B` is private - match b { other::B(_b) => {} } //~ ERROR tuple struct `B` is private - match b { other::B(1) => {} other::B(_) => {} } //~ ERROR tuple struct `B` is private - //~^ ERROR tuple struct `B` is private - - let other::C(_, _) = c; //~ ERROR tuple struct `C` is private - let other::C(_a, _) = c; //~ ERROR tuple struct `C` is private - let other::C(_, _b) = c; //~ ERROR tuple struct `C` is private - let other::C(_a, _b) = c; //~ ERROR tuple struct `C` is private - match c { other::C(_, _) => {} } //~ ERROR tuple struct `C` is private - match c { other::C(_a, _) => {} } //~ ERROR tuple struct `C` is private - match c { other::C(_, _b) => {} } //~ ERROR tuple struct `C` is private - match c { other::C(_a, _b) => {} } //~ ERROR tuple struct `C` is private + let other::A(()) = a; //~ ERROR tuple struct constructor `A` is private + let other::A(_) = a; //~ ERROR tuple struct constructor `A` is private + match a { other::A(()) => {} } //~ ERROR tuple struct constructor `A` is private + match a { other::A(_) => {} } //~ ERROR tuple struct constructor `A` is private + + let other::B(_) = b; //~ ERROR tuple struct constructor `B` is private + let other::B(_b) = b; //~ ERROR tuple struct constructor `B` is private + match b { other::B(_) => {} } //~ ERROR tuple struct constructor `B` is private + match b { other::B(_b) => {} } //~ ERROR tuple struct constructor `B` is private + match b { other::B(1) => {}//~ ERROR tuple struct constructor `B` is private + other::B(_) => {} } //~ ERROR tuple struct constructor `B` is private + + let other::C(_, _) = c; //~ ERROR tuple struct constructor `C` is private + let other::C(_a, _) = c; //~ ERROR tuple struct constructor `C` is private + let other::C(_, _b) = c; //~ ERROR tuple struct constructor `C` is private + let other::C(_a, _b) = c; //~ ERROR tuple struct constructor `C` is private + match c { other::C(_, _) => {} } //~ ERROR tuple struct constructor `C` is private + match c { other::C(_a, _) => {} } //~ ERROR tuple struct constructor `C` is private + match c { other::C(_, _b) => {} } //~ ERROR tuple struct constructor `C` is private + match c { other::C(_a, _b) => {} } //~ ERROR tuple struct constructor `C` is private let other::D(_) = d; let other::D(_d) = d; @@ -119,9 +119,9 @@ fn xcrate() { match d { other::D(_d) => {} } match d { other::D(1) => {} other::D(_) => {} } - let a2 = other::A; //~ ERROR tuple struct `A` is private - let b2 = other::B; //~ ERROR tuple struct `B` is private - let c2 = other::C; //~ ERROR tuple struct `C` is private + let a2 = other::A; //~ ERROR tuple struct constructor `A` is private + let b2 = other::B; //~ ERROR tuple struct constructor `B` is private + let c2 = other::C; //~ ERROR tuple struct constructor `C` is private let d2 = other::D; } diff --git a/src/test/ui/privacy/privacy5.stderr b/src/test/ui/privacy/privacy5.stderr index c1b90d7c6bf..2ee83149b69 100644 --- a/src/test/ui/privacy/privacy5.stderr +++ b/src/test/ui/privacy/privacy5.stderr @@ -1,220 +1,220 @@ -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:51:16 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private ... LL | let a = a::A(()); | ^ -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:52:16 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private ... LL | let b = a::B(2); | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:53:16 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | let c = a::C(2, 3); | ^ -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:56:12 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private ... LL | let a::A(()) = a; | ^ -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:57:12 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private ... LL | let a::A(_) = a; | ^ -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:58:18 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private ... LL | match a { a::A(()) => {} } | ^ -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:59:18 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private ... LL | match a { a::A(_) => {} } | ^ -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:61:12 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private ... LL | let a::B(_) = b; | ^ -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:62:12 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private ... LL | let a::B(_b) = b; | ^ -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:63:18 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(_) => {} } | ^ -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:64:18 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(_b) => {} } | ^ -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:18 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(1) => {} a::B(_) => {} } | ^ -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:32 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(1) => {} a::B(_) => {} } | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:68:12 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_, _) = c; | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:69:12 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_a, _) = c; | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:70:12 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_, _b) = c; | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:71:12 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_a, _b) = c; | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:72:18 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_, _) => {} } | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:73:18 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_a, _) => {} } | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:74:18 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_, _b) => {} } | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:75:18 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_a, _b) => {} } | ^ -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:83:17 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private ... LL | let a2 = a::A; | ^ -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:84:17 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private ... LL | let b2 = a::B; | ^ -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:85:17 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private ... LL | let c2 = a::C; | ^ -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:90:20 | LL | let a = other::A(()); @@ -223,9 +223,9 @@ LL | let a = other::A(()); ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:91:20 | LL | let b = other::B(2); @@ -234,9 +234,9 @@ LL | let b = other::B(2); ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:92:20 | LL | let c = other::C(2, 3); @@ -245,9 +245,9 @@ LL | let c = other::C(2, 3); ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:95:16 | LL | let other::A(()) = a; @@ -256,9 +256,9 @@ LL | let other::A(()) = a; ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:96:16 | LL | let other::A(_) = a; @@ -267,9 +267,9 @@ LL | let other::A(_) = a; ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:97:22 | LL | match a { other::A(()) => {} } @@ -278,9 +278,9 @@ LL | match a { other::A(()) => {} } ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:98:22 | LL | match a { other::A(_) => {} } @@ -289,9 +289,9 @@ LL | match a { other::A(_) => {} } ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:100:16 | LL | let other::B(_) = b; @@ -300,9 +300,9 @@ LL | let other::B(_) = b; ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:101:16 | LL | let other::B(_b) = b; @@ -311,9 +311,9 @@ LL | let other::B(_b) = b; ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:102:22 | LL | match b { other::B(_) => {} } @@ -322,9 +322,9 @@ LL | match b { other::B(_) => {} } ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:103:22 | LL | match b { other::B(_b) => {} } @@ -333,31 +333,31 @@ LL | match b { other::B(_b) => {} } ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:104:22 | -LL | match b { other::B(1) => {} other::B(_) => {} } +LL | match b { other::B(1) => {} | ^ | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private -error[E0603]: tuple struct `B` is private - --> $DIR/privacy5.rs:104:40 +error[E0603]: tuple struct constructor `B` is private + --> $DIR/privacy5.rs:105:16 | -LL | match b { other::B(1) => {} other::B(_) => {} } - | ^ +LL | other::B(_) => {} } + | ^ | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:107:16 | LL | let other::C(_, _) = c; @@ -366,9 +366,9 @@ LL | let other::C(_, _) = c; ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:108:16 | LL | let other::C(_a, _) = c; @@ -377,9 +377,9 @@ LL | let other::C(_a, _) = c; ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:109:16 | LL | let other::C(_, _b) = c; @@ -388,9 +388,9 @@ LL | let other::C(_, _b) = c; ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:110:16 | LL | let other::C(_a, _b) = c; @@ -399,9 +399,9 @@ LL | let other::C(_a, _b) = c; ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:111:22 | LL | match c { other::C(_, _) => {} } @@ -410,9 +410,9 @@ LL | match c { other::C(_, _) => {} } ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:112:22 | LL | match c { other::C(_a, _) => {} } @@ -421,9 +421,9 @@ LL | match c { other::C(_a, _) => {} } ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:113:22 | LL | match c { other::C(_, _b) => {} } @@ -432,9 +432,9 @@ LL | match c { other::C(_, _b) => {} } ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:114:22 | LL | match c { other::C(_a, _b) => {} } @@ -443,9 +443,9 @@ LL | match c { other::C(_a, _b) => {} } ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private -error[E0603]: tuple struct `A` is private +error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:122:21 | LL | let a2 = other::A; @@ -454,9 +454,9 @@ LL | let a2 = other::A; ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private -error[E0603]: tuple struct `B` is private +error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:123:21 | LL | let b2 = other::B; @@ -465,9 +465,9 @@ LL | let b2 = other::B; ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); - | ----- a tuple struct constructor is private if any of its fields is private + | ----- a constructor is private if any of the fields is private -error[E0603]: tuple struct `C` is private +error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:124:21 | LL | let c2 = other::C; @@ -476,7 +476,7 @@ LL | let c2 = other::C; ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private error: aborting due to 48 previous errors diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr index b9385952faf..f9ae75b1831 100644 --- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -3,6 +3,13 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered | LL | let Ok(x) = res; | ^^^^^ pattern `Err(_)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Ok(x) = res { /* */ } + | error[E0381]: use of possibly-uninitialized variable: `x` --> $DIR/recursive-types-are-not-uninhabited.rs:8:5 diff --git a/src/test/ui/refutable-pattern-errors.stderr b/src/test/ui/refutable-pattern-errors.stderr index 3b13e25293d..0cf5d9cd5f1 100644 --- a/src/test/ui/refutable-pattern-errors.stderr +++ b/src/test/ui/refutable-pattern-errors.stderr @@ -9,6 +9,13 @@ error[E0005]: refutable pattern in local binding: `(std::i32::MIN..=0i32, _)` an | LL | let (1, (Some(1), 2..=3)) = (1, (None, 2)); | ^^^^^^^^^^^^^^^^^^^^^ patterns `(std::i32::MIN..=0i32, _)` and `(2i32..=std::i32::MAX, _)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let (1, (Some(1), 2..=3)) = (1, (None, 2)) { /* */ } + | error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr index 751a4c1021e..184cead2123 100644 --- a/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr +++ b/src/test/ui/regions/region-bounds-on-objects-and-type-parameters.stderr @@ -10,12 +10,12 @@ error[E0478]: lifetime bound not satisfied LL | z: Box<dyn Is<'a>+'b+'c>, | ^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lifetime parameter instantiated with the lifetime 'b as defined on the struct at 11:15 +note: lifetime parameter instantiated with the lifetime `'b` as defined on the struct at 11:15 --> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:15 | LL | struct Foo<'a,'b,'c> { | ^^ -note: but lifetime parameter must outlive the lifetime 'a as defined on the struct at 11:12 +note: but lifetime parameter must outlive the lifetime `'a` as defined on the struct at 11:12 --> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:12 | LL | struct Foo<'a,'b,'c> { diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.rs b/src/test/ui/regions/region-invariant-static-error-reporting.rs index df92ed51e9a..911904813d0 100644 --- a/src/test/ui/regions/region-invariant-static-error-reporting.rs +++ b/src/test/ui/regions/region-invariant-static-error-reporting.rs @@ -3,7 +3,7 @@ // over time, but this test used to exhibit some pretty bogus messages // that were not remotely helpful. -// error-pattern:the lifetime 'a +// error-pattern:the lifetime `'a` // error-pattern:the static lifetime struct Invariant<'a>(Option<&'a mut &'a mut ()>); diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.stderr b/src/test/ui/regions/region-invariant-static-error-reporting.stderr index 60e70ddcd97..8358a7988c8 100644 --- a/src/test/ui/regions/region-invariant-static-error-reporting.stderr +++ b/src/test/ui/regions/region-invariant-static-error-reporting.stderr @@ -13,7 +13,7 @@ LL | | }; | = note: expected type `Invariant<'a>` found type `Invariant<'static>` -note: the lifetime 'a as defined on the function body at 13:10... +note: the lifetime `'a` as defined on the function body at 13:10... --> $DIR/region-invariant-static-error-reporting.rs:13:10 | LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) { diff --git a/src/test/ui/regions/region-object-lifetime-2.stderr b/src/test/ui/regions/region-object-lifetime-2.stderr index cc8d150d04c..74ea1b731e9 100644 --- a/src/test/ui/regions/region-object-lifetime-2.stderr +++ b/src/test/ui/regions/region-object-lifetime-2.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflictin LL | x.borrowed() | ^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:42... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:42... --> $DIR/region-object-lifetime-2.rs:9:42 | LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () { @@ -14,7 +14,7 @@ note: ...so that reference does not outlive borrowed content | LL | x.borrowed() | ^ -note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 9:45... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 9:45... --> $DIR/region-object-lifetime-2.rs:9:45 | LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () { diff --git a/src/test/ui/regions/region-object-lifetime-4.stderr b/src/test/ui/regions/region-object-lifetime-4.stderr index 23fd4d03628..10532182905 100644 --- a/src/test/ui/regions/region-object-lifetime-4.stderr +++ b/src/test/ui/regions/region-object-lifetime-4.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflictin LL | x.borrowed() | ^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 11:41... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 11:41... --> $DIR/region-object-lifetime-4.rs:11:41 | LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () { @@ -14,7 +14,7 @@ note: ...so that reference does not outlive borrowed content | LL | x.borrowed() | ^ -note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 11:44... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 11:44... --> $DIR/region-object-lifetime-4.rs:11:44 | LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () { diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 3ccb8866ca4..14934d6fa48 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -29,7 +29,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | Box::new(v) | ^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 25:6... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 25:6... --> $DIR/region-object-lifetime-in-coercion.rs:25:6 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> { @@ -37,7 +37,7 @@ LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> { = note: ...so that the expression is assignable: expected &[u8] found &'a [u8] -note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 25:9... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 25:9... --> $DIR/region-object-lifetime-in-coercion.rs:25:9 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> { diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.stderr index ac5e5e9aabc..7a051b8ac83 100644 --- a/src/test/ui/regions/regions-addr-of-upvar-self.stderr +++ b/src/test/ui/regions/regions-addr-of-upvar-self.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | let p: &'static mut usize = &mut self.food; | ^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 9:18... +note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 9:18... --> $DIR/regions-addr-of-upvar-self.rs:9:18 | LL | let _f = || { diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr index 61be0778c99..c0401780b8f 100644 --- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr @@ -4,12 +4,12 @@ error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifet LL | let _: &'a WithAssoc<TheType<'b>> = loop { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 33:15 +note: the pointer is valid for the lifetime `'a` as defined on the function body at 33:15 --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:15 | LL | fn with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 33:18 +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 33:18 --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:18 | LL | fn with_assoc<'a,'b>() { diff --git a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr index d01e9911039..a636c9ef22c 100644 --- a/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr +++ b/src/test/ui/regions/regions-assoc-type-region-bound-in-trait-not-met.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d LL | impl<'a> Foo<'static> for &'a i32 { | ^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 14:6... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 14:6... --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:14:6 | LL | impl<'a> Foo<'static> for &'a i32 { @@ -25,7 +25,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d LL | impl<'a,'b> Foo<'b> for &'a i64 { | ^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 19:6... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 19:6... --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:6 | LL | impl<'a,'b> Foo<'b> for &'a i64 { @@ -33,7 +33,7 @@ LL | impl<'a,'b> Foo<'b> for &'a i64 { = note: ...so that the types are compatible: expected Foo<'b> found Foo<'_> -note: but, the lifetime must be valid for the lifetime 'b as defined on the impl at 19:9... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the impl at 19:9... --> $DIR/regions-assoc-type-region-bound-in-trait-not-met.rs:19:9 | LL | impl<'a,'b> Foo<'b> for &'a i64 { diff --git a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr index 33a4ea01ce2..81256e3b46c 100644 --- a/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr +++ b/src/test/ui/regions/regions-assoc-type-static-bound-in-trait-not-met.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d LL | impl<'a> Foo for &'a i32 { | ^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 9:6... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 9:6... --> $DIR/regions-assoc-type-static-bound-in-trait-not-met.rs:9:6 | LL | impl<'a> Foo for &'a i32 { diff --git a/src/test/ui/regions/regions-bounds.stderr b/src/test/ui/regions/regions-bounds.stderr index 27eb8891c6c..a15710b86c0 100644 --- a/src/test/ui/regions/regions-bounds.stderr +++ b/src/test/ui/regions/regions-bounds.stderr @@ -6,12 +6,12 @@ LL | return e; | = note: expected type `TupleStruct<'b>` found type `TupleStruct<'a>` -note: the lifetime 'a as defined on the function body at 8:10... +note: the lifetime `'a` as defined on the function body at 8:10... --> $DIR/regions-bounds.rs:8:10 | LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> { | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 8:13 +note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 8:13 --> $DIR/regions-bounds.rs:8:13 | LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> { @@ -25,12 +25,12 @@ LL | return e; | = note: expected type `Struct<'b>` found type `Struct<'a>` -note: the lifetime 'a as defined on the function body at 12:10... +note: the lifetime `'a` as defined on the function body at 12:10... --> $DIR/regions-bounds.rs:12:10 | LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> { | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 12:13 +note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 12:13 --> $DIR/regions-bounds.rs:12:13 | LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> { diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 7af608d2c80..8e473dad693 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | box B(&*v) as Box<dyn X> | ^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:6... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6... --> $DIR/regions-close-object-into-object-2.rs:9:6 | LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> { diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index ef47db18d39..c80d13e15b1 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | box B(&*v) as Box<dyn X> | ^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 9:6... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 9:6... --> $DIR/regions-close-object-into-object-4.rs:9:6 | LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> { diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr index 6f7466a8b0e..ef21316ea83 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen LL | box v as Box<dyn SomeTrait + 'a> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 18:20... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 18:20... --> $DIR/regions-close-over-type-parameter-multiple.rs:18:20 | LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'c> { @@ -14,7 +14,7 @@ note: ...so that the declared lifetime parameter bounds are satisfied | LL | box v as Box<dyn SomeTrait + 'a> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: but, the lifetime must be valid for the lifetime 'c as defined on the function body at 18:26... +note: but, the lifetime must be valid for the lifetime `'c` as defined on the function body at 18:26... --> $DIR/regions-close-over-type-parameter-multiple.rs:18:26 | LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'c> { diff --git a/src/test/ui/regions/regions-creating-enums4.stderr b/src/test/ui/regions/regions-creating-enums4.stderr index 4d00783d180..12b89787d5f 100644 --- a/src/test/ui/regions/regions-creating-enums4.stderr +++ b/src/test/ui/regions/regions-creating-enums4.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d LL | Ast::Add(x, y) | ^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 6:16... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 6:16... --> $DIR/regions-creating-enums4.rs:6:16 | LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { @@ -12,7 +12,7 @@ LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { = note: ...so that the expression is assignable: expected &Ast<'_> found &Ast<'a> -note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 6:19... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 6:19... --> $DIR/regions-creating-enums4.rs:6:19 | LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { diff --git a/src/test/ui/regions/regions-early-bound-error-method.stderr b/src/test/ui/regions/regions-early-bound-error-method.stderr index 7b9f2c9503b..9095451da05 100644 --- a/src/test/ui/regions/regions-early-bound-error-method.stderr +++ b/src/test/ui/regions/regions-early-bound-error-method.stderr @@ -4,12 +4,12 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content... LL | g2.get() | ^^^^^^^^ | -note: ...the reference is valid for the lifetime 'a as defined on the impl at 18:6... +note: ...the reference is valid for the lifetime `'a` as defined on the impl at 18:6... --> $DIR/regions-early-bound-error-method.rs:18:6 | LL | impl<'a> Box<'a> { | ^^ -note: ...but the borrowed content is only valid for the lifetime 'b as defined on the method body at 19:11 +note: ...but the borrowed content is only valid for the lifetime `'b` as defined on the method body at 19:11 --> $DIR/regions-early-bound-error-method.rs:19:11 | LL | fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize { diff --git a/src/test/ui/regions/regions-early-bound-error.stderr b/src/test/ui/regions/regions-early-bound-error.stderr index a68355b78f5..162d573362d 100644 --- a/src/test/ui/regions/regions-early-bound-error.stderr +++ b/src/test/ui/regions/regions-early-bound-error.stderr @@ -4,12 +4,12 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content... LL | g1.get() | ^^^^^^^^ | -note: ...the reference is valid for the lifetime 'b as defined on the function body at 18:11... +note: ...the reference is valid for the lifetime `'b` as defined on the function body at 18:11... --> $DIR/regions-early-bound-error.rs:18:11 | LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize { | ^^ -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 18:8 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 18:8 --> $DIR/regions-early-bound-error.rs:18:8 | LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize { diff --git a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr index 3b8f09f1ad8..ad555efadf7 100644 --- a/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-callee-4.stderr @@ -8,12 +8,12 @@ LL | | let z: Option<&'a &'b usize> = None; LL | | } | |_^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 5:14 +note: the pointer is valid for the lifetime `'a` as defined on the function body at 5:14 --> $DIR/regions-free-region-ordering-callee-4.rs:5:14 | LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 5:18 +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 5:18 --> $DIR/regions-free-region-ordering-callee-4.rs:5:18 | LL | fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr b/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr index 676e96a038b..10644174b9b 100644 --- a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | None => &self.val | ^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the method body at 14:12... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the method body at 14:12... --> $DIR/regions-free-region-ordering-incorrect.rs:14:12 | LL | fn get<'a>(&'a self) -> &'b T { @@ -14,7 +14,7 @@ note: ...so that reference does not outlive borrowed content | LL | None => &self.val | ^^^^^^^^^ -note: but, the lifetime must be valid for the lifetime 'b as defined on the impl at 13:6... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the impl at 13:6... --> $DIR/regions-free-region-ordering-incorrect.rs:13:6 | LL | impl<'b, T> Node<'b, T> { diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr index b3390bcc4d5..c4ca7e97074 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-hr-1.stderr @@ -7,12 +7,12 @@ LL | | { LL | | } | |_^ | -note: the pointer is valid for the lifetime 'x as defined on the function body at 21:11 +note: the pointer is valid for the lifetime `'x` as defined on the function body at 21:11 --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:11 | LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >) | ^^ -note: but the referenced data is only valid for the lifetime 'y as defined on the function body at 21:15 +note: but the referenced data is only valid for the lifetime `'y` as defined on the function body at 21:15 --> $DIR/regions-implied-bounds-projection-gap-hr-1.rs:21:15 | LL | fn callee<'x, 'y, T>(t: &'x dyn for<'z> Trait1< <T as Trait2<'y, 'z>>::Foo >) diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr index d31ed3ede36..f4e223bbf6f 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr @@ -6,7 +6,7 @@ LL | b_isize | = note: expected type `Invariant<'static>` found type `Invariant<'r>` -note: the lifetime 'r as defined on the function body at 11:23... +note: the lifetime `'r` as defined on the function body at 11:23... --> $DIR/regions-infer-invariance-due-to-decl.rs:11:23 | LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr index f8bdd014db7..6322244fcf9 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr @@ -6,7 +6,7 @@ LL | b_isize | = note: expected type `Invariant<'static>` found type `Invariant<'r>` -note: the lifetime 'r as defined on the function body at 9:23... +note: the lifetime `'r` as defined on the function body at 9:23... --> $DIR/regions-infer-invariance-due-to-mutability-3.rs:9:23 | LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr index 1de6f22f08e..7baae69945f 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr @@ -6,7 +6,7 @@ LL | b_isize | = note: expected type `Invariant<'static>` found type `Invariant<'r>` -note: the lifetime 'r as defined on the function body at 9:23... +note: the lifetime `'r` as defined on the function body at 9:23... --> $DIR/regions-infer-invariance-due-to-mutability-4.rs:9:23 | LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { diff --git a/src/test/ui/regions/regions-infer-not-param.stderr b/src/test/ui/regions/regions-infer-not-param.stderr index f43ab829121..6365769430f 100644 --- a/src/test/ui/regions/regions-infer-not-param.stderr +++ b/src/test/ui/regions/regions-infer-not-param.stderr @@ -6,12 +6,12 @@ LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } | = note: expected type `Direct<'b>` found type `Direct<'a>` -note: the lifetime 'a as defined on the function body at 15:16... +note: the lifetime `'a` as defined on the function body at 15:16... --> $DIR/regions-infer-not-param.rs:15:16 | LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 15:19 +note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 15:19 --> $DIR/regions-infer-not-param.rs:15:19 | LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } @@ -25,12 +25,12 @@ LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | = note: expected type `Indirect2<'b>` found type `Indirect2<'a>` -note: the lifetime 'a as defined on the function body at 19:19... +note: the lifetime `'a` as defined on the function body at 19:19... --> $DIR/regions-infer-not-param.rs:19:19 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the function body at 19:22 +note: ...does not necessarily outlive the lifetime `'b` as defined on the function body at 19:22 --> $DIR/regions-infer-not-param.rs:19:22 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } @@ -44,12 +44,12 @@ LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | = note: expected type `Indirect2<'b>` found type `Indirect2<'a>` -note: the lifetime 'b as defined on the function body at 19:22... +note: the lifetime `'b` as defined on the function body at 19:22... --> $DIR/regions-infer-not-param.rs:19:22 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | ^^ -note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 19:19 +note: ...does not necessarily outlive the lifetime `'a` as defined on the function body at 19:19 --> $DIR/regions-infer-not-param.rs:19:19 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } diff --git a/src/test/ui/regions/regions-infer-paramd-indirect.stderr b/src/test/ui/regions/regions-infer-paramd-indirect.stderr index 1b999ed059c..b1fd337b8d0 100644 --- a/src/test/ui/regions/regions-infer-paramd-indirect.stderr +++ b/src/test/ui/regions/regions-infer-paramd-indirect.stderr @@ -17,7 +17,7 @@ LL | | LL | | LL | | } | |_____^ -note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 16:6 +note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 16:6 --> $DIR/regions-infer-paramd-indirect.rs:16:6 | LL | impl<'a> SetF<'a> for C<'a> { diff --git a/src/test/ui/regions/regions-nested-fns.stderr b/src/test/ui/regions/regions-nested-fns.stderr index bc3c06d7ff3..f4eb5c8644f 100644 --- a/src/test/ui/regions/regions-nested-fns.stderr +++ b/src/test/ui/regions/regions-nested-fns.stderr @@ -49,7 +49,7 @@ LL | | if false { return ay; } LL | | return z; LL | | })); | |_____^ -note: ...but the borrowed content is only valid for the lifetime 'x as defined on the function body at 3:11 +note: ...but the borrowed content is only valid for the lifetime `'x` as defined on the function body at 3:11 --> $DIR/regions-nested-fns.rs:3:11 | LL | fn nested<'x>(x: &'x isize) { diff --git a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr index c44edf1f03b..d29fd80943f 100644 --- a/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr +++ b/src/test/ui/regions/regions-normalize-in-where-clause-list.stderr @@ -7,12 +7,12 @@ LL | | { LL | | } | |_^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 22:8... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 22:8... --> $DIR/regions-normalize-in-where-clause-list.rs:22:8 | LL | fn bar<'a, 'b>() | ^^ -note: ...but the lifetime must also be valid for the lifetime 'b as defined on the function body at 22:12... +note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the function body at 22:12... --> $DIR/regions-normalize-in-where-clause-list.rs:22:12 | LL | fn bar<'a, 'b>() diff --git a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr index ed5800940ee..0992d9bf295 100644 --- a/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr +++ b/src/test/ui/regions/regions-outlives-projection-container-hrtb.migrate.stderr @@ -4,12 +4,12 @@ error[E0491]: in type `&'a WithHrAssoc<TheType<'b>>`, reference has a longer lif LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 27:15 +note: the pointer is valid for the lifetime `'a` as defined on the function body at 27:15 --> $DIR/regions-outlives-projection-container-hrtb.rs:27:15 | LL | fn with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 27:18 +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 27:18 --> $DIR/regions-outlives-projection-container-hrtb.rs:27:18 | LL | fn with_assoc<'a,'b>() { @@ -21,12 +21,12 @@ error[E0491]: in type `&'a WithHrAssocSub<TheType<'b>>`, reference has a longer LL | let _: &'a WithHrAssocSub<TheType<'b>> = loop { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 46:19 +note: the pointer is valid for the lifetime `'a` as defined on the function body at 46:19 --> $DIR/regions-outlives-projection-container-hrtb.rs:46:19 | LL | fn with_assoc_sub<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 46:22 +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 46:22 --> $DIR/regions-outlives-projection-container-hrtb.rs:46:22 | LL | fn with_assoc_sub<'a,'b>() { diff --git a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr index 152e6c5600c..49e28a14d8a 100644 --- a/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr +++ b/src/test/ui/regions/regions-outlives-projection-container-wc.migrate.stderr @@ -4,12 +4,12 @@ error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifet LL | let _: &'a WithAssoc<TheType<'b>> = loop { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 27:15 +note: the pointer is valid for the lifetime `'a` as defined on the function body at 27:15 --> $DIR/regions-outlives-projection-container-wc.rs:27:15 | LL | fn with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 27:18 +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 27:18 --> $DIR/regions-outlives-projection-container-wc.rs:27:18 | LL | fn with_assoc<'a,'b>() { diff --git a/src/test/ui/regions/regions-outlives-projection-container.stderr b/src/test/ui/regions/regions-outlives-projection-container.stderr index 3c1a98a3c01..dba15fb0576 100644 --- a/src/test/ui/regions/regions-outlives-projection-container.stderr +++ b/src/test/ui/regions/regions-outlives-projection-container.stderr @@ -4,12 +4,12 @@ error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifet LL | let _x: &'a WithAssoc<TheType<'b>> = loop { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 28:15 +note: the pointer is valid for the lifetime `'a` as defined on the function body at 28:15 --> $DIR/regions-outlives-projection-container.rs:28:15 | LL | fn with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 28:18 +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 28:18 --> $DIR/regions-outlives-projection-container.rs:28:18 | LL | fn with_assoc<'a,'b>() { @@ -21,12 +21,12 @@ error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer li LL | let _x: &'a WithoutAssoc<TheType<'b>> = loop { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 50:18 +note: the pointer is valid for the lifetime `'a` as defined on the function body at 50:18 --> $DIR/regions-outlives-projection-container.rs:50:18 | LL | fn without_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 50:21 +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 50:21 --> $DIR/regions-outlives-projection-container.rs:50:21 | LL | fn without_assoc<'a,'b>() { @@ -38,12 +38,12 @@ error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifet LL | call::<&'a WithAssoc<TheType<'b>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 58:20 +note: the pointer is valid for the lifetime `'a` as defined on the function body at 58:20 --> $DIR/regions-outlives-projection-container.rs:58:20 | LL | fn call_with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 58:23 +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 58:23 --> $DIR/regions-outlives-projection-container.rs:58:23 | LL | fn call_with_assoc<'a,'b>() { @@ -55,12 +55,12 @@ error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer li LL | call::<&'a WithoutAssoc<TheType<'b>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 67:23 +note: the pointer is valid for the lifetime `'a` as defined on the function body at 67:23 --> $DIR/regions-outlives-projection-container.rs:67:23 | LL | fn call_without_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 67:26 +note: but the referenced data is only valid for the lifetime `'b` as defined on the function body at 67:26 --> $DIR/regions-outlives-projection-container.rs:67:26 | LL | fn call_without_assoc<'a,'b>() { diff --git a/src/test/ui/regions/regions-ret-borrowed-1.stderr b/src/test/ui/regions/regions-ret-borrowed-1.stderr index 72e47cea094..49076673ad3 100644 --- a/src/test/ui/regions/regions-ret-borrowed-1.stderr +++ b/src/test/ui/regions/regions-ret-borrowed-1.stderr @@ -12,7 +12,7 @@ LL | with(|o| o) = note: ...so that the expression is assignable: expected &isize found &isize -note: but, the lifetime must be valid for the lifetime 'a as defined on the function body at 9:14... +note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 9:14... --> $DIR/regions-ret-borrowed-1.rs:9:14 | LL | fn return_it<'a>() -> &'a isize { diff --git a/src/test/ui/regions/regions-ret-borrowed.stderr b/src/test/ui/regions/regions-ret-borrowed.stderr index ce0c429ccb2..eb1ade27ace 100644 --- a/src/test/ui/regions/regions-ret-borrowed.stderr +++ b/src/test/ui/regions/regions-ret-borrowed.stderr @@ -12,7 +12,7 @@ LL | with(|o| o) = note: ...so that the expression is assignable: expected &isize found &isize -note: but, the lifetime must be valid for the lifetime 'a as defined on the function body at 12:14... +note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 12:14... --> $DIR/regions-ret-borrowed.rs:12:14 | LL | fn return_it<'a>() -> &'a isize { diff --git a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr index be441bc4808..946465bcb5f 100644 --- a/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr +++ b/src/test/ui/regions/regions-return-ref-to-upvar-issue-17403.stderr @@ -4,7 +4,7 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to LL | let mut f = || &mut x; | ^^^^^^ | -note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 7:21... +note: first, the lifetime cannot outlive the lifetime `'_` as defined on the body at 7:21... --> $DIR/regions-return-ref-to-upvar-issue-17403.rs:7:21 | LL | let mut f = || &mut x; diff --git a/src/test/ui/regions/regions-static-bound.migrate.stderr b/src/test/ui/regions/regions-static-bound.migrate.stderr index 21ead8b768f..6e631d40d45 100644 --- a/src/test/ui/regions/regions-static-bound.migrate.stderr +++ b/src/test/ui/regions/regions-static-bound.migrate.stderr @@ -5,7 +5,7 @@ LL | t | ^ | = note: ...the reference is valid for the static lifetime... -note: ...but the borrowed content is only valid for the lifetime 'a as defined on the function body at 8:24 +note: ...but the borrowed content is only valid for the lifetime `'a` as defined on the function body at 8:24 --> $DIR/regions-static-bound.rs:8:24 | LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { diff --git a/src/test/ui/regions/regions-trait-1.stderr b/src/test/ui/regions/regions-trait-1.stderr index 421f826ccc5..f835c005ff9 100644 --- a/src/test/ui/regions/regions-trait-1.stderr +++ b/src/test/ui/regions/regions-trait-1.stderr @@ -6,7 +6,7 @@ LL | fn get_ctxt(&self) -> &'a Ctxt { | = note: expected type `fn(&HasCtxt<'a>) -> &Ctxt` found type `fn(&HasCtxt<'a>) -> &'a Ctxt` -note: the lifetime 'a as defined on the impl at 12:6... +note: the lifetime `'a` as defined on the impl at 12:6... --> $DIR/regions-trait-1.rs:12:6 | LL | impl<'a> GetCtxt for HasCtxt<'a> { diff --git a/src/test/ui/regions/regions-trait-object-subtyping.stderr b/src/test/ui/regions/regions-trait-object-subtyping.stderr index d88be05cb87..b7c7f93149d 100644 --- a/src/test/ui/regions/regions-trait-object-subtyping.stderr +++ b/src/test/ui/regions/regions-trait-object-subtyping.stderr @@ -4,12 +4,12 @@ error[E0478]: lifetime bound not satisfied LL | x | ^ | -note: lifetime parameter instantiated with the lifetime 'a as defined on the function body at 13:9 +note: lifetime parameter instantiated with the lifetime `'a` as defined on the function body at 13:9 --> $DIR/regions-trait-object-subtyping.rs:13:9 | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { | ^^ -note: but lifetime parameter must outlive the lifetime 'b as defined on the function body at 13:12 +note: but lifetime parameter must outlive the lifetime `'b` as defined on the function body at 13:12 --> $DIR/regions-trait-object-subtyping.rs:13:12 | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { @@ -21,7 +21,7 @@ error[E0495]: cannot infer an appropriate lifetime for automatic coercion due to LL | x | ^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the function body at 13:9... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the function body at 13:9... --> $DIR/regions-trait-object-subtyping.rs:13:9 | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { @@ -31,7 +31,7 @@ note: ...so that reference does not outlive borrowed content | LL | x | ^ -note: but, the lifetime must be valid for the lifetime 'b as defined on the function body at 13:12... +note: but, the lifetime must be valid for the lifetime `'b` as defined on the function body at 13:12... --> $DIR/regions-trait-object-subtyping.rs:13:12 | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { @@ -48,12 +48,12 @@ LL | x | = note: expected type `Wrapper<&'b mut (dyn Dummy + 'b)>` found type `Wrapper<&'a mut (dyn Dummy + 'a)>` -note: the lifetime 'b as defined on the function body at 20:15... +note: the lifetime `'b` as defined on the function body at 20:15... --> $DIR/regions-trait-object-subtyping.rs:20:15 | LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dummy> { | ^^ -note: ...does not necessarily outlive the lifetime 'a as defined on the function body at 20:9 +note: ...does not necessarily outlive the lifetime `'a` as defined on the function body at 20:9 --> $DIR/regions-trait-object-subtyping.rs:20:9 | LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dummy> { diff --git a/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr b/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr index 90b37ce935a..aae519c5df2 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr @@ -6,7 +6,7 @@ LL | let _: Invariant<'static> = c; | = note: expected type `Invariant<'static>` found type `Invariant<'b>` -note: the lifetime 'b as defined on the function body at 11:9... +note: the lifetime `'b` as defined on the function body at 11:9... --> $DIR/regions-variance-invariant-use-covariant.rs:11:9 | LL | fn use_<'b>(c: Invariant<'b>) { diff --git a/src/test/ui/regions/regions-wf-trait-object.stderr b/src/test/ui/regions/regions-wf-trait-object.stderr index 4e12478c36d..9f395086041 100644 --- a/src/test/ui/regions/regions-wf-trait-object.stderr +++ b/src/test/ui/regions/regions-wf-trait-object.stderr @@ -4,12 +4,12 @@ error[E0478]: lifetime bound not satisfied LL | x: Box<dyn TheTrait<'a>+'b> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: lifetime parameter instantiated with the lifetime 'b as defined on the struct at 6:15 +note: lifetime parameter instantiated with the lifetime `'b` as defined on the struct at 6:15 --> $DIR/regions-wf-trait-object.rs:6:15 | LL | struct Foo<'a,'b> { | ^^ -note: but lifetime parameter must outlive the lifetime 'a as defined on the struct at 6:12 +note: but lifetime parameter must outlive the lifetime `'a` as defined on the struct at 6:12 --> $DIR/regions-wf-trait-object.rs:6:12 | LL | struct Foo<'a,'b> { diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/reject-specialized-drops-8142.stderr index 16d27c9d961..609a40163a3 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/reject-specialized-drops-8142.stderr @@ -34,7 +34,7 @@ LL | impl Drop for N<'static> { fn drop(&mut self) { } } | = note: expected type `N<'n>` found type `N<'static>` -note: the lifetime 'n as defined on the struct at 8:10... +note: the lifetime `'n` as defined on the struct at 8:10... --> $DIR/reject-specialized-drops-8142.rs:8:10 | LL | struct N<'n> { x: &'n i8 } @@ -95,12 +95,12 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'lw` LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'l1 as defined on the struct at 17:10... +note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 17:10... --> $DIR/reject-specialized-drops-8142.rs:17:10 | LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^ -note: ...but the lifetime must also be valid for the lifetime 'l2 as defined on the struct at 17:15... +note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 17:15... --> $DIR/reject-specialized-drops-8142.rs:17:15 | LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } diff --git a/src/test/ui/resolve/privacy-struct-ctor.rs b/src/test/ui/resolve/privacy-struct-ctor.rs index 0b389acf75d..0eecc7f8cc5 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.rs +++ b/src/test/ui/resolve/privacy-struct-ctor.rs @@ -16,7 +16,7 @@ mod m { fn f() { n::Z; - //~^ ERROR tuple struct `Z` is private + //~^ ERROR tuple struct constructor `Z` is private Z; //~^ ERROR expected value, found struct `Z` } @@ -27,21 +27,21 @@ use m::S2; // OK, only the type is imported fn main() { m::S; - //~^ ERROR tuple struct `S` is private + //~^ ERROR tuple struct constructor `S` is private let _: S = m::S(2); - //~^ ERROR tuple struct `S` is private + //~^ ERROR tuple struct constructor `S` is private S; //~^ ERROR expected value, found struct `S` m::n::Z; - //~^ ERROR tuple struct `Z` is private + //~^ ERROR tuple struct constructor `Z` is private S2; //~^ ERROR expected value, found struct `S2` xcrate::m::S; - //~^ ERROR tuple struct `S` is private + //~^ ERROR tuple struct constructor `S` is private xcrate::S; //~^ ERROR expected value, found struct `xcrate::S` xcrate::m::n::Z; - //~^ ERROR tuple struct `Z` is private + //~^ ERROR tuple struct constructor `Z` is private } diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index d5311fde2e7..7d884d3a669 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -34,43 +34,43 @@ help: possible better candidate is found in another module, you can import it in LL | use m::S; | -error[E0603]: tuple struct `Z` is private +error[E0603]: tuple struct constructor `Z` is private --> $DIR/privacy-struct-ctor.rs:18:12 | LL | pub(in m) struct Z(pub(in m::n) u8); - | --------------- a tuple struct constructor is private if any of its fields is private + | --------------- a constructor is private if any of the fields is private ... LL | n::Z; | ^ -error[E0603]: tuple struct `S` is private +error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:29:8 | LL | pub struct S(u8); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private ... LL | m::S; | ^ -error[E0603]: tuple struct `S` is private +error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:31:19 | LL | pub struct S(u8); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private ... LL | let _: S = m::S(2); | ^ -error[E0603]: tuple struct `Z` is private +error[E0603]: tuple struct constructor `Z` is private --> $DIR/privacy-struct-ctor.rs:35:11 | LL | pub(in m) struct Z(pub(in m::n) u8); - | --------------- a tuple struct constructor is private if any of its fields is private + | --------------- a constructor is private if any of the fields is private ... LL | m::n::Z; | ^ -error[E0603]: tuple struct `S` is private +error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:41:16 | LL | xcrate::m::S; @@ -79,9 +79,9 @@ LL | xcrate::m::S; ::: $DIR/auxiliary/privacy-struct-ctor.rs:2:18 | LL | pub struct S(u8); - | -- a tuple struct constructor is private if any of its fields is private + | -- a constructor is private if any of the fields is private -error[E0603]: tuple struct `Z` is private +error[E0603]: tuple struct constructor `Z` is private --> $DIR/privacy-struct-ctor.rs:45:19 | LL | xcrate::m::n::Z; @@ -90,7 +90,7 @@ LL | xcrate::m::n::Z; ::: $DIR/auxiliary/privacy-struct-ctor.rs:5:28 | LL | pub(in m) struct Z(pub(in m::n) u8); - | --------------- a tuple struct constructor is private if any of its fields is private + | --------------- a constructor is private if any of the fields is private error: aborting due to 10 previous errors diff --git a/src/test/ui/rfc-2008-non-exhaustive/struct.rs b/src/test/ui/rfc-2008-non-exhaustive/struct.rs index 94ac588d240..cf383a260e0 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/struct.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/struct.rs @@ -21,7 +21,7 @@ fn main() { //~^ ERROR expected function, found struct `TupleStruct` [E0423] let ts_explicit = structs::TupleStruct(640, 480); - //~^ ERROR tuple struct `TupleStruct` is private [E0603] + //~^ ERROR tuple struct constructor `TupleStruct` is private [E0603] let TupleStruct { 0: first_field, 1: second_field } = ts; //~^ ERROR `..` required with struct marked as non-exhaustive diff --git a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr index 15f97f7e1d6..d3686a1b869 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr @@ -10,7 +10,7 @@ error[E0423]: expected value, found struct `UnitStruct` LL | let us = UnitStruct; | ^^^^^^^^^^ constructor is not visible here due to private fields -error[E0603]: tuple struct `TupleStruct` is private +error[E0603]: tuple struct constructor `TupleStruct` is private --> $DIR/struct.rs:23:32 | LL | let ts_explicit = structs::TupleStruct(640, 480); @@ -19,7 +19,7 @@ LL | let ts_explicit = structs::TupleStruct(640, 480); ::: $DIR/auxiliary/structs.rs:13:24 | LL | pub struct TupleStruct(pub u16, pub u16); - | ---------------- a tuple struct constructor is private if any of its fields is private + | ---------------- a constructor is private if any of the fields is private error[E0603]: unit struct `UnitStruct` is private --> $DIR/struct.rs:32:32 diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.stderr index be8b5c6446c..6efc1176d05 100644 --- a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region-rev.stderr @@ -4,12 +4,12 @@ error[E0491]: in type `&'a rev_variant_struct_region::Foo<'b>`, reference has a LL | type Out = &'a Foo<'b>; | ^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the impl at 16:10 +note: the pointer is valid for the lifetime `'a` as defined on the impl at 16:10 --> $DIR/regions-outlives-nominal-type-region-rev.rs:16:10 | LL | impl<'a, 'b> Trait<'a, 'b> for usize { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 16:14 +note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 16:14 --> $DIR/regions-outlives-nominal-type-region-rev.rs:16:14 | LL | impl<'a, 'b> Trait<'a, 'b> for usize { diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.stderr index 9a3ba2d65ca..06e5f24dec9 100644 --- a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-region.stderr @@ -4,12 +4,12 @@ error[E0491]: in type `&'a variant_struct_region::Foo<'b>`, reference has a long LL | type Out = &'a Foo<'b>; | ^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the impl at 16:10 +note: the pointer is valid for the lifetime `'a` as defined on the impl at 16:10 --> $DIR/regions-outlives-nominal-type-region.rs:16:10 | LL | impl<'a, 'b> Trait<'a, 'b> for usize { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 16:14 +note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 16:14 --> $DIR/regions-outlives-nominal-type-region.rs:16:14 | LL | impl<'a, 'b> Trait<'a, 'b> for usize { diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.stderr index 5389beea3a7..d02f7b79621 100644 --- a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type-rev.stderr @@ -4,12 +4,12 @@ error[E0491]: in type `&'a variant_struct_type::Foo<&'b i32>`, reference has a l LL | type Out = &'a Foo<&'b i32>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the impl at 16:10 +note: the pointer is valid for the lifetime `'a` as defined on the impl at 16:10 --> $DIR/regions-outlives-nominal-type-type-rev.rs:16:10 | LL | impl<'a, 'b> Trait<'a, 'b> for usize { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 16:14 +note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 16:14 --> $DIR/regions-outlives-nominal-type-type-rev.rs:16:14 | LL | impl<'a, 'b> Trait<'a, 'b> for usize { diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.stderr index 2f3ef48a054..40c70f53245 100644 --- a/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/regions-outlives-nominal-type-type.stderr @@ -4,12 +4,12 @@ error[E0491]: in type `&'a variant_struct_type::Foo<&'b i32>`, reference has a l LL | type Out = &'a Foo<&'b i32>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the impl at 16:10 +note: the pointer is valid for the lifetime `'a` as defined on the impl at 16:10 --> $DIR/regions-outlives-nominal-type-type.rs:16:10 | LL | impl<'a, 'b> Trait<'a, 'b> for usize { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 16:14 +note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 16:14 --> $DIR/regions-outlives-nominal-type-type.rs:16:14 | LL | impl<'a, 'b> Trait<'a, 'b> for usize { diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr index 5a11c5fb95f..825c1015c51 100644 --- a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr @@ -32,12 +32,12 @@ error[E0491]: in type `&'a &'b T`, reference has a longer lifetime than the data LL | type Out = &'a &'b T; | ^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the impl at 24:6 +note: the pointer is valid for the lifetime `'a` as defined on the impl at 24:6 --> $DIR/regions-struct-not-wf.rs:24:6 | LL | impl<'a, 'b, T> Trait1<'a, 'b, T> for u32 { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the impl at 24:10 +note: but the referenced data is only valid for the lifetime `'b` as defined on the impl at 24:10 --> $DIR/regions-struct-not-wf.rs:24:10 | LL | impl<'a, 'b, T> Trait1<'a, 'b, T> for u32 { diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index 2fb152475a1..bce1900ca60 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -6,12 +6,12 @@ LL | async fn f(self: Pin<&Self>) -> impl Clone { self } | | | ...but this borrow... | -note: ...can't outlive the lifetime '_ as defined on the method body at 8:26 +note: ...can't outlive the lifetime `'_` as defined on the method body at 8:26 --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:26 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } | ^ -help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 8:26 +help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime `'_` as defined on the method body at 8:26 | LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/static/static-closures.stderr b/src/test/ui/static/static-closures.stderr index ced78c03e09..99235e26e15 100644 --- a/src/test/ui/static/static-closures.stderr +++ b/src/test/ui/static/static-closures.stderr @@ -6,3 +6,4 @@ LL | static || {}; error: aborting due to previous error +For more information about this error, try `rustc --explain E0697`. diff --git a/src/test/ui/static/static-lifetime.stderr b/src/test/ui/static/static-lifetime.stderr index 8516ac07b6c..bda325dc011 100644 --- a/src/test/ui/static/static-lifetime.stderr +++ b/src/test/ui/static/static-lifetime.stderr @@ -4,7 +4,7 @@ error[E0478]: lifetime bound not satisfied LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} | ^^^^^^^^^ | -note: lifetime parameter instantiated with the lifetime 'a as defined on the impl at 3:6 +note: lifetime parameter instantiated with the lifetime `'a` as defined on the impl at 3:6 --> $DIR/static-lifetime.rs:3:6 | LL | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} diff --git a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr index 4c63d609775..88c9c473eb0 100644 --- a/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr +++ b/src/test/ui/traits/trait-impl-of-supertrait-has-wrong-lifetime-parameters.stderr @@ -4,12 +4,12 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` d LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { | ^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 24:6... +note: first, the lifetime cannot outlive the lifetime `'a` as defined on the impl at 24:6... --> $DIR/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:6 | LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { | ^^ -note: ...but the lifetime must also be valid for the lifetime 'b as defined on the impl at 24:9... +note: ...but the lifetime must also be valid for the lifetime `'b` as defined on the impl at 24:9... --> $DIR/trait-impl-of-supertrait-has-wrong-lifetime-parameters.rs:24:9 | LL | impl<'a,'b> T2<'a, 'b> for S<'a, 'b> { diff --git a/src/test/ui/traits/trait-matching-lifetimes.stderr b/src/test/ui/traits/trait-matching-lifetimes.stderr index 80c577674d1..e1ccde3c9d1 100644 --- a/src/test/ui/traits/trait-matching-lifetimes.stderr +++ b/src/test/ui/traits/trait-matching-lifetimes.stderr @@ -6,12 +6,12 @@ LL | fn foo(x: Foo<'b,'a>) { | = note: expected type `fn(Foo<'a, 'b>)` found type `fn(Foo<'b, 'a>)` -note: the lifetime 'b as defined on the impl at 13:9... +note: the lifetime `'b` as defined on the impl at 13:9... --> $DIR/trait-matching-lifetimes.rs:13:9 | LL | impl<'a,'b> Tr for Foo<'a,'b> { | ^^ -note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 13:6 +note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 13:6 --> $DIR/trait-matching-lifetimes.rs:13:6 | LL | impl<'a,'b> Tr for Foo<'a,'b> { @@ -25,12 +25,12 @@ LL | fn foo(x: Foo<'b,'a>) { | = note: expected type `fn(Foo<'a, 'b>)` found type `fn(Foo<'b, 'a>)` -note: the lifetime 'a as defined on the impl at 13:6... +note: the lifetime `'a` as defined on the impl at 13:6... --> $DIR/trait-matching-lifetimes.rs:13:6 | LL | impl<'a,'b> Tr for Foo<'a,'b> { | ^^ -note: ...does not necessarily outlive the lifetime 'b as defined on the impl at 13:9 +note: ...does not necessarily outlive the lifetime `'b` as defined on the impl at 13:9 --> $DIR/trait-matching-lifetimes.rs:13:9 | LL | impl<'a,'b> Tr for Foo<'a,'b> { diff --git a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr index b2fe1b281fc..de3a997a19e 100644 --- a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr +++ b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr @@ -38,7 +38,7 @@ note: the anonymous lifetime #1 defined on the method body at 37:5... | LL | fn dummy2(self: &Bar<T>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 35:6 +note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 35:6 --> $DIR/ufcs-explicit-self-bad.rs:35:6 | LL | impl<'a, T> SomeTrait for &'a Bar<T> { @@ -52,7 +52,7 @@ LL | fn dummy2(self: &Bar<T>) {} | = note: expected type `&'a Bar<T>` found type `&Bar<T>` -note: the lifetime 'a as defined on the impl at 35:6... +note: the lifetime `'a` as defined on the impl at 35:6... --> $DIR/ufcs-explicit-self-bad.rs:35:6 | LL | impl<'a, T> SomeTrait for &'a Bar<T> { @@ -76,7 +76,7 @@ note: the anonymous lifetime #2 defined on the method body at 39:5... | LL | fn dummy3(self: &&Bar<T>) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 35:6 +note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 35:6 --> $DIR/ufcs-explicit-self-bad.rs:35:6 | LL | impl<'a, T> SomeTrait for &'a Bar<T> { @@ -90,7 +90,7 @@ LL | fn dummy3(self: &&Bar<T>) {} | = note: expected type `&'a Bar<T>` found type `&Bar<T>` -note: the lifetime 'a as defined on the impl at 35:6... +note: the lifetime `'a` as defined on the impl at 35:6... --> $DIR/ufcs-explicit-self-bad.rs:35:6 | LL | impl<'a, T> SomeTrait for &'a Bar<T> { diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr index 29ff1dc3760..26e1be34ea7 100644 --- a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr +++ b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr @@ -12,6 +12,13 @@ LL | | } ... LL | let Foo::D(_y) = x; | ^^^^^^^^^^ pattern `A(_)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Foo::D(_y) = x { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index 25519ab2d6a..a49344e45ce 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -51,6 +51,13 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered | LL | let Ok(x) = x; | ^^^^^ pattern `Err(_)` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Ok(x) = x { /* */ } + | error: aborting due to 7 previous errors diff --git a/src/test/ui/variance/variance-btree-invariant-types.stderr b/src/test/ui/variance/variance-btree-invariant-types.stderr index 49222fc7fa6..0f93927683e 100644 --- a/src/test/ui/variance/variance-btree-invariant-types.stderr +++ b/src/test/ui/variance/variance-btree-invariant-types.stderr @@ -6,7 +6,7 @@ LL | v | = note: expected type `std::collections::btree_map::IterMut<'_, &'new (), _>` found type `std::collections::btree_map::IterMut<'_, &'static (), _>` -note: the lifetime 'new as defined on the function body at 3:21... +note: the lifetime `'new` as defined on the function body at 3:21... --> $DIR/variance-btree-invariant-types.rs:3:21 | LL | fn iter_cov_key<'a, 'new>(v: IterMut<'a, &'static (), ()>) -> IterMut<'a, &'new (), ()> { @@ -21,7 +21,7 @@ LL | v | = note: expected type `std::collections::btree_map::IterMut<'_, _, &'new ()>` found type `std::collections::btree_map::IterMut<'_, _, &'static ()>` -note: the lifetime 'new as defined on the function body at 6:21... +note: the lifetime `'new` as defined on the function body at 6:21... --> $DIR/variance-btree-invariant-types.rs:6:21 | LL | fn iter_cov_val<'a, 'new>(v: IterMut<'a, (), &'static ()>) -> IterMut<'a, (), &'new ()> { @@ -36,7 +36,7 @@ LL | v | = note: expected type `std::collections::btree_map::IterMut<'_, &'static (), _>` found type `std::collections::btree_map::IterMut<'_, &'new (), _>` -note: the lifetime 'new as defined on the function body at 9:24... +note: the lifetime `'new` as defined on the function body at 9:24... --> $DIR/variance-btree-invariant-types.rs:9:24 | LL | fn iter_contra_key<'a, 'new>(v: IterMut<'a, &'new (), ()>) -> IterMut<'a, &'static (), ()> { @@ -51,7 +51,7 @@ LL | v | = note: expected type `std::collections::btree_map::IterMut<'_, _, &'static ()>` found type `std::collections::btree_map::IterMut<'_, _, &'new ()>` -note: the lifetime 'new as defined on the function body at 12:24... +note: the lifetime `'new` as defined on the function body at 12:24... --> $DIR/variance-btree-invariant-types.rs:12:24 | LL | fn iter_contra_val<'a, 'new>(v: IterMut<'a, (), &'new ()>) -> IterMut<'a, (), &'static ()> { @@ -66,7 +66,7 @@ LL | v | = note: expected type `std::collections::btree_map::OccupiedEntry<'_, &'new (), _>` found type `std::collections::btree_map::OccupiedEntry<'_, &'static (), _>` -note: the lifetime 'new as defined on the function body at 16:20... +note: the lifetime `'new` as defined on the function body at 16:20... --> $DIR/variance-btree-invariant-types.rs:16:20 | LL | fn occ_cov_key<'a, 'new>(v: OccupiedEntry<'a, &'static (), ()>) @@ -81,7 +81,7 @@ LL | v | = note: expected type `std::collections::btree_map::OccupiedEntry<'_, _, &'new ()>` found type `std::collections::btree_map::OccupiedEntry<'_, _, &'static ()>` -note: the lifetime 'new as defined on the function body at 20:20... +note: the lifetime `'new` as defined on the function body at 20:20... --> $DIR/variance-btree-invariant-types.rs:20:20 | LL | fn occ_cov_val<'a, 'new>(v: OccupiedEntry<'a, (), &'static ()>) @@ -96,7 +96,7 @@ LL | v | = note: expected type `std::collections::btree_map::OccupiedEntry<'_, &'static (), _>` found type `std::collections::btree_map::OccupiedEntry<'_, &'new (), _>` -note: the lifetime 'new as defined on the function body at 24:23... +note: the lifetime `'new` as defined on the function body at 24:23... --> $DIR/variance-btree-invariant-types.rs:24:23 | LL | fn occ_contra_key<'a, 'new>(v: OccupiedEntry<'a, &'new (), ()>) @@ -111,7 +111,7 @@ LL | v | = note: expected type `std::collections::btree_map::OccupiedEntry<'_, _, &'static ()>` found type `std::collections::btree_map::OccupiedEntry<'_, _, &'new ()>` -note: the lifetime 'new as defined on the function body at 28:23... +note: the lifetime `'new` as defined on the function body at 28:23... --> $DIR/variance-btree-invariant-types.rs:28:23 | LL | fn occ_contra_val<'a, 'new>(v: OccupiedEntry<'a, (), &'new ()>) @@ -126,7 +126,7 @@ LL | v | = note: expected type `std::collections::btree_map::VacantEntry<'_, &'new (), _>` found type `std::collections::btree_map::VacantEntry<'_, &'static (), _>` -note: the lifetime 'new as defined on the function body at 33:20... +note: the lifetime `'new` as defined on the function body at 33:20... --> $DIR/variance-btree-invariant-types.rs:33:20 | LL | fn vac_cov_key<'a, 'new>(v: VacantEntry<'a, &'static (), ()>) @@ -141,7 +141,7 @@ LL | v | = note: expected type `std::collections::btree_map::VacantEntry<'_, _, &'new ()>` found type `std::collections::btree_map::VacantEntry<'_, _, &'static ()>` -note: the lifetime 'new as defined on the function body at 37:20... +note: the lifetime `'new` as defined on the function body at 37:20... --> $DIR/variance-btree-invariant-types.rs:37:20 | LL | fn vac_cov_val<'a, 'new>(v: VacantEntry<'a, (), &'static ()>) @@ -156,7 +156,7 @@ LL | v | = note: expected type `std::collections::btree_map::VacantEntry<'_, &'static (), _>` found type `std::collections::btree_map::VacantEntry<'_, &'new (), _>` -note: the lifetime 'new as defined on the function body at 41:23... +note: the lifetime `'new` as defined on the function body at 41:23... --> $DIR/variance-btree-invariant-types.rs:41:23 | LL | fn vac_contra_key<'a, 'new>(v: VacantEntry<'a, &'new (), ()>) @@ -171,7 +171,7 @@ LL | v | = note: expected type `std::collections::btree_map::VacantEntry<'_, _, &'static ()>` found type `std::collections::btree_map::VacantEntry<'_, _, &'new ()>` -note: the lifetime 'new as defined on the function body at 45:23... +note: the lifetime `'new` as defined on the function body at 45:23... --> $DIR/variance-btree-invariant-types.rs:45:23 | LL | fn vac_contra_val<'a, 'new>(v: VacantEntry<'a, (), &'new ()>) diff --git a/src/test/ui/variance/variance-contravariant-arg-object.stderr b/src/test/ui/variance/variance-contravariant-arg-object.stderr index 263c849e199..27017e5dc47 100644 --- a/src/test/ui/variance/variance-contravariant-arg-object.stderr +++ b/src/test/ui/variance/variance-contravariant-arg-object.stderr @@ -6,12 +6,12 @@ LL | v | = note: expected type `dyn Get<&'min i32>` found type `dyn Get<&'max i32>` -note: the lifetime 'min as defined on the function body at 10:21... +note: the lifetime `'min` as defined on the function body at 10:21... --> $DIR/variance-contravariant-arg-object.rs:10:21 | LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27 --> $DIR/variance-contravariant-arg-object.rs:10:27 | LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>) @@ -25,12 +25,12 @@ LL | v | = note: expected type `dyn Get<&'max i32>` found type `dyn Get<&'min i32>` -note: the lifetime 'min as defined on the function body at 17:21... +note: the lifetime `'min` as defined on the function body at 17:21... --> $DIR/variance-contravariant-arg-object.rs:17:21 | LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 17:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 17:27 --> $DIR/variance-contravariant-arg-object.rs:17:27 | LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>) diff --git a/src/test/ui/variance/variance-contravariant-arg-trait-match.stderr b/src/test/ui/variance/variance-contravariant-arg-trait-match.stderr index ffe690dd220..1752b3b36a4 100644 --- a/src/test/ui/variance/variance-contravariant-arg-trait-match.stderr +++ b/src/test/ui/variance/variance-contravariant-arg-trait-match.stderr @@ -6,12 +6,12 @@ LL | impls_get::<G,&'min i32>() | = note: expected type `Get<&'min i32>` found type `Get<&'max i32>` -note: the lifetime 'min as defined on the function body at 10:21... +note: the lifetime `'min` as defined on the function body at 10:21... --> $DIR/variance-contravariant-arg-trait-match.rs:10:21 | LL | fn get_min_from_max<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27 --> $DIR/variance-contravariant-arg-trait-match.rs:10:27 | LL | fn get_min_from_max<'min, 'max, G>() @@ -25,12 +25,12 @@ LL | impls_get::<G,&'max i32>() | = note: expected type `Get<&'max i32>` found type `Get<&'min i32>` -note: the lifetime 'min as defined on the function body at 16:21... +note: the lifetime `'min` as defined on the function body at 16:21... --> $DIR/variance-contravariant-arg-trait-match.rs:16:21 | LL | fn get_max_from_min<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 16:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 16:27 --> $DIR/variance-contravariant-arg-trait-match.rs:16:27 | LL | fn get_max_from_min<'min, 'max, G>() diff --git a/src/test/ui/variance/variance-contravariant-self-trait-match.stderr b/src/test/ui/variance/variance-contravariant-self-trait-match.stderr index 6f445d79bf5..e35aec4c0ce 100644 --- a/src/test/ui/variance/variance-contravariant-self-trait-match.stderr +++ b/src/test/ui/variance/variance-contravariant-self-trait-match.stderr @@ -6,12 +6,12 @@ LL | impls_get::<&'min G>(); | = note: expected type `Get` found type `Get` -note: the lifetime 'min as defined on the function body at 10:21... +note: the lifetime `'min` as defined on the function body at 10:21... --> $DIR/variance-contravariant-self-trait-match.rs:10:21 | LL | fn get_min_from_max<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27 --> $DIR/variance-contravariant-self-trait-match.rs:10:27 | LL | fn get_min_from_max<'min, 'max, G>() @@ -25,12 +25,12 @@ LL | impls_get::<&'max G>(); | = note: expected type `Get` found type `Get` -note: the lifetime 'min as defined on the function body at 16:21... +note: the lifetime `'min` as defined on the function body at 16:21... --> $DIR/variance-contravariant-self-trait-match.rs:16:21 | LL | fn get_max_from_min<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 16:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 16:27 --> $DIR/variance-contravariant-self-trait-match.rs:16:27 | LL | fn get_max_from_min<'min, 'max, G>() diff --git a/src/test/ui/variance/variance-covariant-arg-object.stderr b/src/test/ui/variance/variance-covariant-arg-object.stderr index 94f80c2b657..b986edb809f 100644 --- a/src/test/ui/variance/variance-covariant-arg-object.stderr +++ b/src/test/ui/variance/variance-covariant-arg-object.stderr @@ -6,12 +6,12 @@ LL | v | = note: expected type `dyn Get<&'min i32>` found type `dyn Get<&'max i32>` -note: the lifetime 'min as defined on the function body at 10:21... +note: the lifetime `'min` as defined on the function body at 10:21... --> $DIR/variance-covariant-arg-object.rs:10:21 | LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27 --> $DIR/variance-covariant-arg-object.rs:10:27 | LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>) @@ -25,12 +25,12 @@ LL | v | = note: expected type `dyn Get<&'max i32>` found type `dyn Get<&'min i32>` -note: the lifetime 'min as defined on the function body at 18:21... +note: the lifetime `'min` as defined on the function body at 18:21... --> $DIR/variance-covariant-arg-object.rs:18:21 | LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 18:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 18:27 --> $DIR/variance-covariant-arg-object.rs:18:27 | LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>) diff --git a/src/test/ui/variance/variance-covariant-arg-trait-match.stderr b/src/test/ui/variance/variance-covariant-arg-trait-match.stderr index c0209edc915..aa383fcc262 100644 --- a/src/test/ui/variance/variance-covariant-arg-trait-match.stderr +++ b/src/test/ui/variance/variance-covariant-arg-trait-match.stderr @@ -6,12 +6,12 @@ LL | impls_get::<G,&'min i32>() | = note: expected type `Get<&'min i32>` found type `Get<&'max i32>` -note: the lifetime 'min as defined on the function body at 10:21... +note: the lifetime `'min` as defined on the function body at 10:21... --> $DIR/variance-covariant-arg-trait-match.rs:10:21 | LL | fn get_min_from_max<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27 --> $DIR/variance-covariant-arg-trait-match.rs:10:27 | LL | fn get_min_from_max<'min, 'max, G>() @@ -25,12 +25,12 @@ LL | impls_get::<G,&'max i32>() | = note: expected type `Get<&'max i32>` found type `Get<&'min i32>` -note: the lifetime 'min as defined on the function body at 17:21... +note: the lifetime `'min` as defined on the function body at 17:21... --> $DIR/variance-covariant-arg-trait-match.rs:17:21 | LL | fn get_max_from_min<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 17:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 17:27 --> $DIR/variance-covariant-arg-trait-match.rs:17:27 | LL | fn get_max_from_min<'min, 'max, G>() diff --git a/src/test/ui/variance/variance-covariant-self-trait-match.stderr b/src/test/ui/variance/variance-covariant-self-trait-match.stderr index fe5fe105c6b..a25d1044d42 100644 --- a/src/test/ui/variance/variance-covariant-self-trait-match.stderr +++ b/src/test/ui/variance/variance-covariant-self-trait-match.stderr @@ -6,12 +6,12 @@ LL | impls_get::<&'min G>(); | = note: expected type `Get` found type `Get` -note: the lifetime 'min as defined on the function body at 10:21... +note: the lifetime `'min` as defined on the function body at 10:21... --> $DIR/variance-covariant-self-trait-match.rs:10:21 | LL | fn get_min_from_max<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 10:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 10:27 --> $DIR/variance-covariant-self-trait-match.rs:10:27 | LL | fn get_min_from_max<'min, 'max, G>() @@ -25,12 +25,12 @@ LL | impls_get::<&'max G>(); | = note: expected type `Get` found type `Get` -note: the lifetime 'min as defined on the function body at 17:21... +note: the lifetime `'min` as defined on the function body at 17:21... --> $DIR/variance-covariant-self-trait-match.rs:17:21 | LL | fn get_max_from_min<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 17:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 17:27 --> $DIR/variance-covariant-self-trait-match.rs:17:27 | LL | fn get_max_from_min<'min, 'max, G>() diff --git a/src/test/ui/variance/variance-invariant-arg-object.stderr b/src/test/ui/variance/variance-invariant-arg-object.stderr index 50a8697d439..8ff1e23e8ad 100644 --- a/src/test/ui/variance/variance-invariant-arg-object.stderr +++ b/src/test/ui/variance/variance-invariant-arg-object.stderr @@ -6,12 +6,12 @@ LL | v | = note: expected type `dyn Get<&'min i32>` found type `dyn Get<&'max i32>` -note: the lifetime 'min as defined on the function body at 7:21... +note: the lifetime `'min` as defined on the function body at 7:21... --> $DIR/variance-invariant-arg-object.rs:7:21 | LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 7:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 7:27 --> $DIR/variance-invariant-arg-object.rs:7:27 | LL | fn get_min_from_max<'min, 'max>(v: Box<dyn Get<&'max i32>>) @@ -25,12 +25,12 @@ LL | v | = note: expected type `dyn Get<&'max i32>` found type `dyn Get<&'min i32>` -note: the lifetime 'min as defined on the function body at 14:21... +note: the lifetime `'min` as defined on the function body at 14:21... --> $DIR/variance-invariant-arg-object.rs:14:21 | LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 14:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 14:27 --> $DIR/variance-invariant-arg-object.rs:14:27 | LL | fn get_max_from_min<'min, 'max, G>(v: Box<dyn Get<&'min i32>>) diff --git a/src/test/ui/variance/variance-invariant-arg-trait-match.stderr b/src/test/ui/variance/variance-invariant-arg-trait-match.stderr index c8a1111e623..b58993737c7 100644 --- a/src/test/ui/variance/variance-invariant-arg-trait-match.stderr +++ b/src/test/ui/variance/variance-invariant-arg-trait-match.stderr @@ -6,12 +6,12 @@ LL | impls_get::<G,&'min i32>() | = note: expected type `Get<&'min i32>` found type `Get<&'max i32>` -note: the lifetime 'min as defined on the function body at 7:21... +note: the lifetime `'min` as defined on the function body at 7:21... --> $DIR/variance-invariant-arg-trait-match.rs:7:21 | LL | fn get_min_from_max<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 7:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 7:27 --> $DIR/variance-invariant-arg-trait-match.rs:7:27 | LL | fn get_min_from_max<'min, 'max, G>() @@ -25,12 +25,12 @@ LL | impls_get::<G,&'max i32>() | = note: expected type `Get<&'max i32>` found type `Get<&'min i32>` -note: the lifetime 'min as defined on the function body at 13:21... +note: the lifetime `'min` as defined on the function body at 13:21... --> $DIR/variance-invariant-arg-trait-match.rs:13:21 | LL | fn get_max_from_min<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 13:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 13:27 --> $DIR/variance-invariant-arg-trait-match.rs:13:27 | LL | fn get_max_from_min<'min, 'max, G>() diff --git a/src/test/ui/variance/variance-invariant-self-trait-match.stderr b/src/test/ui/variance/variance-invariant-self-trait-match.stderr index cb03d95f771..4a1d4d28b48 100644 --- a/src/test/ui/variance/variance-invariant-self-trait-match.stderr +++ b/src/test/ui/variance/variance-invariant-self-trait-match.stderr @@ -6,12 +6,12 @@ LL | impls_get::<&'min G>(); | = note: expected type `Get` found type `Get` -note: the lifetime 'min as defined on the function body at 7:21... +note: the lifetime `'min` as defined on the function body at 7:21... --> $DIR/variance-invariant-self-trait-match.rs:7:21 | LL | fn get_min_from_max<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 7:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 7:27 --> $DIR/variance-invariant-self-trait-match.rs:7:27 | LL | fn get_min_from_max<'min, 'max, G>() @@ -25,12 +25,12 @@ LL | impls_get::<&'max G>(); | = note: expected type `Get` found type `Get` -note: the lifetime 'min as defined on the function body at 13:21... +note: the lifetime `'min` as defined on the function body at 13:21... --> $DIR/variance-invariant-self-trait-match.rs:13:21 | LL | fn get_max_from_min<'min, 'max, G>() | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 13:27 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 13:27 --> $DIR/variance-invariant-self-trait-match.rs:13:27 | LL | fn get_max_from_min<'min, 'max, G>() diff --git a/src/test/ui/variance/variance-use-contravariant-struct-1.stderr b/src/test/ui/variance/variance-use-contravariant-struct-1.stderr index 7c433378df5..618f56da512 100644 --- a/src/test/ui/variance/variance-use-contravariant-struct-1.stderr +++ b/src/test/ui/variance/variance-use-contravariant-struct-1.stderr @@ -6,12 +6,12 @@ LL | v | = note: expected type `SomeStruct<&'min ()>` found type `SomeStruct<&'max ()>` -note: the lifetime 'min as defined on the function body at 8:8... +note: the lifetime `'min` as defined on the function body at 8:8... --> $DIR/variance-use-contravariant-struct-1.rs:8:8 | LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 8:13 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 8:13 --> $DIR/variance-use-contravariant-struct-1.rs:8:13 | LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>) diff --git a/src/test/ui/variance/variance-use-covariant-struct-1.stderr b/src/test/ui/variance/variance-use-covariant-struct-1.stderr index 6ae7d12c463..0b3a8dcfc86 100644 --- a/src/test/ui/variance/variance-use-covariant-struct-1.stderr +++ b/src/test/ui/variance/variance-use-covariant-struct-1.stderr @@ -6,12 +6,12 @@ LL | v | = note: expected type `SomeStruct<&'max ()>` found type `SomeStruct<&'min ()>` -note: the lifetime 'min as defined on the function body at 6:8... +note: the lifetime `'min` as defined on the function body at 6:8... --> $DIR/variance-use-covariant-struct-1.rs:6:8 | LL | fn foo<'min,'max>(v: SomeStruct<&'min ()>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 6:13 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 6:13 --> $DIR/variance-use-covariant-struct-1.rs:6:13 | LL | fn foo<'min,'max>(v: SomeStruct<&'min ()>) diff --git a/src/test/ui/variance/variance-use-invariant-struct-1.stderr b/src/test/ui/variance/variance-use-invariant-struct-1.stderr index 793954e3a1f..31deefb535e 100644 --- a/src/test/ui/variance/variance-use-invariant-struct-1.stderr +++ b/src/test/ui/variance/variance-use-invariant-struct-1.stderr @@ -6,12 +6,12 @@ LL | v | = note: expected type `SomeStruct<&'min ()>` found type `SomeStruct<&'max ()>` -note: the lifetime 'min as defined on the function body at 8:8... +note: the lifetime `'min` as defined on the function body at 8:8... --> $DIR/variance-use-invariant-struct-1.rs:8:8 | LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 8:13 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 8:13 --> $DIR/variance-use-invariant-struct-1.rs:8:13 | LL | fn foo<'min,'max>(v: SomeStruct<&'max ()>) @@ -25,12 +25,12 @@ LL | v | = note: expected type `SomeStruct<&'max ()>` found type `SomeStruct<&'min ()>` -note: the lifetime 'min as defined on the function body at 15:8... +note: the lifetime `'min` as defined on the function body at 15:8... --> $DIR/variance-use-invariant-struct-1.rs:15:8 | LL | fn bar<'min,'max>(v: SomeStruct<&'min ()>) | ^^^^ -note: ...does not necessarily outlive the lifetime 'max as defined on the function body at 15:13 +note: ...does not necessarily outlive the lifetime `'max` as defined on the function body at 15:13 --> $DIR/variance-use-invariant-struct-1.rs:15:13 | LL | fn bar<'min,'max>(v: SomeStruct<&'min ()>) diff --git a/src/test/ui/wf/wf-static-method.stderr b/src/test/ui/wf/wf-static-method.stderr index da4e8ebf9c0..93d16514a50 100644 --- a/src/test/ui/wf/wf-static-method.stderr +++ b/src/test/ui/wf/wf-static-method.stderr @@ -4,12 +4,12 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content... LL | u | ^ | -note: ...the reference is valid for the lifetime 'a as defined on the impl at 14:6... +note: ...the reference is valid for the lifetime `'a` as defined on the impl at 14:6... --> $DIR/wf-static-method.rs:14:6 | LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () { | ^^ -note: ...but the borrowed content is only valid for the lifetime 'b as defined on the impl at 14:10 +note: ...but the borrowed content is only valid for the lifetime `'b` as defined on the impl at 14:10 --> $DIR/wf-static-method.rs:14:10 | LL | impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () { @@ -21,12 +21,12 @@ error[E0478]: lifetime bound not satisfied LL | let me = Self::make_me(); | ^^^^^^^^^^^^^ | -note: lifetime parameter instantiated with the lifetime 'b as defined on the impl at 23:10 +note: lifetime parameter instantiated with the lifetime `'b` as defined on the impl at 23:10 --> $DIR/wf-static-method.rs:23:10 | LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> { | ^^ -note: but lifetime parameter must outlive the lifetime 'a as defined on the impl at 23:6 +note: but lifetime parameter must outlive the lifetime `'a` as defined on the impl at 23:6 --> $DIR/wf-static-method.rs:23:6 | LL | impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> { @@ -38,12 +38,12 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content... LL | u | ^ | -note: ...the reference is valid for the lifetime 'a as defined on the impl at 31:6... +note: ...the reference is valid for the lifetime `'a` as defined on the impl at 31:6... --> $DIR/wf-static-method.rs:31:6 | LL | impl<'a, 'b> Evil<'a, 'b> { | ^^ -note: ...but the borrowed content is only valid for the lifetime 'b as defined on the impl at 31:10 +note: ...but the borrowed content is only valid for the lifetime `'b` as defined on the impl at 31:10 --> $DIR/wf-static-method.rs:31:10 | LL | impl<'a, 'b> Evil<'a, 'b> { @@ -55,7 +55,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` d LL | <()>::static_evil(b) | ^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'b as defined on the function body at 40:13... +note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 40:13... --> $DIR/wf-static-method.rs:40:13 | LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 { @@ -65,7 +65,7 @@ note: ...so that reference does not outlive borrowed content | LL | <()>::static_evil(b) | ^ -note: but, the lifetime must be valid for the lifetime 'a as defined on the function body at 40:9... +note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 40:9... --> $DIR/wf-static-method.rs:40:9 | LL | fn evil<'a, 'b>(b: &'b u32) -> &'a u32 { @@ -82,7 +82,7 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'b` d LL | <IndirectEvil>::static_evil(b) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime 'b as defined on the function body at 44:22... +note: first, the lifetime cannot outlive the lifetime `'b` as defined on the function body at 44:22... --> $DIR/wf-static-method.rs:44:22 | LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 { @@ -92,7 +92,7 @@ note: ...so that reference does not outlive borrowed content | LL | <IndirectEvil>::static_evil(b) | ^ -note: but, the lifetime must be valid for the lifetime 'a as defined on the function body at 44:18... +note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 44:18... --> $DIR/wf-static-method.rs:44:18 | LL | fn indirect_evil<'a, 'b>(b: &'b u32) -> &'a u32 { diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index c0d2deab2f8..f41e7dd17ed 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -399,7 +399,6 @@ impl Builder { fn add_packages_to(&mut self, manifest: &mut Manifest) { let mut package = |name, targets| self.package(name, &mut manifest.pkg, targets); package("rustc", HOSTS); - package("rustc-dev", HOSTS); package("cargo", HOSTS); package("rust-mingw", MINGW); package("rust-std", TARGETS); @@ -427,13 +426,6 @@ impl Builder { "rls-preview", "rust-src", "llvm-tools-preview", "lldb-preview", "rust-analysis", "miri-preview" ]); - - // The compiler libraries are not stable for end users, but `rustc-dev` was only recently - // split out of `rust-std`. We'll include it by default as a transition for nightly users. - if self.rust_release == "nightly" { - self.extend_profile("default", &mut manifest.profiles, &["rustc-dev"]); - self.extend_profile("complete", &mut manifest.profiles, &["rustc-dev"]); - } } fn add_renames_to(&self, manifest: &mut Manifest) { @@ -489,15 +481,6 @@ impl Builder { components.push(host_component("rust-mingw")); } - // The compiler libraries are not stable for end users, but `rustc-dev` was only recently - // split out of `rust-std`. We'll include it by default as a transition for nightly users, - // but ship it as an optional component on the beta and stable channels. - if self.rust_release == "nightly" { - components.push(host_component("rustc-dev")); - } else { - extensions.push(host_component("rustc-dev")); - } - // Tools are always present in the manifest, // but might be marked as unavailable if they weren't built. extensions.extend(vec![ @@ -515,11 +498,6 @@ impl Builder { .filter(|&&target| target != host) .map(|target| Component::from_str("rust-std", target)) ); - extensions.extend( - HOSTS.iter() - .filter(|&&target| target != host) - .map(|target| Component::from_str("rustc-dev", target)) - ); extensions.push(Component::from_str("rust-src", "*")); // If the components/extensions don't actually exist for this @@ -556,14 +534,6 @@ impl Builder { dst.insert(profile_name.to_owned(), pkgs.iter().map(|s| (*s).to_owned()).collect()); } - fn extend_profile(&mut self, - profile_name: &str, - dst: &mut BTreeMap<String, Vec<String>>, - pkgs: &[&str]) { - dst.get_mut(profile_name).expect("existing profile") - .extend(pkgs.iter().map(|s| (*s).to_owned())); - } - fn package(&mut self, pkgname: &str, dst: &mut BTreeMap<String, Package>, |
