Auto merge of #83308 - Dylan-DPC:rollup-p2j6sy8, r=Dylan-DPC
Rollup of 8 pull requests Successful merges: - #79986 (Only build help popup when it's really needed) - #82570 (Add `as_str` method for split whitespace str iterators) - #83244 (Fix overflowing length in Vec<ZST> to VecDeque) - #83254 (Include output stream in `panic!()` documentation) - #83269 (Revert the second deprecation of collections::Bound) - #83277 (Mark early otherwise optimization unsound) - #83285 (Update LLVM to bring in SIMD updates for WebAssembly) - #83297 (Do not ICE on ty::Error as an error must already have been reported) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
6bfbf0c33a
@ -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<R: TypeRelation<'tcx>>(
|
||||
|
||||
// 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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -2783,27 +2783,26 @@ impl<T> From<Vec<T>> for VecDeque<T> {
|
||||
/// 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<T>` came from `From<VecDeque<T>>` and hasn't been reallocated.
|
||||
fn from(other: Vec<T>) -> 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::<T>() != 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<T>) -> Self {
|
||||
let len = other.len();
|
||||
if mem::size_of::<T>() == 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 }
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -13,7 +13,8 @@ use crate::ops::Try;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(Clone)]
|
||||
pub struct Filter<I, P> {
|
||||
iter: I,
|
||||
// Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods
|
||||
pub(crate) iter: I,
|
||||
predicate: P,
|
||||
}
|
||||
impl<I, P> Filter<I, P> {
|
||||
|
@ -57,7 +57,8 @@ use crate::ops::Try;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(Clone)]
|
||||
pub struct Map<I, F> {
|
||||
iter: I,
|
||||
// Used for `SplitWhitespace` and `SplitAsciiWhitespace` `as_str` methods
|
||||
pub(crate) iter: I,
|
||||
f: F,
|
||||
}
|
||||
|
||||
|
@ -9,11 +9,15 @@ 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. This macro panics with a string and uses the [`format!`] syntax
|
||||
for building the message.
|
||||
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 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 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 +30,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
|
||||
|
@ -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> {
|
||||
|
@ -1200,6 +1200,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;
|
||||
@ -1231,6 +1255,35 @@ 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;
|
||||
|
@ -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<T> = crate::ops::Bound<T>;
|
||||
pub use crate::ops::Bound;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use alloc_crate::collections::{binary_heap, btree_map, btree_set};
|
||||
|
@ -1,3 +1,4 @@
|
||||
// ignore-tidy-filelength
|
||||
// Local js definitions:
|
||||
/* global addClass, getSettingValue, hasClass */
|
||||
/* global onEach, onEachLazy, hasOwnProperty, removeClass, updateLocalStorage */
|
||||
@ -374,28 +375,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 +566,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 +575,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 {
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 62a1ddde22c267249eda72184520a21ad2052f0b
|
||||
Subproject commit c3a26cbf6e73f2c5f8d03cee1f151d90a266ef3c
|
@ -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<u32>, y: Option<u32>) -> u32 {
|
||||
match (x, y) {
|
||||
|
@ -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<u32>, y: Option<u32>, z: Option<u32>) -> u32 {
|
||||
|
9
src/test/ui/const-generics/type_mismatch.rs
Normal file
9
src/test/ui/const-generics/type_mismatch.rs
Normal file
@ -0,0 +1,9 @@
|
||||
fn foo<const N: usize>() -> [u8; N] {
|
||||
bar::<N>() //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn bar<const N: u8>() -> [u8; N] {}
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
|
||||
fn main() {}
|
23
src/test/ui/const-generics/type_mismatch.stderr
Normal file
23
src/test/ui/const-generics/type_mismatch.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type_mismatch.rs:2:11
|
||||
|
|
||||
LL | bar::<N>()
|
||||
| ^ expected `u8`, found `usize`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type_mismatch.rs:5:31
|
||||
|
|
||||
LL | fn bar<const N: u8>() -> [u8; N] {}
|
||||
| ^ expected `usize`, found `u8`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type_mismatch.rs:5:26
|
||||
|
|
||||
LL | fn bar<const N: u8>() -> [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`.
|
11
src/test/ui/const-generics/type_not_in_scope.rs
Normal file
11
src/test/ui/const-generics/type_not_in_scope.rs
Normal file
@ -0,0 +1,11 @@
|
||||
impl X {
|
||||
//~^ ERROR cannot find type
|
||||
fn getn<const N: usize>() -> [u8; N] {
|
||||
getn::<N>()
|
||||
}
|
||||
}
|
||||
fn getn<const N: cfg_attr>() -> [u8; N] {}
|
||||
//~^ ERROR expected type, found built-in attribute `cfg_attr`
|
||||
//~| ERROR mismatched types
|
||||
|
||||
fn main() {}
|
24
src/test/ui/const-generics/type_not_in_scope.stderr
Normal file
24
src/test/ui/const-generics/type_not_in_scope.stderr
Normal file
@ -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<const N: cfg_attr>() -> [u8; N] {}
|
||||
| ^^^^^^^^ not a type
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type_not_in_scope.rs:7:33
|
||||
|
|
||||
LL | fn getn<const N: cfg_attr>() -> [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`.
|
Loading…
x
Reference in New Issue
Block a user