diff --git a/Cargo.lock b/Cargo.lock index 8993254627863..5adaa8decc73a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,7 +17,7 @@ dependencies = [ name = "alloc" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -44,6 +44,11 @@ dependencies = [ "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "annotate-snippets" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ansi_term" version = "0.11.0" @@ -97,20 +102,14 @@ dependencies = [ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "autocfg" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "backtrace" -version = "0.3.29" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", @@ -118,11 +117,11 @@ dependencies = [ [[package]] name = "backtrace-sys" -version = "0.1.27" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -335,7 +334,7 @@ name = "cfg-if" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -464,7 +463,7 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -795,7 +794,7 @@ name = "dlmalloc" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -868,7 +867,7 @@ name = "error-chain" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -883,7 +882,7 @@ name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -960,7 +959,7 @@ name = "fortanix-sgx-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -1137,7 +1136,7 @@ name = "hashbrown" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-alloc 1.0.0", "rustc-std-workspace-core 1.0.0", ] @@ -1955,7 +1954,7 @@ dependencies = [ name = "panic_abort" version = "0.0.0" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1966,7 +1965,7 @@ version = "0.0.0" dependencies = [ "alloc 0.0.0", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", "unwind 0.0.0", @@ -2137,7 +2136,7 @@ name = "profiler_builtins" version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2513,7 +2512,7 @@ name = "rustc" version = "0.0.0" dependencies = [ "arena 0.0.0", - "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "chalk-engine 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2674,7 +2673,7 @@ name = "rustc-demangle" version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-std-workspace-core 1.0.0", ] @@ -2766,7 +2765,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -2895,7 +2894,7 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ - "annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "annotate-snippets 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_data_structures 0.0.0", @@ -2988,7 +2987,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3051,7 +3050,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3169,7 +3168,7 @@ dependencies = [ "alloc 0.0.0", "build_helper 0.1.0", "cmake 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", ] @@ -3473,10 +3472,10 @@ name = "std" version = "0.0.0" dependencies = [ "alloc 0.0.0", - "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4103,7 +4102,7 @@ version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4284,15 +4283,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" "checksum ammonia 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "384d704f242a0a9faf793fff775a0be6ab9aa27edabffa097331d73779142520" "checksum annotate-snippets 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e8bcdcd5b291ce85a78f2b9d082a8de9676c12b1840d386d67bc5eea6f9d2b4e" +"checksum annotate-snippets 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7021ce4924a3f25f802b2cccd1af585e39ea1a363a1aa2e72afe54b67a3a7a7" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" "checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392" "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf" -"checksum backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)" = "2d631cd7af21b7ff796293f1990104e3cdb606852863bac32f000c193aa35dfb" -"checksum backtrace-sys 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)" = "6ea90dd7b012b3d1a2cb6bec16670a0db2c95d4e931e84f4047e0460c1b34c8d" +"checksum backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "88fb679bc9af8fa639198790a77f52d345fe13656c08b43afa9424c206b731c6" +"checksum backtrace-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "5b3a000b9c543553af61bc01cbfc403b04b5caa9e421033866f2e98061eb3e61" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" @@ -4317,7 +4316,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum colored 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b0aa3473e85a3161b59845d6096b289bb577874cafeaf75ea1b1beaa6572c7fc" "checksum commoncrypto 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" "checksum commoncrypto-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" -"checksum compiler_builtins 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "ad9b4731b9e701aefe9e6bd1e9173f30526661508f9aaadaa5caec25ddf95585" +"checksum compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1c086a06d6f52f9c0d50cacdc021bfb6034ddeec9fb7e62f099f13f65472f4" "checksum compiletest_rs 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "f40ecc9332b68270998995c00f8051ee856121764a0d3230e64c9efd059d27b6" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887" diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 9995d2aac7f24..2191d5d6e4680 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -112,7 +112,7 @@ $COMMIT\t$(cat "$TOOLSTATE_FILE") } if [ "$RUST_RELEASE_CHANNEL" = nightly ]; then - if [ -n "${TOOLSTATE_REPO_ACCESS_TOKEN+is_set}" ]; then + if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then . "$(dirname $0)/repo.sh" MESSAGE_FILE=$(mktemp -t msg.XXXXXX) echo "($OS CI update)" > "$MESSAGE_FILE" diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 33d6afdc975ee..abc8883d3985f 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -136,7 +136,7 @@ #![stable(feature = "rust1", since = "1.0.0")] use crate::iter::{FromIterator, FusedIterator, TrustedLen}; -use crate::{convert, fmt, hint, mem, ops::{self, Deref}}; +use crate::{convert, fmt, hint, mem, ops::{self, Deref, DerefMut}}; use crate::pin::Pin; // Note that this is not a lang item per se, but it has a hidden dependency on @@ -1104,17 +1104,28 @@ impl Option { #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Option { - /// Converts from `&Option` to `Option<&T::Target>`. + /// Converts from `Option` (or `&Option`) to `Option<&T::Target>`. /// /// Leaves the original Option in-place, creating a new one with a reference /// to the original one, additionally coercing the contents via [`Deref`]. /// /// [`Deref`]: ../../std/ops/trait.Deref.html - pub fn deref(&self) -> Option<&T::Target> { + pub fn as_deref(&self) -> Option<&T::Target> { self.as_ref().map(|t| t.deref()) } } +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Option { + /// Converts from `Option` (or `&mut Option`) to `Option<&mut T::Target>`. + /// + /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to + /// the inner type's `Deref::Target` type. + pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> { + self.as_mut().map(|t| t.deref_mut()) + } +} + impl Option> { /// Transposes an `Option` of a [`Result`] into a [`Result`] of an `Option`. /// diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 3a38b66ad0150..cb6bc058730d1 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -232,7 +232,7 @@ use crate::fmt; use crate::iter::{FromIterator, FusedIterator, TrustedLen}; -use crate::ops::{self, Deref}; +use crate::ops::{self, Deref, DerefMut}; /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). /// @@ -981,24 +981,22 @@ impl Result { #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Result { - /// Converts from `&Result` to `Result<&T::Target, &E>`. + /// Converts from `Result` (or `&Result`) to `Result<&T::Target, &E>`. /// - /// Leaves the original Result in-place, creating a new one with a reference - /// to the original one, additionally coercing the `Ok` arm of the Result via - /// `Deref`. - pub fn deref_ok(&self) -> Result<&T::Target, &E> { + /// Leaves the original `Result` in-place, creating a new one containing a reference to the + /// `Ok` type's `Deref::Target` type. + pub fn as_deref_ok(&self) -> Result<&T::Target, &E> { self.as_ref().map(|t| t.deref()) } } #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Result { - /// Converts from `&Result` to `Result<&T, &E::Target>`. + /// Converts from `Result` (or `&Result`) to `Result<&T, &E::Target>`. /// - /// Leaves the original Result in-place, creating a new one with a reference - /// to the original one, additionally coercing the `Err` arm of the Result via - /// `Deref`. - pub fn deref_err(&self) -> Result<&T, &E::Target> + /// Leaves the original `Result` in-place, creating a new one containing a reference to the + /// `Err` type's `Deref::Target` type. + pub fn as_deref_err(&self) -> Result<&T, &E::Target> { self.as_ref().map_err(|e| e.deref()) } @@ -1006,17 +1004,52 @@ impl Result { #[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] impl Result { - /// Converts from `&Result` to `Result<&T::Target, &E::Target>`. + /// Converts from `Result` (or `&Result`) to `Result<&T::Target, &E::Target>`. /// - /// Leaves the original Result in-place, creating a new one with a reference - /// to the original one, additionally coercing both the `Ok` and `Err` arms - /// of the Result via `Deref`. - pub fn deref(&self) -> Result<&T::Target, &E::Target> + /// Leaves the original `Result` in-place, creating a new one containing a reference to both + /// the `Ok` and `Err` types' `Deref::Target` types. + pub fn as_deref(&self) -> Result<&T::Target, &E::Target> { self.as_ref().map(|t| t.deref()).map_err(|e| e.deref()) } } +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Result { + /// Converts from `Result` (or `&mut Result`) to `Result<&mut T::Target, &mut E>`. + /// + /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to + /// the `Ok` type's `Deref::Target` type. + pub fn as_deref_mut_ok(&mut self) -> Result<&mut T::Target, &mut E> { + self.as_mut().map(|t| t.deref_mut()) + } +} + +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Result { + /// Converts from `Result` (or `&mut Result`) to `Result<&mut T, &mut E::Target>`. + /// + /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to + /// the `Err` type's `Deref::Target` type. + pub fn as_deref_mut_err(&mut self) -> Result<&mut T, &mut E::Target> + { + self.as_mut().map_err(|e| e.deref_mut()) + } +} + +#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")] +impl Result { + /// Converts from `Result` (or `&mut Result`) to + /// `Result<&mut T::Target, &mut E::Target>`. + /// + /// Leaves the original `Result` in-place, creating a new one containing a mutable reference to + /// both the `Ok` and `Err` types' `Deref::Target` types. + pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E::Target> + { + self.as_mut().map(|t| t.deref_mut()).map_err(|e| e.deref_mut()) + } +} + impl Result, E> { /// Transposes a `Result` of an `Option` into an `Option` of a `Result`. /// diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index b059b134868d9..ff43fc49f71e3 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -1,6 +1,8 @@ use core::option::*; use core::mem; use core::clone::Clone; +use core::array::FixedSizeArray; +use core::ops::DerefMut; #[test] fn test_get_ptr() { @@ -310,20 +312,38 @@ fn test_try() { } #[test] -fn test_option_deref() { +fn test_option_as_deref() { // Some: &Option::Some(T) -> Option<&T::Deref::Target>::Some(&*T) let ref_option = &Some(&42); - assert_eq!(ref_option.deref(), Some(&42)); + assert_eq!(ref_option.as_deref(), Some(&42)); let ref_option = &Some(String::from("a result")); - assert_eq!(ref_option.deref(), Some("a result")); + assert_eq!(ref_option.as_deref(), Some("a result")); let ref_option = &Some(vec![1, 2, 3, 4, 5]); - assert_eq!(ref_option.deref(), Some(&[1, 2, 3, 4, 5][..])); + assert_eq!(ref_option.as_deref(), Some([1, 2, 3, 4, 5].as_slice())); // None: &Option>::None -> None let ref_option: &Option<&i32> = &None; - assert_eq!(ref_option.deref(), None); + assert_eq!(ref_option.as_deref(), None); +} + +#[test] +fn test_option_as_deref_mut() { + // Some: &mut Option::Some(T) -> Option<&mut T::Deref::Target>::Some(&mut *T) + let mut val = 42; + let ref_option = &mut Some(&mut val); + assert_eq!(ref_option.as_deref_mut(), Some(&mut 42)); + + let ref_option = &mut Some(String::from("a result")); + assert_eq!(ref_option.as_deref_mut(), Some(String::from("a result").deref_mut())); + + let ref_option = &mut Some(vec![1, 2, 3, 4, 5]); + assert_eq!(ref_option.as_deref_mut(), Some([1, 2, 3, 4, 5].as_mut_slice())); + + // None: &mut Option>::None -> None + let ref_option: &mut Option<&mut i32> = &mut None; + assert_eq!(ref_option.as_deref_mut(), None); } #[test] diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index 1fab07526a07f..163f8d0ab3797 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -1,4 +1,6 @@ use core::option::*; +use core::array::FixedSizeArray; +use core::ops::DerefMut; fn op1() -> Result { Ok(666) } fn op2() -> Result { Err("sadface") } @@ -225,94 +227,213 @@ fn test_try() { } #[test] -fn test_result_deref() { - // &Result::Ok(T).deref_ok() -> +fn test_result_as_deref() { + // &Result::Ok(T).as_deref_ok() -> // Result<&T::Deref::Target, &E>::Ok(&*T) let ref_ok = &Result::Ok::<&i32, u8>(&42); let expected_result = Result::Ok::<&i32, &u8>(&42); - assert_eq!(ref_ok.deref_ok(), expected_result); + assert_eq!(ref_ok.as_deref_ok(), expected_result); let ref_ok = &Result::Ok::(String::from("a result")); let expected_result = Result::Ok::<&str, &u32>("a result"); - assert_eq!(ref_ok.deref_ok(), expected_result); + assert_eq!(ref_ok.as_deref_ok(), expected_result); let ref_ok = &Result::Ok::, u32>(vec![1, 2, 3, 4, 5]); - let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]); - assert_eq!(ref_ok.deref_ok(), expected_result); + let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice()); + assert_eq!(ref_ok.as_deref_ok(), expected_result); - // &Result::Ok(T).deref() -> + // &Result::Ok(T).as_deref() -> // Result<&T::Deref::Target, &E::Deref::Target>::Ok(&*T) let ref_ok = &Result::Ok::<&i32, &u8>(&42); let expected_result = Result::Ok::<&i32, &u8>(&42); - assert_eq!(ref_ok.deref(), expected_result); + assert_eq!(ref_ok.as_deref(), expected_result); let ref_ok = &Result::Ok::(String::from("a result")); let expected_result = Result::Ok::<&str, &u32>("a result"); - assert_eq!(ref_ok.deref(), expected_result); + assert_eq!(ref_ok.as_deref(), expected_result); let ref_ok = &Result::Ok::, &u32>(vec![1, 2, 3, 4, 5]); - let expected_result = Result::Ok::<&[i32], &u32>(&[1, 2, 3, 4, 5][..]); - assert_eq!(ref_ok.deref(), expected_result); + let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice()); + assert_eq!(ref_ok.as_deref(), expected_result); - // &Result::Err(T).deref_err() -> + // &Result::Err(T).as_deref_err() -> // Result<&T, &E::Deref::Target>::Err(&*E) let ref_err = &Result::Err::(&41); let expected_result = Result::Err::<&u8, &i32>(&41); - assert_eq!(ref_err.deref_err(), expected_result); + assert_eq!(ref_err.as_deref_err(), expected_result); let ref_err = &Result::Err::(String::from("an error")); let expected_result = Result::Err::<&u32, &str>("an error"); - assert_eq!(ref_err.deref_err(), expected_result); + assert_eq!(ref_err.as_deref_err(), expected_result); let ref_err = &Result::Err::>(vec![5, 4, 3, 2, 1]); - let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]); - assert_eq!(ref_err.deref_err(), expected_result); + let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice()); + assert_eq!(ref_err.as_deref_err(), expected_result); - // &Result::Err(T).deref_err() -> + // &Result::Err(T).as_deref_err() -> // Result<&T, &E::Deref::Target>::Err(&*E) let ref_err = &Result::Err::<&u8, &i32>(&41); let expected_result = Result::Err::<&u8, &i32>(&41); - assert_eq!(ref_err.deref(), expected_result); + assert_eq!(ref_err.as_deref(), expected_result); let ref_err = &Result::Err::<&u32, String>(String::from("an error")); let expected_result = Result::Err::<&u32, &str>("an error"); - assert_eq!(ref_err.deref(), expected_result); + assert_eq!(ref_err.as_deref(), expected_result); let ref_err = &Result::Err::<&u32, Vec>(vec![5, 4, 3, 2, 1]); - let expected_result = Result::Err::<&u32, &[i32]>(&[5, 4, 3, 2, 1][..]); - assert_eq!(ref_err.deref(), expected_result); + let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice()); + assert_eq!(ref_err.as_deref(), expected_result); - // The following cases test calling deref_* with the wrong variant (i.e. - // `deref_ok()` with a `Result::Err()`, or `deref_err()` with a `Result::Ok()`. - // While unusual, these cases are supported to ensure that an `inner_deref` + // The following cases test calling `as_deref_*` with the wrong variant (i.e. + // `as_deref_ok()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`. + // While uncommon, these cases are supported to ensure that an `as_deref_*` // call can still be made even when one of the Result types does not implement // `Deref` (for example, std::io::Error). - // &Result::Ok(T).deref_err() -> + // &Result::Ok(T).as_deref_err() -> // Result<&T, &E::Deref::Target>::Ok(&T) let ref_ok = &Result::Ok::(42); let expected_result = Result::Ok::<&i32, &u8>(&42); - assert_eq!(ref_ok.deref_err(), expected_result); + assert_eq!(ref_ok.as_deref_err(), expected_result); let ref_ok = &Result::Ok::<&str, &u32>("a result"); let expected_result = Result::Ok::<&&str, &u32>(&"a result"); - assert_eq!(ref_ok.deref_err(), expected_result); + assert_eq!(ref_ok.as_deref_err(), expected_result); let ref_ok = &Result::Ok::<[i32; 5], &u32>([1, 2, 3, 4, 5]); let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]); - assert_eq!(ref_ok.deref_err(), expected_result); + assert_eq!(ref_ok.as_deref_err(), expected_result); - // &Result::Err(E).deref_ok() -> + // &Result::Err(E).as_deref_ok() -> // Result<&T::Deref::Target, &E>::Err(&E) let ref_err = &Result::Err::<&u8, i32>(41); let expected_result = Result::Err::<&u8, &i32>(&41); - assert_eq!(ref_err.deref_ok(), expected_result); + assert_eq!(ref_err.as_deref_ok(), expected_result); let ref_err = &Result::Err::<&u32, &str>("an error"); let expected_result = Result::Err::<&u32, &&str>(&"an error"); - assert_eq!(ref_err.deref_ok(), expected_result); + assert_eq!(ref_err.as_deref_ok(), expected_result); let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]); let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]); - assert_eq!(ref_err.deref_ok(), expected_result); + assert_eq!(ref_err.as_deref_ok(), expected_result); +} + +#[test] +fn test_result_as_deref_mut() { + // &mut Result::Ok(T).as_deref_mut_ok() -> + // Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T) + let mut val = 42; + let mut expected_val = 42; + let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val); + let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val); + assert_eq!(mut_ok.as_deref_mut_ok(), expected_result); + + let mut expected_string = String::from("a result"); + let mut_ok = &mut Result::Ok::(expected_string.clone()); + let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut()); + assert_eq!(mut_ok.as_deref_mut_ok(), expected_result); + + let mut expected_vec = vec![1, 2, 3, 4, 5]; + let mut_ok = &mut Result::Ok::, u32>(expected_vec.clone()); + let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice()); + assert_eq!(mut_ok.as_deref_mut_ok(), expected_result); + + // &mut Result::Ok(T).as_deref_mut() -> + // Result<&mut T::Deref::Target, &mut E::Deref::Target>::Ok(&mut *T) + let mut val = 42; + let mut expected_val = 42; + let mut_ok = &mut Result::Ok::<&mut i32, &mut u8>(&mut val); + let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val); + assert_eq!(mut_ok.as_deref_mut(), expected_result); + + let mut expected_string = String::from("a result"); + let mut_ok = &mut Result::Ok::(expected_string.clone()); + let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut()); + assert_eq!(mut_ok.as_deref_mut(), expected_result); + + let mut expected_vec = vec![1, 2, 3, 4, 5]; + let mut_ok = &mut Result::Ok::, &mut u32>(expected_vec.clone()); + let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice()); + assert_eq!(mut_ok.as_deref_mut(), expected_result); + + // &mut Result::Err(T).as_deref_mut_err() -> + // Result<&mut T, &mut E::Deref::Target>::Err(&mut *E) + let mut val = 41; + let mut expected_val = 41; + let mut_err = &mut Result::Err::(&mut val); + let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); + assert_eq!(mut_err.as_deref_mut_err(), expected_result); + + let mut expected_string = String::from("an error"); + let mut_err = &mut Result::Err::(expected_string.clone()); + let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.deref_mut()); + assert_eq!(mut_err.as_deref_mut_err(), expected_result); + + let mut expected_vec = vec![5, 4, 3, 2, 1]; + let mut_err = &mut Result::Err::>(expected_vec.clone()); + let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice()); + assert_eq!(mut_err.as_deref_mut_err(), expected_result); + + // &mut Result::Err(T).as_deref_mut_err() -> + // Result<&mut T, &mut E::Deref::Target>::Err(&mut *E) + let mut val = 41; + let mut expected_val = 41; + let mut_err = &mut Result::Err::<&mut u8, &mut i32>(&mut val); + let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); + assert_eq!(mut_err.as_deref_mut(), expected_result); + + let mut expected_string = String::from("an error"); + let mut_err = &mut Result::Err::<&mut u32, String>(expected_string.clone()); + let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.as_mut_str()); + assert_eq!(mut_err.as_deref_mut(), expected_result); + + let mut expected_vec = vec![5, 4, 3, 2, 1]; + let mut_err = &mut Result::Err::<&mut u32, Vec>(expected_vec.clone()); + let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice()); + assert_eq!(mut_err.as_deref_mut(), expected_result); + + // The following cases test calling `as_deref_mut_*` with the wrong variant (i.e. + // `as_deref_mut_ok()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`. + // While uncommon, these cases are supported to ensure that an `as_deref_mut_*` + // call can still be made even when one of the Result types does not implement + // `Deref` (for example, std::io::Error). + + // &mut Result::Ok(T).as_deref_mut_err() -> + // Result<&mut T, &mut E::Deref::Target>::Ok(&mut T) + let mut expected_val = 42; + let mut_ok = &mut Result::Ok::(expected_val.clone()); + let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val); + assert_eq!(mut_ok.as_deref_mut_err(), expected_result); + + let string = String::from("a result"); + let expected_string = string.clone(); + let mut ref_str = expected_string.as_ref(); + let mut_ok = &mut Result::Ok::<&str, &mut u32>(string.as_str()); + let expected_result = Result::Ok::<&mut &str, &mut u32>(&mut ref_str); + assert_eq!(mut_ok.as_deref_mut_err(), expected_result); + + let mut expected_arr = [1, 2, 3, 4, 5]; + let mut_ok = &mut Result::Ok::<[i32; 5], &mut u32>(expected_arr.clone()); + let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr); + assert_eq!(mut_ok.as_deref_mut_err(), expected_result); + + // &mut Result::Err(E).as_deref_mut_ok() -> + // Result<&mut T::Deref::Target, &mut E>::Err(&mut E) + let mut expected_val = 41; + let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone()); + let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val); + assert_eq!(mut_err.as_deref_mut_ok(), expected_result); + + let string = String::from("an error"); + let expected_string = string.clone(); + let mut ref_str = expected_string.as_ref(); + let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str()); + let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str); + assert_eq!(mut_err.as_deref_mut_ok(), expected_result); + + let mut expected_arr = [5, 4, 3, 2, 1]; + let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone()); + let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr); + assert_eq!(mut_err.as_deref_mut_ok(), expected_result); } diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs index a793ac3eb74b0..bfe784afaa47d 100644 --- a/src/libcore/unicode/tables.rs +++ b/src/libcore/unicode/tables.rs @@ -1,6 +1,6 @@ // NOTE: The following code was generated by "./unicode.py", do not edit directly -#![allow(missing_docs, non_upper_case_globals, non_snake_case)] +#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] use crate::unicode::version::UnicodeVersion; use crate::unicode::bool_trie::{BoolTrie, SmallBoolTrie}; diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py index 3a20d0548c15f..5389d1cf80383 100755 --- a/src/libcore/unicode/unicode.py +++ b/src/libcore/unicode/unicode.py @@ -79,7 +79,7 @@ class UnicodeFiles(object): PREAMBLE = """\ // NOTE: The following code was generated by "./unicode.py", do not edit directly -#![allow(missing_docs, non_upper_case_globals, non_snake_case)] +#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] use crate::unicode::version::UnicodeVersion; use crate::unicode::bool_trie::{{BoolTrie, SmallBoolTrie}}; diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 3e571baaa4e51..da4a25e0860b1 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -941,7 +941,7 @@ impl<'a> State<'a> { self.maybe_print_comment(st.span.lo()); match st.node { hir::StmtKind::Local(ref loc) => { - self.print_local(loc.init.deref(), |this| this.print_local_decl(&loc)); + self.print_local(loc.init.as_deref(), |this| this.print_local_decl(&loc)); } hir::StmtKind::Item(item) => { self.ann.nested(self, Nested::Item(item)) diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index bdd48b3447498..cc09a0b20cfd5 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -367,34 +367,6 @@ language_item_table! { DebugTraitLangItem, "debug_trait", debug_trait, Target::Trait; - // A lang item for each of the 128-bit operators we can optionally lower. - I128AddFnLangItem, "i128_add", i128_add_fn, Target::Fn; - U128AddFnLangItem, "u128_add", u128_add_fn, Target::Fn; - I128SubFnLangItem, "i128_sub", i128_sub_fn, Target::Fn; - U128SubFnLangItem, "u128_sub", u128_sub_fn, Target::Fn; - I128MulFnLangItem, "i128_mul", i128_mul_fn, Target::Fn; - U128MulFnLangItem, "u128_mul", u128_mul_fn, Target::Fn; - I128DivFnLangItem, "i128_div", i128_div_fn, Target::Fn; - U128DivFnLangItem, "u128_div", u128_div_fn, Target::Fn; - I128RemFnLangItem, "i128_rem", i128_rem_fn, Target::Fn; - U128RemFnLangItem, "u128_rem", u128_rem_fn, Target::Fn; - I128ShlFnLangItem, "i128_shl", i128_shl_fn, Target::Fn; - U128ShlFnLangItem, "u128_shl", u128_shl_fn, Target::Fn; - I128ShrFnLangItem, "i128_shr", i128_shr_fn, Target::Fn; - U128ShrFnLangItem, "u128_shr", u128_shr_fn, Target::Fn; - // And overflow versions for the operators that are checkable. - // While MIR calls these Checked*, they return (T,bool), not Option. - I128AddoFnLangItem, "i128_addo", i128_addo_fn, Target::Fn; - U128AddoFnLangItem, "u128_addo", u128_addo_fn, Target::Fn; - I128SuboFnLangItem, "i128_subo", i128_subo_fn, Target::Fn; - U128SuboFnLangItem, "u128_subo", u128_subo_fn, Target::Fn; - I128MuloFnLangItem, "i128_mulo", i128_mulo_fn, Target::Fn; - U128MuloFnLangItem, "u128_mulo", u128_mulo_fn, Target::Fn; - I128ShloFnLangItem, "i128_shlo", i128_shlo_fn, Target::Fn; - U128ShloFnLangItem, "u128_shlo", u128_shlo_fn, Target::Fn; - I128ShroFnLangItem, "i128_shro", i128_shro_fn, Target::Fn; - U128ShroFnLangItem, "u128_shro", u128_shro_fn, Target::Fn; - // Align offset for stride != 1, must not panic. AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn; diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 9a8429733d103..74653d4fbda73 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1406,10 +1406,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, saturating_float_casts: bool = (false, parse_bool, [TRACKED], "make float->int casts UB-free: numbers outside the integer type's range are clipped to \ the max/min integer respectively, and NaN is mapped to 0"), - lower_128bit_ops: Option = (None, parse_opt_bool, [TRACKED], - "rewrite operators on i128 and u128 into lang item calls (typically provided \ - by compiler-builtins) so codegen doesn't need to support them, - overriding the default for the current target"), human_readable_cgu_names: bool = (false, parse_bool, [TRACKED], "generate human-readable, predictable names for codegen units"), dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED], diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index f1550b9d756a5..46b8114030f29 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,7 +21,7 @@ use crate::middle::cstore::EncodedMetadata; use crate::middle::lang_items; use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault}; use crate::middle::stability; -use crate::mir::{self, Body, interpret, ProjectionKind}; +use crate::mir::{Body, interpret, ProjectionKind}; use crate::mir::interpret::{ConstValue, Allocation, Scalar}; use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst}; use crate::ty::ReprOptions; @@ -1297,40 +1297,6 @@ impl<'tcx> TyCtxt<'tcx> { self.get_lang_items(LOCAL_CRATE) } - /// Due to missing llvm support for lowering 128 bit math to software emulation - /// (on some targets), the lowering can be done in MIR. - /// - /// This function only exists until said support is implemented. - pub fn is_binop_lang_item(&self, def_id: DefId) -> Option<(mir::BinOp, bool)> { - let items = self.lang_items(); - let def_id = Some(def_id); - if items.i128_add_fn() == def_id { Some((mir::BinOp::Add, false)) } - else if items.u128_add_fn() == def_id { Some((mir::BinOp::Add, false)) } - else if items.i128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) } - else if items.u128_sub_fn() == def_id { Some((mir::BinOp::Sub, false)) } - else if items.i128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) } - else if items.u128_mul_fn() == def_id { Some((mir::BinOp::Mul, false)) } - else if items.i128_div_fn() == def_id { Some((mir::BinOp::Div, false)) } - else if items.u128_div_fn() == def_id { Some((mir::BinOp::Div, false)) } - else if items.i128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) } - else if items.u128_rem_fn() == def_id { Some((mir::BinOp::Rem, false)) } - else if items.i128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) } - else if items.u128_shl_fn() == def_id { Some((mir::BinOp::Shl, false)) } - else if items.i128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) } - else if items.u128_shr_fn() == def_id { Some((mir::BinOp::Shr, false)) } - else if items.i128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) } - else if items.u128_addo_fn() == def_id { Some((mir::BinOp::Add, true)) } - else if items.i128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) } - else if items.u128_subo_fn() == def_id { Some((mir::BinOp::Sub, true)) } - else if items.i128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) } - else if items.u128_mulo_fn() == def_id { Some((mir::BinOp::Mul, true)) } - else if items.i128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) } - else if items.u128_shlo_fn() == def_id { Some((mir::BinOp::Shl, true)) } - else if items.i128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) } - else if items.u128_shro_fn() == def_id { Some((mir::BinOp::Shr, true)) } - else { None } - } - pub fn stability(self) -> &'tcx stability::Index<'tcx> { self.stability_index(LOCAL_CRATE) } diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index 4ed52a1e96638..3b4b814c92a90 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -246,6 +246,14 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let align = a.value.align(dl).max(b_align).max(dl.aggregate_align); let b_offset = a.value.size(dl).align_to(b_align.abi); let size = (b_offset + b.value.size(dl)).align_to(align.abi); + + // HACK(nox): We iter on `b` and then `a` because `max_by_key` + // returns the last maximum. + let largest_niche = Niche::from_scalar(dl, b_offset, b.clone()) + .into_iter() + .chain(Niche::from_scalar(dl, Size::ZERO, a.clone())) + .max_by_key(|niche| niche.available(dl)); + LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Arbitrary { @@ -253,6 +261,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { memory_index: vec![0, 1] }, abi: Abi::ScalarPair(a, b), + largest_niche, align, size } @@ -321,6 +330,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let mut offset = Size::ZERO; + let mut largest_niche = None; + let mut largest_niche_available = 0; if let StructKind::Prefixed(prefix_size, prefix_align) = kind { let prefix_align = if packed { @@ -355,6 +366,15 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { debug!("univariant offset: {:?} field: {:#?}", offset, field); offsets[i as usize] = offset; + if let Some(mut niche) = field.largest_niche.clone() { + let available = niche.available(dl); + if available > largest_niche_available { + largest_niche_available = available; + niche.offset += offset; + largest_niche = Some(niche); + } + } + offset = offset.checked_add(field.size, dl) .ok_or(LayoutError::SizeOverflow(ty))?; } @@ -466,6 +486,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { memory_index }, abi, + largest_niche, align, size }) @@ -525,6 +546,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Union(0), abi: Abi::Uninhabited, + largest_niche: None, align: dl.i8_align, size: Size::ZERO }) @@ -583,6 +605,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { Abi::Aggregate { sized: true } }; + let largest_niche = if count != 0 { + element.largest_niche.clone() + } else { + None + }; + tcx.intern_layout(LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Array { @@ -590,6 +618,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { count }, abi, + largest_niche, align: element.align, size }) @@ -603,6 +632,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { count: 0 }, abi: Abi::Aggregate { sized: false }, + largest_niche: None, align: element.align, size: Size::ZERO }) @@ -615,6 +645,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { count: 0 }, abi: Abi::Aggregate { sized: false }, + largest_niche: None, align: dl.i8_align, size: Size::ZERO }) @@ -683,6 +714,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { element: scalar, count }, + largest_niche: element.largest_niche.clone(), size, align, }) @@ -768,6 +800,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { variants: Variants::Single { index }, fields: FieldPlacement::Union(variants[index].len()), abi, + largest_niche: None, align, size: size.align_to(align.abi) })); @@ -829,14 +862,38 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // `#[rustc_layout_scalar_valid_range(n)]` // attribute to widen the range of anything as that would probably // result in UB somewhere + // FIXME(eddyb) the asserts are probably not needed, + // as larger validity ranges would result in missed + // optimizations, *not* wrongly assuming the inner + // value is valid. e.g. unions enlarge validity ranges, + // because the values may be uninitialized. if let Bound::Included(start) = start { + // FIXME(eddyb) this might be incorrect - it doesn't + // account for wrap-around (end < start) ranges. assert!(*scalar.valid_range.start() <= start); scalar.valid_range = start..=*scalar.valid_range.end(); } if let Bound::Included(end) = end { + // FIXME(eddyb) this might be incorrect - it doesn't + // account for wrap-around (end < start) ranges. assert!(*scalar.valid_range.end() >= end); scalar.valid_range = *scalar.valid_range.start()..=end; } + + // Update `largest_niche` if we have introduced a larger niche. + let niche = Niche::from_scalar(dl, Size::ZERO, scalar.clone()); + if let Some(niche) = niche { + match &st.largest_niche { + Some(largest_niche) => { + // Replace the existing niche even if they're equal, + // because this one is at a lower offset. + if largest_niche.available(dl) <= niche.available(dl) { + st.largest_niche = Some(niche); + } + } + None => st.largest_niche = Some(niche), + } + } } _ => assert!( start == Bound::Unbounded && end == Bound::Unbounded, @@ -845,6 +902,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { st, ), } + return Ok(tcx.intern_layout(st)); } @@ -886,8 +944,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { let count = ( niche_variants.end().as_u32() - niche_variants.start().as_u32() + 1 ) as u128; + // FIXME(#62691) use the largest niche across all fields, + // not just the first one. for (field_index, &field) in variants[i].iter().enumerate() { - let niche = match self.find_niche(field)? { + let niche = match &field.largest_niche { Some(niche) => niche, _ => continue, }; @@ -937,6 +997,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { abi = Abi::Uninhabited; } + + let largest_niche = + Niche::from_scalar(dl, offset, niche_scalar.clone()); + return Ok(tcx.intern_layout(LayoutDetails { variants: Variants::Multiple { discr: niche_scalar, @@ -953,6 +1017,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { memory_index: vec![0] }, abi, + largest_niche, size, align, })); @@ -1164,6 +1229,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { abi = Abi::Uninhabited; } + let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag.clone()); + tcx.intern_layout(LayoutDetails { variants: Variants::Multiple { discr: tag, @@ -1175,6 +1242,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { offsets: vec![Size::ZERO], memory_index: vec![0] }, + largest_niche, abi, align, size @@ -1332,16 +1400,31 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { // locals as part of the prefix. We compute the layout of all of // these fields at once to get optimal packing. let discr_index = substs.prefix_tys(def_id, tcx).count(); - let promoted_tys = - ineligible_locals.iter().map(|local| subst_field(info.field_tys[local])); - let prefix_tys = substs.prefix_tys(def_id, tcx) - .chain(iter::once(substs.discr_ty(tcx))) - .chain(promoted_tys); - let prefix = self.univariant_uninterned( + // FIXME(eddyb) set the correct vaidity range for the discriminant. + let discr_layout = self.layout_of(substs.discr_ty(tcx))?; + let discr = match &discr_layout.abi { + Abi::Scalar(s) => s.clone(), + _ => bug!(), + }; + // FIXME(eddyb) wrap each promoted type in `MaybeUninit` so that they + // don't poison the `largest_niche` or `abi` fields of `prefix`. + let promoted_layouts = ineligible_locals.iter() + .map(|local| subst_field(info.field_tys[local])) + .map(|ty| self.layout_of(ty)); + let prefix_layouts = substs.prefix_tys(def_id, tcx) + .map(|ty| self.layout_of(ty)) + .chain(iter::once(Ok(discr_layout))) + .chain(promoted_layouts) + .collect::, _>>()?; + let mut prefix = self.univariant_uninterned( ty, - &prefix_tys.map(|ty| self.layout_of(ty)).collect::, _>>()?, + &prefix_layouts, &ReprOptions::default(), - StructKind::AlwaysSized)?; + StructKind::AlwaysSized, + )?; + // FIXME(eddyb) need `MaybeUninit` around promoted types (see above). + prefix.largest_niche = None; + let (prefix_size, prefix_align) = (prefix.size, prefix.align); // Split the prefix layout into the "outer" fields (upvars and @@ -1463,10 +1546,6 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } else { Abi::Aggregate { sized: true } }; - let discr = match &self.layout_of(substs.discr_ty(tcx))?.abi { - Abi::Scalar(s) => s.clone(), - _ => bug!(), - }; let layout = tcx.intern_layout(LayoutDetails { variants: Variants::Multiple { @@ -1477,6 +1556,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }, fields: outer_fields, abi, + largest_niche: prefix.largest_niche, size, align, }); @@ -1950,6 +2030,7 @@ where variants: Variants::Single { index: variant_index }, fields: FieldPlacement::Union(fields), abi: Abi::Uninhabited, + largest_niche: None, align: tcx.data_layout.i8_align, size: Size::ZERO }) @@ -2222,120 +2303,6 @@ where } } -struct Niche { - offset: Size, - scalar: Scalar, - available: u128, -} - -impl Niche { - fn reserve<'tcx>( - &self, - cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, - count: u128, - ) -> Option<(u128, Scalar)> { - if count > self.available { - return None; - } - let Scalar { value, valid_range: ref v } = self.scalar; - let bits = value.size(cx).bits(); - assert!(bits <= 128); - let max_value = !0u128 >> (128 - bits); - let start = v.end().wrapping_add(1) & max_value; - let end = v.end().wrapping_add(count) & max_value; - Some((start, Scalar { value, valid_range: *v.start()..=end })) - } -} - -impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { - /// Find the offset of a niche leaf field, starting from - /// the given type and recursing through aggregates. - // FIXME(eddyb) traverse already optimized enums. - fn find_niche(&self, layout: TyLayout<'tcx>) -> Result, LayoutError<'tcx>> { - let scalar_niche = |scalar: &Scalar, offset| { - let Scalar { value, valid_range: ref v } = *scalar; - - let bits = value.size(self).bits(); - assert!(bits <= 128); - let max_value = !0u128 >> (128 - bits); - - // Find out how many values are outside the valid range. - let available = if v.start() <= v.end() { - v.start() + (max_value - v.end()) - } else { - v.start() - v.end() - 1 - }; - - // Give up if there is no niche value available. - if available == 0 { - return None; - } - - Some(Niche { offset, scalar: scalar.clone(), available }) - }; - - // Locals variables which live across yields are stored - // in the generator type as fields. These may be uninitialized - // so we don't look for niches there. - if let ty::Generator(..) = layout.ty.sty { - return Ok(None); - } - - match layout.abi { - Abi::Scalar(ref scalar) => { - return Ok(scalar_niche(scalar, Size::ZERO)); - } - Abi::ScalarPair(ref a, ref b) => { - // HACK(nox): We iter on `b` and then `a` because `max_by_key` - // returns the last maximum. - let niche = iter::once( - (b, a.value.size(self).align_to(b.value.align(self).abi)) - ) - .chain(iter::once((a, Size::ZERO))) - .filter_map(|(scalar, offset)| scalar_niche(scalar, offset)) - .max_by_key(|niche| niche.available); - return Ok(niche); - } - Abi::Vector { ref element, .. } => { - return Ok(scalar_niche(element, Size::ZERO)); - } - _ => {} - } - - // Perhaps one of the fields is non-zero, let's recurse and find out. - if let FieldPlacement::Union(_) = layout.fields { - // Only Rust enums have safe-to-inspect fields - // (a discriminant), other unions are unsafe. - if let Variants::Single { .. } = layout.variants { - return Ok(None); - } - } - 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 { - return Ok(None); - } - } - let mut niche = None; - let mut available = 0; - for i in 0..layout.fields.count() { - if let Some(mut c) = self.find_niche(layout.field(self, i)?)? { - if c.available > available { - available = c.available; - c.offset += layout.fields.offset(i); - niche = Some(c); - } - } - } - Ok(niche) - } -} - impl<'a> HashStable> for Variants { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, @@ -2456,10 +2423,16 @@ impl<'a> HashStable> for Scalar { } } +impl_stable_hash_for!(struct crate::ty::layout::Niche { + offset, + scalar +}); + impl_stable_hash_for!(struct crate::ty::layout::LayoutDetails { variants, fields, abi, + largest_niche, size, align }); diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs index 5ac1cf8c36f93..894e5c2fd3d93 100644 --- a/src/librustc_codegen_llvm/builder.rs +++ b/src/librustc_codegen_llvm/builder.rs @@ -1153,11 +1153,14 @@ impl Builder<'a, 'll, 'tcx> { } } + pub fn vector_reduce_fadd(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + unsafe { llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src) } + } + pub fn vector_reduce_fmul(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { + unsafe { llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src) } + } pub fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { unsafe { - // FIXME: add a non-fast math version once - // https://bugs.llvm.org/show_bug.cgi?id=36732 - // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr @@ -1165,9 +1168,6 @@ impl Builder<'a, 'll, 'tcx> { } pub fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value { unsafe { - // FIXME: add a non-fast math version once - // https://bugs.llvm.org/show_bug.cgi?id=36732 - // is fixed. let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src); llvm::LLVMRustSetHasUnsafeAlgebra(instr); instr diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs index e9f25e6344b06..f00624f3811f1 100644 --- a/src/librustc_codegen_llvm/common.rs +++ b/src/librustc_codegen_llvm/common.rs @@ -166,25 +166,6 @@ impl CodegenCx<'ll, 'tcx> { r } } - - pub fn const_get_real(&self, v: &'ll Value) -> Option<(f64, bool)> { - unsafe { - if self.is_const_real(v) { - let mut loses_info: llvm::Bool = 0; - let r = llvm::LLVMConstRealGetDouble(v, &mut loses_info); - let loses_info = if loses_info == 1 { true } else { false }; - Some((r, loses_info)) - } else { - None - } - } - } - - fn is_const_real(&self, v: &'ll Value) -> bool { - unsafe { - llvm::LLVMIsAConstantFP(v).is_some() - } - } } impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index dd6cfd7e29e4e..44b3eff2ac5c9 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -1640,29 +1640,11 @@ fn generic_simd_intrinsic( } }, ty::Float(f) => { - // ordered arithmetic reductions take an accumulator let acc = if $ordered { - let acc = args[1].immediate(); - // FIXME: https://bugs.llvm.org/show_bug.cgi?id=36734 - // * if the accumulator of the fadd isn't 0, incorrect - // code is generated - // * if the accumulator of the fmul isn't 1, incorrect - // code is generated - match bx.const_get_real(acc) { - None => return_error!("accumulator of {} is not a constant", $name), - Some((v, loses_info)) => { - if $name.contains("mul") && v != 1.0_f64 { - return_error!("accumulator of {} is not 1.0", $name); - } else if $name.contains("add") && v != 0.0_f64 { - return_error!("accumulator of {} is not 0.0", $name); - } else if loses_info { - return_error!("accumulator of {} loses information", $name); - } - } - } - acc + // ordered arithmetic reductions take an accumulator + args[1].immediate() } else { - // unordered arithmetic reductions do not: + // unordered arithmetic reductions use the identity accumulator let identity_acc = if $name.contains("mul") { 1.0 } else { 0.0 }; match f.bit_width() { 32 => bx.const_real(bx.type_f32(), identity_acc), @@ -1688,8 +1670,8 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, } } - arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd_fast, true); - arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul_fast, true); + arith_red!("simd_reduce_add_ordered": vector_reduce_add, vector_reduce_fadd, true); + arith_red!("simd_reduce_mul_ordered": vector_reduce_mul, vector_reduce_fmul, true); arith_red!("simd_reduce_add_unordered": vector_reduce_add, vector_reduce_fadd_fast, false); arith_red!("simd_reduce_mul_unordered": vector_reduce_mul, vector_reduce_fmul_fast, false); diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs index 5d82698d8efb6..8c6ea00eb8c87 100644 --- a/src/librustc_codegen_llvm/llvm/ffi.rs +++ b/src/librustc_codegen_llvm/llvm/ffi.rs @@ -719,7 +719,6 @@ extern "C" { pub fn LLVMConstIntGetZExtValue(ConstantVal: &Value) -> c_ulonglong; pub fn LLVMRustConstInt128Get(ConstantVal: &Value, SExt: bool, high: &mut u64, low: &mut u64) -> bool; - pub fn LLVMConstRealGetDouble (ConstantVal: &Value, losesInfo: &mut Bool) -> f64; // Operations on composite constants @@ -1663,7 +1662,6 @@ extern "C" { pub fn LLVMRustWriteValueToString(value_ref: &Value, s: &RustString); pub fn LLVMIsAConstantInt(value_ref: &Value) -> Option<&Value>; - pub fn LLVMIsAConstantFP(value_ref: &Value) -> Option<&Value>; pub fn LLVMRustPassKind(Pass: &Pass) -> PassKind; pub fn LLVMRustFindAndCreatePass(Pass: *const c_char) -> Option<&'static mut Pass>; diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml index 5a192e472aa85..32f121f18f689 100644 --- a/src/librustc_errors/Cargo.toml +++ b/src/librustc_errors/Cargo.toml @@ -17,4 +17,4 @@ rustc_data_structures = { path = "../librustc_data_structures" } unicode-width = "0.1.4" atty = "0.2" termcolor = "1.0" -annotate-snippets = "0.5.0" +annotate-snippets = "0.6.1" diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 3641d355ef19c..96a9b6c5c4f7f 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -23,7 +23,7 @@ pub struct AnnotateSnippetEmitterWriter { source_map: Option>, /// If true, hides the longer explanation text short_message: bool, - /// If true, will normalize line numbers with LL to prevent noise in UI test diffs. + /// If true, will normalize line numbers with `LL` to prevent noise in UI test diffs. ui_testing: bool, } @@ -173,10 +173,6 @@ impl AnnotateSnippetEmitterWriter { /// Allows to modify `Self` to enable or disable the `ui_testing` flag. /// /// If this is set to true, line numbers will be normalized as `LL` in the output. - // FIXME(#59346): This method is used via the public interface, but setting the `ui_testing` - // flag currently does not anonymize line numbers. We would have to add the `maybe_anonymized` - // method from `emitter.rs` and implement rust-lang/annotate-snippets-rs#2 in order to - // anonymize line numbers. pub fn ui_testing(mut self, ui_testing: bool) -> Self { self.ui_testing = ui_testing; self @@ -202,7 +198,7 @@ impl AnnotateSnippetEmitterWriter { }; if let Some(snippet) = converter.to_annotation_snippet() { let dl = DisplayList::from(snippet); - let dlf = DisplayListFormatter::new(true); + let dlf = DisplayListFormatter::new(true, self.ui_testing); // FIXME(#59346): Figure out if we can _always_ print to stderr or not. // `emitter.rs` has the `Destination` enum that lists various possible output // destinations. diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index 3def2d8232f63..16cdbb7dd4d39 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -112,6 +112,10 @@ fn main() { println!("cargo:rustc-cfg=llvm_component=\"{}\"", component); } + if major >= 9 { + println!("cargo:rustc-cfg=llvm_has_msp430_asm_parser"); + } + // Link in our own LLVM shims, compiled with the same flags as LLVM let mut cmd = Command::new(&llvm_config); cmd.arg("--cxxflags"); diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index bdf6b09185735..dea7e6ae0a2ab 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -76,6 +76,8 @@ pub fn initialize_available_targets() { LLVMInitializeMSP430Target, LLVMInitializeMSP430TargetMC, LLVMInitializeMSP430AsmPrinter); + init_target!(all(llvm_component = "msp430", llvm_has_msp430_asm_parser), + LLVMInitializeMSP430AsmParser); init_target!(llvm_component = "riscv", LLVMInitializeRISCVTargetInfo, LLVMInitializeRISCVTarget, diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 6623661f938fe..6a5b933e4a530 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -230,21 +230,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &mut self, instance: ty::Instance<'tcx>, args: &[OpTy<'tcx, M::PointerTag>], - dest: Option>, + _dest: Option>, ) -> InterpResult<'tcx, bool> { let def_id = instance.def_id(); - // Some fn calls are actually BinOp intrinsics - if let Some((op, oflo)) = self.tcx.is_binop_lang_item(def_id) { - let dest = dest.expect("128 lowerings can't diverge"); - let l = self.read_immediate(args[0])?; - let r = self.read_immediate(args[1])?; - if oflo { - self.binop_with_overflow(op, l, r, dest)?; - } else { - self.binop_ignore_overflow(op, l, r, dest)?; - } - return Ok(true); - } else if Some(def_id) == self.tcx.lang_items().panic_fn() { + if Some(def_id) == self.tcx.lang_items().panic_fn() { assert!(args.len() == 1); // &(&'static str, &'static str, u32, u32) let place = self.deref_operand(args[0])?; diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 343832fe4a761..40cb1fbdc57fa 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -232,13 +232,6 @@ impl Inliner<'tcx> { return false; } - // Do not inline {u,i}128 lang items, codegen const eval depends - // on detecting calls to these lang items and intercepting them - if tcx.is_binop_lang_item(callsite.callee).is_some() { - debug!(" not inlining 128bit integer lang item"); - return false; - } - let codegen_fn_attrs = tcx.codegen_fn_attrs(callsite.callee); let hinted = match codegen_fn_attrs.inline { diff --git a/src/librustc_mir/transform/lower_128bit.rs b/src/librustc_mir/transform/lower_128bit.rs deleted file mode 100644 index f09a77d486c7e..0000000000000 --- a/src/librustc_mir/transform/lower_128bit.rs +++ /dev/null @@ -1,230 +0,0 @@ -//! Replaces 128-bit operators with lang item calls - -use rustc::hir::def_id::DefId; -use rustc::middle::lang_items::LangItem; -use rustc::mir::*; -use rustc::ty::{self, List, Ty, TyCtxt}; -use rustc_data_structures::indexed_vec::{Idx}; -use crate::transform::{MirPass, MirSource}; - -pub struct Lower128Bit; - -impl MirPass for Lower128Bit { - fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { - let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops; - let target_default = tcx.sess.host.options.i128_lowering; - if !debugging_override.unwrap_or(target_default) { - return - } - - self.lower_128bit_ops(tcx, body); -} -} - -impl Lower128Bit { - fn lower_128bit_ops<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mut new_blocks = Vec::new(); - let cur_len = body.basic_blocks().len(); - - let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); - for block in basic_blocks.iter_mut() { - for i in (0..block.statements.len()).rev() { - let (lang_item, rhs_kind) = - if let Some((lang_item, rhs_kind)) = - lower_to(&block.statements[i], local_decls, tcx) - { - (lang_item, rhs_kind) - } else { - continue; - }; - - let rhs_override_ty = rhs_kind.ty(tcx); - let cast_local = - match rhs_override_ty { - None => None, - Some(ty) => { - let local_decl = LocalDecl::new_internal( - ty, block.statements[i].source_info.span); - Some(local_decls.push(local_decl)) - }, - }; - - let storage_dead = cast_local.map(|local| { - Statement { - source_info: block.statements[i].source_info, - kind: StatementKind::StorageDead(local), - } - }); - let after_call = BasicBlockData { - statements: storage_dead.into_iter() - .chain(block.statements.drain((i+1)..)).collect(), - is_cleanup: block.is_cleanup, - terminator: block.terminator.take(), - }; - - let bin_statement = block.statements.pop().unwrap(); - let source_info = bin_statement.source_info; - let (place, lhs, mut rhs) = match bin_statement.kind { - StatementKind::Assign(place, box rvalue) => { - match rvalue { - Rvalue::BinaryOp(_, lhs, rhs) - | Rvalue::CheckedBinaryOp(_, lhs, rhs) => (place, lhs, rhs), - _ => bug!(), - } - } - _ => bug!() - }; - - if let Some(local) = cast_local { - block.statements.push(Statement { - source_info: source_info, - kind: StatementKind::StorageLive(local), - }); - block.statements.push(Statement { - source_info: source_info, - kind: StatementKind::Assign( - Place::from(local), - box Rvalue::Cast( - CastKind::Misc, - rhs, - rhs_override_ty.unwrap())), - }); - rhs = Operand::Move(Place::from(local)); - } - - let call_did = check_lang_item_type( - lang_item, &place, &lhs, &rhs, local_decls, tcx); - - let bb = BasicBlock::new(cur_len + new_blocks.len()); - new_blocks.push(after_call); - - block.terminator = - Some(Terminator { - source_info, - kind: TerminatorKind::Call { - func: Operand::function_handle(tcx, call_did, - List::empty(), source_info.span), - args: vec![lhs, rhs], - destination: Some((place, bb)), - cleanup: None, - from_hir_call: false, - }, - }); - } - } - - basic_blocks.extend(new_blocks); - } -} - -fn check_lang_item_type<'tcx, D>( - lang_item: LangItem, - place: &Place<'tcx>, - lhs: &Operand<'tcx>, - rhs: &Operand<'tcx>, - local_decls: &D, - tcx: TyCtxt<'tcx>, -) -> DefId -where - D: HasLocalDecls<'tcx>, -{ - let did = tcx.require_lang_item(lang_item); - let poly_sig = tcx.fn_sig(did); - let sig = poly_sig.no_bound_vars().unwrap(); - let lhs_ty = lhs.ty(local_decls, tcx); - let rhs_ty = rhs.ty(local_decls, tcx); - let place_ty = place.ty(local_decls, tcx).ty; - let expected = [lhs_ty, rhs_ty, place_ty]; - assert_eq!(sig.inputs_and_output[..], expected, - "lang item `{}`", tcx.def_path_str(did)); - did -} - -fn lower_to<'tcx, D>( - statement: &Statement<'tcx>, - local_decls: &D, - tcx: TyCtxt<'tcx>, -) -> Option<(LangItem, RhsKind)> -where - D: HasLocalDecls<'tcx>, -{ - match statement.kind { - StatementKind::Assign(_, box Rvalue::BinaryOp(bin_op, ref lhs, _)) => { - let ty = lhs.ty(local_decls, tcx); - if let Some(is_signed) = sign_of_128bit(ty) { - return item_for_op(bin_op, is_signed); - } - }, - StatementKind::Assign(_, box Rvalue::CheckedBinaryOp(bin_op, ref lhs, _)) => { - let ty = lhs.ty(local_decls, tcx); - if let Some(is_signed) = sign_of_128bit(ty) { - return item_for_checked_op(bin_op, is_signed); - } - }, - _ => {}, - } - None -} - -#[derive(Copy, Clone)] -enum RhsKind { - Unchanged, - ForceU128, - ForceU32, -} - -impl RhsKind { - fn ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option> { - match *self { - RhsKind::Unchanged => None, - RhsKind::ForceU128 => Some(tcx.types.u128), - RhsKind::ForceU32 => Some(tcx.types.u32), - } - } -} - -fn sign_of_128bit(ty: Ty<'_>) -> Option { - match ty.sty { - ty::Int(syntax::ast::IntTy::I128) => Some(true), - ty::Uint(syntax::ast::UintTy::U128) => Some(false), - _ => None, - } -} - -fn item_for_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { - let i = match (bin_op, is_signed) { - (BinOp::Add, true) => (LangItem::I128AddFnLangItem, RhsKind::Unchanged), - (BinOp::Add, false) => (LangItem::U128AddFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, true) => (LangItem::I128SubFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, false) => (LangItem::U128SubFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, true) => (LangItem::I128MulFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, false) => (LangItem::U128MulFnLangItem, RhsKind::Unchanged), - (BinOp::Div, true) => (LangItem::I128DivFnLangItem, RhsKind::Unchanged), - (BinOp::Div, false) => (LangItem::U128DivFnLangItem, RhsKind::Unchanged), - (BinOp::Rem, true) => (LangItem::I128RemFnLangItem, RhsKind::Unchanged), - (BinOp::Rem, false) => (LangItem::U128RemFnLangItem, RhsKind::Unchanged), - (BinOp::Shl, true) => (LangItem::I128ShlFnLangItem, RhsKind::ForceU32), - (BinOp::Shl, false) => (LangItem::U128ShlFnLangItem, RhsKind::ForceU32), - (BinOp::Shr, true) => (LangItem::I128ShrFnLangItem, RhsKind::ForceU32), - (BinOp::Shr, false) => (LangItem::U128ShrFnLangItem, RhsKind::ForceU32), - _ => return None, - }; - Some(i) -} - -fn item_for_checked_op(bin_op: BinOp, is_signed: bool) -> Option<(LangItem, RhsKind)> { - let i = match (bin_op, is_signed) { - (BinOp::Add, true) => (LangItem::I128AddoFnLangItem, RhsKind::Unchanged), - (BinOp::Add, false) => (LangItem::U128AddoFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, true) => (LangItem::I128SuboFnLangItem, RhsKind::Unchanged), - (BinOp::Sub, false) => (LangItem::U128SuboFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, true) => (LangItem::I128MuloFnLangItem, RhsKind::Unchanged), - (BinOp::Mul, false) => (LangItem::U128MuloFnLangItem, RhsKind::Unchanged), - (BinOp::Shl, true) => (LangItem::I128ShloFnLangItem, RhsKind::ForceU128), - (BinOp::Shl, false) => (LangItem::U128ShloFnLangItem, RhsKind::ForceU128), - (BinOp::Shr, true) => (LangItem::I128ShroFnLangItem, RhsKind::ForceU128), - (BinOp::Shr, false) => (LangItem::U128ShroFnLangItem, RhsKind::ForceU128), - _ => bug!("That should be all the checked ones?"), - }; - Some(i) -} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 195a652b0a2e6..61d0b1f3485b6 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -34,7 +34,6 @@ pub mod copy_prop; pub mod const_prop; pub mod generator; pub mod inline; -pub mod lower_128bit; pub mod uniform_array_move_out; pub(crate) fn provide(providers: &mut Providers<'_>) { @@ -272,8 +271,6 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> { // From here on out, regions are gone. &erase_regions::EraseRegions, - &lower_128bit::Lower128Bit, - // Optimizations begin. &uniform_array_move_out::RestoreSubsliceArrayMoveOut, diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 01586e92aeb1c..4a4c6799c005e 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -878,23 +878,94 @@ pub enum DiscriminantKind { }, } +#[derive(Clone, PartialEq, Eq, Hash, Debug)] +pub struct Niche { + pub offset: Size, + pub scalar: Scalar, +} + +impl Niche { + pub fn from_scalar(cx: &C, offset: Size, scalar: Scalar) -> Option { + let niche = Niche { + offset, + scalar, + }; + if niche.available(cx) > 0 { + Some(niche) + } else { + None + } + } + + pub fn available(&self, cx: &C) -> u128 { + let Scalar { value, valid_range: ref v } = self.scalar; + let bits = value.size(cx).bits(); + assert!(bits <= 128); + let max_value = !0u128 >> (128 - bits); + + // Find out how many values are outside the valid range. + let niche = v.end().wrapping_add(1)..*v.start(); + niche.end.wrapping_sub(niche.start) & max_value + } + + pub fn reserve(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> { + assert!(count > 0); + + let Scalar { value, valid_range: ref v } = self.scalar; + let bits = value.size(cx).bits(); + assert!(bits <= 128); + let max_value = !0u128 >> (128 - bits); + + if count > max_value { + return None; + } + + // Compute the range of invalid values being reserved. + let start = v.end().wrapping_add(1) & max_value; + let end = v.end().wrapping_add(count) & max_value; + + // If the `end` of our range is inside the valid range, + // then we ran out of invalid values. + // FIXME(eddyb) abstract this with a wraparound range type. + let valid_range_contains = |x| { + if v.start() <= v.end() { + *v.start() <= x && x <= *v.end() + } else { + *v.start() <= x || x <= *v.end() + } + }; + if valid_range_contains(end) { + return None; + } + + Some((start, Scalar { value, valid_range: *v.start()..=end })) + } +} + #[derive(PartialEq, Eq, Hash, Debug)] pub struct LayoutDetails { pub variants: Variants, pub fields: FieldPlacement, pub abi: Abi, + + /// The leaf scalar with the largest number of invalid values + /// (i.e. outside of its `valid_range`), if it exists. + pub largest_niche: Option, + pub align: AbiAndPrefAlign, pub size: Size } impl LayoutDetails { pub fn scalar(cx: &C, scalar: Scalar) -> Self { + let largest_niche = Niche::from_scalar(cx, Size::ZERO, scalar.clone()); let size = scalar.value.size(cx); let align = scalar.value.align(cx); LayoutDetails { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldPlacement::Union(0), abi: Abi::Scalar(scalar), + largest_niche, size, align, } diff --git a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs index 8eb19a6518a3f..3c63371d12192 100644 --- a/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_gnueabihf.rs @@ -16,7 +16,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+strict-align,+v6,+vfp2".to_string(), + features: "+strict-align,+v6,+vfp2,-d32".to_string(), abi_blacklist: super::arm_base::abi_blacklist(), target_mcount: "\u{1}__gnu_mcount_nc".to_string(), .. base diff --git a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs index 496a0c4a43a7e..fb5a16f74c00b 100644 --- a/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_target/spec/arm_unknown_linux_musleabihf.rs @@ -5,7 +5,7 @@ pub fn target() -> TargetResult { // Most of these settings are copied from the arm_unknown_linux_gnueabihf // target. - base.features = "+strict-align,+v6,+vfp2".to_string(); + base.features = "+strict-align,+v6,+vfp2,-d32".to_string(); base.max_atomic_width = Some(64); Ok(Target { // It's important we use "gnueabihf" and not "musleabihf" here. LLVM diff --git a/src/librustc_target/spec/armv6_unknown_freebsd.rs b/src/librustc_target/spec/armv6_unknown_freebsd.rs index efbbee959ed95..06233f7caa351 100644 --- a/src/librustc_target/spec/armv6_unknown_freebsd.rs +++ b/src/librustc_target/spec/armv6_unknown_freebsd.rs @@ -15,7 +15,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+v6,+vfp2".to_string(), + features: "+v6,+vfp2,-d32".to_string(), max_atomic_width: Some(64), abi_blacklist: super::arm_base::abi_blacklist(), target_mcount: "\u{1}__gnu_mcount_nc".to_string(), diff --git a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs index b76c39ac75b8b..40411befcfc2b 100644 --- a/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs +++ b/src/librustc_target/spec/armv6_unknown_netbsd_eabihf.rs @@ -16,7 +16,7 @@ pub fn target() -> TargetResult { linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { - features: "+v6,+vfp2".to_string(), + features: "+v6,+vfp2,-d32".to_string(), abi_blacklist: super::arm_base::abi_blacklist(), target_mcount: "__mcount".to_string(), .. base diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index 34b580acbd5c0..b2ea6b7411a2e 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -733,10 +733,6 @@ pub struct TargetOptions { /// for this target unconditionally. pub no_builtins: bool, - /// Whether to lower 128-bit operations to compiler_builtins calls. Use if - /// your backend only supports 64-bit and smaller math. - pub i128_lowering: bool, - /// The codegen backend to use for this target, typically "llvm" pub codegen_backend: String, @@ -852,7 +848,6 @@ impl Default for TargetOptions { requires_lto: false, singlethread: false, no_builtins: false, - i128_lowering: false, codegen_backend: "llvm".to_string(), default_hidden_visibility: false, embed_bitcode: false, diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index f2dbceb31b9ca..8d2160c0ec7aa 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -225,7 +225,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.mk_unit() } ExprKind::Break(destination, ref expr_opt) => { - self.check_expr_break(destination, expr_opt.deref(), expr) + self.check_expr_break(destination, expr_opt.as_deref(), expr) } ExprKind::Continue(destination) => { if destination.target_id.is_ok() { @@ -236,7 +236,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } ExprKind::Ret(ref expr_opt) => { - self.check_expr_return(expr_opt.deref(), expr) + self.check_expr_return(expr_opt.as_deref(), expr) } ExprKind::Assign(ref lhs, ref rhs) => { self.check_expr_assign(expr, expected, lhs, rhs) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 3cd520fd4b50b..6270ed3785905 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1173,7 +1173,7 @@ themePicker.onblur = handleThemeButtonsBlur; title: "Index of crates", css_class: "mod", root_path: "./", - static_root_path: cx.shared.static_root_path.deref(), + static_root_path: cx.shared.static_root_path.as_deref(), description: "List of crates", keywords: BASIC_KEYWORDS, resource_suffix: &cx.shared.resource_suffix, @@ -1513,7 +1513,7 @@ impl<'a> SourceCollector<'a> { title: &title, css_class: "source", root_path: &root_path, - static_root_path: self.scx.static_root_path.deref(), + static_root_path: self.scx.static_root_path.as_deref(), description: &desc, keywords: BASIC_KEYWORDS, resource_suffix: &self.scx.resource_suffix, @@ -2110,7 +2110,7 @@ impl Context { title: "List of all items in this crate", css_class: "mod", root_path: "../", - static_root_path: self.shared.static_root_path.deref(), + static_root_path: self.shared.static_root_path.as_deref(), description: "List of all items in this crate", keywords: BASIC_KEYWORDS, resource_suffix: &self.shared.resource_suffix, @@ -2137,7 +2137,7 @@ impl Context { self.shared.fs.write(&final_file, &v)?; // Generating settings page. - let settings = Settings::new(self.shared.static_root_path.deref().unwrap_or("./"), + let settings = Settings::new(self.shared.static_root_path.as_deref().unwrap_or("./"), &self.shared.resource_suffix); page.title = "Rustdoc settings"; page.description = "Settings of Rustdoc"; @@ -2195,7 +2195,7 @@ impl Context { let page = layout::Page { css_class: tyname, root_path: &self.root_path(), - static_root_path: self.shared.static_root_path.deref(), + static_root_path: self.shared.static_root_path.as_deref(), title: &title, description: &desc, keywords: &keywords, diff --git a/src/libstd/sys/vxworks/alloc.rs b/src/libstd/sys/vxworks/alloc.rs index c60d1b8dab898..e0c560b9214ea 100644 --- a/src/libstd/sys/vxworks/alloc.rs +++ b/src/libstd/sys/vxworks/alloc.rs @@ -41,36 +41,6 @@ unsafe impl GlobalAlloc for System { } } -#[cfg(any(target_os = "android", - target_os = "hermit", - target_os = "redox", - target_os = "solaris"))] -#[inline] -unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { - // On android we currently target API level 9 which unfortunately - // doesn't have the `posix_memalign` API used below. Instead we use - // `memalign`, but this unfortunately has the property on some systems - // where the memory returned cannot be deallocated by `free`! - // - // Upon closer inspection, however, this appears to work just fine with - // Android, so for this platform we should be fine to call `memalign` - // (which is present in API level 9). Some helpful references could - // possibly be chromium using memalign [1], attempts at documenting that - // memalign + free is ok [2] [3], or the current source of chromium - // which still uses memalign on android [4]. - // - // [1]: https://codereview.chromium.org/10796020/ - // [2]: https://code.google.com/p/android/issues/detail?id=35391 - // [3]: https://bugs.chromium.org/p/chromium/issues/detail?id=138579 - // [4]: https://chromium.googlesource.com/chromium/src/base/+/master/ - // /memory/aligned_memory.cc - libc::memalign(layout.align(), layout.size()) as *mut u8 -} - -#[cfg(not(any(target_os = "android", - target_os = "hermit", - target_os = "redox", - target_os = "solaris")))] #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { let mut out = ptr::null_mut(); diff --git a/src/libstd/sys/vxworks/android.rs b/src/libstd/sys/vxworks/android.rs deleted file mode 100644 index 6774160bb2561..0000000000000 --- a/src/libstd/sys/vxworks/android.rs +++ /dev/null @@ -1,160 +0,0 @@ -//! Android ABI-compatibility module -//! -//! The ABI of Android has changed quite a bit over time, and libstd attempts to -//! be both forwards and backwards compatible as much as possible. We want to -//! always work with the most recent version of Android, but we also want to -//! work with older versions of Android for whenever projects need to. -//! -//! Our current minimum supported Android version is `android-9`, e.g., Android -//! with API level 9. We then in theory want to work on that and all future -//! versions of Android! -//! -//! Some of the detection here is done at runtime via `dlopen` and -//! introspection. Other times no detection is performed at all and we just -//! provide a fallback implementation as some versions of Android we support -//! don't have the function. -//! -//! You'll find more details below about why each compatibility shim is needed. - -#![cfg(target_os = "android")] - -use libc::{c_int, c_void, sighandler_t, size_t, ssize_t}; -use libc::{ftruncate, pread, pwrite}; - -use crate::io; -use super::{cvt, cvt_r}; - -// The `log2` and `log2f` functions apparently appeared in android-18, or at -// least you can see they're not present in the android-17 header [1] and they -// are present in android-18 [2]. -// -// [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms -// /android-17/arch-arm/usr/include/math.h -// [2]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms -// /android-18/arch-arm/usr/include/math.h -// -// Note that these shims are likely less precise than directly calling `log2`, -// but hopefully that should be enough for now... -// -// Note that mathematically, for any arbitrary `y`: -// -// log_2(x) = log_y(x) / log_y(2) -// = log_y(x) / (1 / log_2(y)) -// = log_y(x) * log_2(y) -// -// Hence because `ln` (log_e) is available on all Android we just choose `y = e` -// and get: -// -// log_2(x) = ln(x) * log_2(e) - -#[cfg(not(test))] -pub fn log2f32(f: f32) -> f32 { - f.ln() * crate::f32::consts::LOG2_E -} - -#[cfg(not(test))] -pub fn log2f64(f: f64) -> f64 { - f.ln() * crate::f64::consts::LOG2_E -} - -// Back in the day [1] the `signal` function was just an inline wrapper -// around `bsd_signal`, but starting in API level android-20 the `signal` -// symbols was introduced [2]. Finally, in android-21 the API `bsd_signal` was -// removed [3]. -// -// Basically this means that if we want to be binary compatible with multiple -// Android releases (oldest being 9 and newest being 21) then we need to check -// for both symbols and not actually link against either. -// -// [1]: https://chromium.googlesource.com/android_tools/+/20ee6d20/ndk/platforms -// /android-18/arch-arm/usr/include/signal.h -// [2]: https://chromium.googlesource.com/android_tools/+/fbd420/ndk_experimental -// /platforms/android-20/arch-arm -// /usr/include/signal.h -// [3]: https://chromium.googlesource.com/android_tools/+/20ee6d/ndk/platforms -// /android-21/arch-arm/usr/include/signal.h -pub unsafe fn signal(signum: c_int, handler: sighandler_t) -> sighandler_t { - weak!(fn signal(c_int, sighandler_t) -> sighandler_t); - weak!(fn bsd_signal(c_int, sighandler_t) -> sighandler_t); - - let f = signal.get().or_else(|| bsd_signal.get()); - let f = f.expect("neither `signal` nor `bsd_signal` symbols found"); - f(signum, handler) -} - -// The `ftruncate64` symbol apparently appeared in android-12, so we do some -// dynamic detection to see if we can figure out whether `ftruncate64` exists. -// -// If it doesn't we just fall back to `ftruncate`, generating an error for -// too-large values. -#[cfg(target_pointer_width = "32")] -pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> { - weak!(fn ftruncate64(c_int, i64) -> c_int); - - unsafe { - match ftruncate64.get() { - Some(f) => cvt_r(|| f(fd, size as i64)).map(|_| ()), - None => { - if size > i32::max_value() as u64 { - Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot truncate >2GB")) - } else { - cvt_r(|| ftruncate(fd, size as i32)).map(|_| ()) - } - } - } - } -} - -#[cfg(target_pointer_width = "64")] -pub fn ftruncate64(fd: c_int, size: u64) -> io::Result<()> { - unsafe { - cvt_r(|| ftruncate(fd, size as i64)).map(|_| ()) - } -} - -#[cfg(target_pointer_width = "32")] -pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64) - -> io::Result -{ - use crate::convert::TryInto; - weak!(fn pread64(c_int, *mut c_void, size_t, i64) -> ssize_t); - pread64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| { - if let Ok(o) = offset.try_into() { - cvt(pread(fd, buf, count, o)) - } else { - Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot pread >2GB")) - } - }) -} - -#[cfg(target_pointer_width = "32")] -pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64) - -> io::Result -{ - use crate::convert::TryInto; - weak!(fn pwrite64(c_int, *const c_void, size_t, i64) -> ssize_t); - pwrite64.get().map(|f| cvt(f(fd, buf, count, offset))).unwrap_or_else(|| { - if let Ok(o) = offset.try_into() { - cvt(pwrite(fd, buf, count, o)) - } else { - Err(io::Error::new(io::ErrorKind::InvalidInput, - "cannot pwrite >2GB")) - } - }) -} - -#[cfg(target_pointer_width = "64")] -pub unsafe fn cvt_pread64(fd: c_int, buf: *mut c_void, count: size_t, offset: i64) - -> io::Result -{ - cvt(pread(fd, buf, count, offset)) -} - -#[cfg(target_pointer_width = "64")] -pub unsafe fn cvt_pwrite64(fd: c_int, buf: *const c_void, count: size_t, offset: i64) - -> io::Result -{ - cvt(pwrite(fd, buf, count, offset)) -} diff --git a/src/libstd/sys/vxworks/condvar.rs b/src/libstd/sys/vxworks/condvar.rs index 4d221264f232f..783c3eb7c766f 100644 --- a/src/libstd/sys/vxworks/condvar.rs +++ b/src/libstd/sys/vxworks/condvar.rs @@ -62,10 +62,6 @@ impl Condvar { // where we configure condition variable to use monotonic clock (instead of // default system clock). This approach avoids all problems that result // from changes made to the system time. - #[cfg(not(any(target_os = "macos", - target_os = "ios", - target_os = "android", - target_os = "hermit")))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { use crate::mem; @@ -92,78 +88,9 @@ impl Condvar { } - // This implementation is modeled after libcxx's condition_variable - // https://github.com/llvm-mirror/libcxx/blob/release_35/src/condition_variable.cpp#L46 - // https://github.com/llvm-mirror/libcxx/blob/release_35/include/__mutex_base#L367 - #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android", target_os = "hermit"))] - pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool { - use crate::ptr; - use crate::time::Instant; - - // 1000 years - let max_dur = Duration::from_secs(1000 * 365 * 86400); - - if dur > max_dur { - // OSX implementation of `pthread_cond_timedwait` is buggy - // with super long durations. When duration is greater than - // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait` - // in macOS Sierra return error 316. - // - // This program demonstrates the issue: - // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c - // - // To work around this issue, and possible bugs of other OSes, timeout - // is clamped to 1000 years, which is allowable per the API of `wait_timeout` - // because of spurious wakeups. - - dur = max_dur; - } - - // First, figure out what time it currently is, in both system and - // stable time. pthread_cond_timedwait uses system time, but we want to - // report timeout based on stable time. - let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 }; - let stable_now = Instant::now(); - let r = libc::gettimeofday(&mut sys_now, ptr::null_mut()); - debug_assert_eq!(r, 0); - - let nsec = dur.subsec_nanos() as libc::c_long + - (sys_now.tv_usec * 1000) as libc::c_long; - let extra = (nsec / 1_000_000_000) as libc::time_t; - let nsec = nsec % 1_000_000_000; - let seconds = saturating_cast_to_time_t(dur.as_secs()); - - let timeout = sys_now.tv_sec.checked_add(extra).and_then(|s| { - s.checked_add(seconds) - }).map(|s| { - libc::timespec { tv_sec: s, tv_nsec: nsec } - }).unwrap_or(TIMESPEC_MAX); - - // And wait! - let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex), - &timeout); - debug_assert!(r == libc::ETIMEDOUT || r == 0); - - // ETIMEDOUT is not a totally reliable method of determining timeout due - // to clock shifts, so do the check ourselves - stable_now.elapsed() < dur - } - #[inline] - #[cfg(not(target_os = "dragonfly"))] pub unsafe fn destroy(&self) { let r = libc::pthread_cond_destroy(self.inner.get()); debug_assert_eq!(r, 0); } - - #[inline] - #[cfg(target_os = "dragonfly")] - pub unsafe fn destroy(&self) { - let r = libc::pthread_cond_destroy(self.inner.get()); - // On DragonFly pthread_cond_destroy() returns EINVAL if called on - // a condvar that was just initialized with - // libc::PTHREAD_COND_INITIALIZER. Once it is used or - // pthread_cond_init() is called, this behaviour no longer occurs. - debug_assert!(r == 0 || r == libc::EINVAL); - } } diff --git a/src/libstd/sys/vxworks/ext/net.rs b/src/libstd/sys/vxworks/ext/net.rs index 41090caee8459..3f0a7e9e84319 100644 --- a/src/libstd/sys/vxworks/ext/net.rs +++ b/src/libstd/sys/vxworks/ext/net.rs @@ -5,16 +5,6 @@ #[cfg(unix)] use libc; -// FIXME(#43348): Make libc adapt #[doc(cfg(...))] so we don't need these fake definitions here? -#[cfg(not(unix))] -mod libc { - pub use libc::c_int; - pub type socklen_t = u32; - pub struct sockaddr; - #[derive(Clone)] - pub struct sockaddr_un; -} - use crate::ascii; use crate::ffi::OsStr; use crate::fmt; @@ -29,15 +19,6 @@ use crate::sys::{self, cvt}; use crate::sys::net::Socket; use crate::sys_common::{self, AsInner, FromInner, IntoInner}; -#[cfg(any(target_os = "linux", target_os = "android", - target_os = "dragonfly", target_os = "freebsd", - target_os = "openbsd", target_os = "netbsd", - target_os = "haiku"))] -use libc::MSG_NOSIGNAL; -#[cfg(not(any(target_os = "linux", target_os = "android", - target_os = "dragonfly", target_os = "freebsd", - target_os = "openbsd", target_os = "netbsd", - target_os = "haiku")))] const MSG_NOSIGNAL: libc::c_int = 0x0; fn sun_path_offset(addr: &libc::sockaddr_un) -> usize { @@ -202,13 +183,7 @@ impl SocketAddr { let len = self.len as usize - sun_path_offset(&self.addr); let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }; - // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses - if len == 0 - || (cfg!(not(any(target_os = "linux", target_os = "android"))) - && self.addr.sun_path[0] == 0) - { - AddressKind::Unnamed - } else if self.addr.sun_path[0] == 0 { + if self.addr.sun_path[0] == 0 { AddressKind::Abstract(&path[1..len]) } else { AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref()) diff --git a/src/libstd/sys/vxworks/l4re.rs b/src/libstd/sys/vxworks/l4re.rs deleted file mode 100644 index b3dd1cf6aaac7..0000000000000 --- a/src/libstd/sys/vxworks/l4re.rs +++ /dev/null @@ -1,469 +0,0 @@ -macro_rules! unimpl { - () => (return Err(io::Error::new(io::ErrorKind::Other, "No networking available on L4Re."));) -} - -pub mod net { - #![allow(warnings)] - use crate::fmt; - use crate::io::{self, IoVec, IoVecMut}; - use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr}; - use crate::sys_common::{AsInner, FromInner, IntoInner}; - use crate::sys::fd::FileDesc; - use crate::time::Duration; - use crate::convert::TryFrom; - - #[allow(unused_extern_crates)] - pub extern crate libc as netc; - - pub struct Socket(FileDesc); - impl Socket { - pub fn new(_: &SocketAddr, _: libc::c_int) -> io::Result { - unimpl!(); - } - - pub fn new_raw(_: libc::c_int, _: libc::c_int) -> io::Result { - unimpl!(); - } - - pub fn new_pair(_: libc::c_int, _: libc::c_int) -> io::Result<(Socket, Socket)> { - unimpl!(); - } - - pub fn connect_timeout(&self, _: &SocketAddr, _: Duration) -> io::Result<()> { - unimpl!(); - } - - pub fn accept(&self, _: *mut libc::sockaddr, _: *mut libc::socklen_t) - -> io::Result { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result { - unimpl!(); - } - - pub fn read(&self, _: &mut [u8]) -> io::Result { - unimpl!(); - } - - pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result { - unimpl!(); - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result { - unimpl!(); - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn write(&self, _: &[u8]) -> io::Result { - unimpl!(); - } - - pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result { - unimpl!(); - } - - pub fn set_timeout(&self, _: Option, _: libc::c_int) -> io::Result<()> { - unimpl!(); - } - - pub fn timeout(&self, _: libc::c_int) -> io::Result> { - unimpl!(); - } - - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { - unimpl!(); - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn nodelay(&self) -> io::Result { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result> { - unimpl!(); - } - } - - impl AsInner for Socket { - fn as_inner(&self) -> &libc::c_int { self.0.as_inner() } - } - - impl FromInner for Socket { - fn from_inner(fd: libc::c_int) -> Socket { Socket(FileDesc::new(fd)) } - } - - impl IntoInner for Socket { - fn into_inner(self) -> libc::c_int { self.0.into_raw() } - } - - pub struct TcpStream { - inner: Socket, - } - - impl TcpStream { - pub fn connect(_: io::Result<&SocketAddr>) -> io::Result { - unimpl!(); - } - - pub fn connect_timeout(_: &SocketAddr, _: Duration) -> io::Result { - unimpl!(); - } - - pub fn socket(&self) -> &Socket { &self.inner } - - pub fn into_socket(self) -> Socket { self.inner } - - pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { - unimpl!(); - } - - pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { - unimpl!(); - } - - pub fn read_timeout(&self) -> io::Result> { - unimpl!(); - } - - pub fn write_timeout(&self) -> io::Result> { - unimpl!(); - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result { - unimpl!(); - } - - pub fn read(&self, _: &mut [u8]) -> io::Result { - unimpl!(); - } - - pub fn read_vectored(&self, _: &mut [IoVecMut<'_>]) -> io::Result { - unimpl!(); - } - - pub fn write(&self, _: &[u8]) -> io::Result { - unimpl!(); - } - - pub fn write_vectored(&self, _: &[IoVec<'_>]) -> io::Result { - unimpl!(); - } - - pub fn peer_addr(&self) -> io::Result { - unimpl!(); - } - - pub fn socket_addr(&self) -> io::Result { - unimpl!(); - } - - pub fn shutdown(&self, _: Shutdown) -> io::Result<()> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result { - unimpl!(); - } - - pub fn set_nodelay(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn nodelay(&self) -> io::Result { - unimpl!(); - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn ttl(&self) -> io::Result { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - } - - impl FromInner for TcpStream { - fn from_inner(socket: Socket) -> TcpStream { - TcpStream { inner: socket } - } - } - - impl fmt::Debug for TcpStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "No networking support available on L4Re") - } - } - - pub struct TcpListener { - inner: Socket, - } - - impl TcpListener { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result { - unimpl!(); - } - - pub fn socket(&self) -> &Socket { &self.inner } - - pub fn into_socket(self) -> Socket { self.inner } - - pub fn socket_addr(&self) -> io::Result { - unimpl!(); - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result { - unimpl!(); - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn ttl(&self) -> io::Result { - unimpl!(); - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn only_v6(&self) -> io::Result { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - } - - impl FromInner for TcpListener { - fn from_inner(socket: Socket) -> TcpListener { - TcpListener { inner: socket } - } - } - - impl fmt::Debug for TcpListener { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "No networking support available on L4Re.") - } - } - - pub struct UdpSocket { - inner: Socket, - } - - impl UdpSocket { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result { - unimpl!(); - } - - pub fn socket(&self) -> &Socket { &self.inner } - - pub fn into_socket(self) -> Socket { self.inner } - - pub fn peer_addr(&self) -> io::Result { - unimpl!(); - } - - pub fn socket_addr(&self) -> io::Result { - unimpl!(); - } - - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unimpl!(); - } - - pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result { - unimpl!(); - } - - pub fn duplicate(&self) -> io::Result { - unimpl!(); - } - - pub fn set_read_timeout(&self, _: Option) -> io::Result<()> { - unimpl!(); - } - - pub fn set_write_timeout(&self, _: Option) -> io::Result<()> { - unimpl!(); - } - - pub fn read_timeout(&self) -> io::Result> { - unimpl!(); - } - - pub fn write_timeout(&self) -> io::Result> { - unimpl!(); - } - - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn broadcast(&self) -> io::Result { - unimpl!(); - } - - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_loop_v4(&self) -> io::Result { - unimpl!(); - } - - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_ttl_v4(&self) -> io::Result { - unimpl!(); - } - - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn multicast_loop_v6(&self) -> io::Result { - unimpl!(); - } - - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) - -> io::Result<()> { - unimpl!(); - } - - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) - -> io::Result<()> { - unimpl!(); - } - - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) - -> io::Result<()> { - unimpl!(); - } - - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) - -> io::Result<()> { - unimpl!(); - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unimpl!(); - } - - pub fn ttl(&self) -> io::Result { - unimpl!(); - } - - pub fn take_error(&self) -> io::Result> { - unimpl!(); - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unimpl!(); - } - - pub fn recv(&self, _: &mut [u8]) -> io::Result { - unimpl!(); - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result { - unimpl!(); - } - - pub fn send(&self, _: &[u8]) -> io::Result { - unimpl!(); - } - - pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { - unimpl!(); - } - } - - impl FromInner for UdpSocket { - fn from_inner(socket: Socket) -> UdpSocket { - UdpSocket { inner: socket } - } - } - - impl fmt::Debug for UdpSocket { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "No networking support on L4Re available.") - } - } - - pub struct LookupHost { - original: *mut libc::addrinfo, - cur: *mut libc::addrinfo, - } - - impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option { - None - } - } - - impl LookupHost { - pub fn port(&self) -> u16 { - unimpl!(); - } - } - - unsafe impl Sync for LookupHost {} - unsafe impl Send for LookupHost {} - - - impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(_v: &str) -> io::Result { - unimpl!(); - } - } - - impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from(_v: (&'a str, u16)) -> io::Result { - unimpl!(); - } - } -} diff --git a/src/libstd/sys/vxworks/memchr.rs b/src/libstd/sys/vxworks/memchr.rs index 1984678bdde4e..b5b4e6d9c134e 100644 --- a/src/libstd/sys/vxworks/memchr.rs +++ b/src/libstd/sys/vxworks/memchr.rs @@ -16,25 +16,6 @@ pub fn memchr(needle: u8, haystack: &[u8]) -> Option { } pub fn memrchr(needle: u8, haystack: &[u8]) -> Option { - - #[cfg(target_os = "linux")] - fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option { - // GNU's memrchr() will - unlike memchr() - error if haystack is empty. - if haystack.is_empty() {return None} - let p = unsafe { - libc::memrchr( - haystack.as_ptr() as *const libc::c_void, - needle as libc::c_int, - haystack.len()) - }; - if p.is_null() { - None - } else { - Some(p as usize - (haystack.as_ptr() as usize)) - } - } - - #[cfg(not(target_os = "linux"))] fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option { core::slice::memchr::memrchr(needle, haystack) } diff --git a/src/libstd/sys/vxworks/mod.rs b/src/libstd/sys/vxworks/mod.rs index b01bea03c1b52..1eff4fbcd83b7 100644 --- a/src/libstd/sys/vxworks/mod.rs +++ b/src/libstd/sys/vxworks/mod.rs @@ -7,14 +7,8 @@ pub use crate::os::vxworks as platform; pub use self::rand::hashmap_random_keys; pub use libc::strlen; -#[macro_use] -pub mod weak; - pub mod alloc; pub mod args; -pub mod android; -//#[cfg(feature = "backtrace")] -//pub mod backtrace; pub mod cmath; pub mod condvar; pub mod env; @@ -25,12 +19,7 @@ pub mod fs; pub mod memchr; pub mod io; pub mod mutex; -#[cfg(not(target_os = "l4re"))] pub mod net; -#[cfg(target_os = "l4re")] -mod l4re; -#[cfg(target_os = "l4re")] -pub use self::l4re::net; pub mod os; pub mod path; pub mod pipe; @@ -61,9 +50,6 @@ pub fn init() { unsafe fn reset_sigpipe() { } } -#[cfg(target_os = "android")] -pub use crate::sys::android::signal; -#[cfg(not(target_os = "android"))] pub use libc::signal; pub fn decode_error_kind(errno: i32) -> ErrorKind { diff --git a/src/libstd/sys/vxworks/net.rs b/src/libstd/sys/vxworks/net.rs index 686cea49a6ea8..aa6b93c860069 100644 --- a/src/libstd/sys/vxworks/net.rs +++ b/src/libstd/sys/vxworks/net.rs @@ -58,19 +58,6 @@ impl Socket { pub fn new_raw(fam: c_int, ty: c_int) -> io::Result { unsafe { - // On linux we first attempt to pass the SOCK_CLOEXEC flag to - // atomically create the socket and set it as CLOEXEC. Support for - // this option, however, was added in 2.6.27, and we still support - // 2.6.18 as a kernel, so if the returned error is EINVAL we - // fallthrough to the fallback. - if cfg!(target_os = "linux") { - match cvt(libc::socket(fam, ty | SOCK_CLOEXEC, 0)) { - Ok(fd) => return Ok(Socket(FileDesc::new(fd))), - Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {} - Err(e) => return Err(e), - } - } - let fd = cvt(libc::socket(fam, ty, 0))?; let fd = FileDesc::new(fd); fd.set_cloexec()?; diff --git a/src/libstd/sys/vxworks/process/process_common.rs b/src/libstd/sys/vxworks/process/process_common.rs index db4e80c216c12..9fce5f5811f35 100644 --- a/src/libstd/sys/vxworks/process/process_common.rs +++ b/src/libstd/sys/vxworks/process/process_common.rs @@ -422,46 +422,12 @@ mod tests { } } - // Android with api less than 21 define sig* functions inline, so it is not - // available for dynamic link. Implementing sigemptyset and sigaddset allow us - // to support older Android version (independent of libc version). - // The following implementations are based on https://git.io/vSkNf - - #[cfg(not(target_os = "android"))] extern { - #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")] fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int; - - #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")] fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int; } - #[cfg(target_os = "android")] - unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int { - libc::memset(set as *mut _, 0, mem::size_of::()); - return 0; - } - - #[cfg(target_os = "android")] - unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int { - use crate::slice; - - let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::()); - let bit = (signum - 1) as usize; - raw[bit / 8] |= 1 << (bit % 8); - return 0; - } - - // See #14232 for more information, but it appears that signal delivery to a - // newly spawned process may just be raced in the macOS, so to prevent this - // test from being flaky we ignore it on macOS. #[test] - #[cfg_attr(target_os = "macos", ignore)] - // When run under our current QEMU emulation test suite this test fails, - // although the reason isn't very clear as to why. For now this test is - // ignored there. - #[cfg_attr(target_arch = "arm", ignore)] - #[cfg_attr(target_arch = "aarch64", ignore)] fn test_process_mask() { unsafe { // Test to make sure that a signal mask does not get inherited. diff --git a/src/libstd/sys/vxworks/stack_overflow.rs b/src/libstd/sys/vxworks/stack_overflow.rs index 561279e82785c..08e7b310ca1b8 100644 --- a/src/libstd/sys/vxworks/stack_overflow.rs +++ b/src/libstd/sys/vxworks/stack_overflow.rs @@ -23,174 +23,6 @@ impl Drop for Handler { } } -#[cfg(any(target_os = "linux", - target_os = "macos", - target_os = "bitrig", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "solaris", - all(target_os = "netbsd", not(target_vendor = "rumprun")), - target_os = "openbsd"))] -mod imp { - use super::Handler; - use crate::mem; - use crate::ptr; - - use libc::{sigaltstack, SIGSTKSZ, SS_DISABLE}; - use libc::{sigaction, SIGBUS, SIG_DFL, - SA_SIGINFO, SA_ONSTACK, sighandler_t}; - use libc::{mmap, munmap}; - use libc::{SIGSEGV, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON}; - use libc::MAP_FAILED; - - use crate::sys_common::thread_info; - - - #[cfg(any(target_os = "linux", target_os = "android"))] - unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize { - #[repr(C)] - struct siginfo_t { - a: [libc::c_int; 3], // si_signo, si_errno, si_code - si_addr: *mut libc::c_void, - } - - (*(info as *const siginfo_t)).si_addr as usize - } - - #[cfg(not(any(target_os = "linux", target_os = "android")))] - unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize { - (*info).si_addr as usize - } - - // Signal handler for the SIGSEGV and SIGBUS handlers. We've got guard pages - // (unmapped pages) at the end of every thread's stack, so if a thread ends - // up running into the guard page it'll trigger this handler. We want to - // detect these cases and print out a helpful error saying that the stack - // has overflowed. All other signals, however, should go back to what they - // were originally supposed to do. - // - // This handler currently exists purely to print an informative message - // whenever a thread overflows its stack. We then abort to exit and - // indicate a crash, but to avoid a misleading SIGSEGV that might lead - // users to believe that unsafe code has accessed an invalid pointer; the - // SIGSEGV encountered when overflowing the stack is expected and - // well-defined. - // - // If this is not a stack overflow, the handler un-registers itself and - // then returns (to allow the original signal to be delivered again). - // Returning from this kind of signal handler is technically not defined - // to work when reading the POSIX spec strictly, but in practice it turns - // out many large systems and all implementations allow returning from a - // signal handler to work. For a more detailed explanation see the - // comments on #26458. - unsafe extern fn signal_handler(signum: libc::c_int, - info: *mut libc::siginfo_t, - _data: *mut libc::c_void) { - use crate::sys_common::util::report_overflow; - - let guard = thread_info::stack_guard().unwrap_or(0..0); - let addr = siginfo_si_addr(info); - - // If the faulting address is within the guard page, then we print a - // message saying so and abort. - if guard.start <= addr && addr < guard.end { - report_overflow(); - rtabort!("stack overflow"); - } else { - // Unregister ourselves by reverting back to the default behavior. - let mut action: sigaction = mem::zeroed(); - action.sa_sigaction = SIG_DFL; - sigaction(signum, &action, ptr::null_mut()); - - // See comment above for why this function returns. - } - } - - static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut(); - - pub unsafe fn init() { - let mut action: sigaction = mem::zeroed(); - action.sa_flags = SA_SIGINFO | SA_ONSTACK; - action.sa_sigaction = signal_handler as sighandler_t; - sigaction(SIGSEGV, &action, ptr::null_mut()); - sigaction(SIGBUS, &action, ptr::null_mut()); - - let handler = make_handler(); - MAIN_ALTSTACK = handler._data; - mem::forget(handler); - } - - pub unsafe fn cleanup() { - Handler { _data: MAIN_ALTSTACK }; - } - - unsafe fn get_stackp() -> *mut libc::c_void { - let stackp = mmap(ptr::null_mut(), - SIGSTKSZ, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, - -1, - 0); - if stackp == MAP_FAILED { - panic!("failed to allocate an alternative stack"); - } - stackp - } - - #[cfg(any(target_os = "linux", - target_os = "macos", - target_os = "bitrig", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd", - target_os = "solaris"))] - unsafe fn get_stack() -> libc::stack_t { - libc::stack_t { ss_sp: get_stackp(), ss_flags: 0, ss_size: SIGSTKSZ } - } - - #[cfg(target_os = "dragonfly")] - unsafe fn get_stack() -> libc::stack_t { - libc::stack_t { ss_sp: get_stackp() as *mut i8, ss_flags: 0, ss_size: SIGSTKSZ } - } - - pub unsafe fn make_handler() -> Handler { - let mut stack = mem::zeroed(); - sigaltstack(ptr::null(), &mut stack); - // Configure alternate signal stack, if one is not already set. - if stack.ss_flags & SS_DISABLE != 0 { - stack = get_stack(); - sigaltstack(&stack, ptr::null_mut()); - Handler { _data: stack.ss_sp as *mut libc::c_void } - } else { - Handler { _data: ptr::null_mut() } - } - } - - pub unsafe fn drop_handler(handler: &mut Handler) { - if !handler._data.is_null() { - let stack = libc::stack_t { - ss_sp: ptr::null_mut(), - ss_flags: SS_DISABLE, - // Workaround for bug in macOS implementation of sigaltstack - // UNIX2003 which returns ENOMEM when disabling a stack while - // passing ss_size smaller than MINSIGSTKSZ. According to POSIX - // both ss_sp and ss_size should be ignored in this case. - ss_size: SIGSTKSZ, - }; - sigaltstack(&stack, ptr::null_mut()); - munmap(handler._data, SIGSTKSZ); - } - } -} - -#[cfg(not(any(target_os = "linux", - target_os = "macos", - target_os = "bitrig", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "solaris", - all(target_os = "netbsd", not(target_vendor = "rumprun")), - target_os = "openbsd")))] mod imp { use crate::ptr; diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs index 810dbad7284e3..58af8cbe48e36 100644 --- a/src/libstd/sys/vxworks/thread.rs +++ b/src/libstd/sys/vxworks/thread.rs @@ -1,4 +1,3 @@ -//use crate::boxed::FnBox; use crate::cmp; use crate::ffi::CStr; use crate::io; @@ -9,10 +8,7 @@ use crate::time::Duration; use crate::sys_common::thread::*; -#[cfg(not(target_os = "l4re"))] pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024; -#[cfg(target_os = "l4re")] -pub const DEFAULT_MIN_STACK_SIZE: usize = 1024 * 1024; pub struct Thread { id: libc::pthread_t, @@ -25,18 +21,11 @@ unsafe impl Sync for Thread {} // The pthread_attr_setstacksize symbol doesn't exist in the emscripten libc, // so we have to not link to it to satisfy emcc's ERROR_ON_UNDEFINED_SYMBOLS. -#[cfg(not(target_os = "emscripten"))] unsafe fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t, stack_size: libc::size_t) -> libc::c_int { libc::pthread_attr_setstacksize(attr, stack_size) } -#[cfg(target_os = "emscripten")] -unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t, - _stack_size: libc::size_t) -> libc::c_int { - panic!() -} - impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements pub unsafe fn new(stack: usize, p: Box) @@ -149,31 +138,6 @@ pub mod guard { pub unsafe fn deinit() {} } -// glibc >= 2.15 has a __pthread_get_minstack() function that returns -// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local -// storage. We need that information to avoid blowing up when a small stack -// is created in an application with big thread-local storage requirements. -// See #6233 for rationale and details. -#[cfg(target_os = "linux")] -#[allow(deprecated)] -fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize { - weak!(fn __pthread_get_minstack(*const libc::pthread_attr_t) -> libc::size_t); - - match __pthread_get_minstack.get() { - None => libc::PTHREAD_STACK_MIN, - Some(f) => unsafe { f(attr) }, - } -} - -// No point in looking up __pthread_get_minstack() on non-glibc -// platforms. -#[cfg(all(not(target_os = "linux"), - not(target_os = "netbsd")))] fn min_stack_size(_: *const libc::pthread_attr_t) -> usize { libc::PTHREAD_STACK_MIN } - -#[cfg(target_os = "netbsd")] -fn min_stack_size(_: *const libc::pthread_attr_t) -> usize { - 2048 // just a guess -} diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index ae1979540ff8d..dbf14daa30e75 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -92,7 +92,6 @@ use rustc_data_structures::sync::Lrc; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::mem; use std::ops::{Deref, DerefMut}; -use std::rc::Rc; // To avoid costly uniqueness checks, we require that `MatchSeq` always has a nonempty body. @@ -280,7 +279,7 @@ pub enum ParseResult { /// A `ParseResult` where the `Success` variant contains a mapping of `Ident`s to `NamedMatch`es. /// This represents the mapping of metavars to the token trees they bind to. -pub type NamedParseResult = ParseResult>>; +pub type NamedParseResult = ParseResult>; /// Count how many metavars are named in the given matcher `ms`. pub fn count_names(ms: &[TokenTree]) -> usize { @@ -373,7 +372,7 @@ fn nameize>( sess: &ParseSess, m: &TokenTree, res: &mut I, - ret_val: &mut FxHashMap>, + ret_val: &mut FxHashMap, ) -> Result<(), (syntax_pos::Span, String)> { match *m { TokenTree::Sequence(_, ref seq) => for next_m in &seq.tts { @@ -390,8 +389,7 @@ fn nameize>( TokenTree::MetaVarDecl(sp, bind_name, _) => { match ret_val.entry(bind_name) { Vacant(spot) => { - // FIXME(simulacrum): Don't construct Rc here - spot.insert(Rc::new(res.next().unwrap())); + spot.insert(res.next().unwrap()); } Occupied(..) => { return Err((sp, format!("duplicated bind name: {}", bind_name))) diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 4503cea0f10c8..817d8547e8760 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -308,7 +308,7 @@ pub fn compile( let mut valid = true; // Extract the arguments: - let lhses = match *argument_map[&lhs_nm] { + let lhses = match argument_map[&lhs_nm] { MatchedSeq(ref s, _) => s .iter() .map(|m| { @@ -335,7 +335,7 @@ pub fn compile( _ => sess.span_diagnostic.span_bug(def.span, "wrong-structured lhs"), }; - let rhses = match *argument_map[&rhs_nm] { + let rhses = match argument_map[&rhs_nm] { MatchedSeq(ref s, _) => s .iter() .map(|m| { @@ -625,38 +625,37 @@ impl FirstSets { return first; } TokenTree::Sequence(sp, ref seq_rep) => { - match self.first.get(&sp.entire()) { - Some(&Some(ref subfirst)) => { - // If the sequence contents can be empty, then the first - // token could be the separator token itself. - - if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) { - first.add_one_maybe(TokenTree::Token(sep.clone())); - } - - assert!(first.maybe_empty); - first.add_all(subfirst); - if subfirst.maybe_empty - || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore - || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne - { - // continue scanning for more first - // tokens, but also make sure we - // restore empty-tracking state - first.maybe_empty = true; - continue; - } else { - return first; - } - } - + let subfirst_owned; + let subfirst = match self.first.get(&sp.entire()) { + Some(&Some(ref subfirst)) => subfirst, Some(&None) => { - panic!("assume all sequences have (unique) spans for now"); + subfirst_owned = self.first(&seq_rep.tts[..]); + &subfirst_owned } - None => { panic!("We missed a sequence during FirstSets construction"); } + }; + + // If the sequence contents can be empty, then the first + // token could be the separator token itself. + if let (Some(sep), true) = (&seq_rep.separator, subfirst.maybe_empty) { + first.add_one_maybe(TokenTree::Token(sep.clone())); + } + + assert!(first.maybe_empty); + first.add_all(subfirst); + if subfirst.maybe_empty + || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrMore + || seq_rep.kleene.op == quoted::KleeneOp::ZeroOrOne + { + // Continue scanning for more first + // tokens, but also make sure we + // restore empty-tracking state. + first.maybe_empty = true; + continue; + } else { + return first; } } } diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index fa93c5a904eb0..214e721fd1506 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -12,7 +12,6 @@ use smallvec::{smallvec, SmallVec}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; use std::mem; -use std::rc::Rc; /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`). enum Frame { @@ -65,9 +64,9 @@ impl Iterator for Frame { /// `transcribe` would return a `TokenStream` containing `println!("{}", stringify!(bar));`. /// /// Along the way, we do some additional error checking. -pub fn transcribe( +pub(super) fn transcribe( cx: &ExtCtxt<'_>, - interp: &FxHashMap>, + interp: &FxHashMap, src: Vec, ) -> TokenStream { // Nothing for us to transcribe... @@ -212,7 +211,7 @@ pub fn transcribe( // Find the matched nonterminal from the macro invocation, and use it to replace // the meta-var. if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) { - if let MatchedNonterminal(ref nt) = *cur_matched { + if let MatchedNonterminal(ref nt) = cur_matched { // FIXME #2887: why do we apply a mark when matching a token tree meta-var // (e.g. `$x:tt`), but not when we are matching any other type of token // tree? @@ -273,18 +272,17 @@ pub fn transcribe( /// See the definition of `repeats` in the `transcribe` function. `repeats` is used to descend /// into the right place in nested matchers. If we attempt to descend too far, the macro writer has /// made a mistake, and we return `None`. -fn lookup_cur_matched( +fn lookup_cur_matched<'a>( ident: Ident, - interpolations: &FxHashMap>, + interpolations: &'a FxHashMap, repeats: &[(usize, usize)], -) -> Option> { +) -> Option<&'a NamedMatch> { interpolations.get(&ident).map(|matched| { - let mut matched = matched.clone(); + let mut matched = matched; for &(idx, _) in repeats { - let m = matched.clone(); - match *m { + match matched { MatchedNonterminal(_) => break, - MatchedSeq(ref ads, _) => matched = Rc::new(ads[idx].clone()), + MatchedSeq(ref ads, _) => matched = ads.get(idx).unwrap(), } } @@ -343,7 +341,7 @@ impl LockstepIterSize { /// multiple nested matcher sequences. fn lockstep_iter_size( tree: "ed::TokenTree, - interpolations: &FxHashMap>, + interpolations: &FxHashMap, repeats: &[(usize, usize)], ) -> LockstepIterSize { use quoted::TokenTree; @@ -360,7 +358,7 @@ fn lockstep_iter_size( } TokenTree::MetaVar(_, name) | TokenTree::MetaVarDecl(_, name, _) => { match lookup_cur_matched(name, interpolations, repeats) { - Some(matched) => match *matched { + Some(matched) => match matched { MatchedNonterminal(_) => LockstepIterSize::Unconstrained, MatchedSeq(ref ads, _) => LockstepIterSize::Constraint(ads.len(), name), }, diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index b97801a50d472..52f65e1b47475 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -389,8 +389,18 @@ impl<'a> StringReader<'a> { self.pos, "unknown start of token", c); - unicode_chars::check_for_substitution(self, start, c, &mut err); - return Err(err) + // FIXME: the lexer could be used to turn the ASCII version of unicode homoglyphs, + // instead of keeping a table in `check_for_substitution`into the token. Ideally, + // this should be inside `rustc_lexer`. However, we should first remove compound + // tokens like `<<` from `rustc_lexer`, and then add fancier error recovery to it, + // as there will be less overall work to do this way. + return match unicode_chars::check_for_substitution(self, start, c, &mut err) { + Some(token) => { + err.emit(); + Ok(token) + } + None => Err(err), + } } }; Ok(kind) diff --git a/src/libsyntax/parse/lexer/unicode_chars.rs b/src/libsyntax/parse/lexer/unicode_chars.rs index b728a9e1988c8..eaa736c6a3517 100644 --- a/src/libsyntax/parse/lexer/unicode_chars.rs +++ b/src/libsyntax/parse/lexer/unicode_chars.rs @@ -3,7 +3,8 @@ use super::StringReader; use errors::{Applicability, DiagnosticBuilder}; -use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION}; +use syntax_pos::{BytePos, Pos, Span, NO_EXPANSION, symbol::kw}; +use crate::parse::token; #[rustfmt::skip] // for line breaks const UNICODE_ARRAY: &[(char, &str, char)] = &[ @@ -297,32 +298,38 @@ const UNICODE_ARRAY: &[(char, &str, char)] = &[ ('>', "Fullwidth Greater-Than Sign", '>'), ]; -const ASCII_ARRAY: &[(char, &str)] = &[ - (' ', "Space"), - ('_', "Underscore"), - ('-', "Minus/Hyphen"), - (',', "Comma"), - (';', "Semicolon"), - (':', "Colon"), - ('!', "Exclamation Mark"), - ('?', "Question Mark"), - ('.', "Period"), - ('\'', "Single Quote"), - ('"', "Quotation Mark"), - ('(', "Left Parenthesis"), - (')', "Right Parenthesis"), - ('[', "Left Square Bracket"), - (']', "Right Square Bracket"), - ('{', "Left Curly Brace"), - ('}', "Right Curly Brace"), - ('*', "Asterisk"), - ('/', "Slash"), - ('\\', "Backslash"), - ('&', "Ampersand"), - ('+', "Plus Sign"), - ('<', "Less-Than Sign"), - ('=', "Equals Sign"), - ('>', "Greater-Than Sign"), +// FIXME: the lexer could be used to turn the ASCII version of unicode homoglyphs, instead of +// keeping the substitution token in this table. Ideally, this should be inside `rustc_lexer`. +// However, we should first remove compound tokens like `<<` from `rustc_lexer`, and then add +// fancier error recovery to it, as there will be less overall work to do this way. +const ASCII_ARRAY: &[(char, &str, Option)] = &[ + (' ', "Space", Some(token::Whitespace)), + ('_', "Underscore", Some(token::Ident(kw::Underscore, false))), + ('-', "Minus/Hyphen", Some(token::BinOp(token::Minus))), + (',', "Comma", Some(token::Comma)), + (';', "Semicolon", Some(token::Semi)), + (':', "Colon", Some(token::Colon)), + ('!', "Exclamation Mark", Some(token::Not)), + ('?', "Question Mark", Some(token::Question)), + ('.', "Period", Some(token::Dot)), + ('(', "Left Parenthesis", Some(token::OpenDelim(token::Paren))), + (')', "Right Parenthesis", Some(token::CloseDelim(token::Paren))), + ('[', "Left Square Bracket", Some(token::OpenDelim(token::Bracket))), + (']', "Right Square Bracket", Some(token::CloseDelim(token::Bracket))), + ('{', "Left Curly Brace", Some(token::OpenDelim(token::Brace))), + ('}', "Right Curly Brace", Some(token::CloseDelim(token::Brace))), + ('*', "Asterisk", Some(token::BinOp(token::Star))), + ('/', "Slash", Some(token::BinOp(token::Slash))), + ('\\', "Backslash", None), + ('&', "Ampersand", Some(token::BinOp(token::And))), + ('+', "Plus Sign", Some(token::BinOp(token::Plus))), + ('<', "Less-Than Sign", Some(token::Lt)), + ('=', "Equals Sign", Some(token::Eq)), + ('>', "Greater-Than Sign", Some(token::Gt)), + // FIXME: Literals are already lexed by this point, so we can't recover gracefully just by + // spitting the correct token out. + ('\'', "Single Quote", None), + ('"', "Quotation Mark", None), ]; crate fn check_for_substitution<'a>( @@ -330,20 +337,20 @@ crate fn check_for_substitution<'a>( pos: BytePos, ch: char, err: &mut DiagnosticBuilder<'a>, -) -> bool { +) -> Option { let (u_name, ascii_char) = match UNICODE_ARRAY.iter().find(|&&(c, _, _)| c == ch) { Some(&(_u_char, u_name, ascii_char)) => (u_name, ascii_char), - None => return false, + None => return None, }; let span = Span::new(pos, pos + Pos::from_usize(ch.len_utf8()), NO_EXPANSION); - let ascii_name = match ASCII_ARRAY.iter().find(|&&(c, _)| c == ascii_char) { - Some((_ascii_char, ascii_name)) => ascii_name, + let (ascii_name, token) = match ASCII_ARRAY.iter().find(|&&(c, _, _)| c == ascii_char) { + Some((_ascii_char, ascii_name, token)) => (ascii_name, token), None => { let msg = format!("substitution character not found for '{}'", ch); reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); - return false; + return None; } }; @@ -371,7 +378,7 @@ crate fn check_for_substitution<'a>( ); err.span_suggestion(span, &msg, ascii_char.to_string(), Applicability::MaybeIncorrect); } - true + token.clone() } /// Extract string if found at current position with given delimiters diff --git a/src/test/mir-opt/lower_128bit_debug_test.rs b/src/test/mir-opt/lower_128bit_debug_test.rs deleted file mode 100644 index 1d23bac4ee206..0000000000000 --- a/src/test/mir-opt/lower_128bit_debug_test.rs +++ /dev/null @@ -1,226 +0,0 @@ -// asmjs can't even pass i128 as arguments or return values, so ignore it. -// this will hopefully be fixed by the LLVM 5 upgrade (#43370) -// ignore-asmjs -// ignore-emscripten - -// compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=yes - -static TEST_SIGNED: i128 = const_signed(-222); -static TEST_UNSIGNED: u128 = const_unsigned(200); - -const fn const_signed(mut x: i128) -> i128 { - ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7 -} - -const fn const_unsigned(mut x: u128) -> u128 { - ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7 -} - -fn test_signed(mut x: i128) -> i128 { - x += 1; - x -= 2; - x *= 3; - x /= 4; - x %= 5; - x <<= 6; - x >>= 7; - x -} - -fn test_unsigned(mut x: u128) -> u128 { - x += 1; - x -= 2; - x *= 3; - x /= 4; - x %= 5; - x <<= 6; - x >>= 7; - x -} - -fn check(x: i128, y: u128) { - assert_eq!(test_signed(x), -1); - assert_eq!(const_signed(x), -1); - assert_eq!(TEST_SIGNED, -1); - assert_eq!(test_unsigned(y), 2); - assert_eq!(const_unsigned(y), 2); - assert_eq!(TEST_UNSIGNED, 2); -} - -fn main() { - check(-222, 200); -} - -// END RUST SOURCE - -// START rustc.const_signed.Lower128Bit.after.mir -// _8 = _1; -// _9 = const compiler_builtins::int::addsub::rust_i128_addo(move _8, const 1i128) -> bb10; -// ... -// _7 = move (_9.0: i128); -// ... -// _10 = const compiler_builtins::int::addsub::rust_i128_subo(move _7, const 2i128) -> bb11; -// ... -// _6 = move (_10.0: i128); -// ... -// _11 = const compiler_builtins::int::mul::rust_i128_mulo(move _6, const 3i128) -> bb12; -// ... -// _5 = move (_11.0: i128); -// ... -// _12 = Eq(const 4i128, const 0i128); -// assert(!move _12, "attempt to divide by zero") -> bb4; -// ... -// _13 = Eq(const 4i128, const -1i128); -// _14 = Eq(_5, const -170141183460469231731687303715884105728i128); -// _15 = BitAnd(move _13, move _14); -// assert(!move _15, "attempt to divide with overflow") -> bb5; -// ... -// _4 = const compiler_builtins::int::sdiv::rust_i128_div(move _5, const 4i128) -> bb13; -// ... -// _17 = Eq(const 5i128, const -1i128); -// _18 = Eq(_4, const -170141183460469231731687303715884105728i128); -// _19 = BitAnd(move _17, move _18); -// assert(!move _19, "attempt to calculate the remainder with overflow") -> bb7; -// ... -// _3 = const compiler_builtins::int::sdiv::rust_i128_rem(move _4, const 5i128) -> bb15; -// ... -// _2 = move (_20.0: i128); -// ... -// _23 = const 7i32 as u128 (Misc); -// _21 = const compiler_builtins::int::shift::rust_i128_shro(move _2, move _23) -> bb16; -// ... -// _0 = move (_21.0: i128); -// ... -// assert(!move (_9.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_10.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_11.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// _16 = Eq(const 5i128, const 0i128); -// assert(!move _16, "attempt to calculate the remainder with a divisor of zero") -> bb6; -// ... -// assert(!move (_20.1: bool), "attempt to shift left with overflow") -> bb8; -// ... -// _22 = const 6i32 as u128 (Misc); -// _20 = const compiler_builtins::int::shift::rust_i128_shlo(move _3, move _22) -> bb14; -// ... -// assert(!move (_21.1: bool), "attempt to shift right with overflow") -> bb9; -// END rustc.const_signed.Lower128Bit.after.mir - -// START rustc.const_unsigned.Lower128Bit.after.mir -// _8 = _1; -// _9 = const compiler_builtins::int::addsub::rust_u128_addo(move _8, const 1u128) -> bb8; -// ... -// _7 = move (_9.0: u128); -// ... -// _10 = const compiler_builtins::int::addsub::rust_u128_subo(move _7, const 2u128) -> bb9; -// ... -// _6 = move (_10.0: u128); -// ... -// _11 = const compiler_builtins::int::mul::rust_u128_mulo(move _6, const 3u128) -> bb10; -// ... -// _5 = move (_11.0: u128); -// ... -// _12 = Eq(const 4u128, const 0u128); -// assert(!move _12, "attempt to divide by zero") -> bb4; -// ... -// _4 = const compiler_builtins::int::udiv::rust_u128_div(move _5, const 4u128) -> bb11; -// ... -// _3 = const compiler_builtins::int::udiv::rust_u128_rem(move _4, const 5u128) -> bb13; -// ... -// _2 = move (_14.0: u128); -// ... -// _17 = const 7i32 as u128 (Misc); -// _15 = const compiler_builtins::int::shift::rust_u128_shro(move _2, move _17) -> bb14; -// ... -// _0 = move (_15.0: u128); -// ... -// assert(!move (_9.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_10.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_11.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// _13 = Eq(const 5u128, const 0u128); -// assert(!move _13, "attempt to calculate the remainder with a divisor of zero") -> bb5; -// ... -// assert(!move (_14.1: bool), "attempt to shift left with overflow") -> bb6; -// ... -// _16 = const 6i32 as u128 (Misc); -// _14 = const compiler_builtins::int::shift::rust_u128_shlo(move _3, move _16) -> bb12; -// ... -// assert(!move (_15.1: bool), "attempt to shift right with overflow") -> bb7; -// END rustc.const_unsigned.Lower128Bit.after.mir - -// START rustc.test_signed.Lower128Bit.after.mir -// _2 = const compiler_builtins::int::addsub::rust_i128_addo(_1, const 1i128) -> bb10; -// ... -// _1 = move (_2.0: i128); -// _3 = const compiler_builtins::int::addsub::rust_i128_subo(_1, const 2i128) -> bb11; -// ... -// _1 = move (_3.0: i128); -// _4 = const compiler_builtins::int::mul::rust_i128_mulo(_1, const 3i128) -> bb12; -// ... -// _1 = move (_4.0: i128); -// ... -// _1 = const compiler_builtins::int::sdiv::rust_i128_div(_1, const 4i128) -> bb13; -// ... -// _1 = const compiler_builtins::int::sdiv::rust_i128_rem(_1, const 5i128) -> bb15; -// ... -// _1 = move (_13.0: i128); -// ... -// _16 = const 7i32 as u128 (Misc); -// _14 = const compiler_builtins::int::shift::rust_i128_shro(_1, move _16) -> bb16; -// ... -// _1 = move (_14.0: i128); -// ... -// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_3.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_4.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// assert(!move (_13.1: bool), "attempt to shift left with overflow") -> bb8; -// ... -// _15 = const 6i32 as u128 (Misc); -// _13 = const compiler_builtins::int::shift::rust_i128_shlo(_1, move _15) -> bb14; -// ... -// assert(!move (_14.1: bool), "attempt to shift right with overflow") -> bb9; -// END rustc.test_signed.Lower128Bit.after.mir - -// START rustc.test_unsigned.Lower128Bit.after.mir -// _2 = const compiler_builtins::int::addsub::rust_u128_addo(_1, const 1u128) -> bb8; -// ... -// _1 = move (_2.0: u128); -// _3 = const compiler_builtins::int::addsub::rust_u128_subo(_1, const 2u128) -> bb9; -// ... -// _1 = move (_3.0: u128); -// _4 = const compiler_builtins::int::mul::rust_u128_mulo(_1, const 3u128) -> bb10; -// ... -// _1 = move (_4.0: u128); -// ... -// _1 = const compiler_builtins::int::udiv::rust_u128_div(_1, const 4u128) -> bb11; -// ... -// _1 = const compiler_builtins::int::udiv::rust_u128_rem(_1, const 5u128) -> bb13; -// ... -// _1 = move (_7.0: u128); -// ... -// _10 = const 7i32 as u128 (Misc); -// _8 = const compiler_builtins::int::shift::rust_u128_shro(_1, move _10) -> bb14; -// ... -// _1 = move (_8.0: u128); -// ... -// assert(!move (_2.1: bool), "attempt to add with overflow") -> bb1; -// ... -// assert(!move (_3.1: bool), "attempt to subtract with overflow") -> bb2; -// ... -// assert(!move (_4.1: bool), "attempt to multiply with overflow") -> bb3; -// ... -// assert(!move (_7.1: bool), "attempt to shift left with overflow") -> bb6; -// ... -// _9 = const 6i32 as u128 (Misc); -// _7 = const compiler_builtins::int::shift::rust_u128_shlo(_1, move _9) -> bb12; -// ... -// assert(!move (_8.1: bool), "attempt to shift right with overflow") -> bb7; -// END rustc.test_unsigned.Lower128Bit.after.mir diff --git a/src/test/mir-opt/lower_128bit_test.rs b/src/test/mir-opt/lower_128bit_test.rs deleted file mode 100644 index 7528330b030ce..0000000000000 --- a/src/test/mir-opt/lower_128bit_test.rs +++ /dev/null @@ -1,149 +0,0 @@ -// ignore-emscripten - -// compile-flags: -Z lower_128bit_ops=yes -C debug_assertions=no -O - -static TEST_SIGNED: i128 = const_signed(-222); -static TEST_UNSIGNED: u128 = const_unsigned(200); - -const fn const_signed(mut x: i128) -> i128 { - ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7 -} - -const fn const_unsigned(mut x: u128) -> u128 { - ((((((x + 1) - 2) * 3) / 4) % 5) << 6) >> 7 -} - -fn test_signed(mut x: i128) -> i128 { - x += 1; - x -= 2; - x *= 3; - x /= 4; - x %= 5; - x <<= 6; - x >>= 7; - x -} - -fn test_unsigned(mut x: u128) -> u128 { - x += 1; - x -= 2; - x *= 3; - x /= 4; - x %= 5; - x <<= 6; - x >>= 7; - x -} - -fn check(x: i128, y: u128) { - assert_eq!(test_signed(x), -1); - assert_eq!(const_signed(x), -1); - assert_eq!(TEST_SIGNED, -1); - assert_eq!(test_unsigned(y), 2); - assert_eq!(const_unsigned(y), 2); - assert_eq!(TEST_UNSIGNED, 2); -} - -fn main() { - check(-222, 200); -} - -// END RUST SOURCE - -// START rustc.const_signed.Lower128Bit.after.mir -// _7 = const compiler_builtins::int::addsub::rust_i128_add(move _8, const 1i128) -> bb7; -// ... -// _10 = Eq(const 4i128, const -1i128); -// _11 = Eq(_5, const -170141183460469231731687303715884105728i128); -// _12 = BitAnd(move _10, move _11); -// assert(!move _12, "attempt to divide with overflow") -> bb2; -// ... -// _4 = const compiler_builtins::int::sdiv::rust_i128_div(move _5, const 4i128) -> bb8; -// ... -// _14 = Eq(const 5i128, const -1i128); -// _15 = Eq(_4, const -170141183460469231731687303715884105728i128); -// _16 = BitAnd(move _14, move _15); -// assert(!move _16, "attempt to calculate the remainder with overflow") -> bb4; -// ... -// _3 = const compiler_builtins::int::sdiv::rust_i128_rem(move _4, const 5i128) -> bb11; -// ... -// _9 = Eq(const 4i128, const 0i128); -// assert(!move _9, "attempt to divide by zero") -> bb1; -// ... -// _5 = const compiler_builtins::int::mul::rust_i128_mul(move _6, const 3i128) -> bb5; -// ... -// _6 = const compiler_builtins::int::addsub::rust_i128_sub(move _7, const 2i128) -> bb6; -// ... -// _13 = Eq(const 5i128, const 0i128); -// assert(!move _13, "attempt to calculate the remainder with a divisor of zero") -> bb3; -// ... -// _17 = const 7i32 as u32 (Misc); -// _0 = const compiler_builtins::int::shift::rust_i128_shr(move _2, move _17) -> bb9; -// ... -// _18 = const 6i32 as u32 (Misc); -// _2 = const compiler_builtins::int::shift::rust_i128_shl(move _3, move _18) -> bb10; -// END rustc.const_signed.Lower128Bit.after.mir - -// START rustc.const_unsigned.Lower128Bit.after.mir -// _8 = _1; -// _7 = const compiler_builtins::int::addsub::rust_u128_add(move _8, const 1u128) -> bb5; -// ... -// _4 = const compiler_builtins::int::udiv::rust_u128_div(move _5, const 4u128) -> bb6; -// ... -// _3 = const compiler_builtins::int::udiv::rust_u128_rem(move _4, const 5u128) -> bb9; -// ... -// _9 = Eq(const 4u128, const 0u128); -// assert(!move _9, "attempt to divide by zero") -> bb1; -// ... -// _5 = const compiler_builtins::int::mul::rust_u128_mul(move _6, const 3u128) -> bb3; -// ... -// _6 = const compiler_builtins::int::addsub::rust_u128_sub(move _7, const 2u128) -> bb4; -// ... -// _10 = Eq(const 5u128, const 0u128); -// assert(!move _10, "attempt to calculate the remainder with a divisor of zero") -> bb2; -// ... -// return; -// ... -// _11 = const 7i32 as u32 (Misc); -// _0 = const compiler_builtins::int::shift::rust_u128_shr(move _2, move _11) -> bb7; -// ... -// _12 = const 6i32 as u32 (Misc); -// _2 = const compiler_builtins::int::shift::rust_u128_shl(move _3, move _12) -> bb8; - -// END rustc.const_unsigned.Lower128Bit.after.mir - -// START rustc.test_signed.Lower128Bit.after.mir -// _1 = const compiler_builtins::int::addsub::rust_i128_add(_1, const 1i128) -> bb7; -// ... -// _1 = const compiler_builtins::int::sdiv::rust_i128_div(_1, const 4i128) -> bb8; -// ... -// _1 = const compiler_builtins::int::sdiv::rust_i128_rem(_1, const 5i128) -> bb11; -// ... -// _1 = const compiler_builtins::int::mul::rust_i128_mul(_1, const 3i128) -> bb5; -// ... -// _1 = const compiler_builtins::int::addsub::rust_i128_sub(_1, const 2i128) -> bb6; -// ... -// _10 = const 7i32 as u32 (Misc); -// _1 = const compiler_builtins::int::shift::rust_i128_shr(_1, move _10) -> bb9; -// ... -// _11 = const 6i32 as u32 (Misc); -// _1 = const compiler_builtins::int::shift::rust_i128_shl(_1, move _11) -> bb10; -// END rustc.test_signed.Lower128Bit.after.mir - -// START rustc.test_unsigned.Lower128Bit.after.mir -// _1 = const compiler_builtins::int::addsub::rust_u128_add(_1, const 1u128) -> bb5; -// ... -// _1 = const compiler_builtins::int::udiv::rust_u128_div(_1, const 4u128) -> bb6; -// ... -// _1 = const compiler_builtins::int::udiv::rust_u128_rem(_1, const 5u128) -> bb9; -// ... -// _1 = const compiler_builtins::int::mul::rust_u128_mul(_1, const 3u128) -> bb3; -// ... -// _1 = const compiler_builtins::int::addsub::rust_u128_sub(_1, const 2u128) -> bb4; -// ... -// _4 = const 7i32 as u32 (Misc); -// _1 = const compiler_builtins::int::shift::rust_u128_shr(_1, move _4) -> bb7; -// ... -// _5 = const 6i32 as u32 (Misc); -// _1 = const compiler_builtins::int::shift::rust_u128_shl(_1, move _5) -> bb8; -// END rustc.test_unsigned.Lower128Bit.after.mir diff --git a/src/test/run-pass/backtrace-debuginfo.rs b/src/test/run-pass/backtrace-debuginfo.rs index a2a934513d2f7..af5ccb45727a1 100644 --- a/src/test/run-pass/backtrace-debuginfo.rs +++ b/src/test/run-pass/backtrace-debuginfo.rs @@ -10,7 +10,6 @@ // ignore-pretty issue #37195 // ignore-cloudabi spawning processes is not supported // ignore-emscripten spawning processes is not supported -// ignore-msvc issue #62844 // ignore-sgx no processes // normalize-stderr-test ".*\n" -> "" diff --git a/src/test/run-pass/backtrace.rs b/src/test/run-pass/backtrace.rs index 93e8c9f172997..c73ba293ee25b 100644 --- a/src/test/run-pass/backtrace.rs +++ b/src/test/run-pass/backtrace.rs @@ -2,7 +2,6 @@ // ignore-cloudabi spawning processes is not supported // ignore-emscripten spawning processes is not supported // ignore-openbsd no support for libbacktrace without filename -// ignore-msvc issue #62844 // ignore-sgx no processes // compile-flags:-g diff --git a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs b/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs index e3faa7c625ccc..4195444a73f67 100644 --- a/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs +++ b/src/test/run-pass/simd/simd-intrinsic-generic-reduction.rs @@ -2,7 +2,7 @@ #![allow(non_camel_case_types)] // ignore-emscripten -// ignore-aarch64 FIXME: https://github.com/rust-lang/rust/issues/54510 +// min-system-llvm-version: 9.0 // Test that the simd_reduce_{op} intrinsics produce the correct results. @@ -124,14 +124,14 @@ fn main() { assert_eq!(r, 6_f32); let r: f32 = simd_reduce_mul_unordered(x); assert_eq!(r, -24_f32); - // FIXME: only works correctly for accumulator, 0: - // https://bugs.llvm.org/show_bug.cgi?id=36734 let r: f32 = simd_reduce_add_ordered(x, 0.); assert_eq!(r, 6_f32); - // FIXME: only works correctly for accumulator, 1: - // https://bugs.llvm.org/show_bug.cgi?id=36734 let r: f32 = simd_reduce_mul_ordered(x, 1.); assert_eq!(r, -24_f32); + let r: f32 = simd_reduce_add_ordered(x, 1.); + assert_eq!(r, 7_f32); + let r: f32 = simd_reduce_mul_ordered(x, 2.); + assert_eq!(r, -48_f32); let r: f32 = simd_reduce_min(x); assert_eq!(r, -2_f32); diff --git a/src/test/ui/annotate-snippet/missing-type.stderr b/src/test/ui/annotate-snippet/missing-type.stderr index 8857ae7d85034..806acf0bed5d1 100644 --- a/src/test/ui/annotate-snippet/missing-type.stderr +++ b/src/test/ui/annotate-snippet/missing-type.stderr @@ -1,6 +1,6 @@ error[E0412]: cannot find type `Iter` in this scope - --> $DIR/missing-type.rs:4:11 - | -4 | let x: Iter; - | ^^^^ not found in this scope - | + --> $DIR/missing-type.rs:4:11 + | +LL | let x: Iter; + | ^^^^ not found in this scope + | diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs index 5c2c3b8ec61d5..66d562d2eb519 100644 --- a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs +++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.rs @@ -1,5 +1,6 @@ const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² //~^ ERROR expected at least one digit in exponent //~| ERROR unknown start of token: \u{2212} +//~| ERROR cannot subtract `{integer}` from `{float}` fn main() {} diff --git a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr index 07653c791db1c..9ee86adec52d9 100644 --- a/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr +++ b/src/test/ui/did_you_mean/issue-49746-unicode-confusable-in-float-literal-expt.stderr @@ -14,5 +14,14 @@ help: Unicode character '−' (Minus Sign) looks like '-' (Minus/Hyphen), but it LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e-11; // m³⋅kg⁻¹⋅s⁻² | ^ -error: aborting due to 2 previous errors +error[E0277]: cannot subtract `{integer}` from `{float}` + --> $DIR/issue-49746-unicode-confusable-in-float-literal-expt.rs:1:53 + | +LL | const UNIVERSAL_GRAVITATIONAL_CONSTANT: f64 = 6.674e−11; // m³⋅kg⁻¹⋅s⁻² + | ^ no implementation for `{float} - {integer}` + | + = help: the trait `std::ops::Sub<{integer}>` is not implemented for `{float}` + +error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs new file mode 100644 index 0000000000000..67feb3ff6aec3 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &Some(42).as_deref(); +//~^ ERROR no method named `as_deref` found for type `std::option::Option<{integer}>` +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr new file mode 100644 index 0000000000000..345f91437b827 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref` found for type `std::option::Option<{integer}>` in the current scope + --> $DIR/option-as_deref.rs:4:29 + | +LL | let _result = &Some(42).as_deref(); + | ^^^^^^^^ help: there is a method with a similar name: `as_ref` + | + = note: the method `as_deref` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::Deref` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs new file mode 100644 index 0000000000000..56aead8d0e00d --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &mut Some(42).as_deref_mut(); +//~^ ERROR no method named `as_deref_mut` found for type `std::option::Option<{integer}>` +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr new file mode 100644 index 0000000000000..2c3a18be67c8f --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_mut` found for type `std::option::Option<{integer}>` in the current scope + --> $DIR/option-as_deref_mut.rs:4:33 + | +LL | let _result = &mut Some(42).as_deref_mut(); + | ^^^^^^^^^^^^ + | + = note: the method `as_deref_mut` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::DerefMut` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs deleted file mode 100644 index f82eafcaffa9a..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Some(42).deref(); -//~^ ERROR no method named `deref` found for type `std::option::Option<{integer}>` -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr deleted file mode 100644 index e916b7d7d3447..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-deref.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `deref` found for type `std::option::Option<{integer}>` in the current scope - --> $DIR/option-deref.rs:4:29 - | -LL | let _result = &Some(42).deref(); - | ^^^^^ - | - = note: the method `deref` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::Deref` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs new file mode 100644 index 0000000000000..1d5eabd6170b7 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &Ok(42).as_deref(); +//~^ ERROR no method named `as_deref` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr new file mode 100644 index 0000000000000..5e016748770dc --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref` found for type `std::result::Result<{integer}, _>` in the current scope + --> $DIR/result-as_deref.rs:4:27 + | +LL | let _result = &Ok(42).as_deref(); + | ^^^^^^^^ help: there is a method with a similar name: `as_ref` + | + = note: the method `as_deref` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::Deref` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs new file mode 100644 index 0000000000000..104aa3bcadff2 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &Err(41).as_deref_err(); +//~^ ERROR no method named `as_deref_err` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr new file mode 100644 index 0000000000000..6dc13da548b12 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_err.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_err` found for type `std::result::Result<_, {integer}>` in the current scope + --> $DIR/result-as_deref_err.rs:4:28 + | +LL | let _result = &Err(41).as_deref_err(); + | ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_ok` + | + = note: the method `as_deref_err` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::Deref` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs new file mode 100644 index 0000000000000..c897ab3531f0e --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &mut Ok(42).as_deref_mut(); +//~^ ERROR no method named `as_deref_mut` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr new file mode 100644 index 0000000000000..f21e97388b6f4 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_mut` found for type `std::result::Result<{integer}, _>` in the current scope + --> $DIR/result-as_deref_mut.rs:4:31 + | +LL | let _result = &mut Ok(42).as_deref_mut(); + | ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_err` + | + = note: the method `as_deref_mut` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::DerefMut` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs new file mode 100644 index 0000000000000..b7849ecb6d242 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &mut Err(41).as_deref_mut_err(); +//~^ ERROR no method named `as_deref_mut_err` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr new file mode 100644 index 0000000000000..44c0c954eeeca --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_err.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_mut_err` found for type `std::result::Result<_, {integer}>` in the current scope + --> $DIR/result-as_deref_mut_err.rs:4:32 + | +LL | let _result = &mut Err(41).as_deref_mut_err(); + | ^^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_ok` + | + = note: the method `as_deref_mut_err` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::DerefMut` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs new file mode 100644 index 0000000000000..54b695a0865f1 --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &mut Ok(42).as_deref_mut_ok(); +//~^ ERROR no method named `as_deref_mut_ok` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr new file mode 100644 index 0000000000000..b8369c9b82e1a --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut_ok.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_mut_ok` found for type `std::result::Result<{integer}, _>` in the current scope + --> $DIR/result-as_deref_mut_ok.rs:4:31 + | +LL | let _result = &mut Ok(42).as_deref_mut_ok(); + | ^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_err` + | + = note: the method `as_deref_mut_ok` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::DerefMut` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs new file mode 100644 index 0000000000000..ebb0500e8190f --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.rs @@ -0,0 +1,6 @@ +#![feature(inner_deref)] + +fn main() { + let _result = &Ok(42).as_deref_ok(); +//~^ ERROR no method named `as_deref_ok` found +} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr new file mode 100644 index 0000000000000..b26705a99e3bc --- /dev/null +++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_ok.stderr @@ -0,0 +1,12 @@ +error[E0599]: no method named `as_deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope + --> $DIR/result-as_deref_ok.rs:4:27 + | +LL | let _result = &Ok(42).as_deref_ok(); + | ^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_err` + | + = note: the method `as_deref_ok` exists but the following trait bounds were not satisfied: + `{integer} : std::ops::Deref` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs deleted file mode 100644 index 4be2000f058a5..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Err(41).deref_err(); -//~^ ERROR no method named `deref_err` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr deleted file mode 100644 index 333036127eadb..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-err.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `deref_err` found for type `std::result::Result<_, {integer}>` in the current scope - --> $DIR/result-deref-err.rs:4:28 - | -LL | let _result = &Err(41).deref_err(); - | ^^^^^^^^^ help: there is a method with a similar name: `deref_ok` - | - = note: the method `deref_err` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::Deref` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs deleted file mode 100644 index a706cde734805..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Ok(42).deref_ok(); -//~^ ERROR no method named `deref_ok` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr deleted file mode 100644 index 593705123540c..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref-ok.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `deref_ok` found for type `std::result::Result<{integer}, _>` in the current scope - --> $DIR/result-deref-ok.rs:4:27 - | -LL | let _result = &Ok(42).deref_ok(); - | ^^^^^^^^ - | - = note: the method `deref_ok` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::Deref` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs deleted file mode 100644 index 43a68e37dd0c3..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![feature(inner_deref)] - -fn main() { - let _result = &Ok(42).deref(); -//~^ ERROR no method named `deref` found -} diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr deleted file mode 100644 index 05baa7907fae0..0000000000000 --- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-deref.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0599]: no method named `deref` found for type `std::result::Result<{integer}, _>` in the current scope - --> $DIR/result-deref.rs:4:27 - | -LL | let _result = &Ok(42).deref(); - | ^^^^^ - | - = note: the method `deref` exists but the following trait bounds were not satisfied: - `{integer} : std::ops::Deref` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/macros/auxiliary/proc_macro_sequence.rs b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs new file mode 100644 index 0000000000000..b50ed7ca92ad5 --- /dev/null +++ b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs @@ -0,0 +1,36 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro_span, proc_macro_hygiene, proc_macro_quote)] + +extern crate proc_macro; + +use proc_macro::{quote, Span, TokenStream}; + +fn assert_same_span(a: Span, b: Span) { + assert_eq!(a.start(), b.start()); + assert_eq!(a.end(), b.end()); +} + +// This macro generates a macro with the same macro definition as `manual_foo` in +// `same-sequence-span.rs` but with the same span for all sequences. +#[proc_macro] +pub fn make_foo(_: TokenStream) -> TokenStream { + let result = quote! { + macro_rules! generated_foo { + (1 $$x:expr $$($$y:tt,)* $$(= $$z:tt)*) => {}; + } + }; + + // Check that all spans are equal. + let mut span = None; + for tt in result.clone() { + match span { + None => span = Some(tt.span()), + Some(span) => assert_same_span(tt.span(), span), + } + } + + result +} diff --git a/src/test/ui/macros/same-sequence-span.rs b/src/test/ui/macros/same-sequence-span.rs new file mode 100644 index 0000000000000..a4f70b6b68d1e --- /dev/null +++ b/src/test/ui/macros/same-sequence-span.rs @@ -0,0 +1,23 @@ +// aux-build:proc_macro_sequence.rs + +// Regression test for issue #62831: Check that multiple sequences with the same span in the +// left-hand side of a macro definition behave as if they had unique spans, and in particular that +// they don't crash the compiler. + +#![feature(proc_macro_hygiene)] +#![allow(unused_macros)] + +extern crate proc_macro_sequence; + +// When ignoring spans, this macro has the same macro definition as `generated_foo` in +// `proc_macro_sequence.rs`. +macro_rules! manual_foo { + (1 $x:expr $($y:tt,)* //~ERROR `$x:expr` may be followed by `$y:tt` + $(= $z:tt)* //~ERROR `$x:expr` may be followed by `=` + ) => {}; +} + +proc_macro_sequence::make_foo!(); //~ERROR `$x:expr` may be followed by `$y:tt` + //~^ERROR `$x:expr` may be followed by `=` + +fn main() {} diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr new file mode 100644 index 0000000000000..aee1b4c9c5d99 --- /dev/null +++ b/src/test/ui/macros/same-sequence-span.stderr @@ -0,0 +1,34 @@ +error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments + --> $DIR/same-sequence-span.rs:15:18 + | +LL | (1 $x:expr $($y:tt,)* + | ^^^^^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments + --> $DIR/same-sequence-span.rs:16:18 + | +LL | $(= $z:tt)* + | ^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments + --> $DIR/same-sequence-span.rs:20:1 + | +LL | proc_macro_sequence::make_foo!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: `$x:expr` may be followed by `=`, which is not allowed for `expr` fragments + --> $DIR/same-sequence-span.rs:20:1 + | +LL | proc_macro_sequence::make_foo!(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not allowed after `expr` fragments + | + = note: allowed there are: `=>`, `,` or `;` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/parser/recover-from-homoglyph.rs b/src/test/ui/parser/recover-from-homoglyph.rs new file mode 100644 index 0000000000000..99ce0d1a630df --- /dev/null +++ b/src/test/ui/parser/recover-from-homoglyph.rs @@ -0,0 +1,4 @@ +fn main() { + println!(""); //~ ERROR unknown start of token: \u{37e} + let x: usize = (); //~ ERROR mismatched types +} diff --git a/src/test/ui/parser/recover-from-homoglyph.stderr b/src/test/ui/parser/recover-from-homoglyph.stderr new file mode 100644 index 0000000000000..424d492b7ba64 --- /dev/null +++ b/src/test/ui/parser/recover-from-homoglyph.stderr @@ -0,0 +1,22 @@ +error: unknown start of token: \u{37e} + --> $DIR/recover-from-homoglyph.rs:2:17 + | +LL | println!(""); + | ^ +help: Unicode character ';' (Greek Question Mark) looks like ';' (Semicolon), but it is not + | +LL | println!(""); + | ^ + +error[E0308]: mismatched types + --> $DIR/recover-from-homoglyph.rs:3:20 + | +LL | let x: usize = (); + | ^^ expected usize, found () + | + = note: expected type `usize` + found type `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs index 8e67c27ef2255..9a6dbe9d9ab1d 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.rs @@ -30,13 +30,10 @@ fn main() { let z = f32x4(0.0, 0.0, 0.0, 0.0); unsafe { - simd_reduce_add_ordered(z, 0_f32); - simd_reduce_mul_ordered(z, 1_f32); - - simd_reduce_add_ordered(z, 2_f32); - //~^ ERROR accumulator of simd_reduce_add_ordered is not 0.0 - simd_reduce_mul_ordered(z, 3_f32); - //~^ ERROR accumulator of simd_reduce_mul_ordered is not 1.0 + simd_reduce_add_ordered(z, 0); + //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32` + simd_reduce_mul_ordered(z, 1); + //~^ ERROR expected return type `f32` (element of input `f32x4`), found `i32` let _: f32 = simd_reduce_and(x); //~^ ERROR expected return type `u32` (element of input `u32x4`), found `f32` @@ -56,16 +53,5 @@ fn main() { //~^ ERROR unsupported simd_reduce_all from `f32x4` with element `f32` to `bool` let _: bool = simd_reduce_any(z); //~^ ERROR unsupported simd_reduce_any from `f32x4` with element `f32` to `bool` - - foo(0_f32); } } - -#[inline(never)] -unsafe fn foo(x: f32) { - let z = f32x4(0.0, 0.0, 0.0, 0.0); - simd_reduce_add_ordered(z, x); - //~^ ERROR accumulator of simd_reduce_add_ordered is not a constant - simd_reduce_mul_ordered(z, x); - //~^ ERROR accumulator of simd_reduce_mul_ordered is not a constant -} diff --git a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr index 144571cb26353..3863eeac3f394 100644 --- a/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr +++ b/src/test/ui/simd-intrinsic/simd-intrinsic-generic-reduction.stderr @@ -1,74 +1,62 @@ -error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: accumulator of simd_reduce_add_ordered is not 0.0 - --> $DIR/simd-intrinsic-generic-reduction.rs:36:9 +error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32` + --> $DIR/simd-intrinsic-generic-reduction.rs:33:9 | -LL | simd_reduce_add_ordered(z, 2_f32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_reduce_add_ordered(z, 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: accumulator of simd_reduce_mul_ordered is not 1.0 - --> $DIR/simd-intrinsic-generic-reduction.rs:38:9 +error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `f32` (element of input `f32x4`), found `i32` + --> $DIR/simd-intrinsic-generic-reduction.rs:35:9 | -LL | simd_reduce_mul_ordered(z, 3_f32); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | simd_reduce_mul_ordered(z, 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:41:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:38:22 | LL | let _: f32 = simd_reduce_and(x); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:43:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:40:22 | LL | let _: f32 = simd_reduce_or(x); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: expected return type `u32` (element of input `u32x4`), found `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:45:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:42:22 | LL | let _: f32 = simd_reduce_xor(x); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_and` intrinsic: unsupported simd_reduce_and from `f32x4` with element `f32` to `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:48:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:45:22 | LL | let _: f32 = simd_reduce_and(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_or` intrinsic: unsupported simd_reduce_or from `f32x4` with element `f32` to `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:50:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:47:22 | LL | let _: f32 = simd_reduce_or(z); | ^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_xor` intrinsic: unsupported simd_reduce_xor from `f32x4` with element `f32` to `f32` - --> $DIR/simd-intrinsic-generic-reduction.rs:52:22 + --> $DIR/simd-intrinsic-generic-reduction.rs:49:22 | LL | let _: f32 = simd_reduce_xor(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_all` intrinsic: unsupported simd_reduce_all from `f32x4` with element `f32` to `bool` - --> $DIR/simd-intrinsic-generic-reduction.rs:55:23 + --> $DIR/simd-intrinsic-generic-reduction.rs:52:23 | LL | let _: bool = simd_reduce_all(z); | ^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `simd_reduce_any` intrinsic: unsupported simd_reduce_any from `f32x4` with element `f32` to `bool` - --> $DIR/simd-intrinsic-generic-reduction.rs:57:23 + --> $DIR/simd-intrinsic-generic-reduction.rs:54:23 | LL | let _: bool = simd_reduce_any(z); | ^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_reduce_add_ordered` intrinsic: accumulator of simd_reduce_add_ordered is not a constant - --> $DIR/simd-intrinsic-generic-reduction.rs:67:5 - | -LL | simd_reduce_add_ordered(z, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: accumulator of simd_reduce_mul_ordered is not a constant - --> $DIR/simd-intrinsic-generic-reduction.rs:69:5 - | -LL | simd_reduce_mul_ordered(z, x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 12 previous errors +error: aborting due to 10 previous errors