From 652f34d2709ec0c323ae632ba14992f80ebf7629 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 12 Sep 2020 01:15:28 -0700 Subject: [PATCH 01/18] Add [T]::as_chunks_mut (as unstable) Allows getting the slices directly, rather than just through an iterator as in `array_chunks(_mut)`. The constructors for those iterators are then written in terms of these methods, so the iterator constructors no longer have any `unsafe` of their own. --- library/core/src/slice/iter.rs | 19 ++-------- library/core/src/slice/mod.rs | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 15 deletions(-) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 793cbf994956f..9c58153316aa5 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -2102,13 +2102,8 @@ pub struct ArrayChunks<'a, T: 'a, const N: usize> { impl<'a, T, const N: usize> ArrayChunks<'a, T, N> { #[inline] pub(super) fn new(slice: &'a [T]) -> Self { - let len = slice.len() / N; - let (fst, snd) = slice.split_at(len * N); - // SAFETY: We cast a slice of `len * N` elements into - // a slice of `len` many `N` elements chunks. - let array_slice: &[[T; N]] = unsafe { from_raw_parts(fst.as_ptr().cast(), len) }; - - Self { iter: array_slice.iter(), rem: snd } + let (array_slice, rem) = slice.as_chunks(); + Self { iter: array_slice.iter(), rem } } /// Returns the remainder of the original slice that is not going to be @@ -2229,14 +2224,8 @@ pub struct ArrayChunksMut<'a, T: 'a, const N: usize> { impl<'a, T, const N: usize> ArrayChunksMut<'a, T, N> { #[inline] pub(super) fn new(slice: &'a mut [T]) -> Self { - let len = slice.len() / N; - let (fst, snd) = slice.split_at_mut(len * N); - // SAFETY: We cast a slice of `len * N` elements into - // a slice of `len` many `N` elements chunks. - unsafe { - let array_slice: &mut [[T; N]] = from_raw_parts_mut(fst.as_mut_ptr().cast(), len); - Self { iter: array_slice.iter_mut(), rem: snd } - } + let (array_slice, rem) = slice.as_chunks_mut(); + Self { iter: array_slice.iter_mut(), rem } } /// Returns the remainder of the original slice that is not going to be diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index b1ca093add581..d3591e8547525 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -883,6 +883,36 @@ impl [T] { ChunksExactMut::new(self, chunk_size) } + /// Splits the slice into a slice of `N`-element arrays, + /// starting at the beginning of the slice, + /// and a remainder slice with length strictly less than `N`. + /// + /// # Panics + /// + /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// error before this method gets stabilized. + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_as_chunks)] + /// let slice = ['l', 'o', 'r', 'e', 'm']; + /// let (chunks, remainder) = slice.as_chunks(); + /// assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]); + /// assert_eq!(remainder, &['m']); + /// ``` + #[unstable(feature = "slice_as_chunks", issue = "74985")] + #[inline] + pub fn as_chunks(&self) -> (&[[T; N]], &[T]) { + assert_ne!(N, 0); + let len = self.len() / N; + let (multiple_of_n, remainder) = self.split_at(len * N); + // SAFETY: We cast a slice of `len * N` elements into + // a slice of `len` many `N` elements chunks. + let array_slice: &[[T; N]] = unsafe { from_raw_parts(multiple_of_n.as_ptr().cast(), len) }; + (array_slice, remainder) + } + /// Returns an iterator over `N` elements of the slice at a time, starting at the /// beginning of the slice. /// @@ -917,6 +947,43 @@ impl [T] { ArrayChunks::new(self) } + /// Splits the slice into a slice of `N`-element arrays, + /// starting at the beginning of the slice, + /// and a remainder slice with length strictly less than `N`. + /// + /// # Panics + /// + /// Panics if `N` is 0. This check will most probably get changed to a compile time + /// error before this method gets stabilized. + /// + /// # Examples + /// + /// ``` + /// #![feature(slice_as_chunks)] + /// let v = &mut [0, 0, 0, 0, 0]; + /// let mut count = 1; + /// + /// let (chunks, remainder) = v.as_chunks_mut(); + /// remainder[0] = 9; + /// for chunk in chunks { + /// *chunk = [count; 2]; + /// count += 1; + /// } + /// assert_eq!(v, &[1, 1, 2, 2, 9]); + /// ``` + #[unstable(feature = "slice_as_chunks", issue = "74985")] + #[inline] + pub fn as_chunks_mut(&mut self) -> (&mut [[T; N]], &mut [T]) { + assert_ne!(N, 0); + let len = self.len() / N; + let (multiple_of_n, remainder) = self.split_at_mut(len * N); + let array_slice: &mut [[T; N]] = + // SAFETY: We cast a slice of `len * N` elements into + // a slice of `len` many `N` elements chunks. + unsafe { from_raw_parts_mut(multiple_of_n.as_mut_ptr().cast(), len) }; + (array_slice, remainder) + } + /// Returns an iterator over `N` elements of the slice at a time, starting at the /// beginning of the slice. /// From 66fa42a94627dc04de6d44227c5d06fec6b26d76 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Thu, 8 Oct 2020 15:05:31 +0200 Subject: [PATCH 02/18] allow using the system-wide llvm-libunwind as the unwinder Signed-off-by: Marc-Antoine Perennou --- config.toml.example | 3 ++- library/std/Cargo.toml | 1 + library/test/Cargo.toml | 1 + library/unwind/Cargo.toml | 1 + library/unwind/src/lib.rs | 16 +++++++++++++++- src/bootstrap/config.rs | 35 ++++++++++++++++++++++++++++++++--- src/bootstrap/configure.py | 2 +- src/bootstrap/lib.rs | 8 +++++--- 8 files changed, 58 insertions(+), 9 deletions(-) diff --git a/config.toml.example b/config.toml.example index e7e37c679e545..05bc989dc98c3 100644 --- a/config.toml.example +++ b/config.toml.example @@ -527,7 +527,8 @@ changelog-seen = 2 #test-compare-mode = false # Use LLVM libunwind as the implementation for Rust's unwinder. -#llvm-libunwind = false +# Accepted values are 'in-tree' (formerly true), 'system' or 'no' (formerly false). +#llvm-libunwind = 'no' # Enable Windows Control Flow Guard checks in the standard library. # This only applies from stage 1 onwards, and only for Windows targets. diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index c08828bc0cde9..5dfa3395ddd72 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -61,6 +61,7 @@ profiler = ["profiler_builtins"] compiler-builtins-c = ["alloc/compiler-builtins-c"] compiler-builtins-mem = ["alloc/compiler-builtins-mem"] llvm-libunwind = ["unwind/llvm-libunwind"] +system-llvm-libunwind = ["unwind/system-llvm-libunwind"] # Make panics and failed asserts immediately abort without formatting any message panic_immediate_abort = ["core/panic_immediate_abort"] diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml index e44c781113583..3d6910b107dd5 100644 --- a/library/test/Cargo.toml +++ b/library/test/Cargo.toml @@ -27,6 +27,7 @@ backtrace = ["std/backtrace"] compiler-builtins-c = ["std/compiler-builtins-c"] compiler-builtins-mem = ["std/compiler-builtins-mem"] llvm-libunwind = ["std/llvm-libunwind"] +system-llvm-libunwind = ["std/system-llvm-libunwind"] panic-unwind = ["std/panic_unwind"] panic_immediate_abort = ["std/panic_immediate_abort"] profiler = ["std/profiler"] diff --git a/library/unwind/Cargo.toml b/library/unwind/Cargo.toml index 7138d0c8fea6d..4f7a304a59f68 100644 --- a/library/unwind/Cargo.toml +++ b/library/unwind/Cargo.toml @@ -23,3 +23,4 @@ cc = { version = "1.0.1" } [features] llvm-libunwind = [] +system-llvm-libunwind = [] diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index e7fa37bc9db19..dbdefa471a9ed 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -45,10 +45,24 @@ extern "C" {} // When building with crt-static, we get `gcc_eh` from the `libc` crate, since // glibc needs it, and needs it listed later on the linker command line. We // don't want to duplicate it here. -#[cfg(all(target_os = "linux", target_env = "gnu", not(feature = "llvm-libunwind")))] +#[cfg(all( + target_os = "linux", + target_env = "gnu", + not(feature = "llvm-libunwind"), + not(feature = "system-llvm-libunwind") +))] #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] extern "C" {} +#[cfg(all( + target_os = "linux", + target_env = "gnu", + not(feature = "llvm-libunwind"), + feature = "system-llvm-libunwind" +))] +#[link(name = "unwind", cfg(not(target_feature = "crt-static")))] +extern "C" {} + #[cfg(target_os = "redox")] #[link(name = "gcc_eh", kind = "static-nobundle", cfg(target_feature = "crt-static"))] #[link(name = "gcc_s", cfg(not(target_feature = "crt-static")))] diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 3c1249f8de434..7698ff62880d6 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -10,6 +10,7 @@ use std::ffi::OsString; use std::fmt; use std::fs; use std::path::{Path, PathBuf}; +use std::str::FromStr; use crate::cache::{Interned, INTERNER}; use crate::flags::Flags; @@ -65,7 +66,7 @@ pub struct Config { pub rustc_error_format: Option, pub json_output: bool, pub test_compare_mode: bool, - pub llvm_libunwind: bool, + pub llvm_libunwind: Option, pub on_fail: Option, pub stage: u32, @@ -177,6 +178,32 @@ pub struct Config { pub out: PathBuf, } +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum LlvmLibunwind { + No, + InTree, + System, +} + +impl Default for LlvmLibunwind { + fn default() -> Self { + Self::No + } +} + +impl FromStr for LlvmLibunwind { + type Err = String; + + fn from_str(value: &str) -> Result { + match value { + "no" => Ok(Self::No), + "in-tree" => Ok(Self::InTree), + "system" => Ok(Self::System), + invalid => Err(format!("Invalid value '{}' for rust.llvm-libunwind config.", invalid)), + } + } +} + #[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct TargetSelection { pub triple: Interned, @@ -457,7 +484,7 @@ struct Rust { remap_debuginfo: Option, jemalloc: Option, test_compare_mode: Option, - llvm_libunwind: Option, + llvm_libunwind: Option, control_flow_guard: Option, new_symbol_mangling: Option, } @@ -799,7 +826,9 @@ impl Config { set(&mut config.rust_rpath, rust.rpath); set(&mut config.jemalloc, rust.jemalloc); set(&mut config.test_compare_mode, rust.test_compare_mode); - set(&mut config.llvm_libunwind, rust.llvm_libunwind); + config.llvm_libunwind = rust + .llvm_libunwind + .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind")); set(&mut config.backtrace, rust.backtrace); set(&mut config.channel, rust.channel); set(&mut config.rust_dist_src, rust.dist_src); diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index 47673ce1e8703..e156952d56f3d 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -65,7 +65,7 @@ def v(*args): v("llvm-cxxflags", "llvm.cxxflags", "build LLVM with these extra compiler flags") v("llvm-ldflags", "llvm.ldflags", "build LLVM with these extra linker flags") -o("llvm-libunwind", "rust.llvm-libunwind", "use LLVM libunwind") +v("llvm-libunwind", "rust.llvm-libunwind", "use LLVM libunwind") # Optimization and debugging options. These may be overridden by the release # channel, etc. diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 22a8e828862f7..b24c6a2c4b82f 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -121,7 +121,7 @@ use std::os::windows::fs::symlink_file; use build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed}; use filetime::FileTime; -use crate::config::TargetSelection; +use crate::config::{LlvmLibunwind, TargetSelection}; use crate::util::{exe, libdir, CiEnv}; mod builder; @@ -537,8 +537,10 @@ impl Build { fn std_features(&self) -> String { let mut features = "panic-unwind".to_string(); - if self.config.llvm_libunwind { - features.push_str(" llvm-libunwind"); + match self.config.llvm_libunwind.unwrap_or_default() { + LlvmLibunwind::InTree => features.push_str(" llvm-libunwind"), + LlvmLibunwind::System => features.push_str(" system-llvm-libunwind"), + LlvmLibunwind::No => {} } if self.config.backtrace { features.push_str(" backtrace"); From 6fdd53b7de6bbc6d8739774bd74febc31ac08e3f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 22 Oct 2020 14:40:09 +0900 Subject: [PATCH 03/18] Prefer to use `print_def_path` --- compiler/rustc_middle/src/ty/print/pretty.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index de24322e07de2..9735099a4e1ee 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -658,7 +658,7 @@ pub trait PrettyPrinter<'tcx>: let span = self.tcx().hir().span(hir_id); p!(write("@{}", self.tcx().sess.source_map().span_to_string(span))); } else { - p!(write("@{}", self.tcx().def_path_str(did))); + p!(write("@"), print_def_path(did, substs)); } } else { p!(print_def_path(did, substs)); @@ -694,7 +694,7 @@ pub trait PrettyPrinter<'tcx>: p!(write("@{}", self.tcx().sess.source_map().span_to_string(span))); } } else { - p!(write("@{}", self.tcx().def_path_str(did))); + p!(write("@"), print_def_path(did, substs)); } } else { p!(print_def_path(did, substs)); From 59232187617c6bc2c7ca1bc748b8d93fc685430f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Fri, 23 Oct 2020 14:13:37 -0400 Subject: [PATCH 04/18] Add test for bad NLL higher-ranked subtype Fixes #57642 --- .../nll/issue-57642-higher-ranked-subtype.rs | 41 +++++++++++++++++++ .../issue-57642-higher-ranked-subtype.stderr | 31 ++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/test/ui/nll/issue-57642-higher-ranked-subtype.rs create mode 100644 src/test/ui/nll/issue-57642-higher-ranked-subtype.stderr diff --git a/src/test/ui/nll/issue-57642-higher-ranked-subtype.rs b/src/test/ui/nll/issue-57642-higher-ranked-subtype.rs new file mode 100644 index 0000000000000..36c54628317e9 --- /dev/null +++ b/src/test/ui/nll/issue-57642-higher-ranked-subtype.rs @@ -0,0 +1,41 @@ +// Regression test for issue #57642 +// Tests that we reject a bad higher-ranked subtype +// with `#![feature(nll)]` + +#![feature(nll)] + +trait X { + type G; + fn make_g() -> Self::G; +} + +impl<'a> X for fn(&'a ()) { + type G = &'a (); + + fn make_g() -> Self::G { + &() + } +} + +trait Y { + type F; + fn make_f() -> Self::F; +} + +impl Y for fn(T) { + type F = fn(T); + + fn make_f() -> Self::F { + |_| {} + } +} + +fn higher_ranked_region_has_lost_its_binder() { + let x = ::make_g(); //~ ERROR no function +} + +fn magical() { + let x = ::make_f(); //~ ERROR no function +} + +fn main() {} diff --git a/src/test/ui/nll/issue-57642-higher-ranked-subtype.stderr b/src/test/ui/nll/issue-57642-higher-ranked-subtype.stderr new file mode 100644 index 0000000000000..f69098193429c --- /dev/null +++ b/src/test/ui/nll/issue-57642-higher-ranked-subtype.stderr @@ -0,0 +1,31 @@ +error[E0599]: no function or associated item named `make_g` found for fn pointer `for<'r> fn(&'r ())` in the current scope + --> $DIR/issue-57642-higher-ranked-subtype.rs:34:25 + | +LL | let x = ::make_g(); + | ^^^^^^ function or associated item not found in `for<'r> fn(&'r ())` + | + = note: the method `make_g` exists but the following trait bounds were not satisfied: + `for<'r> fn(&'r ()): X` + = help: items from traits can only be used if the trait is implemented and in scope +note: `X` defines an item `make_g`, perhaps you need to implement it + --> $DIR/issue-57642-higher-ranked-subtype.rs:7:1 + | +LL | trait X { + | ^^^^^^^ + +error[E0599]: no function or associated item named `make_f` found for fn pointer `for<'r> fn(&'r ())` in the current scope + --> $DIR/issue-57642-higher-ranked-subtype.rs:38:25 + | +LL | let x = ::make_f(); + | ^^^^^^ function or associated item not found in `for<'r> fn(&'r ())` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Y` defines an item `make_f`, perhaps you need to implement it + --> $DIR/issue-57642-higher-ranked-subtype.rs:20:1 + | +LL | trait Y { + | ^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. From cc468c0829dd159a50359441989c06834faa6a00 Mon Sep 17 00:00:00 2001 From: Olivia Crain Date: Sat, 24 Oct 2020 19:22:53 -0500 Subject: [PATCH 05/18] Use check-pass in single-use-lifetime ui test suite --- .../ui/single-use-lifetime/one-use-in-fn-return.rs | 5 +++-- src/test/ui/single-use-lifetime/one-use-in-struct.rs | 11 +++++------ .../two-uses-in-fn-argument-and-return.rs | 7 ++++--- .../single-use-lifetime/two-uses-in-fn-arguments.rs | 12 ++++++------ .../two-uses-in-inherent-impl-header.rs | 9 ++++----- .../ui/single-use-lifetime/two-uses-in-trait-impl.rs | 6 +++--- 6 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs b/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs index d9d7e66d0cae2..7b7ff08da7cac 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-fn-return.rs @@ -5,11 +5,12 @@ // (Normally, using `'static` would be preferred, but there are // times when that is not what you want.) -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![deny(single_use_lifetimes)] -fn b<'a>() -> &'a u32 { // OK: used only in return type +// OK: used only in return type +fn b<'a>() -> &'a u32 { &22 } diff --git a/src/test/ui/single-use-lifetime/one-use-in-struct.rs b/src/test/ui/single-use-lifetime/one-use-in-struct.rs index 7285324ef6300..9082aa68ed22b 100644 --- a/src/test/ui/single-use-lifetime/one-use-in-struct.rs +++ b/src/test/ui/single-use-lifetime/one-use-in-struct.rs @@ -2,27 +2,26 @@ // even when they are only used once (since to not use a named // lifetime is illegal!) // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![deny(single_use_lifetimes)] #![allow(dead_code)] #![allow(unused_variables)] struct Foo<'f> { - data: &'f u32 + data: &'f u32, } enum Bar<'f> { - Data(&'f u32) + Data(&'f u32), } -trait Baz<'f> { } +trait Baz<'f> {} // `Derive`d impls shouldn't trigger a warning, either (Issue #53738). - #[derive(Debug)] struct Quux<'a> { priors: &'a u32, } -fn main() { } +fn main() {} diff --git a/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs b/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs index 8efe806b6e6e2..f80f3f63c66d9 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-fn-argument-and-return.rs @@ -1,14 +1,15 @@ // Test that we DO NOT warn when lifetime name is used in // both the argument and return. // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![deny(single_use_lifetimes)] #![allow(dead_code)] #![allow(unused_variables)] -fn c<'a>(x: &'a u32) -> &'a u32 { // OK: used twice +// OK: used twice +fn c<'a>(x: &'a u32) -> &'a u32 { &22 } -fn main() { } +fn main() {} diff --git a/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs b/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs index 09b01d8b05bae..51724ebf89888 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-fn-arguments.rs @@ -1,16 +1,16 @@ // Test that we DO NOT warn when lifetime name is used multiple // arguments, or more than once in a single argument. // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![deny(single_use_lifetimes)] #![allow(dead_code)] #![allow(unused_variables)] -fn c<'a>(x: &'a u32, y: &'a u32) { // OK: used twice -} +// OK: used twice +fn c<'a>(x: &'a u32, y: &'a u32) {} -fn d<'a>(x: (&'a u32, &'a u32)) { // OK: used twice -} +// OK: used twice +fn d<'a>(x: (&'a u32, &'a u32)) {} -fn main() { } +fn main() {} diff --git a/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs b/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs index eb85a148e6040..125a395db3be3 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-inherent-impl-header.rs @@ -1,18 +1,17 @@ // Test that we DO NOT warn for a lifetime used twice in an impl. // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![deny(single_use_lifetimes)] #![allow(dead_code)] #![allow(unused_variables)] struct Foo<'f> { - data: &'f u32 + data: &'f u32, } impl<'f> Foo<'f> { - fn inherent_a(&self, data: &'f u32) { - } + fn inherent_a(&self, data: &'f u32) {} } -fn main() { } +fn main() {} diff --git a/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs b/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs index fd8c899f4fa6b..16431a39fd0e5 100644 --- a/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs +++ b/src/test/ui/single-use-lifetime/two-uses-in-trait-impl.rs @@ -1,14 +1,14 @@ // Test that we DO NOT warn for a lifetime on an impl used in both // header and in an associated type. // -// build-pass (FIXME(62277): could be check-pass?) +// check-pass #![deny(single_use_lifetimes)] #![allow(dead_code)] #![allow(unused_variables)] struct Foo<'f> { - data: &'f u32 + data: &'f u32, } impl<'f> Iterator for Foo<'f> { @@ -19,4 +19,4 @@ impl<'f> Iterator for Foo<'f> { } } -fn main() { } +fn main() {} From e2183801b592464a56f9979dd12929500421948a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 25 Oct 2020 05:18:44 -0400 Subject: [PATCH 06/18] Make some functions private that don't have to be public --- src/librustdoc/clean/inline.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 6267b02e5d2c4..b3de70e590574 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -37,7 +37,7 @@ type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>; /// and `Some` of a vector of items if it was successfully expanded. /// /// `parent_module` refers to the parent of the *re-export*, not the original item. -pub fn try_inline( +crate fn try_inline( cx: &DocContext<'_>, parent_module: DefId, res: Res, @@ -137,7 +137,7 @@ pub fn try_inline( Some(ret) } -pub fn try_inline_glob( +crate fn try_inline_glob( cx: &DocContext<'_>, res: Res, visited: &mut FxHashSet, @@ -160,7 +160,7 @@ pub fn try_inline_glob( } } -pub fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> { +crate fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> { cx.tcx.get_attrs(did) } @@ -168,7 +168,7 @@ pub fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> Attrs<'hir> { /// /// These names are used later on by HTML rendering to generate things like /// source links back to the original item. -pub fn record_extern_fqn(cx: &DocContext<'_>, did: DefId, kind: clean::TypeKind) { +crate fn record_extern_fqn(cx: &DocContext<'_>, did: DefId, kind: clean::TypeKind) { let crate_name = cx.tcx.crate_name(did.krate).to_string(); let relative = cx.tcx.def_path(did).data.into_iter().filter_map(|elem| { @@ -189,7 +189,7 @@ pub fn record_extern_fqn(cx: &DocContext<'_>, did: DefId, kind: clean::TypeKind) } } -pub fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait { +crate fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait { let trait_items = cx.tcx.associated_items(did).in_definition_order().map(|item| item.clean(cx)).collect(); @@ -284,7 +284,7 @@ fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option type_.def_id().and_then(|did| build_ty(cx, did)) } -pub fn build_ty(cx: &DocContext<'_>, did: DefId) -> Option { +crate fn build_ty(cx: &DocContext<'_>, did: DefId) -> Option { match cx.tcx.def_kind(did) { DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Const | DefKind::Static => { Some(cx.tcx.type_of(did).clean(cx)) @@ -295,7 +295,7 @@ pub fn build_ty(cx: &DocContext<'_>, did: DefId) -> Option { } /// Builds all inherent implementations of an ADT (struct/union/enum) or Trait item/path/reexport. -pub fn build_impls( +crate fn build_impls( cx: &DocContext<'_>, parent_module: Option, did: DefId, @@ -338,7 +338,7 @@ fn merge_attrs( } /// Builds a specific implementation of a type. The `did` could be a type method or trait method. -pub fn build_impl( +crate fn build_impl( cx: &DocContext<'_>, parent_module: impl Into>, did: DefId, @@ -527,7 +527,7 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet) } } -pub fn print_inlined_const(cx: &DocContext<'_>, did: DefId) -> String { +crate fn print_inlined_const(cx: &DocContext<'_>, did: DefId) -> String { if let Some(did) = did.as_local() { let hir_id = cx.tcx.hir().local_def_id_to_hir_id(did); rustc_hir_pretty::id_to_string(&cx.tcx.hir(), hir_id) @@ -644,7 +644,7 @@ fn separate_supertrait_bounds( (g, ty_bounds) } -pub fn record_extern_trait(cx: &DocContext<'_>, did: DefId) { +crate fn record_extern_trait(cx: &DocContext<'_>, did: DefId) { if did.is_local() { return; } From 88d39673d7147af0d33705ffe06a83876e70aa2d Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 25 Oct 2020 18:33:13 +0900 Subject: [PATCH 07/18] Use its own `TypeckResults` to avoid ICE --- compiler/rustc_save_analysis/src/lib.rs | 11 ++++++++--- ...stderr => bound-normalization-pass.default.stderr} | 2 +- src/test/ui/impl-trait/bound-normalization-pass.rs | 3 +++ .../ui/impl-trait/bound-normalization-pass.sa.stderr | 11 +++++++++++ 4 files changed, 23 insertions(+), 4 deletions(-) rename src/test/ui/impl-trait/{bound-normalization-pass.stderr => bound-normalization-pass.default.stderr} (89%) create mode 100644 src/test/ui/impl-trait/bound-normalization-pass.sa.stderr diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index f6434689fec01..48d15370ee320 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -630,9 +630,14 @@ impl<'tcx> SaveContext<'tcx> { }) | Node::Ty(&hir::Ty { kind: hir::TyKind::Path(ref qpath), .. }) => match qpath { hir::QPath::Resolved(_, path) => path.res, - hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self - .maybe_typeck_results - .map_or(Res::Err, |typeck_results| typeck_results.qpath_res(qpath, hir_id)), + hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => { + // #75962: `self.typeck_results` may be different from the `hir_id`'s result. + if self.tcx.has_typeck_results(hir_id.owner.to_def_id()) { + self.tcx.typeck(hir_id.owner).qpath_res(qpath, hir_id) + } else { + Res::Err + } + } }, Node::Binding(&hir::Pat { diff --git a/src/test/ui/impl-trait/bound-normalization-pass.stderr b/src/test/ui/impl-trait/bound-normalization-pass.default.stderr similarity index 89% rename from src/test/ui/impl-trait/bound-normalization-pass.stderr rename to src/test/ui/impl-trait/bound-normalization-pass.default.stderr index afc181a906ac7..ef3cb7401128e 100644 --- a/src/test/ui/impl-trait/bound-normalization-pass.stderr +++ b/src/test/ui/impl-trait/bound-normalization-pass.default.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bound-normalization-pass.rs:5:12 + --> $DIR/bound-normalization-pass.rs:8:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/bound-normalization-pass.rs b/src/test/ui/impl-trait/bound-normalization-pass.rs index fff17667fdae1..3e6884ef10fa6 100644 --- a/src/test/ui/impl-trait/bound-normalization-pass.rs +++ b/src/test/ui/impl-trait/bound-normalization-pass.rs @@ -1,5 +1,8 @@ // check-pass // edition:2018 +// revisions: default sa +//[sa] compile-flags: -Z save-analysis +//-^ To make this the regression test for #75962. #![feature(type_alias_impl_trait)] #![feature(impl_trait_in_bindings)] diff --git a/src/test/ui/impl-trait/bound-normalization-pass.sa.stderr b/src/test/ui/impl-trait/bound-normalization-pass.sa.stderr new file mode 100644 index 0000000000000..ef3cb7401128e --- /dev/null +++ b/src/test/ui/impl-trait/bound-normalization-pass.sa.stderr @@ -0,0 +1,11 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bound-normalization-pass.rs:8:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #63065 for more information + +warning: 1 warning emitted + From 4f345377082ab564cd83d0cb7f805e2a97594366 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 25 Oct 2020 18:33:22 +0900 Subject: [PATCH 08/18] Fix small typos --- compiler/rustc_save_analysis/src/sig.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs index 747e198cd9324..1bf8160e4c384 100644 --- a/compiler/rustc_save_analysis/src/sig.rs +++ b/compiler/rustc_save_analysis/src/sig.rs @@ -262,7 +262,7 @@ impl<'hir> Sig for hir::Ty<'hir> { } else { let start = offset + prefix.len() + 5; let end = start + name.len(); - // FIXME should put the proper path in there, not elipses. + // FIXME should put the proper path in there, not ellipsis. Ok(Signature { text: prefix + "...::" + &name, defs: vec![], @@ -272,7 +272,7 @@ impl<'hir> Sig for hir::Ty<'hir> { } hir::TyKind::Path(hir::QPath::TypeRelative(ty, segment)) => { let nested_ty = ty.make(offset + 1, id, scx)?; - let prefix = format!("<{}>::", nested_ty.text,); + let prefix = format!("<{}>::", nested_ty.text); let name = path_segment_to_string(segment); let res = scx.get_path_res(id.ok_or("Missing id for Path")?); @@ -551,7 +551,7 @@ impl<'hir> Sig for hir::Item<'hir> { // FIXME where clause } hir::ItemKind::ForeignMod(_) => Err("extern mod"), - hir::ItemKind::GlobalAsm(_) => Err("glboal asm"), + hir::ItemKind::GlobalAsm(_) => Err("global asm"), hir::ItemKind::ExternCrate(_) => Err("extern crate"), hir::ItemKind::OpaqueTy(..) => Err("opaque type"), // FIXME should implement this (e.g., pub use). From 666afba684c153d8942ce5f62581dbcb79452150 Mon Sep 17 00:00:00 2001 From: Olivier FAURE Date: Sat, 24 Oct 2020 22:02:52 +0200 Subject: [PATCH 09/18] Update description for error E0308 As per #76462 --- .../src/error_codes/E0308.md | 32 +++-- .../ui/json-bom-plus-crlf-multifile.stderr | 128 +++++++++++------- src/test/ui/json-bom-plus-crlf.stderr | 128 +++++++++++------- src/test/ui/terminal-width/flag-json.stderr | 32 +++-- 4 files changed, 200 insertions(+), 120 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0308.md b/compiler/rustc_error_codes/src/error_codes/E0308.md index e2c40f03019c1..decee6309955a 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0308.md +++ b/compiler/rustc_error_codes/src/error_codes/E0308.md @@ -1,18 +1,26 @@ Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = "I am not a number!"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one("Not a number"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if "Not a bool" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = "Not a float"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. diff --git a/src/test/ui/json-bom-plus-crlf-multifile.stderr b/src/test/ui/json-bom-plus-crlf-multifile.stderr index b222334eda95e..da8849a82844f 100644 --- a/src/test/ui/json-bom-plus-crlf-multifile.stderr +++ b/src/test/ui/json-bom-plus-crlf-multifile.stderr @@ -1,81 +1,113 @@ {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = \"I am not a number!\"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one(\"Not a number\"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if \"Not a bool\" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = \"Not a float\"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":612,"byte_end":618,"line_start":17,"line_end":17,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:17:22: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = \"I am not a number!\"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one(\"Not a number\"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if \"Not a bool\" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = \"Not a float\"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":672,"byte_end":678,"line_start":19,"line_end":19,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:19:22: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = \"I am not a number!\"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one(\"Not a number\"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if \"Not a bool\" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = \"Not a float\"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":735,"byte_end":741,"line_start":22,"line_end":22,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:23:1: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = \"I am not a number!\"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one(\"Not a number\"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if \"Not a bool\" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = \"Not a float\"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":801,"byte_end":809,"line_start":25,"line_end":26,"column_start":22,"column_end":6,"is_primary":true,"text":[{"text":" let s : String = (","highlight_start":22,"highlight_end":23},{"text":" ); // Error spanning the newline.","highlight_start":1,"highlight_end":6}],"label":"expected struct `String`, found `()`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":792,"byte_end":798,"line_start":25,"line_end":25,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = (","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:25:22: error[E0308]: mismatched types "} {"message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors diff --git a/src/test/ui/json-bom-plus-crlf.stderr b/src/test/ui/json-bom-plus-crlf.stderr index 6041366dbd883..811206f9aa076 100644 --- a/src/test/ui/json-bom-plus-crlf.stderr +++ b/src/test/ui/json-bom-plus-crlf.stderr @@ -1,81 +1,113 @@ {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = \"I am not a number!\"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one(\"Not a number\"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if \"Not a bool\" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = \"Not a float\"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":597,"byte_end":603,"line_start":16,"line_end":16,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:22: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = \"I am not a number!\"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one(\"Not a number\"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if \"Not a bool\" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = \"Not a float\"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":657,"byte_end":663,"line_start":18,"line_end":18,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = \"I am not a number!\"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one(\"Not a number\"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if \"Not a bool\" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = \"Not a float\"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":720,"byte_end":726,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:22:1: error[E0308]: mismatched types "} {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = \"I am not a number!\"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one(\"Not a number\"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if \"Not a bool\" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = \"Not a float\"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":786,"byte_end":794,"line_start":24,"line_end":25,"column_start":22,"column_end":6,"is_primary":true,"text":[{"text":" let s : String = (","highlight_start":22,"highlight_end":23},{"text":" ); // Error spanning the newline.","highlight_start":1,"highlight_end":6}],"label":"expected struct `String`, found `()`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":777,"byte_end":783,"line_start":24,"line_end":24,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = (","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-bom-plus-crlf.rs:24:22: error[E0308]: mismatched types "} {"message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors diff --git a/src/test/ui/terminal-width/flag-json.stderr b/src/test/ui/terminal-width/flag-json.stderr index 29730ccdd4ed7..93c246cb3f501 100644 --- a/src/test/ui/terminal-width/flag-json.stderr +++ b/src/test/ui/terminal-width/flag-json.stderr @@ -1,21 +1,29 @@ {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. -Erroneous code example: +Erroneous code examples: ```compile_fail,E0308 -let x: i32 = \"I am not a number!\"; -// ~~~ ~~~~~~~~~~~~~~~~~~~~ -// | | -// | initializing expression; -// | compiler infers type `&str` -// | -// type `i32` assigned to variable `x` +fn plus_one(x: i32) -> i32 { + x + 1 +} + +plus_one(\"Not a number\"); +// ^^^^^^^^^^^^^^ expected `i32`, found `&str` + +if \"Not a bool\" { +// ^^^^^^^^^^^^ expected `bool`, found `&str` +} + +let x: f32 = \"Not a float\"; +// --- ^^^^^^^^^^^^^ expected `f32`, found `&str` +// | +// expected due to this ``` -This error occurs when the compiler is unable to infer the concrete type of a -variable. It can occur in several cases, the most common being a mismatch -between two types: the type the author explicitly assigned, and the type the -compiler inferred. +This error occurs when an expression was used in a place where the compiler +expected an expression of a different type. It can occur in several cases, the +most common being when calling a function and passing an argument which has a +different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/flag-json.rs","byte_start":244,"byte_end":246,"line_start":7,"line_end":7,"column_start":17,"column_end":19,"is_primary":true,"text":[{"text":" let _: () = 42;","highlight_start":17,"highlight_end":19}],"label":"expected `()`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/flag-json.rs","byte_start":239,"byte_end":241,"line_start":7,"line_end":7,"column_start":12,"column_end":14,"is_primary":false,"text":[{"text":" let _: () = 42;","highlight_start":12,"highlight_end":14}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"error[E0308]: mismatched types --> $DIR/flag-json.rs:7:17 | From 9de15188b018cc2891cac00c4c5b19b95cc63c7d Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sun, 25 Oct 2020 20:54:44 +0100 Subject: [PATCH 10/18] Fix typo in debug statement --- compiler/rustc_mir_build/src/build/matches/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index b7bd67fea0679..3ee15248ae28e 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -231,7 +231,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let arm_end_blocks: Vec<_> = arm_candidates .into_iter() .map(|(arm, candidate)| { - debug!("lowering arm {:?}\ncanidate = {:?}", arm, candidate); + debug!("lowering arm {:?}\ncandidate = {:?}", arm, candidate); let arm_source_info = self.source_info(arm.span); let arm_scope = (arm.scope, arm_source_info); From 04c0018d1b08875b6e51205d2b62b67925b6238a Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Mon, 26 Oct 2020 07:15:37 +0900 Subject: [PATCH 11/18] Use ? in core/std macros --- library/core/src/macros/mod.rs | 59 ++++++++------------------- library/std/src/macros.rs | 7 +--- src/test/ui/parser/issue-62894.stderr | 2 +- 3 files changed, 19 insertions(+), 49 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index ac45e819cf67a..bce8a70e92f31 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -6,15 +6,12 @@ macro_rules! panic { () => ( $crate::panic!("explicit panic") ); - ($msg:literal) => ( + ($msg:literal $(,)?) => ( $crate::panicking::panic($msg) ); - ($msg:expr) => ( + ($msg:expr $(,)?) => ( $crate::panicking::panic_str($msg) ); - ($msg:expr,) => ( - $crate::panic!($msg) - ); ($fmt:expr, $($arg:tt)+) => ( $crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+)) ); @@ -40,7 +37,7 @@ macro_rules! panic { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] macro_rules! assert_eq { - ($left:expr, $right:expr) => ({ + ($left:expr, $right:expr $(,)?) => ({ match (&$left, &$right) { (left_val, right_val) => { if !(*left_val == *right_val) { @@ -54,9 +51,6 @@ macro_rules! assert_eq { } } }); - ($left:expr, $right:expr,) => ({ - $crate::assert_eq!($left, $right) - }); ($left:expr, $right:expr, $($arg:tt)+) => ({ match (&($left), &($right)) { (left_val, right_val) => { @@ -94,7 +88,7 @@ macro_rules! assert_eq { #[macro_export] #[stable(feature = "assert_ne", since = "1.13.0")] macro_rules! assert_ne { - ($left:expr, $right:expr) => ({ + ($left:expr, $right:expr $(,)?) => ({ match (&$left, &$right) { (left_val, right_val) => { if *left_val == *right_val { @@ -108,9 +102,6 @@ macro_rules! assert_ne { } } }); - ($left:expr, $right:expr,) => { - $crate::assert_ne!($left, $right) - }; ($left:expr, $right:expr, $($arg:tt)+) => ({ match (&($left), &($right)) { (left_val, right_val) => { @@ -315,7 +306,7 @@ macro_rules! matches { #[rustc_deprecated(since = "1.39.0", reason = "use the `?` operator instead")] #[doc(alias = "?")] macro_rules! r#try { - ($expr:expr) => { + ($expr:expr $(,)?) => { match $expr { $crate::result::Result::Ok(val) => val, $crate::result::Result::Err(err) => { @@ -323,9 +314,6 @@ macro_rules! r#try { } } }; - ($expr:expr,) => { - $crate::r#try!($expr) - }; } /// Writes formatted data into a buffer. @@ -451,12 +439,9 @@ macro_rules! write { #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(format_args_nl)] macro_rules! writeln { - ($dst:expr) => ( + ($dst:expr $(,)?) => ( $crate::write!($dst, "\n") ); - ($dst:expr,) => ( - $crate::writeln!($dst) - ); ($dst:expr, $($arg:tt)*) => ( $dst.write_fmt($crate::format_args_nl!($($arg)*)) ); @@ -517,12 +502,9 @@ macro_rules! unreachable { () => ({ panic!("internal error: entered unreachable code") }); - ($msg:expr) => ({ + ($msg:expr $(,)?) => ({ $crate::unreachable!("{}", $msg) }); - ($msg:expr,) => ({ - $crate::unreachable!($msg) - }); ($fmt:expr, $($arg:tt)*) => ({ panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*) }); @@ -711,8 +693,7 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[macro_export] macro_rules! compile_error { - ($msg:expr) => {{ /* compiler built-in */ }}; - ($msg:expr,) => {{ /* compiler built-in */ }}; + ($msg:expr $(,)?) => {{ /* compiler built-in */ }}; } /// Constructs parameters for the other string-formatting macros. @@ -816,8 +797,7 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[macro_export] macro_rules! env { - ($name:expr) => {{ /* compiler built-in */ }}; - ($name:expr,) => {{ /* compiler built-in */ }}; + ($name:expr $(,)?) => {{ /* compiler built-in */ }}; } /// Optionally inspects an environment variable at compile time. @@ -841,8 +821,7 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[macro_export] macro_rules! option_env { - ($name:expr) => {{ /* compiler built-in */ }}; - ($name:expr,) => {{ /* compiler built-in */ }}; + ($name:expr $(,)?) => {{ /* compiler built-in */ }}; } /// Concatenates identifiers into one identifier. @@ -877,8 +856,7 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[macro_export] macro_rules! concat_idents { - ($($e:ident),+) => {{ /* compiler built-in */ }}; - ($($e:ident,)+) => {{ /* compiler built-in */ }}; + ($($e:ident),+ $(,)?) => {{ /* compiler built-in */ }}; } /// Concatenates literals into a static string slice. @@ -900,8 +878,7 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[macro_export] macro_rules! concat { - ($($e:expr),*) => {{ /* compiler built-in */ }}; - ($($e:expr,)*) => {{ /* compiler built-in */ }}; + ($($e:expr),* $(,)?) => {{ /* compiler built-in */ }}; } /// Expands to the line number on which it was invoked. @@ -1043,8 +1020,7 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[macro_export] macro_rules! include_str { - ($file:expr) => {{ /* compiler built-in */ }}; - ($file:expr,) => {{ /* compiler built-in */ }}; + ($file:expr $(,)?) => {{ /* compiler built-in */ }}; } /// Includes a file as a reference to a byte array. @@ -1083,8 +1059,7 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[macro_export] macro_rules! include_bytes { - ($file:expr) => {{ /* compiler built-in */ }}; - ($file:expr,) => {{ /* compiler built-in */ }}; + ($file:expr $(,)?) => {{ /* compiler built-in */ }}; } /// Expands to a string that represents the current module path. @@ -1191,8 +1166,7 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[macro_export] macro_rules! include { - ($file:expr) => {{ /* compiler built-in */ }}; - ($file:expr,) => {{ /* compiler built-in */ }}; + ($file:expr $(,)?) => {{ /* compiler built-in */ }}; } /// Asserts that a boolean expression is `true` at runtime. @@ -1242,8 +1216,7 @@ pub(crate) mod builtin { #[rustc_builtin_macro] #[macro_export] macro_rules! assert { - ($cond:expr) => {{ /* compiler built-in */ }}; - ($cond:expr,) => {{ /* compiler built-in */ }}; + ($cond:expr $(,)?) => {{ /* compiler built-in */ }}; ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }}; } diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index e8898d98ff35f..57649d6f8f252 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -10,8 +10,7 @@ #[allow_internal_unstable(libstd_sys_internals)] macro_rules! panic { () => ({ $crate::panic!("explicit panic") }); - ($msg:expr) => ({ $crate::rt::begin_panic($msg) }); - ($msg:expr,) => ({ $crate::panic!($msg) }); + ($msg:expr $(,)?) => ({ $crate::rt::begin_panic($msg) }); ($fmt:expr, $($arg:tt)+) => ({ $crate::rt::begin_panic_fmt(&$crate::format_args!($fmt, $($arg)+)) }); @@ -285,7 +284,7 @@ macro_rules! dbg { () => { $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!()); }; - ($val:expr) => { + ($val:expr $(,)?) => { // Use of `match` here is intentional because it affects the lifetimes // of temporaries - https://stackoverflow.com/a/48732525/1063961 match $val { @@ -296,8 +295,6 @@ macro_rules! dbg { } } }; - // Trailing comma with single argument is ignored - ($val:expr,) => { $crate::dbg!($val) }; ($($val:expr),+ $(,)?) => { ($($crate::dbg!($val)),+,) }; diff --git a/src/test/ui/parser/issue-62894.stderr b/src/test/ui/parser/issue-62894.stderr index 93d43bda32d52..cf3727c9d579d 100644 --- a/src/test/ui/parser/issue-62894.stderr +++ b/src/test/ui/parser/issue-62894.stderr @@ -45,7 +45,7 @@ LL | fn main() {} | ::: $SRC_DIR/core/src/macros/mod.rs:LL:COL | -LL | ($left:expr, $right:expr) => ({ +LL | ($left:expr, $right:expr $(,)?) => ({ | ---------- while parsing argument for this `expr` macro fragment error: aborting due to 4 previous errors From a4ba179bdddcabae1947eb307ec017d576ae4b3a Mon Sep 17 00:00:00 2001 From: Michele Lacchia Date: Mon, 26 Oct 2020 11:13:47 +0100 Subject: [PATCH 12/18] fix(docs): typo in BufWriter documentation --- library/std/src/io/buffered/bufwriter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs index 8ce795a05ed36..3ec272fea6668 100644 --- a/library/std/src/io/buffered/bufwriter.rs +++ b/library/std/src/io/buffered/bufwriter.rs @@ -15,7 +15,7 @@ use crate::io::{ /// *repeated* write calls to the same file or network socket. It does not /// help when writing very large amounts at once, or writing just one or a few /// times. It also provides no advantage when writing to a destination that is -/// in memory, like a [`Vec`]`. +/// in memory, like a [`Vec`]``. /// /// It is critical to call [`flush`] before `BufWriter` is dropped. Though /// dropping will attempt to flush the contents of the buffer, any errors From ad552bc17e9e494e039f3db180d4e63be44fe889 Mon Sep 17 00:00:00 2001 From: Joe Richey Date: Mon, 26 Oct 2020 03:46:54 -0700 Subject: [PATCH 13/18] Add compiler support for LLVM's x86 ERMSB feature This change is needed for compiler-builtins to check for this feature when implementing memcpy/memset. See: https://github.com/rust-lang/compiler-builtins/pull/365 The change just does compile-time detection. I think that runtime detection will have to come in a follow-up CL to std-detect. Like all the CPU feature flags, this just references #44839 Signed-off-by: Joe Richey --- compiler/rustc_codegen_ssa/src/target_features.rs | 1 + compiler/rustc_feature/src/active.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_typeck/src/collect.rs | 1 + src/test/ui/target-feature/gate.rs | 1 + src/test/ui/target-feature/gate.stderr | 2 +- 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index a8d88a95f7a27..000ddf4260429 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -63,6 +63,7 @@ const X86_ALLOWED_FEATURES: &[(&str, Option)] = &[ ("bmi1", None), ("bmi2", None), ("cmpxchg16b", Some(sym::cmpxchg16b_target_feature)), + ("ermsb", Some(sym::ermsb_target_feature)), ("f16c", Some(sym::f16c_target_feature)), ("fma", None), ("fxsr", None), diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 7fbd070a609b7..cca4fc4cb0cde 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -238,6 +238,7 @@ declare_features! ( (active, rtm_target_feature, "1.35.0", Some(44839), None), (active, f16c_target_feature, "1.36.0", Some(44839), None), (active, riscv_target_feature, "1.45.0", Some(44839), None), + (active, ermsb_target_feature, "1.49.0", Some(44839), None), // ------------------------------------------------------------------------- // feature-group-end: actual feature gates (target features) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 28fef65da070a..7f7c7187951d4 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -467,6 +467,7 @@ symbols! { encode, env, eq, + ermsb_target_feature, err, exact_div, except, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 630e80d502efa..9ccd1ce8fc94b 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2414,6 +2414,7 @@ fn from_target_feature( Some(sym::movbe_target_feature) => rust_features.movbe_target_feature, Some(sym::rtm_target_feature) => rust_features.rtm_target_feature, Some(sym::f16c_target_feature) => rust_features.f16c_target_feature, + Some(sym::ermsb_target_feature) => rust_features.ermsb_target_feature, Some(name) => bug!("unknown target feature gate {}", name), None => true, }; diff --git a/src/test/ui/target-feature/gate.rs b/src/test/ui/target-feature/gate.rs index e4b78c76e1699..164830fecee57 100644 --- a/src/test/ui/target-feature/gate.rs +++ b/src/test/ui/target-feature/gate.rs @@ -26,6 +26,7 @@ // gate-test-rtm_target_feature // gate-test-f16c_target_feature // gate-test-riscv_target_feature +// gate-test-ermsb_target_feature #[target_feature(enable = "avx512bw")] //~^ ERROR: currently unstable diff --git a/src/test/ui/target-feature/gate.stderr b/src/test/ui/target-feature/gate.stderr index 2384a00aa47aa..2d6abcc0a0150 100644 --- a/src/test/ui/target-feature/gate.stderr +++ b/src/test/ui/target-feature/gate.stderr @@ -1,5 +1,5 @@ error[E0658]: the target feature `avx512bw` is currently unstable - --> $DIR/gate.rs:30:18 + --> $DIR/gate.rs:31:18 | LL | #[target_feature(enable = "avx512bw")] | ^^^^^^^^^^^^^^^^^^^ From 42844ed2cf4ca0ff2a9271e0aaa8e5910c5f4ccd Mon Sep 17 00:00:00 2001 From: Rustin-Liu Date: Sun, 25 Oct 2020 17:46:45 +0800 Subject: [PATCH 14/18] Add lexicographical comparison doc Add links Fix typo Use `sequence` Fix typo Fix broken link Fix broken link Fix broken link Fix broken links Fix broken links --- library/alloc/src/vec.rs | 4 ++-- library/core/src/array/mod.rs | 2 +- library/core/src/cmp.rs | 12 +++++++++++- library/core/src/iter/traits/iterator.rs | 16 ++++++++-------- library/core/src/slice/cmp.rs | 4 ++-- library/core/src/str/traits.rs | 4 ++-- 6 files changed, 26 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index 5b3604db563c6..202e3a836384d 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -2566,7 +2566,7 @@ __impl_slice_eq1! { [const N: usize] Vec, &[B; N], #[stable(feature = "rust1" //__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &[B; N], } //__impl_slice_eq1! { [const N: usize] Cow<'a, [A]>, &mut [B; N], } -/// Implements comparison of vectors, lexicographically. +/// Implements comparison of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for Vec { #[inline] @@ -2578,7 +2578,7 @@ impl PartialOrd for Vec { #[stable(feature = "rust1", since = "1.0.0")] impl Eq for Vec {} -/// Implements ordering of vectors, lexicographically. +/// Implements ordering of vectors, [lexicographically](core::cmp::Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] impl Ord for Vec { #[inline] diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 966272ca11549..1d55a5ef659d4 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -344,7 +344,7 @@ impl PartialOrd for [T; N] { } } -/// Implements comparison of arrays lexicographically. +/// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] impl Ord for [T; N] { #[inline] diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index ee79a94cc66ab..a048f65a14992 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -506,9 +506,19 @@ impl Ord for Reverse { /// ## Derivable /// /// This trait can be used with `#[derive]`. When `derive`d on structs, it will produce a -/// lexicographic ordering based on the top-to-bottom declaration order of the struct's members. +/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering based on the top-to-bottom declaration order of the struct's members. /// When `derive`d on enums, variants are ordered by their top-to-bottom discriminant order. /// +/// ## Lexicographical comparison +/// +/// Lexicographical comparison is an operation with the following properties: +/// - Two sequences are compared element by element. +/// - The first mismatching element defines which sequence is lexicographically less or greater than the other. +/// - If one sequence is a prefix of another, the shorter sequence is lexicographically less than the other. +/// - If two sequence have equivalent elements and are of the same length, then the sequences are lexicographically equal. +/// - An empty sequence is lexicographically less than any non-empty sequence. +/// - Two empty sequences are lexicographically equal. +/// /// ## How can I implement `Ord`? /// /// `Ord` requires that the type also be [`PartialOrd`] and [`Eq`] (which requires [`PartialEq`]). diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 7fc60caec2a73..19484bfd0419f 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2851,7 +2851,7 @@ pub trait Iterator { Product::product(self) } - /// Lexicographically compares the elements of this [`Iterator`] with those + /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those /// of another. /// /// # Examples @@ -2873,7 +2873,7 @@ pub trait Iterator { self.cmp_by(other, |x, y| x.cmp(&y)) } - /// Lexicographically compares the elements of this [`Iterator`] with those + /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those /// of another with respect to the specified comparison function. /// /// # Examples @@ -2925,7 +2925,7 @@ pub trait Iterator { } } - /// Lexicographically compares the elements of this [`Iterator`] with those + /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those /// of another. /// /// # Examples @@ -2949,7 +2949,7 @@ pub trait Iterator { self.partial_cmp_by(other, |x, y| x.partial_cmp(&y)) } - /// Lexicographically compares the elements of this [`Iterator`] with those + /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those /// of another with respect to the specified comparison function. /// /// # Examples @@ -3089,7 +3089,7 @@ pub trait Iterator { !self.eq(other) } - /// Determines if the elements of this [`Iterator`] are lexicographically + /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison) /// less than those of another. /// /// # Examples @@ -3110,7 +3110,7 @@ pub trait Iterator { self.partial_cmp(other) == Some(Ordering::Less) } - /// Determines if the elements of this [`Iterator`] are lexicographically + /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison) /// less or equal to those of another. /// /// # Examples @@ -3131,7 +3131,7 @@ pub trait Iterator { matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal)) } - /// Determines if the elements of this [`Iterator`] are lexicographically + /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison) /// greater than those of another. /// /// # Examples @@ -3152,7 +3152,7 @@ pub trait Iterator { self.partial_cmp(other) == Some(Ordering::Greater) } - /// Determines if the elements of this [`Iterator`] are lexicographically + /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison) /// greater than or equal to those of another. /// /// # Examples diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs index ed26c59c17c43..18073f4afedf7 100644 --- a/library/core/src/slice/cmp.rs +++ b/library/core/src/slice/cmp.rs @@ -35,7 +35,7 @@ where #[stable(feature = "rust1", since = "1.0.0")] impl Eq for [T] {} -/// Implements comparison of vectors lexicographically. +/// Implements comparison of vectors [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] impl Ord for [T] { fn cmp(&self, other: &[T]) -> Ordering { @@ -43,7 +43,7 @@ impl Ord for [T] { } } -/// Implements comparison of vectors lexicographically. +/// Implements comparison of vectors [lexicographically](Ord#lexicographical-comparison). #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for [T] { fn partial_cmp(&self, other: &[T]) -> Option { diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 9cfb5a8998773..1906fa27bf44b 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -9,7 +9,7 @@ use super::ParseBoolError; /// Implements ordering of strings. /// -/// Strings are ordered lexicographically by their byte values. This orders Unicode code +/// Strings are ordered [lexicographically](Ord#lexicographical-comparison) by their byte values. This orders Unicode code /// points based on their positions in the code charts. This is not necessarily the same as /// "alphabetical" order, which varies by language and locale. Sorting strings according to /// culturally-accepted standards requires locale-specific data that is outside the scope of @@ -39,7 +39,7 @@ impl Eq for str {} /// Implements comparison operations on strings. /// -/// Strings are compared lexicographically by their byte values. This compares Unicode code +/// Strings are compared [lexicographically](Ord#lexicographical-comparison) by their byte values. This compares Unicode code /// points based on their positions in the code charts. This is not necessarily the same as /// "alphabetical" order, which varies by language and locale. Comparing strings according to /// culturally-accepted standards requires locale-specific data that is outside the scope of From 74a98912354324e985b087923bf0448e98f309d4 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 26 Oct 2020 11:46:11 -0700 Subject: [PATCH 15/18] Fix typo in lint description --- compiler/rustc_session/src/lint/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_session/src/lint/builtin.rs b/compiler/rustc_session/src/lint/builtin.rs index d12eb0edd4d39..ab56a0a566757 100644 --- a/compiler/rustc_session/src/lint/builtin.rs +++ b/compiler/rustc_session/src/lint/builtin.rs @@ -2648,7 +2648,7 @@ declare_lint! { } declare_lint! { - /// The `uninhabited_static` lint detects uninhbaited statics. + /// The `uninhabited_static` lint detects uninhabited statics. /// /// ### Example /// From 94ed9455e831e820041291165576a4f78e6e722a Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 25 Oct 2020 22:01:37 -0700 Subject: [PATCH 16/18] Add some regression tests --- src/test/ui/issues/issue-75763.rs | 14 ++++++++++++++ src/test/ui/issues/issue-76179.rs | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/test/ui/issues/issue-75763.rs create mode 100644 src/test/ui/issues/issue-76179.rs diff --git a/src/test/ui/issues/issue-75763.rs b/src/test/ui/issues/issue-75763.rs new file mode 100644 index 0000000000000..2ecc16be7f6de --- /dev/null +++ b/src/test/ui/issues/issue-75763.rs @@ -0,0 +1,14 @@ +// build-pass + +#![allow(incomplete_features)] +#![feature(const_generics)] + +struct Bug; + +fn main() { + let b: Bug::<{ + unsafe { + std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) + } + }>; +} diff --git a/src/test/ui/issues/issue-76179.rs b/src/test/ui/issues/issue-76179.rs new file mode 100644 index 0000000000000..0e086968b9056 --- /dev/null +++ b/src/test/ui/issues/issue-76179.rs @@ -0,0 +1,19 @@ +// check-pass + +#![feature(associated_type_defaults)] + +use std::io::Read; + +trait View { + type Deserializers: Deserializer; + type RequestParams = DefaultRequestParams; +} + +struct DefaultRequestParams; + +trait Deserializer { + type Item; + fn deserialize(r: impl Read) -> Self::Item; +} + +fn main() {} From 4641d2e6aa990d3fb6730a3208e9fd857f52eb33 Mon Sep 17 00:00:00 2001 From: Camelid Date: Mon, 26 Oct 2020 13:56:31 -0700 Subject: [PATCH 17/18] Add FIXME note to const generics test Co-authored-by: lcnr --- src/test/ui/issues/issue-75763.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/issues/issue-75763.rs b/src/test/ui/issues/issue-75763.rs index 2ecc16be7f6de..2fd9f9a60de9f 100644 --- a/src/test/ui/issues/issue-75763.rs +++ b/src/test/ui/issues/issue-75763.rs @@ -8,6 +8,7 @@ struct Bug; fn main() { let b: Bug::<{ unsafe { + // FIXME(const_generics): Decide on how to deal with invalid values as const params. std::mem::transmute::<&[u8], &str>(&[0xC0, 0xC1, 0xF5]) } }>; From 59f108885ed38c7f7049a1830b7c50205989cb17 Mon Sep 17 00:00:00 2001 From: Camelid Date: Mon, 26 Oct 2020 14:05:06 -0700 Subject: [PATCH 18/18] Improve formatting of hash collections docs --- library/std/src/collections/hash/map.rs | 7 ++++--- library/std/src/collections/hash/set.rs | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 114707b639bce..d1244c2ca538c 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -606,7 +606,7 @@ where } /// Tries to reserve capacity for at least `additional` more elements to be inserted - /// in the given `HashMap`. The collection may reserve more space to avoid + /// in the given `HashMap`. The collection may reserve more space to avoid /// frequent reallocations. /// /// # Errors @@ -619,6 +619,7 @@ where /// ``` /// #![feature(try_reserve)] /// use std::collections::HashMap; + /// /// let mut map: HashMap<&str, isize> = HashMap::new(); /// map.try_reserve(10).expect("why is the test harness OOMing on 10 bytes?"); /// ``` @@ -898,14 +899,14 @@ where /// Retains only the elements specified by the predicate. /// - /// In other words, remove all pairs `(k, v)` such that `f(&k,&mut v)` returns `false`. + /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)` returns `false`. /// /// # Examples /// /// ``` /// use std::collections::HashMap; /// - /// let mut map: HashMap = (0..8).map(|x|(x, x*10)).collect(); + /// let mut map: HashMap = (0..8).map(|x| (x, x*10)).collect(); /// map.retain(|&k, _| k % 2 == 0); /// assert_eq!(map.len(), 4); /// ``` diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index a0c39852ad5d8..3299fd12e024e 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -412,7 +412,7 @@ where } /// Tries to reserve capacity for at least `additional` more elements to be inserted - /// in the given `HashSet`. The collection may reserve more space to avoid + /// in the given `HashSet`. The collection may reserve more space to avoid /// frequent reallocations. /// /// # Errors @@ -918,7 +918,7 @@ where /// ``` /// use std::collections::HashSet; /// - /// let xs = [1,2,3,4,5,6]; + /// let xs = [1, 2, 3, 4, 5, 6]; /// let mut set: HashSet = xs.iter().cloned().collect(); /// set.retain(|&k| k % 2 == 0); /// assert_eq!(set.len(), 3);