diff --git a/README.md b/README.md index 7eb5e8067eda2..cb1f06257ed15 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,6 @@ Read ["Installation"] from [The Book]. 3. Build and install: ```sh - $ git submodule update --init --recursive --progress $ ./x.py build && sudo ./x.py install ``` diff --git a/RELEASES.md b/RELEASES.md index 7022a86a45c5b..83c44774da283 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,301 @@ +Version 1.32.0 (2019-01-17) +========================== + +Language +-------- +#### 2018 edition +- [You can now use the `?` operator in macro definitions.][56245] The `?` + operator allows you to specify zero or one repetitions similar to the `*` and + `+` operators. +- [Module paths with no leading keyword like `super`, `self`, or `crate`, will + now always resolve to the item (`enum`, `struct`, etc.) available in the + module if present, before resolving to a external crate or an item the prelude.][56759] + E.g. + ```rust + enum Color { Red, Green, Blue } + + use Color::*; + ``` + +#### All editions +- [You can now match against `PhantomData` types.][55837] +- [You can now match against literals in macros with the `literal` + specifier.][56072] This will match against a literal of any type. + E.g. `1`, `'A'`, `"Hello World"` +- [Self can now be used as a constructor and pattern for unit and tuple structs.][56365] E.g. + ```rust + struct Point(i32, i32); + + impl Point { + pub fn new(x: i32, y: i32) -> Self { + Self(x, y) + } + + pub fn is_origin(&self) -> bool { + match self { + Self(0, 0) => true, + _ => false, + } + } + } + ``` +- [Self can also now be used in type definitions.][56366] E.g. + ```rust + enum List + where + Self: PartialOrd // can write `Self` instead of `List` + { + Nil, + Cons(T, Box) // likewise here + } + ``` +- [You can now mark traits with `#[must_use]`.][55663] This provides a warning if + a `impl Trait` or `dyn Trait` is returned and unused in the program. + +Compiler +-------- +- [The default allocator has changed from jemalloc to the default allocator on + your system.][55238] The compiler itself on Linux & macOS will still use + jemalloc, but programs compiled with it will use the system allocator. +- [Added the `aarch64-pc-windows-msvc` target.][55702] + +Libraries +--------- +- [`PathBuf` now implements `FromStr`.][55148] +- [`Box<[T]>` now implements `FromIterator`.][55843] +- [The `dbg!` macro has been stabilized.][56395] This macro enables you to + easily debug expressions in your rust program. E.g. + ```rust + let a = 2; + let b = dbg!(a * 2) + 1; + // ^-- prints: [src/main.rs:4] a * 2 = 4 + assert_eq!(b, 5); + ``` + +The following APIs are now `const` functions and can be used in a +`const` context. + +- [`Cell::as_ptr`] +- [`UnsafeCell::get`] +- [`char::is_ascii`] +- [`iter::empty`] +- [`ManuallyDrop::new`] +- [`ManuallyDrop::into_inner`] +- [`RangeInclusive::start`] +- [`RangeInclusive::end`] +- [`NonNull::as_ptr`] +- [`slice::as_ptr`] +- [`str::as_ptr`] +- [`Duration::as_secs`] +- [`Duration::subsec_millis`] +- [`Duration::subsec_micros`] +- [`Duration::subsec_nanos`] +- [`CStr::as_ptr`] +- [`Ipv4Addr::is_unspecified`] +- [`Ipv6Addr::new`] +- [`Ipv6Addr::octets`] + +Stabilized APIs +--------------- +- [`i8::to_be_bytes`] +- [`i8::to_le_bytes`] +- [`i8::to_ne_bytes`] +- [`i8::from_be_bytes`] +- [`i8::from_le_bytes`] +- [`i8::from_ne_bytes`] +- [`i16::to_be_bytes`] +- [`i16::to_le_bytes`] +- [`i16::to_ne_bytes`] +- [`i16::from_be_bytes`] +- [`i16::from_le_bytes`] +- [`i16::from_ne_bytes`] +- [`i32::to_be_bytes`] +- [`i32::to_le_bytes`] +- [`i32::to_ne_bytes`] +- [`i32::from_be_bytes`] +- [`i32::from_le_bytes`] +- [`i32::from_ne_bytes`] +- [`i64::to_be_bytes`] +- [`i64::to_le_bytes`] +- [`i64::to_ne_bytes`] +- [`i64::from_be_bytes`] +- [`i64::from_le_bytes`] +- [`i64::from_ne_bytes`] +- [`i128::to_be_bytes`] +- [`i128::to_le_bytes`] +- [`i128::to_ne_bytes`] +- [`i128::from_be_bytes`] +- [`i128::from_le_bytes`] +- [`i128::from_ne_bytes`] +- [`isize::to_be_bytes`] +- [`isize::to_le_bytes`] +- [`isize::to_ne_bytes`] +- [`isize::from_be_bytes`] +- [`isize::from_le_bytes`] +- [`isize::from_ne_bytes`] +- [`u8::to_be_bytes`] +- [`u8::to_le_bytes`] +- [`u8::to_ne_bytes`] +- [`u8::from_be_bytes`] +- [`u8::from_le_bytes`] +- [`u8::from_ne_bytes`] +- [`u16::to_be_bytes`] +- [`u16::to_le_bytes`] +- [`u16::to_ne_bytes`] +- [`u16::from_be_bytes`] +- [`u16::from_le_bytes`] +- [`u16::from_ne_bytes`] +- [`u32::to_be_bytes`] +- [`u32::to_le_bytes`] +- [`u32::to_ne_bytes`] +- [`u32::from_be_bytes`] +- [`u32::from_le_bytes`] +- [`u32::from_ne_bytes`] +- [`u64::to_be_bytes`] +- [`u64::to_le_bytes`] +- [`u64::to_ne_bytes`] +- [`u64::from_be_bytes`] +- [`u64::from_le_bytes`] +- [`u64::from_ne_bytes`] +- [`u128::to_be_bytes`] +- [`u128::to_le_bytes`] +- [`u128::to_ne_bytes`] +- [`u128::from_be_bytes`] +- [`u128::from_le_bytes`] +- [`u128::from_ne_bytes`] +- [`usize::to_be_bytes`] +- [`usize::to_le_bytes`] +- [`usize::to_ne_bytes`] +- [`usize::from_be_bytes`] +- [`usize::from_le_bytes`] +- [`usize::from_ne_bytes`] + +Cargo +----- +- [You can now run `cargo c` as an alias for `cargo check`.][cargo/6218] +- [Usernames are now allowed in alt registry URLs.][cargo/6242] + +Misc +---- +- [`libproc_macro` has been added to the `rust-src` distribution.][55280] + +Compatibility Notes +------------------- +- [The argument types for AVX's + `_mm256_stream_si256`, `_mm256_stream_pd`, `_mm256_stream_ps`][55610] have + been changed from `*const` to `*mut` as the previous implementation + was unsound. + + +[55148]: https://github.com/rust-lang/rust/pull/55148/ +[55238]: https://github.com/rust-lang/rust/pull/55238/ +[55280]: https://github.com/rust-lang/rust/pull/55280/ +[55610]: https://github.com/rust-lang/rust/pull/55610/ +[55663]: https://github.com/rust-lang/rust/pull/55663/ +[55702]: https://github.com/rust-lang/rust/pull/55702/ +[55837]: https://github.com/rust-lang/rust/pull/55837/ +[55843]: https://github.com/rust-lang/rust/pull/55843/ +[56072]: https://github.com/rust-lang/rust/pull/56072/ +[56245]: https://github.com/rust-lang/rust/pull/56245/ +[56365]: https://github.com/rust-lang/rust/pull/56365/ +[56366]: https://github.com/rust-lang/rust/pull/56366/ +[56395]: https://github.com/rust-lang/rust/pull/56395/ +[56759]: https://github.com/rust-lang/rust/pull/56759/ +[cargo/6218]: https://github.com/rust-lang/cargo/pull/6218/ +[cargo/6242]: https://github.com/rust-lang/cargo/pull/6242/ +[`CStr::as_ptr`]: https://doc.rust-lang.org/std/ffi/struct.CStr.html#method.as_ptr +[`Cell::as_ptr`]: https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_ptr +[`Duration::as_secs`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs +[`Duration::subsec_micros`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_micros +[`Duration::subsec_millis`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_millis +[`Duration::subsec_nanos`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.subsec_nanos +[`Ipv4Addr::is_unspecified`]: https://doc.rust-lang.org/std/net/struct.Ipv4Addr.html#method.is_unspecified +[`Ipv6Addr::new`]: https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.new +[`Ipv6Addr::octets`]: https://doc.rust-lang.org/std/net/struct.Ipv6Addr.html#method.octets +[`ManuallyDrop::into_inner`]: https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html#method.into_inner +[`ManuallyDrop::new`]: https://doc.rust-lang.org/std/mem/struct.ManuallyDrop.html#method.new +[`NonNull::as_ptr`]: https://doc.rust-lang.org/std/ptr/struct.NonNull.html#method.as_ptr +[`RangeInclusive::end`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.end +[`RangeInclusive::start`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html#method.start +[`UnsafeCell::get`]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html#method.get +[`slice::as_ptr`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr +[`char::is_ascii`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_ascii +[`i128::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_be_bytes +[`i128::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_le_bytes +[`i128::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_ne_bytes +[`i128::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_be_bytes +[`i128::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_le_bytes +[`i128::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_ne_bytes +[`i16::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_be_bytes +[`i16::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_le_bytes +[`i16::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_ne_bytes +[`i16::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.to_be_bytes +[`i16::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.to_le_bytes +[`i16::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.to_ne_bytes +[`i32::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.from_be_bytes +[`i32::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.from_le_bytes +[`i32::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.from_ne_bytes +[`i32::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.to_be_bytes +[`i32::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.to_le_bytes +[`i32::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i32.html#method.to_ne_bytes +[`i64::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.from_be_bytes +[`i64::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.from_le_bytes +[`i64::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.from_ne_bytes +[`i64::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.to_be_bytes +[`i64::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.to_le_bytes +[`i64::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i64.html#method.to_ne_bytes +[`i8::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.from_be_bytes +[`i8::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.from_le_bytes +[`i8::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.from_ne_bytes +[`i8::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.to_be_bytes +[`i8::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.to_le_bytes +[`i8::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i8.html#method.to_ne_bytes +[`isize::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.from_be_bytes +[`isize::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.from_le_bytes +[`isize::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.from_ne_bytes +[`isize::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_be_bytes +[`isize::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_le_bytes +[`isize::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_ne_bytes +[`iter::empty`]: https://doc.rust-lang.org/std/iter/fn.empty.html +[`str::as_ptr`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_ptr +[`u128::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_be_bytes +[`u128::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_le_bytes +[`u128::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_ne_bytes +[`u128::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_be_bytes +[`u128::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_le_bytes +[`u128::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_ne_bytes +[`u16::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_be_bytes +[`u16::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_le_bytes +[`u16::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_ne_bytes +[`u16::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.to_be_bytes +[`u16::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.to_le_bytes +[`u16::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.to_ne_bytes +[`u32::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.from_be_bytes +[`u32::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.from_le_bytes +[`u32::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.from_ne_bytes +[`u32::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.to_be_bytes +[`u32::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.to_le_bytes +[`u32::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u32.html#method.to_ne_bytes +[`u64::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.from_be_bytes +[`u64::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.from_le_bytes +[`u64::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.from_ne_bytes +[`u64::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.to_be_bytes +[`u64::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.to_le_bytes +[`u64::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u64.html#method.to_ne_bytes +[`u8::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.from_be_bytes +[`u8::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.from_le_bytes +[`u8::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.from_ne_bytes +[`u8::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_be_bytes +[`u8::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_le_bytes +[`u8::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u8.html#method.to_ne_bytes +[`usize::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.from_be_bytes +[`usize::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.from_le_bytes +[`usize::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.from_ne_bytes +[`usize::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.to_be_bytes +[`usize::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.to_le_bytes +[`usize::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.usize.html#method.to_ne_bytes + + Version 1.31.1 (2018-12-20) =========================== diff --git a/config.toml.example b/config.toml.example index c68d358b6a67e..23943d34b7ca8 100644 --- a/config.toml.example +++ b/config.toml.example @@ -288,7 +288,7 @@ #codegen-units-std = 1 # Whether or not debug assertions are enabled for the compiler and standard -# library. Also enables compilation of debug! and trace! logging macros. +# library. #debug-assertions = false # Whether or not debuginfo is emitted diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 3f9a093149423..df34dfe4544ae 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1984,6 +1984,7 @@ impl Step for HashSign { cmd.arg(distdir(builder)); cmd.arg(today.trim()); cmd.arg(builder.rust_package_vers()); + cmd.arg(addr); cmd.arg(builder.package_vers(&builder.release_num("cargo"))); cmd.arg(builder.package_vers(&builder.release_num("rls"))); cmd.arg(builder.package_vers(&builder.release_num("clippy"))); @@ -1991,7 +1992,6 @@ impl Step for HashSign { cmd.arg(builder.package_vers(&builder.release_num("rustfmt"))); cmd.arg(builder.llvm_tools_package_vers()); cmd.arg(builder.lldb_package_vers()); - cmd.arg(addr); builder.create_dir(&distdir(builder)); diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 7ddfc385fc0fe..cb9c86df55080 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -346,15 +346,13 @@ fn configure_cmake(builder: &Builder, if builder.config.llvm_clang_cl.is_some() && target.contains("i686") { cfg.env("SCCACHE_EXTRA_ARGS", "-m32"); } - - // If ccache is configured we inform the build a little differently how - // to invoke ccache while also invoking our compilers. - } else if let Some(ref ccache) = builder.config.ccache { - cfg.define("CMAKE_C_COMPILER", ccache) - .define("CMAKE_C_COMPILER_ARG1", sanitize_cc(cc)) - .define("CMAKE_CXX_COMPILER", ccache) - .define("CMAKE_CXX_COMPILER_ARG1", sanitize_cc(cxx)); } else { + // If ccache is configured we inform the build a little differently how + // to invoke ccache while also invoking our compilers. + if let Some(ref ccache) = builder.config.ccache { + cfg.define("CMAKE_C_COMPILER_LAUNCHER", ccache) + .define("CMAKE_CXX_COMPILER_LAUNCHER", ccache); + } cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc)) .define("CMAKE_CXX_COMPILER", sanitize_cc(cxx)); } diff --git a/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md b/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md deleted file mode 100644 index 46b843778e810..0000000000000 --- a/src/doc/unstable-book/src/language-features/irrefutable-let-patterns.md +++ /dev/null @@ -1,28 +0,0 @@ -# `irrefutable_let_patterns` - -The tracking issue for this feature is: [#44495] - -[#44495]: https://github.com/rust-lang/rust/issues/44495 - ------------------------- - -This feature changes the way that "irrefutable patterns" are handled -in the `if let` and `while let` forms. An *irrefutable pattern* is one -that cannot fail to match -- for example, the `_` pattern matches any -value, and hence it is "irrefutable". Without this feature, using an -irrefutable pattern in an `if let` gives a hard error (since often -this indicates programmer error). But when the feature is enabled, the -error becomes a lint (since in some cases irrefutable patterns are -expected). This means you can use `#[allow]` to silence the lint: - -```rust -#![feature(irrefutable_let_patterns)] - -#[allow(irrefutable_let_patterns)] -fn main() { - // These two examples used to be errors, but now they - // trigger a lint (that is allowed): - if let _ = 5 {} - while let _ = 5 { break; } -} -``` diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index b69c114ed4594..e1c5ab15bb5ce 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -738,53 +738,88 @@ impl Vec { self } - /// Sets the length of a vector. + /// Forces the length of the vector to `new_len`. /// - /// This will explicitly set the size of the vector, without actually - /// modifying its buffers, so it is up to the caller to ensure that the - /// vector is actually the specified size. + /// This is a low-level operation that maintains none of the normal + /// invariants of the type. Normally changing the length of a vector + /// is done using one of the safe operations instead, such as + /// [`truncate`], [`resize`], [`extend`], or [`clear`]. /// - /// # Examples + /// [`truncate`]: #method.truncate + /// [`resize`]: #method.resize + /// [`extend`]: #method.extend-1 + /// [`clear`]: #method.clear /// - /// ``` - /// use std::ptr; + /// # Safety /// - /// let mut vec = vec!['r', 'u', 's', 't']; + /// - `new_len` must be less than or equal to [`capacity()`]. + /// - The elements at `old_len..new_len` must be initialized. /// - /// unsafe { - /// ptr::drop_in_place(&mut vec[3]); - /// vec.set_len(3); + /// [`capacity()`]: #method.capacity + /// + /// # Examples + /// + /// This method can be useful for situations in which the vector + /// is serving as a buffer for other code, particularly over FFI: + /// + /// ```no_run + /// # #![allow(dead_code)] + /// # // This is just a minimal skeleton for the doc example; + /// # // don't use this as a starting point for a real library. + /// # pub struct StreamWrapper { strm: *mut std::ffi::c_void } + /// # const Z_OK: i32 = 0; + /// # extern "C" { + /// # fn deflateGetDictionary( + /// # strm: *mut std::ffi::c_void, + /// # dictionary: *mut u8, + /// # dictLength: *mut usize, + /// # ) -> i32; + /// # } + /// # impl StreamWrapper { + /// pub fn get_dictionary(&self) -> Option> { + /// // Per the FFI method's docs, "32768 bytes is always enough". + /// let mut dict = Vec::with_capacity(32_768); + /// let mut dict_length = 0; + /// // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that: + /// // 1. `dict_length` elements were initialized. + /// // 2. `dict_length` <= the capacity (32_768) + /// // which makes `set_len` safe to call. + /// unsafe { + /// // Make the FFI call... + /// let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length); + /// if r == Z_OK { + /// // ...and update the length to what was initialized. + /// dict.set_len(dict_length); + /// Some(dict) + /// } else { + /// None + /// } + /// } /// } - /// assert_eq!(vec, ['r', 'u', 's']); + /// # } /// ``` /// - /// In this example, there is a memory leak since the memory locations - /// owned by the inner vectors were not freed prior to the `set_len` call: + /// While the following example is sound, there is a memory leak since + /// the inner vectors were not freed prior to the `set_len` call: /// /// ``` /// let mut vec = vec![vec![1, 0, 0], /// vec![0, 1, 0], /// vec![0, 0, 1]]; + /// // SAFETY: + /// // 1. `old_len..0` is empty so no elements need to be initialized. + /// // 2. `0 <= capacity` always holds whatever `capacity` is. /// unsafe { /// vec.set_len(0); /// } /// ``` /// - /// In this example, the vector gets expanded from zero to four items - /// without any memory allocations occurring, resulting in vector - /// values of unallocated memory: - /// - /// ``` - /// let mut vec: Vec = Vec::new(); - /// - /// unsafe { - /// vec.set_len(4); - /// } - /// ``` + /// Normally, here, one would use [`clear`] instead to correctly drop + /// the contents and thus not leak memory. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub unsafe fn set_len(&mut self, len: usize) { - self.len = len; + pub unsafe fn set_len(&mut self, new_len: usize) { + self.len = new_len; } /// Removes an element from the vector and returns it. diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 4f5310f5285c9..db19baf7a2c64 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -1348,7 +1348,7 @@ extern "rust-intrinsic" { /// use std::intrinsics::ctlz; /// /// let x = 0b0001_1100_u8; - /// let num_leading = unsafe { ctlz(x) }; + /// let num_leading = ctlz(x); /// assert_eq!(num_leading, 3); /// ``` /// @@ -1360,7 +1360,7 @@ extern "rust-intrinsic" { /// use std::intrinsics::ctlz; /// /// let x = 0u16; - /// let num_leading = unsafe { ctlz(x) }; + /// let num_leading = ctlz(x); /// assert_eq!(num_leading, 16); /// ``` pub fn ctlz(x: T) -> T; @@ -1391,7 +1391,7 @@ extern "rust-intrinsic" { /// use std::intrinsics::cttz; /// /// let x = 0b0011_1000_u8; - /// let num_trailing = unsafe { cttz(x) }; + /// let num_trailing = cttz(x); /// assert_eq!(num_trailing, 3); /// ``` /// @@ -1403,7 +1403,7 @@ extern "rust-intrinsic" { /// use std::intrinsics::cttz; /// /// let x = 0u16; - /// let num_trailing = unsafe { cttz(x) }; + /// let num_trailing = cttz(x); /// assert_eq!(num_trailing, 16); /// ``` pub fn cttz(x: T) -> T; diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index b2cafc4cede2e..a5f20d08e47be 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -71,7 +71,7 @@ #![feature(cfg_target_has_atomic)] #![feature(concat_idents)] #![feature(const_fn)] -#![feature(const_int_ops)] +#![cfg_attr(stage0, feature(const_int_ops))] #![feature(const_fn_union)] #![feature(custom_attribute)] #![feature(doc_cfg)] @@ -114,9 +114,7 @@ #![feature(const_slice_len)] #![feature(const_str_as_bytes)] #![feature(const_str_len)] -#![feature(const_int_rotate)] -#![feature(const_int_wrapping)] -#![feature(const_int_sign)] +#![cfg_attr(stage0, feature(const_int_rotate))] #![feature(const_int_conversion)] #![feature(const_transmute)] #![feature(reverse_bits)] diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 97bf582df5a8c..7ff04410516a3 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -275,7 +275,7 @@ $EndFeature, " ``` "), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() } } @@ -291,7 +291,7 @@ Basic usage: ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 1);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn count_zeros(self) -> u32 { (!self).count_ones() @@ -312,7 +312,7 @@ assert_eq!(n.leading_zeros(), 0);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn leading_zeros(self) -> u32 { (self as $UnsignedT).leading_zeros() @@ -333,7 +333,7 @@ assert_eq!(n.trailing_zeros(), 2);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn trailing_zeros(self) -> u32 { (self as $UnsignedT).trailing_zeros() @@ -357,7 +357,7 @@ let m = ", $rot_result, "; assert_eq!(n.rotate_left(", $rot, "), m); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_rotate")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))] #[inline] pub const fn rotate_left(self, n: u32) -> Self { (self as $UnsignedT).rotate_left(n) as Self @@ -382,7 +382,7 @@ let m = ", $rot_op, "; assert_eq!(n.rotate_right(", $rot, "), m); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_rotate")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))] #[inline] pub const fn rotate_right(self, n: u32) -> Self { (self as $UnsignedT).rotate_right(n) as Self @@ -404,7 +404,7 @@ let m = n.swap_bytes(); assert_eq!(m, ", $swapped, "); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn swap_bytes(self) -> Self { (self as $UnsignedT).swap_bytes() as Self @@ -454,7 +454,7 @@ if cfg!(target_endian = \"big\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn from_be(x: Self) -> Self { #[cfg(target_endian = "big")] @@ -488,7 +488,7 @@ if cfg!(target_endian = \"little\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn from_le(x: Self) -> Self { #[cfg(target_endian = "little")] @@ -522,7 +522,7 @@ if cfg!(target_endian = \"big\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn to_be(self) -> Self { // or not to be? #[cfg(target_endian = "big")] @@ -556,7 +556,7 @@ if cfg!(target_endian = \"little\") { $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn to_le(self) -> Self { #[cfg(target_endian = "little")] @@ -994,12 +994,15 @@ assert_eq!(", stringify!($SelfT), "::max_value().wrapping_add(2), ", stringify!( $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_add(self, rhs: Self) -> Self { + #[cfg(stage0)] unsafe { intrinsics::overflowing_add(self, rhs) } + #[cfg(not(stage0))] + intrinsics::overflowing_add(self, rhs) } } @@ -1018,12 +1021,15 @@ stringify!($SelfT), "::max_value());", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_sub(self, rhs: Self) -> Self { + #[cfg(stage0)] unsafe { intrinsics::overflowing_sub(self, rhs) } + #[cfg(not(stage0))] + intrinsics::overflowing_sub(self, rhs) } } @@ -1041,12 +1047,15 @@ assert_eq!(11i8.wrapping_mul(12), -124);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_mul(self, rhs: Self) -> Self { + #[cfg(stage0)] unsafe { intrinsics::overflowing_mul(self, rhs) } + #[cfg(not(stage0))] + intrinsics::overflowing_mul(self, rhs) } } @@ -1205,7 +1214,7 @@ assert_eq!((-1", stringify!($SelfT), ").wrapping_shl(128), -1);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_shl(self, rhs: u32) -> Self { unsafe { @@ -1233,7 +1242,7 @@ assert_eq!((-128i16).wrapping_shr(64), -128);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_shr(self, rhs: u32) -> Self { unsafe { @@ -1886,7 +1895,6 @@ assert!(!(-10", stringify!($SelfT), ").is_positive());", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_sign")] #[inline] pub const fn is_positive(self) -> bool { self > 0 } } @@ -1905,7 +1913,6 @@ assert!(!10", stringify!($SelfT), ".is_negative());", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_sign")] #[inline] pub const fn is_negative(self) -> bool { self < 0 } } @@ -2227,10 +2234,13 @@ Basic usage: assert_eq!(n.count_ones(), 3);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn count_ones(self) -> u32 { + #[cfg(stage0)] unsafe { intrinsics::ctpop(self as $ActualT) as u32 } + #[cfg(not(stage0))] + { intrinsics::ctpop(self as $ActualT) as u32 } } } @@ -2245,7 +2255,7 @@ Basic usage: ", $Feature, "assert_eq!(", stringify!($SelfT), "::max_value().count_zeros(), 0);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn count_zeros(self) -> u32 { (!self).count_ones() @@ -2265,10 +2275,13 @@ Basic usage: assert_eq!(n.leading_zeros(), 2);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn leading_zeros(self) -> u32 { + #[cfg(stage0)] unsafe { intrinsics::ctlz(self as $ActualT) as u32 } + #[cfg(not(stage0))] + { intrinsics::ctlz(self as $ActualT) as u32 } } } @@ -2286,10 +2299,13 @@ Basic usage: assert_eq!(n.trailing_zeros(), 3);", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn trailing_zeros(self) -> u32 { + #[cfg(stage0)] unsafe { intrinsics::cttz(self) as u32 } + #[cfg(not(stage0))] + { intrinsics::cttz(self) as u32 } } } @@ -2310,10 +2326,13 @@ let m = ", $rot_result, "; assert_eq!(n.rotate_left(", $rot, "), m); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_rotate")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))] #[inline] pub const fn rotate_left(self, n: u32) -> Self { + #[cfg(stage0)] unsafe { intrinsics::rotate_left(self, n as $SelfT) } + #[cfg(not(stage0))] + intrinsics::rotate_left(self, n as $SelfT) } } @@ -2335,10 +2354,13 @@ let m = ", $rot_op, "; assert_eq!(n.rotate_right(", $rot, "), m); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_rotate")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_rotate"))] #[inline] pub const fn rotate_right(self, n: u32) -> Self { + #[cfg(stage0)] unsafe { intrinsics::rotate_right(self, n as $SelfT) } + #[cfg(not(stage0))] + intrinsics::rotate_right(self, n as $SelfT) } } @@ -2357,10 +2379,13 @@ let m = n.swap_bytes(); assert_eq!(m, ", $swapped, "); ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn swap_bytes(self) -> Self { + #[cfg(stage0)] unsafe { intrinsics::bswap(self as $ActualT) as Self } + #[cfg(not(stage0))] + { intrinsics::bswap(self as $ActualT) as Self } } } @@ -2380,10 +2405,13 @@ let m = n.reverse_bits(); assert_eq!(m, ", $reversed, "); ```"), #[unstable(feature = "reverse_bits", issue = "48763")] - #[rustc_const_unstable(feature = "const_int_conversion")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_conversion"))] #[inline] pub const fn reverse_bits(self) -> Self { + #[cfg(stage0)] unsafe { intrinsics::bitreverse(self as $ActualT) as Self } + #[cfg(not(stage0))] + { intrinsics::bitreverse(self as $ActualT) as Self } } } @@ -2407,7 +2435,7 @@ if cfg!(target_endian = \"big\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn from_be(x: Self) -> Self { #[cfg(target_endian = "big")] @@ -2441,7 +2469,7 @@ if cfg!(target_endian = \"little\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn from_le(x: Self) -> Self { #[cfg(target_endian = "little")] @@ -2475,7 +2503,7 @@ if cfg!(target_endian = \"big\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn to_be(self) -> Self { // or not to be? #[cfg(target_endian = "big")] @@ -2509,7 +2537,7 @@ if cfg!(target_endian = \"little\") { }", $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_ops")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_ops"))] #[inline] pub const fn to_le(self) -> Self { #[cfg(target_endian = "little")] @@ -2884,12 +2912,15 @@ assert_eq!(200", stringify!($SelfT), ".wrapping_add(", stringify!($SelfT), "::ma $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_add(self, rhs: Self) -> Self { + #[cfg(stage0)] unsafe { intrinsics::overflowing_add(self, rhs) } + #[cfg(not(stage0))] + intrinsics::overflowing_add(self, rhs) } } @@ -2907,12 +2938,15 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_sub(", stringify!($SelfT), "::ma $EndFeature, " ```"), #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_sub(self, rhs: Self) -> Self { + #[cfg(stage0)] unsafe { intrinsics::overflowing_sub(self, rhs) } + #[cfg(not(stage0))] + intrinsics::overflowing_sub(self, rhs) } } @@ -2931,12 +2965,15 @@ $EndFeature, " /// assert_eq!(25u8.wrapping_mul(12), 44); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_mul(self, rhs: Self) -> Self { + #[cfg(stage0)] unsafe { intrinsics::overflowing_mul(self, rhs) } + #[cfg(not(stage0))] + intrinsics::overflowing_mul(self, rhs) } doc_comment! { @@ -3081,7 +3118,7 @@ Basic usage: assert_eq!(1", stringify!($SelfT), ".wrapping_shl(128), 1);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_shl(self, rhs: u32) -> Self { unsafe { @@ -3111,7 +3148,7 @@ Basic usage: assert_eq!(128", stringify!($SelfT), ".wrapping_shr(128), 128);", $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] - #[rustc_const_unstable(feature = "const_int_wrapping")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_int_wrapping"))] #[inline] pub const fn wrapping_shr(self, rhs: u32) -> Self { unsafe { diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 55a72d7a9a94d..02eef07afd7ab 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -849,6 +849,7 @@ pub unsafe fn write_unaligned(dst: *mut T, src: T) { /// [valid]: ../ptr/index.html#safety /// [`Copy`]: ../marker/trait.Copy.html /// [`read`]: ./fn.read.html +/// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value /// /// Just like in C, whether an operation is volatile has no bearing whatsoever /// on questions involving concurrent access from multiple threads. Volatile diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 689d456d41246..bdde187d931cc 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -20,8 +20,7 @@ pub mod pattern; #[allow(missing_docs)] pub mod lossy; -/// A trait to abstract the idea of creating a new instance of a type from a -/// string. +/// Parse a value from a string /// /// `FromStr`'s [`from_str`] method is often used implicitly, through /// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples. @@ -30,6 +29,11 @@ pub mod lossy; /// [`str`]: ../../std/primitive.str.html /// [`parse`]: ../../std/primitive.str.html#method.parse /// +/// `FromStr` does not have a lifetime parameter, and so you can only parse types +/// that do not contain a lifetime parameter themselves. In other words, you can +/// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that +/// contains an `i32`, but not one that contains an `&i32`. +/// /// # Examples /// /// Basic implementation of `FromStr` on an example `Point` type: diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index 20ec620a281fd..2382a2ea50bba 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -240,7 +240,7 @@ impl CtorKind { } impl NonMacroAttrKind { - fn descr(self) -> &'static str { + pub fn descr(self) -> &'static str { match self { NonMacroAttrKind::Builtin => "built-in attribute", NonMacroAttrKind::Tool => "tool attribute", diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index fb2c873d740ca..0a8c72a0ad8ec 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -17,8 +17,6 @@ pub enum CrateNum { // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get // `CrateNum`s. BuiltinMacros, - /// A CrateNum value that indicates that something is wrong. - Invalid, /// A special CrateNum that we use for the tcx.rcache when decoding from /// the incr. comp. cache. ReservedForIncrCompCache, @@ -29,7 +27,6 @@ impl ::std::fmt::Debug for CrateNum { fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { match self { CrateNum::Index(id) => write!(fmt, "crate{}", id.private), - CrateNum::Invalid => write!(fmt, "invalid crate"), CrateNum::BuiltinMacros => write!(fmt, "builtin macros crate"), CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"), } @@ -90,7 +87,6 @@ impl fmt::Display for CrateNum { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { CrateNum::Index(id) => fmt::Display::fmt(&id.private, f), - CrateNum::Invalid => write!(f, "invalid crate"), CrateNum::BuiltinMacros => write!(f, "builtin macros crate"), CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"), } diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 22854382df15c..c428ff1bd1b37 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -286,7 +286,7 @@ declare_lint! { declare_lint! { pub IRREFUTABLE_LET_PATTERNS, - Deny, + Warn, "detects irrefutable patterns in if-let and while-let statements" } diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 00967242bed0e..c37dc2a855ed0 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -252,6 +252,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { method: &ty::AssociatedItem) -> Option { + debug!("object_safety_violation_for_method({:?}, {:?})", trait_def_id, method); // Any method that has a `Self : Sized` requisite is otherwise // exempt from the regulations. if self.generics_require_sized_self(method.def_id) { @@ -270,6 +271,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { method: &ty::AssociatedItem) -> bool { + debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method); // Any method that has a `Self : Sized` requisite can't be called. if self.generics_require_sized_self(method.def_id) { return false; @@ -402,6 +404,7 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { fn receiver_for_self_ty( self, receiver_ty: Ty<'tcx>, self_ty: Ty<'tcx>, method_def_id: DefId ) -> Ty<'tcx> { + debug!("receiver_for_self_ty({:?}, {:?}, {:?})", receiver_ty, self_ty, method_def_id); let substs = Substs::for_item(self, method_def_id, |param, _| { if param.index == 0 { self_ty.into() @@ -410,7 +413,10 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { } }); - receiver_ty.subst(self, substs) + let result = receiver_ty.subst(self, substs); + debug!("receiver_for_self_ty({:?}, {:?}, {:?}) = {:?}", + receiver_ty, self_ty, method_def_id, result); + result } /// creates the object type for the current trait. For example, @@ -426,18 +432,26 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { ); let mut associated_types = traits::supertraits(self, ty::Binder::dummy(trait_ref)) - .flat_map(|trait_ref| self.associated_items(trait_ref.def_id())) - .filter(|item| item.kind == ty::AssociatedKind::Type) + .flat_map(|super_trait_ref| { + self.associated_items(super_trait_ref.def_id()) + .map(move |item| (super_trait_ref, item)) + }) + .filter(|(_, item)| item.kind == ty::AssociatedKind::Type) .collect::>(); // existential predicates need to be in a specific order - associated_types.sort_by_cached_key(|item| self.def_path_hash(item.def_id)); - - let projection_predicates = associated_types.into_iter().map(|item| { + associated_types.sort_by_cached_key(|(_, item)| self.def_path_hash(item.def_id)); + + let projection_predicates = associated_types.into_iter().map(|(super_trait_ref, item)| { + // We *can* get bound lifetimes here in cases like + // `trait MyTrait: for<'s> OtherTrait<&'s T, Output=bool>`. + // + // binder moved to (*)... + let super_trait_ref = super_trait_ref.skip_binder(); ty::ExistentialPredicate::Projection(ty::ExistentialProjection { - ty: self.mk_projection(item.def_id, trait_ref.substs), + ty: self.mk_projection(item.def_id, super_trait_ref.substs), item_def_id: item.def_id, - substs: trait_ref.substs, + substs: super_trait_ref.substs, }) }); @@ -446,7 +460,8 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> { ); let object_ty = self.mk_dynamic( - ty::Binder::dummy(existential_predicates), + // (*) ... binder re-introduced here + ty::Binder::bind(existential_predicates), lifetime, ); diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 1fd2172212d3c..ef23fb82dcccb 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -218,10 +218,9 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> // (T1..Tn) and closures have same properties as T1..Tn -- // check if *any* of those are trivial. ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t)), - ty::Closure(def_id, ref substs) => substs - .upvar_tys(def_id, tcx) - .all(|t| trivial_dropck_outlives(tcx, t)), - + ty::Closure(def_id, ref substs) => { + trivial_dropck_outlives(tcx, substs.upvar_tuple_ty(def_id, tcx)) + } ty::Adt(def, _) => { if Some(def.did) == tcx.lang_items().manually_drop() { // `ManuallyDrop` never has a dtor. diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 6db6fe31fba70..2a15ebc93bfe4 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -312,7 +312,7 @@ struct EvaluatedCandidate<'tcx> { /// When does the builtin impl for `T: Trait` apply? enum BuiltinImplConditions<'tcx> { /// The impl is conditional on T1,T2,.. : Trait - Where(ty::Binder>>), + Where(ty::Binder<(Vec>, bool)>), /// There is no built-in impl. There may be some other /// candidate (a where-clause or user-defined impl). None, @@ -2307,7 +2307,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { BuiltinImplConditions::Where(nested) => { debug!("builtin_bound: nested={:?}", nested); candidates.vec.push(BuiltinCandidate { - has_nested: nested.skip_binder().len() > 0, + has_nested: nested.skip_binder().0.len() > 0, }); } BuiltinImplConditions::None => {} @@ -2349,21 +2349,23 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { | ty::Never | ty::Error => { // safe for everything - Where(ty::Binder::dummy(Vec::new())) + Where(ty::Binder::dummy( (Vec::new(), false) )) } ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, - ty::Tuple(tys) => Where(ty::Binder::bind(tys.last().into_iter().cloned().collect())), + ty::Tuple(tys) => Where(ty::Binder::bind( + (tys.last().into_iter().cloned().collect(), false) + )), ty::Adt(def, substs) => { let sized_crit = def.sized_constraint(self.tcx()); // (*) binder moved here Where(ty::Binder::bind( - sized_crit + (sized_crit .iter() .map(|ty| ty.subst(self.tcx(), substs)) - .collect(), + .collect(), false), )) } @@ -2399,7 +2401,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { | ty::Infer(ty::FloatVar(_)) | ty::FnDef(..) | ty::FnPtr(_) - | ty::Error => Where(ty::Binder::dummy(Vec::new())), + | ty::Error => Where(ty::Binder::dummy( + (Vec::new(), false) )), ty::Uint(_) | ty::Int(_) @@ -2423,21 +2426,24 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ty::Array(element_ty, _) => { // (*) binder moved here - Where(ty::Binder::bind(vec![element_ty])) + Where(ty::Binder::bind( + (vec![element_ty], false) )) } ty::Tuple(tys) => { // (*) binder moved here - Where(ty::Binder::bind(tys.to_vec())) + Where(ty::Binder::bind( + (tys.to_vec(), false) )) } ty::Closure(def_id, substs) => { let trait_id = obligation.predicate.def_id(); - let is_copy_trait = Some(trait_id) == self.tcx().lang_items().copy_trait(); - let is_clone_trait = Some(trait_id) == self.tcx().lang_items().clone_trait(); + let lang_items = self.tcx().lang_items(); + let is_copy_trait = Some(trait_id) == lang_items.copy_trait(); + let is_clone_trait = Some(trait_id) == lang_items.clone_trait(); if is_copy_trait || is_clone_trait { Where(ty::Binder::bind( - substs.upvar_tys(def_id, self.tcx()).collect(), + (vec![substs.upvar_tuple_ty(def_id, self.tcx())], true) )) } else { None @@ -2481,7 +2487,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { /// Bar where struct Bar { x: T, y: u32 } -> [i32, u32] /// Zed where enum Zed { A(T), B(u32) } -> [i32, u32] /// ``` - fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec> { + fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> (Vec>, bool) { match t.sty { ty::Uint(_) | ty::Int(_) @@ -2494,7 +2500,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) | ty::Never - | ty::Char => Vec::new(), + | ty::Char => (Vec::new(), false), ty::UnnormalizedProjection(..) | ty::Placeholder(..) @@ -2514,43 +2520,48 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } ty::RawPtr(ty::TypeAndMut { ty: element_ty, .. }) | ty::Ref(_, element_ty, _) => { - vec![element_ty] + (vec![element_ty], false) } - ty::Array(element_ty, _) | ty::Slice(element_ty) => vec![element_ty], + ty::Array(element_ty, _) | ty::Slice(element_ty) => { + (vec![element_ty], false) + } ty::Tuple(ref tys) => { // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet - tys.to_vec() + (tys.to_vec(), false) } - ty::Closure(def_id, ref substs) => substs.upvar_tys(def_id, self.tcx()).collect(), + ty::Closure(def_id, ref substs) => { + (vec![substs.upvar_tuple_ty(def_id, self.tcx())], true) + }, ty::Generator(def_id, ref substs, _) => { let witness = substs.witness(def_id, self.tcx()); - substs - .upvar_tys(def_id, self.tcx()) - .chain(iter::once(witness)) - .collect() + (vec![witness, substs.upvar_tuple_ty(def_id, self.tcx())], true) } ty::GeneratorWitness(types) => { // This is sound because no regions in the witness can refer to // the binder outside the witness. So we'll effectivly reuse // the implicit binder around the witness. - types.skip_binder().to_vec() + (types.skip_binder().to_vec(), false) } // for `PhantomData`, we pass `T` - ty::Adt(def, substs) if def.is_phantom_data() => substs.types().collect(), + ty::Adt(def, substs) if def.is_phantom_data() => { + (substs.types().collect(), false) + } - ty::Adt(def, substs) => def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect(), + ty::Adt(def, substs) => { + (def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect(), false) + } ty::Opaque(def_id, substs) => { // We can resolve the `impl Trait` to its concrete type, // which enforces a DAG between the functions requiring // the auto trait bounds in question. - vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)] + (vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)], false) } } } @@ -2740,7 +2751,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let lang_items = self.tcx().lang_items(); let obligations = if has_nested { let trait_def = obligation.predicate.def_id(); - let conditions = if Some(trait_def) == lang_items.sized_trait() { + let conditions_pair = if Some(trait_def) == lang_items.sized_trait() { self.sized_conditions(obligation) } else if Some(trait_def) == lang_items.copy_trait() { self.copy_clone_conditions(obligation) @@ -2749,21 +2760,28 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } else { bug!("unexpected builtin trait {:?}", trait_def) }; - let nested = match conditions { - BuiltinImplConditions::Where(nested) => nested, + let (nested_bound_types, is_closure_tuple) = match conditions_pair { + BuiltinImplConditions::Where(nested) => { + nested.skip_binder().clone() + }, _ => bug!( "obligation {:?} had matched a builtin impl but now doesn't", obligation ), }; - let cause = obligation.derived_cause(BuiltinDerivedObligation); + let cause = if is_closure_tuple { + obligation.derived_cause(BuiltinDerivedObligation) + } else { + obligation.cause.clone() + }; + self.collect_predicates_for_types( obligation.param_env, cause, obligation.recursion_depth + 1, trait_def, - nested, + ty::Binder::bind(nested_bound_types), ) } else { vec![] @@ -2791,11 +2809,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation, trait_def_id ); + let mut is_upvar_tuple_ty = false; let types = obligation.predicate.map_bound(|inner| { let self_ty = self.infcx.shallow_resolve(inner.self_ty()); - self.constituent_types_for_ty(self_ty) + let ret = self.constituent_types_for_ty(self_ty); + is_upvar_tuple_ty = ret.1; + ret.0 }); - self.vtable_auto_impl(obligation, trait_def_id, types) + self.vtable_auto_impl(obligation, trait_def_id, types, is_upvar_tuple_ty) } /// See `confirm_auto_impl_candidate`. @@ -2804,10 +2825,15 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: &TraitObligation<'tcx>, trait_def_id: DefId, nested: ty::Binder>>, + is_upvar_tuple_ty: bool ) -> VtableAutoImplData> { debug!("vtable_auto_impl: nested={:?}", nested); - let cause = obligation.derived_cause(BuiltinDerivedObligation); + let cause = if is_upvar_tuple_ty { + obligation.derived_cause(BuiltinDerivedObligation) + } else { + obligation.cause.clone() + }; let mut obligations = self.collect_predicates_for_types( obligation.param_env, cause, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index c0ba4329ae05c..8d4b8aae8b176 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -417,6 +417,12 @@ pub struct TypeckTables<'tcx> { /// All the existential types that are restricted to concrete types /// by this function pub concrete_existential_types: FxHashMap>, + + /// Given the closure ID this map provides the list of UpvarIDs used by it. + /// The upvarID contains the HIR node ID and it also contains the full path + /// leading to the member of the struct or tuple that is used instead of the + /// entire variable. + pub upvar_list: ty::UpvarListMap, } impl<'tcx> TypeckTables<'tcx> { @@ -441,6 +447,7 @@ impl<'tcx> TypeckTables<'tcx> { tainted_by_errors: false, free_region_map: Default::default(), concrete_existential_types: Default::default(), + upvar_list: Default::default(), } } @@ -741,6 +748,8 @@ impl<'a, 'gcx> HashStable> for TypeckTables<'gcx> { tainted_by_errors, ref free_region_map, ref concrete_existential_types, + ref upvar_list, + } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { @@ -783,6 +792,7 @@ impl<'a, 'gcx> HashStable> for TypeckTables<'gcx> { tainted_by_errors.hash_stable(hcx, hasher); free_region_map.hash_stable(hcx, hasher); concrete_existential_types.hash_stable(hcx, hasher); + upvar_list.hash_stable(hcx, hasher); }) } } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 171c53b7b20ba..4e69bde94b85b 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -614,7 +614,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { ty::Closure(def_id, ref substs) => { let tys = substs.upvar_tys(def_id, tcx); - univariant(&tys.map(|ty| self.layout_of(ty)).collect::, _>>()?, + univariant(&tys.iter().map(|ty| self.layout_of(ty)).collect::, _>>()?, &ReprOptions::default(), StructKind::AlwaysSized)? } @@ -1711,7 +1711,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx> // Tuples, generators and closures. ty::Closure(def_id, ref substs) => { - substs.upvar_tys(def_id, tcx).nth(i).unwrap() + substs.upvar_tys(def_id, tcx).iter().nth(i).unwrap() } ty::Generator(def_id, ref substs, _) => { @@ -1842,7 +1842,11 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { return Ok(None); } } - if let FieldPlacement::Array { .. } = layout.fields { + if let FieldPlacement::Array { count: original_64_bit_count, .. } = layout.fields { + // rust-lang/rust#57038: avoid ICE within FieldPlacement::count when count too big + if original_64_bit_count > usize::max_value() as u64 { + return Err(LayoutError::SizeOverflow(layout.ty)); + } if layout.fields.count() > 0 { return self.find_niche(layout.field(self, 0)?); } else { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index a2c96e7cf9f66..cfd99948e4370 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -808,6 +808,7 @@ pub struct UpvarBorrow<'tcx> { pub region: ty::Region<'tcx>, } +pub type UpvarListMap = FxHashMap>; pub type UpvarCaptureMap<'tcx> = FxHashMap>; #[derive(Copy, Clone)] diff --git a/src/librustc/ty/outlives.rs b/src/librustc/ty/outlives.rs index ca2d5cd718c64..aa4ce9e4c0d56 100644 --- a/src/librustc/ty/outlives.rs +++ b/src/librustc/ty/outlives.rs @@ -62,16 +62,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // projection). match ty.sty { ty::Closure(def_id, ref substs) => { - for upvar_ty in substs.upvar_tys(def_id, *self) { - self.compute_components(upvar_ty, out); - } + self.compute_components(substs.upvar_tuple_ty(def_id, *self), out) } ty::Generator(def_id, ref substs, _) => { - // Same as the closure case - for upvar_ty in substs.upvar_tys(def_id, *self) { - self.compute_components(upvar_ty, out); - } + self.compute_components(substs.upvar_tuple_ty(def_id, *self), out) // We ignore regions in the generator interior as we don't // want these to affect region inference diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index b98369b62ea37..e632a1773f7df 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -7,7 +7,7 @@ use mir::interpret::ConstValue; use middle::region; use polonius_engine::Atom; use rustc_data_structures::indexed_vec::Idx; -use ty::subst::{Substs, Subst, Kind, UnpackedKind}; +use ty::subst::{Substs, Subst}; use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; use ty::{List, TyS, ParamEnvAnd, ParamEnv}; use util::captures::Captures; @@ -208,7 +208,7 @@ static_assert!(MEM_SIZE_OF_TY_KIND: ::std::mem::size_of::>() == 24); /// A closure can be modeled as a struct that looks like: /// -/// struct Closure<'l0...'li, T0...Tj, CK, CS, U0...Uk> { +/// struct Closure<'l0...'li, T0...Tj, CK, CS, (U0...Uk)> { /// upvar0: U0, /// ... /// upvark: Uk @@ -225,9 +225,17 @@ static_assert!(MEM_SIZE_OF_TY_KIND: ::std::mem::size_of::>() == 24); /// type. For example, `fn(u32, u32) -> u32` would mean that the closure /// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait /// specified above. -/// - U0...Uk are type parameters representing the types of its upvars -/// (borrowed, if appropriate; that is, if Ui represents a by-ref upvar, -/// and the up-var has the type `Foo`, then `Ui = &Foo`). +/// - (U0...Uk) represents a type parameter which will always be a +/// tuple of k different types (post type inference). Each type Ui +/// represents the type of a upvar (borrowed, if appropriate; that +/// is, if Ui represents a by-ref upvar, and the up-var has the type +/// `Foo`, then `Ui = &Foo`). +/// - Note that the struct above is not legal Rust syntax, because +/// the upvar fields get their type from elements of the +/// `(U0..Uk)` tuple. We can do this because this struct is not +/// *truly* represented as an ordinary struct in the compiler. +/// - FIXME: We might want to refactor to a single field `upvars: +/// (U0..Uk)` of tuple type, just to be nice. /// /// So, for example, given this function: /// @@ -314,43 +322,74 @@ pub struct ClosureSubsts<'tcx> { /// Struct returned by `split()`. Note that these are subslices of the /// parent slice and not canonical substs themselves. struct SplitClosureSubsts<'tcx> { + /// Tells you whether the closure implements Fn or FnMut or FnOnce also known + /// as the kind of the closure in the rustc lingo. closure_kind_ty: Ty<'tcx>, + + /// Gives the type of the closure signature as a function. So the inputs and + /// the outputs to the closure. closure_sig_ty: Ty<'tcx>, - upvar_kinds: &'tcx [Kind<'tcx>], + + /// This represents all the upvars to the closure packed in a tuple. Its type + /// is tuple with the arity of the number of upvars referred by the closure. + upvar_tuple_ty: Ty<'tcx>, } impl<'tcx> ClosureSubsts<'tcx> { /// Divides the closure substs into their respective /// components. Single source of truth with respect to the /// ordering. - fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> SplitClosureSubsts<'tcx> { + fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> SplitClosureSubsts<'tcx> { let generics = tcx.generics_of(def_id); let parent_len = generics.parent_count; + SplitClosureSubsts { closure_kind_ty: self.substs.type_at(parent_len), closure_sig_ty: self.substs.type_at(parent_len + 1), - upvar_kinds: &self.substs[parent_len + 2..], + upvar_tuple_ty: self.substs.type_at(parent_len + 2), } } + /// This returns an iterator to the type parameters of the upvars that are + /// used by the closure. If the type of the upvar_tuple_ty is not yet known + /// then it means it is being called too early during inference stage and + /// hence a panic will occur. #[inline] - pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> - impl Iterator> + 'tcx + pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> + &'tcx[Ty<'tcx>] { - let SplitClosureSubsts { upvar_kinds, .. } = self.split(def_id, tcx); - upvar_kinds.iter().map(|t| { - if let UnpackedKind::Type(ty) = t.unpack() { - ty - } else { - bug!("upvar should be type") - } - }) + match self.upvar_tuple_ty(def_id, tcx).sty { + ty::Tuple(tys) => tys, + ref t => bug!("upvar_tuple_ty is not a valid tuple: {:?}", t), + } + } + + /// Returns the tuple of the upvar type parameters. If invoked during type + /// inference, may return an unresolved inference variable, in which case + /// the type of parameters representing types of the upvars is not known + /// yet. + pub fn upvar_tuple_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { + self.split(def_id, tcx).upvar_tuple_ty + } + + /// This is safe to be called even when the upvar type parameters are not + /// bound and is exactly called for that same reason. + pub fn opt_tuple_tys( + self, + def_id: DefId, + tcx: TyCtxt<'_, '_, 'tcx>, + ) -> Option<&'tcx[Ty<'tcx>]> { + match self.upvar_tuple_ty(def_id, tcx).sty { + ty::Tuple(tys) => Some(tys), + ty::Infer(_) => None, + _ => bug!("unexpected type") + } } /// Returns the closure kind for this closure; may return a type /// variable during inference. To get the closure kind during /// inference, use `infcx.closure_kind(def_id, substs)`. - pub fn closure_kind_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + pub fn closure_kind_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { self.split(def_id, tcx).closure_kind_ty } @@ -358,7 +397,7 @@ impl<'tcx> ClosureSubsts<'tcx> { /// closure; may contain type variables during inference. To get /// the closure signature during inference, use /// `infcx.fn_sig(def_id)`. - pub fn closure_sig_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + pub fn closure_sig_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { self.split(def_id, tcx).closure_sig_ty } @@ -393,18 +432,18 @@ struct SplitGeneratorSubsts<'tcx> { yield_ty: Ty<'tcx>, return_ty: Ty<'tcx>, witness: Ty<'tcx>, - upvar_kinds: &'tcx [Kind<'tcx>], + upvar_tuple_ty: Ty<'tcx>, } impl<'tcx> GeneratorSubsts<'tcx> { - fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> SplitGeneratorSubsts<'tcx> { + fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> SplitGeneratorSubsts<'tcx> { let generics = tcx.generics_of(def_id); let parent_len = generics.parent_count; SplitGeneratorSubsts { yield_ty: self.substs.type_at(parent_len), return_ty: self.substs.type_at(parent_len + 1), witness: self.substs.type_at(parent_len + 2), - upvar_kinds: &self.substs[parent_len + 3..], + upvar_tuple_ty: self.substs.type_at(parent_len + 3), } } @@ -413,31 +452,48 @@ impl<'tcx> GeneratorSubsts<'tcx> { /// It contains a tuple of all the types that could end up on a generator frame. /// The state transformation MIR pass may only produce layouts which mention types /// in this tuple. Upvars are not counted here. - pub fn witness(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + pub fn witness(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { self.split(def_id, tcx).witness } + /// It gives you a tuple containing the type parameters of all the upvars + /// captured by the closure. This should not be called at the time of the + /// type inference as the arity of the tuple will not be known at the time. #[inline] - pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> - impl Iterator> + 'tcx + pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> + &'tcx[Ty<'tcx>] { - let SplitGeneratorSubsts { upvar_kinds, .. } = self.split(def_id, tcx); - upvar_kinds.iter().map(|t| { - if let UnpackedKind::Type(ty) = t.unpack() { - ty - } else { - bug!("upvar should be type") - } - }) + match self.upvar_tuple_ty(def_id, tcx).sty { + ty::Tuple(tys) => tys, + ref t => bug!("Upvar_tuple_ty is not a tuple {:?}", t), + } + } + + /// This is safe to be called even when the upvar type parameters are not + /// bound and is exactly called for that same reason. + pub fn opt_tuple_tys( + self, + def_id: DefId, + tcx: TyCtxt<'_, '_, 'tcx>, + ) -> Option<&'tcx[Ty<'tcx>]> { + match self.upvar_tuple_ty(def_id, tcx).sty { + ty::Tuple(tys) => Some(tys), + ty::Infer(_) => None, + _ => bug!("unexpected type") + } + } + + pub fn upvar_tuple_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { + self.split(def_id, tcx).upvar_tuple_ty } /// Returns the type representing the yield type of the generator. - pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { self.split(def_id, tcx).yield_ty } /// Returns the type representing the return type of the generator. - pub fn return_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> { + pub fn return_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { self.split(def_id, tcx).return_ty } @@ -447,13 +503,13 @@ impl<'tcx> GeneratorSubsts<'tcx> { /// NB. Some bits of the code prefers to see this wrapped in a /// binder, but it never contains bound regions. Probably this /// function should be removed. - pub fn poly_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> PolyGenSig<'tcx> { + pub fn poly_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> PolyGenSig<'tcx> { ty::Binder::dummy(self.sig(def_id, tcx)) } /// Return the "generator signature", which consists of its yield /// and return types. - pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> GenSig<'tcx> { + pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> GenSig<'tcx> { ty::GenSig { yield_ty: self.yield_ty(def_id, tcx), return_ty: self.return_ty(def_id, tcx), @@ -480,7 +536,7 @@ impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> { pub fn pre_transforms_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> impl Iterator> + 'a { - self.upvar_tys(def_id, tcx).chain(iter::once(tcx.types.u32)) + self.upvar_tys(def_id, tcx).iter().cloned().chain(iter::once(tcx.types.u32)) } /// This is the types of all the fields stored in a generator. @@ -499,21 +555,30 @@ pub enum UpvarSubsts<'tcx> { } impl<'tcx> UpvarSubsts<'tcx> { + // (FIXME) Ideally we would like for the lifetimes for TyCtxt to change from <'_, '_, 'tcx> to + // <'_, 'tcx, 'tcx> to cause a compile time failure if this was called from the inference + // context. Currently, it will lead to a runtime panic which is not that bad but in the + // interest of compile time failure being better than runtime failures, we should. In words of + // @niko in particular, pre_transforms_ty is used in the NLL type-check (which does have an + // inference context) however, we could also just rewrite that function -- and perhaps move it + // into the NLL type_check/mod.rs file, the only place it is invoked -- to match against the + // tuple and extract the contents. the point being that we know that, when we are in the NLL + // type-check, these types should be fully inferred (we do have an active inference context + // then, but we are inferring different things) #[inline] - pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> - impl Iterator> + 'tcx - { - let upvar_kinds = match self { - UpvarSubsts::Closure(substs) => substs.split(def_id, tcx).upvar_kinds, - UpvarSubsts::Generator(substs) => substs.split(def_id, tcx).upvar_kinds, - }; - upvar_kinds.iter().map(|t| { - if let UnpackedKind::Type(ty) = t.unpack() { - ty - } else { - bug!("upvar should be type") - } - }) + pub fn upvar_tuple_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> Ty<'tcx> { + match self { + UpvarSubsts::Closure(subts) => subts.upvar_tuple_ty(def_id, tcx), + UpvarSubsts::Generator(substs) => substs.upvar_tuple_ty(def_id, tcx), + } + } + + #[inline] + pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, 'tcx>) -> &'tcx [Ty<'tcx>] { + match self { + UpvarSubsts::Closure(subts) => subts.upvar_tys(def_id, tcx), + UpvarSubsts::Generator(substs) => substs.upvar_tys(def_id, tcx), + } } } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 64e7af815b4bf..e0deda1914e48 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -161,6 +161,16 @@ pub type Substs<'tcx> = List>; impl<'a, 'gcx, 'tcx> Substs<'tcx> { /// Creates a `Substs` that maps each generic parameter to itself. + /// + /// # Example + /// + /// Given a struct `S` declared like so: + /// + /// ``` + /// struct S {..} + /// ``` + /// + /// this would return a set of substitutions `[A, B, C]`. pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId) -> &'tcx Substs<'tcx> { Substs::for_item(tcx, def_id, |param, _| { diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index e989ef823e979..c5dd03643088b 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -1045,7 +1045,8 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // Structural recursion. ty::Array(ty, _) | ty::Slice(ty) => needs_drop(ty), - ty::Closure(def_id, ref substs) => substs.upvar_tys(def_id, tcx).any(needs_drop), + ty::Closure(def_id, ref substs) => + needs_drop(substs.upvar_tuple_ty(def_id, tcx)), // Pessimistically assume that all generators will require destructors // as we don't know if a destructor is a noop or not until after the MIR diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index ef68394029680..204646f46cd19 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -346,9 +346,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { // anyway, except via auto trait matching (which // only inspects the upvar types). subtys.skip_current_subtree(); // subtree handled by compute_projection - for upvar_ty in substs.upvar_tys(def_id, self.infcx.tcx) { - self.compute(upvar_ty); - } + self.compute(substs.upvar_tuple_ty(def_id, self.infcx.tcx)); } ty::FnPtr(_) => { diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 04e571863d42f..6827e5c801ec3 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1354,7 +1354,8 @@ define_print! { } Str => write!(f, "str"), Generator(did, substs, movability) => ty::tls::with(|tcx| { - let upvar_tys = substs.upvar_tys(did, tcx); + let substs = tcx.lift(&substs).unwrap(); + let upvar_tys = substs.opt_tuple_tys(did, tcx).unwrap_or(&[]); let witness = substs.witness(did, tcx); if movability == hir::GeneratorMovability::Movable { write!(f, "[generator")?; @@ -1366,12 +1367,19 @@ define_print! { write!(f, "@{:?}", tcx.hir().span(node_id))?; let mut sep = " "; tcx.with_freevars(node_id, |freevars| { - for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - print!(f, cx, - write("{}{}:", - sep, - tcx.hir().name(freevar.var_id())), - print(upvar_ty))?; + for (index, freevar) in freevars.iter().enumerate() { + if let Some(upvar_ty) = upvar_tys.get(index) { + print!(f, cx, + write("{}{}:", + sep, + tcx.hir().name(freevar.var_id())), + print(upvar_ty))?; + } else { + print!(f, cx, + write("{}{}:_", + sep, + tcx.hir().name(freevar.var_id())))?; + } sep = ", "; } Ok(()) @@ -1381,7 +1389,7 @@ define_print! { // visible in codegen bug reports, I imagine. write!(f, "@{:?}", did)?; let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { + for (index, upvar_ty) in upvar_tys.iter().enumerate() { print!(f, cx, write("{}{}:", sep, index), print(upvar_ty))?; @@ -1395,7 +1403,11 @@ define_print! { ty::tls::with(|tcx| cx.in_binder(f, tcx, &types, tcx.lift(&types))) } Closure(did, substs) => ty::tls::with(|tcx| { - let upvar_tys = substs.upvar_tys(did, tcx); + let substs = tcx.lift(&substs).unwrap(); + let upvar_tys = substs.opt_tuple_tys(did, tcx).unwrap_or(&[]); + // Even if the upvars types are not bound yet, calling + // the opt-tuple_tys will return an empty list and so + // this branch will execute and not the else. write!(f, "[closure")?; if let Some(node_id) = tcx.hir().as_local_node_id(did) { @@ -1406,12 +1418,19 @@ define_print! { } let mut sep = " "; tcx.with_freevars(node_id, |freevars| { - for (freevar, upvar_ty) in freevars.iter().zip(upvar_tys) { - print!(f, cx, - write("{}{}:", - sep, - tcx.hir().name(freevar.var_id())), - print(upvar_ty))?; + for (index, freevar) in freevars.iter().enumerate() { + if let Some(upvar_ty) = upvar_tys.get(index) { + print!(f, cx, + write("{}{}:", + sep, + tcx.hir().name(freevar.var_id())), + print(upvar_ty))?; + } else { + print!(f, cx, + write("{}{}:_", + sep, + tcx.hir().name(freevar.var_id())))?; + } sep = ", "; } Ok(()) @@ -1421,9 +1440,9 @@ define_print! { // visible in codegen bug reports, I imagine. write!(f, "@{:?}", did)?; let mut sep = " "; - for (index, upvar_ty) in upvar_tys.enumerate() { + for (index, upvar_ty) in upvar_tys.iter().enumerate() { print!(f, cx, - write("{}{}:", sep, index), + write("{} oho {}:", sep, index), print(upvar_ty))?; sep = ", "; } diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 72ed55df94658..c7cad59725776 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -612,7 +612,7 @@ pub fn type_metadata( } ty::Closure(def_id, substs) => { - let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect(); + let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).iter().cloned().collect(); prepare_tuple_metadata(cx, t, &upvar_tys, diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs index c2f2e99c0a55b..3c9ad7d7a02e1 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs @@ -39,6 +39,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { .universal_regions .defining_ty .upvar_tys(tcx) + .iter() + .cloned() .position(|upvar_ty| { debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty); tcx.any_free_region_meets(&upvar_ty, |r| { @@ -52,6 +54,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { .universal_regions .defining_ty .upvar_tys(tcx) + .iter() .nth(upvar_index); debug!( 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 180aa1907e8d1..1510d52b3e568 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -674,10 +674,10 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { ty::Adt(adt_def, substs) if !adt_def.is_enum() => (&adt_def.variants[VariantIdx::new(0)], substs), ty::Closure(def_id, substs) => { - return match substs.upvar_tys(def_id, tcx).nth(field.index()) { + return match substs.upvar_tys(def_id, tcx).iter().nth(field.index()) { Some(ty) => Ok(ty), None => Err(FieldAccessError::OutOfRange { - field_count: substs.upvar_tys(def_id, tcx).count(), + field_count: substs.upvar_tys(def_id, tcx).iter().count(), }), } } @@ -1819,10 +1819,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } AggregateKind::Closure(def_id, substs) => { - match substs.upvar_tys(def_id, tcx).nth(field_index) { + match substs.upvar_tys(def_id, tcx).iter().nth(field_index) { Some(ty) => Ok(ty), None => Err(FieldAccessError::OutOfRange { - field_count: substs.upvar_tys(def_id, tcx).count(), + field_count: substs.upvar_tys(def_id, tcx).iter().count(), }), } } diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index c63d45ce1d272..b19ec573b7b32 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -12,7 +12,6 @@ //! The code in this file doesn't *do anything* with those results; it //! just returns them for other code to use. -use either::Either; use rustc::hir::def_id::DefId; use rustc::hir::{self, BodyOwnerKind, HirId}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; @@ -107,15 +106,11 @@ impl<'tcx> DefiningTy<'tcx> { /// not a closure or generator, there are no upvars, and hence it /// will be an empty list. The order of types in this list will /// match up with the `upvar_decls` field of `Mir`. - pub fn upvar_tys(self, tcx: TyCtxt<'_, '_, 'tcx>) -> impl Iterator> + 'tcx { + pub fn upvar_tys(self, tcx: TyCtxt<'_, '_, 'tcx>) -> &'tcx[Ty<'tcx>] { match self { - DefiningTy::Closure(def_id, substs) => Either::Left(substs.upvar_tys(def_id, tcx)), - DefiningTy::Generator(def_id, substs, _) => { - Either::Right(Either::Left(substs.upvar_tys(def_id, tcx))) - } - DefiningTy::FnDef(..) | DefiningTy::Const(..) => { - Either::Right(Either::Right(iter::empty())) - } + DefiningTy::Closure(def_id, substs) => substs.upvar_tys(def_id, tcx), + DefiningTy::Generator(def_id, substs, _) => substs.upvar_tys(def_id, tcx), + DefiningTy::FnDef(..) | DefiningTy::Const(..) => &[], } } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 727b769cf4d44..65ae111fbc0fc 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -4,7 +4,7 @@ use hair::cx::Cx; use hair::{LintLevel, BindingMode, PatternKind}; use rustc::hir; use rustc::hir::Node; -use rustc::hir::def_id::{DefId, LocalDefId}; +use rustc::hir::def_id::DefId; use rustc::middle::region; use rustc::mir::*; use rustc::mir::visit::{MutVisitor, TyContext}; @@ -640,21 +640,29 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, let arguments: Vec<_> = arguments.collect(); let tcx = hir.tcx(); - let span = tcx.hir().span(fn_id); + let tcx_hir = tcx.hir(); + let span = tcx_hir.span(fn_id); + + let hir_tables = hir.tables(); + let fn_def_id = tcx_hir.local_def_id(fn_id); // Gather the upvars of a closure, if any. - let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| { - freevars.iter().map(|fv| { - let var_id = fv.var_id(); - let var_hir_id = tcx.hir().node_to_hir_id(var_id); - let closure_expr_id = tcx.hir().local_def_id(fn_id); - let capture = hir.tables().upvar_capture(ty::UpvarId { - var_path: ty::UpvarPath {hir_id: var_hir_id}, - closure_expr_id: LocalDefId::from_def_id(closure_expr_id), - }); + // In analyze_closure() in upvar.rs we gathered a list of upvars used by a + // closure and we stored in a map called upvar_list in TypeckTables indexed + // with the closure's DefId. Here, we run through that vec of UpvarIds for + // the given closure and use the necessary information to create UpvarDecl. + let upvar_decls: Vec<_> = hir_tables + .upvar_list + .get(&fn_def_id) + .into_iter() + .flatten() + .map(|upvar_id| { + let var_hir_id = upvar_id.var_path.hir_id; + let var_node_id = tcx_hir.hir_to_node_id(var_hir_id); + let capture = hir_tables.upvar_capture(*upvar_id); let by_ref = match capture { ty::UpvarCapture::ByValue => false, - ty::UpvarCapture::ByRef(..) => true + ty::UpvarCapture::ByRef(..) => true, }; let mut decl = UpvarDecl { debug_name: keywords::Invalid.name(), @@ -662,10 +670,9 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, by_ref, mutability: Mutability::Not, }; - if let Some(Node::Binding(pat)) = tcx.hir().find(var_id) { + if let Some(Node::Binding(pat)) = tcx_hir.find(var_node_id) { if let hir::PatKind::Binding(_, _, ident, _) = pat.node { decl.debug_name = ident.name; - if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) { if bm == ty::BindByValue(hir::MutMutable) { decl.mutability = Mutability::Mut; @@ -678,8 +685,8 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, } } decl - }).collect() - }); + }) + .collect(); let mut builder = Builder::new(hir, span, @@ -689,7 +696,6 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, return_ty_span, upvar_decls); - let fn_def_id = tcx.hir().local_def_id(fn_id); let call_site_scope = region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite @@ -732,7 +738,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, // RustCall pseudo-ABI untuples the last argument. spread_arg = Some(Local::new(arguments.len())); } - let closure_expr_id = tcx.hir().local_def_id(fn_id); + let closure_expr_id = tcx_hir.local_def_id(fn_id); info!("fn_id {:?} has attrs {:?}", closure_expr_id, tcx.get_attrs(closure_expr_id)); diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs index 7e8ac3fb72006..a324761f06ab5 100644 --- a/src/librustc_mir/diagnostics.rs +++ b/src/librustc_mir/diagnostics.rs @@ -325,11 +325,13 @@ match Some(42) { "##, E0162: r##" +#### Note: this error code is no longer emitted by the compiler. + An if-let pattern attempts to match the pattern, and enters the body if the match was successful. If the match is irrefutable (when it cannot fail to match), use a regular `let`-binding instead. For instance: -```compile_fail,E0162 +```compile_pass struct Irrefutable(i32); let irr = Irrefutable(0); @@ -352,11 +354,13 @@ println!("{}", x); "##, E0165: r##" +#### Note: this error code is no longer emitted by the compiler. + A while-let pattern attempts to match the pattern, and enters the body if the match was successful. If the match is irrefutable (when it cannot fail to match), use a regular `let`-binding inside a `loop` instead. For instance: -```compile_fail,E0165 +```compile_pass,no_run struct Irrefutable(i32); let irr = Irrefutable(0); @@ -2334,7 +2338,7 @@ local variable that already exists, and hence no temporary is created. Temporaries are not always dropped at the end of the enclosing statement. In simple cases where the `&` expression is immediately stored into a variable, the compiler will automatically extend -the lifetime of the temporary until the end of the enclosinb +the lifetime of the temporary until the end of the enclosing block. Therefore, an alternative way to fix the original program is to write `let tmp = &foo()` and not `let tmp = foo()`: diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index c104af7a7d81b..10213beba2a6d 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -350,7 +350,6 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, { let mut seen = Matrix::empty(); let mut catchall = None; - let mut printed_if_let_err = false; for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() { for &(pat, hir_pat) in pats { let v = smallvec![pat]; @@ -359,27 +358,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, NotUseful => { match source { hir::MatchSource::IfLetDesugar { .. } => { - if cx.tcx.features().irrefutable_let_patterns { - cx.tcx.lint_node( - lint::builtin::IRREFUTABLE_LET_PATTERNS, - hir_pat.id, pat.span, - "irrefutable if-let pattern"); - } else { - if printed_if_let_err { - // we already printed an irrefutable if-let pattern error. - // We don't want two, that's just confusing. - } else { - // find the first arm pattern so we can use its span - let &(ref first_arm_pats, _) = &arms[0]; - let first_pat = &first_arm_pats[0]; - let span = first_pat.0.span; - struct_span_err!(cx.tcx.sess, span, E0162, - "irrefutable if-let pattern") - .span_label(span, "irrefutable pattern") - .emit(); - printed_if_let_err = true; - } - } + cx.tcx.lint_node( + lint::builtin::IRREFUTABLE_LET_PATTERNS, + hir_pat.id, + pat.span, + "irrefutable if-let pattern", + ); } hir::MatchSource::WhileLetDesugar => { @@ -394,21 +378,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>, }, // The arm with the wildcard pattern. 1 => { - if cx.tcx.features().irrefutable_let_patterns { - cx.tcx.lint_node( - lint::builtin::IRREFUTABLE_LET_PATTERNS, - hir_pat.id, pat.span, - "irrefutable while-let pattern"); - } else { - // find the first arm pattern so we can use its span - let &(ref first_arm_pats, _) = &arms[0]; - let first_pat = &first_arm_pats[0]; - let span = first_pat.0.span; - struct_span_err!(cx.tcx.sess, span, E0165, - "irrefutable while-let pattern") - .span_label(span, "irrefutable pattern") - .emit(); - } + cx.tcx.lint_node( + lint::builtin::IRREFUTABLE_LET_PATTERNS, + hir_pat.id, + pat.span, + "irrefutable while-let pattern", + ); }, _ => bug!(), } diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 4735ebae9d42e..9395da60b3886 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -24,7 +24,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(unicode_internals)] #![feature(step_trait)] #![feature(slice_concat_ext)] -#![feature(if_while_or_patterns)] +#![cfg_attr(stage0, feature(if_while_or_patterns))] #![feature(try_from)] #![feature(reverse_bits)] #![cfg_attr(stage0, feature(underscore_imports))] diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 751815eab287b..b1dc4af3754f4 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -324,7 +324,7 @@ fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::Closure(def_id, substs) => { builder.tuple_like_shim( dest, src, - substs.upvar_tys(def_id, tcx) + substs.upvar_tys(def_id, tcx).iter().cloned() ) } ty::Tuple(tys) => builder.tuple_like_shim(dest, src, tys.iter().cloned()), diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index ec0c118634d0f..f8196b35ebec8 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -843,7 +843,7 @@ impl MirPass for StateTransform { // Get the interior types and substs which typeck computed let (upvars, interior, movable) = match gen_ty.sty { ty::Generator(_, substs, movability) => { - (substs.upvar_tys(def_id, tcx).collect(), + (substs.upvar_tys(def_id, tcx).iter().cloned().collect(), substs.witness(def_id, tcx), movability == hir::GeneratorMovability::Movable) } diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index a04dd5bb5970f..193b0fe05f002 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -21,7 +21,7 @@ use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUs use rustc::middle::lang_items; use rustc::session::config::nightly_options; use syntax::ast::LitKind; -use syntax::feature_gate::{UnstableFeatures, feature_err, emit_feature_err, GateIssue}; +use syntax::feature_gate::{UnstableFeatures, emit_feature_err, GateIssue}; use syntax_pos::{Span, DUMMY_SP}; use std::fmt; @@ -104,7 +104,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { param_env: ty::ParamEnv<'tcx>, local_qualif: IndexVec>, qualif: Qualif, - const_fn_arg_vars: BitSet, temp_promotion_state: IndexVec, promotion_candidates: Vec } @@ -139,7 +138,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { param_env, local_qualif, qualif: Qualif::empty(), - const_fn_arg_vars: BitSet::new_empty(mir.local_decls.len()), temp_promotion_state: temps, promotion_candidates: vec![] } @@ -168,26 +166,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { } } - /// Error about extra statements in a constant. - fn statement_like(&mut self) { - self.add(Qualif::NOT_CONST); - if self.mode != Mode::Fn { - let mut err = feature_err( - &self.tcx.sess.parse_sess, - "const_let", - self.span, - GateIssue::Language, - &format!("statements in {}s are unstable", self.mode), - ); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note("Blocks in constants may only contain items (such as constant, function \ - definition, etc...) and a tail expression."); - err.help("To avoid it, you have to replace the non-item object."); - } - err.emit(); - } - } - /// Add the given qualification to self.qualif. fn add(&mut self, qualif: Qualif) { self.qualif = self.qualif | qualif; @@ -233,80 +211,46 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { return; } - if self.tcx.features().const_let { - let mut dest = dest; - let index = loop { - match dest { - // with `const_let` active, we treat all locals equal - Place::Local(index) => break *index, - // projections are transparent for assignments - // we qualify the entire destination at once, even if just a field would have - // stricter qualification - Place::Projection(proj) => { - // Catch more errors in the destination. `visit_place` also checks various - // projection rules like union field access and raw pointer deref - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - dest = &proj.base; - }, - Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"), - Place::Static(..) => { - // Catch more errors in the destination. `visit_place` also checks that we - // do not try to access statics from constants or try to mutate statics - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - return; - } + let mut dest = dest; + let index = loop { + match dest { + // We treat all locals equal in constants + Place::Local(index) => break *index, + // projections are transparent for assignments + // we qualify the entire destination at once, even if just a field would have + // stricter qualification + Place::Projection(proj) => { + // Catch more errors in the destination. `visit_place` also checks various + // projection rules like union field access and raw pointer deref + self.visit_place( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + dest = &proj.base; + }, + Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"), + Place::Static(..) => { + // Catch more errors in the destination. `visit_place` also checks that we + // do not try to access statics from constants or try to mutate statics + self.visit_place( + dest, + PlaceContext::MutatingUse(MutatingUseContext::Store), + location + ); + return; } - }; - debug!("store to var {:?}", index); - match &mut self.local_qualif[index] { - // this is overly restrictive, because even full assignments do not clear the qualif - // While we could special case full assignments, this would be inconsistent with - // aggregates where we overwrite all fields via assignments, which would not get - // that feature. - Some(ref mut qualif) => *qualif = *qualif | self.qualif, - // insert new qualification - qualif @ None => *qualif = Some(self.qualif), - } - return; - } - - match *dest { - Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp || - self.mir.local_kind(index) == LocalKind::ReturnPointer => { - debug!("store to {:?} (temp or return pointer)", index); - store(&mut self.local_qualif[index]) - } - - Place::Projection(box Projection { - base: Place::Local(index), - elem: ProjectionElem::Deref - }) if self.mir.local_kind(index) == LocalKind::Temp - && self.mir.local_decls[index].ty.is_box() - && self.local_qualif[index].map_or(false, |qualif| { - qualif.contains(Qualif::NOT_CONST) - }) => { - // Part of `box expr`, we should've errored - // already for the Box allocation Rvalue. - } - - // This must be an explicit assignment. - _ => { - // Catch more errors in the destination. - self.visit_place( - dest, - PlaceContext::MutatingUse(MutatingUseContext::Store), - location - ); - self.statement_like(); } + }; + debug!("store to var {:?}", index); + match &mut self.local_qualif[index] { + // this is overly restrictive, because even full assignments do not clear the qualif + // While we could special case full assignments, this would be inconsistent with + // aggregates where we overwrite all fields via assignments, which would not get + // that feature. + Some(ref mut qualif) => *qualif = *qualif | self.qualif, + // insert new qualification + qualif @ None => *qualif = Some(self.qualif), } } @@ -347,45 +291,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> { TerminatorKind::FalseUnwind { .. } => None, TerminatorKind::Return => { - if !self.tcx.features().const_let { - // Check for unused values. This usually means - // there are extra statements in the AST. - for temp in mir.temps_iter() { - if self.local_qualif[temp].is_none() { - continue; - } - - let state = self.temp_promotion_state[temp]; - if let TempState::Defined { location, uses: 0 } = state { - let data = &mir[location.block]; - let stmt_idx = location.statement_index; - - // Get the span for the initialization. - let source_info = if stmt_idx < data.statements.len() { - data.statements[stmt_idx].source_info - } else { - data.terminator().source_info - }; - self.span = source_info.span; - - // Treat this as a statement in the AST. - self.statement_like(); - } - } - - // Make sure there are no extra unassigned variables. - self.qualif = Qualif::NOT_CONST; - for index in mir.vars_iter() { - if !self.const_fn_arg_vars.contains(index) { - debug!("unassigned variable {:?}", index); - self.assign(&Place::Local(index), Location { - block: bb, - statement_index: usize::MAX, - }); - } - } - } - break; } }; @@ -454,12 +359,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { LocalKind::ReturnPointer => { self.not_const(); } - LocalKind::Var if !self.tcx.features().const_let => { - if self.mode != Mode::Fn { - emit_feature_err(&self.tcx.sess.parse_sess, "const_let", - self.span, GateIssue::Language, - &format!("let bindings in {}s are unstable",self.mode)); - } + LocalKind::Var if self.mode == Mode::Fn => { self.add(Qualif::NOT_CONST); } LocalKind::Var | @@ -569,6 +469,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } } + ProjectionElem::ConstantIndex {..} | + ProjectionElem::Subslice {..} | ProjectionElem::Field(..) | ProjectionElem::Index(_) => { let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx); @@ -598,8 +500,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { this.qualif.restrict(ty, this.tcx, this.param_env); } - ProjectionElem::ConstantIndex {..} | - ProjectionElem::Subslice {..} | ProjectionElem::Downcast(..) => { this.not_const() } @@ -1168,46 +1068,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { debug!("visit_assign: dest={:?} rvalue={:?} location={:?}", dest, rvalue, location); self.visit_rvalue(rvalue, location); - // Check the allowed const fn argument forms. - if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) { - if self.mir.local_kind(index) == LocalKind::Var && - self.const_fn_arg_vars.insert(index) && - !self.tcx.features().const_let { - // Direct use of an argument is permitted. - match *rvalue { - Rvalue::Use(Operand::Copy(Place::Local(local))) | - Rvalue::Use(Operand::Move(Place::Local(local))) => { - if self.mir.local_kind(local) == LocalKind::Arg { - return; - } - } - _ => {} - } - // Avoid a generic error for other uses of arguments. - if self.qualif.contains(Qualif::FN_ARGUMENT) { - let decl = &self.mir.local_decls[index]; - let mut err = feature_err( - &self.tcx.sess.parse_sess, - "const_let", - decl.source_info.span, - GateIssue::Language, - "arguments of constant functions can only be immutable by-value bindings" - ); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note("Constant functions are not allowed to mutate anything. Thus, \ - binding to an argument with a mutable pattern is not allowed."); - err.note("Remove any mutable bindings from the argument list to fix this \ - error. In case you need to mutate the argument, try lazily \ - initializing a global variable instead of using a const fn, or \ - refactoring the code to a functional style to avoid mutation if \ - possible."); - } - err.emit(); - return; - } - } - } - self.assign(dest, location); } diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index c1c5b18915aed..41a042ebcb643 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -65,12 +65,6 @@ pub fn is_min_const_fn( } } - for local in mir.vars_iter() { - return Err(( - mir.local_decls[local].source_info.span, - "local variables in const fn are unstable".into(), - )); - } for local in &mir.local_decls { check_ty(tcx, local.ty, local.source_info.span)?; } @@ -147,7 +141,7 @@ fn check_rvalue( check_operand(tcx, mir, operand, span) } Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) => { - check_place(tcx, mir, place, span, PlaceMode::Read) + check_place(tcx, mir, place, span) } Rvalue::Cast(CastKind::Misc, operand, cast_ty) => { use rustc::ty::cast::CastTy; @@ -213,11 +207,6 @@ fn check_rvalue( } } -enum PlaceMode { - Assign, - Read, -} - fn check_statement( tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &'a Mir<'tcx>, @@ -226,11 +215,11 @@ fn check_statement( let span = statement.source_info.span; match &statement.kind { StatementKind::Assign(place, rval) => { - check_place(tcx, mir, place, span, PlaceMode::Assign)?; + check_place(tcx, mir, place, span)?; check_rvalue(tcx, mir, rval, span) } - StatementKind::FakeRead(_, place) => check_place(tcx, mir, place, span, PlaceMode::Read), + StatementKind::FakeRead(_, place) => check_place(tcx, mir, place, span), // just an assignment StatementKind::SetDiscriminant { .. } => Ok(()), @@ -256,7 +245,7 @@ fn check_operand( ) -> McfResult { match operand { Operand::Move(place) | Operand::Copy(place) => { - check_place(tcx, mir, place, span, PlaceMode::Read) + check_place(tcx, mir, place, span) } Operand::Constant(_) => Ok(()), } @@ -267,29 +256,17 @@ fn check_place( mir: &'a Mir<'tcx>, place: &Place<'tcx>, span: Span, - mode: PlaceMode, ) -> McfResult { match place { - Place::Local(l) => match mode { - PlaceMode::Assign => match mir.local_kind(*l) { - LocalKind::Temp | LocalKind::ReturnPointer => Ok(()), - LocalKind::Arg | LocalKind::Var => { - Err((span, "assignments in const fn are unstable".into())) - } - }, - PlaceMode::Read => Ok(()), - }, + Place::Local(_) => Ok(()), // promoteds are always fine, they are essentially constants Place::Promoted(_) => Ok(()), Place::Static(_) => Err((span, "cannot access `static` items in const fn".into())), Place::Projection(proj) => { match proj.elem { + | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } | ProjectionElem::Deref | ProjectionElem::Field(..) | ProjectionElem::Index(_) => { - check_place(tcx, mir, &proj.base, span, mode) - } - // slice patterns are unstable - | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { - return Err((span, "slice patterns in const fn are unstable".into())) + check_place(tcx, mir, &proj.base, span) } | ProjectionElem::Downcast(..) => { Err((span, "`match` or `if let` in `const fn` is unstable".into())) @@ -311,10 +288,10 @@ fn check_terminator( | TerminatorKind::Resume => Ok(()), TerminatorKind::Drop { location, .. } => { - check_place(tcx, mir, location, span, PlaceMode::Read) + check_place(tcx, mir, location, span) } TerminatorKind::DropAndReplace { location, value, .. } => { - check_place(tcx, mir, location, span, PlaceMode::Read)?; + check_place(tcx, mir, location, span)?; check_operand(tcx, mir, value, span) }, @@ -342,15 +319,11 @@ fn check_terminator( // some intrinsics are waved through if called inside the // standard library. Users never need to call them directly match tcx.fn_sig(def_id).abi() { - abi::Abi::RustIntrinsic => match &tcx.item_name(def_id).as_str()[..] { - | "size_of" - | "min_align_of" - | "needs_drop" - => {}, - _ => return Err(( + abi::Abi::RustIntrinsic => if !is_intrinsic_whitelisted(tcx, def_id) { + return Err(( span, "can only call a curated list of intrinsics in `min_const_fn`".into(), - )), + )) }, abi::Abi::Rust if tcx.is_min_const_fn(def_id) => {}, abi::Abi::Rust => return Err(( @@ -390,3 +363,30 @@ fn check_terminator( }, } } + +/// Returns true if the `def_id` refers to an intrisic which we've whitelisted +/// for being called from stable `const fn`s (`min_const_fn`). +/// +/// Adding more intrinsics requires sign-off from @rust-lang/lang. +fn is_intrinsic_whitelisted(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool { + match &tcx.item_name(def_id).as_str()[..] { + | "size_of" + | "min_align_of" + | "needs_drop" + // Arithmetic: + | "overflowing_add" // ~> .wrapping_add + | "overflowing_sub" // ~> .wrapping_sub + | "overflowing_mul" // ~> .wrapping_mul + | "unchecked_shl" // ~> .wrapping_shl + | "unchecked_shr" // ~> .wrapping_shr + | "rotate_left" // ~> .rotate_left + | "rotate_right" // ~> .rotate_right + | "ctpop" // ~> .count_ones + | "ctlz" // ~> .leading_zeros + | "cttz" // ~> .trailing_zeros + | "bswap" // ~> .swap_bytes + | "bitreverse" // ~> .reverse_bits + => true, + _ => false, + } +} diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 8b55a4424ae29..baf4a8503d2b0 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -780,7 +780,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let ty = self.place_ty(self.place); match ty.sty { ty::Closure(def_id, substs) => { - let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect(); + let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).iter().cloned().collect(); self.open_drop_for_tuple(&tys) } // Note that `elaborate_drops` only drops the upvars of a generator, @@ -790,7 +790,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> // It effetively only contains upvars until the generator transformation runs. // See librustc_mir/transform/generator.rs for more details. ty::Generator(def_id, substs, _) => { - let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect(); + let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).iter().cloned().collect(); self.open_drop_for_tuple(&tys) } ty::Tuple(tys) => { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 584f0ba0449e1..3d0e46d998622 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -438,8 +438,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } for predicate in &generics.where_clause.predicates { if let WherePredicate::EqPredicate(ref predicate) = *predicate { - self.err_handler().span_err(predicate.span, "equality constraints are not yet \ - supported in where clauses (#20041)"); + self.err_handler() + .span_err(predicate.span, "equality constraints are not yet \ + supported in where clauses (see #20041)"); } } visit::walk_generics(self, generics) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index cf949b62a634e..7c05913467c54 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -67,7 +67,7 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use std::cell::{Cell, RefCell}; -use std::{cmp, fmt, iter, ptr}; +use std::{cmp, fmt, iter, mem, ptr}; use std::collections::BTreeSet; use std::mem::replace; use rustc_data_structures::ptr_key::PtrKey; @@ -2375,11 +2375,27 @@ impl<'a> Resolver<'a> { ast::UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..], _ => &[TypeNS], }; + let report_error = |this: &Self, ns| { + let what = if ns == TypeNS { "type parameters" } else { "local variables" }; + this.session.span_err(ident.span, &format!("imports cannot refer to {}", what)); + }; + for &ns in nss { - if let Some(LexicalScopeBinding::Def(..)) = - self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) { - let what = if ns == TypeNS { "type parameters" } else { "local variables" }; - self.session.span_err(ident.span, &format!("imports cannot refer to {}", what)); + match self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) { + Some(LexicalScopeBinding::Def(..)) => { + report_error(self, ns); + } + Some(LexicalScopeBinding::Item(binding)) => { + let orig_blacklisted_binding = + mem::replace(&mut self.blacklisted_binding, Some(binding)); + if let Some(LexicalScopeBinding::Def(..)) = + self.resolve_ident_in_lexical_scope(ident, ns, None, + use_tree.prefix.span) { + report_error(self, ns); + } + self.blacklisted_binding = orig_blacklisted_binding; + } + None => {} } } } else if let ast::UseTreeKind::Nested(use_trees) = &use_tree.kind { @@ -3874,6 +3890,13 @@ impl<'a> Resolver<'a> { module = Some(ModuleOrUniformRoot::Module(next_module)); record_segment_def(self, def); } else if def == Def::ToolMod && i + 1 != path.len() { + if binding.is_import() { + self.session.struct_span_err( + ident.span, "cannot use a tool module through an import" + ).span_note( + binding.span, "the tool module imported here" + ).emit(); + } let def = Def::NonMacroAttr(NonMacroAttrKind::Tool); return PathResult::NonModule(PathResolution::new(def)); } else if def == Def::Err { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index e5e6c7a994b7a..bb679d340eae7 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -376,6 +376,7 @@ impl<'a> Resolver<'a> { .push((path, path_span, kind, parent_scope.clone(), def.ok())); } + self.prohibit_imported_non_macro_attrs(None, def.ok(), path_span); def } else { let binding = self.early_resolve_ident_in_lexical_scope( @@ -390,7 +391,9 @@ impl<'a> Resolver<'a> { .push((path[0].ident, kind, parent_scope.clone(), binding.ok())); } - binding.map(|binding| binding.def()) + let def = binding.map(|binding| binding.def()); + self.prohibit_imported_non_macro_attrs(binding.ok(), def.ok(), path_span); + def } } @@ -828,27 +831,23 @@ impl<'a> Resolver<'a> { // but its `Def` should coincide with a crate passed with `--extern` // (otherwise there would be ambiguity) and we can skip feature error in this case. 'ok: { - if !is_import || self.session.features_untracked().uniform_paths { + if !is_import || !rust_2015 { break 'ok; } if ns == TypeNS && use_prelude && self.extern_prelude_get(ident, true).is_some() { break 'ok; } - if rust_2015 { - let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span); - let root_module = self.resolve_crate_root(root_ident); - if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module), - orig_ident, ns, None, false, path_span) - .is_ok() { - break 'ok; - } + let root_ident = Ident::new(keywords::PathRoot.name(), orig_ident.span); + let root_module = self.resolve_crate_root(root_ident); + if self.resolve_ident_in_module_ext(ModuleOrUniformRoot::Module(root_module), + orig_ident, ns, None, false, path_span) + .is_ok() { + break 'ok; } - let msg = "imports can only refer to extern crate names \ - passed with `--extern` on stable channel"; - let mut err = feature_err(&self.session.parse_sess, "uniform_paths", - ident.span, GateIssue::Language, msg); - + let msg = "imports can only refer to extern crate names passed with \ + `--extern` in macros originating from 2015 edition"; + let mut err = self.session.struct_span_err(ident.span, msg); let what = self.binding_description(binding, ident, flags.contains(Flags::MISC_FROM_PRELUDE)); let note_msg = format!("this import refers to {what}", what = what); @@ -977,6 +976,20 @@ impl<'a> Resolver<'a> { } } + fn prohibit_imported_non_macro_attrs(&self, binding: Option<&'a NameBinding<'a>>, + def: Option, span: Span) { + if let Some(Def::NonMacroAttr(kind)) = def { + if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) { + let msg = format!("cannot use a {} through an import", kind.descr()); + let mut err = self.session.struct_span_err(span, &msg); + if let Some(binding) = binding { + err.span_note(binding.span, &format!("the {} imported here", kind.descr())); + } + err.emit(); + } + } + } + fn suggest_macro_name(&mut self, name: &str, kind: MacroKind, err: &mut DiagnosticBuilder<'a>, span: Span) { // First check if this is a locally-defined bang macro. @@ -1073,7 +1086,12 @@ impl<'a> Resolver<'a> { let ident = ident.modern(); self.macro_names.insert(ident); let def = Def::Macro(def_id, MacroKind::Bang); - let vis = ty::Visibility::Invisible; // Doesn't matter for legacy bindings + let is_macro_export = attr::contains_name(&item.attrs, "macro_export"); + let vis = if is_macro_export { + ty::Visibility::Public + } else { + ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) + }; let binding = (def, vis, item.span, expansion).to_name_binding(self.arenas); self.set_binding_parent_module(binding, self.current_module); let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding { @@ -1081,9 +1099,8 @@ impl<'a> Resolver<'a> { }); *current_legacy_scope = LegacyScope::Binding(legacy_binding); self.all_macros.insert(ident.name, def); - if attr::contains_name(&item.attrs, "macro_export") { + if is_macro_export { let module = self.graph_root; - let vis = ty::Visibility::Public; self.define(module, ident, MacroNS, (def, vis, item.span, expansion, IsMacroExport)); } else { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index c84dbd2974624..fd55897522bf7 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -223,6 +223,11 @@ impl<'a> Resolver<'a> { } let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| { + if let Some(blacklisted_binding) = this.blacklisted_binding { + if ptr::eq(binding, blacklisted_binding) { + return Err((Determined, Weak::No)); + } + } // `extern crate` are always usable for backwards compatibility, see issue #37020, // remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`. let usable = this.is_accessible(binding.vis) || binding.is_extern_crate(); diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs index 7979fe4a75073..a222135595e12 100644 --- a/src/librustc_traits/dropck_outlives.rs +++ b/src/librustc_traits/dropck_outlives.rs @@ -194,10 +194,13 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty)) .collect(), - ty::Closure(def_id, substs) => substs - .upvar_tys(def_id, tcx) - .map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty)) - .collect(), + ty::Closure(def_id, substs) => + dtorck_constraint_for_ty( + tcx, + span, + for_ty, + depth+1, + substs.upvar_tuple_ty(def_id, tcx)), ty::Generator(def_id, substs, _movability) => { // rust-lang/rust#49918: types can be constructed, stored @@ -224,7 +227,12 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>( // *do* incorporate the upvars here. let constraint = DtorckConstraint { - outlives: substs.upvar_tys(def_id, tcx).map(|t| t.into()).collect(), + outlives: substs + .upvar_tys(def_id, tcx) + .iter() + .cloned() + .map(|t| t.into()) + .collect(), dtorck_types: vec![], overflows: vec![], }; diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 38f9adee0a48f..fbba89164e6db 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -213,8 +213,14 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> { fcx.ty_to_string(self.expr_ty), cast_ty)); if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr.span) { - err.span_help(self.expr.span, - &format!("did you mean `*{}`?", snippet)); + err.span_suggestion_with_applicability( + self.expr.span, + "dereference the expression", + format!("*{}", snippet), + Applicability::MaybeIncorrect, + ); + } else { + err.span_help(self.expr.span, "dereference the expression with `*`"); } err.emit(); } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index df83c92fde5b4..b93d325383bc9 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -96,7 +96,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // inference phase (`upvar.rs`). let base_substs = Substs::identity_for_item(self.tcx, self.tcx.closure_base_def_id(expr_def_id)); - let substs = base_substs.extend_to(self.tcx,expr_def_id, |param, _| { + let substs = base_substs.extend_to(self.tcx, expr_def_id, |param, _| { match param.kind { GenericParamDefKind::Lifetime => { span_bug!(expr.span, "closure has region param") diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 821c30b4fa709..04d18ff7aa372 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -66,6 +66,18 @@ fn equate_intrinsic_type<'a, 'tcx>( require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(def_id)), fty); } +/// Returns whether the given intrinsic is unsafe to call or not. +pub fn intrisic_operation_unsafety(intrinsic: &str) -> hir::Unsafety { + match intrinsic { + "size_of" | "min_align_of" | "needs_drop" | + "overflowing_add" | "overflowing_sub" | "overflowing_mul" | + "rotate_left" | "rotate_right" | + "ctpop" | "ctlz" | "cttz" | "bswap" | "bitreverse" + => hir::Unsafety::Normal, + _ => hir::Unsafety::Unsafe, + } +} + /// Remember to add all intrinsics here, in librustc_codegen_llvm/intrinsic.rs, /// and in libcore/intrinsics.rs pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -117,10 +129,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } else if &name[..] == "abort" || &name[..] == "unreachable" { (0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe) } else { - let unsafety = match &name[..] { - "size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal, - _ => hir::Unsafety::Unsafe, - }; + let unsafety = intrisic_operation_unsafety(&name[..]); let (n_tps, inputs, output) = match &name[..] { "breakpoint" => (0, Vec::new(), tcx.mk_unit()), "size_of" | diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1a5d164873d32..870c6dd8bc1f6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -80,7 +80,7 @@ mod closure; mod callee; mod compare_method; mod generator_interior; -mod intrinsic; +pub mod intrinsic; mod op; use astconv::{AstConv, PathSeg}; diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 86165d50b27e4..400f96e00b068 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -122,14 +122,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; self.tcx.with_freevars(closure_node_id, |freevars| { + let mut freevar_list: Vec = Vec::with_capacity(freevars.len()); for freevar in freevars { let upvar_id = ty::UpvarId { var_path: ty::UpvarPath { - hir_id : self.tcx.hir().node_to_hir_id(freevar.var_id()), + hir_id: self.tcx.hir().node_to_hir_id(freevar.var_id()), }, closure_expr_id: LocalDefId::from_def_id(closure_def_id), }; debug!("seed upvar_id {:?}", upvar_id); + // Adding the upvar Id to the list of Upvars, which will be added + // to the map for the closure at the end of the for loop. + freevar_list.push(upvar_id); let capture_kind = match capture_clause { hir::CaptureByValue => ty::UpvarCapture::ByValue, @@ -149,6 +153,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { .upvar_capture_map .insert(upvar_id, capture_kind); } + // Add the vector of freevars to the map keyed with the closure id. + // This gives us an easier access to them without having to call + // with_freevars again.. + if !freevar_list.is_empty() { + self.tables + .borrow_mut() + .upvar_list + .insert(closure_def_id, freevar_list); + } }); let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id()); @@ -166,7 +179,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.param_env, region_scope_tree, &self.tables.borrow(), - ).consume_body(body); + ) + .consume_body(body); if let Some(closure_substs) = infer_kind { // Unify the (as yet unbound) type variable in the closure @@ -207,12 +221,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "analyze_closure: id={:?} substs={:?} final_upvar_tys={:?}", closure_node_id, substs, final_upvar_tys ); - for (upvar_ty, final_upvar_ty) in substs - .upvar_tys(closure_def_id, self.tcx) - .zip(final_upvar_tys) - { - self.demand_suptype(span, upvar_ty, final_upvar_ty); - } + let final_upvar_tuple_ty = self.tcx.mk_tup(final_upvar_tys.iter()); + let subst_upvar_tuple_ty = substs.upvar_tuple_ty(closure_def_id, self.tcx); + self.demand_suptype(span, subst_upvar_tuple_ty, final_upvar_tuple_ty); // If we are also inferred the closure kind here, // process any deferred resolutions. @@ -240,9 +251,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let var_hir_id = tcx.hir().node_to_hir_id(var_node_id); let freevar_ty = self.node_ty(var_hir_id); let upvar_id = ty::UpvarId { - var_path: ty::UpvarPath { - hir_id: var_hir_id, - }, + var_path: ty::UpvarPath { hir_id: var_hir_id }, closure_expr_id: LocalDefId::from_def_id(closure_def_index), }; let capture = self.tables.borrow().upvar_capture(upvar_id); @@ -252,8 +261,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { var_node_id, freevar_ty, capture ); + // Given some variable `x: T` in the parent's scope... match capture { + // If the variable `x` is captured "by move", + // then the corresponding type is just `T`. ty::UpvarCapture::ByValue => freevar_ty, + + // Otherwise it is captured by reference, so + // the desugared upvar in the closure has type + // `&T` or `&mut T`. ty::UpvarCapture::ByRef(borrow) => tcx.mk_ref( borrow.region, ty::TypeAndMut { @@ -262,7 +278,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }, ), } - }).collect() + }) + .collect() }) } } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 38de936a027ff..c61159eb49481 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -21,6 +21,15 @@ use syntax_pos::Span; /////////////////////////////////////////////////////////////////////////// // Entry point +// During type inference, partially inferred types are +// represented using Type variables (ty::Infer). These don't appear in +// the final TypeckTables since all of the types should have been +// inferred once typeck_tables_of is done. +// When type inference is running however, having to update the typeck +// tables every time a new type is inferred would be unreasonably slow, +// so instead all of the replacement happens at the end in +// resolve_type_vars_in_body, which creates a new TypeTables which +// doesn't contain any inference types. impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) -> &'gcx ty::TypeckTables<'gcx> { let item_id = self.tcx.hir().body_owner(body.id()); @@ -35,7 +44,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { wbcx.visit_node_id(arg.pat.span, arg.hir_id); } wbcx.visit_body(body); - wbcx.visit_upvar_borrow_map(); + wbcx.visit_upvar_capture_map(); + wbcx.visit_upvar_list_map(); wbcx.visit_closures(); wbcx.visit_liberated_fn_sigs(); wbcx.visit_fru_field_types(); @@ -291,7 +301,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { } impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { - fn visit_upvar_borrow_map(&mut self) { + fn visit_upvar_capture_map(&mut self) { for (upvar_id, upvar_capture) in self.fcx.tables.borrow().upvar_capture_map.iter() { let new_upvar_capture = match *upvar_capture { ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue, @@ -314,6 +324,21 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } } + /// Runs through the function context's upvar list map and adds the same to + /// the TypeckTables. upvarlist is a hashmap of the list of upvars referred + /// to in a closure.. + fn visit_upvar_list_map(&mut self) { + for (closure_def_id, upvar_list) in self.fcx.tables.borrow().upvar_list.iter() { + debug!( + "UpvarIDs captured by closure {:?} are: {:?}", + closure_def_id, upvar_list + ); + self.tables + .upvar_list + .insert(*closure_def_id, upvar_list.to_vec()); + } + } + fn visit_closures(&mut self) { let fcx_tables = self.fcx.tables.borrow(); debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index e0e173901ef38..c49c06a4360d9 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -16,6 +16,7 @@ use astconv::{AstConv, Bounds}; use constrained_type_params as ctp; +use check::intrinsic::intrisic_operation_unsafety; use lint; use middle::lang_items::SizedTraitLangItem; use middle::resolve_lifetime as rl; @@ -1053,6 +1054,10 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty &["", ""][..] }; + // For closures: Add the CK, CS type parameters discussed in + // `ClosureSubsts` comment. + // + // For generators: add the yield/return/witness types. params.extend( dummy_args .iter() @@ -1070,20 +1075,17 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty }), ); - tcx.with_freevars(node_id, |fv| { - params.extend(fv.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| { - ty::GenericParamDef { - index: type_start + i, - name: Symbol::intern("").as_interned_str(), - def_id, - pure_wrt_drop: false, - kind: ty::GenericParamDefKind::Type { - has_default: false, - object_lifetime_default: rl::Set1::Empty, - synthetic: None, - }, - } - })); + // For closures/generators: Add the (U0...Uk) tuple. + params.push(ty::GenericParamDef { + index: type_start + dummy_args.len() as u32, + name: Symbol::intern("").as_interned_str(), + def_id, + pure_wrt_drop: false, + kind: ty::GenericParamDefKind::Type { + has_default: false, + object_lifetime_default: rl::Set1::Empty, + synthetic: None, + }, }); } @@ -1107,7 +1109,7 @@ fn report_assoc_ty_on_inherent_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: tcx.sess, span, E0202, - "associated types are not allowed in inherent impls" + "associated types are not yet supported in inherent impls (see #8995)" ); } @@ -2080,10 +2082,7 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>( abi: abi::Abi, ) -> ty::PolyFnSig<'tcx> { let unsafety = if abi == abi::Abi::RustIntrinsic { - match &*tcx.item_name(def_id).as_str() { - "size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal, - _ => hir::Unsafety::Unsafe, - } + intrisic_operation_unsafety(&*tcx.item_name(def_id).as_str()) } else { hir::Unsafety::Unsafe }; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 184d5b24d6e12..b48951d7593b6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -893,14 +893,12 @@ themePicker.onblur = handleThemeButtonsBlur; static_files::fira_sans::MEDIUM)?; write(cx.dst.join("FiraSans-LICENSE.txt"), static_files::fira_sans::LICENSE)?; - write(cx.dst.join("Heuristica-Italic.woff"), - static_files::heuristica::ITALIC)?; - write(cx.dst.join("Heuristica-LICENSE.txt"), - static_files::heuristica::LICENSE)?; - write(cx.dst.join("SourceSerifPro-Regular.woff"), + write(cx.dst.join("SourceSerifPro-Regular.ttf.woff"), static_files::source_serif_pro::REGULAR)?; - write(cx.dst.join("SourceSerifPro-Bold.woff"), + write(cx.dst.join("SourceSerifPro-Bold.ttf.woff"), static_files::source_serif_pro::BOLD)?; + write(cx.dst.join("SourceSerifPro-It.ttf.woff"), + static_files::source_serif_pro::ITALIC)?; write(cx.dst.join("SourceSerifPro-LICENSE.txt"), static_files::source_serif_pro::LICENSE)?; write(cx.dst.join("SourceCodePro-Regular.woff"), diff --git a/src/librustdoc/html/static/COPYRIGHT.txt b/src/librustdoc/html/static/COPYRIGHT.txt index c69861aa70a23..af77776cca431 100644 --- a/src/librustdoc/html/static/COPYRIGHT.txt +++ b/src/librustdoc/html/static/COPYRIGHT.txt @@ -12,21 +12,6 @@ included, and carry their own copyright notices and license terms: Licensed under the SIL Open Font License, Version 1.1. See FiraSans-LICENSE.txt. -* Heuristica (Heuristica-Italic.woff): - - Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved. - Utopia is either a registered trademark or trademark of Adobe Systems - Incorporated in the United States and/or other countries. Used under - license. - - Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net - - Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru), - with Reserved Font Name Heuristica. - - Licensed under the SIL Open Font License, Version 1.1. - See Heuristica-LICENSE.txt. - * rustdoc.css, main.js, and playpen.js: Copyright 2015 The Rust Developers. @@ -47,7 +32,8 @@ included, and carry their own copyright notices and license terms: Licensed under the SIL Open Font License, Version 1.1. See SourceCodePro-LICENSE.txt. -* Source Serif Pro (SourceSerifPro-Regular.woff, SourceSerifPro-Bold.woff): +* Source Serif Pro (SourceSerifPro-Regular.ttf.woff, + SourceSerifPro-Bold.ttf.woff, SourceSerifPro-It.ttf.woff): Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of diff --git a/src/librustdoc/html/static/Heuristica-Italic.woff b/src/librustdoc/html/static/Heuristica-Italic.woff deleted file mode 100644 index b0cebf01de49b..0000000000000 Binary files a/src/librustdoc/html/static/Heuristica-Italic.woff and /dev/null differ diff --git a/src/librustdoc/html/static/Heuristica-LICENSE.txt b/src/librustdoc/html/static/Heuristica-LICENSE.txt deleted file mode 100644 index dd85e40e64548..0000000000000 --- a/src/librustdoc/html/static/Heuristica-LICENSE.txt +++ /dev/null @@ -1,101 +0,0 @@ -Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved. -Utopia is either a registered trademark or trademark of Adobe Systems -Incorporated in the United States and/or other countries. Used under -license. - -Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net - -Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru), -with Reserved Font Name Heuristica. - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff b/src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff new file mode 100644 index 0000000000000..e283dae58de6b Binary files /dev/null and b/src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff differ diff --git a/src/librustdoc/html/static/SourceSerifPro-Bold.woff b/src/librustdoc/html/static/SourceSerifPro-Bold.woff deleted file mode 100644 index ac1b1b3a0bb7a..0000000000000 Binary files a/src/librustdoc/html/static/SourceSerifPro-Bold.woff and /dev/null differ diff --git a/src/librustdoc/html/static/SourceSerifPro-It.ttf.woff b/src/librustdoc/html/static/SourceSerifPro-It.ttf.woff new file mode 100644 index 0000000000000..4bd621c9bd0ba Binary files /dev/null and b/src/librustdoc/html/static/SourceSerifPro-It.ttf.woff differ diff --git a/src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff b/src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff new file mode 100644 index 0000000000000..96b36a0ed2366 Binary files /dev/null and b/src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff differ diff --git a/src/librustdoc/html/static/SourceSerifPro-Regular.woff b/src/librustdoc/html/static/SourceSerifPro-Regular.woff deleted file mode 100644 index e8c43b852e10e..0000000000000 Binary files a/src/librustdoc/html/static/SourceSerifPro-Regular.woff and /dev/null differ diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 2cc0b5e30b893..14273c6b1db33 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -12,25 +12,24 @@ src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff'); } -/* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license and - * Heuristica-LICENSE.txt for the Heuristica license. */ +/* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license. */ @font-face { font-family: 'Source Serif Pro'; font-style: normal; font-weight: 400; - src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff'); + src: local('Source Serif Pro'), url("SourceSerifPro-Regular.ttf.woff") format('woff'); } @font-face { font-family: 'Source Serif Pro'; font-style: italic; font-weight: 400; - src: url("Heuristica-Italic.woff") format('woff'); + src: local('Source Serif Pro Italic'), url("SourceSerifPro-It.ttf.woff") format('woff'); } @font-face { font-family: 'Source Serif Pro'; font-style: normal; font-weight: 700; - src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff'); + src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.ttf.woff") format('woff'); } /* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */ diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 47629d058e31a..f340590e5fe33 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -73,22 +73,17 @@ pub mod fira_sans { pub static LICENSE: &'static [u8] = include_bytes!("static/FiraSans-LICENSE.txt"); } -/// Files related to the Heuristica font. -pub mod heuristica { - /// The file `Heuristica-Italic.woff`, the Italic variant of the Heuristica font. - pub static ITALIC: &'static [u8] = include_bytes!("static/Heuristica-Italic.woff"); - - /// The file `Heuristica-LICENSE.txt`, the license text for the Heuristica font. - pub static LICENSE: &'static [u8] = include_bytes!("static/Heuristica-LICENSE.txt"); -} - /// Files related to the Source Serif Pro font. pub mod source_serif_pro { - /// The file `SourceSerifPro-Regular.woff`, the Regular variant of the Source Serif Pro font. - pub static REGULAR: &'static [u8] = include_bytes!("static/SourceSerifPro-Regular.woff"); + /// The file `SourceSerifPro-Regular.ttf.woff`, the Regular variant of the Source Serif Pro + /// font. + pub static REGULAR: &'static [u8] = include_bytes!("static/SourceSerifPro-Regular.ttf.woff"); + + /// The file `SourceSerifPro-Bold.ttf.woff`, the Bold variant of the Source Serif Pro font. + pub static BOLD: &'static [u8] = include_bytes!("static/SourceSerifPro-Bold.ttf.woff"); - /// The file `SourceSerifPro-Bold.woff`, the Bold variant of the Source Serif Pro font. - pub static BOLD: &'static [u8] = include_bytes!("static/SourceSerifPro-Bold.woff"); + /// The file `SourceSerifPro-It.ttf.woff`, the Italic variant of the Source Serif Pro font. + pub static ITALIC: &'static [u8] = include_bytes!("static/SourceSerifPro-It.ttf.woff"); /// The file `SourceSerifPro-LICENSE.txt`, the license text for the Source Serif Pro font. pub static LICENSE: &'static [u8] = include_bytes!("static/SourceSerifPro-LICENSE.txt"); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 2170054b532b9..1f19fa2e7f598 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -394,7 +394,7 @@ pub fn make_test(s: &str, // Uses libsyntax to parse the doctest and find if there's a main fn and the extern // crate already is included. - let (already_has_main, already_has_extern_crate) = crate::syntax::with_globals(|| { + let (already_has_main, already_has_extern_crate, found_macro) = crate::syntax::with_globals(|| { use crate::syntax::{ast, parse::{self, ParseSess}, source_map::FilePathMapping}; use crate::syntax_pos::FileName; use errors::emitter::EmitterWriter; @@ -412,6 +412,7 @@ pub fn make_test(s: &str, let mut found_main = false; let mut found_extern_crate = cratename.is_none(); + let mut found_macro = false; let mut parser = match parse::maybe_new_parser_from_source_str(&sess, filename, source) { Ok(p) => p, @@ -420,7 +421,7 @@ pub fn make_test(s: &str, err.cancel(); } - return (found_main, found_extern_crate); + return (found_main, found_extern_crate, found_macro); } }; @@ -448,6 +449,12 @@ pub fn make_test(s: &str, } } + if !found_macro { + if let ast::ItemKind::Mac(..) = item.node { + found_macro = true; + } + } + if found_main && found_extern_crate { break; } @@ -460,9 +467,28 @@ pub fn make_test(s: &str, } } - (found_main, found_extern_crate) + (found_main, found_extern_crate, found_macro) }); + // If a doctest's `fn main` is being masked by a wrapper macro, the parsing loop above won't + // see it. In that case, run the old text-based scan to see if they at least have a main + // function written inside a macro invocation. See + // https://github.com/rust-lang/rust/issues/56898 + let already_has_main = if found_macro && !already_has_main { + s.lines() + .map(|line| { + let comment = line.find("//"); + if let Some(comment_begins) = comment { + &line[0..comment_begins] + } else { + line + } + }) + .any(|code| code.contains("fn main")) + } else { + already_has_main + }; + // Don't inject `extern crate std` because it's already injected by the // compiler. if !already_has_extern_crate && !opts.no_crate_inject && cratename != Some("std") { @@ -1143,4 +1169,23 @@ assert_eq!(asdf::foo, 4); let output = make_test(input, Some("asdf"), false, &opts); assert_eq!(output, (expected, 3)); } + + #[test] + fn make_test_main_in_macro() { + let opts = TestOptions::default(); + let input = +"#[macro_use] extern crate my_crate; +test_wrapper! { + fn main() {} +}"; + let expected = +"#![allow(unused)] +#[macro_use] extern crate my_crate; +test_wrapper! { + fn main() {} +}".to_string(); + + let output = make_test(input, Some("my_crate"), false, &opts); + assert_eq!(output, (expected, 1)); + } } diff --git a/src/libstd/error.rs b/src/libstd/error.rs index f026cadd639c3..2f9efb3f0fb57 100644 --- a/src/libstd/error.rs +++ b/src/libstd/error.rs @@ -30,17 +30,17 @@ use string; /// themselves through the [`Display`] and [`Debug`] traits, and may provide /// cause chain information: /// -/// The [`cause`] method is generally used when errors cross "abstraction -/// boundaries", i.e., when a one module must report an error that is "caused" -/// by an error from a lower-level module. This setup makes it possible for the -/// high-level module to provide its own errors that do not commit to any -/// particular implementation, but also reveal some of its implementation for -/// debugging via [`cause`] chains. +/// The [`source`] method is generally used when errors cross "abstraction +/// boundaries". If one module must report an error that is caused by an error +/// from a lower-level module, it can allow access to that error via the +/// [`source`] method. This makes it possible for the high-level module to +/// provide its own errors while also revealing some of the implementation for +/// debugging via [`source`] chains. /// /// [`Result`]: ../result/enum.Result.html /// [`Display`]: ../fmt/trait.Display.html /// [`Debug`]: ../fmt/trait.Debug.html -/// [`cause`]: trait.Error.html#method.cause +/// [`source`]: trait.Error.html#method.source #[stable(feature = "rust1", since = "1.0.0")] pub trait Error: Debug + Display { /// **This method is soft-deprecated.** diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 0991957fa7fd5..28a6fbd48cf09 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -252,7 +252,7 @@ //! [`println!`]: ../macro.println.html //! [`Lines`]: struct.Lines.html //! [`io::Result`]: type.Result.html -//! [`?` operator]: ../../book/first-edition/syntax-index.html +//! [`?` operator]: ../../book/appendix-02-operators.html //! [`Read::read`]: trait.Read.html#tymethod.read //! [`Result`]: ../result/enum.Result.html //! [`.unwrap()`]: ../result/enum.Result.html#method.unwrap diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index ccfce672e5f9e..e220080844946 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -242,8 +242,8 @@ #![feature(char_error_internals)] #![feature(compiler_builtins_lib)] #![feature(concat_idents)] -#![feature(const_int_ops)] -#![feature(const_ip)] +#![cfg_attr(stage0, feature(const_int_ops))] +#![cfg_attr(stage0, feature(const_ip))] #![feature(const_raw_ptr_deref)] #![feature(const_cstr_unchecked)] #![feature(core_intrinsics)] @@ -305,7 +305,7 @@ #![feature(maybe_uninit)] #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), feature(global_asm, range_contains, slice_index_methods, - decl_macro, coerce_unsized, sgx_platform))] + decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] #![default_lib_allocator] diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 52a29f4885f56..f98113e0896f7 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -328,7 +328,7 @@ impl Ipv4Addr { /// let addr = Ipv4Addr::new(127, 0, 0, 1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_ip")] + #[cfg_attr(stage0, rustc_const_unstable(feature = "const_ip"))] pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { Ipv4Addr { inner: c::in_addr { diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 317a7d817db43..5c7bff70a0dcd 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -2203,6 +2203,8 @@ impl Path { /// `a/b` all have `a` and `b` as components, but `./a/b` starts with /// an additional [`CurDir`] component. /// + /// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent. + /// /// Note that no other normalization takes place; in particular, `a/c` /// and `a/b/../c` are distinct, to account for the possibility that `b` /// is a symbolic link (so its parent isn't `a`). diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index 475c9b4aeaa4e..c2751508ce094 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -550,7 +550,6 @@ mod prim_array { } #[doc(alias = "[")] #[doc(alias = "]")] #[doc(alias = "[]")] -// /// A dynamically-sized view into a contiguous sequence, `[T]`. /// /// *[See also the `std::slice` module](slice/index.html).* @@ -572,11 +571,11 @@ mod prim_array { } /// points to: /// /// ``` -/// let x = &mut [1, 2, 3]; +/// let mut x = [1, 2, 3]; +/// let x = &mut x[..]; // Take a full slice of `x`. /// x[1] = 7; /// assert_eq!(x, &[1, 7, 3]); /// ``` -/// #[stable(feature = "rust1", since = "1.0.0")] mod prim_slice { } diff --git a/src/libstd/sys/sgx/abi/mem.rs b/src/libstd/sys/sgx/abi/mem.rs index 09552d5b4af29..808f1ce3ff2c7 100644 --- a/src/libstd/sys/sgx/abi/mem.rs +++ b/src/libstd/sys/sgx/abi/mem.rs @@ -17,8 +17,10 @@ extern { // Do not remove inline: will result in relocation failure // For the same reason we use inline ASM here instead of an extern static to // locate the base +/// Returns address at which current enclave is loaded. #[inline(always)] -fn image_base() -> u64 { +#[unstable(feature = "sgx_platform", issue = "56975")] +pub fn image_base() -> u64 { let base; unsafe { asm!("lea IMAGE_BASE(%rip),$0":"=r"(base)) }; base diff --git a/src/libstd/sys/sgx/backtrace.rs b/src/libstd/sys/sgx/backtrace.rs index 52d4a63bb6384..2b8e1da05791d 100644 --- a/src/libstd/sys/sgx/backtrace.rs +++ b/src/libstd/sys/sgx/backtrace.rs @@ -1,21 +1,90 @@ use io; -use sys::unsupported; +use error::Error; +use libc; use sys_common::backtrace::Frame; +use unwind as uw; +use sys::sgx::abi::mem::image_base; pub struct BacktraceContext; -pub fn unwind_backtrace(_frames: &mut [Frame]) - -> io::Result<(usize, BacktraceContext)> -{ - unsupported() +struct Context<'a> { + idx: usize, + frames: &'a mut [Frame], +} + +#[derive(Debug)] +struct UnwindError(uw::_Unwind_Reason_Code); + +impl Error for UnwindError { + fn description(&self) -> &'static str { + "unexpected return value while unwinding" + } +} + +impl ::fmt::Display for UnwindError { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + write!(f, "{}: {:?}", self.description(), self.0) + } +} + +#[inline(never)] // this function call can be skipped it when tracing. +pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> { + let mut cx = Context { idx: 0, frames }; + let result_unwind = + unsafe { uw::_Unwind_Backtrace(trace_fn, &mut cx as *mut Context as *mut libc::c_void) }; + // See libunwind:src/unwind/Backtrace.c for the return values. + // No, there is no doc. + let res = match result_unwind { + // These return codes seem to be benign and need to be ignored for backtraces + // to show up properly on all tested platforms. + uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => { + Ok((cx.idx, BacktraceContext)) + } + _ => Err(io::Error::new( + io::ErrorKind::Other, + UnwindError(result_unwind), + )), + }; + res +} + +extern "C" fn trace_fn( + ctx: *mut uw::_Unwind_Context, + arg: *mut libc::c_void, +) -> uw::_Unwind_Reason_Code { + let cx = unsafe { &mut *(arg as *mut Context) }; + if cx.idx >= cx.frames.len() { + return uw::_URC_NORMAL_STOP; + } + + let mut ip_before_insn = 0; + let mut ip = unsafe { uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void }; + if !ip.is_null() && ip_before_insn == 0 { + // this is a non-signaling frame, so `ip` refers to the address + // after the calling instruction. account for that. + ip = (ip as usize - 1) as *mut _; + } + + let symaddr = unsafe { uw::_Unwind_FindEnclosingFunction(ip) }; + cx.frames[cx.idx] = Frame { + symbol_addr: symaddr as *mut u8, + exact_position: ip as *mut u8, + inline_context: 0, + }; + cx.idx += 1; + + uw::_URC_NO_REASON } -pub fn resolve_symname(_frame: Frame, - _callback: F, +// To reduce TCB size in Sgx enclave, we do not want to implement resolve_symname functionality. +// Rather, we print the offset of the address here, which could be later mapped to correct function. +pub fn resolve_symname(frame: Frame, + callback: F, _: &BacktraceContext) -> io::Result<()> where F: FnOnce(Option<&str>) -> io::Result<()> { - unsupported() + callback(Some(&format!("0x{:x}", + (frame.symbol_addr.wrapping_offset_from(image_base() as _))))) } pub fn foreach_symbol_fileline(_: Frame, @@ -23,5 +92,5 @@ pub fn foreach_symbol_fileline(_: Frame, _: &BacktraceContext) -> io::Result where F: FnMut(&[u8], u32) -> io::Result<()> { - unsupported() + Ok(false) } diff --git a/src/libstd/sys/sgx/ext/arch.rs b/src/libstd/sys/sgx/ext/arch.rs index ba6f9e622ad35..3bd87b5d26574 100644 --- a/src/libstd/sys/sgx/ext/arch.rs +++ b/src/libstd/sys/sgx/ext/arch.rs @@ -36,7 +36,7 @@ pub fn egetkey(request: &Align512<[u8; 512]>) -> Result, u32> : "={eax}"(error) : "{eax}"(ENCLU_EGETKEY), "{rbx}"(request), - "{rcx}"(out.get_mut()) + "{rcx}"(out.as_mut_ptr()) : "flags" ); @@ -66,7 +66,7 @@ pub fn ereport( : "{eax}"(ENCLU_EREPORT), "{rbx}"(targetinfo), "{rcx}"(reportdata), - "{rdx}"(report.get_mut()) + "{rdx}"(report.as_mut_ptr()) ); report.into_inner() diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index cddec3eb23a5a..89da1a219b70a 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -193,9 +193,6 @@ declare_features! ( // Allows the definition of `const` functions with some advanced features. (active, const_fn, "1.2.0", Some(24111), None), - // Allows let bindings and destructuring in `const` functions and constants. - (active, const_let, "1.22.1", Some(48821), None), - // Allows accessing fields of unions inside `const` functions. (active, const_fn_union, "1.27.0", Some(51909), None), @@ -384,9 +381,6 @@ declare_features! ( // Infer static outlives requirements (RFC 2093). (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None), - // Multiple patterns with `|` in `if let` and `while let`. - (active, if_while_or_patterns, "1.26.0", Some(48215), None), - // Allows macro invocations in `extern {}` blocks. (active, macros_in_extern, "1.27.0", Some(49476), None), @@ -414,9 +408,6 @@ declare_features! ( // `#[doc(alias = "...")]` (active, doc_alias, "1.27.0", Some(50146), None), - // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086). - (active, irrefutable_let_patterns, "1.27.0", Some(44495), None), - // inconsistent bounds in where clauses (active, trivial_bounds, "1.28.0", Some(48214), None), @@ -443,9 +434,6 @@ declare_features! ( // support for arbitrary delimited token streams in non-macro attributes (active, unrestricted_attribute_tokens, "1.30.0", Some(55208), None), - // Allows `use x::y;` to resolve through `self::x`, not just `::x`. - (active, uniform_paths, "1.30.0", Some(53130), None), - // Allows unsized rvalues at arguments and parameters. (active, unsized_locals, "1.30.0", Some(48055), None), @@ -684,10 +672,20 @@ declare_features! ( (accepted, underscore_imports, "1.33.0", Some(48216), None), // Allows `#[repr(packed(N))]` attribute on structs. (accepted, repr_packed, "1.33.0", Some(33158), None), + // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086). + (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None), // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions. (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None), + // Allows let bindings, assignments and destructuring in `const` functions and constants. + // As long as control flow is not implemented in const eval, `&&` and `||` may not be used + // at the same time as let bindings. + (accepted, const_let, "1.33.0", Some(48821), None), // `#[cfg_attr(predicate, multiple, attributes, here)]` (accepted, cfg_attr_multi, "1.33.0", Some(54881), None), + // Top level or-patterns (`p | q`) in `if let` and `while let`. + (accepted, if_while_or_patterns, "1.33.0", Some(48215), None), + // Allows `use x::y;` to search `x` in the current scope. + (accepted, uniform_paths, "1.32.0", Some(53130), None), ); // If you change this, please modify `src/doc/unstable-book` as well. You must @@ -1701,12 +1699,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ExprKind::TryBlock(_) => { gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental"); } - ast::ExprKind::IfLet(ref pats, ..) | ast::ExprKind::WhileLet(ref pats, ..) => { - if pats.len() > 1 { - gate_feature_post!(&self, if_while_or_patterns, e.span, - "multiple patterns in `if let` and `while let` are unstable"); - } - } ast::ExprKind::Block(_, opt_label) => { if let Some(label) = opt_label { gate_feature_post!(&self, label_break_value, label.ident.span, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1e4a26b353759..b90eeaca54b97 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3660,8 +3660,6 @@ impl<'a> Parser<'a> { maybe_whole!(self, NtArm, |x| x); let attrs = self.parse_outer_attributes()?; - // Allow a '|' before the pats (RFC 1925) - self.eat(&token::BinOp(token::Or)); let pats = self.parse_pats()?; let guard = if self.eat_keyword(keywords::If) { Some(Guard::If(self.parse_expr()?)) @@ -3768,6 +3766,9 @@ impl<'a> Parser<'a> { /// Parse patterns, separated by '|' s fn parse_pats(&mut self) -> PResult<'a, Vec>> { + // Allow a '|' before the pats (RFC 1925 + RFC 2530) + self.eat(&token::BinOp(token::Or)); + let mut pats = Vec::new(); loop { pats.push(self.parse_top_level_pat()?); diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 61722ba551653..3e3bca7080fb6 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -159,7 +159,7 @@ fn parse_args<'a>( }; let name: &str = &ident.as_str(); - p.expect(&token::Eq).unwrap(); + p.expect(&token::Eq)?; let e = p.parse_expr()?; if let Some(prev) = names.get(name) { ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", name)) diff --git a/src/test/compile-fail/const-fn-error.rs b/src/test/compile-fail/const-fn-error.rs index 9913138693c94..da6036a04a549 100644 --- a/src/test/compile-fail/const-fn-error.rs +++ b/src/test/compile-fail/const-fn-error.rs @@ -1,4 +1,4 @@ -#![feature(const_fn, const_let)] +#![feature(const_fn)] const X : usize = 2; diff --git a/src/test/run-pass/binding/allow_irrefutable_let_patterns.rs b/src/test/run-pass/binding/allow_irrefutable_let_patterns.rs deleted file mode 100644 index d9a42a2963998..0000000000000 --- a/src/test/run-pass/binding/allow_irrefutable_let_patterns.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass -#![feature(irrefutable_let_patterns)] - -// must-compile-successfully-irrefutable_let_patterns_with_gate -#[allow(irrefutable_let_patterns)] -fn main() { - if let _ = 5 {} - - while let _ = 5 { - break; - } -} diff --git a/src/test/run-pass/const-int-conversion.rs b/src/test/run-pass/const-int-conversion.rs index 2b4904cc6c39a..19d65860179b2 100644 --- a/src/test/run-pass/const-int-conversion.rs +++ b/src/test/run-pass/const-int-conversion.rs @@ -1,4 +1,4 @@ -#![feature(const_int_conversion, const_int_ops, reverse_bits)] +#![feature(const_int_conversion, reverse_bits)] const REVERSE: u32 = 0x12345678_u32.reverse_bits(); const FROM_BE_BYTES: i32 = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]); @@ -21,4 +21,3 @@ fn main() { assert_eq!(TO_LE_BYTES, ident([0x78, 0x56, 0x34, 0x12])); assert_eq!(TO_NE_BYTES, ident([0x80, 0, 0, 0])); } - diff --git a/src/test/run-pass/const-int-rotate.rs b/src/test/run-pass/const-int-rotate.rs index 68c77f27a3193..c014e97ef19b8 100644 --- a/src/test/run-pass/const-int-rotate.rs +++ b/src/test/run-pass/const-int-rotate.rs @@ -1,5 +1,3 @@ -#![feature(const_int_rotate)] - const LEFT: u32 = 0x10000b3u32.rotate_left(8); const RIGHT: u32 = 0xb301u32.rotate_right(8); diff --git a/src/test/run-pass/const-int-sign.rs b/src/test/run-pass/const-int-sign.rs index ae55c1a9b0e39..9d656a0203069 100644 --- a/src/test/run-pass/const-int-sign.rs +++ b/src/test/run-pass/const-int-sign.rs @@ -1,5 +1,3 @@ -#![feature(const_int_sign)] - const NEGATIVE_A: bool = (-10i32).is_negative(); const NEGATIVE_B: bool = 10i32.is_negative(); const POSITIVE_A: bool= (-10i32).is_positive(); diff --git a/src/test/run-pass/const-int-wrapping.rs b/src/test/run-pass/const-int-wrapping.rs index 504a654c0db65..5ab712015dfc3 100644 --- a/src/test/run-pass/const-int-wrapping.rs +++ b/src/test/run-pass/const-int-wrapping.rs @@ -1,5 +1,3 @@ -#![feature(const_int_wrapping)] - const ADD_A: u32 = 200u32.wrapping_add(55); const ADD_B: u32 = 200u32.wrapping_add(u32::max_value()); diff --git a/src/test/run-pass/consts/const-endianess.rs b/src/test/run-pass/consts/const-endianess.rs index dfc6678ba289d..cbe6d864c9c3a 100644 --- a/src/test/run-pass/consts/const-endianess.rs +++ b/src/test/run-pass/consts/const-endianess.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(const_int_ops)] #![feature(test)] extern crate test; @@ -8,7 +7,6 @@ use test::black_box as b; const BE_U32: u32 = 55u32.to_be(); const LE_U32: u32 = 55u32.to_le(); - fn main() { assert_eq!(BE_U32, b(55u32).to_be()); assert_eq!(LE_U32, b(55u32).to_le()); diff --git a/src/test/run-pass/ctfe/bswap-const.rs b/src/test/run-pass/ctfe/bswap-const.rs index 90e97c8edbdd5..3145c21acc988 100644 --- a/src/test/run-pass/ctfe/bswap-const.rs +++ b/src/test/run-pass/ctfe/bswap-const.rs @@ -4,9 +4,9 @@ use std::intrinsics; -const SWAPPED_U8: u8 = unsafe { intrinsics::bswap(0x12_u8) }; -const SWAPPED_U16: u16 = unsafe { intrinsics::bswap(0x12_34_u16) }; -const SWAPPED_I32: i32 = unsafe { intrinsics::bswap(0x12_34_56_78_i32) }; +const SWAPPED_U8: u8 = intrinsics::bswap(0x12_u8); +const SWAPPED_U16: u16 = intrinsics::bswap(0x12_34_u16); +const SWAPPED_I32: i32 = intrinsics::bswap(0x12_34_56_78_i32); fn main() { assert_eq!(SWAPPED_U8, 0x12); diff --git a/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs b/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs index 90295414d3efc..10a4c31f24ed4 100644 --- a/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs +++ b/src/test/run-pass/ctfe/const-block-non-item-statement-3.rs @@ -1,8 +1,8 @@ // run-pass #![allow(dead_code)] -#![feature(const_let)] - type Array = [u32; { let x = 2; 5 }]; -pub fn main() {} +pub fn main() { + let _: Array = [0; 5]; +} diff --git a/src/test/run-pass/ctfe/const-block-non-item-statement.rs b/src/test/run-pass/ctfe/const-block-non-item-statement.rs index 21ce08ab69c73..a1b9b586ad038 100644 --- a/src/test/run-pass/ctfe/const-block-non-item-statement.rs +++ b/src/test/run-pass/ctfe/const-block-non-item-statement.rs @@ -1,10 +1,11 @@ // run-pass #![allow(dead_code)] -#![feature(const_let)] - +#[repr(u8)] enum Foo { Bar = { let x = 1; 3 } } -pub fn main() {} +pub fn main() { + assert_eq!(3, Foo::Bar as u8); +} diff --git a/src/test/run-pass/ctfe/issue-37550.rs b/src/test/run-pass/ctfe/issue-37550.rs index 732c34dff5a80..04865830df2eb 100644 --- a/src/test/run-pass/ctfe/issue-37550.rs +++ b/src/test/run-pass/ctfe/issue-37550.rs @@ -2,7 +2,7 @@ #![allow(dead_code)] #![allow(unused_variables)] -#![feature(const_fn, const_let)] +#![feature(const_fn)] const fn x() { let t = true; diff --git a/src/test/run-pass/ctfe/locals-in-const-fn.rs b/src/test/run-pass/ctfe/locals-in-const-fn.rs index e527e1e88c8da..95d50171a847b 100644 --- a/src/test/run-pass/ctfe/locals-in-const-fn.rs +++ b/src/test/run-pass/ctfe/locals-in-const-fn.rs @@ -2,8 +2,6 @@ // https://github.com/rust-lang/rust/issues/48821 -#![feature(const_fn, const_let)] - const fn foo(i: usize) -> usize { let x = i; x diff --git a/src/test/run-pass/intrinsics/intrinsics-integer.rs b/src/test/run-pass/intrinsics/intrinsics-integer.rs index 66e07f8683a87..0154f04995029 100644 --- a/src/test/run-pass/intrinsics/intrinsics-integer.rs +++ b/src/test/run-pass/intrinsics/intrinsics-integer.rs @@ -16,63 +16,63 @@ mod rusti { } pub fn main() { - unsafe { - use rusti::*; - - assert_eq!(ctpop(0u8), 0); assert_eq!(ctpop(0i8), 0); - assert_eq!(ctpop(0u16), 0); assert_eq!(ctpop(0i16), 0); - assert_eq!(ctpop(0u32), 0); assert_eq!(ctpop(0i32), 0); - assert_eq!(ctpop(0u64), 0); assert_eq!(ctpop(0i64), 0); - assert_eq!(ctpop(0u128), 0); assert_eq!(ctpop(0i128), 0); - - assert_eq!(ctpop(1u8), 1); assert_eq!(ctpop(1i8), 1); - assert_eq!(ctpop(1u16), 1); assert_eq!(ctpop(1i16), 1); - assert_eq!(ctpop(1u32), 1); assert_eq!(ctpop(1i32), 1); - assert_eq!(ctpop(1u64), 1); assert_eq!(ctpop(1i64), 1); - assert_eq!(ctpop(1u128), 1); assert_eq!(ctpop(1i128), 1); - - assert_eq!(ctpop(10u8), 2); assert_eq!(ctpop(10i8), 2); - assert_eq!(ctpop(10u16), 2); assert_eq!(ctpop(10i16), 2); - assert_eq!(ctpop(10u32), 2); assert_eq!(ctpop(10i32), 2); - assert_eq!(ctpop(10u64), 2); assert_eq!(ctpop(10i64), 2); - assert_eq!(ctpop(10u128), 2); assert_eq!(ctpop(10i128), 2); - - assert_eq!(ctpop(100u8), 3); assert_eq!(ctpop(100i8), 3); - assert_eq!(ctpop(100u16), 3); assert_eq!(ctpop(100i16), 3); - assert_eq!(ctpop(100u32), 3); assert_eq!(ctpop(100i32), 3); - assert_eq!(ctpop(100u64), 3); assert_eq!(ctpop(100i64), 3); - assert_eq!(ctpop(100u128), 3); assert_eq!(ctpop(100i128), 3); - - assert_eq!(ctpop(-1i8 as u8), 8); assert_eq!(ctpop(-1i8), 8); - assert_eq!(ctpop(-1i16 as u16), 16); assert_eq!(ctpop(-1i16), 16); - assert_eq!(ctpop(-1i32 as u32), 32); assert_eq!(ctpop(-1i32), 32); - assert_eq!(ctpop(-1i64 as u64), 64); assert_eq!(ctpop(-1i64), 64); - assert_eq!(ctpop(-1i128 as u128), 128); assert_eq!(ctpop(-1i128), 128); - - assert_eq!(ctlz(0u8), 8); assert_eq!(ctlz(0i8), 8); - assert_eq!(ctlz(0u16), 16); assert_eq!(ctlz(0i16), 16); - assert_eq!(ctlz(0u32), 32); assert_eq!(ctlz(0i32), 32); - assert_eq!(ctlz(0u64), 64); assert_eq!(ctlz(0i64), 64); - assert_eq!(ctlz(0u128), 128); assert_eq!(ctlz(0i128), 128); - - assert_eq!(ctlz(1u8), 7); assert_eq!(ctlz(1i8), 7); - assert_eq!(ctlz(1u16), 15); assert_eq!(ctlz(1i16), 15); - assert_eq!(ctlz(1u32), 31); assert_eq!(ctlz(1i32), 31); - assert_eq!(ctlz(1u64), 63); assert_eq!(ctlz(1i64), 63); - assert_eq!(ctlz(1u128), 127); assert_eq!(ctlz(1i128), 127); - - assert_eq!(ctlz(10u8), 4); assert_eq!(ctlz(10i8), 4); - assert_eq!(ctlz(10u16), 12); assert_eq!(ctlz(10i16), 12); - assert_eq!(ctlz(10u32), 28); assert_eq!(ctlz(10i32), 28); - assert_eq!(ctlz(10u64), 60); assert_eq!(ctlz(10i64), 60); - assert_eq!(ctlz(10u128), 124); assert_eq!(ctlz(10i128), 124); - - assert_eq!(ctlz(100u8), 1); assert_eq!(ctlz(100i8), 1); - assert_eq!(ctlz(100u16), 9); assert_eq!(ctlz(100i16), 9); - assert_eq!(ctlz(100u32), 25); assert_eq!(ctlz(100i32), 25); - assert_eq!(ctlz(100u64), 57); assert_eq!(ctlz(100i64), 57); - assert_eq!(ctlz(100u128), 121); assert_eq!(ctlz(100i128), 121); + use rusti::*; + + assert_eq!(ctpop(0u8), 0); assert_eq!(ctpop(0i8), 0); + assert_eq!(ctpop(0u16), 0); assert_eq!(ctpop(0i16), 0); + assert_eq!(ctpop(0u32), 0); assert_eq!(ctpop(0i32), 0); + assert_eq!(ctpop(0u64), 0); assert_eq!(ctpop(0i64), 0); + assert_eq!(ctpop(0u128), 0); assert_eq!(ctpop(0i128), 0); + + assert_eq!(ctpop(1u8), 1); assert_eq!(ctpop(1i8), 1); + assert_eq!(ctpop(1u16), 1); assert_eq!(ctpop(1i16), 1); + assert_eq!(ctpop(1u32), 1); assert_eq!(ctpop(1i32), 1); + assert_eq!(ctpop(1u64), 1); assert_eq!(ctpop(1i64), 1); + assert_eq!(ctpop(1u128), 1); assert_eq!(ctpop(1i128), 1); + + assert_eq!(ctpop(10u8), 2); assert_eq!(ctpop(10i8), 2); + assert_eq!(ctpop(10u16), 2); assert_eq!(ctpop(10i16), 2); + assert_eq!(ctpop(10u32), 2); assert_eq!(ctpop(10i32), 2); + assert_eq!(ctpop(10u64), 2); assert_eq!(ctpop(10i64), 2); + assert_eq!(ctpop(10u128), 2); assert_eq!(ctpop(10i128), 2); + + assert_eq!(ctpop(100u8), 3); assert_eq!(ctpop(100i8), 3); + assert_eq!(ctpop(100u16), 3); assert_eq!(ctpop(100i16), 3); + assert_eq!(ctpop(100u32), 3); assert_eq!(ctpop(100i32), 3); + assert_eq!(ctpop(100u64), 3); assert_eq!(ctpop(100i64), 3); + assert_eq!(ctpop(100u128), 3); assert_eq!(ctpop(100i128), 3); + + assert_eq!(ctpop(-1i8 as u8), 8); assert_eq!(ctpop(-1i8), 8); + assert_eq!(ctpop(-1i16 as u16), 16); assert_eq!(ctpop(-1i16), 16); + assert_eq!(ctpop(-1i32 as u32), 32); assert_eq!(ctpop(-1i32), 32); + assert_eq!(ctpop(-1i64 as u64), 64); assert_eq!(ctpop(-1i64), 64); + assert_eq!(ctpop(-1i128 as u128), 128); assert_eq!(ctpop(-1i128), 128); + + assert_eq!(ctlz(0u8), 8); assert_eq!(ctlz(0i8), 8); + assert_eq!(ctlz(0u16), 16); assert_eq!(ctlz(0i16), 16); + assert_eq!(ctlz(0u32), 32); assert_eq!(ctlz(0i32), 32); + assert_eq!(ctlz(0u64), 64); assert_eq!(ctlz(0i64), 64); + assert_eq!(ctlz(0u128), 128); assert_eq!(ctlz(0i128), 128); + + assert_eq!(ctlz(1u8), 7); assert_eq!(ctlz(1i8), 7); + assert_eq!(ctlz(1u16), 15); assert_eq!(ctlz(1i16), 15); + assert_eq!(ctlz(1u32), 31); assert_eq!(ctlz(1i32), 31); + assert_eq!(ctlz(1u64), 63); assert_eq!(ctlz(1i64), 63); + assert_eq!(ctlz(1u128), 127); assert_eq!(ctlz(1i128), 127); + + assert_eq!(ctlz(10u8), 4); assert_eq!(ctlz(10i8), 4); + assert_eq!(ctlz(10u16), 12); assert_eq!(ctlz(10i16), 12); + assert_eq!(ctlz(10u32), 28); assert_eq!(ctlz(10i32), 28); + assert_eq!(ctlz(10u64), 60); assert_eq!(ctlz(10i64), 60); + assert_eq!(ctlz(10u128), 124); assert_eq!(ctlz(10i128), 124); + + assert_eq!(ctlz(100u8), 1); assert_eq!(ctlz(100i8), 1); + assert_eq!(ctlz(100u16), 9); assert_eq!(ctlz(100i16), 9); + assert_eq!(ctlz(100u32), 25); assert_eq!(ctlz(100i32), 25); + assert_eq!(ctlz(100u64), 57); assert_eq!(ctlz(100i64), 57); + assert_eq!(ctlz(100u128), 121); assert_eq!(ctlz(100i128), 121); + unsafe { assert_eq!(ctlz_nonzero(1u8), 7); assert_eq!(ctlz_nonzero(1i8), 7); assert_eq!(ctlz_nonzero(1u16), 15); assert_eq!(ctlz_nonzero(1i16), 15); assert_eq!(ctlz_nonzero(1u32), 31); assert_eq!(ctlz_nonzero(1i32), 31); @@ -90,37 +90,39 @@ pub fn main() { assert_eq!(ctlz_nonzero(100u32), 25); assert_eq!(ctlz_nonzero(100i32), 25); assert_eq!(ctlz_nonzero(100u64), 57); assert_eq!(ctlz_nonzero(100i64), 57); assert_eq!(ctlz_nonzero(100u128), 121); assert_eq!(ctlz_nonzero(100i128), 121); + } - assert_eq!(cttz(-1i8 as u8), 0); assert_eq!(cttz(-1i8), 0); - assert_eq!(cttz(-1i16 as u16), 0); assert_eq!(cttz(-1i16), 0); - assert_eq!(cttz(-1i32 as u32), 0); assert_eq!(cttz(-1i32), 0); - assert_eq!(cttz(-1i64 as u64), 0); assert_eq!(cttz(-1i64), 0); - assert_eq!(cttz(-1i128 as u128), 0); assert_eq!(cttz(-1i128), 0); - - assert_eq!(cttz(0u8), 8); assert_eq!(cttz(0i8), 8); - assert_eq!(cttz(0u16), 16); assert_eq!(cttz(0i16), 16); - assert_eq!(cttz(0u32), 32); assert_eq!(cttz(0i32), 32); - assert_eq!(cttz(0u64), 64); assert_eq!(cttz(0i64), 64); - assert_eq!(cttz(0u128), 128); assert_eq!(cttz(0i128), 128); - - assert_eq!(cttz(1u8), 0); assert_eq!(cttz(1i8), 0); - assert_eq!(cttz(1u16), 0); assert_eq!(cttz(1i16), 0); - assert_eq!(cttz(1u32), 0); assert_eq!(cttz(1i32), 0); - assert_eq!(cttz(1u64), 0); assert_eq!(cttz(1i64), 0); - assert_eq!(cttz(1u128), 0); assert_eq!(cttz(1i128), 0); - - assert_eq!(cttz(10u8), 1); assert_eq!(cttz(10i8), 1); - assert_eq!(cttz(10u16), 1); assert_eq!(cttz(10i16), 1); - assert_eq!(cttz(10u32), 1); assert_eq!(cttz(10i32), 1); - assert_eq!(cttz(10u64), 1); assert_eq!(cttz(10i64), 1); - assert_eq!(cttz(10u128), 1); assert_eq!(cttz(10i128), 1); - - assert_eq!(cttz(100u8), 2); assert_eq!(cttz(100i8), 2); - assert_eq!(cttz(100u16), 2); assert_eq!(cttz(100i16), 2); - assert_eq!(cttz(100u32), 2); assert_eq!(cttz(100i32), 2); - assert_eq!(cttz(100u64), 2); assert_eq!(cttz(100i64), 2); - assert_eq!(cttz(100u128), 2); assert_eq!(cttz(100i128), 2); + assert_eq!(cttz(-1i8 as u8), 0); assert_eq!(cttz(-1i8), 0); + assert_eq!(cttz(-1i16 as u16), 0); assert_eq!(cttz(-1i16), 0); + assert_eq!(cttz(-1i32 as u32), 0); assert_eq!(cttz(-1i32), 0); + assert_eq!(cttz(-1i64 as u64), 0); assert_eq!(cttz(-1i64), 0); + assert_eq!(cttz(-1i128 as u128), 0); assert_eq!(cttz(-1i128), 0); + + assert_eq!(cttz(0u8), 8); assert_eq!(cttz(0i8), 8); + assert_eq!(cttz(0u16), 16); assert_eq!(cttz(0i16), 16); + assert_eq!(cttz(0u32), 32); assert_eq!(cttz(0i32), 32); + assert_eq!(cttz(0u64), 64); assert_eq!(cttz(0i64), 64); + assert_eq!(cttz(0u128), 128); assert_eq!(cttz(0i128), 128); + + assert_eq!(cttz(1u8), 0); assert_eq!(cttz(1i8), 0); + assert_eq!(cttz(1u16), 0); assert_eq!(cttz(1i16), 0); + assert_eq!(cttz(1u32), 0); assert_eq!(cttz(1i32), 0); + assert_eq!(cttz(1u64), 0); assert_eq!(cttz(1i64), 0); + assert_eq!(cttz(1u128), 0); assert_eq!(cttz(1i128), 0); + + assert_eq!(cttz(10u8), 1); assert_eq!(cttz(10i8), 1); + assert_eq!(cttz(10u16), 1); assert_eq!(cttz(10i16), 1); + assert_eq!(cttz(10u32), 1); assert_eq!(cttz(10i32), 1); + assert_eq!(cttz(10u64), 1); assert_eq!(cttz(10i64), 1); + assert_eq!(cttz(10u128), 1); assert_eq!(cttz(10i128), 1); + + assert_eq!(cttz(100u8), 2); assert_eq!(cttz(100i8), 2); + assert_eq!(cttz(100u16), 2); assert_eq!(cttz(100i16), 2); + assert_eq!(cttz(100u32), 2); assert_eq!(cttz(100i32), 2); + assert_eq!(cttz(100u64), 2); assert_eq!(cttz(100i64), 2); + assert_eq!(cttz(100u128), 2); assert_eq!(cttz(100i128), 2); + unsafe { assert_eq!(cttz_nonzero(-1i8 as u8), 0); assert_eq!(cttz_nonzero(-1i8), 0); assert_eq!(cttz_nonzero(-1i16 as u16), 0); assert_eq!(cttz_nonzero(-1i16), 0); assert_eq!(cttz_nonzero(-1i32 as u32), 0); assert_eq!(cttz_nonzero(-1i32), 0); @@ -144,27 +146,27 @@ pub fn main() { assert_eq!(cttz_nonzero(100u32), 2); assert_eq!(cttz_nonzero(100i32), 2); assert_eq!(cttz_nonzero(100u64), 2); assert_eq!(cttz_nonzero(100i64), 2); assert_eq!(cttz_nonzero(100u128), 2); assert_eq!(cttz_nonzero(100i128), 2); - - assert_eq!(bswap(0x0Au8), 0x0A); // no-op - assert_eq!(bswap(0x0Ai8), 0x0A); // no-op - assert_eq!(bswap(0x0A0Bu16), 0x0B0A); - assert_eq!(bswap(0x0A0Bi16), 0x0B0A); - assert_eq!(bswap(0x0ABBCC0Du32), 0x0DCCBB0A); - assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A); - assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201); - assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201); - assert_eq!(bswap(0x0122334455667708u128), 0x08776655443322010000000000000000); - assert_eq!(bswap(0x0122334455667708i128), 0x08776655443322010000000000000000); - - assert_eq!(bitreverse(0x0Au8), 0x50); - assert_eq!(bitreverse(0x0Ai8), 0x50); - assert_eq!(bitreverse(0x0A0Cu16), 0x3050); - assert_eq!(bitreverse(0x0A0Ci16), 0x3050); - assert_eq!(bitreverse(0x0ABBCC0Eu32), 0x7033DD50); - assert_eq!(bitreverse(0x0ABBCC0Ei32), 0x7033DD50); - assert_eq!(bitreverse(0x0122334455667708u64), 0x10EE66AA22CC4480); - assert_eq!(bitreverse(0x0122334455667708i64), 0x10EE66AA22CC4480); - assert_eq!(bitreverse(0x0122334455667708u128), 0x10EE66AA22CC44800000000000000000); - assert_eq!(bitreverse(0x0122334455667708i128), 0x10EE66AA22CC44800000000000000000); } + + assert_eq!(bswap(0x0Au8), 0x0A); // no-op + assert_eq!(bswap(0x0Ai8), 0x0A); // no-op + assert_eq!(bswap(0x0A0Bu16), 0x0B0A); + assert_eq!(bswap(0x0A0Bi16), 0x0B0A); + assert_eq!(bswap(0x0ABBCC0Du32), 0x0DCCBB0A); + assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A); + assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201); + assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201); + assert_eq!(bswap(0x0122334455667708u128), 0x08776655443322010000000000000000); + assert_eq!(bswap(0x0122334455667708i128), 0x08776655443322010000000000000000); + + assert_eq!(bitreverse(0x0Au8), 0x50); + assert_eq!(bitreverse(0x0Ai8), 0x50); + assert_eq!(bitreverse(0x0A0Cu16), 0x3050); + assert_eq!(bitreverse(0x0A0Ci16), 0x3050); + assert_eq!(bitreverse(0x0ABBCC0Eu32), 0x7033DD50); + assert_eq!(bitreverse(0x0ABBCC0Ei32), 0x7033DD50); + assert_eq!(bitreverse(0x0122334455667708u64), 0x10EE66AA22CC4480); + assert_eq!(bitreverse(0x0122334455667708i64), 0x10EE66AA22CC4480); + assert_eq!(bitreverse(0x0122334455667708u128), 0x10EE66AA22CC44800000000000000000); + assert_eq!(bitreverse(0x0122334455667708i128), 0x10EE66AA22CC44800000000000000000); } diff --git a/src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs b/src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs index f9bd2f471ae9d..22f04c58f3b3c 100644 --- a/src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs +++ b/src/test/run-pass/rfcs/rfc-2175-or-if-while-let/basic.rs @@ -1,6 +1,5 @@ // run-pass #![allow(dead_code)] -#![feature(if_while_or_patterns)] enum E { V(u8), @@ -19,4 +18,16 @@ fn main() { assert_eq!(x, 10); e = W; } + + // Accept leading `|`: + + let mut e = V(10); + + if let | V(x) | U(x) = e { + assert_eq!(x, 10); + } + while let | V(x) | U(x) = e { + assert_eq!(x, 10); + e = W; + } } diff --git a/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs b/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs index e8e25d877477a..a46533178609b 100644 --- a/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs +++ b/src/test/run-pass/uniform-paths/auxiliary/issue-53691.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(uniform_paths)] - mod m { pub fn f() {} } mod n { pub fn g() {} } diff --git a/src/test/run-pass/uniform-paths/basic-nested.rs b/src/test/run-pass/uniform-paths/basic-nested.rs index 0b95618ded5d3..e4e8b32c70ee9 100644 --- a/src/test/run-pass/uniform-paths/basic-nested.rs +++ b/src/test/run-pass/uniform-paths/basic-nested.rs @@ -1,12 +1,12 @@ -// run-pass -#![allow(unused_imports)] -#![allow(non_camel_case_types)] +// This test is similar to `basic.rs`, but nested in modules. +// run-pass // edition:2018 -#![feature(decl_macro, uniform_paths)] +#![feature(decl_macro)] -// This test is similar to `basic.rs`, but nested in modules. +#![allow(unused_imports)] +#![allow(non_camel_case_types)] mod foo { // Test that ambiguity errors are not emitted between `self::test` and diff --git a/src/test/run-pass/uniform-paths/basic.rs b/src/test/run-pass/uniform-paths/basic.rs index 347e0bc00f118..4e2e2dedef679 100644 --- a/src/test/run-pass/uniform-paths/basic.rs +++ b/src/test/run-pass/uniform-paths/basic.rs @@ -1,10 +1,8 @@ // run-pass -#![allow(unused_imports)] -#![allow(non_camel_case_types)] - // edition:2018 -#![feature(uniform_paths)] +#![allow(unused_imports)] +#![allow(non_camel_case_types)] // Test that ambiguity errors are not emitted between `self::test` and // `::test`, assuming the latter (crate) is not in `extern_prelude`. diff --git a/src/test/run-pass/uniform-paths/macros-nested.rs b/src/test/run-pass/uniform-paths/macros-nested.rs index cf33c4860a1b4..a62a28bb94d12 100644 --- a/src/test/run-pass/uniform-paths/macros-nested.rs +++ b/src/test/run-pass/uniform-paths/macros-nested.rs @@ -1,11 +1,9 @@ -// run-pass -#![allow(non_camel_case_types)] +// This test is similar to `macros.rs`, but nested in modules. +// run-pass // edition:2018 -#![feature(uniform_paths)] - -// This test is similar to `macros.rs`, but nested in modules. +#![allow(non_camel_case_types)] mod foo { // Test that ambiguity errors are not emitted between `self::test` and diff --git a/src/test/run-pass/uniform-paths/macros.rs b/src/test/run-pass/uniform-paths/macros.rs index 332c2266e322b..31b809f0cfdc5 100644 --- a/src/test/run-pass/uniform-paths/macros.rs +++ b/src/test/run-pass/uniform-paths/macros.rs @@ -1,11 +1,9 @@ -// run-pass -#![allow(non_camel_case_types)] +// This test is similar to `basic.rs`, but with macros defining local items. +// run-pass // edition:2018 -#![feature(uniform_paths)] - -// This test is similar to `basic.rs`, but with macros defining local items. +#![allow(non_camel_case_types)] // Test that ambiguity errors are not emitted between `self::test` and // `::test`, assuming the latter (crate) is not in `extern_prelude`. diff --git a/src/test/run-pass/uniform-paths/same-crate.rs b/src/test/run-pass/uniform-paths/same-crate.rs index 18a7d089a9b0c..ce4cc13d9ecd7 100644 --- a/src/test/run-pass/uniform-paths/same-crate.rs +++ b/src/test/run-pass/uniform-paths/same-crate.rs @@ -1,9 +1,6 @@ // run-pass - // edition:2018 -#![feature(uniform_paths)] - pub const A: usize = 0; pub mod foo { diff --git a/src/test/ui/assoc-inherent.rs b/src/test/ui/assoc-inherent.rs index fe34be3731736..05329a2714257 100644 --- a/src/test/ui/assoc-inherent.rs +++ b/src/test/ui/assoc-inherent.rs @@ -1,9 +1,9 @@ -// Test associated types are forbidden in inherent impls. +// Test associated types are, until #8995 is implemented, forbidden in inherent impls. struct Foo; impl Foo { - type Bar = isize; //~ERROR associated types are not allowed in inherent impls + type Bar = isize; //~ERROR associated types are not yet supported in inherent impls (see #8995) } fn main() {} diff --git a/src/test/ui/assoc-inherent.stderr b/src/test/ui/assoc-inherent.stderr index 1a555bd53ac83..f438ac8df4a09 100644 --- a/src/test/ui/assoc-inherent.stderr +++ b/src/test/ui/assoc-inherent.stderr @@ -1,7 +1,7 @@ -error[E0202]: associated types are not allowed in inherent impls +error[E0202]: associated types are not yet supported in inherent impls (see #8995) --> $DIR/assoc-inherent.rs:6:5 | -LL | type Bar = isize; //~ERROR associated types are not allowed in inherent impls +LL | type Bar = isize; //~ERROR associated types are not yet supported in inherent impls (see #8995) | ^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/bad/bad-intrinsic-monomorphization.rs b/src/test/ui/bad/bad-intrinsic-monomorphization.rs index b56e1ea039cf1..a29723f34b432 100644 --- a/src/test/ui/bad/bad-intrinsic-monomorphization.rs +++ b/src/test/ui/bad/bad-intrinsic-monomorphization.rs @@ -14,7 +14,7 @@ use std::intrinsics; #[derive(Copy, Clone)] pub struct Foo(i64); -pub unsafe fn test_cttz(v: Foo) -> Foo { +pub fn test_cttz(v: Foo) -> Foo { intrinsics::cttz(v) //~^ ERROR `cttz` intrinsic: expected basic integer type, found `Foo` } diff --git a/src/test/ui/check-static-values-constraints.nll.stderr b/src/test/ui/check-static-values-constraints.nll.stderr index d2f6c7510a91d..f1a2312490813 100644 --- a/src/test/ui/check-static-values-constraints.nll.stderr +++ b/src/test/ui/check-static-values-constraints.nll.stderr @@ -13,44 +13,80 @@ error[E0010]: allocations are not allowed in statics LL | static STATIC11: Box = box MyOwned; | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:79:37 + | +LL | static STATIC11: Box = box MyOwned; + | ^^^^^^^ + error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/check-static-values-constraints.rs:89:32 + --> $DIR/check-static-values-constraints.rs:90:32 | LL | field2: SafeEnum::Variant4("str".to_string()) | ^^^^^^^^^^^^^^^^^ error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:94:5 + --> $DIR/check-static-values-constraints.rs:95:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:95:9 + | +LL | box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:95:5 + --> $DIR/check-static-values-constraints.rs:97:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:97:9 + | +LL | box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:99:6 + --> $DIR/check-static-values-constraints.rs:102:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:102:10 + | +LL | &box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:100:6 + --> $DIR/check-static-values-constraints.rs:104:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:104:10 + | +LL | &box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:106:5 + --> $DIR/check-static-values-constraints.rs:111:5 | LL | box 3; | ^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:111:9 + | +LL | box 3; + | ^ + error[E0507]: cannot move out of static item - --> $DIR/check-static-values-constraints.rs:110:45 + --> $DIR/check-static-values-constraints.rs:116:45 | LL | let y = { static x: Box = box 3; x }; | ^ @@ -59,12 +95,18 @@ LL | let y = { static x: Box = box 3; x }; | help: consider borrowing here: `&x` error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:110:38 + --> $DIR/check-static-values-constraints.rs:116:38 | LL | let y = { static x: Box = box 3; x }; | ^^^^^ allocation not allowed in statics -error: aborting due to 10 previous errors +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:116:42 + | +LL | let y = { static x: Box = box 3; x }; + | ^ + +error: aborting due to 17 previous errors -Some errors occurred: E0010, E0015, E0493, E0507. +Some errors occurred: E0010, E0015, E0019, E0493, E0507. For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/check-static-values-constraints.rs b/src/test/ui/check-static-values-constraints.rs index eb0fc39e1bf15..acfb3b5e44bab 100644 --- a/src/test/ui/check-static-values-constraints.rs +++ b/src/test/ui/check-static-values-constraints.rs @@ -78,6 +78,7 @@ struct MyOwned; static STATIC11: Box = box MyOwned; //~^ ERROR allocations are not allowed in statics +//~| ERROR static contains unimplemented expression type static mut STATIC12: UnsafeStruct = UnsafeStruct; @@ -92,12 +93,16 @@ static mut STATIC14: SafeStruct = SafeStruct { static STATIC15: &'static [Box] = &[ box MyOwned, //~ ERROR allocations are not allowed in statics + //~| ERROR contains unimplemented expression box MyOwned, //~ ERROR allocations are not allowed in statics + //~| ERROR contains unimplemented expression ]; static STATIC16: (&'static Box, &'static Box) = ( &box MyOwned, //~ ERROR allocations are not allowed in statics + //~| ERROR contains unimplemented expression &box MyOwned, //~ ERROR allocations are not allowed in statics + //~| ERROR contains unimplemented expression ); static mut STATIC17: SafeEnum = SafeEnum::Variant1; @@ -105,9 +110,11 @@ static mut STATIC17: SafeEnum = SafeEnum::Variant1; static STATIC19: Box = box 3; //~^ ERROR allocations are not allowed in statics + //~| ERROR contains unimplemented expression pub fn main() { let y = { static x: Box = box 3; x }; //~^ ERROR allocations are not allowed in statics - //~^^ ERROR cannot move out of static item + //~| ERROR cannot move out of static item + //~| ERROR contains unimplemented expression } diff --git a/src/test/ui/check-static-values-constraints.stderr b/src/test/ui/check-static-values-constraints.stderr index 450a9ba0c0d11..5b1f265c34aef 100644 --- a/src/test/ui/check-static-values-constraints.stderr +++ b/src/test/ui/check-static-values-constraints.stderr @@ -13,55 +13,97 @@ error[E0010]: allocations are not allowed in statics LL | static STATIC11: Box = box MyOwned; | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:79:37 + | +LL | static STATIC11: Box = box MyOwned; + | ^^^^^^^ + error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/check-static-values-constraints.rs:89:32 + --> $DIR/check-static-values-constraints.rs:90:32 | LL | field2: SafeEnum::Variant4("str".to_string()) | ^^^^^^^^^^^^^^^^^ error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:94:5 + --> $DIR/check-static-values-constraints.rs:95:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:95:9 + | +LL | box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:95:5 + --> $DIR/check-static-values-constraints.rs:97:5 | LL | box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:97:9 + | +LL | box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:99:6 + --> $DIR/check-static-values-constraints.rs:102:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:102:10 + | +LL | &box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:100:6 + --> $DIR/check-static-values-constraints.rs:104:6 | LL | &box MyOwned, //~ ERROR allocations are not allowed in statics | ^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:104:10 + | +LL | &box MyOwned, //~ ERROR allocations are not allowed in statics + | ^^^^^^^ + error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:106:5 + --> $DIR/check-static-values-constraints.rs:111:5 | LL | box 3; | ^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:111:9 + | +LL | box 3; + | ^ + error[E0507]: cannot move out of static item - --> $DIR/check-static-values-constraints.rs:110:45 + --> $DIR/check-static-values-constraints.rs:116:45 | LL | let y = { static x: Box = box 3; x }; | ^ cannot move out of static item error[E0010]: allocations are not allowed in statics - --> $DIR/check-static-values-constraints.rs:110:38 + --> $DIR/check-static-values-constraints.rs:116:38 | LL | let y = { static x: Box = box 3; x }; | ^^^^^ allocation not allowed in statics -error: aborting due to 10 previous errors +error[E0019]: static contains unimplemented expression type + --> $DIR/check-static-values-constraints.rs:116:42 + | +LL | let y = { static x: Box = box 3; x }; + | ^ + +error: aborting due to 17 previous errors -Some errors occurred: E0010, E0015, E0493, E0507. +Some errors occurred: E0010, E0015, E0019, E0493, E0507. For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/consts/const-block-non-item-statement-2.rs b/src/test/ui/consts/const-block-non-item-statement-2.rs deleted file mode 100644 index 58a6cf6dcfdeb..0000000000000 --- a/src/test/ui/consts/const-block-non-item-statement-2.rs +++ /dev/null @@ -1,18 +0,0 @@ -const A: usize = { 1; 2 }; -//~^ ERROR statements in constants are unstable - -const B: usize = { { } 2 }; -//~^ ERROR statements in constants are unstable - -macro_rules! foo { - () => (()) //~ ERROR statements in constants are unstable -} -const C: usize = { foo!(); 2 }; - -const D: usize = { let x = 4; 2 }; -//~^ ERROR let bindings in constants are unstable -//~| ERROR statements in constants are unstable -//~| ERROR let bindings in constants are unstable -//~| ERROR statements in constants are unstable - -pub fn main() {} diff --git a/src/test/ui/consts/const-block-non-item-statement-2.stderr b/src/test/ui/consts/const-block-non-item-statement-2.stderr deleted file mode 100644 index e0c61a953f50b..0000000000000 --- a/src/test/ui/consts/const-block-non-item-statement-2.stderr +++ /dev/null @@ -1,62 +0,0 @@ -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:1:20 - | -LL | const A: usize = { 1; 2 }; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:4:20 - | -LL | const B: usize = { { } 2 }; - | ^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:8:12 - | -LL | () => (()) //~ ERROR statements in constants are unstable - | ^^ -LL | } -LL | const C: usize = { foo!(); 2 }; - | ------- in this macro invocation - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:12:28 - | -LL | const D: usize = { let x = 4; 2 }; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:12:28 - | -LL | const D: usize = { let x = 4; 2 }; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:12:1 - | -LL | const D: usize = { let x = 4; 2 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-2.rs:12:1 - | -LL | const D: usize = { let x = 4; 2 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 7 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-block-non-item-statement-3.rs b/src/test/ui/consts/const-block-non-item-statement-3.rs deleted file mode 100644 index 867840925b2d5..0000000000000 --- a/src/test/ui/consts/const-block-non-item-statement-3.rs +++ /dev/null @@ -1,7 +0,0 @@ -type Array = [u32; { let x = 2; 5 }]; -//~^ ERROR let bindings in constants are unstable -//~| ERROR statements in constants are unstable -//~| ERROR let bindings in constants are unstable -//~| ERROR statements in constants are unstable - -pub fn main() {} diff --git a/src/test/ui/consts/const-block-non-item-statement-3.stderr b/src/test/ui/consts/const-block-non-item-statement-3.stderr deleted file mode 100644 index 0a549bc0c8ded..0000000000000 --- a/src/test/ui/consts/const-block-non-item-statement-3.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-3.rs:1:31 - | -LL | type Array = [u32; { let x = 2; 5 }]; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-3.rs:1:31 - | -LL | type Array = [u32; { let x = 2; 5 }]; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-3.rs:1:20 - | -LL | type Array = [u32; { let x = 2; 5 }]; - | ^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement-3.rs:1:20 - | -LL | type Array = [u32; { let x = 2; 5 }]; - | ^^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-block-non-item-statement.rs b/src/test/ui/consts/const-block-non-item-statement.rs index 2db9e2413e5b5..5ecf9a049842d 100644 --- a/src/test/ui/consts/const-block-non-item-statement.rs +++ b/src/test/ui/consts/const-block-non-item-statement.rs @@ -1,9 +1,23 @@ +// compile-pass + enum Foo { Bar = { let x = 1; 3 } - //~^ ERROR let bindings in constants are unstable - //~| ERROR statements in constants are unstable - //~| ERROR let bindings in constants are unstable - //~| ERROR statements in constants are unstable } + +const A: usize = { 1; 2 }; + +const B: usize = { { } 2 }; + +macro_rules! foo { + () => (()) +} + +const C: usize = { foo!(); 2 }; + +const D: usize = { let x = 4; 2 }; + +type Array = [u32; { let x = 2; 5 }]; +type Array2 = [u32; { let mut x = 2; x = 3; x}]; + pub fn main() {} diff --git a/src/test/ui/consts/const-block-non-item-statement.stderr b/src/test/ui/consts/const-block-non-item-statement.stderr deleted file mode 100644 index f0d751e07561c..0000000000000 --- a/src/test/ui/consts/const-block-non-item-statement.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement.rs:2:21 - | -LL | Bar = { let x = 1; 3 } - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement.rs:2:21 - | -LL | Bar = { let x = 1; 3 } - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement.rs:2:11 - | -LL | Bar = { let x = 1; 3 } - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/const-block-non-item-statement.rs:2:11 - | -LL | Bar = { let x = 1; 3 } - | ^^^^^^^^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs index ba8d032367ef8..4d3c714481a29 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.rs @@ -2,7 +2,6 @@ // The test should never compile successfully #![feature(const_raw_ptr_deref)] -#![feature(const_let)] use std::cell::UnsafeCell; diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr index 6ca9d688bd062..be1be6c060071 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static-2.stderr @@ -1,5 +1,5 @@ error[E0019]: static contains unimplemented expression type - --> $DIR/assign-to-static-within-other-static-2.rs:17:5 + --> $DIR/assign-to-static-within-other-static-2.rs:16:5 | LL | *FOO.0.get() = 5; //~ ERROR contains unimplemented expression type | ^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs index 9fe17bfc6a06e..b4c416b1c55f0 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.rs @@ -2,7 +2,6 @@ // The test should never compile successfully #![feature(const_raw_ptr_deref)] -#![feature(const_let)] use std::cell::UnsafeCell; diff --git a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr index 2ab9765305f47..31e49dc10ca60 100644 --- a/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr +++ b/src/test/ui/consts/const-eval/assign-to-static-within-other-static.stderr @@ -1,5 +1,5 @@ error: cannot mutate statics in the initializer of another static - --> $DIR/assign-to-static-within-other-static.rs:11:5 + --> $DIR/assign-to-static-within-other-static.rs:10:5 | LL | FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static | ^^^^^^^ diff --git a/src/test/ui/consts/const-eval/const_let.rs b/src/test/ui/consts/const-eval/const_let.rs index 9e6952733bb0b..63321b9120076 100644 --- a/src/test/ui/consts/const-eval/const_let.rs +++ b/src/test/ui/consts/const-eval/const_let.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - fn main() {} struct FakeNeedsDrop; diff --git a/src/test/ui/consts/const-eval/const_let.stderr b/src/test/ui/consts/const-eval/const_let.stderr index e128ca07d8659..00de97e6fb3a0 100644 --- a/src/test/ui/consts/const-eval/const_let.stderr +++ b/src/test/ui/consts/const-eval/const_let.stderr @@ -1,11 +1,11 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/const_let.rs:15:55 + --> $DIR/const_let.rs:13:55 | LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x }; | ^ error[E0019]: constant contains unimplemented expression type - --> $DIR/const_let.rs:19:35 + --> $DIR/const_let.rs:17:35 | LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); }; | ^ diff --git a/src/test/ui/consts/const-eval/infinite_loop.rs b/src/test/ui/consts/const-eval/infinite_loop.rs index 0d5530acc9582..a2a45af7cb086 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.rs +++ b/src/test/ui/consts/const-eval/infinite_loop.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - fn main() { // Tests the Collatz conjecture with an incorrect base case (0 instead of 1). // The value of `n` will loop indefinitely (4 - 2 - 1 - 4). diff --git a/src/test/ui/consts/const-eval/infinite_loop.stderr b/src/test/ui/consts/const-eval/infinite_loop.stderr index 90d2159d7b551..422c2bab6ea90 100644 --- a/src/test/ui/consts/const-eval/infinite_loop.stderr +++ b/src/test/ui/consts/const-eval/infinite_loop.stderr @@ -1,5 +1,5 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/infinite_loop.rs:9:9 + --> $DIR/infinite_loop.rs:7:9 | LL | / while n != 0 { //~ ERROR constant contains unimplemented expression type LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; @@ -8,7 +8,7 @@ LL | | } | |_________^ warning: Constant evaluating a complex constant, this might take some time - --> $DIR/infinite_loop.rs:6:18 + --> $DIR/infinite_loop.rs:4:18 | LL | let _ = [(); { | __________________^ @@ -21,7 +21,7 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/infinite_loop.rs:10:20 + --> $DIR/infinite_loop.rs:8:20 | LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 }; | ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate diff --git a/src/test/ui/consts/const-eval/issue-52475.rs b/src/test/ui/consts/const-eval/issue-52475.rs index 2e3d6fb9e84be..aafdd5fe61782 100644 --- a/src/test/ui/consts/const-eval/issue-52475.rs +++ b/src/test/ui/consts/const-eval/issue-52475.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - fn main() { let _ = [(); { //~^ WARNING Constant evaluating a complex constant, this might take some time diff --git a/src/test/ui/consts/const-eval/issue-52475.stderr b/src/test/ui/consts/const-eval/issue-52475.stderr index 329ea8a21f989..4f1b2ab4c8f46 100644 --- a/src/test/ui/consts/const-eval/issue-52475.stderr +++ b/src/test/ui/consts/const-eval/issue-52475.stderr @@ -1,5 +1,5 @@ error[E0019]: constant contains unimplemented expression type - --> $DIR/issue-52475.rs:8:9 + --> $DIR/issue-52475.rs:6:9 | LL | / while n < 5 { //~ ERROR constant contains unimplemented expression type LL | | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed @@ -8,7 +8,7 @@ LL | | } | |_________^ warning: Constant evaluating a complex constant, this might take some time - --> $DIR/issue-52475.rs:4:18 + --> $DIR/issue-52475.rs:2:18 | LL | let _ = [(); { | __________________^ @@ -21,7 +21,7 @@ LL | | }]; | |_____^ error[E0080]: evaluation of constant value failed - --> $DIR/issue-52475.rs:9:17 + --> $DIR/issue-52475.rs:7:17 | LL | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed | ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs index 62090f4180d36..32f0062168b3d 100644 --- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs +++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.rs @@ -2,7 +2,6 @@ // The test should never compile successfully #![feature(const_raw_ptr_deref)] -#![feature(const_let)] use std::cell::UnsafeCell; diff --git a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr index 12d6e3be40a99..9fad6868d2038 100644 --- a/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr +++ b/src/test/ui/consts/const-eval/mod-static-with-const-fn.stderr @@ -1,11 +1,11 @@ error[E0019]: static contains unimplemented expression type - --> $DIR/mod-static-with-const-fn.rs:19:5 + --> $DIR/mod-static-with-const-fn.rs:18:5 | LL | *FOO.0.get() = 5; | ^^^^^^^^^^^^^^^^ error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/mod-static-with-const-fn.rs:22:5 + --> $DIR/mod-static-with-const-fn.rs:21:5 | LL | foo(); | ^^^^^ diff --git a/src/test/ui/consts/const-eval/ub-upvars.rs b/src/test/ui/consts/const-eval/ub-upvars.rs index 16df0c1b0cc0e..9b7bca6b72d61 100644 --- a/src/test/ui/consts/const-eval/ub-upvars.rs +++ b/src/test/ui/consts/const-eval/ub-upvars.rs @@ -1,4 +1,4 @@ -#![feature(const_transmute,const_let)] +#![feature(const_transmute)] #![allow(const_err)] // make sure we cannot allow away the errors tested here use std::mem; diff --git a/src/test/ui/consts/const-fn-destructuring-arg.rs b/src/test/ui/consts/const-fn-destructuring-arg.rs index 7f818079a19d1..dcf89f90e31da 100644 --- a/src/test/ui/consts/const-fn-destructuring-arg.rs +++ b/src/test/ui/consts/const-fn-destructuring-arg.rs @@ -1,17 +1,7 @@ -// test that certain things are disallowed in constant functions +// compile-pass -#![feature(const_fn)] - -// no destructuring -const fn i(( - a, - //~^ ERROR arguments of constant functions can only be immutable by-value bindings - b - //~^ ERROR arguments of constant functions can only be immutable by-value bindings - ): (u32, u32)) -> u32 { +const fn i((a, b): (u32, u32)) -> u32 { a + b - //~^ ERROR let bindings in constant functions are unstable - //~| ERROR let bindings in constant functions are unstable } fn main() {} diff --git a/src/test/ui/consts/const-fn-destructuring-arg.stderr b/src/test/ui/consts/const-fn-destructuring-arg.stderr deleted file mode 100644 index db63e8308045a..0000000000000 --- a/src/test/ui/consts/const-fn-destructuring-arg.stderr +++ /dev/null @@ -1,35 +0,0 @@ -error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821) - --> $DIR/const-fn-destructuring-arg.rs:7:13 - | -LL | a, - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821) - --> $DIR/const-fn-destructuring-arg.rs:9:13 - | -LL | b - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-destructuring-arg.rs:12:5 - | -LL | a + b - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-destructuring-arg.rs:12:9 - | -LL | a + b - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.rs b/src/test/ui/consts/const-fn-not-safe-for-const.rs index fe672e7b3e6da..085ff5c58e60c 100644 --- a/src/test/ui/consts/const-fn-not-safe-for-const.rs +++ b/src/test/ui/consts/const-fn-not-safe-for-const.rs @@ -27,13 +27,9 @@ const fn get_Y_addr() -> &'static u32 { } const fn get() -> u32 { - let x = 22; //~ ERROR let bindings in constant functions are unstable -//~^ ERROR statements in constant functions - let y = 44; //~ ERROR let bindings in constant functions are unstable -//~^ ERROR statements in constant functions + let x = 22; + let y = 44; x + y -//~^ ERROR let bindings in constant functions are unstable -//~| ERROR let bindings in constant functions are unstable } fn main() {} diff --git a/src/test/ui/consts/const-fn-not-safe-for-const.stderr b/src/test/ui/consts/const-fn-not-safe-for-const.stderr index 8cc4c38526238..2003b137c272b 100644 --- a/src/test/ui/consts/const-fn-not-safe-for-const.stderr +++ b/src/test/ui/consts/const-fn-not-safe-for-const.stderr @@ -16,55 +16,7 @@ error[E0013]: constant functions cannot refer to statics, use a constant instead LL | &Y | ^^ -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:30:13 - | -LL | let x = 22; //~ ERROR let bindings in constant functions are unstable - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:30:13 - | -LL | let x = 22; //~ ERROR let bindings in constant functions are unstable - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:32:13 - | -LL | let y = 44; //~ ERROR let bindings in constant functions are unstable - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:32:13 - | -LL | let y = 44; //~ ERROR let bindings in constant functions are unstable - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:34:5 - | -LL | x + y - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constant functions are unstable (see issue #48821) - --> $DIR/const-fn-not-safe-for-const.rs:34:9 - | -LL | x + y - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 9 previous errors +error: aborting due to 3 previous errors -Some errors occurred: E0013, E0015, E0658. +Some errors occurred: E0013, E0015. For more information about an error, try `rustc --explain E0013`. diff --git a/src/test/ui/consts/const-int-unchecked.rs b/src/test/ui/consts/const-int-unchecked.rs index aeac6c37dcbab..8ee029b6cc390 100644 --- a/src/test/ui/consts/const-int-unchecked.rs +++ b/src/test/ui/consts/const-int-unchecked.rs @@ -2,10 +2,119 @@ use std::intrinsics; -const SHR: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) }; +// The documentation of `unchecked_shl` states that it: +// +// Performs an unchecked left shift, resulting in undefined behavior when +// y < 0 or y >= N, where N is the width of T in bits. +// +// So we check this for a few `y`. + +// unsigned types: + +const SHL_U8: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) }; +//~^ ERROR any use of this value will cause an error +const SHL_U16: u16 = unsafe { intrinsics::unchecked_shl(5_u16, 16) }; +//~^ ERROR any use of this value will cause an error +const SHL_U32: u32 = unsafe { intrinsics::unchecked_shl(5_u32, 32) }; +//~^ ERROR any use of this value will cause an error +const SHL_U64: u64 = unsafe { intrinsics::unchecked_shl(5_u64, 64) }; +//~^ ERROR any use of this value will cause an error +const SHL_U128: u128 = unsafe { intrinsics::unchecked_shl(5_u128, 128) }; +//~^ ERROR any use of this value will cause an error + +// signed types: + +const SHL_I8: i8 = unsafe { intrinsics::unchecked_shl(5_i8, 8) }; +//~^ ERROR any use of this value will cause an error +const SHL_I16: i16 = unsafe { intrinsics::unchecked_shl(5_16, 16) }; +//~^ ERROR any use of this value will cause an error +const SHL_I32: i32 = unsafe { intrinsics::unchecked_shl(5_i32, 32) }; +//~^ ERROR any use of this value will cause an error +const SHL_I64: i64 = unsafe { intrinsics::unchecked_shl(5_i64, 64) }; +//~^ ERROR any use of this value will cause an error +const SHL_I128: i128 = unsafe { intrinsics::unchecked_shl(5_i128, 128) }; +//~^ ERROR any use of this value will cause an error + +// and make sure we capture y < 0: + +const SHL_I8_NEG: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -1) }; +//~^ ERROR any use of this value will cause an error +const SHL_I16_NEG: i16 = unsafe { intrinsics::unchecked_shl(5_16, -1) }; +//~^ ERROR any use of this value will cause an error +const SHL_I32_NEG: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -1) }; +//~^ ERROR any use of this value will cause an error +const SHL_I64_NEG: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -1) }; +//~^ ERROR any use of this value will cause an error +const SHL_I128_NEG: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -1) }; +//~^ ERROR any use of this value will cause an error + +// and that there's no special relation to the value -1 by picking some +// negative values at random: + +const SHL_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -6) }; +//~^ ERROR any use of this value will cause an error +const SHL_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shl(5_16, -13) }; +//~^ ERROR any use of this value will cause an error +const SHL_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -25) }; +//~^ ERROR any use of this value will cause an error +const SHL_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -30) }; +//~^ ERROR any use of this value will cause an error +const SHL_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -93) }; +//~^ ERROR any use of this value will cause an error + +// Repeat it all over for `unchecked_shr` + +// unsigned types: + +const SHR_U8: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) }; +//~^ ERROR any use of this value will cause an error +const SHR_U16: u16 = unsafe { intrinsics::unchecked_shr(5_u16, 16) }; +//~^ ERROR any use of this value will cause an error +const SHR_U32: u32 = unsafe { intrinsics::unchecked_shr(5_u32, 32) }; +//~^ ERROR any use of this value will cause an error +const SHR_U64: u64 = unsafe { intrinsics::unchecked_shr(5_u64, 64) }; +//~^ ERROR any use of this value will cause an error +const SHR_U128: u128 = unsafe { intrinsics::unchecked_shr(5_u128, 128) }; +//~^ ERROR any use of this value will cause an error + +// signed types: + +const SHR_I8: i8 = unsafe { intrinsics::unchecked_shr(5_i8, 8) }; +//~^ ERROR any use of this value will cause an error +const SHR_I16: i16 = unsafe { intrinsics::unchecked_shr(5_16, 16) }; +//~^ ERROR any use of this value will cause an error +const SHR_I32: i32 = unsafe { intrinsics::unchecked_shr(5_i32, 32) }; +//~^ ERROR any use of this value will cause an error +const SHR_I64: i64 = unsafe { intrinsics::unchecked_shr(5_i64, 64) }; +//~^ ERROR any use of this value will cause an error +const SHR_I128: i128 = unsafe { intrinsics::unchecked_shr(5_i128, 128) }; +//~^ ERROR any use of this value will cause an error + +// and make sure we capture y < 0: + +const SHR_I8_NEG: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -1) }; +//~^ ERROR any use of this value will cause an error +const SHR_I16_NEG: i16 = unsafe { intrinsics::unchecked_shr(5_16, -1) }; +//~^ ERROR any use of this value will cause an error +const SHR_I32_NEG: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -1) }; +//~^ ERROR any use of this value will cause an error +const SHR_I64_NEG: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -1) }; +//~^ ERROR any use of this value will cause an error +const SHR_I128_NEG: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -1) }; +//~^ ERROR any use of this value will cause an error + +// and that there's no special relation to the value -1 by picking some +// negative values at random: + +const SHR_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -6) }; +//~^ ERROR any use of this value will cause an error +const SHR_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shr(5_16, -13) }; +//~^ ERROR any use of this value will cause an error +const SHR_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -25) }; +//~^ ERROR any use of this value will cause an error +const SHR_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -30) }; //~^ ERROR any use of this value will cause an error -const SHL: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) }; +const SHR_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -93) }; //~^ ERROR any use of this value will cause an error -fn main() { -} +fn main() {} diff --git a/src/test/ui/consts/const-int-unchecked.stderr b/src/test/ui/consts/const-int-unchecked.stderr index dd28cc4d533e9..4382d9174b757 100644 --- a/src/test/ui/consts/const-int-unchecked.stderr +++ b/src/test/ui/consts/const-int-unchecked.stderr @@ -1,20 +1,324 @@ error: any use of this value will cause an error - --> $DIR/const-int-unchecked.rs:5:1 + --> $DIR/const-int-unchecked.rs:14:1 | -LL | const SHR: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^ - | | - | Overflowing shift by 8 in unchecked_shr +LL | const SHL_U8: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^ + | | + | Overflowing shift by 8 in unchecked_shl | = note: #[deny(const_err)] on by default error: any use of this value will cause an error - --> $DIR/const-int-unchecked.rs:7:1 + --> $DIR/const-int-unchecked.rs:16:1 | -LL | const SHL: u8 = unsafe { intrinsics::unchecked_shl(5_u8, 8) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^ - | | - | Overflowing shift by 8 in unchecked_shl +LL | const SHL_U16: u16 = unsafe { intrinsics::unchecked_shl(5_u16, 16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 16 in unchecked_shl -error: aborting due to 2 previous errors +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:18:1 + | +LL | const SHL_U32: u32 = unsafe { intrinsics::unchecked_shl(5_u32, 32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 32 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:20:1 + | +LL | const SHL_U64: u64 = unsafe { intrinsics::unchecked_shl(5_u64, 64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 64 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:22:1 + | +LL | const SHL_U128: u128 = unsafe { intrinsics::unchecked_shl(5_u128, 128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^ + | | + | Overflowing shift by 128 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:27:1 + | +LL | const SHL_I8: i8 = unsafe { intrinsics::unchecked_shl(5_i8, 8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^ + | | + | Overflowing shift by 8 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:29:1 + | +LL | const SHL_I16: i16 = unsafe { intrinsics::unchecked_shl(5_16, 16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^ + | | + | Overflowing shift by 16 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:31:1 + | +LL | const SHL_I32: i32 = unsafe { intrinsics::unchecked_shl(5_i32, 32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 32 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:33:1 + | +LL | const SHL_I64: i64 = unsafe { intrinsics::unchecked_shl(5_i64, 64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 64 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:35:1 + | +LL | const SHL_I128: i128 = unsafe { intrinsics::unchecked_shl(5_i128, 128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^ + | | + | Overflowing shift by 128 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:40:1 + | +LL | const SHL_I8_NEG: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^ + | | + | Overflowing shift by 255 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:42:1 + | +LL | const SHL_I16_NEG: i16 = unsafe { intrinsics::unchecked_shl(5_16, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^ + | | + | Overflowing shift by 65535 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:44:1 + | +LL | const SHL_I32_NEG: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 4294967295 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:46:1 + | +LL | const SHL_I64_NEG: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 18446744073709551615 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:48:1 + | +LL | const SHL_I128_NEG: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^ + | | + | Overflowing shift by 340282366920938463463374607431768211455 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:54:1 + | +LL | const SHL_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -6) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^ + | | + | Overflowing shift by 250 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:56:1 + | +LL | const SHL_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shl(5_16, -13) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 65523 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:58:1 + | +LL | const SHL_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -25) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^ + | | + | Overflowing shift by 4294967271 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:60:1 + | +LL | const SHL_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -30) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^ + | | + | Overflowing shift by 18446744073709551586 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:62:1 + | +LL | const SHL_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -93) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^ + | | + | Overflowing shift by 340282366920938463463374607431768211363 in unchecked_shl + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:69:1 + | +LL | const SHR_U8: u8 = unsafe { intrinsics::unchecked_shr(5_u8, 8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^ + | | + | Overflowing shift by 8 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:71:1 + | +LL | const SHR_U16: u16 = unsafe { intrinsics::unchecked_shr(5_u16, 16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 16 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:73:1 + | +LL | const SHR_U32: u32 = unsafe { intrinsics::unchecked_shr(5_u32, 32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 32 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:75:1 + | +LL | const SHR_U64: u64 = unsafe { intrinsics::unchecked_shr(5_u64, 64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 64 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:77:1 + | +LL | const SHR_U128: u128 = unsafe { intrinsics::unchecked_shr(5_u128, 128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^ + | | + | Overflowing shift by 128 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:82:1 + | +LL | const SHR_I8: i8 = unsafe { intrinsics::unchecked_shr(5_i8, 8) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^^^ + | | + | Overflowing shift by 8 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:84:1 + | +LL | const SHR_I16: i16 = unsafe { intrinsics::unchecked_shr(5_16, 16) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^ + | | + | Overflowing shift by 16 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:86:1 + | +LL | const SHR_I32: i32 = unsafe { intrinsics::unchecked_shr(5_i32, 32) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 32 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:88:1 + | +LL | const SHR_I64: i64 = unsafe { intrinsics::unchecked_shr(5_i64, 64) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 64 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:90:1 + | +LL | const SHR_I128: i128 = unsafe { intrinsics::unchecked_shr(5_i128, 128) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^ + | | + | Overflowing shift by 128 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:95:1 + | +LL | const SHR_I8_NEG: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^ + | | + | Overflowing shift by 255 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:97:1 + | +LL | const SHR_I16_NEG: i16 = unsafe { intrinsics::unchecked_shr(5_16, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^ + | | + | Overflowing shift by 65535 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:99:1 + | +LL | const SHR_I32_NEG: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 4294967295 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:101:1 + | +LL | const SHR_I64_NEG: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 18446744073709551615 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:103:1 + | +LL | const SHR_I128_NEG: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^ + | | + | Overflowing shift by 340282366920938463463374607431768211455 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:109:1 + | +LL | const SHR_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -6) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------------------------^^^ + | | + | Overflowing shift by 250 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:111:1 + | +LL | const SHR_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shr(5_16, -13) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------^^^ + | | + | Overflowing shift by 65523 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:113:1 + | +LL | const SHR_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -25) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^ + | | + | Overflowing shift by 4294967271 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:115:1 + | +LL | const SHR_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -30) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------------------------------^^^ + | | + | Overflowing shift by 18446744073709551586 in unchecked_shr + +error: any use of this value will cause an error + --> $DIR/const-int-unchecked.rs:117:1 + | +LL | const SHR_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -93) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------------------------------^^^ + | | + | Overflowing shift by 340282366920938463463374607431768211363 in unchecked_shr + +error: aborting due to 40 previous errors diff --git a/src/test/ui/consts/const_let_assign.rs b/src/test/ui/consts/const_let_assign.rs index a3c53a451e106..0b09b8469fd75 100644 --- a/src/test/ui/consts/const_let_assign.rs +++ b/src/test/ui/consts/const_let_assign.rs @@ -1,7 +1,5 @@ // compile-pass -#![feature(const_let)] - struct S(i32); const A: () = { diff --git a/src/test/ui/consts/const_let_assign2.rs b/src/test/ui/consts/const_let_assign2.rs index 0de7396501adc..1c44237e49b7a 100644 --- a/src/test/ui/consts/const_let_assign2.rs +++ b/src/test/ui/consts/const_let_assign2.rs @@ -1,8 +1,5 @@ // compile-pass -#![feature(const_let)] -#![feature(const_fn)] - pub struct AA { pub data: [u8; 10], } diff --git a/src/test/ui/consts/const_let_assign3.rs b/src/test/ui/consts/const_let_assign3.rs index c2ed6cd85ab5c..cbe73923e9c42 100644 --- a/src/test/ui/consts/const_let_assign3.rs +++ b/src/test/ui/consts/const_let_assign3.rs @@ -1,4 +1,3 @@ -#![feature(const_let)] #![feature(const_fn)] struct S { @@ -18,6 +17,15 @@ const FOO: S = { s }; +type Array = [u32; { + let mut x = 2; + let y = &mut x; +//~^ ERROR references in constants may only refer to immutable values + *y = 42; +//~^ ERROR constant contains unimplemented expression type + *y +}]; + fn main() { assert_eq!(FOO.state, 3); } diff --git a/src/test/ui/consts/const_let_assign3.stderr b/src/test/ui/consts/const_let_assign3.stderr index 0f294616d255c..6649fb997cce4 100644 --- a/src/test/ui/consts/const_let_assign3.stderr +++ b/src/test/ui/consts/const_let_assign3.stderr @@ -1,16 +1,28 @@ error[E0019]: constant function contains unimplemented expression type - --> $DIR/const_let_assign3.rs:10:9 + --> $DIR/const_let_assign3.rs:9:9 | LL | self.state = x; | ^^^^^^^^^^^^^^ error[E0017]: references in constants may only refer to immutable values - --> $DIR/const_let_assign3.rs:17:5 + --> $DIR/const_let_assign3.rs:16:5 | LL | s.foo(3); //~ ERROR references in constants may only refer to immutable values | ^ constants require immutable values -error: aborting due to 2 previous errors +error[E0017]: references in constants may only refer to immutable values + --> $DIR/const_let_assign3.rs:22:13 + | +LL | let y = &mut x; + | ^^^^^^ constants require immutable values + +error[E0019]: constant contains unimplemented expression type + --> $DIR/const_let_assign3.rs:24:5 + | +LL | *y = 42; + | ^^^^^^^ + +error: aborting due to 4 previous errors Some errors occurred: E0017, E0019. For more information about an error, try `rustc --explain E0017`. diff --git a/src/test/ui/consts/const_let_eq.rs b/src/test/ui/consts/const_let_eq.rs index 8739cb80e9403..a2364c392f26b 100644 --- a/src/test/ui/consts/const_let_eq.rs +++ b/src/test/ui/consts/const_let_eq.rs @@ -1,5 +1,3 @@ -#![feature(const_let, const_fn)] - // run-pass struct Foo(T); diff --git a/src/test/ui/consts/const_let_eq_float.rs b/src/test/ui/consts/const_let_eq_float.rs index 2c7262df367a3..c48f54e567b2c 100644 --- a/src/test/ui/consts/const_let_eq_float.rs +++ b/src/test/ui/consts/const_let_eq_float.rs @@ -1,6 +1,6 @@ // compile-pass -#![feature(const_let, const_fn)] +#![feature(const_fn)] struct Foo(T); struct Bar { x: T } diff --git a/src/test/ui/consts/const_let_irrefutable.rs b/src/test/ui/consts/const_let_irrefutable.rs new file mode 100644 index 0000000000000..424a16f7ed39b --- /dev/null +++ b/src/test/ui/consts/const_let_irrefutable.rs @@ -0,0 +1,11 @@ +// compile-pass + +fn main() {} + +const fn tup((a, b): (i32, i32)) -> i32 { + a + b +} + +const fn array([a, b]: [i32; 2]) -> i32 { + a + b +} diff --git a/src/test/ui/consts/const_let_refutable.rs b/src/test/ui/consts/const_let_refutable.rs new file mode 100644 index 0000000000000..345f682868fbc --- /dev/null +++ b/src/test/ui/consts/const_let_refutable.rs @@ -0,0 +1,5 @@ +fn main() {} + +const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument + a + b +} diff --git a/src/test/ui/consts/const_let_refutable.stderr b/src/test/ui/consts/const_let_refutable.stderr new file mode 100644 index 0000000000000..c5d2ba02a70c6 --- /dev/null +++ b/src/test/ui/consts/const_let_refutable.stderr @@ -0,0 +1,9 @@ +error[E0005]: refutable pattern in function argument: `&[]` not covered + --> $DIR/const_let_refutable.rs:3:16 + | +LL | const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument + | ^^^^^^ pattern `&[]` not covered + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/consts/const_short_circuit.rs b/src/test/ui/consts/const_short_circuit.rs index cc49e4696e58f..1e7b7ed319355 100644 --- a/src/test/ui/consts/const_short_circuit.rs +++ b/src/test/ui/consts/const_short_circuit.rs @@ -1,4 +1,4 @@ -#![feature(underscore_const_names, const_let)] +#![feature(underscore_const_names)] const _: bool = false && false; const _: bool = true && false; diff --git a/src/test/ui/consts/dangling-alloc-id-ice.rs b/src/test/ui/consts/dangling-alloc-id-ice.rs index 695d33b690898..dbc50f1fbd4b4 100644 --- a/src/test/ui/consts/dangling-alloc-id-ice.rs +++ b/src/test/ui/consts/dangling-alloc-id-ice.rs @@ -1,7 +1,5 @@ // https://github.com/rust-lang/rust/issues/55223 -#![feature(const_let)] - union Foo<'a> { y: &'a (), long_live_the_unit: &'static (), diff --git a/src/test/ui/consts/dangling-alloc-id-ice.stderr b/src/test/ui/consts/dangling-alloc-id-ice.stderr index a5fa88e5e6832..2cd8711f03d31 100644 --- a/src/test/ui/consts/dangling-alloc-id-ice.stderr +++ b/src/test/ui/consts/dangling-alloc-id-ice.stderr @@ -1,5 +1,5 @@ error: any use of this value will cause an error - --> $DIR/dangling-alloc-id-ice.rs:10:1 + --> $DIR/dangling-alloc-id-ice.rs:8:1 | LL | / const FOO: &() = { //~ ERROR any use of this value will cause an error LL | | let y = (); diff --git a/src/test/ui/consts/dangling_raw_ptr.rs b/src/test/ui/consts/dangling_raw_ptr.rs index 7fc773412f2f8..c2d8e6d421a28 100644 --- a/src/test/ui/consts/dangling_raw_ptr.rs +++ b/src/test/ui/consts/dangling_raw_ptr.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - const FOO: *const u32 = { //~ ERROR any use of this value will cause an error let x = 42; &x diff --git a/src/test/ui/consts/dangling_raw_ptr.stderr b/src/test/ui/consts/dangling_raw_ptr.stderr index 3b20936f8ae97..091f1f785cb02 100644 --- a/src/test/ui/consts/dangling_raw_ptr.stderr +++ b/src/test/ui/consts/dangling_raw_ptr.stderr @@ -1,5 +1,5 @@ error: any use of this value will cause an error - --> $DIR/dangling_raw_ptr.rs:3:1 + --> $DIR/dangling_raw_ptr.rs:1:1 | LL | / const FOO: *const u32 = { //~ ERROR any use of this value will cause an error LL | | let x = 42; diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr index 551bc57e5ae7d..91b076097b018 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr @@ -112,12 +112,6 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn | ^^^^^^^^^^^ -error: local variables in const fn are unstable - --> $DIR/min_const_fn.rs:99:34 - | -LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn - | ^ - error: `if`, `match`, `&&` and `||` are not stable in const fn --> $DIR/min_const_fn.rs:100:44 | @@ -220,7 +214,7 @@ error: function pointers in const fn are unstable LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ -error: aborting due to 35 previous errors +error: aborting due to 34 previous errors Some errors occurred: E0493, E0515. For more information about an error, try `rustc --explain E0493`. diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.rs b/src/test/ui/consts/min_const_fn/min_const_fn.rs index 238b5f7e31003..05cf3d5f1f173 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn.rs @@ -96,7 +96,7 @@ const fn foo30_2(x: *mut u32) -> usize { x as usize } const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } } //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn -const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn +const fn foo30_6() -> bool { let x = true; x } const fn foo36(a: bool, b: bool) -> bool { a && b } //~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn const fn foo37(a: bool, b: bool) -> bool { a || b } diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index 1c68df513b697..2cae714fbf727 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -112,12 +112,6 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn | ^^^^^^^^^^^ -error: local variables in const fn are unstable - --> $DIR/min_const_fn.rs:99:34 - | -LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn - | ^ - error: `if`, `match`, `&&` and `||` are not stable in const fn --> $DIR/min_const_fn.rs:100:44 | @@ -208,6 +202,6 @@ error: function pointers in const fn are unstable LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo } | ^^^^ -error: aborting due to 35 previous errors +error: aborting due to 34 previous errors For more information about this error, try `rustc --explain E0493`. diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.rs b/src/test/ui/consts/min_const_fn/mutable_borrow.rs index 3dd76b630a883..89acfea6ed8ff 100644 --- a/src/test/ui/consts/min_const_fn/mutable_borrow.rs +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.rs @@ -1,6 +1,6 @@ const fn mutable_ref_in_const() -> u8 { - let mut a = 0; //~ ERROR local variables in const fn - let b = &mut a; + let mut a = 0; + let b = &mut a; //~ ERROR mutable references in const fn *b } @@ -8,8 +8,8 @@ struct X; impl X { const fn inherent_mutable_ref_in_const() -> u8 { - let mut a = 0; //~ ERROR local variables in const fn - let b = &mut a; + let mut a = 0; + let b = &mut a; //~ ERROR mutable references in const fn *b } } diff --git a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr index fa46f5c804fe0..5ce0f30dc6e1f 100644 --- a/src/test/ui/consts/min_const_fn/mutable_borrow.stderr +++ b/src/test/ui/consts/min_const_fn/mutable_borrow.stderr @@ -1,14 +1,14 @@ -error: local variables in const fn are unstable - --> $DIR/mutable_borrow.rs:2:9 +error: mutable references in const fn are unstable + --> $DIR/mutable_borrow.rs:3:9 | -LL | let mut a = 0; //~ ERROR local variables in const fn - | ^^^^^ +LL | let b = &mut a; //~ ERROR mutable references in const fn + | ^ -error: local variables in const fn are unstable - --> $DIR/mutable_borrow.rs:11:13 +error: mutable references in const fn are unstable + --> $DIR/mutable_borrow.rs:12:13 | -LL | let mut a = 0; //~ ERROR local variables in const fn - | ^^^^^ +LL | let b = &mut a; //~ ERROR mutable references in const fn + | ^ error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/partial_qualif.rs b/src/test/ui/consts/partial_qualif.rs index 4ce41f80f82c8..32c68e69f4bed 100644 --- a/src/test/ui/consts/partial_qualif.rs +++ b/src/test/ui/consts/partial_qualif.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - use std::cell::Cell; const FOO: &(Cell, bool) = { diff --git a/src/test/ui/consts/partial_qualif.stderr b/src/test/ui/consts/partial_qualif.stderr index d695f64e2c3b5..967fb83b78b08 100644 --- a/src/test/ui/consts/partial_qualif.stderr +++ b/src/test/ui/consts/partial_qualif.stderr @@ -1,5 +1,5 @@ error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead - --> $DIR/partial_qualif.rs:8:5 + --> $DIR/partial_qualif.rs:6:5 | LL | &{a} //~ ERROR cannot borrow a constant which may contain interior mutability | ^^^^ diff --git a/src/test/ui/consts/projection_qualif.rs b/src/test/ui/consts/projection_qualif.rs index 5863429a2f2c5..dedb7db592089 100644 --- a/src/test/ui/consts/projection_qualif.rs +++ b/src/test/ui/consts/projection_qualif.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - use std::cell::Cell; const FOO: &u32 = { diff --git a/src/test/ui/consts/projection_qualif.stderr b/src/test/ui/consts/projection_qualif.stderr index cc3635a979b37..410c51c4b54e1 100644 --- a/src/test/ui/consts/projection_qualif.stderr +++ b/src/test/ui/consts/projection_qualif.stderr @@ -1,17 +1,17 @@ error[E0017]: references in constants may only refer to immutable values - --> $DIR/projection_qualif.rs:8:27 + --> $DIR/projection_qualif.rs:6:27 | LL | let b: *mut u32 = &mut a; //~ ERROR may only refer to immutable values | ^^^^^^ constants require immutable values error[E0019]: constant contains unimplemented expression type - --> $DIR/projection_qualif.rs:9:18 + --> $DIR/projection_qualif.rs:7:18 | LL | unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants | ^^^^^^ error[E0658]: dereferencing raw pointers in constants is unstable (see issue #51911) - --> $DIR/projection_qualif.rs:9:18 + --> $DIR/projection_qualif.rs:7:18 | LL | unsafe { *b = 5; } //~ ERROR dereferencing raw pointers in constants | ^^^^^^ diff --git a/src/test/ui/consts/promote_const_let.nll.stderr b/src/test/ui/consts/promote_const_let.nll.stderr index d8749bb5fd90b..e6ee1523a3b28 100644 --- a/src/test/ui/consts/promote_const_let.nll.stderr +++ b/src/test/ui/consts/promote_const_let.nll.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/promote_const_let.rs:6:9 + --> $DIR/promote_const_let.rs:4:9 | LL | let x: &'static u32 = { | ------------ type annotation requires that `y` is borrowed for `'static` @@ -9,6 +9,21 @@ LL | &y //~ ERROR does not live long enough LL | }; | - `y` dropped here while still borrowed -error: aborting due to previous error +error[E0716]: temporary value dropped while borrowed + --> $DIR/promote_const_let.rs:6:28 + | +LL | let x: &'static u32 = &{ //~ ERROR does not live long enough + | ____________------------____^ + | | | + | | type annotation requires that borrow lasts for `'static` +LL | | let y = 42; +LL | | y +LL | | }; + | |_____^ creates a temporary which is freed while still in use +LL | } + | - temporary value is freed at the end of this statement + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0597`. +Some errors occurred: E0597, E0716. +For more information about an error, try `rustc --explain E0597`. diff --git a/src/test/ui/consts/promote_const_let.rs b/src/test/ui/consts/promote_const_let.rs index 8de9b00eb111d..a8a6d4d99c6ff 100644 --- a/src/test/ui/consts/promote_const_let.rs +++ b/src/test/ui/consts/promote_const_let.rs @@ -1,8 +1,10 @@ -#![feature(const_let)] - fn main() { let x: &'static u32 = { let y = 42; &y //~ ERROR does not live long enough }; + let x: &'static u32 = &{ //~ ERROR does not live long enough + let y = 42; + y + }; } diff --git a/src/test/ui/consts/promote_const_let.stderr b/src/test/ui/consts/promote_const_let.stderr index 6bbb7495fb0dc..d37bd49186032 100644 --- a/src/test/ui/consts/promote_const_let.stderr +++ b/src/test/ui/consts/promote_const_let.stderr @@ -1,5 +1,5 @@ error[E0597]: `y` does not live long enough - --> $DIR/promote_const_let.rs:6:10 + --> $DIR/promote_const_let.rs:4:10 | LL | &y //~ ERROR does not live long enough | ^ borrowed value does not live long enough @@ -8,6 +8,20 @@ LL | }; | = note: borrowed value must be valid for the static lifetime... -error: aborting due to previous error +error[E0597]: borrowed value does not live long enough + --> $DIR/promote_const_let.rs:6:28 + | +LL | let x: &'static u32 = &{ //~ ERROR does not live long enough + | ____________________________^ +LL | | let y = 42; +LL | | y +LL | | }; + | |_____^ temporary value does not live long enough +LL | } + | - temporary value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/consts/qualif_overwrite.rs b/src/test/ui/consts/qualif_overwrite.rs index 806a74ee4530b..430eea37de73c 100644 --- a/src/test/ui/consts/qualif_overwrite.rs +++ b/src/test/ui/consts/qualif_overwrite.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - use std::cell::Cell; // this is overly conservative. The reset to `None` should clear `a` of all qualifications diff --git a/src/test/ui/consts/qualif_overwrite.stderr b/src/test/ui/consts/qualif_overwrite.stderr index 4fac64bf8063f..30479139e314c 100644 --- a/src/test/ui/consts/qualif_overwrite.stderr +++ b/src/test/ui/consts/qualif_overwrite.stderr @@ -1,5 +1,5 @@ error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead - --> $DIR/qualif_overwrite.rs:12:5 + --> $DIR/qualif_overwrite.rs:10:5 | LL | &{a} //~ ERROR cannot borrow a constant which may contain interior mutability | ^^^^ diff --git a/src/test/ui/consts/qualif_overwrite_2.rs b/src/test/ui/consts/qualif_overwrite_2.rs index 29557a3da4781..fa79b5c14a736 100644 --- a/src/test/ui/consts/qualif_overwrite_2.rs +++ b/src/test/ui/consts/qualif_overwrite_2.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - use std::cell::Cell; // const qualification is not smart enough to know about fields and always assumes that there might diff --git a/src/test/ui/consts/qualif_overwrite_2.stderr b/src/test/ui/consts/qualif_overwrite_2.stderr index 181b728c7b76f..8276db99a12c0 100644 --- a/src/test/ui/consts/qualif_overwrite_2.stderr +++ b/src/test/ui/consts/qualif_overwrite_2.stderr @@ -1,5 +1,5 @@ error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead - --> $DIR/qualif_overwrite_2.rs:10:5 + --> $DIR/qualif_overwrite_2.rs:8:5 | LL | &{a.0} //~ ERROR cannot borrow a constant which may contain interior mutability | ^^^^^^ diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.rs b/src/test/ui/consts/static_mut_containing_mut_ref2.rs index 4180b1e295ab0..ef378fa84518e 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.rs +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - static mut STDERR_BUFFER_SPACE: u8 = 0; pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; diff --git a/src/test/ui/consts/static_mut_containing_mut_ref2.stderr b/src/test/ui/consts/static_mut_containing_mut_ref2.stderr index f0ae1545056b7..72186571d697e 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref2.stderr +++ b/src/test/ui/consts/static_mut_containing_mut_ref2.stderr @@ -1,11 +1,11 @@ error[E0017]: references in statics may only refer to immutable values - --> $DIR/static_mut_containing_mut_ref2.rs:5:46 + --> $DIR/static_mut_containing_mut_ref2.rs:3:46 | LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ statics require immutable values error[E0019]: static contains unimplemented expression type - --> $DIR/static_mut_containing_mut_ref2.rs:5:45 + --> $DIR/static_mut_containing_mut_ref2.rs:3:45 | LL | pub static mut STDERR_BUFFER: () = unsafe { *(&mut STDERR_BUFFER_SPACE) = 42; }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/consts/static_mut_containing_mut_ref3.rs b/src/test/ui/consts/static_mut_containing_mut_ref3.rs index 0bc7faa9afdec..c24c7e2792079 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref3.rs +++ b/src/test/ui/consts/static_mut_containing_mut_ref3.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - static mut FOO: (u8, u8) = (42, 43); static mut BAR: () = unsafe { FOO.0 = 99; }; diff --git a/src/test/ui/consts/static_mut_containing_mut_ref3.stderr b/src/test/ui/consts/static_mut_containing_mut_ref3.stderr index cae53c6fee9dd..e88e49b097af2 100644 --- a/src/test/ui/consts/static_mut_containing_mut_ref3.stderr +++ b/src/test/ui/consts/static_mut_containing_mut_ref3.stderr @@ -1,5 +1,5 @@ error[E0080]: could not evaluate static initializer - --> $DIR/static_mut_containing_mut_ref3.rs:5:31 + --> $DIR/static_mut_containing_mut_ref3.rs:3:31 | LL | static mut BAR: () = unsafe { FOO.0 = 99; }; | ^^^^^^^^^^ tried to modify a static's initial value from another static's initializer diff --git a/src/test/ui/editions/edition-imports-2015.rs b/src/test/ui/editions/edition-imports-2015.rs index b89ca28e279db..5ba45b19dded0 100644 --- a/src/test/ui/editions/edition-imports-2015.rs +++ b/src/test/ui/editions/edition-imports-2015.rs @@ -3,8 +3,6 @@ // aux-build:edition-imports-2018.rs // aux-build:absolute.rs -#![feature(uniform_paths)] - #[macro_use] extern crate edition_imports_2018; diff --git a/src/test/ui/editions/edition-imports-2015.stderr b/src/test/ui/editions/edition-imports-2015.stderr index fb6b2e64ef5b8..816ab21d81426 100644 --- a/src/test/ui/editions/edition-imports-2015.stderr +++ b/src/test/ui/editions/edition-imports-2015.stderr @@ -1,5 +1,5 @@ error: cannot glob-import all possible crates - --> $DIR/edition-imports-2015.rs:25:5 + --> $DIR/edition-imports-2015.rs:23:5 | LL | gen_glob!(); //~ ERROR cannot glob-import all possible crates | ^^^^^^^^^^^^ diff --git a/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr index 7c1837e3f56e3..7c78fbb26a1b8 100644 --- a/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr +++ b/src/test/ui/editions/edition-imports-virtual-2015-gated.stderr @@ -1,4 +1,4 @@ -error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130) +error: imports can only refer to extern crate names passed with `--extern` in macros originating from 2015 edition --> <::edition_imports_2015::gen_gated macros>:1:50 | LL | ( ) => { fn check_gated ( ) { enum E { A } use E :: * ; } } @@ -9,7 +9,6 @@ LL | ( ) => { fn check_gated ( ) { enum E { A } use E :: * ; } } LL | gen_gated!(); | ------------- not an extern crate passed with `--extern` | - = help: add #![feature(uniform_paths)] to the crate attributes to enable note: this import refers to the enum defined here --> $DIR/edition-imports-virtual-2015-gated.rs:9:5 | @@ -19,4 +18,3 @@ LL | gen_gated!(); error: aborting due to previous error -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/error-codes/E0010-teach.rs b/src/test/ui/error-codes/E0010-teach.rs index fc5dffb37cfe7..da51035ab5550 100644 --- a/src/test/ui/error-codes/E0010-teach.rs +++ b/src/test/ui/error-codes/E0010-teach.rs @@ -4,5 +4,6 @@ #![allow(warnings)] const CON : Box = box 0; //~ ERROR E0010 +//~^ ERROR constant contains unimplemented expression type fn main() {} diff --git a/src/test/ui/error-codes/E0010-teach.stderr b/src/test/ui/error-codes/E0010-teach.stderr index da0aadfded5f8..77e7b5ec0e860 100644 --- a/src/test/ui/error-codes/E0010-teach.stderr +++ b/src/test/ui/error-codes/E0010-teach.stderr @@ -6,6 +6,16 @@ LL | const CON : Box = box 0; //~ ERROR E0010 | = note: The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time. -error: aborting due to previous error +error[E0019]: constant contains unimplemented expression type + --> $DIR/E0010-teach.rs:6:28 + | +LL | const CON : Box = box 0; //~ ERROR E0010 + | ^ + | + = note: A function call isn't allowed in the const's initialization expression because the expression's value must be known at compile-time. + = note: Remember: you can't use a function call inside a const's initialization expression! However, you can use it anywhere else. + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0010`. +Some errors occurred: E0010, E0019. +For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/error-codes/E0010.rs b/src/test/ui/error-codes/E0010.rs index e62997640f473..3398e2c28ba6b 100644 --- a/src/test/ui/error-codes/E0010.rs +++ b/src/test/ui/error-codes/E0010.rs @@ -2,5 +2,6 @@ #![allow(warnings)] const CON : Box = box 0; //~ ERROR E0010 +//~^ ERROR constant contains unimplemented expression type fn main() {} diff --git a/src/test/ui/error-codes/E0010.stderr b/src/test/ui/error-codes/E0010.stderr index b4b490922c45f..1364693109e08 100644 --- a/src/test/ui/error-codes/E0010.stderr +++ b/src/test/ui/error-codes/E0010.stderr @@ -4,6 +4,13 @@ error[E0010]: allocations are not allowed in constants LL | const CON : Box = box 0; //~ ERROR E0010 | ^^^^^ allocation not allowed in constants -error: aborting due to previous error +error[E0019]: constant contains unimplemented expression type + --> $DIR/E0010.rs:4:28 + | +LL | const CON : Box = box 0; //~ ERROR E0010 + | ^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0010`. +Some errors occurred: E0010, E0019. +For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/error-codes/E0162.rs b/src/test/ui/error-codes/E0162.rs deleted file mode 100644 index d3221f8e1769a..0000000000000 --- a/src/test/ui/error-codes/E0162.rs +++ /dev/null @@ -1,8 +0,0 @@ -struct Irrefutable(i32); - -fn main() { - let irr = Irrefutable(0); - if let Irrefutable(x) = irr { //~ ERROR E0162 - println!("{}", x); - } -} diff --git a/src/test/ui/error-codes/E0162.stderr b/src/test/ui/error-codes/E0162.stderr deleted file mode 100644 index ca5c56cd59d31..0000000000000 --- a/src/test/ui/error-codes/E0162.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0162]: irrefutable if-let pattern - --> $DIR/E0162.rs:5:12 - | -LL | if let Irrefutable(x) = irr { //~ ERROR E0162 - | ^^^^^^^^^^^^^^ irrefutable pattern - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0162`. diff --git a/src/test/ui/error-codes/E0165.rs b/src/test/ui/error-codes/E0165.rs deleted file mode 100644 index 952071c8b9e77..0000000000000 --- a/src/test/ui/error-codes/E0165.rs +++ /dev/null @@ -1,9 +0,0 @@ -struct Irrefutable(i32); - -fn main() { - let irr = Irrefutable(0); - while let Irrefutable(x) = irr { //~ ERROR E0165 - //~| irrefutable pattern - // ... - } -} diff --git a/src/test/ui/error-codes/E0165.stderr b/src/test/ui/error-codes/E0165.stderr deleted file mode 100644 index e0d192ea15290..0000000000000 --- a/src/test/ui/error-codes/E0165.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0165]: irrefutable while-let pattern - --> $DIR/E0165.rs:5:15 - | -LL | while let Irrefutable(x) = irr { //~ ERROR E0165 - | ^^^^^^^^^^^^^^ irrefutable pattern - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0165`. diff --git a/src/test/ui/error-codes/E0606.stderr b/src/test/ui/error-codes/E0606.stderr index bc872b3b79cce..89ec4896a2b43 100644 --- a/src/test/ui/error-codes/E0606.stderr +++ b/src/test/ui/error-codes/E0606.stderr @@ -2,13 +2,10 @@ error[E0606]: casting `&u8` as `u8` is invalid --> $DIR/E0606.rs:2:5 | LL | &0u8 as u8; //~ ERROR E0606 - | ^^^^^^^^^^ cannot cast `&u8` as `u8` - | -help: did you mean `*&0u8`? - --> $DIR/E0606.rs:2:5 - | -LL | &0u8 as u8; //~ ERROR E0606 - | ^^^^ + | ----^^^^^^ + | | + | cannot cast `&u8` as `u8` + | help: dereference the expression: `*&0u8` error: aborting due to previous error diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr index 2a48272216919..ef7b49399bf3a 100644 --- a/src/test/ui/error-festival.stderr +++ b/src/test/ui/error-festival.stderr @@ -60,13 +60,10 @@ error[E0606]: casting `&u8` as `u32` is invalid --> $DIR/error-festival.rs:37:18 | LL | let y: u32 = x as u32; - | ^^^^^^^^ cannot cast `&u8` as `u32` - | -help: did you mean `*x`? - --> $DIR/error-festival.rs:37:18 - | -LL | let y: u32 = x as u32; - | ^ + | -^^^^^^^ + | | + | cannot cast `&u8` as `u32` + | help: dereference the expression: `*x` error[E0607]: cannot cast thin pointer `*const u8` to fat pointer `*const [u8]` --> $DIR/error-festival.rs:41:5 diff --git a/src/test/ui/feature-gates/feature-gate-const_let.rs b/src/test/ui/feature-gates/feature-gate-const_let.rs deleted file mode 100644 index 74cefd7c0670d..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-const_let.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Test use of const let without feature gate. - -const FOO: usize = { - //~^ ERROR statements in constants are unstable - //~| ERROR: let bindings in constants are unstable - let x = 42; - //~^ ERROR statements in constants are unstable - //~| ERROR: let bindings in constants are unstable - 42 -}; - -static BAR: usize = { - //~^ ERROR statements in statics are unstable - //~| ERROR: let bindings in statics are unstable - let x = 42; - //~^ ERROR statements in statics are unstable - //~| ERROR: let bindings in statics are unstable - 42 -}; - -fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-const_let.stderr b/src/test/ui/feature-gates/feature-gate-const_let.stderr deleted file mode 100644 index 56312999a5fd8..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-const_let.stderr +++ /dev/null @@ -1,91 +0,0 @@ -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/feature-gate-const_let.rs:6:13 - | -LL | let x = 42; - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/feature-gate-const_let.rs:6:13 - | -LL | let x = 42; - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/feature-gate-const_let.rs:3:1 - | -LL | / const FOO: usize = { -LL | | //~^ ERROR statements in constants are unstable -LL | | //~| ERROR: let bindings in constants are unstable -LL | | let x = 42; -... | -LL | | 42 -LL | | }; - | |__^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/feature-gate-const_let.rs:3:1 - | -LL | / const FOO: usize = { -LL | | //~^ ERROR statements in constants are unstable -LL | | //~| ERROR: let bindings in constants are unstable -LL | | let x = 42; -... | -LL | | 42 -LL | | }; - | |__^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in statics are unstable (see issue #48821) - --> $DIR/feature-gate-const_let.rs:15:13 - | -LL | let x = 42; - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/feature-gate-const_let.rs:15:13 - | -LL | let x = 42; - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in statics are unstable (see issue #48821) - --> $DIR/feature-gate-const_let.rs:12:1 - | -LL | / static BAR: usize = { -LL | | //~^ ERROR statements in statics are unstable -LL | | //~| ERROR: let bindings in statics are unstable -LL | | let x = 42; -... | -LL | | 42 -LL | | }; - | |__^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/feature-gate-const_let.rs:12:1 - | -LL | / static BAR: usize = { -LL | | //~^ ERROR statements in statics are unstable -LL | | //~| ERROR: let bindings in statics are unstable -LL | | let x = 42; -... | -LL | | 42 -LL | | }; - | |__^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 8 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.rs b/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.rs deleted file mode 100644 index 233185f92e3f5..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.rs +++ /dev/null @@ -1,8 +0,0 @@ -fn main() { - if let 0 | 1 = 0 { //~ ERROR multiple patterns in `if let` and `while let` are unstable - ; - } - while let 0 | 1 = 1 { //~ ERROR multiple patterns in `if let` and `while let` are unstable - break; - } -} diff --git a/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.stderr b/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.stderr deleted file mode 100644 index ff991819a9218..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-if_while_or_patterns.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0658]: multiple patterns in `if let` and `while let` are unstable (see issue #48215) - --> $DIR/feature-gate-if_while_or_patterns.rs:2:5 - | -LL | / if let 0 | 1 = 0 { //~ ERROR multiple patterns in `if let` and `while let` are unstable -LL | | ; -LL | | } - | |_____^ - | - = help: add #![feature(if_while_or_patterns)] to the crate attributes to enable - -error[E0658]: multiple patterns in `if let` and `while let` are unstable (see issue #48215) - --> $DIR/feature-gate-if_while_or_patterns.rs:5:5 - | -LL | / while let 0 | 1 = 1 { //~ ERROR multiple patterns in `if let` and `while let` are unstable -LL | | break; -LL | | } - | |_____^ - | - = help: add #![feature(if_while_or_patterns)] to the crate attributes to enable - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-underscore_const_names.rs b/src/test/ui/feature-gates/feature-gate-underscore_const_names.rs index a82b356c75216..6b97c24a47ed2 100644 --- a/src/test/ui/feature-gates/feature-gate-underscore_const_names.rs +++ b/src/test/ui/feature-gates/feature-gate-underscore_const_names.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - trait Trt {} struct Str {} diff --git a/src/test/ui/feature-gates/feature-gate-underscore_const_names.stderr b/src/test/ui/feature-gates/feature-gate-underscore_const_names.stderr index b3658208828e9..d608f3d37cf2a 100644 --- a/src/test/ui/feature-gates/feature-gate-underscore_const_names.stderr +++ b/src/test/ui/feature-gates/feature-gate-underscore_const_names.stderr @@ -1,5 +1,5 @@ error[E0658]: naming constants with `_` is unstable (see issue #54912) - --> $DIR/feature-gate-underscore_const_names.rs:8:1 + --> $DIR/feature-gate-underscore_const_names.rs:6:1 | LL | / const _ : () = { LL | | //~^ ERROR is unstable diff --git a/src/test/ui/feature-gates/feature-gate-uniform-paths.rs b/src/test/ui/feature-gates/feature-gate-uniform-paths.rs deleted file mode 100644 index 71f880aae2cec..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-uniform-paths.rs +++ /dev/null @@ -1,19 +0,0 @@ -// edition:2018 - -pub mod foo { - pub use bar::Bar; //~ ERROR imports can only refer to extern crate names - - pub mod bar { - pub struct Bar; - } -} - -use inline; //~ ERROR imports can only refer to extern crate names - -use Vec; //~ ERROR imports can only refer to extern crate names - -use vec; //~ ERROR imports can only refer to extern crate names - -fn main() { - let _ = foo::Bar; -} diff --git a/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr b/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr deleted file mode 100644 index 8b79e597e63fe..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-uniform-paths.stderr +++ /dev/null @@ -1,50 +0,0 @@ -error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130) - --> $DIR/feature-gate-uniform-paths.rs:4:13 - | -LL | pub use bar::Bar; //~ ERROR imports can only refer to extern crate names - | ^^^ -LL | -LL | / pub mod bar { -LL | | pub struct Bar; -LL | | } - | |_____- not an extern crate passed with `--extern` - | - = help: add #![feature(uniform_paths)] to the crate attributes to enable -note: this import refers to the module defined here - --> $DIR/feature-gate-uniform-paths.rs:6:5 - | -LL | / pub mod bar { -LL | | pub struct Bar; -LL | | } - | |_____^ - -error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130) - --> $DIR/feature-gate-uniform-paths.rs:11:5 - | -LL | use inline; //~ ERROR imports can only refer to extern crate names - | ^^^^^^ not an extern crate passed with `--extern` - | - = help: add #![feature(uniform_paths)] to the crate attributes to enable - = note: this import refers to a built-in attribute - -error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130) - --> $DIR/feature-gate-uniform-paths.rs:13:5 - | -LL | use Vec; //~ ERROR imports can only refer to extern crate names - | ^^^ not an extern crate passed with `--extern` - | - = help: add #![feature(uniform_paths)] to the crate attributes to enable - = note: this import refers to a struct from prelude - -error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130) - --> $DIR/feature-gate-uniform-paths.rs:15:5 - | -LL | use vec; //~ ERROR imports can only refer to extern crate names - | ^^^ not an extern crate passed with `--extern` - | - = help: add #![feature(uniform_paths)] to the crate attributes to enable - = note: this import refers to a macro from prelude - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.rs b/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.rs deleted file mode 100644 index cae2f1d2793df..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.rs +++ /dev/null @@ -1,8 +0,0 @@ -// gate-test-irrefutable_let_patterns - - -#[allow(irrefutable_let_patterns)] -fn main() { - if let _ = 5 {} - //~^ ERROR irrefutable if-let pattern [E0162] -} diff --git a/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.stderr b/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.stderr deleted file mode 100644 index fa8b74ffecf3a..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-without_gate_irrefutable_pattern.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0162]: irrefutable if-let pattern - --> $DIR/feature-gate-without_gate_irrefutable_pattern.rs:6:12 - | -LL | if let _ = 5 {} - | ^ irrefutable pattern - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0162`. diff --git a/src/test/ui/if/if-let.rs b/src/test/ui/if/if-let.rs index 304de457059f3..741685fe9b649 100644 --- a/src/test/ui/if/if-let.rs +++ b/src/test/ui/if/if-let.rs @@ -1,3 +1,5 @@ +// compile-pass + fn macros() { macro_rules! foo{ ($p:pat, $e:expr, $b:block) => {{ @@ -10,20 +12,20 @@ fn macros() { }} } - foo!(a, 1, { //~ ERROR irrefutable if-let + foo!(a, 1, { //~ WARN irrefutable if-let println!("irrefutable pattern"); }); - bar!(a, 1, { //~ ERROR irrefutable if-let + bar!(a, 1, { //~ WARN irrefutable if-let println!("irrefutable pattern"); }); } pub fn main() { - if let a = 1 { //~ ERROR irrefutable if-let + if let a = 1 { //~ WARN irrefutable if-let println!("irrefutable pattern"); } - if let a = 1 { //~ ERROR irrefutable if-let + if let a = 1 { //~ WARN irrefutable if-let println!("irrefutable pattern"); } else if true { println!("else-if in irrefutable if-let"); @@ -33,13 +35,13 @@ pub fn main() { if let 1 = 2 { println!("refutable pattern"); - } else if let a = 1 { //~ ERROR irrefutable if-let + } else if let a = 1 { //~ WARN irrefutable if-let println!("irrefutable pattern"); } if true { println!("if"); - } else if let a = 1 { //~ ERROR irrefutable if-let + } else if let a = 1 { //~ WARN irrefutable if-let println!("irrefutable pattern"); } } diff --git a/src/test/ui/if/if-let.stderr b/src/test/ui/if/if-let.stderr index 3802d7828ae7d..b2a104bfacffc 100644 --- a/src/test/ui/if/if-let.stderr +++ b/src/test/ui/if/if-let.stderr @@ -1,39 +1,62 @@ -error[E0162]: irrefutable if-let pattern - --> $DIR/if-let.rs:13:10 +warning: irrefutable if-let pattern + --> $DIR/if-let.rs:6:13 | -LL | foo!(a, 1, { //~ ERROR irrefutable if-let - | ^ irrefutable pattern - -error[E0162]: irrefutable if-let pattern - --> $DIR/if-let.rs:16:10 +LL | if let $p = $e $b + | ^^ +... +LL | / foo!(a, 1, { //~ WARN irrefutable if-let +LL | | println!("irrefutable pattern"); +LL | | }); + | |_______- in this macro invocation | -LL | bar!(a, 1, { //~ ERROR irrefutable if-let - | ^ irrefutable pattern + = note: #[warn(irrefutable_let_patterns)] on by default -error[E0162]: irrefutable if-let pattern - --> $DIR/if-let.rs:22:12 +warning: irrefutable if-let pattern + --> $DIR/if-let.rs:6:13 | -LL | if let a = 1 { //~ ERROR irrefutable if-let - | ^ irrefutable pattern +LL | if let $p = $e $b + | ^^ +... +LL | / bar!(a, 1, { //~ WARN irrefutable if-let +LL | | println!("irrefutable pattern"); +LL | | }); + | |_______- in this macro invocation -error[E0162]: irrefutable if-let pattern - --> $DIR/if-let.rs:26:12 +warning: irrefutable if-let pattern + --> $DIR/if-let.rs:24:5 | -LL | if let a = 1 { //~ ERROR irrefutable if-let - | ^ irrefutable pattern +LL | / if let a = 1 { //~ WARN irrefutable if-let +LL | | println!("irrefutable pattern"); +LL | | } + | |_____^ -error[E0162]: irrefutable if-let pattern - --> $DIR/if-let.rs:36:19 +warning: irrefutable if-let pattern + --> $DIR/if-let.rs:28:5 | -LL | } else if let a = 1 { //~ ERROR irrefutable if-let - | ^ irrefutable pattern +LL | / if let a = 1 { //~ WARN irrefutable if-let +LL | | println!("irrefutable pattern"); +LL | | } else if true { +LL | | println!("else-if in irrefutable if-let"); +LL | | } else { +LL | | println!("else in irrefutable if-let"); +LL | | } + | |_____^ -error[E0162]: irrefutable if-let pattern - --> $DIR/if-let.rs:42:19 +warning: irrefutable if-let pattern + --> $DIR/if-let.rs:38:12 | -LL | } else if let a = 1 { //~ ERROR irrefutable if-let - | ^ irrefutable pattern +LL | } else if let a = 1 { //~ WARN irrefutable if-let + | ____________^ +LL | | println!("irrefutable pattern"); +LL | | } + | |_____^ -error: aborting due to 6 previous errors +warning: irrefutable if-let pattern + --> $DIR/if-let.rs:44:12 + | +LL | } else if let a = 1 { //~ WARN irrefutable if-let + | ____________^ +LL | | println!("irrefutable pattern"); +LL | | } + | |_____^ -For more information about this error, try `rustc --explain E0162`. diff --git a/src/test/ui/imports/issue-56125.rs b/src/test/ui/imports/issue-56125.rs index 0327522e4b8d6..ec5747b4bca8c 100644 --- a/src/test/ui/imports/issue-56125.rs +++ b/src/test/ui/imports/issue-56125.rs @@ -2,8 +2,6 @@ // compile-flags:--extern issue_56125 // aux-build:issue-56125.rs -#![feature(uniform_paths)] - mod m1 { use issue_56125::last_segment::*; //~^ ERROR `issue_56125` is ambiguous diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr index 210f6a4399635..844962b910a69 100644 --- a/src/test/ui/imports/issue-56125.stderr +++ b/src/test/ui/imports/issue-56125.stderr @@ -1,11 +1,11 @@ error[E0432]: unresolved import `empty::issue_56125` - --> $DIR/issue-56125.rs:19:9 + --> $DIR/issue-56125.rs:17:9 | LL | use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125` | ^^^^^^^^^^^^^^^^^^ no `issue_56125` in `m3::empty` error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) - --> $DIR/issue-56125.rs:8:9 + --> $DIR/issue-56125.rs:6:9 | LL | use issue_56125::last_segment::*; | ^^^^^^^^^^^ ambiguous name @@ -13,14 +13,14 @@ LL | use issue_56125::last_segment::*; = note: `issue_56125` could refer to an extern crate passed with `--extern` = help: use `::issue_56125` to refer to this extern crate unambiguously note: `issue_56125` could also refer to the module imported here - --> $DIR/issue-56125.rs:8:9 + --> $DIR/issue-56125.rs:6:9 | LL | use issue_56125::last_segment::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use `self::issue_56125` to refer to this module unambiguously error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) - --> $DIR/issue-56125.rs:13:9 + --> $DIR/issue-56125.rs:11:9 | LL | use issue_56125::non_last_segment::non_last_segment::*; | ^^^^^^^^^^^ ambiguous name @@ -28,14 +28,14 @@ LL | use issue_56125::non_last_segment::non_last_segment::*; = note: `issue_56125` could refer to an extern crate passed with `--extern` = help: use `::issue_56125` to refer to this extern crate unambiguously note: `issue_56125` could also refer to the module imported here - --> $DIR/issue-56125.rs:13:9 + --> $DIR/issue-56125.rs:11:9 | LL | use issue_56125::non_last_segment::non_last_segment::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use `self::issue_56125` to refer to this module unambiguously error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution) - --> $DIR/issue-56125.rs:20:9 + --> $DIR/issue-56125.rs:18:9 | LL | use issue_56125::*; //~ ERROR `issue_56125` is ambiguous | ^^^^^^^^^^^ ambiguous name @@ -43,7 +43,7 @@ LL | use issue_56125::*; //~ ERROR `issue_56125` is ambiguous = note: `issue_56125` could refer to an extern crate passed with `--extern` = help: use `::issue_56125` to refer to this extern crate unambiguously note: `issue_56125` could also refer to the module imported here - --> $DIR/issue-56125.rs:20:9 + --> $DIR/issue-56125.rs:18:9 | LL | use issue_56125::*; //~ ERROR `issue_56125` is ambiguous | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-18118.nll.stderr b/src/test/ui/issues/issue-18118.nll.stderr index d3084b0616776..1920e1637d149 100644 --- a/src/test/ui/issues/issue-18118.nll.stderr +++ b/src/test/ui/issues/issue-18118.nll.stderr @@ -1,68 +1,14 @@ -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:5:17 - | -LL | let p = 3; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:5:17 - | -LL | let p = 3; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:8:9 - | -LL | &p //~ ERROR `p` does not live long enough - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:2:5 - | -LL | / const z: &'static isize = { -LL | | //~^ ERROR let bindings in constants are unstable -LL | | //~| ERROR statements in constants are unstable -LL | | let p = 3; -... | -LL | | //~^ ERROR let bindings in constants are unstable -LL | | }; - | |______^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:2:5 - | -LL | / const z: &'static isize = { -LL | | //~^ ERROR let bindings in constants are unstable -LL | | //~| ERROR statements in constants are unstable -LL | | let p = 3; -... | -LL | | //~^ ERROR let bindings in constants are unstable -LL | | }; - | |______^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0597]: `p` does not live long enough - --> $DIR/issue-18118.rs:8:9 + --> $DIR/issue-18118.rs:4:9 | LL | &p //~ ERROR `p` does not live long enough | ^^ | | | borrowed value does not live long enough | using this value as a constant requires that `p` is borrowed for `'static` -LL | //~^ ERROR let bindings in constants are unstable LL | }; | - `p` dropped here while still borrowed -error: aborting due to 6 previous errors +error: aborting due to previous error -Some errors occurred: E0597, E0658. -For more information about an error, try `rustc --explain E0597`. +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issues/issue-18118.rs b/src/test/ui/issues/issue-18118.rs index 7bbea191cd167..f58a3de281f1a 100644 --- a/src/test/ui/issues/issue-18118.rs +++ b/src/test/ui/issues/issue-18118.rs @@ -1,11 +1,6 @@ pub fn main() { const z: &'static isize = { - //~^ ERROR let bindings in constants are unstable - //~| ERROR statements in constants are unstable let p = 3; - //~^ ERROR let bindings in constants are unstable - //~| ERROR statements in constants are unstable &p //~ ERROR `p` does not live long enough - //~^ ERROR let bindings in constants are unstable }; } diff --git a/src/test/ui/issues/issue-18118.stderr b/src/test/ui/issues/issue-18118.stderr index 1383cdb4438c9..9b21ece341a9f 100644 --- a/src/test/ui/issues/issue-18118.stderr +++ b/src/test/ui/issues/issue-18118.stderr @@ -1,67 +1,13 @@ -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:5:17 - | -LL | let p = 3; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:5:17 - | -LL | let p = 3; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:8:9 - | -LL | &p //~ ERROR `p` does not live long enough - | ^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: let bindings in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:2:5 - | -LL | / const z: &'static isize = { -LL | | //~^ ERROR let bindings in constants are unstable -LL | | //~| ERROR statements in constants are unstable -LL | | let p = 3; -... | -LL | | //~^ ERROR let bindings in constants are unstable -LL | | }; - | |______^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-18118.rs:2:5 - | -LL | / const z: &'static isize = { -LL | | //~^ ERROR let bindings in constants are unstable -LL | | //~| ERROR statements in constants are unstable -LL | | let p = 3; -... | -LL | | //~^ ERROR let bindings in constants are unstable -LL | | }; - | |______^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0597]: `p` does not live long enough - --> $DIR/issue-18118.rs:8:10 + --> $DIR/issue-18118.rs:4:10 | LL | &p //~ ERROR `p` does not live long enough | ^ borrowed value does not live long enough -LL | //~^ ERROR let bindings in constants are unstable LL | }; | - borrowed value only lives until here | = note: borrowed value must be valid for the static lifetime... -error: aborting due to 6 previous errors +error: aborting due to previous error -Some errors occurred: E0597, E0658. -For more information about an error, try `rustc --explain E0597`. +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issues/issue-32829-2.rs b/src/test/ui/issues/issue-32829-2.rs index 9db9d30411d6f..c93c84b5fb773 100644 --- a/src/test/ui/issues/issue-32829-2.rs +++ b/src/test/ui/issues/issue-32829-2.rs @@ -1,11 +1,8 @@ // ignore-tidy-linelength -#![feature(const_fn)] - const bad : u32 = { { 5; - //~^ ERROR statements in constants are unstable 0 } }; @@ -13,8 +10,7 @@ const bad : u32 = { const bad_two : u32 = { { invalid(); - //~^ ERROR statements in constants are unstable - //~^^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants + //~^ ERROR: calls in constants are limited to constant functions, tuple structs and tuple variants 0 } }; @@ -22,7 +18,6 @@ const bad_two : u32 = { const bad_three : u32 = { { valid(); - //~^ ERROR statements in constants are unstable 0 } }; @@ -30,7 +25,6 @@ const bad_three : u32 = { static bad_four : u32 = { { 5; - //~^ ERROR statements in statics are unstable 0 } }; @@ -39,7 +33,6 @@ static bad_five : u32 = { { invalid(); //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants - //~| ERROR statements in statics are unstable 0 } }; @@ -47,7 +40,6 @@ static bad_five : u32 = { static bad_six : u32 = { { valid(); - //~^ ERROR statements in statics are unstable 0 } }; @@ -55,7 +47,6 @@ static bad_six : u32 = { static mut bad_seven : u32 = { { 5; - //~^ ERROR statements in statics are unstable 0 } }; @@ -63,8 +54,7 @@ static mut bad_seven : u32 = { static mut bad_eight : u32 = { { invalid(); - //~^ ERROR statements in statics are unstable - //~| ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants + //~^ ERROR: calls in statics are limited to constant functions, tuple structs and tuple variants 0 } }; @@ -72,7 +62,6 @@ static mut bad_eight : u32 = { static mut bad_nine : u32 = { { valid(); - //~^ ERROR statements in statics are unstable 0 } }; diff --git a/src/test/ui/issues/issue-32829-2.stderr b/src/test/ui/issues/issue-32829-2.stderr index 7fe0261281830..8d7423f29ae97 100644 --- a/src/test/ui/issues/issue-32829-2.stderr +++ b/src/test/ui/issues/issue-32829-2.stderr @@ -1,94 +1,21 @@ -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:7:9 - | -LL | 5; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:15:9 + --> $DIR/issue-32829-2.rs:12:9 | LL | invalid(); | ^^^^^^^^^ -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:15:9 - | -LL | invalid(); - | ^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in constants are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:24:9 - | -LL | valid(); - | ^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:32:9 - | -LL | 5; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:40:9 + --> $DIR/issue-32829-2.rs:34:9 | LL | invalid(); | ^^^^^^^^^ -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:40:9 - | -LL | invalid(); - | ^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:49:9 - | -LL | valid(); - | ^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:57:9 - | -LL | 5; - | ^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants - --> $DIR/issue-32829-2.rs:65:9 + --> $DIR/issue-32829-2.rs:56:9 | LL | invalid(); | ^^^^^^^^^ -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:65:9 - | -LL | invalid(); - | ^^^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error[E0658]: statements in statics are unstable (see issue #48821) - --> $DIR/issue-32829-2.rs:74:9 - | -LL | valid(); - | ^^^^^^^ - | - = help: add #![feature(const_let)] to the crate attributes to enable - -error: aborting due to 12 previous errors +error: aborting due to 3 previous errors -Some errors occurred: E0015, E0658. -For more information about an error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/issues/issue-37550.rs b/src/test/ui/issues/issue-37550.rs index 12282f3e54887..505c030b96712 100644 --- a/src/test/ui/issues/issue-37550.rs +++ b/src/test/ui/issues/issue-37550.rs @@ -1,6 +1,6 @@ const fn x() { - let t = true; //~ ERROR local variables in const fn - let x = || t; + let t = true; + let x = || t; //~ ERROR function pointers in const fn are unstable } fn main() {} diff --git a/src/test/ui/issues/issue-37550.stderr b/src/test/ui/issues/issue-37550.stderr index d42f72ad3fac8..d2b03416cb73c 100644 --- a/src/test/ui/issues/issue-37550.stderr +++ b/src/test/ui/issues/issue-37550.stderr @@ -1,7 +1,7 @@ -error: local variables in const fn are unstable - --> $DIR/issue-37550.rs:2:9 +error: function pointers in const fn are unstable + --> $DIR/issue-37550.rs:3:9 | -LL | let t = true; //~ ERROR local variables in const fn +LL | let x = || t; //~ ERROR function pointers in const fn are unstable | ^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-51714.rs b/src/test/ui/issues/issue-51714.rs index b52e3ac6abd84..4885e4a2db7d5 100644 --- a/src/test/ui/issues/issue-51714.rs +++ b/src/test/ui/issues/issue-51714.rs @@ -10,5 +10,5 @@ fn main() { [(); return while let Some(n) = Some(0) {}]; //~^ ERROR return statement outside of function body - //~^^ ERROR irrefutable while-let pattern + //~^^ WARN irrefutable while-let pattern } diff --git a/src/test/ui/issues/issue-51714.stderr b/src/test/ui/issues/issue-51714.stderr index 47a8b415b0cf0..df11f6b7f5a53 100644 --- a/src/test/ui/issues/issue-51714.stderr +++ b/src/test/ui/issues/issue-51714.stderr @@ -22,13 +22,14 @@ error[E0572]: return statement outside of function body LL | [(); return while let Some(n) = Some(0) {}]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0165]: irrefutable while-let pattern - --> $DIR/issue-51714.rs:11:27 +warning: irrefutable while-let pattern + --> $DIR/issue-51714.rs:11:17 | LL | [(); return while let Some(n) = Some(0) {}]; - | ^^^^^^^ irrefutable pattern + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(irrefutable_let_patterns)] on by default -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors occurred: E0165, E0572. -For more information about an error, try `rustc --explain E0165`. +For more information about this error, try `rustc --explain E0572`. diff --git a/src/test/ui/issues/issue-57156.rs b/src/test/ui/issues/issue-57156.rs new file mode 100644 index 0000000000000..f20b0f41c7fa5 --- /dev/null +++ b/src/test/ui/issues/issue-57156.rs @@ -0,0 +1,23 @@ +// compile-pass + +trait Foo { + type Output; +} + +trait Bar<'a, T>: for<'s> Foo<&'s T, Output=bool> { + fn cb(&self) -> Box>; +} + +impl<'s> Foo<&'s ()> for () { + type Output = bool; +} + +impl<'a> Bar<'a, ()> for () { + fn cb(&self) -> Box> { + Box::new(*self) + } +} + +fn main() { + let _t = ().cb(); +} diff --git a/src/test/ui/issues/issue-7364.rs b/src/test/ui/issues/issue-7364.rs index 3f9c2ef48a7af..52ec9e42be782 100644 --- a/src/test/ui/issues/issue-7364.rs +++ b/src/test/ui/issues/issue-7364.rs @@ -6,5 +6,6 @@ use std::cell::RefCell; static boxed: Box> = box RefCell::new(0); //~^ ERROR allocations are not allowed in statics //~| ERROR `std::cell::RefCell` cannot be shared between threads safely [E0277] +//~| ERROR static contains unimplemented expression type fn main() { } diff --git a/src/test/ui/issues/issue-7364.stderr b/src/test/ui/issues/issue-7364.stderr index 0e4d6ff1d71fa..52a99ce36b870 100644 --- a/src/test/ui/issues/issue-7364.stderr +++ b/src/test/ui/issues/issue-7364.stderr @@ -4,6 +4,12 @@ error[E0010]: allocations are not allowed in statics LL | static boxed: Box> = box RefCell::new(0); | ^^^^^^^^^^^^^^^^^^^ allocation not allowed in statics +error[E0019]: static contains unimplemented expression type + --> $DIR/issue-7364.rs:6:41 + | +LL | static boxed: Box> = box RefCell::new(0); + | ^^^^^^^^^^^^^^^ + error[E0277]: `std::cell::RefCell` cannot be shared between threads safely --> $DIR/issue-7364.rs:6:1 | @@ -15,7 +21,7 @@ LL | static boxed: Box> = box RefCell::new(0); = note: required because it appears within the type `std::boxed::Box>` = note: shared static variables must have a type that implements `Sync` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -Some errors occurred: E0010, E0277. +Some errors occurred: E0010, E0019, E0277. For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/macros/format-parse-errors.rs b/src/test/ui/macros/format-parse-errors.rs index ba1e441fe339f..96aee5e6aeed5 100644 --- a/src/test/ui/macros/format-parse-errors.rs +++ b/src/test/ui/macros/format-parse-errors.rs @@ -2,6 +2,7 @@ fn main() { format!(); //~ ERROR requires at least a format string argument format!(struct); //~ ERROR expected expression format!("s", name =); //~ ERROR expected expression + format!("s", foo = foo, bar); //~ ERROR expected `=` format!("s", foo = struct); //~ ERROR expected expression format!("s", struct); //~ ERROR expected expression diff --git a/src/test/ui/macros/format-parse-errors.stderr b/src/test/ui/macros/format-parse-errors.stderr index 0463c54890177..a3d2786bce111 100644 --- a/src/test/ui/macros/format-parse-errors.stderr +++ b/src/test/ui/macros/format-parse-errors.stderr @@ -18,20 +18,26 @@ error: expected expression, found `` LL | format!("s", name =); //~ ERROR expected expression | ^ expected expression +error: expected `=`, found `` + --> $DIR/format-parse-errors.rs:5:29 + | +LL | format!("s", foo = foo, bar); //~ ERROR expected `=` + | ^^^ expected `=` + error: expected expression, found keyword `struct` - --> $DIR/format-parse-errors.rs:5:24 + --> $DIR/format-parse-errors.rs:6:24 | LL | format!("s", foo = struct); //~ ERROR expected expression | ^^^^^^ expected expression error: expected expression, found keyword `struct` - --> $DIR/format-parse-errors.rs:6:18 + --> $DIR/format-parse-errors.rs:7:18 | LL | format!("s", struct); //~ ERROR expected expression | ^^^^^^ expected expression error: format argument must be a string literal - --> $DIR/format-parse-errors.rs:9:13 + --> $DIR/format-parse-errors.rs:10:13 | LL | format!(123); //~ ERROR format argument must be a string literal | ^^^ @@ -40,5 +46,5 @@ help: you might be missing a string literal to format with LL | format!("{}", 123); //~ ERROR format argument must be a string literal | ^^^^^ -error: aborting due to 6 previous errors +error: aborting due to 7 previous errors diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr index 158d114616979..fbe5e6d409934 100644 --- a/src/test/ui/mismatched_types/cast-rfc0401.stderr +++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr @@ -240,13 +240,10 @@ error[E0606]: casting `&{float}` as `f32` is invalid --> $DIR/cast-rfc0401.rs:71:30 | LL | vec![0.0].iter().map(|s| s as f32).collect::>(); //~ ERROR is invalid - | ^^^^^^^^ cannot cast `&{float}` as `f32` - | -help: did you mean `*s`? - --> $DIR/cast-rfc0401.rs:71:30 - | -LL | vec![0.0].iter().map(|s| s as f32).collect::>(); //~ ERROR is invalid - | ^ + | -^^^^^^^ + | | + | cannot cast `&{float}` as `f32` + | help: dereference the expression: `*s` error: aborting due to 34 previous errors diff --git a/src/test/ui/pattern/deny-irrefutable-let-patterns.rs b/src/test/ui/pattern/deny-irrefutable-let-patterns.rs new file mode 100644 index 0000000000000..14040c8ada67d --- /dev/null +++ b/src/test/ui/pattern/deny-irrefutable-let-patterns.rs @@ -0,0 +1,9 @@ +#![deny(irrefutable_let_patterns)] + +fn main() { + if let _ = 5 {} //~ ERROR irrefutable if-let pattern + + while let _ = 5 { //~ ERROR irrefutable while-let pattern + break; + } +} diff --git a/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr b/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr new file mode 100644 index 0000000000000..ad8cc2ef8973b --- /dev/null +++ b/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr @@ -0,0 +1,22 @@ +error: irrefutable if-let pattern + --> $DIR/deny-irrefutable-let-patterns.rs:4:5 + | +LL | if let _ = 5 {} //~ ERROR irrefutable if-let pattern + | ^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/deny-irrefutable-let-patterns.rs:1:9 + | +LL | #![deny(irrefutable_let_patterns)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: irrefutable while-let pattern + --> $DIR/deny-irrefutable-let-patterns.rs:6:5 + | +LL | / while let _ = 5 { //~ ERROR irrefutable while-let pattern +LL | | break; +LL | | } + | |_____^ + +error: aborting due to 2 previous errors + diff --git a/src/test/run-pass/enum-variant-generic-args.rs b/src/test/ui/pattern/enum-variant-generic-args.rs similarity index 97% rename from src/test/run-pass/enum-variant-generic-args.rs rename to src/test/ui/pattern/enum-variant-generic-args.rs index 0743f99897922..85599530ea6a4 100644 --- a/src/test/run-pass/enum-variant-generic-args.rs +++ b/src/test/ui/pattern/enum-variant-generic-args.rs @@ -1,4 +1,5 @@ -#![feature(irrefutable_let_patterns)] +// run-pass + #![feature(type_alias_enum_variants)] #![allow(irrefutable_let_patterns)] diff --git a/src/test/ui/pattern/irrefutable-let-patterns.rs b/src/test/ui/pattern/irrefutable-let-patterns.rs new file mode 100644 index 0000000000000..d400ef0bbd64c --- /dev/null +++ b/src/test/ui/pattern/irrefutable-let-patterns.rs @@ -0,0 +1,11 @@ +// run-pass + +#![allow(irrefutable_let_patterns)] + +fn main() { + if let _ = 5 {} + + while let _ = 5 { + break; + } +} diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.rs b/src/test/ui/proc-macro/derive-helper-shadowing.rs index aa9eae0ba317a..f6fe9f9fd8b30 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.rs +++ b/src/test/ui/proc-macro/derive-helper-shadowing.rs @@ -5,6 +5,26 @@ use derive_helper_shadowing::*; #[my_attr] //~ ERROR `my_attr` is ambiguous #[derive(MyTrait)] -struct S; +struct S { + // FIXME No ambiguity, attributes in non-macro positions are not resolved properly + #[my_attr] + field: [u8; { + // FIXME No ambiguity, derive helpers are not put into scope for non-attributes + use my_attr; -fn main() {} + // FIXME No ambiguity, derive helpers are not put into scope for inner items + #[my_attr] + struct U; + + mod inner { + #[my_attr] //~ ERROR attribute `my_attr` is currently unknown + struct V; + } + + 0 + }] +} + +fn main() { + let s = S { field: [] }; +} diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr index cc50fefc46453..8180c84d3f6eb 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr @@ -1,3 +1,11 @@ +error[E0658]: The attribute `my_attr` is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642) + --> $DIR/derive-helper-shadowing.rs:20:15 + | +LL | #[my_attr] //~ ERROR attribute `my_attr` is currently unknown + | ^^^^^^^ + | + = help: add #![feature(custom_attribute)] to the crate attributes to enable + error[E0659]: `my_attr` is ambiguous (derive helper attribute vs any other name) --> $DIR/derive-helper-shadowing.rs:6:3 | @@ -16,6 +24,7 @@ LL | use derive_helper_shadowing::*; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use `crate::my_attr` to refer to this attribute macro unambiguously -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0659`. +Some errors occurred: E0658, E0659. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs index 1dd428b7c83f6..dd21de75aaf75 100644 --- a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs +++ b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(uniform_paths)] - // Tests that arbitrary crates (other than `core`, `std` and `meta`) // aren't allowed without `--extern`, even if they're in the sysroot. use alloc; //~ ERROR unresolved import `alloc` diff --git a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr index e4eaa1dc3d2b3..3bea7816b3061 100644 --- a/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr +++ b/src/test/ui/rfc-2126-extern-absolute-paths/not-whitelisted.stderr @@ -1,11 +1,11 @@ error: cannot import a built-in macro - --> $DIR/not-whitelisted.rs:8:5 + --> $DIR/not-whitelisted.rs:6:5 | LL | use test; //~ ERROR cannot import a built-in macro | ^^^^ error[E0432]: unresolved import `alloc` - --> $DIR/not-whitelisted.rs:7:5 + --> $DIR/not-whitelisted.rs:5:5 | LL | use alloc; //~ ERROR unresolved import `alloc` | ^^^^^ no `alloc` external crate diff --git a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.rs b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.rs index 3814fc02745a7..d79798d57e820 100644 --- a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.rs +++ b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.rs @@ -2,7 +2,6 @@ // Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up // with examples easier. -#![feature(irrefutable_let_patterns)] #[allow(irrefutable_let_patterns)] fn main() { diff --git a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.stderr b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.stderr index 1d518215c2c36..2cd59fe56cf2d 100644 --- a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2015.stderr @@ -1,5 +1,5 @@ error: ambiguous use of `&&` - --> $DIR/syntax-ambiguity-2015.rs:11:47 + --> $DIR/syntax-ambiguity-2015.rs:10:47 | LL | if let Range { start: _, end: _ } = true..true && false { } | ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)` @@ -8,7 +8,7 @@ LL | if let Range { start: _, end: _ } = true..true && false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `||` - --> $DIR/syntax-ambiguity-2015.rs:14:47 + --> $DIR/syntax-ambiguity-2015.rs:13:47 | LL | if let Range { start: _, end: _ } = true..true || false { } | ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)` @@ -17,7 +17,7 @@ LL | if let Range { start: _, end: _ } = true..true || false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `&&` - --> $DIR/syntax-ambiguity-2015.rs:17:50 + --> $DIR/syntax-ambiguity-2015.rs:16:50 | LL | while let Range { start: _, end: _ } = true..true && false { } | ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)` @@ -26,7 +26,7 @@ LL | while let Range { start: _, end: _ } = true..true && false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `||` - --> $DIR/syntax-ambiguity-2015.rs:20:50 + --> $DIR/syntax-ambiguity-2015.rs:19:50 | LL | while let Range { start: _, end: _ } = true..true || false { } | ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)` @@ -35,7 +35,7 @@ LL | while let Range { start: _, end: _ } = true..true || false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `&&` - --> $DIR/syntax-ambiguity-2015.rs:23:19 + --> $DIR/syntax-ambiguity-2015.rs:22:19 | LL | if let true = false && false { } | ^^^^^^^^^^^^^^ help: consider adding parentheses: `(false && false)` @@ -44,7 +44,7 @@ LL | if let true = false && false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `&&` - --> $DIR/syntax-ambiguity-2015.rs:26:22 + --> $DIR/syntax-ambiguity-2015.rs:25:22 | LL | while let true = (1 == 2) && false { } | ^^^^^^^^^^^^^^^^^ help: consider adding parentheses: `((1 == 2) && false)` diff --git a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.rs b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.rs index 311953a283e37..687bf659416ab 100644 --- a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.rs +++ b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.rs @@ -2,7 +2,6 @@ // Enabling `ireffutable_let_patterns` isn't necessary for what this tests, but it makes coming up // with examples easier. -#![feature(irrefutable_let_patterns)] #[allow(irrefutable_let_patterns)] fn main() { diff --git a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.stderr b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.stderr index b3579973ca2bd..cbba2d7473334 100644 --- a/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/syntax-ambiguity-2018.stderr @@ -1,5 +1,5 @@ error: ambiguous use of `&&` - --> $DIR/syntax-ambiguity-2018.rs:11:47 + --> $DIR/syntax-ambiguity-2018.rs:10:47 | LL | if let Range { start: _, end: _ } = true..true && false { } | ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)` @@ -8,7 +8,7 @@ LL | if let Range { start: _, end: _ } = true..true && false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `||` - --> $DIR/syntax-ambiguity-2018.rs:14:47 + --> $DIR/syntax-ambiguity-2018.rs:13:47 | LL | if let Range { start: _, end: _ } = true..true || false { } | ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)` @@ -17,7 +17,7 @@ LL | if let Range { start: _, end: _ } = true..true || false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `&&` - --> $DIR/syntax-ambiguity-2018.rs:17:50 + --> $DIR/syntax-ambiguity-2018.rs:16:50 | LL | while let Range { start: _, end: _ } = true..true && false { } | ^^^^^^^^^^^^^ help: consider adding parentheses: `(true && false)` @@ -26,7 +26,7 @@ LL | while let Range { start: _, end: _ } = true..true && false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `||` - --> $DIR/syntax-ambiguity-2018.rs:20:50 + --> $DIR/syntax-ambiguity-2018.rs:19:50 | LL | while let Range { start: _, end: _ } = true..true || false { } | ^^^^^^^^^^^^^ help: consider adding parentheses: `(true || false)` @@ -35,7 +35,7 @@ LL | while let Range { start: _, end: _ } = true..true || false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `&&` - --> $DIR/syntax-ambiguity-2018.rs:23:19 + --> $DIR/syntax-ambiguity-2018.rs:22:19 | LL | if let true = false && false { } | ^^^^^^^^^^^^^^ help: consider adding parentheses: `(false && false)` @@ -44,7 +44,7 @@ LL | if let true = false && false { } = note: see rust-lang/rust#53668 for more information error: ambiguous use of `&&` - --> $DIR/syntax-ambiguity-2018.rs:26:22 + --> $DIR/syntax-ambiguity-2018.rs:25:22 | LL | while let true = (1 == 2) && false { } | ^^^^^^^^^^^^^^^^^ help: consider adding parentheses: `((1 == 2) && false)` diff --git a/src/test/ui/rust-2018/future-proofing-locals.rs b/src/test/ui/rust-2018/future-proofing-locals.rs index d777b1165f30b..1e53c2d1daca4 100644 --- a/src/test/ui/rust-2018/future-proofing-locals.rs +++ b/src/test/ui/rust-2018/future-proofing-locals.rs @@ -1,6 +1,5 @@ // edition:2018 -#![feature(uniform_paths)] #![allow(non_camel_case_types)] mod T { @@ -17,7 +16,7 @@ fn type_param() { } fn self_import() { - use T; // FIXME Should be an error, but future-proofing fails due to `T` being "self-shadowed" + use T; //~ ERROR imports cannot refer to type parameters } fn let_binding() { diff --git a/src/test/ui/rust-2018/future-proofing-locals.stderr b/src/test/ui/rust-2018/future-proofing-locals.stderr index 594b22496e74a..413e199cd646c 100644 --- a/src/test/ui/rust-2018/future-proofing-locals.stderr +++ b/src/test/ui/rust-2018/future-proofing-locals.stderr @@ -1,50 +1,56 @@ error: imports cannot refer to type parameters - --> $DIR/future-proofing-locals.rs:14:9 + --> $DIR/future-proofing-locals.rs:13:9 | LL | use T as _; //~ ERROR imports cannot refer to type parameters | ^ error: imports cannot refer to type parameters - --> $DIR/future-proofing-locals.rs:15:9 + --> $DIR/future-proofing-locals.rs:14:9 | LL | use T::U; //~ ERROR imports cannot refer to type parameters | ^ error: imports cannot refer to type parameters - --> $DIR/future-proofing-locals.rs:16:9 + --> $DIR/future-proofing-locals.rs:15:9 | LL | use T::*; //~ ERROR imports cannot refer to type parameters | ^ +error: imports cannot refer to type parameters + --> $DIR/future-proofing-locals.rs:19:9 + | +LL | use T; //~ ERROR imports cannot refer to type parameters + | ^ + error: imports cannot refer to local variables - --> $DIR/future-proofing-locals.rs:26:9 + --> $DIR/future-proofing-locals.rs:25:9 | LL | use x as _; //~ ERROR imports cannot refer to local variables | ^ error: imports cannot refer to local variables - --> $DIR/future-proofing-locals.rs:32:9 + --> $DIR/future-proofing-locals.rs:31:9 | LL | use x; //~ ERROR imports cannot refer to local variables | ^ error: imports cannot refer to local variables - --> $DIR/future-proofing-locals.rs:38:17 + --> $DIR/future-proofing-locals.rs:37:17 | LL | use x; //~ ERROR imports cannot refer to local variables | ^ error: imports cannot refer to type parameters - --> $DIR/future-proofing-locals.rs:46:10 + --> $DIR/future-proofing-locals.rs:45:10 | LL | use {T as _, x}; //~ ERROR imports cannot refer to type parameters | ^ error: imports cannot refer to local variables - --> $DIR/future-proofing-locals.rs:46:18 + --> $DIR/future-proofing-locals.rs:45:18 | LL | use {T as _, x}; //~ ERROR imports cannot refer to type parameters | ^ -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/src/test/ui/rust-2018/local-path-suggestions-2018.rs b/src/test/ui/rust-2018/local-path-suggestions-2018.rs index 824405074abe3..5eafbb2c2fc66 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.rs +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.rs @@ -2,8 +2,6 @@ // compile-flags:--extern baz // edition:2018 -#![feature(uniform_paths)] - mod foo { pub type Bar = u32; } diff --git a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr index 8425ee0752e8b..71c8289264ffe 100644 --- a/src/test/ui/rust-2018/local-path-suggestions-2018.stderr +++ b/src/test/ui/rust-2018/local-path-suggestions-2018.stderr @@ -1,5 +1,5 @@ error[E0432]: unresolved import `foo` - --> $DIR/local-path-suggestions-2018.rs:12:9 + --> $DIR/local-path-suggestions-2018.rs:10:9 | LL | use foo::Bar; //~ ERROR unresolved import `foo` | ^^^ did you mean `crate::foo`? @@ -7,7 +7,7 @@ LL | use foo::Bar; //~ ERROR unresolved import `foo` = note: `use` statements changed in Rust 2018; read more at error[E0432]: unresolved import `foobar` - --> $DIR/local-path-suggestions-2018.rs:21:5 + --> $DIR/local-path-suggestions-2018.rs:19:5 | LL | use foobar::Baz; //~ ERROR unresolved import `foobar` | ^^^^^^ did you mean `baz::foobar`? diff --git a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs index 19be7dc964040..3f5897901a056 100644 --- a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs +++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(uniform_paths)] - mod my { pub mod sub { pub fn bar() {} diff --git a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr index 0088296b1a471..4a01ba5088f62 100644 --- a/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr +++ b/src/test/ui/rust-2018/uniform-paths/block-scoped-shadow-nested.stderr @@ -1,16 +1,16 @@ error[E0659]: `sub` is ambiguous (name vs any other name during import resolution) - --> $DIR/block-scoped-shadow-nested.rs:18:13 + --> $DIR/block-scoped-shadow-nested.rs:16:13 | LL | use sub::bar; //~ ERROR `sub` is ambiguous | ^^^ ambiguous name | note: `sub` could refer to the module imported here - --> $DIR/block-scoped-shadow-nested.rs:16:9 + --> $DIR/block-scoped-shadow-nested.rs:14:9 | LL | use my::sub; | ^^^^^^^ note: `sub` could also refer to the module defined here - --> $DIR/block-scoped-shadow-nested.rs:11:1 + --> $DIR/block-scoped-shadow-nested.rs:9:1 | LL | / mod sub { LL | | pub fn bar() {} diff --git a/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs index a7bc625bbf0a4..0c2da1884b758 100644 --- a/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs +++ b/src/test/ui/rust-2018/uniform-paths/fn-local-enum.rs @@ -1,8 +1,6 @@ // compile-pass // edition:2018 -#![feature(uniform_paths)] - fn main() { enum E { A, B, C } diff --git a/src/test/ui/rust-2018/uniform-paths/issue-54390.rs b/src/test/ui/rust-2018/uniform-paths/issue-54390.rs deleted file mode 100644 index 536cc25e35ac1..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths/issue-54390.rs +++ /dev/null @@ -1,11 +0,0 @@ -// edition:2018 - -#![deny(unused)] - -use std::fmt; - -// No "unresolved import" + "unused import" combination here. -use fmt::Write; //~ ERROR imports can only refer to extern crate names - //~| ERROR unused import: `fmt::Write` - -fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths/issue-54390.stderr b/src/test/ui/rust-2018/uniform-paths/issue-54390.stderr deleted file mode 100644 index 8f86698c9c11a..0000000000000 --- a/src/test/ui/rust-2018/uniform-paths/issue-54390.stderr +++ /dev/null @@ -1,32 +0,0 @@ -error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130) - --> $DIR/issue-54390.rs:8:5 - | -LL | use std::fmt; - | -------- not an extern crate passed with `--extern` -... -LL | use fmt::Write; //~ ERROR imports can only refer to extern crate names - | ^^^ - | - = help: add #![feature(uniform_paths)] to the crate attributes to enable -note: this import refers to the module imported here - --> $DIR/issue-54390.rs:5:5 - | -LL | use std::fmt; - | ^^^^^^^^ - -error: unused import: `fmt::Write` - --> $DIR/issue-54390.rs:8:5 - | -LL | use fmt::Write; //~ ERROR imports can only refer to extern crate names - | ^^^^^^^^^^ - | -note: lint level defined here - --> $DIR/issue-54390.rs:3:9 - | -LL | #![deny(unused)] - | ^^^^^^ - = note: #[deny(unused_imports)] implied by #[deny(unused)] - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rust-2018/uniform-paths/macro-rules.rs b/src/test/ui/rust-2018/uniform-paths/macro-rules.rs index 69f6a8668add3..6c3f1892cb369 100644 --- a/src/test/ui/rust-2018/uniform-paths/macro-rules.rs +++ b/src/test/ui/rust-2018/uniform-paths/macro-rules.rs @@ -1,23 +1,23 @@ // edition:2018 -// For the time being `macro_rules` items are treated as *very* private... - -#![feature(decl_macro, uniform_paths)] -#![allow(non_camel_case_types)] +#![feature(decl_macro)] mod m1 { + // Non-exported legacy macros are treated as `pub(crate)`. macro_rules! legacy_macro { () => () } - // ... so they can't be imported by themselves, ... - use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported + use legacy_macro as _; // OK + pub(crate) use legacy_macro as _; // OK + pub use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported } mod m2 { macro_rules! legacy_macro { () => () } + #[allow(non_camel_case_types)] type legacy_macro = u8; - // ... but don't prevent names from other namespaces from being imported, ... + // Legacy macro imports don't prevent names from other namespaces from being imported. use legacy_macro as _; // OK } @@ -27,19 +27,17 @@ mod m3 { fn f() { macro_rules! legacy_macro { () => () } - // ... but still create ambiguities with other names in the same namespace. + // Legacy macro imports create ambiguities with other names in the same namespace. use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous - //~| ERROR `legacy_macro` is private, and cannot be re-exported } } mod exported { - // Exported macros are treated as private as well, - // some better rules need to be figured out later. + // Exported legacy macros are treated as `pub`. #[macro_export] macro_rules! legacy_macro { () => () } - use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported + pub use legacy_macro as _; // OK } fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths/macro-rules.stderr b/src/test/ui/rust-2018/uniform-paths/macro-rules.stderr index be7bbd314df31..684f5fceac15f 100644 --- a/src/test/ui/rust-2018/uniform-paths/macro-rules.stderr +++ b/src/test/ui/rust-2018/uniform-paths/macro-rules.stderr @@ -1,39 +1,15 @@ error[E0364]: `legacy_macro` is private, and cannot be re-exported - --> $DIR/macro-rules.rs:12:9 + --> $DIR/macro-rules.rs:11:13 | -LL | use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported - | ^^^^^^^^^^^^^^^^^ - | -note: consider marking `legacy_macro` as `pub` in the imported module - --> $DIR/macro-rules.rs:12:9 - | -LL | use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported - | ^^^^^^^^^^^^^^^^^ - -error[E0364]: `legacy_macro` is private, and cannot be re-exported - --> $DIR/macro-rules.rs:31:13 - | -LL | use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous +LL | pub use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported | ^^^^^^^^^^^^^^^^^ | note: consider marking `legacy_macro` as `pub` in the imported module - --> $DIR/macro-rules.rs:31:13 + --> $DIR/macro-rules.rs:11:13 | -LL | use legacy_macro as _; //~ ERROR `legacy_macro` is ambiguous +LL | pub use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported | ^^^^^^^^^^^^^^^^^ -error[E0364]: `legacy_macro` is private, and cannot be re-exported - --> $DIR/macro-rules.rs:42:9 - | -LL | use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported - | ^^^^^^^^^^^^^^^^^ - | -note: consider marking `legacy_macro` as `pub` in the imported module - --> $DIR/macro-rules.rs:42:9 - | -LL | use legacy_macro as _; //~ ERROR `legacy_macro` is private, and cannot be re-exported - | ^^^^^^^^^^^^^^^^^ - error[E0659]: `legacy_macro` is ambiguous (name vs any other name during import resolution) --> $DIR/macro-rules.rs:31:13 | @@ -52,7 +28,7 @@ LL | macro legacy_macro() {} | ^^^^^^^^^^^^^^^^^^^^^^^ = help: use `self::legacy_macro` to refer to this macro unambiguously -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors Some errors occurred: E0364, E0659. For more information about an error, try `rustc --explain E0364`. diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs new file mode 100644 index 0000000000000..541fc1be4e82f --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.rs @@ -0,0 +1,19 @@ +// edition:2018 + +// Built-in attribute +use inline as imported_inline; +mod builtin { + pub use inline as imported_inline; +} + +// Tool module +use rustfmt as imported_rustfmt; +mod tool_mod { + pub use rustfmt as imported_rustfmt; +} + +#[imported_inline] //~ ERROR cannot use a built-in attribute through an import +#[builtin::imported_inline] //~ ERROR cannot use a built-in attribute through an import +#[imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import +#[tool_mod::imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import +fn main() {} diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr new file mode 100644 index 0000000000000..40b8fcf7158eb --- /dev/null +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail-2.stderr @@ -0,0 +1,44 @@ +error: cannot use a built-in attribute through an import + --> $DIR/prelude-fail-2.rs:15:3 + | +LL | #[imported_inline] //~ ERROR cannot use a built-in attribute through an import + | ^^^^^^^^^^^^^^^ + | +note: the built-in attribute imported here + --> $DIR/prelude-fail-2.rs:4:5 + | +LL | use inline as imported_inline; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot use a built-in attribute through an import + --> $DIR/prelude-fail-2.rs:16:3 + | +LL | #[builtin::imported_inline] //~ ERROR cannot use a built-in attribute through an import + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot use a tool module through an import + --> $DIR/prelude-fail-2.rs:17:3 + | +LL | #[imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import + | ^^^^^^^^^^^^^^^^ + | +note: the tool module imported here + --> $DIR/prelude-fail-2.rs:10:5 + | +LL | use rustfmt as imported_rustfmt; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: cannot use a tool module through an import + --> $DIR/prelude-fail-2.rs:18:13 + | +LL | #[tool_mod::imported_rustfmt::skip] //~ ERROR cannot use a tool module through an import + | ^^^^^^^^^^^^^^^^ + | +note: the tool module imported here + --> $DIR/prelude-fail-2.rs:12:13 + | +LL | pub use rustfmt as imported_rustfmt; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs b/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs index c5bd50f2f567f..d717884c901b3 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(uniform_paths)] - // Built-in macro use env as env_imported; //~ ERROR cannot import a built-in macro diff --git a/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr index 794d986b82ef1..fdfea416b12f1 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr +++ b/src/test/ui/rust-2018/uniform-paths/prelude-fail.stderr @@ -1,11 +1,11 @@ error: cannot import a built-in macro - --> $DIR/prelude-fail.rs:6:5 + --> $DIR/prelude-fail.rs:4:5 | LL | use env as env_imported; //~ ERROR cannot import a built-in macro | ^^^^^^^^^^^^^^^^^^^ error[E0432]: unresolved import `rustfmt` - --> $DIR/prelude-fail.rs:9:5 + --> $DIR/prelude-fail.rs:7:5 | LL | use rustfmt::skip as imported_rustfmt_skip; //~ ERROR unresolved import `rustfmt` | ^^^^^^^ not a module `rustfmt` diff --git a/src/test/ui/rust-2018/uniform-paths/prelude.rs b/src/test/ui/rust-2018/uniform-paths/prelude.rs index 5aab5fc3a4018..9a326b4c728bd 100644 --- a/src/test/ui/rust-2018/uniform-paths/prelude.rs +++ b/src/test/ui/rust-2018/uniform-paths/prelude.rs @@ -1,17 +1,9 @@ // compile-pass // edition:2018 -#![feature(uniform_paths)] - // Macro imported with `#[macro_use] extern crate` use vec as imported_vec; -// Built-in attribute -use inline as imported_inline; - -// Tool module -use rustfmt as imported_rustfmt; - // Standard library prelude use Vec as ImportedVec; @@ -20,8 +12,6 @@ use u8 as imported_u8; type A = imported_u8; -#[imported_inline] -#[imported_rustfmt::skip] fn main() { imported_vec![0]; ImportedVec::::new(); diff --git a/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.rs b/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.rs deleted file mode 100644 index 2899298a0cb1d..0000000000000 --- a/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.rs +++ /dev/null @@ -1,5 +0,0 @@ -// should-fail-irrefutable_let_patterns -fn main() { - if let _ = 5 {} - //~^ ERROR irrefutable if-let pattern [E0162] -} diff --git a/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.stderr b/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.stderr deleted file mode 100644 index 9c9ebc6659b73..0000000000000 --- a/src/test/ui/should-fail-no_gate_irrefutable_if_let_pattern.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0162]: irrefutable if-let pattern - --> $DIR/should-fail-no_gate_irrefutable_if_let_pattern.rs:3:12 - | -LL | if let _ = 5 {} - | ^ irrefutable pattern - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0162`. diff --git a/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.rs b/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.rs deleted file mode 100644 index 1b9b3dc1a4cbe..0000000000000 --- a/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![feature(irrefutable_let_patterns)] - -// should-fail-irrefutable_let_patterns_with_gate -fn main() { - if let _ = 5 {} - //~^ ERROR irrefutable if-let pattern [irrefutable_let_patterns] -} diff --git a/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.stderr b/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.stderr deleted file mode 100644 index dc670f0e59081..0000000000000 --- a/src/test/ui/should-fail-with_gate_irrefutable_pattern_deny.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: irrefutable if-let pattern - --> $DIR/should-fail-with_gate_irrefutable_pattern_deny.rs:5:5 - | -LL | if let _ = 5 {} - | ^^^^^^^^^^^^^^^ - | - = note: #[deny(irrefutable_let_patterns)] on by default - -error: aborting due to previous error - diff --git a/src/test/ui/static/static-mut-not-constant.rs b/src/test/ui/static/static-mut-not-constant.rs index 2091fffd418ee..84d401c9fa61d 100644 --- a/src/test/ui/static/static-mut-not-constant.rs +++ b/src/test/ui/static/static-mut-not-constant.rs @@ -2,5 +2,6 @@ static mut a: Box = box 3; //~^ ERROR allocations are not allowed in statics +//~| ERROR static contains unimplemented expression type fn main() {} diff --git a/src/test/ui/static/static-mut-not-constant.stderr b/src/test/ui/static/static-mut-not-constant.stderr index a0fa245156f87..d2c6ba6a2f85a 100644 --- a/src/test/ui/static/static-mut-not-constant.stderr +++ b/src/test/ui/static/static-mut-not-constant.stderr @@ -4,6 +4,13 @@ error[E0010]: allocations are not allowed in statics LL | static mut a: Box = box 3; | ^^^^^ allocation not allowed in statics -error: aborting due to previous error +error[E0019]: static contains unimplemented expression type + --> $DIR/static-mut-not-constant.rs:3:32 + | +LL | static mut a: Box = box 3; + | ^ + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0010`. +Some errors occurred: E0010, E0019. +For more information about an error, try `rustc --explain E0010`. diff --git a/src/test/ui/underscore_const_names.rs b/src/test/ui/underscore_const_names.rs index 811d166ed65a7..1db022e886208 100644 --- a/src/test/ui/underscore_const_names.rs +++ b/src/test/ui/underscore_const_names.rs @@ -1,6 +1,5 @@ // compile-pass -#![feature(const_let)] #![feature(underscore_const_names)] trait Trt {} diff --git a/src/test/ui/unsafe/ranged_ints2_const.rs b/src/test/ui/unsafe/ranged_ints2_const.rs index a61e3329bdce8..788f49f743cda 100644 --- a/src/test/ui/unsafe/ranged_ints2_const.rs +++ b/src/test/ui/unsafe/ranged_ints2_const.rs @@ -1,4 +1,4 @@ -#![feature(rustc_attrs, const_let, const_fn)] +#![feature(rustc_attrs)] #[rustc_layout_scalar_valid_range_start(1)] #[repr(transparent)] @@ -8,13 +8,13 @@ fn main() { const fn foo() -> NonZero { let mut x = unsafe { NonZero(1) }; - let y = &mut x.0; //~ ERROR references in constant functions may only refer to immutable + let y = &mut x.0; //~ ERROR references in const fn are unstable //~^ ERROR mutation of layout constrained field is unsafe unsafe { NonZero(1) } } const fn bar() -> NonZero { let mut x = unsafe { NonZero(1) }; - let y = unsafe { &mut x.0 }; //~ ERROR references in constant functions may only refer to immut + let y = unsafe { &mut x.0 }; //~ ERROR mutable references in const fn are unstable unsafe { NonZero(1) } } diff --git a/src/test/ui/unsafe/ranged_ints2_const.stderr b/src/test/ui/unsafe/ranged_ints2_const.stderr index f79792ffba9be..39a55190b17de 100644 --- a/src/test/ui/unsafe/ranged_ints2_const.stderr +++ b/src/test/ui/unsafe/ranged_ints2_const.stderr @@ -1,24 +1,23 @@ -error[E0017]: references in constant functions may only refer to immutable values - --> $DIR/ranged_ints2_const.rs:11:13 +error: mutable references in const fn are unstable + --> $DIR/ranged_ints2_const.rs:11:9 | -LL | let y = &mut x.0; //~ ERROR references in constant functions may only refer to immutable - | ^^^^^^^^ constant functions require immutable values +LL | let y = &mut x.0; //~ ERROR references in const fn are unstable + | ^ -error[E0017]: references in constant functions may only refer to immutable values - --> $DIR/ranged_ints2_const.rs:18:22 +error: mutable references in const fn are unstable + --> $DIR/ranged_ints2_const.rs:18:9 | -LL | let y = unsafe { &mut x.0 }; //~ ERROR references in constant functions may only refer to immut - | ^^^^^^^^ constant functions require immutable values +LL | let y = unsafe { &mut x.0 }; //~ ERROR mutable references in const fn are unstable + | ^ error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block --> $DIR/ranged_ints2_const.rs:11:13 | -LL | let y = &mut x.0; //~ ERROR references in constant functions may only refer to immutable +LL | let y = &mut x.0; //~ ERROR references in const fn are unstable | ^^^^^^^^ mutation of layout constrained field | = note: mutating layout constrained fields cannot statically be checked for valid values error: aborting due to 3 previous errors -Some errors occurred: E0017, E0133. -For more information about an error, try `rustc --explain E0017`. +For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/ranged_ints3_const.rs b/src/test/ui/unsafe/ranged_ints3_const.rs index 6497b611224b6..7b03d8eda9380 100644 --- a/src/test/ui/unsafe/ranged_ints3_const.rs +++ b/src/test/ui/unsafe/ranged_ints3_const.rs @@ -1,4 +1,4 @@ -#![feature(rustc_attrs, const_let, const_fn)] +#![feature(rustc_attrs)] use std::cell::Cell; diff --git a/src/test/ui/unsafe/ranged_ints4_const.rs b/src/test/ui/unsafe/ranged_ints4_const.rs index f589e4739baf1..f09168c3d3f9c 100644 --- a/src/test/ui/unsafe/ranged_ints4_const.rs +++ b/src/test/ui/unsafe/ranged_ints4_const.rs @@ -1,4 +1,4 @@ -#![feature(rustc_attrs, const_let, const_fn)] +#![feature(rustc_attrs)] #[rustc_layout_scalar_valid_range_start(1)] #[repr(transparent)] diff --git a/src/test/ui/where-clauses/where-equality-constraints.stderr b/src/test/ui/where-clauses/where-equality-constraints.stderr index 56caaaeee401e..220447079c629 100644 --- a/src/test/ui/where-clauses/where-equality-constraints.stderr +++ b/src/test/ui/where-clauses/where-equality-constraints.stderr @@ -1,10 +1,10 @@ -error: equality constraints are not yet supported in where clauses (#20041) +error: equality constraints are not yet supported in where clauses (see #20041) --> $DIR/where-equality-constraints.rs:1:14 | LL | fn f() where u8 = u16 {} | ^^^^^^^^ -error: equality constraints are not yet supported in where clauses (#20041) +error: equality constraints are not yet supported in where clauses (see #20041) --> $DIR/where-equality-constraints.rs:3:14 | LL | fn g() where for<'a> &'static (u8,) == u16, {} diff --git a/src/test/ui/while-let.rs b/src/test/ui/while-let.rs index 348edc15aca4c..69f9de9497740 100644 --- a/src/test/ui/while-let.rs +++ b/src/test/ui/while-let.rs @@ -1,3 +1,5 @@ +// run-pass + fn macros() { macro_rules! foo{ ($p:pat, $e:expr, $b:block) => {{ @@ -10,16 +12,17 @@ fn macros() { }} } - foo!(a, 1, { //~ ERROR irrefutable while-let + foo!(a, 1, { //~ WARN irrefutable while-let println!("irrefutable pattern"); }); - bar!(a, 1, { //~ ERROR irrefutable while-let + bar!(a, 1, { //~ WARN irrefutable while-let println!("irrefutable pattern"); }); } pub fn main() { - while let a = 1 { //~ ERROR irrefutable while-let + while let a = 1 { //~ WARN irrefutable while-let println!("irrefutable pattern"); + break; } } diff --git a/src/test/ui/while-let.stderr b/src/test/ui/while-let.stderr index 838dd8c14d7b5..6d61143d33c84 100644 --- a/src/test/ui/while-let.stderr +++ b/src/test/ui/while-let.stderr @@ -1,21 +1,33 @@ -error[E0165]: irrefutable while-let pattern - --> $DIR/while-let.rs:13:10 +warning: irrefutable while-let pattern + --> $DIR/while-let.rs:6:13 | -LL | foo!(a, 1, { //~ ERROR irrefutable while-let - | ^ irrefutable pattern - -error[E0165]: irrefutable while-let pattern - --> $DIR/while-let.rs:16:10 +LL | while let $p = $e $b + | ^^^^^ +... +LL | / foo!(a, 1, { //~ WARN irrefutable while-let +LL | | println!("irrefutable pattern"); +LL | | }); + | |_______- in this macro invocation | -LL | bar!(a, 1, { //~ ERROR irrefutable while-let - | ^ irrefutable pattern + = note: #[warn(irrefutable_let_patterns)] on by default -error[E0165]: irrefutable while-let pattern - --> $DIR/while-let.rs:22:15 +warning: irrefutable while-let pattern + --> $DIR/while-let.rs:6:13 | -LL | while let a = 1 { //~ ERROR irrefutable while-let - | ^ irrefutable pattern +LL | while let $p = $e $b + | ^^^^^ +... +LL | / bar!(a, 1, { //~ WARN irrefutable while-let +LL | | println!("irrefutable pattern"); +LL | | }); + | |_______- in this macro invocation -error: aborting due to 3 previous errors +warning: irrefutable while-let pattern + --> $DIR/while-let.rs:24:5 + | +LL | / while let a = 1 { //~ WARN irrefutable while-let +LL | | println!("irrefutable pattern"); +LL | | break; +LL | | } + | |_____^ -For more information about this error, try `rustc --explain E0165`. diff --git a/src/test/ui/write-to-static-mut-in-static.rs b/src/test/ui/write-to-static-mut-in-static.rs index 3c34a7704e0df..43c63fed8cef1 100644 --- a/src/test/ui/write-to-static-mut-in-static.rs +++ b/src/test/ui/write-to-static-mut-in-static.rs @@ -1,5 +1,3 @@ -#![feature(const_let)] - pub static mut A: u32 = 0; pub static mut B: () = unsafe { A = 1; }; //~^ ERROR could not evaluate static initializer diff --git a/src/test/ui/write-to-static-mut-in-static.stderr b/src/test/ui/write-to-static-mut-in-static.stderr index 7be83b8dafcfd..eba1c609d2f83 100644 --- a/src/test/ui/write-to-static-mut-in-static.stderr +++ b/src/test/ui/write-to-static-mut-in-static.stderr @@ -1,23 +1,23 @@ error[E0080]: could not evaluate static initializer - --> $DIR/write-to-static-mut-in-static.rs:4:33 + --> $DIR/write-to-static-mut-in-static.rs:2:33 | LL | pub static mut B: () = unsafe { A = 1; }; | ^^^^^ tried to modify a static's initial value from another static's initializer error[E0391]: cycle detected when const-evaluating `C` - --> $DIR/write-to-static-mut-in-static.rs:7:34 + --> $DIR/write-to-static-mut-in-static.rs:5:34 | LL | pub static mut C: u32 = unsafe { C = 1; 0 }; | ^^^^^ | note: ...which requires const-evaluating `C`... - --> $DIR/write-to-static-mut-in-static.rs:7:1 + --> $DIR/write-to-static-mut-in-static.rs:5:1 | LL | pub static mut C: u32 = unsafe { C = 1; 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires const-evaluating `C`, completing the cycle note: cycle used when const-evaluating + checking `C` - --> $DIR/write-to-static-mut-in-static.rs:7:1 + --> $DIR/write-to-static-mut-in-static.rs:5:1 | LL | pub static mut C: u32 = unsafe { C = 1; 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 574526c6a56a3..b00daa716777f 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -131,7 +131,8 @@ struct Manifest { manifest_version: String, date: String, pkg: BTreeMap, - renames: BTreeMap + renames: BTreeMap, + profiles: BTreeMap>, } #[derive(Serialize)] @@ -192,6 +193,7 @@ struct Builder { rustfmt_release: String, llvm_tools_release: String, lldb_release: String, + miri_release: String, input: PathBuf, output: PathBuf, @@ -207,6 +209,7 @@ struct Builder { rustfmt_version: Option, llvm_tools_version: Option, lldb_version: Option, + miri_version: Option, rust_git_commit_hash: Option, cargo_git_commit_hash: Option, @@ -215,6 +218,7 @@ struct Builder { rustfmt_git_commit_hash: Option, llvm_tools_git_commit_hash: Option, lldb_git_commit_hash: Option, + miri_git_commit_hash: Option, should_sign: bool, } @@ -237,13 +241,14 @@ fn main() { let output = PathBuf::from(args.next().unwrap()); let date = args.next().unwrap(); let rust_release = args.next().unwrap(); + let s3_address = args.next().unwrap(); let cargo_release = args.next().unwrap(); let rls_release = args.next().unwrap(); let clippy_release = args.next().unwrap(); + let miri_release = args.next().unwrap(); let rustfmt_release = args.next().unwrap(); let llvm_tools_release = args.next().unwrap(); let lldb_release = args.next().unwrap(); - let s3_address = args.next().unwrap(); // Do not ask for a passphrase while manually testing let mut passphrase = String::new(); @@ -259,6 +264,7 @@ fn main() { rustfmt_release, llvm_tools_release, lldb_release, + miri_release, input, output, @@ -274,6 +280,7 @@ fn main() { rustfmt_version: None, llvm_tools_version: None, lldb_version: None, + miri_version: None, rust_git_commit_hash: None, cargo_git_commit_hash: None, @@ -282,6 +289,7 @@ fn main() { rustfmt_git_commit_hash: None, llvm_tools_git_commit_hash: None, lldb_git_commit_hash: None, + miri_git_commit_hash: None, should_sign, }.build(); @@ -297,6 +305,7 @@ impl Builder { self.llvm_tools_version = self.version("llvm-tools", "x86_64-unknown-linux-gnu"); // lldb is only built for macOS. self.lldb_version = self.version("lldb", "x86_64-apple-darwin"); + self.miri_version = self.version("miri", "x86_64-unknown-linux-gnu"); self.rust_git_commit_hash = self.git_commit_hash("rust", "x86_64-unknown-linux-gnu"); self.cargo_git_commit_hash = self.git_commit_hash("cargo", "x86_64-unknown-linux-gnu"); @@ -306,6 +315,7 @@ impl Builder { self.llvm_tools_git_commit_hash = self.git_commit_hash("llvm-tools", "x86_64-unknown-linux-gnu"); self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu"); + self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu"); self.digest_and_sign(); let manifest = self.build_manifest(); @@ -331,6 +341,7 @@ impl Builder { date: self.date.to_string(), pkg: BTreeMap::new(), renames: BTreeMap::new(), + profiles: BTreeMap::new(), }; self.package("rustc", &mut manifest.pkg, HOSTS); @@ -346,6 +357,20 @@ impl Builder { self.package("llvm-tools-preview", &mut manifest.pkg, TARGETS); self.package("lldb-preview", &mut manifest.pkg, TARGETS); + self.profile("minimal", + &mut manifest.profiles, + &["rustc", "cargo", "rust-std", "rust-mingw"]); + self.profile("default", + &mut manifest.profiles, + &["rustc", "cargo", "rust-std", "rust-mingw", + "rust-docs", "rustfmt-preview", "clippy-preview"]); + self.profile("complete", + &mut manifest.profiles, + &["rustc", "cargo", "rust-std", "rust-mingw", + "rust-docs", "rustfmt-preview", "clippy-preview", + "rls-preview", "rust-src", "llvm-tools-preview", + "lldb-preview", "rust-analysis"]); + manifest.renames.insert("rls".to_owned(), Rename { to: "rls-preview".to_owned() }); manifest.renames.insert("rustfmt".to_owned(), Rename { to: "rustfmt-preview".to_owned() }); manifest.renames.insert("clippy".to_owned(), Rename { to: "clippy-preview".to_owned() }); @@ -444,6 +469,13 @@ impl Builder { return manifest; } + fn profile(&mut self, + profile_name: &str, + dst: &mut BTreeMap>, + pkgs: &[&str]) { + dst.insert(profile_name.to_owned(), pkgs.iter().map(|s| (*s).to_owned()).collect()); + } + fn package(&mut self, pkgname: &str, dst: &mut BTreeMap, @@ -516,6 +548,8 @@ impl Builder { format!("llvm-tools-{}-{}.tar.gz", self.llvm_tools_release, target) } else if component == "lldb" || component == "lldb-preview" { format!("lldb-{}-{}.tar.gz", self.lldb_release, target) + } else if component == "miri" || component == "miri-preview" { + format!("miri-{}-{}.tar.gz", self.miri_release, target) } else { format!("{}-{}-{}.tar.gz", component, self.rust_release, target) } @@ -534,6 +568,8 @@ impl Builder { &self.llvm_tools_version } else if component == "lldb" || component == "lldb-preview" { &self.lldb_version + } else if component == "miri" || component == "miri-preview" { + &self.miri_version } else { &self.rust_version } @@ -552,6 +588,8 @@ impl Builder { &self.llvm_tools_git_commit_hash } else if component == "lldb" || component == "lldb-preview" { &self.lldb_git_commit_hash + } else if component == "miri" || component == "miri-preview" { + &self.miri_git_commit_hash } else { &self.rust_git_commit_hash } diff --git a/src/tools/miri b/src/tools/miri index 2e2a33aab8972..97f4cff8e904c 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 2e2a33aab897273a36498d526530f648d6113dc8 +Subproject commit 97f4cff8e904c268569d37922a27835209deff5d