From 12d6238f4d598cfff94ed001b0633ec4490d05dc Mon Sep 17 00:00:00 2001 From: Waffle Date: Sat, 27 Feb 2021 01:36:19 +0300 Subject: [PATCH 01/14] Add `as_str` method for split whitespace str iterators This commit adds `as_str` methods to `SplitWhitespace` and `SplitAsciiWhitespace` str iterators. The methods return the remainder, similar to `as_str` methods on `Chars` and other split iterators. This commit also makes fields of some iterators `pub(crate)`. --- library/core/src/iter/adapters/filter.rs | 3 +- library/core/src/iter/adapters/map.rs | 3 +- library/core/src/slice/iter.rs | 6 ++- library/core/src/str/iter.rs | 55 ++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/library/core/src/iter/adapters/filter.rs b/library/core/src/iter/adapters/filter.rs index f8d684fcdda..0337892b9e8 100644 --- a/library/core/src/iter/adapters/filter.rs +++ b/library/core/src/iter/adapters/filter.rs @@ -13,7 +13,8 @@ use crate::ops::Try; #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Filter { - iter: I, + // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods + pub(crate) iter: I, predicate: P, } impl Filter { diff --git a/library/core/src/iter/adapters/map.rs b/library/core/src/iter/adapters/map.rs index f238baf743c..f6dbfce3e97 100644 --- a/library/core/src/iter/adapters/map.rs +++ b/library/core/src/iter/adapters/map.rs @@ -57,7 +57,8 @@ use crate::ops::Try; #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone)] pub struct Map { - iter: I, + // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods + pub(crate) iter: I, f: F, } diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 50664267a67..052021571b4 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -335,9 +335,11 @@ pub struct Split<'a, T: 'a, P> where P: FnMut(&T) -> bool, { - v: &'a [T], + // Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods + pub(crate) v: &'a [T], pred: P, - finished: bool, + // Used for `SplitAsciiWhitespace` `as_str` method + pub(crate) finished: bool, } impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> { diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 83f484dc570..93248d15833 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -1203,6 +1203,30 @@ impl<'a> DoubleEndedIterator for SplitWhitespace<'a> { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for SplitWhitespace<'_> {} +impl<'a> SplitWhitespace<'a> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_whitespace_as_str)] + /// + /// let mut split = "Mary had a little lamb".split_whitespace(); + /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// + /// split.next(); + /// assert_eq!(split.as_str(), "had a little lamb"); + /// + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + self.inner.iter.as_str() + } +} + #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] impl<'a> Iterator for SplitAsciiWhitespace<'a> { type Item = &'a str; @@ -1234,6 +1258,37 @@ impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a> { #[stable(feature = "split_ascii_whitespace", since = "1.34.0")] impl FusedIterator for SplitAsciiWhitespace<'_> {} +impl<'a> SplitAsciiWhitespace<'a> { + /// Returns remainder of the splitted string + /// + /// # Examples + /// + /// ``` + /// #![feature(str_split_whitespace_as_str)] + /// + /// let mut split = "Mary had a little lamb".split_ascii_whitespace(); + /// assert_eq!(split.as_str(), "Mary had a little lamb"); + /// + /// split.next(); + /// assert_eq!(split.as_str(), "had a little lamb"); + /// + /// split.by_ref().for_each(drop); + /// assert_eq!(split.as_str(), ""); + /// ``` + #[inline] + #[unstable(feature = "str_split_whitespace_as_str", issue = "77998")] + pub fn as_str(&self) -> &'a str { + if self.inner.iter.iter.finished { + return ""; + } + + // Safety: + // + // Slice is created from str. + unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) } + } +} + #[stable(feature = "split_inclusive", since = "1.51.0")] impl<'a, P: Pattern<'a>> Iterator for SplitInclusive<'a, P> { type Item = &'a str; From d4fd8538cb01f8be6083d2597a294c673f968290 Mon Sep 17 00:00:00 2001 From: Waffle Date: Sat, 27 Feb 2021 02:33:09 +0300 Subject: [PATCH 02/14] Change formatting of safety comment --- library/core/src/str/iter.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/core/src/str/iter.rs b/library/core/src/str/iter.rs index 93248d15833..524a672bfbd 100644 --- a/library/core/src/str/iter.rs +++ b/library/core/src/str/iter.rs @@ -1282,9 +1282,7 @@ impl<'a> SplitAsciiWhitespace<'a> { return ""; } - // Safety: - // - // Slice is created from str. + // SAFETY: Slice is created from str. unsafe { crate::str::from_utf8_unchecked(&self.inner.iter.iter.v) } } } From c07955c6b6a8901fc59d9c22004127b30a965407 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 17 Mar 2021 16:02:07 -0700 Subject: [PATCH 03/14] Fix overflowing length in Vec to VecDeque `Vec` can hold up to `usize::MAX` ZST items, but `VecDeque` has a lower limit to keep its raw capacity as a power of two, so we should check that in `From> for VecDeque`. We can also simplify the capacity check for the remaining non-ZST case. Before this fix, the new test would fail on the length: ``` thread 'collections::vec_deque::tests::test_from_vec_zst_overflow' panicked at 'assertion failed: `(left == right)` left: `0`, right: `9223372036854775808`', library/alloc/src/collections/vec_deque/tests.rs:474:5 note: panic did not contain expected string panic message: `"assertion failed: `(left == right)`\n left: `0`,\n right: `9223372036854775808`"`, expected substring: `"capacity overflow"` ``` That was a result of `len()` using a mask `& (size - 1)` with the improper length. Now we do get a "capacity overflow" panic as soon as that `VecDeque::from(vec)` is attempted. --- .../alloc/src/collections/vec_deque/mod.rs | 37 +++++++++---------- .../alloc/src/collections/vec_deque/tests.rs | 15 ++++++++ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index f7cefdce278..7a0de74eb23 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2783,27 +2783,26 @@ impl From> for VecDeque { /// This avoids reallocating where possible, but the conditions for that are /// strict, and subject to change, and so shouldn't be relied upon unless the /// `Vec` came from `From>` and hasn't been reallocated. - fn from(other: Vec) -> Self { - unsafe { - let mut other = ManuallyDrop::new(other); - let other_buf = other.as_mut_ptr(); - let mut buf = RawVec::from_raw_parts(other_buf, other.capacity()); - let len = other.len(); - - // We need to extend the buf if it's not a power of two, too small - // or doesn't have at least one free space. - // We check if `T` is a ZST in the first condition, - // because `usize::MAX` (the capacity returned by `capacity()` for ZST) - // is not a power of two and thus it'll always try - // to reserve more memory which will panic for ZST (rust-lang/rust#78532) - if (!buf.capacity().is_power_of_two() && mem::size_of::() != 0) - || (buf.capacity() < (MINIMUM_CAPACITY + 1)) - || (buf.capacity() == len) - { - let cap = cmp::max(buf.capacity() + 1, MINIMUM_CAPACITY + 1).next_power_of_two(); - buf.reserve_exact(len, cap - len); + fn from(mut other: Vec) -> Self { + let len = other.len(); + if mem::size_of::() == 0 { + // There's no actual allocation for ZSTs to worry about capacity, + // but `VecDeque` can't handle as much length as `Vec`. + assert!(len < MAXIMUM_ZST_CAPACITY, "capacity overflow"); + } else { + // We need to resize if the capacity is not a power of two, too small or + // doesn't have at least one free space. We do this while it's still in + // the `Vec` so the items will drop on panic. + let min_cap = cmp::max(MINIMUM_CAPACITY, len) + 1; + let cap = cmp::max(min_cap, other.capacity()).next_power_of_two(); + if other.capacity() != cap { + other.reserve_exact(cap - len); } + } + unsafe { + let (other_buf, len, capacity) = other.into_raw_parts(); + let buf = RawVec::from_raw_parts(other_buf, capacity); VecDeque { tail: 0, head: len, buf } } } diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index 87e06fa394d..6116cfe1d01 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -457,6 +457,21 @@ fn test_from_vec() { assert!(vd.into_iter().eq(vec)); } } + + let vec = Vec::from([(); MAXIMUM_ZST_CAPACITY - 1]); + let vd = VecDeque::from(vec.clone()); + assert!(vd.cap().is_power_of_two()); + assert_eq!(vd.len(), vec.len()); +} + +#[test] +#[should_panic = "capacity overflow"] +fn test_from_vec_zst_overflow() { + use crate::vec::Vec; + let vec = Vec::from([(); MAXIMUM_ZST_CAPACITY]); + let vd = VecDeque::from(vec.clone()); // no room for +1 + assert!(vd.cap().is_power_of_two()); + assert_eq!(vd.len(), vec.len()); } #[test] From 55d9e0f601d9154d99a2fec3d803b42cbf60ff2a Mon Sep 17 00:00:00 2001 From: Julian Frimmel Date: Thu, 18 Mar 2021 09:52:21 +0100 Subject: [PATCH 04/14] Include output stream in `panic!()` documentation --- library/core/src/macros/panic.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index 6e502426df9..e5e286ca5a2 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -10,8 +10,8 @@ tests. `panic!` is closely tied with the `unwrap` method of both `panic!` when they are set to [`None`] or [`Err`] variants. This macro is used to inject panic into a Rust thread, causing the thread to -panic entirely. This macro panics with a string and uses the [`format!`] syntax -for building the message. +panic entirely. The string built by this macro (using the [`format!`] syntax +for building the actual message) is printed to `stderr`. Each thread's panic can be reaped as the [`Box`]`<`[`Any`]`>` type, which contains either a `&str` or `String` for regular `panic!()` invocations. From 61e5d549b49152b5fdc714fde93ab5c55e301127 Mon Sep 17 00:00:00 2001 From: Julian Frimmel Date: Thu, 18 Mar 2021 14:23:05 +0100 Subject: [PATCH 05/14] Add more information about panicking This includes the description of the default `std` behavior and mentions the `panic::set_hook()` function. --- library/core/src/macros/panic.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index e5e286ca5a2..39fe9d8077e 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -9,11 +9,14 @@ tests. `panic!` is closely tied with the `unwrap` method of both [`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call `panic!` when they are set to [`None`] or [`Err`] variants. -This macro is used to inject panic into a Rust thread, causing the thread to -panic entirely. The string built by this macro (using the [`format!`] syntax -for building the actual message) is printed to `stderr`. +When using `panic!()` you can specify a string payload, that is built using +the [`format!`] syntax. That payload is used when injecting the panic into +the calling Rust thread, causing the thread to panic entirely. -Each thread's panic can be reaped as the [`Box`]`<`[`Any`]`>` type, +The default `std` panic handling strategy is to print the message payload to +the `stderr` along with the file/line/column information of the `panic!()` +call. You can override the panic hook using [`std::panic::set_hook()`]. +Inside the hook a panic can be reaped as the [`Box`]`<`[`Any`]`>` type, which contains either a `&str` or `String` for regular `panic!()` invocations. To panic with a value of another other type, [`panic_any`] can be used. @@ -26,6 +29,7 @@ See also the macro [`compile_error!`], for raising errors during compilation. [ounwrap]: Option::unwrap [runwrap]: Result::unwrap +[`std::panic::set_hook()`]: ../std/panic/fn.set_hook.html [`panic_any`]: ../std/panic/fn.panic_any.html [`Box`]: ../std/boxed/struct.Box.html [`Any`]: crate::any::Any From d5e45b50cdfc029a061229d9edf5f5fa58eb0353 Mon Sep 17 00:00:00 2001 From: Julian Frimmel Date: Thu, 18 Mar 2021 15:15:28 +0100 Subject: [PATCH 06/14] Incorporate review feedback #2 --- library/core/src/macros/panic.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index 39fe9d8077e..e59be12a689 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -13,10 +13,11 @@ When using `panic!()` you can specify a string payload, that is built using the [`format!`] syntax. That payload is used when injecting the panic into the calling Rust thread, causing the thread to panic entirely. -The default `std` panic handling strategy is to print the message payload to -the `stderr` along with the file/line/column information of the `panic!()` +The behavior of the default `std` hook, i.e. the code, that runs directy +after the panic is invoked, is to print the message payload to the +`stderr` along with the file/line/column information of the `panic!()` call. You can override the panic hook using [`std::panic::set_hook()`]. -Inside the hook a panic can be reaped as the [`Box`]`<`[`Any`]`>` type, +Inside the hook a panic can be accessed as a `&dyn Any + Send`, which which contains either a `&str` or `String` for regular `panic!()` invocations. To panic with a value of another other type, [`panic_any`] can be used. From 1e322e33fe4469ff18e3d9fddc218b82bbede82e Mon Sep 17 00:00:00 2001 From: bstrie <865233+bstrie@users.noreply.github.com> Date: Thu, 18 Mar 2021 13:57:31 -0400 Subject: [PATCH 07/14] Revert the second deprecation of collections::Bound --- library/std/src/collections/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/src/collections/mod.rs b/library/std/src/collections/mod.rs index 7f8f9c991fe..8cda601edd1 100644 --- a/library/std/src/collections/mod.rs +++ b/library/std/src/collections/mod.rs @@ -401,9 +401,10 @@ #![stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_deprecated(reason = "moved to `std::ops::Bound`", since = "1.52.0")] +// FIXME(#82080) The deprecation here is only theoretical, and does not actually produce a warning. +#[rustc_deprecated(reason = "moved to `std::ops::Bound`", since = "1.26.0")] #[doc(hidden)] -pub type Bound = crate::ops::Bound; +pub use crate::ops::Bound; #[stable(feature = "rust1", since = "1.0.0")] pub use alloc_crate::collections::{binary_heap, btree_map, btree_set}; From 19bd0669b45fcc5ce81b8003cafccf318c3cc22e Mon Sep 17 00:00:00 2001 From: "J. Frimmel" <31166235+jfrimmel@users.noreply.github.com> Date: Thu, 18 Mar 2021 21:15:19 +0100 Subject: [PATCH 08/14] Apply suggestions from code review Co-authored-by: Josh Triplett --- library/core/src/macros/panic.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/macros/panic.md b/library/core/src/macros/panic.md index e59be12a689..5127a16bbfd 100644 --- a/library/core/src/macros/panic.md +++ b/library/core/src/macros/panic.md @@ -13,11 +13,11 @@ When using `panic!()` you can specify a string payload, that is built using the [`format!`] syntax. That payload is used when injecting the panic into the calling Rust thread, causing the thread to panic entirely. -The behavior of the default `std` hook, i.e. the code, that runs directy -after the panic is invoked, is to print the message payload to the +The behavior of the default `std` hook, i.e. the code that runs directly +after the panic is invoked, is to print the message payload to `stderr` along with the file/line/column information of the `panic!()` call. You can override the panic hook using [`std::panic::set_hook()`]. -Inside the hook a panic can be accessed as a `&dyn Any + Send`, which +Inside the hook a panic can be accessed as a `&dyn Any + Send`, which contains either a `&str` or `String` for regular `panic!()` invocations. To panic with a value of another other type, [`panic_any`] can be used. From 1c8c2616e4a83b04d08b7ba504a2ae83866a497a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 18 Mar 2021 11:12:28 -0700 Subject: [PATCH 09/14] Update LLVM to bring in SIMD updates for WebAssembly This is a continuation of https://github.com/rust-lang/llvm-project/pull/96 to continue to make progress on updating Rust's support for SIMD intrinsics on WebAssembly to the latest version of the specification. --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 62a1ddde22c..c3a26cbf6e7 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 62a1ddde22c267249eda72184520a21ad2052f0b +Subproject commit c3a26cbf6e73f2c5f8d03cee1f151d90a266ef3c From 778e1978d5ad67b1e4f69622b86237b1f4732f0f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 18 Mar 2021 17:35:46 -0300 Subject: [PATCH 10/14] Mark early otherwise optimization unsound --- compiler/rustc_mir/src/transform/early_otherwise_branch.rs | 5 +++++ src/test/mir-opt/early_otherwise_branch.rs | 2 +- src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs index e64a539c7f8..f7ea9faec47 100644 --- a/compiler/rustc_mir/src/transform/early_otherwise_branch.rs +++ b/compiler/rustc_mir/src/transform/early_otherwise_branch.rs @@ -26,6 +26,11 @@ pub struct EarlyOtherwiseBranch; impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + // FIXME(#78496) + if !tcx.sess.opts.debugging_opts.unsound_mir_opts { + return; + } + if tcx.sess.mir_opt_level() < 3 { return; } diff --git a/src/test/mir-opt/early_otherwise_branch.rs b/src/test/mir-opt/early_otherwise_branch.rs index 548213ab83c..b2caf7d7b8f 100644 --- a/src/test/mir-opt/early_otherwise_branch.rs +++ b/src/test/mir-opt/early_otherwise_branch.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z mir-opt-level=4 +// compile-flags: -Z mir-opt-level=4 -Z unsound-mir-opts // EMIT_MIR early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff fn opt1(x: Option, y: Option) -> u32 { match (x, y) { diff --git a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs index aa304f747f7..8527c01d756 100644 --- a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs +++ b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z mir-opt-level=4 +// compile-flags: -Z mir-opt-level=4 -Z unsound-mir-opts // EMIT_MIR early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff fn opt1(x: Option, y: Option, z: Option) -> u32 { From 430c0d1d95475f5edb066da53c3b2174d6223d80 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 19 Mar 2021 11:46:27 +0000 Subject: [PATCH 11/14] Do not ICE on ty::Error as an error must already have been reported --- compiler/rustc_middle/src/ty/relate.rs | 14 +++++++---- .../ui/const-generics/type_not_in_scope.rs | 11 +++++++++ .../const-generics/type_not_in_scope.stderr | 24 +++++++++++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/const-generics/type_not_in_scope.rs create mode 100644 src/test/ui/const-generics/type_not_in_scope.stderr diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 436ca4c0578..b41bf70e88e 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -10,6 +10,7 @@ use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_hir as ast; use rustc_hir::def_id::DefId; +use rustc_span::DUMMY_SP; use rustc_target::spec::abi; use std::iter; @@ -499,11 +500,14 @@ pub fn super_relate_consts>( // FIXME(oli-obk): once const generics can have generic types, this assertion // will likely get triggered. Move to `normalize_erasing_regions` at that point. - assert_eq!( - tcx.erase_regions(a.ty), - tcx.erase_regions(b.ty), - "cannot relate constants of different types" - ); + let a_ty = tcx.erase_regions(a.ty); + let b_ty = tcx.erase_regions(b.ty); + if a_ty != b_ty { + relation.tcx().sess.delay_span_bug( + DUMMY_SP, + &format!("cannot relate constants of different types: {} != {}", a_ty, b_ty), + ); + } let eagerly_eval = |x: &'tcx ty::Const<'tcx>| x.eval(tcx, relation.param_env()); let a = eagerly_eval(a); diff --git a/src/test/ui/const-generics/type_not_in_scope.rs b/src/test/ui/const-generics/type_not_in_scope.rs new file mode 100644 index 00000000000..5933701808b --- /dev/null +++ b/src/test/ui/const-generics/type_not_in_scope.rs @@ -0,0 +1,11 @@ +impl X { + //~^ ERROR cannot find type + fn getn() -> [u8; N] { + getn::() + } +} +fn getn() -> [u8; N] {} +//~^ ERROR expected type, found built-in attribute `cfg_attr` +//~| ERROR mismatched types + +fn main() {} diff --git a/src/test/ui/const-generics/type_not_in_scope.stderr b/src/test/ui/const-generics/type_not_in_scope.stderr new file mode 100644 index 00000000000..16796acb3d2 --- /dev/null +++ b/src/test/ui/const-generics/type_not_in_scope.stderr @@ -0,0 +1,24 @@ +error[E0412]: cannot find type `X` in this scope + --> $DIR/type_not_in_scope.rs:1:6 + | +LL | impl X { + | ^ not found in this scope + +error[E0573]: expected type, found built-in attribute `cfg_attr` + --> $DIR/type_not_in_scope.rs:7:18 + | +LL | fn getn() -> [u8; N] {} + | ^^^^^^^^ not a type + +error[E0308]: mismatched types + --> $DIR/type_not_in_scope.rs:7:33 + | +LL | fn getn() -> [u8; N] {} + | ---- ^^^^^^^ expected array `[u8; N]`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0308, E0412, E0573. +For more information about an error, try `rustc --explain E0308`. From 957705802ee2f255ec57e42fe60a59a60e56a425 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 19 Mar 2021 13:30:27 +0000 Subject: [PATCH 12/14] Add a second regression test --- src/test/ui/const-generics/type_mismatch.rs | 9 ++++++++ .../ui/const-generics/type_mismatch.stderr | 23 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/test/ui/const-generics/type_mismatch.rs create mode 100644 src/test/ui/const-generics/type_mismatch.stderr diff --git a/src/test/ui/const-generics/type_mismatch.rs b/src/test/ui/const-generics/type_mismatch.rs new file mode 100644 index 00000000000..4a7534e3713 --- /dev/null +++ b/src/test/ui/const-generics/type_mismatch.rs @@ -0,0 +1,9 @@ +fn foo() -> [u8; N] { + bar::() //~ ERROR mismatched types +} + +fn bar() -> [u8; N] {} +//~^ ERROR mismatched types +//~| ERROR mismatched types + +fn main() {} diff --git a/src/test/ui/const-generics/type_mismatch.stderr b/src/test/ui/const-generics/type_mismatch.stderr new file mode 100644 index 00000000000..f5053e4c8c8 --- /dev/null +++ b/src/test/ui/const-generics/type_mismatch.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:2:11 + | +LL | bar::() + | ^ expected `u8`, found `usize` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:5:31 + | +LL | fn bar() -> [u8; N] {} + | ^ expected `usize`, found `u8` + +error[E0308]: mismatched types + --> $DIR/type_mismatch.rs:5:26 + | +LL | fn bar() -> [u8; N] {} + | --- ^^^^^^^ expected array `[u8; N]`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. From 1491496eb08a1114a612ab66062eb9b89712d452 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 12 Dec 2020 23:32:44 +0100 Subject: [PATCH 13/14] Only build help popup when it's really needed --- src/librustdoc/html/static/main.js | 31 ++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index e7b522093c7..ed88e65c4f0 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -374,28 +374,35 @@ function defocusSearchBar() { } } - function getHelpElement() { - buildHelperPopup(); + function getHelpElement(build) { + if (build !== false) { + buildHelperPopup(); + } return document.getElementById("help"); } function displayHelp(display, ev, help) { - help = help ? help : getHelpElement(); if (display === true) { + help = help ? help : getHelpElement(true); if (hasClass(help, "hidden")) { ev.preventDefault(); removeClass(help, "hidden"); addClass(document.body, "blur"); } - } else if (hasClass(help, "hidden") === false) { - ev.preventDefault(); - addClass(help, "hidden"); - removeClass(document.body, "blur"); + } else { + // No need to build the help popup if we want to hide it in case it hasn't been + // built yet... + help = help ? help : getHelpElement(false); + if (help && hasClass(help, "hidden") === false) { + ev.preventDefault(); + addClass(help, "hidden"); + removeClass(document.body, "blur"); + } } } function handleEscape(ev) { - var help = getHelpElement(); + var help = getHelpElement(false); var search = getSearchElement(); if (hasClass(help, "hidden") === false) { displayHelp(false, ev, help); @@ -558,6 +565,7 @@ function defocusSearchBar() { }()); document.addEventListener("click", function(ev) { + var helpElem = getHelpElement(false); if (hasClass(ev.target, "help-button")) { displayHelp(true, ev); } else if (hasClass(ev.target, "collapse-toggle")) { @@ -566,11 +574,10 @@ function defocusSearchBar() { collapseDocs(ev.target.parentNode, "toggle"); } else if (ev.target.tagName === "SPAN" && hasClass(ev.target.parentNode, "line-numbers")) { handleSourceHighlight(ev); - } else if (hasClass(getHelpElement(), "hidden") === false) { - var help = getHelpElement(); - var is_inside_help_popup = ev.target !== help && help.contains(ev.target); + } else if (helpElem && hasClass(helpElem, "hidden") === false) { + var is_inside_help_popup = ev.target !== helpElem && helpElem.contains(ev.target); if (is_inside_help_popup === false) { - addClass(help, "hidden"); + addClass(helpElem, "hidden"); removeClass(document.body, "blur"); } } else { From e2c70f7da0accb932708e0ffd01c7e2865e75eed Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 19 Mar 2021 17:33:27 +0100 Subject: [PATCH 14/14] Ignore main.js file length --- src/librustdoc/html/static/main.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ed88e65c4f0..f1ecaaa619c 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1,3 +1,4 @@ +// ignore-tidy-filelength // Local js definitions: /* global addClass, getSettingValue, hasClass */ /* global onEach, onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */