mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
Auto merge of #57063 - kennytm:rollup, r=kennytm
Rollup of 25 pull requests Successful merges: - #56802 (Add DoubleEndedIterator::nth_back) - #56909 (static eval: Do not ICE on layout size overflow) - #56914 (Ignore ui/target-feature-gate on sparc, sparc64, powerpc, powerpc64 and powerpc64le) - #56919 (Remove a wrong multiplier on relocation offset computation) - #56933 (Add --progress to git submodule commands in x.py) - #56936 (rename div_euc -> div_euclid, and mod_euc -> rem_euclid) - #56941 (deny intra-doc link resolution failures in libstd) - #56945 (Fix rustdoc-js tests) - #56967 (Replace current crate's searchIndex when regenerating) - #56970 (Mem uninit doc ptr drop) - #56973 (make basic CTFE tracing available on release builds) - #56979 (Adding unwinding support for x86_64_fortanix_unknown_sgx target.) - #56981 (miri: allocation is infallible) - #56984 (A few tweaks to dropck_outlives) - #56989 (Fix compiletest `trim` deprecation warnings) - #56992 (suggest similar lint names for unknown lints) - #57002 (Stabilize Vec(Deque)::resize_with) - #57011 (rustdoc: add new CLI flag to load static files from a different location) - #57027 (Optimize away a move) - #57034 (Inline tweaks) - #57039 (Update migrate warning wording.) - #57040 (Fix feature gate to point to 1.32.0 for `path_from_str`) - #57049 (Stabilize #[repr(packed(N))]) - #57050 (Fixed typo in HashMap documentation) - #57052 (Fix stabilization version numbers (exhaustive_integer_patterns + macro_literal_matcher))
This commit is contained in:
commit
16329b0ad3
@ -678,10 +678,10 @@ class RustBuild(object):
|
||||
|
||||
print("Updating submodule", module)
|
||||
|
||||
run(["git", "submodule", "-q", "sync", module],
|
||||
run(["git", "submodule", "-q", "sync", "--progress", module],
|
||||
cwd=self.rust_root, verbose=self.verbose)
|
||||
run(["git", "submodule", "update",
|
||||
"--init", "--recursive", module],
|
||||
"--init", "--recursive", "--progress", module],
|
||||
cwd=self.rust_root, verbose=self.verbose)
|
||||
run(["git", "reset", "-q", "--hard"],
|
||||
cwd=module_path, verbose=self.verbose)
|
||||
|
@ -402,3 +402,18 @@ Using `index-page` option enables `enable-index-page` option as well.
|
||||
### `--enable-index-page`: generate a default index page for docs
|
||||
|
||||
This feature allows the generation of a default index-page which lists the generated crates.
|
||||
|
||||
### `--static-root-path`: control how static files are loaded in HTML output
|
||||
|
||||
Using this flag looks like this:
|
||||
|
||||
```bash
|
||||
$ rustdoc src/lib.rs -Z unstable-options --static-root-path '/cache/'
|
||||
```
|
||||
|
||||
This flag controls how rustdoc links to its static files on HTML pages. If you're hosting a lot of
|
||||
crates' docs generated by the same version of rustdoc, you can use this flag to cache rustdoc's CSS,
|
||||
JavaScript, and font files in a single location, rather than duplicating it once per "doc root"
|
||||
(grouping of crate docs generated into the same output directory, like with `cargo doc`). Per-crate
|
||||
files like the search index will still load from the documentation root, but anything that gets
|
||||
renamed with `--resource-suffix` will load from the given path.
|
||||
|
@ -1,8 +0,0 @@
|
||||
# `repr_packed`
|
||||
|
||||
The tracking issue for this feature is [#33158]
|
||||
|
||||
[#33158]: https://github.com/rust-lang/rust/issues/33158
|
||||
|
||||
------------------------
|
||||
|
@ -1897,8 +1897,6 @@ impl<T> VecDeque<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(vec_resize_with)]
|
||||
///
|
||||
/// use std::collections::VecDeque;
|
||||
///
|
||||
/// let mut buf = VecDeque::new();
|
||||
@ -1917,7 +1915,7 @@ impl<T> VecDeque<T> {
|
||||
/// buf.resize_with(5, || { state += 1; state });
|
||||
/// assert_eq!(buf, [5, 10, 101, 102, 103]);
|
||||
/// ```
|
||||
#[unstable(feature = "vec_resize_with", issue = "41758")]
|
||||
#[stable(feature = "vec_resize_with", since = "1.33.0")]
|
||||
pub fn resize_with(&mut self, new_len: usize, generator: impl FnMut()->T) {
|
||||
let len = self.len();
|
||||
|
||||
|
@ -72,6 +72,8 @@
|
||||
test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
|
||||
#![no_std]
|
||||
#![needs_allocator]
|
||||
|
||||
#![deny(intra_doc_link_resolution_failure)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
|
||||
#![cfg_attr(not(test), feature(fn_traits))]
|
||||
|
@ -843,6 +843,8 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Rc<T> {
|
||||
/// drop(foo); // Doesn't print anything
|
||||
/// drop(foo2); // Prints "dropped!"
|
||||
/// ```
|
||||
///
|
||||
/// [`Weak`]: ../../std/rc/struct.Weak.html
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
self.dec_strong();
|
||||
@ -1422,9 +1424,10 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Weak<T> {
|
||||
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
||||
impl<T> Default for Weak<T> {
|
||||
/// Constructs a new `Weak<T>`, allocating memory for `T` without initializing
|
||||
/// it. Calling [`upgrade`][Weak::upgrade] on the return value always gives [`None`].
|
||||
/// it. Calling [`upgrade`] on the return value always gives [`None`].
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html
|
||||
/// [`upgrade`]: ../../std/rc/struct.Weak.html#method.upgrade
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -955,6 +955,8 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Arc<T> {
|
||||
/// drop(foo); // Doesn't print anything
|
||||
/// drop(foo2); // Prints "dropped!"
|
||||
/// ```
|
||||
///
|
||||
/// [`Weak`]: ../../std/sync/struct.Weak.html
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
// Because `fetch_sub` is already atomic, we do not need to synchronize
|
||||
@ -1222,10 +1224,11 @@ impl<T: ?Sized> Clone for Weak<T> {
|
||||
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
||||
impl<T> Default for Weak<T> {
|
||||
/// Constructs a new `Weak<T>`, without allocating memory.
|
||||
/// Calling [`upgrade`][Weak::upgrade] on the return value always
|
||||
/// Calling [`upgrade`] on the return value always
|
||||
/// gives [`None`].
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
/// [`upgrade`]: ../../std/sync/struct.Weak.html#method.upgrade
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -1241,8 +1241,6 @@ impl<T> Vec<T> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(vec_resize_with)]
|
||||
///
|
||||
/// let mut vec = vec![1, 2, 3];
|
||||
/// vec.resize_with(5, Default::default);
|
||||
/// assert_eq!(vec, [1, 2, 3, 0, 0]);
|
||||
@ -1255,7 +1253,7 @@ impl<T> Vec<T> {
|
||||
///
|
||||
/// [`resize`]: #method.resize
|
||||
/// [`Clone`]: ../../std/clone/trait.Clone.html
|
||||
#[unstable(feature = "vec_resize_with", issue = "41758")]
|
||||
#[stable(feature = "vec_resize_with", since = "1.33.0")]
|
||||
pub fn resize_with<F>(&mut self, new_len: usize, f: F)
|
||||
where F: FnMut() -> T
|
||||
{
|
||||
|
@ -429,6 +429,9 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
|
||||
|
||||
#[inline]
|
||||
fn nth(&mut self, n: usize) -> Option<<I as Iterator>::Item> { self.iter.nth_back(n) }
|
||||
|
||||
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
|
||||
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
|
||||
{
|
||||
@ -461,6 +464,9 @@ impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next() }
|
||||
|
||||
#[inline]
|
||||
fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> { self.iter.nth(n) }
|
||||
|
||||
fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
|
||||
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
|
||||
{
|
||||
|
@ -427,6 +427,62 @@ pub trait DoubleEndedIterator: Iterator {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn next_back(&mut self) -> Option<Self::Item>;
|
||||
|
||||
/// Returns the `n`th element from the end of the iterator.
|
||||
///
|
||||
/// This is essentially the reversed version of [`nth`]. Although like most indexing
|
||||
/// operations, the count starts from zero, so `nth_back(0)` returns the first value fro
|
||||
/// the end, `nth_back(1)` the second, and so on.
|
||||
///
|
||||
/// Note that all elements between the end and the returned element will be
|
||||
/// consumed, including the returned element. This also means that calling
|
||||
/// `nth_back(0)` multiple times on the same iterator will return different
|
||||
/// elements.
|
||||
///
|
||||
/// `nth_back()` will return [`None`] if `n` is greater than or equal to the length of the
|
||||
/// iterator.
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
/// [`nth`]: ../../std/iter/trait.Iterator.html#method.nth
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_nth_back)]
|
||||
/// let a = [1, 2, 3];
|
||||
/// assert_eq!(a.iter().nth_back(2), Some(&1));
|
||||
/// ```
|
||||
///
|
||||
/// Calling `nth_back()` multiple times doesn't rewind the iterator:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_nth_back)]
|
||||
/// let a = [1, 2, 3];
|
||||
///
|
||||
/// let mut iter = a.iter();
|
||||
///
|
||||
/// assert_eq!(iter.nth_back(1), Some(&2));
|
||||
/// assert_eq!(iter.nth_back(1), None);
|
||||
/// ```
|
||||
///
|
||||
/// Returning `None` if there are less than `n + 1` elements:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(iter_nth_back)]
|
||||
/// let a = [1, 2, 3];
|
||||
/// assert_eq!(a.iter().nth_back(10), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "iter_nth_back", issue = "56995")]
|
||||
fn nth_back(&mut self, mut n: usize) -> Option<Self::Item> {
|
||||
for x in self.rev() {
|
||||
if n == 0 { return Some(x) }
|
||||
n -= 1;
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// This is the reverse version of [`try_fold()`]: it takes elements
|
||||
/// starting from the back of the iterator.
|
||||
///
|
||||
@ -461,8 +517,11 @@ pub trait DoubleEndedIterator: Iterator {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "iterator_try_fold", since = "1.27.0")]
|
||||
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
|
||||
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
|
||||
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(B, Self::Item) -> R,
|
||||
R: Try<Ok=B>
|
||||
{
|
||||
let mut accum = init;
|
||||
while let Some(x) = self.next_back() {
|
||||
@ -524,8 +583,10 @@ pub trait DoubleEndedIterator: Iterator {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "iter_rfold", since = "1.27.0")]
|
||||
fn rfold<B, F>(mut self, accum: B, mut f: F) -> B where
|
||||
Self: Sized, F: FnMut(B, Self::Item) -> B,
|
||||
fn rfold<B, F>(mut self, accum: B, mut f: F) -> B
|
||||
where
|
||||
Self: Sized,
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
self.try_rfold(accum, move |acc, x| Ok::<B, !>(f(acc, x))).unwrap()
|
||||
}
|
||||
@ -574,7 +635,8 @@ pub trait DoubleEndedIterator: Iterator {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "iter_rfind", since = "1.27.0")]
|
||||
fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
|
||||
fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item>
|
||||
where
|
||||
Self: Sized,
|
||||
P: FnMut(&Self::Item) -> bool
|
||||
{
|
||||
@ -587,7 +649,12 @@ pub trait DoubleEndedIterator: Iterator {
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
|
||||
fn next_back(&mut self) -> Option<I::Item> { (**self).next_back() }
|
||||
fn next_back(&mut self) -> Option<I::Item> {
|
||||
(**self).next_back()
|
||||
}
|
||||
fn nth_back(&mut self, n: usize) -> Option<I::Item> {
|
||||
(**self).nth_back(n)
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that knows its exact length.
|
||||
|
@ -71,6 +71,7 @@
|
||||
|
||||
#![no_core]
|
||||
#![deny(missing_docs)]
|
||||
#![deny(intra_doc_link_resolution_failure)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
|
||||
#![feature(allow_internal_unstable)]
|
||||
|
@ -530,6 +530,12 @@ pub unsafe fn zeroed<T>() -> T {
|
||||
/// it goes out of scope (and therefore would be dropped). Note that this
|
||||
/// includes a `panic` occurring and unwinding the stack suddenly.
|
||||
///
|
||||
/// If you partially initialize an array, you may need to use
|
||||
/// [`ptr::drop_in_place`][drop_in_place] to remove the elements you have fully
|
||||
/// initialized followed by [`mem::forget`][mem_forget] to prevent drop running
|
||||
/// on the array. If a partially allocated array is dropped this will lead to
|
||||
/// undefined behaviour.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Here's how to safely initialize an array of [`Vec`]s.
|
||||
@ -583,11 +589,44 @@ pub unsafe fn zeroed<T>() -> T {
|
||||
/// println!("{:?}", &data[0]);
|
||||
/// ```
|
||||
///
|
||||
/// This example shows how to handle partially initialized arrays, which could
|
||||
/// be found in low-level datastructures.
|
||||
///
|
||||
/// ```
|
||||
/// use std::mem;
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// // Count the number of elements we have assigned.
|
||||
/// let mut data_len: usize = 0;
|
||||
/// let mut data: [String; 1000];
|
||||
///
|
||||
/// unsafe {
|
||||
/// data = mem::uninitialized();
|
||||
///
|
||||
/// for elem in &mut data[0..500] {
|
||||
/// ptr::write(elem, String::from("hello"));
|
||||
/// data_len += 1;
|
||||
/// }
|
||||
///
|
||||
/// // For each item in the array, drop if we allocated it.
|
||||
/// for i in &mut data[0..data_len] {
|
||||
/// ptr::drop_in_place(i);
|
||||
/// }
|
||||
/// }
|
||||
/// // Forget the data. If this is allowed to drop, you may see a crash such as:
|
||||
/// // 'mem_uninit_test(2457,0x7fffb55dd380) malloc: *** error for object
|
||||
/// // 0x7ff3b8402920: pointer being freed was not allocated'
|
||||
/// mem::forget(data);
|
||||
/// ```
|
||||
///
|
||||
/// [`Vec`]: ../../std/vec/struct.Vec.html
|
||||
/// [`vec!`]: ../../std/macro.vec.html
|
||||
/// [`Clone`]: ../../std/clone/trait.Clone.html
|
||||
/// [ub]: ../../reference/behavior-considered-undefined.html
|
||||
/// [write]: ../ptr/fn.write.html
|
||||
/// [drop_in_place]: ../ptr/fn.drop_in_place.html
|
||||
/// [mem_zeroed]: fn.zeroed.html
|
||||
/// [mem_forget]: fn.forget.html
|
||||
/// [copy]: ../intrinsics/fn.copy.html
|
||||
/// [copy_no]: ../intrinsics/fn.copy_nonoverlapping.html
|
||||
/// [`Drop`]: ../ops/trait.Drop.html
|
||||
@ -984,6 +1023,9 @@ impl<T> ManuallyDrop<T> {
|
||||
///
|
||||
/// This function semantically moves out the contained value without preventing further usage.
|
||||
/// It is up to the user of this method to ensure that this container is not used again.
|
||||
///
|
||||
/// [`ManuallyDrop::drop`]: #method.drop
|
||||
/// [`ManuallyDrop::into_inner`]: #method.into_inner
|
||||
#[must_use = "if you don't need the value, you can use `ManuallyDrop::drop` instead"]
|
||||
#[unstable(feature = "manually_drop_take", issue = "55422")]
|
||||
#[inline]
|
||||
|
@ -673,7 +673,7 @@ $EndFeature, "
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Checked Euclidean division. Computes `self.div_euc(rhs)`,
|
||||
concat!("Checked Euclidean division. Computes `self.div_euclid(rhs)`,
|
||||
returning `None` if `rhs == 0` or the division results in overflow.
|
||||
|
||||
# Examples
|
||||
@ -683,17 +683,17 @@ Basic usage:
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!((", stringify!($SelfT),
|
||||
"::min_value() + 1).checked_div_euc(-1), Some(", stringify!($Max), "));
|
||||
assert_eq!(", stringify!($SelfT), "::min_value().checked_div_euc(-1), None);
|
||||
assert_eq!((1", stringify!($SelfT), ").checked_div_euc(0), None);
|
||||
"::min_value() + 1).checked_div_euclid(-1), Some(", stringify!($Max), "));
|
||||
assert_eq!(", stringify!($SelfT), "::min_value().checked_div_euclid(-1), None);
|
||||
assert_eq!((1", stringify!($SelfT), ").checked_div_euclid(0), None);
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
pub fn checked_div_euc(self, rhs: Self) -> Option<Self> {
|
||||
pub fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
|
||||
if rhs == 0 || (self == Self::min_value() && rhs == -1) {
|
||||
None
|
||||
} else {
|
||||
Some(self.div_euc(rhs))
|
||||
Some(self.div_euclid(rhs))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -726,8 +726,8 @@ $EndFeature, "
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Checked Euclidean modulo. Computes `self.mod_euc(rhs)`, returning `None` if
|
||||
`rhs == 0` or the division results in overflow.
|
||||
concat!("Checked Euclidean remainder. Computes `self.rem_euclid(rhs)`, returning `None`
|
||||
if `rhs == 0` or the division results in overflow.
|
||||
|
||||
# Examples
|
||||
|
||||
@ -737,17 +737,17 @@ Basic usage:
|
||||
#![feature(euclidean_division)]
|
||||
use std::", stringify!($SelfT), ";
|
||||
|
||||
assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(2), Some(1));
|
||||
assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(0), None);
|
||||
assert_eq!(", stringify!($SelfT), "::MIN.checked_mod_euc(-1), None);
|
||||
assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));
|
||||
assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
|
||||
assert_eq!(", stringify!($SelfT), "::MIN.checked_rem_euclid(-1), None);
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
pub fn checked_mod_euc(self, rhs: Self) -> Option<Self> {
|
||||
pub fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
|
||||
if rhs == 0 || (self == Self::min_value() && rhs == -1) {
|
||||
None
|
||||
} else {
|
||||
Some(self.mod_euc(rhs))
|
||||
Some(self.rem_euclid(rhs))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1089,7 +1089,7 @@ $EndFeature, "
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Wrapping Euclidean division. Computes `self.div_euc(rhs)`,
|
||||
concat!("Wrapping Euclidean division. Computes `self.div_euclid(rhs)`,
|
||||
wrapping around at the boundary of the type.
|
||||
|
||||
Wrapping will only occur in `MIN / -1` on a signed type (where `MIN` is the negative minimal value
|
||||
@ -1106,13 +1106,13 @@ Basic usage:
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(100", stringify!($SelfT), ".wrapping_div_euc(10), 10);
|
||||
assert_eq!((-128i8).wrapping_div_euc(-1), -128);
|
||||
assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
|
||||
assert_eq!((-128i8).wrapping_div_euclid(-1), -128);
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
pub fn wrapping_div_euc(self, rhs: Self) -> Self {
|
||||
self.overflowing_div_euc(rhs).0
|
||||
pub fn wrapping_div_euclid(self, rhs: Self) -> Self {
|
||||
self.overflowing_div_euclid(rhs).0
|
||||
}
|
||||
}
|
||||
|
||||
@ -1145,8 +1145,8 @@ $EndFeature, "
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Wrapping Euclidean modulo. Computes `self.mod_euc(rhs)`, wrapping around at the
|
||||
boundary of the type.
|
||||
concat!("Wrapping Euclidean remainder. Computes `self.rem_euclid(rhs)`, wrapping around
|
||||
at the boundary of the type.
|
||||
|
||||
Wrapping will only occur in `MIN % -1` on a signed type (where `MIN` is the negative minimal value
|
||||
for the type). In this case, this method returns 0.
|
||||
@ -1161,13 +1161,13 @@ Basic usage:
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(100", stringify!($SelfT), ".wrapping_mod_euc(10), 0);
|
||||
assert_eq!((-128i8).wrapping_mod_euc(-1), 0);
|
||||
assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
|
||||
assert_eq!((-128i8).wrapping_rem_euclid(-1), 0);
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
pub fn wrapping_mod_euc(self, rhs: Self) -> Self {
|
||||
self.overflowing_mod_euc(rhs).0
|
||||
pub fn wrapping_rem_euclid(self, rhs: Self) -> Self {
|
||||
self.overflowing_rem_euclid(rhs).0
|
||||
}
|
||||
}
|
||||
|
||||
@ -1442,7 +1442,7 @@ $EndFeature, "
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Calculates the quotient of Euclidean division `self.div_euc(rhs)`.
|
||||
concat!("Calculates the quotient of Euclidean division `self.div_euclid(rhs)`.
|
||||
|
||||
Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would
|
||||
occur. If an overflow would occur then `self` is returned.
|
||||
@ -1459,17 +1459,17 @@ Basic usage:
|
||||
#![feature(euclidean_division)]
|
||||
use std::", stringify!($SelfT), ";
|
||||
|
||||
assert_eq!(5", stringify!($SelfT), ".overflowing_div_euc(2), (2, false));
|
||||
assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euc(-1), (", stringify!($SelfT),
|
||||
assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));
|
||||
assert_eq!(", stringify!($SelfT), "::MIN.overflowing_div_euclid(-1), (", stringify!($SelfT),
|
||||
"::MIN, true));
|
||||
```"),
|
||||
#[inline]
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
pub fn overflowing_div_euc(self, rhs: Self) -> (Self, bool) {
|
||||
pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
|
||||
if self == Self::min_value() && rhs == -1 {
|
||||
(self, true)
|
||||
} else {
|
||||
(self.div_euc(rhs), false)
|
||||
(self.div_euclid(rhs), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1508,7 +1508,7 @@ $EndFeature, "
|
||||
|
||||
|
||||
doc_comment! {
|
||||
concat!("Calculates the remainder `self.mod_euc(rhs)` by Euclidean division.
|
||||
concat!("Overflowing Euclidean remainder. Calculates `self.rem_euclid(rhs)`.
|
||||
|
||||
Returns a tuple of the remainder after dividing along with a boolean indicating whether an
|
||||
arithmetic overflow would occur. If an overflow would occur then 0 is returned.
|
||||
@ -1525,16 +1525,16 @@ Basic usage:
|
||||
#![feature(euclidean_division)]
|
||||
use std::", stringify!($SelfT), ";
|
||||
|
||||
assert_eq!(5", stringify!($SelfT), ".overflowing_mod_euc(2), (1, false));
|
||||
assert_eq!(", stringify!($SelfT), "::MIN.overflowing_mod_euc(-1), (0, true));
|
||||
assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
|
||||
assert_eq!(", stringify!($SelfT), "::MIN.overflowing_rem_euclid(-1), (0, true));
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
pub fn overflowing_mod_euc(self, rhs: Self) -> (Self, bool) {
|
||||
pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
|
||||
if self == Self::min_value() && rhs == -1 {
|
||||
(0, true)
|
||||
} else {
|
||||
(self.mod_euc(rhs), false)
|
||||
(self.rem_euclid(rhs), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1739,9 +1739,13 @@ $EndFeature, "
|
||||
doc_comment! {
|
||||
concat!("Calculates the quotient of Euclidean division of `self` by `rhs`.
|
||||
|
||||
This computes the integer `n` such that `self = n * rhs + self.mod_euc(rhs)`.
|
||||
This computes the integer `n` such that `self = n * rhs + self.rem_euclid(rhs)`,
|
||||
with `0 <= self.rem_euclid(rhs) < rhs`.
|
||||
|
||||
In other words, the result is `self / rhs` rounded to the integer `n`
|
||||
such that `self >= n * rhs`.
|
||||
If `self > 0`, this is equal to round towards zero (the default in Rust);
|
||||
if `self < 0`, this is equal to round towards +/- infinity.
|
||||
|
||||
# Panics
|
||||
|
||||
@ -1756,15 +1760,15 @@ Basic usage:
|
||||
let a: ", stringify!($SelfT), " = 7; // or any other integer type
|
||||
let b = 4;
|
||||
|
||||
assert_eq!(a.div_euc(b), 1); // 7 >= 4 * 1
|
||||
assert_eq!(a.div_euc(-b), -1); // 7 >= -4 * -1
|
||||
assert_eq!((-a).div_euc(b), -2); // -7 >= 4 * -2
|
||||
assert_eq!((-a).div_euc(-b), 2); // -7 >= -4 * 2
|
||||
assert_eq!(a.div_euclid(b), 1); // 7 >= 4 * 1
|
||||
assert_eq!(a.div_euclid(-b), -1); // 7 >= -4 * -1
|
||||
assert_eq!((-a).div_euclid(b), -2); // -7 >= 4 * -2
|
||||
assert_eq!((-a).div_euclid(-b), 2); // -7 >= -4 * 2
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn div_euc(self, rhs: Self) -> Self {
|
||||
pub fn div_euclid(self, rhs: Self) -> Self {
|
||||
let q = self / rhs;
|
||||
if self % rhs < 0 {
|
||||
return if rhs > 0 { q - 1 } else { q + 1 }
|
||||
@ -1775,9 +1779,11 @@ assert_eq!((-a).div_euc(-b), 2); // -7 >= -4 * 2
|
||||
|
||||
|
||||
doc_comment! {
|
||||
concat!("Calculates the remainder `self mod rhs` by Euclidean division.
|
||||
concat!("Calculates the least nonnegative remainder of `self (mod rhs)`.
|
||||
|
||||
In particular, the result `n` satisfies `0 <= n < rhs.abs()`.
|
||||
This is done as if by the Euclidean division algorithm -- given
|
||||
`r = self.rem_euclid(rhs)`, `self = rhs * self.div_euclid(rhs) + r`, and
|
||||
`0 <= r < abs(rhs)`.
|
||||
|
||||
# Panics
|
||||
|
||||
@ -1792,15 +1798,15 @@ Basic usage:
|
||||
let a: ", stringify!($SelfT), " = 7; // or any other integer type
|
||||
let b = 4;
|
||||
|
||||
assert_eq!(a.mod_euc(b), 3);
|
||||
assert_eq!((-a).mod_euc(b), 1);
|
||||
assert_eq!(a.mod_euc(-b), 3);
|
||||
assert_eq!((-a).mod_euc(-b), 1);
|
||||
assert_eq!(a.rem_euclid(b), 3);
|
||||
assert_eq!((-a).rem_euclid(b), 1);
|
||||
assert_eq!(a.rem_euclid(-b), 3);
|
||||
assert_eq!((-a).rem_euclid(-b), 1);
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn mod_euc(self, rhs: Self) -> Self {
|
||||
pub fn rem_euclid(self, rhs: Self) -> Self {
|
||||
let r = self % rhs;
|
||||
if r < 0 {
|
||||
if rhs < 0 {
|
||||
@ -2611,7 +2617,7 @@ assert_eq!(1", stringify!($SelfT), ".checked_div(0), None);", $EndFeature, "
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Checked Euclidean division. Computes `self.div_euc(rhs)`, returning `None`
|
||||
concat!("Checked Euclidean division. Computes `self.div_euclid(rhs)`, returning `None`
|
||||
if `rhs == 0`.
|
||||
|
||||
# Examples
|
||||
@ -2620,16 +2626,16 @@ Basic usage:
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(128", stringify!($SelfT), ".checked_div(2), Some(64));
|
||||
assert_eq!(1", stringify!($SelfT), ".checked_div_euc(0), None);
|
||||
assert_eq!(128", stringify!($SelfT), ".checked_div_euclid(2), Some(64));
|
||||
assert_eq!(1", stringify!($SelfT), ".checked_div_euclid(0), None);
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
pub fn checked_div_euc(self, rhs: Self) -> Option<Self> {
|
||||
pub fn checked_div_euclid(self, rhs: Self) -> Option<Self> {
|
||||
if rhs == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(self.div_euc(rhs))
|
||||
Some(self.div_euclid(rhs))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2659,7 +2665,7 @@ assert_eq!(5", stringify!($SelfT), ".checked_rem(0), None);", $EndFeature, "
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Checked Euclidean modulo. Computes `self.mod_euc(rhs)`, returning `None`
|
||||
concat!("Checked Euclidean modulo. Computes `self.rem_euclid(rhs)`, returning `None`
|
||||
if `rhs == 0`.
|
||||
|
||||
# Examples
|
||||
@ -2668,16 +2674,16 @@ Basic usage:
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(2), Some(1));
|
||||
assert_eq!(5", stringify!($SelfT), ".checked_mod_euc(0), None);
|
||||
assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(2), Some(1));
|
||||
assert_eq!(5", stringify!($SelfT), ".checked_rem_euclid(0), None);
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
pub fn checked_mod_euc(self, rhs: Self) -> Option<Self> {
|
||||
pub fn checked_rem_euclid(self, rhs: Self) -> Option<Self> {
|
||||
if rhs == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(self.mod_euc(rhs))
|
||||
Some(self.rem_euclid(rhs))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2965,11 +2971,14 @@ Basic usage:
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Wrapping Euclidean division. Computes `self.div_euc(rhs)`.
|
||||
concat!("Wrapping Euclidean division. Computes `self.div_euclid(rhs)`.
|
||||
Wrapped division on unsigned types is just normal division.
|
||||
There's no way wrapping could ever happen.
|
||||
This function exists, so that all operations
|
||||
are accounted for in the wrapping operations.
|
||||
Since, for the positive integers, all common
|
||||
definitions of division are equal, this
|
||||
is exactly equal to `self.wrapping_div(rhs)`.
|
||||
|
||||
# Examples
|
||||
|
||||
@ -2977,11 +2986,11 @@ Basic usage:
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(100", stringify!($SelfT), ".wrapping_div_euc(10), 10);
|
||||
assert_eq!(100", stringify!($SelfT), ".wrapping_div_euclid(10), 10);
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
pub fn wrapping_div_euc(self, rhs: Self) -> Self {
|
||||
pub fn wrapping_div_euclid(self, rhs: Self) -> Self {
|
||||
self / rhs
|
||||
}
|
||||
}
|
||||
@ -3009,12 +3018,15 @@ Basic usage:
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Wrapping Euclidean modulo. Computes `self.mod_euc(rhs)`.
|
||||
concat!("Wrapping Euclidean modulo. Computes `self.rem_euclid(rhs)`.
|
||||
Wrapped modulo calculation on unsigned types is
|
||||
just the regular remainder calculation.
|
||||
There's no way wrapping could ever happen.
|
||||
This function exists, so that all operations
|
||||
are accounted for in the wrapping operations.
|
||||
Since, for the positive integers, all common
|
||||
definitions of division are equal, this
|
||||
is exactly equal to `self.wrapping_rem(rhs)`.
|
||||
|
||||
# Examples
|
||||
|
||||
@ -3022,11 +3034,11 @@ Basic usage:
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(100", stringify!($SelfT), ".wrapping_mod_euc(10), 0);
|
||||
assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0);
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
pub fn wrapping_mod_euc(self, rhs: Self) -> Self {
|
||||
pub fn wrapping_rem_euclid(self, rhs: Self) -> Self {
|
||||
self % rhs
|
||||
}
|
||||
}
|
||||
@ -3270,12 +3282,15 @@ Basic usage
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Calculates the quotient of Euclidean division `self.div_euc(rhs)`.
|
||||
concat!("Calculates the quotient of Euclidean division `self.div_euclid(rhs)`.
|
||||
|
||||
Returns a tuple of the divisor along with a boolean indicating
|
||||
whether an arithmetic overflow would occur. Note that for unsigned
|
||||
integers overflow never occurs, so the second value is always
|
||||
`false`.
|
||||
Since, for the positive integers, all common
|
||||
definitions of division are equal, this
|
||||
is exactly equal to `self.overflowing_div(rhs)`.
|
||||
|
||||
# Panics
|
||||
|
||||
@ -3287,11 +3302,11 @@ Basic usage
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(5", stringify!($SelfT), ".overflowing_div_euc(2), (2, false));
|
||||
assert_eq!(5", stringify!($SelfT), ".overflowing_div_euclid(2), (2, false));
|
||||
```"),
|
||||
#[inline]
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
pub fn overflowing_div_euc(self, rhs: Self) -> (Self, bool) {
|
||||
pub fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
|
||||
(self / rhs, false)
|
||||
}
|
||||
}
|
||||
@ -3323,12 +3338,15 @@ Basic usage
|
||||
}
|
||||
|
||||
doc_comment! {
|
||||
concat!("Calculates the remainder `self.mod_euc(rhs)` by Euclidean division.
|
||||
concat!("Calculates the remainder `self.rem_euclid(rhs)` as if by Euclidean division.
|
||||
|
||||
Returns a tuple of the modulo after dividing along with a boolean
|
||||
indicating whether an arithmetic overflow would occur. Note that for
|
||||
unsigned integers overflow never occurs, so the second value is
|
||||
always `false`.
|
||||
Since, for the positive integers, all common
|
||||
definitions of division are equal, this operation
|
||||
is exactly equal to `self.overflowing_rem(rhs)`.
|
||||
|
||||
# Panics
|
||||
|
||||
@ -3340,11 +3358,11 @@ Basic usage
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(5", stringify!($SelfT), ".overflowing_mod_euc(2), (1, false));
|
||||
assert_eq!(5", stringify!($SelfT), ".overflowing_rem_euclid(2), (1, false));
|
||||
```"),
|
||||
#[inline]
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
pub fn overflowing_mod_euc(self, rhs: Self) -> (Self, bool) {
|
||||
pub fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
|
||||
(self % rhs, false)
|
||||
}
|
||||
}
|
||||
@ -3511,7 +3529,9 @@ Basic usage:
|
||||
doc_comment! {
|
||||
concat!("Performs Euclidean division.
|
||||
|
||||
For unsigned types, this is just the same as `self / rhs`.
|
||||
Since, for the positive integers, all common
|
||||
definitions of division are equal, this
|
||||
is exactly equal to `self / rhs`.
|
||||
|
||||
# Examples
|
||||
|
||||
@ -3519,21 +3539,23 @@ Basic usage:
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(7", stringify!($SelfT), ".div_euc(4), 1); // or any other integer type
|
||||
assert_eq!(7", stringify!($SelfT), ".div_euclid(4), 1); // or any other integer type
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn div_euc(self, rhs: Self) -> Self {
|
||||
pub fn div_euclid(self, rhs: Self) -> Self {
|
||||
self / rhs
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
doc_comment! {
|
||||
concat!("Calculates the remainder `self mod rhs` by Euclidean division.
|
||||
concat!("Calculates the least remainder of `self (mod rhs)`.
|
||||
|
||||
For unsigned types, this is just the same as `self % rhs`.
|
||||
Since, for the positive integers, all common
|
||||
definitions of division are equal, this
|
||||
is exactly equal to `self % rhs`.
|
||||
|
||||
# Examples
|
||||
|
||||
@ -3541,12 +3563,12 @@ Basic usage:
|
||||
|
||||
```
|
||||
#![feature(euclidean_division)]
|
||||
assert_eq!(7", stringify!($SelfT), ".mod_euc(4), 3); // or any other integer type
|
||||
assert_eq!(7", stringify!($SelfT), ".rem_euclid(4), 3); // or any other integer type
|
||||
```"),
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn mod_euc(self, rhs: Self) -> Self {
|
||||
pub fn rem_euclid(self, rhs: Self) -> Self {
|
||||
self % rhs
|
||||
}
|
||||
}
|
||||
|
@ -877,6 +877,7 @@ impl<T> [T] {
|
||||
/// assert_eq!(iter.remainder(), &['l']);
|
||||
/// ```
|
||||
///
|
||||
/// [`chunks`]: #method.chunks
|
||||
/// [`rchunks`]: #method.rchunks
|
||||
/// [`chunks_exact`]: #method.chunks_exact
|
||||
#[stable(feature = "rchunks", since = "1.31.0")]
|
||||
@ -921,6 +922,7 @@ impl<T> [T] {
|
||||
/// assert_eq!(v, &[0, 2, 2, 1, 1]);
|
||||
/// ```
|
||||
///
|
||||
/// [`chunks_mut`]: #method.chunks_mut
|
||||
/// [`rchunks_mut`]: #method.rchunks_mut
|
||||
/// [`chunks_exact_mut`]: #method.chunks_exact_mut
|
||||
#[stable(feature = "rchunks", since = "1.31.0")]
|
||||
|
@ -1016,6 +1016,33 @@ fn test_iterator_nth() {
|
||||
assert_eq!(v.iter().nth(v.len()), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_nth_back() {
|
||||
let v: &[_] = &[0, 1, 2, 3, 4];
|
||||
for i in 0..v.len() {
|
||||
assert_eq!(v.iter().nth_back(i).unwrap(), &v[v.len() - 1 - i]);
|
||||
}
|
||||
assert_eq!(v.iter().nth_back(v.len()), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_rev_nth_back() {
|
||||
let v: &[_] = &[0, 1, 2, 3, 4];
|
||||
for i in 0..v.len() {
|
||||
assert_eq!(v.iter().rev().nth_back(i).unwrap(), &v[i]);
|
||||
}
|
||||
assert_eq!(v.iter().rev().nth_back(v.len()), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_rev_nth() {
|
||||
let v: &[_] = &[0, 1, 2, 3, 4];
|
||||
for i in 0..v.len() {
|
||||
assert_eq!(v.iter().rev().nth(i).unwrap(), &v[v.len() - 1 - i]);
|
||||
}
|
||||
assert_eq!(v.iter().rev().nth(v.len()), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_last() {
|
||||
let v: &[_] = &[0, 1, 2, 3, 4];
|
||||
|
@ -19,6 +19,7 @@
|
||||
#![feature(flt2dec)]
|
||||
#![feature(fmt_internals)]
|
||||
#![feature(hashmap_internals)]
|
||||
#![feature(iter_nth_back)]
|
||||
#![feature(iter_unfold)]
|
||||
#![feature(pattern)]
|
||||
#![feature(range_is_empty)]
|
||||
|
@ -31,8 +31,8 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mod_euc() {
|
||||
assert!((-1 as $T).mod_euc(MIN) == MAX);
|
||||
fn test_rem_euclid() {
|
||||
assert!((-1 as $T).rem_euclid(MIN) == MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -694,23 +694,23 @@ macro_rules! test_float {
|
||||
assert!(($nan as $fty).max($nan).is_nan());
|
||||
}
|
||||
#[test]
|
||||
fn mod_euc() {
|
||||
fn rem_euclid() {
|
||||
let a: $fty = 42.0;
|
||||
assert!($inf.mod_euc(a).is_nan());
|
||||
assert_eq!(a.mod_euc($inf), a);
|
||||
assert!(a.mod_euc($nan).is_nan());
|
||||
assert!($inf.mod_euc($inf).is_nan());
|
||||
assert!($inf.mod_euc($nan).is_nan());
|
||||
assert!($nan.mod_euc($inf).is_nan());
|
||||
assert!($inf.rem_euclid(a).is_nan());
|
||||
assert_eq!(a.rem_euclid($inf), a);
|
||||
assert!(a.rem_euclid($nan).is_nan());
|
||||
assert!($inf.rem_euclid($inf).is_nan());
|
||||
assert!($inf.rem_euclid($nan).is_nan());
|
||||
assert!($nan.rem_euclid($inf).is_nan());
|
||||
}
|
||||
#[test]
|
||||
fn div_euc() {
|
||||
fn div_euclid() {
|
||||
let a: $fty = 42.0;
|
||||
assert_eq!(a.div_euc($inf), 0.0);
|
||||
assert!(a.div_euc($nan).is_nan());
|
||||
assert!($inf.div_euc($inf).is_nan());
|
||||
assert!($inf.div_euc($nan).is_nan());
|
||||
assert!($nan.div_euc($inf).is_nan());
|
||||
assert_eq!(a.div_euclid($inf), 0.0);
|
||||
assert!(a.div_euclid($nan).is_nan());
|
||||
assert!($inf.div_euclid($inf).is_nan());
|
||||
assert!($inf.div_euclid($nan).is_nan());
|
||||
assert!($nan.div_euclid($inf).is_nan());
|
||||
}
|
||||
} }
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ cfg_if! {
|
||||
if #[cfg(target_os = "emscripten")] {
|
||||
#[path = "emcc.rs"]
|
||||
mod imp;
|
||||
} else if #[cfg(any(target_arch = "wasm32", target_env = "sgx"))] {
|
||||
} else if #[cfg(target_arch = "wasm32")] {
|
||||
#[path = "dummy.rs"]
|
||||
mod imp;
|
||||
} else if #[cfg(all(target_env = "msvc", target_arch = "aarch64"))] {
|
||||
|
@ -42,11 +42,12 @@ use util::nodemap::FxHashMap;
|
||||
use std::default::Default as StdDefault;
|
||||
use syntax::ast;
|
||||
use syntax::edition;
|
||||
use syntax_pos::{MultiSpan, Span, symbol::LocalInternedString};
|
||||
use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
|
||||
use errors::DiagnosticBuilder;
|
||||
use hir;
|
||||
use hir::def_id::LOCAL_CRATE;
|
||||
use hir::intravisit as hir_visit;
|
||||
use syntax::util::lev_distance::find_best_match_for_name;
|
||||
use syntax::visit as ast_visit;
|
||||
|
||||
/// Information about the registered lints.
|
||||
@ -139,8 +140,8 @@ struct LintGroup {
|
||||
|
||||
pub enum CheckLintNameResult<'a> {
|
||||
Ok(&'a [LintId]),
|
||||
/// Lint doesn't exist
|
||||
NoLint,
|
||||
/// Lint doesn't exist. Potentially contains a suggestion for a correct lint name.
|
||||
NoLint(Option<Symbol>),
|
||||
/// The lint is either renamed or removed. This is the warning
|
||||
/// message, and an optional new name (`None` if removed).
|
||||
Warning(String, Option<String>),
|
||||
@ -359,8 +360,14 @@ impl LintStore {
|
||||
CheckLintNameResult::Warning(ref msg, _) => {
|
||||
Some(sess.struct_warn(msg))
|
||||
},
|
||||
CheckLintNameResult::NoLint => {
|
||||
Some(struct_err!(sess, E0602, "unknown lint: `{}`", lint_name))
|
||||
CheckLintNameResult::NoLint(suggestion) => {
|
||||
let mut err = struct_err!(sess, E0602, "unknown lint: `{}`", lint_name);
|
||||
|
||||
if let Some(suggestion) = suggestion {
|
||||
err.help(&format!("did you mean: `{}`", suggestion));
|
||||
}
|
||||
|
||||
Some(err)
|
||||
}
|
||||
CheckLintNameResult::Tool(result) => match result {
|
||||
Err((Some(_), new_name)) => Some(sess.struct_warn(&format!(
|
||||
@ -464,7 +471,16 @@ impl LintStore {
|
||||
match self.by_name.get(&complete_name) {
|
||||
None => match self.lint_groups.get(&*complete_name) {
|
||||
// Now we are sure, that this lint exists nowhere
|
||||
None => CheckLintNameResult::NoLint,
|
||||
None => {
|
||||
let symbols = self.by_name.keys()
|
||||
.map(|name| Symbol::intern(&name))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let suggestion =
|
||||
find_best_match_for_name(symbols.iter(), &lint_name.to_lowercase(), None);
|
||||
|
||||
CheckLintNameResult::NoLint(suggestion)
|
||||
}
|
||||
Some(LintGroup { lint_ids, depr, .. }) => {
|
||||
// Reaching this would be weird, but let's cover this case anyway
|
||||
if let Some(LintAlias { name, silent }) = depr {
|
||||
@ -484,7 +500,7 @@ impl LintStore {
|
||||
Some(&Id(ref id)) => {
|
||||
CheckLintNameResult::Tool(Err((Some(slice::from_ref(id)), complete_name)))
|
||||
}
|
||||
_ => CheckLintNameResult::NoLint,
|
||||
_ => CheckLintNameResult::NoLint(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ impl<'a> LintLevelsBuilder<'a> {
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
CheckLintNameResult::NoLint => {
|
||||
CheckLintNameResult::NoLint(suggestion) => {
|
||||
let lint = builtin::UNKNOWN_LINTS;
|
||||
let (level, src) = self.sets.get_lint_level(lint,
|
||||
self.cur,
|
||||
@ -398,26 +398,21 @@ impl<'a> LintLevelsBuilder<'a> {
|
||||
src,
|
||||
Some(li.span.into()),
|
||||
&msg);
|
||||
if name.as_str().chars().any(|c| c.is_uppercase()) {
|
||||
let name_lower = name.as_str().to_lowercase().to_string();
|
||||
if let CheckLintNameResult::NoLint =
|
||||
store.check_lint_name(&name_lower, tool_name) {
|
||||
db.emit();
|
||||
} else {
|
||||
|
||||
if let Some(suggestion) = suggestion {
|
||||
db.span_suggestion_with_applicability(
|
||||
li.span,
|
||||
"lowercase the lint name",
|
||||
name_lower,
|
||||
Applicability::MachineApplicable
|
||||
).emit();
|
||||
"did you mean",
|
||||
suggestion.to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
db.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (id, &(level, ref src)) in specs.iter() {
|
||||
if level == Level::Forbid {
|
||||
|
@ -55,8 +55,8 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
|
||||
let c_ty = self.infcx.canonicalize_query(&self.param_env.and(ty), &mut orig_values);
|
||||
let span = self.cause.span;
|
||||
debug!("c_ty = {:?}", c_ty);
|
||||
match &gcx.dropck_outlives(c_ty) {
|
||||
Ok(result) if result.is_proven() => {
|
||||
if let Ok(result) = &gcx.dropck_outlives(c_ty) {
|
||||
if result.is_proven() {
|
||||
if let Ok(InferOk { value, obligations }) =
|
||||
self.infcx.instantiate_query_response_and_region_obligations(
|
||||
self.cause,
|
||||
@ -72,8 +72,6 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
_ => { /* fallthrough to error-handling code below */ }
|
||||
}
|
||||
|
||||
// Errors and ambiuity in dropck occur in two cases:
|
||||
@ -82,10 +80,11 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
|
||||
// Either of these should have created an error before.
|
||||
tcx.sess
|
||||
.delay_span_bug(span, "dtorck encountered internal error");
|
||||
return InferOk {
|
||||
|
||||
InferOk {
|
||||
value: vec![],
|
||||
obligations: vec![],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,7 +101,7 @@ impl<'tcx> DropckOutlivesResult<'tcx> {
|
||||
span: Span,
|
||||
ty: Ty<'tcx>,
|
||||
) {
|
||||
for overflow_ty in self.overflows.iter().take(1) {
|
||||
if let Some(overflow_ty) = self.overflows.iter().next() {
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
span,
|
||||
@ -228,7 +227,7 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) ->
|
||||
|
||||
// (T1..Tn) and closures have same properties as T1..Tn --
|
||||
// check if *any* of those are trivial.
|
||||
ty::Tuple(ref tys) => tys.iter().cloned().all(|t| trivial_dropck_outlives(tcx, t)),
|
||||
ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t)),
|
||||
ty::Closure(def_id, ref substs) => substs
|
||||
.upvar_tys(def_id, tcx)
|
||||
.all(|t| trivial_dropck_outlives(tcx, t)),
|
||||
|
@ -1926,6 +1926,7 @@ pub mod tls {
|
||||
/// to `value` during the call to `f`. It is restored to its previous value after.
|
||||
/// This is used to set the pointer to the new ImplicitCtxt.
|
||||
#[cfg(parallel_queries)]
|
||||
#[inline]
|
||||
fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
|
||||
rayon_core::tlv::with(value, f)
|
||||
}
|
||||
@ -1933,6 +1934,7 @@ pub mod tls {
|
||||
/// Gets Rayon's thread local variable which is preserved for Rayon jobs.
|
||||
/// This is used to get the pointer to the current ImplicitCtxt.
|
||||
#[cfg(parallel_queries)]
|
||||
#[inline]
|
||||
fn get_tlv() -> usize {
|
||||
rayon_core::tlv::get()
|
||||
}
|
||||
@ -1945,6 +1947,7 @@ pub mod tls {
|
||||
/// It is restored to its previous value after.
|
||||
/// This is used to set the pointer to the new ImplicitCtxt.
|
||||
#[cfg(not(parallel_queries))]
|
||||
#[inline]
|
||||
fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
|
||||
let old = get_tlv();
|
||||
let _reset = OnDrop(move || TLV.with(|tlv| tlv.set(old)));
|
||||
@ -2009,6 +2012,7 @@ pub mod tls {
|
||||
}
|
||||
|
||||
/// Sets `context` as the new current ImplicitCtxt for the duration of the function `f`
|
||||
#[inline]
|
||||
pub fn enter_context<'a, 'gcx: 'tcx, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'gcx, 'tcx>,
|
||||
f: F) -> R
|
||||
where F: FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
|
||||
@ -2080,6 +2084,7 @@ pub mod tls {
|
||||
}
|
||||
|
||||
/// Allows access to the current ImplicitCtxt in a closure if one is available
|
||||
#[inline]
|
||||
pub fn with_context_opt<F, R>(f: F) -> R
|
||||
where F: for<'a, 'gcx, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'gcx, 'tcx>>) -> R
|
||||
{
|
||||
@ -2097,6 +2102,7 @@ pub mod tls {
|
||||
|
||||
/// Allows access to the current ImplicitCtxt.
|
||||
/// Panics if there is no ImplicitCtxt available
|
||||
#[inline]
|
||||
pub fn with_context<F, R>(f: F) -> R
|
||||
where F: for<'a, 'gcx, 'tcx> FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
|
||||
{
|
||||
@ -2108,6 +2114,7 @@ pub mod tls {
|
||||
/// with the same 'gcx lifetime as the TyCtxt passed in.
|
||||
/// This will panic if you pass it a TyCtxt which has a different global interner from
|
||||
/// the current ImplicitCtxt's tcx field.
|
||||
#[inline]
|
||||
pub fn with_related_context<'a, 'gcx, 'tcx1, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx1>, f: F) -> R
|
||||
where F: for<'b, 'tcx2> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx2>) -> R
|
||||
{
|
||||
@ -2126,6 +2133,7 @@ pub mod tls {
|
||||
/// is given an ImplicitCtxt with the same 'tcx and 'gcx lifetimes as the TyCtxt passed in.
|
||||
/// This will panic if you pass it a TyCtxt which has a different global interner or
|
||||
/// a different local interner from the current ImplicitCtxt's tcx field.
|
||||
#[inline]
|
||||
pub fn with_fully_related_context<'a, 'gcx, 'tcx, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx>, f: F) -> R
|
||||
where F: for<'b> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx>) -> R
|
||||
{
|
||||
@ -2143,6 +2151,7 @@ pub mod tls {
|
||||
|
||||
/// Allows access to the TyCtxt in the current ImplicitCtxt.
|
||||
/// Panics if there is no ImplicitCtxt available
|
||||
#[inline]
|
||||
pub fn with<F, R>(f: F) -> R
|
||||
where F: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R
|
||||
{
|
||||
@ -2151,6 +2160,7 @@ pub mod tls {
|
||||
|
||||
/// Allows access to the TyCtxt in the current ImplicitCtxt.
|
||||
/// The closure is passed None if there is no ImplicitCtxt available
|
||||
#[inline]
|
||||
pub fn with_opt<F, R>(f: F) -> R
|
||||
where F: for<'a, 'gcx, 'tcx> FnOnce(Option<TyCtxt<'a, 'gcx, 'tcx>>) -> R
|
||||
{
|
||||
|
@ -136,11 +136,14 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
|
||||
Entry::Vacant(entry) => {
|
||||
// No job entry for this query. Return a new one to be started later
|
||||
return tls::with_related_context(tcx, |icx| {
|
||||
// Create the `parent` variable before `info`. This allows LLVM
|
||||
// to elide the move of `info`
|
||||
let parent = icx.query.clone();
|
||||
let info = QueryInfo {
|
||||
span,
|
||||
query: Q::query(key.clone()),
|
||||
};
|
||||
let job = Lrc::new(QueryJob::new(info, icx.query.clone()));
|
||||
let job = Lrc::new(QueryJob::new(info, parent));
|
||||
let owner = JobOwner {
|
||||
cache,
|
||||
job: job.clone(),
|
||||
@ -171,6 +174,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
|
||||
|
||||
/// Completes the query by updating the query cache with the `result`,
|
||||
/// signals the waiter and forgets the JobOwner, so it won't poison the query
|
||||
#[inline(always)]
|
||||
pub(super) fn complete(self, result: &Q::Value, dep_node_index: DepNodeIndex) {
|
||||
// We can move out of `self` here because we `mem::forget` it below
|
||||
let key = unsafe { ptr::read(&self.key) };
|
||||
@ -227,6 +231,8 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
|
||||
#[inline(never)]
|
||||
#[cold]
|
||||
fn drop(&mut self) {
|
||||
// Poison the query so jobs waiting on it panic
|
||||
self.cache.borrow_mut().active.insert(self.key.clone(), QueryResult::Poisoned);
|
||||
|
@ -28,7 +28,6 @@
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(nll)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(vec_resize_with)]
|
||||
#![feature(hash_raw_entry)]
|
||||
#![feature(stmt_expr_attributes)]
|
||||
#![feature(core_intrinsics)]
|
||||
@ -113,12 +112,14 @@ pub struct OnDrop<F: Fn()>(pub F);
|
||||
impl<F: Fn()> OnDrop<F> {
|
||||
/// Forgets the function which prevents it from running.
|
||||
/// Ensure that the function owns no memory, otherwise it will be leaked.
|
||||
#[inline]
|
||||
pub fn disable(self) {
|
||||
std::mem::forget(self);
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Fn()> Drop for OnDrop<F> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
(self.0)();
|
||||
}
|
||||
|
@ -373,10 +373,14 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
||||
for err in &mut mbcx.errors_buffer {
|
||||
if err.is_error() {
|
||||
err.level = Level::Warning;
|
||||
err.warn("This error has been downgraded to a warning \
|
||||
for backwards compatibility with previous releases.\n\
|
||||
It represents potential unsoundness in your code.\n\
|
||||
This warning will become a hard error in the future.");
|
||||
err.warn(
|
||||
"this error has been downgraded to a warning for backwards \
|
||||
compatibility with previous releases",
|
||||
);
|
||||
err.warn(
|
||||
"this represents potential undefined behavior in your code and \
|
||||
this warning will become a hard error in the future",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
|
||||
}
|
||||
let layout = ecx.layout_of(mir.return_ty().subst(tcx, cid.instance.substs))?;
|
||||
assert!(!layout.is_unsized());
|
||||
let ret = ecx.allocate(layout, MemoryKind::Stack)?;
|
||||
let ret = ecx.allocate(layout, MemoryKind::Stack);
|
||||
|
||||
let name = ty::tls::with(|tcx| tcx.item_path_str(cid.instance.def_id()));
|
||||
let prom = cid.promoted.map_or(String::new(), |p| format!("::promoted[{:?}]", p));
|
||||
@ -490,8 +490,8 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
|
||||
_ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
||||
ptr: Pointer,
|
||||
_kind: MemoryKind<Self::MemoryKinds>,
|
||||
) -> EvalResult<'tcx, Pointer> {
|
||||
Ok(ptr)
|
||||
) -> Pointer {
|
||||
ptr
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -692,12 +692,16 @@ pub fn const_eval_raw_provider<'a, 'tcx>(
|
||||
let err = error_to_const_error(&ecx, error);
|
||||
// errors in statics are always emitted as fatal errors
|
||||
if tcx.is_static(def_id).is_some() {
|
||||
let err = err.report_as_error(ecx.tcx, "could not evaluate static initializer");
|
||||
// check that a static never produces `TooGeneric`
|
||||
let reported_err = err.report_as_error(ecx.tcx,
|
||||
"could not evaluate static initializer");
|
||||
// Ensure that if the above error was either `TooGeneric` or `Reported`
|
||||
// an error must be reported.
|
||||
if tcx.sess.err_count() == 0 {
|
||||
span_bug!(ecx.tcx.span, "static eval failure didn't emit an error: {:#?}", err);
|
||||
tcx.sess.delay_span_bug(err.span,
|
||||
&format!("static eval failure did not emit an error: {:#?}",
|
||||
reported_err));
|
||||
}
|
||||
err
|
||||
reported_err
|
||||
} else if def_id.is_local() {
|
||||
// constant defined in this crate, we can figure out a lint level!
|
||||
match tcx.describe_def(def_id) {
|
||||
|
@ -422,7 +422,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||
return_to_block: StackPopCleanup,
|
||||
) -> EvalResult<'tcx> {
|
||||
if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...
|
||||
debug!("PAUSING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
info!("PAUSING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
}
|
||||
::log_settings::settings().indentation += 1;
|
||||
|
||||
@ -491,7 +491,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||
}
|
||||
|
||||
if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE
|
||||
debug!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
}
|
||||
|
||||
if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit {
|
||||
@ -503,7 +503,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||
|
||||
pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx> {
|
||||
if self.stack.len() > 1 { // FIXME no check should be needed, but some instances ICE
|
||||
debug!("LEAVING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
info!("LEAVING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
}
|
||||
::log_settings::settings().indentation -= 1;
|
||||
let frame = self.stack.pop().expect(
|
||||
@ -557,7 +557,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||
}
|
||||
|
||||
if self.stack.len() > 1 { // FIXME should be "> 0", printing topmost frame crashes rustc...
|
||||
debug!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
info!("CONTINUING({}) {}", self.cur_frame(), self.frame().instance);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -185,7 +185,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
|
||||
ecx: &mut EvalContext<'a, 'mir, 'tcx, Self>,
|
||||
ptr: Pointer,
|
||||
kind: MemoryKind<Self::MemoryKinds>,
|
||||
) -> EvalResult<'tcx, Pointer<Self::PointerTag>>;
|
||||
) -> Pointer<Self::PointerTag>;
|
||||
|
||||
/// Executed when evaluating the `*` operator: Following a reference.
|
||||
/// This has the chance to adjust the tag. It should not change anything else!
|
||||
|
@ -131,10 +131,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
&mut self,
|
||||
alloc: Allocation<M::PointerTag, M::AllocExtra>,
|
||||
kind: MemoryKind<M::MemoryKinds>,
|
||||
) -> EvalResult<'tcx, AllocId> {
|
||||
) -> AllocId {
|
||||
let id = self.tcx.alloc_map.lock().reserve();
|
||||
self.alloc_map.insert(id, (kind, alloc));
|
||||
Ok(id)
|
||||
id
|
||||
}
|
||||
|
||||
pub fn allocate(
|
||||
@ -142,9 +142,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
size: Size,
|
||||
align: Align,
|
||||
kind: MemoryKind<M::MemoryKinds>,
|
||||
) -> EvalResult<'tcx, Pointer> {
|
||||
) -> Pointer {
|
||||
let extra = AllocationExtra::memory_allocated(size, &self.extra);
|
||||
Ok(Pointer::from(self.allocate_with(Allocation::undef(size, align, extra), kind)?))
|
||||
Pointer::from(self.allocate_with(Allocation::undef(size, align, extra), kind))
|
||||
}
|
||||
|
||||
pub fn reallocate(
|
||||
@ -162,7 +162,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
|
||||
// For simplicities' sake, we implement reallocate as "alloc, copy, dealloc".
|
||||
// This happens so rarely, the perf advantage is outweighed by the maintenance cost.
|
||||
let new_ptr = self.allocate(new_size, new_align, kind)?;
|
||||
let new_ptr = self.allocate(new_size, new_align, kind);
|
||||
self.copy(
|
||||
ptr.into(),
|
||||
old_align,
|
||||
@ -708,8 +708,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
relocations
|
||||
.iter()
|
||||
.map(|&(offset, reloc)| {
|
||||
(offset + dest.offset - src.offset + (i * size * relocations.len() as u64),
|
||||
reloc)
|
||||
// compute offset for current repetition
|
||||
let dest_offset = dest.offset + (i * size);
|
||||
(
|
||||
// shift offsets from source allocation to destination allocation
|
||||
offset + dest_offset - src.offset,
|
||||
reloc,
|
||||
)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
_ => {
|
||||
trace!("Forcing allocation for local of type {:?}", layout.ty);
|
||||
Operand::Indirect(
|
||||
*self.allocate(layout, MemoryKind::Stack)?
|
||||
*self.allocate(layout, MemoryKind::Stack)
|
||||
)
|
||||
}
|
||||
})
|
||||
|
@ -911,7 +911,7 @@ where
|
||||
// that might e.g., be an inner field of a struct with `Scalar` layout,
|
||||
// that has different alignment than the outer field.
|
||||
let local_layout = self.layout_of_local(&self.stack[frame], local)?;
|
||||
let ptr = self.allocate(local_layout, MemoryKind::Stack)?;
|
||||
let ptr = self.allocate(local_layout, MemoryKind::Stack);
|
||||
// We don't have to validate as we can assume the local
|
||||
// was already valid for its type.
|
||||
self.write_immediate_to_mplace_no_validate(value, ptr)?;
|
||||
@ -933,15 +933,15 @@ where
|
||||
&mut self,
|
||||
layout: TyLayout<'tcx>,
|
||||
kind: MemoryKind<M::MemoryKinds>,
|
||||
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||
) -> MPlaceTy<'tcx, M::PointerTag> {
|
||||
if layout.is_unsized() {
|
||||
assert!(self.tcx.features().unsized_locals, "cannot alloc memory for unsized type");
|
||||
// FIXME: What should we do here? We should definitely also tag!
|
||||
Ok(MPlaceTy::dangling(layout, self))
|
||||
MPlaceTy::dangling(layout, self)
|
||||
} else {
|
||||
let ptr = self.memory.allocate(layout.size, layout.align.abi, kind)?;
|
||||
let ptr = M::tag_new_allocation(self, ptr, kind)?;
|
||||
Ok(MPlaceTy::from_aligned_ptr(ptr, layout))
|
||||
let ptr = self.memory.allocate(layout.size, layout.align.abi, kind);
|
||||
let ptr = M::tag_new_allocation(self, ptr, kind);
|
||||
MPlaceTy::from_aligned_ptr(ptr, layout)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
}
|
||||
|
||||
fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> {
|
||||
debug!("{:?}", stmt);
|
||||
info!("{:?}", stmt);
|
||||
|
||||
use rustc::mir::StatementKind::*;
|
||||
|
||||
@ -289,7 +289,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
}
|
||||
|
||||
fn terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> EvalResult<'tcx> {
|
||||
debug!("{:?}", terminator.kind);
|
||||
info!("{:?}", terminator.kind);
|
||||
self.tcx.span = terminator.source_info.span;
|
||||
self.memory.tcx.span = terminator.source_info.span;
|
||||
|
||||
@ -299,7 +299,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
if !self.stack.is_empty() {
|
||||
// This should change *something*
|
||||
debug_assert!(self.cur_frame() != old_stack || self.frame().block != old_bb);
|
||||
debug!("// {:?}", self.frame().block);
|
||||
info!("// {:?}", self.frame().block);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
|
||||
ptr_size * (3 + methods.len() as u64),
|
||||
ptr_align,
|
||||
MemoryKind::Vtable,
|
||||
)?.with_default_tag();
|
||||
).with_default_tag();
|
||||
let tcx = &*self.tcx;
|
||||
|
||||
let drop = ::monomorphize::resolve_drop_in_place(*tcx, ty);
|
||||
|
@ -346,7 +346,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||
Rvalue::Cast(kind, ref operand, _) => {
|
||||
let (op, span) = self.eval_operand(operand, source_info)?;
|
||||
self.use_ecx(source_info, |this| {
|
||||
let dest = this.ecx.allocate(place_layout, MemoryKind::Stack)?;
|
||||
let dest = this.ecx.allocate(place_layout, MemoryKind::Stack);
|
||||
this.ecx.cast(op, kind, dest.into())?;
|
||||
Ok((dest.into(), span))
|
||||
})
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use std::iter;
|
||||
|
||||
use super::{LinkerFlavor, Target, TargetOptions, PanicStrategy};
|
||||
use super::{LinkerFlavor, PanicStrategy, Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Result<Target, String> {
|
||||
const PRE_LINK_ARGS: &[&str] = &[
|
||||
@ -32,6 +32,7 @@ pub fn target() -> Result<Target, String> {
|
||||
"-Wl,-Bsymbolic",
|
||||
"-Wl,--export-dynamic",
|
||||
];
|
||||
|
||||
const EXPORT_SYMBOLS: &[&str] = &[
|
||||
"sgx_entry",
|
||||
"HEAP_BASE",
|
||||
@ -41,19 +42,26 @@ pub fn target() -> Result<Target, String> {
|
||||
"ENCLAVE_SIZE",
|
||||
"CFGDATA_BASE",
|
||||
"DEBUG",
|
||||
"EH_FRM_HDR_BASE",
|
||||
"EH_FRM_HDR_SIZE",
|
||||
"TEXT_BASE",
|
||||
"TEXT_SIZE",
|
||||
];
|
||||
let opts = TargetOptions {
|
||||
dynamic_linking: false,
|
||||
executables: true,
|
||||
linker_is_gnu: true,
|
||||
max_atomic_width: Some(64),
|
||||
panic_strategy: PanicStrategy::Abort,
|
||||
panic_strategy: PanicStrategy::Unwind,
|
||||
cpu: "x86-64".into(),
|
||||
features: "+rdrnd,+rdseed".into(),
|
||||
position_independent_executables: true,
|
||||
pre_link_args: iter::once(
|
||||
(LinkerFlavor::Gcc, PRE_LINK_ARGS.iter().cloned().map(String::from).collect())
|
||||
).collect(),
|
||||
pre_link_args: iter::once((
|
||||
LinkerFlavor::Gcc,
|
||||
PRE_LINK_ARGS.iter().cloned().map(String::from).collect(),
|
||||
))
|
||||
.collect(),
|
||||
post_link_objects: vec!["libunwind.a".into()],
|
||||
override_export_symbols: Some(EXPORT_SYMBOLS.iter().cloned().map(String::from).collect()),
|
||||
..Default::default()
|
||||
};
|
||||
|
@ -181,6 +181,9 @@ pub struct RenderOptions {
|
||||
/// A file to use as the index page at the root of the output directory. Overrides
|
||||
/// `enable_index_page` to be true if set.
|
||||
pub index_page: Option<PathBuf>,
|
||||
/// An optional path to use as the location of static files. If not set, uses combinations of
|
||||
/// `../` to reach the documentation root.
|
||||
pub static_root_path: Option<String>,
|
||||
|
||||
// Options specific to reading standalone Markdown files
|
||||
|
||||
@ -433,6 +436,7 @@ impl Options {
|
||||
let markdown_playground_url = matches.opt_str("markdown-playground-url");
|
||||
let crate_version = matches.opt_str("crate-version");
|
||||
let enable_index_page = matches.opt_present("enable-index-page") || index_page.is_some();
|
||||
let static_root_path = matches.opt_str("static-root-path");
|
||||
|
||||
let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
|
||||
|
||||
@ -471,6 +475,7 @@ impl Options {
|
||||
enable_minification,
|
||||
enable_index_page,
|
||||
index_page,
|
||||
static_root_path,
|
||||
markdown_no_toc,
|
||||
markdown_css,
|
||||
markdown_playground_url,
|
||||
|
@ -26,16 +26,20 @@ pub struct Page<'a> {
|
||||
pub title: &'a str,
|
||||
pub css_class: &'a str,
|
||||
pub root_path: &'a str,
|
||||
pub static_root_path: Option<&'a str>,
|
||||
pub description: &'a str,
|
||||
pub keywords: &'a str,
|
||||
pub resource_suffix: &'a str,
|
||||
pub extra_scripts: &'a [&'a str],
|
||||
pub static_extra_scripts: &'a [&'a str],
|
||||
}
|
||||
|
||||
pub fn render<T: fmt::Display, S: fmt::Display>(
|
||||
dst: &mut dyn io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
|
||||
css_file_extension: bool, themes: &[PathBuf], extra_scripts: &[&str])
|
||||
css_file_extension: bool, themes: &[PathBuf])
|
||||
-> io::Result<()>
|
||||
{
|
||||
let static_root_path = page.static_root_path.unwrap_or(page.root_path);
|
||||
write!(dst,
|
||||
"<!DOCTYPE html>\
|
||||
<html lang=\"en\">\
|
||||
@ -46,20 +50,20 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
|
||||
<meta name=\"description\" content=\"{description}\">\
|
||||
<meta name=\"keywords\" content=\"{keywords}\">\
|
||||
<title>{title}</title>\
|
||||
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}normalize{suffix}.css\">\
|
||||
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}rustdoc{suffix}.css\" \
|
||||
<link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}normalize{suffix}.css\">\
|
||||
<link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}rustdoc{suffix}.css\" \
|
||||
id=\"mainThemeStyle\">\
|
||||
{themes}\
|
||||
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}dark{suffix}.css\">\
|
||||
<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}light{suffix}.css\" \
|
||||
<link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}dark{suffix}.css\">\
|
||||
<link rel=\"stylesheet\" type=\"text/css\" href=\"{static_root_path}light{suffix}.css\" \
|
||||
id=\"themeStyle\">\
|
||||
<script src=\"{root_path}storage{suffix}.js\"></script>\
|
||||
<noscript><link rel=\"stylesheet\" href=\"{root_path}noscript{suffix}.css\"></noscript>\
|
||||
<script src=\"{static_root_path}storage{suffix}.js\"></script>\
|
||||
<noscript><link rel=\"stylesheet\" href=\"{static_root_path}noscript{suffix}.css\"></noscript>\
|
||||
{css_extension}\
|
||||
{favicon}\
|
||||
{in_header}\
|
||||
<style type=\"text/css\">\
|
||||
#crate-search{{background-image:url(\"{root_path}down-arrow{suffix}.svg\");}}\
|
||||
#crate-search{{background-image:url(\"{static_root_path}down-arrow{suffix}.svg\");}}\
|
||||
</style>\
|
||||
</head>\
|
||||
<body class=\"rustdoc {css_class}\">\
|
||||
@ -77,11 +81,13 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
|
||||
</nav>\
|
||||
<div class=\"theme-picker\">\
|
||||
<button id=\"theme-picker\" aria-label=\"Pick another theme!\">\
|
||||
<img src=\"{root_path}brush{suffix}.svg\" width=\"18\" alt=\"Pick another theme!\">\
|
||||
<img src=\"{static_root_path}brush{suffix}.svg\" \
|
||||
width=\"18\" \
|
||||
alt=\"Pick another theme!\">\
|
||||
</button>\
|
||||
<div id=\"theme-choices\"></div>\
|
||||
</div>\
|
||||
<script src=\"{root_path}theme{suffix}.js\"></script>\
|
||||
<script src=\"{static_root_path}theme{suffix}.js\"></script>\
|
||||
<nav class=\"sub\">\
|
||||
<form class=\"search-form js-only\">\
|
||||
<div class=\"search-container\">\
|
||||
@ -96,7 +102,9 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
|
||||
type=\"search\">\
|
||||
</div>\
|
||||
<a id=\"settings-menu\" href=\"{root_path}settings.html\">\
|
||||
<img src=\"{root_path}wheel{suffix}.svg\" width=\"18\" alt=\"Change settings\">\
|
||||
<img src=\"{static_root_path}wheel{suffix}.svg\" \
|
||||
width=\"18\" \
|
||||
alt=\"Change settings\">\
|
||||
</a>\
|
||||
</div>\
|
||||
</form>\
|
||||
@ -157,19 +165,23 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
|
||||
window.currentCrate = \"{krate}\";\
|
||||
</script>\
|
||||
<script src=\"{root_path}aliases.js\"></script>\
|
||||
<script src=\"{root_path}main{suffix}.js\"></script>\
|
||||
<script src=\"{static_root_path}main{suffix}.js\"></script>\
|
||||
{static_extra_scripts}\
|
||||
{extra_scripts}\
|
||||
<script defer src=\"{root_path}search-index.js\"></script>\
|
||||
</body>\
|
||||
</html>",
|
||||
css_extension = if css_file_extension {
|
||||
format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme{suffix}.css\">",
|
||||
root_path = page.root_path,
|
||||
format!("<link rel=\"stylesheet\" \
|
||||
type=\"text/css\" \
|
||||
href=\"{static_root_path}theme{suffix}.css\">",
|
||||
static_root_path = static_root_path,
|
||||
suffix=page.resource_suffix)
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
content = *t,
|
||||
static_root_path = static_root_path,
|
||||
root_path = page.root_path,
|
||||
css_class = page.css_class,
|
||||
logo = if layout.logo.is_empty() {
|
||||
@ -197,12 +209,17 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
|
||||
.filter_map(|t| t.file_stem())
|
||||
.filter_map(|t| t.to_str())
|
||||
.map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}{}.css">"#,
|
||||
page.root_path,
|
||||
static_root_path,
|
||||
t,
|
||||
page.resource_suffix))
|
||||
.collect::<String>(),
|
||||
suffix=page.resource_suffix,
|
||||
extra_scripts=extra_scripts.iter().map(|e| {
|
||||
static_extra_scripts=page.static_extra_scripts.iter().map(|e| {
|
||||
format!("<script src=\"{static_root_path}{extra_script}.js\"></script>",
|
||||
static_root_path=static_root_path,
|
||||
extra_script=e)
|
||||
}).collect::<String>(),
|
||||
extra_scripts=page.extra_scripts.iter().map(|e| {
|
||||
format!("<script src=\"{root_path}{extra_script}.js\"></script>",
|
||||
root_path=page.root_path,
|
||||
extra_script=e)
|
||||
|
@ -140,6 +140,9 @@ struct SharedContext {
|
||||
/// Suffix to be added on resource files (if suffix is "-v2" then "light.css" becomes
|
||||
/// "light-v2.css").
|
||||
pub resource_suffix: String,
|
||||
/// Optional path string to be used to load static files on output pages. If not set, uses
|
||||
/// combinations of `../` to reach the documentation root.
|
||||
pub static_root_path: Option<String>,
|
||||
}
|
||||
|
||||
impl SharedContext {
|
||||
@ -506,6 +509,7 @@ pub fn run(mut krate: clean::Crate,
|
||||
extension_css,
|
||||
extern_html_root_urls,
|
||||
resource_suffix,
|
||||
static_root_path,
|
||||
..
|
||||
} = options;
|
||||
|
||||
@ -533,6 +537,7 @@ pub fn run(mut krate: clean::Crate,
|
||||
sort_modules_alphabetically,
|
||||
themes,
|
||||
resource_suffix,
|
||||
static_root_path,
|
||||
};
|
||||
|
||||
// If user passed in `--playground-url` arg, we fill in crate name here
|
||||
@ -964,7 +969,7 @@ themePicker.onblur = handleThemeButtonsBlur;
|
||||
.collect::<Vec<_>>()
|
||||
.join(",")));
|
||||
}
|
||||
all_aliases.push(format!("ALIASES['{}'] = {{{}}};", krate.name, output));
|
||||
all_aliases.push(format!("ALIASES[\"{}\"] = {{{}}};", krate.name, output));
|
||||
all_aliases.sort();
|
||||
try_err!(writeln!(&mut w, "var ALIASES = {{}};"), &dst);
|
||||
for aliases in &all_aliases {
|
||||
@ -1038,7 +1043,7 @@ themePicker.onblur = handleThemeButtonsBlur;
|
||||
|
||||
let dst = cx.dst.join("source-files.js");
|
||||
let (mut all_sources, _krates) = try_err!(collect(&dst, &krate.name, "sourcesIndex"), &dst);
|
||||
all_sources.push(format!("sourcesIndex['{}'] = {};",
|
||||
all_sources.push(format!("sourcesIndex[\"{}\"] = {};",
|
||||
&krate.name,
|
||||
hierarchy.to_json_string()));
|
||||
all_sources.sort();
|
||||
@ -1080,9 +1085,12 @@ themePicker.onblur = handleThemeButtonsBlur;
|
||||
title: "Index of crates",
|
||||
css_class: "mod",
|
||||
root_path: "./",
|
||||
static_root_path: cx.shared.static_root_path.deref(),
|
||||
description: "List of crates",
|
||||
keywords: BASIC_KEYWORDS,
|
||||
resource_suffix: &cx.shared.resource_suffix,
|
||||
extra_scripts: &[],
|
||||
static_extra_scripts: &[],
|
||||
};
|
||||
krates.push(krate.name.clone());
|
||||
krates.sort();
|
||||
@ -1101,7 +1109,7 @@ themePicker.onblur = handleThemeButtonsBlur;
|
||||
try_err!(layout::render(&mut w, &cx.shared.layout,
|
||||
&page, &(""), &content,
|
||||
cx.shared.css_file_extension.is_some(),
|
||||
&cx.shared.themes, &[]), &dst);
|
||||
&cx.shared.themes), &dst);
|
||||
try_err!(w.flush(), &dst);
|
||||
}
|
||||
}
|
||||
@ -1366,15 +1374,17 @@ impl<'a> SourceCollector<'a> {
|
||||
title: &title,
|
||||
css_class: "source",
|
||||
root_path: &root_path,
|
||||
static_root_path: self.scx.static_root_path.deref(),
|
||||
description: &desc,
|
||||
keywords: BASIC_KEYWORDS,
|
||||
resource_suffix: &self.scx.resource_suffix,
|
||||
extra_scripts: &["source-files"],
|
||||
static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)],
|
||||
};
|
||||
layout::render(&mut w, &self.scx.layout,
|
||||
&page, &(""), &Source(contents),
|
||||
self.scx.css_file_extension.is_some(),
|
||||
&self.scx.themes, &["source-files",
|
||||
&format!("source-script{}", page.resource_suffix)])?;
|
||||
&self.scx.themes)?;
|
||||
w.flush()?;
|
||||
self.scx.local_sources.insert(p.clone(), href);
|
||||
Ok(())
|
||||
@ -1956,9 +1966,12 @@ impl Context {
|
||||
title: "List of all items in this crate",
|
||||
css_class: "mod",
|
||||
root_path: "../",
|
||||
static_root_path: self.shared.static_root_path.deref(),
|
||||
description: "List of all items in this crate",
|
||||
keywords: BASIC_KEYWORDS,
|
||||
resource_suffix: &self.shared.resource_suffix,
|
||||
extra_scripts: &[],
|
||||
static_extra_scripts: &[],
|
||||
};
|
||||
let sidebar = if let Some(ref version) = cache().crate_version {
|
||||
format!("<p class='location'>Crate {}</p>\
|
||||
@ -1973,7 +1986,7 @@ impl Context {
|
||||
try_err!(layout::render(&mut w, &self.shared.layout,
|
||||
&page, &sidebar, &all,
|
||||
self.shared.css_file_extension.is_some(),
|
||||
&self.shared.themes, &[]),
|
||||
&self.shared.themes),
|
||||
&final_file);
|
||||
|
||||
// Generating settings page.
|
||||
@ -1993,7 +2006,7 @@ impl Context {
|
||||
try_err!(layout::render(&mut w, &layout,
|
||||
&page, &sidebar, &settings,
|
||||
self.shared.css_file_extension.is_some(),
|
||||
&themes, &[]),
|
||||
&themes),
|
||||
&settings_file);
|
||||
|
||||
Ok(())
|
||||
@ -2035,10 +2048,13 @@ impl Context {
|
||||
let page = layout::Page {
|
||||
css_class: tyname,
|
||||
root_path: &self.root_path(),
|
||||
static_root_path: self.shared.static_root_path.deref(),
|
||||
title: &title,
|
||||
description: &desc,
|
||||
keywords: &keywords,
|
||||
resource_suffix: &self.shared.resource_suffix,
|
||||
extra_scripts: &[],
|
||||
static_extra_scripts: &[],
|
||||
};
|
||||
|
||||
{
|
||||
@ -2051,7 +2067,7 @@ impl Context {
|
||||
&Sidebar{ cx: self, item: it },
|
||||
&Item{ cx: self, item: it },
|
||||
self.shared.css_file_extension.is_some(),
|
||||
&self.shared.themes, &[])?;
|
||||
&self.shared.themes)?;
|
||||
} else {
|
||||
let mut url = self.root_path();
|
||||
if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(inner_deref)]
|
||||
|
||||
#![recursion_limit="256"]
|
||||
|
||||
@ -338,6 +339,13 @@ fn opts() -> Vec<RustcOptGroup> {
|
||||
"enable-index-page",
|
||||
"To enable generation of the index page")
|
||||
}),
|
||||
unstable("static-root-path", |o| {
|
||||
o.optopt("",
|
||||
"static-root-path",
|
||||
"Path string to force loading static files from in output pages. \
|
||||
If not set, uses combinations of '../' to reach the documentation root.",
|
||||
"PATH")
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -172,6 +172,7 @@ pub struct Decoder<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Decoder<'a> {
|
||||
#[inline]
|
||||
pub fn new(data: &'a [u8], position: usize) -> Decoder<'a> {
|
||||
Decoder {
|
||||
data,
|
||||
|
@ -354,7 +354,7 @@ const DISPLACEMENT_THRESHOLD: usize = 128;
|
||||
/// *stat += random_stat_buff();
|
||||
/// ```
|
||||
///
|
||||
/// The easiest way to use `HashMap` with a custom type as key is to derive [`Eq`] and [`Hash`].
|
||||
/// The easiest way to use `HashMap` with a custom key type is to derive [`Eq`] and [`Hash`].
|
||||
/// We must also derive [`PartialEq`].
|
||||
///
|
||||
/// [`Eq`]: ../../std/cmp/trait.Eq.html
|
||||
|
@ -740,6 +740,7 @@ impl<K, V> RawTable<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn new_internal(
|
||||
capacity: usize,
|
||||
fallibility: Fallibility,
|
||||
@ -755,12 +756,14 @@ impl<K, V> RawTable<K, V> {
|
||||
|
||||
/// Tries to create a new raw table from a given capacity. If it cannot allocate,
|
||||
/// it returns with AllocErr.
|
||||
#[inline]
|
||||
pub fn try_new(capacity: usize) -> Result<RawTable<K, V>, CollectionAllocErr> {
|
||||
Self::new_internal(capacity, Fallible)
|
||||
}
|
||||
|
||||
/// Creates a new raw table from a given capacity. All buckets are
|
||||
/// initially empty.
|
||||
#[inline]
|
||||
pub fn new(capacity: usize) -> RawTable<K, V> {
|
||||
match Self::new_internal(capacity, Infallible) {
|
||||
Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"),
|
||||
|
@ -253,10 +253,10 @@ impl f32 {
|
||||
unsafe { intrinsics::fmaf32(self, a, b) }
|
||||
}
|
||||
|
||||
/// Calculates Euclidean division, the matching method for `mod_euc`.
|
||||
/// Calculates Euclidean division, the matching method for `rem_euclid`.
|
||||
///
|
||||
/// This computes the integer `n` such that
|
||||
/// `self = n * rhs + self.mod_euc(rhs)`.
|
||||
/// `self = n * rhs + self.rem_euclid(rhs)`.
|
||||
/// In other words, the result is `self / rhs` rounded to the integer `n`
|
||||
/// such that `self >= n * rhs`.
|
||||
///
|
||||
@ -266,14 +266,14 @@ impl f32 {
|
||||
/// #![feature(euclidean_division)]
|
||||
/// let a: f32 = 7.0;
|
||||
/// let b = 4.0;
|
||||
/// assert_eq!(a.div_euc(b), 1.0); // 7.0 > 4.0 * 1.0
|
||||
/// assert_eq!((-a).div_euc(b), -2.0); // -7.0 >= 4.0 * -2.0
|
||||
/// assert_eq!(a.div_euc(-b), -1.0); // 7.0 >= -4.0 * -1.0
|
||||
/// assert_eq!((-a).div_euc(-b), 2.0); // -7.0 >= -4.0 * 2.0
|
||||
/// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
|
||||
/// assert_eq!((-a).div_euclid(b), -2.0); // -7.0 >= 4.0 * -2.0
|
||||
/// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
|
||||
/// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
pub fn div_euc(self, rhs: f32) -> f32 {
|
||||
pub fn div_euclid(self, rhs: f32) -> f32 {
|
||||
let q = (self / rhs).trunc();
|
||||
if self % rhs < 0.0 {
|
||||
return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }
|
||||
@ -281,7 +281,7 @@ impl f32 {
|
||||
q
|
||||
}
|
||||
|
||||
/// Calculates the Euclidean modulo (self mod rhs), which is never negative.
|
||||
/// Calculates the least nonnegative remainder of `self (mod rhs)`.
|
||||
///
|
||||
/// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in
|
||||
/// most cases. However, due to a floating point round-off error it can
|
||||
@ -289,7 +289,7 @@ impl f32 {
|
||||
/// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`.
|
||||
/// This result is not an element of the function's codomain, but it is the
|
||||
/// closest floating point number in the real numbers and thus fulfills the
|
||||
/// property `self == self.div_euc(rhs) * rhs + self.mod_euc(rhs)`
|
||||
/// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
|
||||
/// approximatively.
|
||||
///
|
||||
/// # Examples
|
||||
@ -298,16 +298,16 @@ impl f32 {
|
||||
/// #![feature(euclidean_division)]
|
||||
/// let a: f32 = 7.0;
|
||||
/// let b = 4.0;
|
||||
/// assert_eq!(a.mod_euc(b), 3.0);
|
||||
/// assert_eq!((-a).mod_euc(b), 1.0);
|
||||
/// assert_eq!(a.mod_euc(-b), 3.0);
|
||||
/// assert_eq!((-a).mod_euc(-b), 1.0);
|
||||
/// assert_eq!(a.rem_euclid(b), 3.0);
|
||||
/// assert_eq!((-a).rem_euclid(b), 1.0);
|
||||
/// assert_eq!(a.rem_euclid(-b), 3.0);
|
||||
/// assert_eq!((-a).rem_euclid(-b), 1.0);
|
||||
/// // limitation due to round-off error
|
||||
/// assert!((-std::f32::EPSILON).mod_euc(3.0) != 0.0);
|
||||
/// assert!((-std::f32::EPSILON).rem_euclid(3.0) != 0.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
pub fn mod_euc(self, rhs: f32) -> f32 {
|
||||
pub fn rem_euclid(self, rhs: f32) -> f32 {
|
||||
let r = self % rhs;
|
||||
if r < 0.0 {
|
||||
r + rhs.abs()
|
||||
|
@ -229,10 +229,10 @@ impl f64 {
|
||||
unsafe { intrinsics::fmaf64(self, a, b) }
|
||||
}
|
||||
|
||||
/// Calculates Euclidean division, the matching method for `mod_euc`.
|
||||
/// Calculates Euclidean division, the matching method for `rem_euclid`.
|
||||
///
|
||||
/// This computes the integer `n` such that
|
||||
/// `self = n * rhs + self.mod_euc(rhs)`.
|
||||
/// `self = n * rhs + self.rem_euclid(rhs)`.
|
||||
/// In other words, the result is `self / rhs` rounded to the integer `n`
|
||||
/// such that `self >= n * rhs`.
|
||||
///
|
||||
@ -242,14 +242,14 @@ impl f64 {
|
||||
/// #![feature(euclidean_division)]
|
||||
/// let a: f64 = 7.0;
|
||||
/// let b = 4.0;
|
||||
/// assert_eq!(a.div_euc(b), 1.0); // 7.0 > 4.0 * 1.0
|
||||
/// assert_eq!((-a).div_euc(b), -2.0); // -7.0 >= 4.0 * -2.0
|
||||
/// assert_eq!(a.div_euc(-b), -1.0); // 7.0 >= -4.0 * -1.0
|
||||
/// assert_eq!((-a).div_euc(-b), 2.0); // -7.0 >= -4.0 * 2.0
|
||||
/// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
|
||||
/// assert_eq!((-a).div_euclid(b), -2.0); // -7.0 >= 4.0 * -2.0
|
||||
/// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
|
||||
/// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
pub fn div_euc(self, rhs: f64) -> f64 {
|
||||
pub fn div_euclid(self, rhs: f64) -> f64 {
|
||||
let q = (self / rhs).trunc();
|
||||
if self % rhs < 0.0 {
|
||||
return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }
|
||||
@ -257,7 +257,7 @@ impl f64 {
|
||||
q
|
||||
}
|
||||
|
||||
/// Calculates the Euclidean modulo (self mod rhs), which is never negative.
|
||||
/// Calculates the least nonnegative remainder of `self (mod rhs)`.
|
||||
///
|
||||
/// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in
|
||||
/// most cases. However, due to a floating point round-off error it can
|
||||
@ -265,7 +265,7 @@ impl f64 {
|
||||
/// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`.
|
||||
/// This result is not an element of the function's codomain, but it is the
|
||||
/// closest floating point number in the real numbers and thus fulfills the
|
||||
/// property `self == self.div_euc(rhs) * rhs + self.mod_euc(rhs)`
|
||||
/// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
|
||||
/// approximatively.
|
||||
///
|
||||
/// # Examples
|
||||
@ -274,16 +274,16 @@ impl f64 {
|
||||
/// #![feature(euclidean_division)]
|
||||
/// let a: f64 = 7.0;
|
||||
/// let b = 4.0;
|
||||
/// assert_eq!(a.mod_euc(b), 3.0);
|
||||
/// assert_eq!((-a).mod_euc(b), 1.0);
|
||||
/// assert_eq!(a.mod_euc(-b), 3.0);
|
||||
/// assert_eq!((-a).mod_euc(-b), 1.0);
|
||||
/// assert_eq!(a.rem_euclid(b), 3.0);
|
||||
/// assert_eq!((-a).rem_euclid(b), 1.0);
|
||||
/// assert_eq!(a.rem_euclid(-b), 3.0);
|
||||
/// assert_eq!((-a).rem_euclid(-b), 1.0);
|
||||
/// // limitation due to round-off error
|
||||
/// assert!((-std::f64::EPSILON).mod_euc(3.0) != 0.0);
|
||||
/// assert!((-std::f64::EPSILON).rem_euclid(3.0) != 0.0);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "euclidean_division", issue = "49048")]
|
||||
pub fn mod_euc(self, rhs: f64) -> f64 {
|
||||
pub fn rem_euclid(self, rhs: f64) -> f64 {
|
||||
let r = self % rhs;
|
||||
if r < 0.0 {
|
||||
r + rhs.abs()
|
||||
|
@ -294,7 +294,7 @@ impl<R: Seek> Seek for BufReader<R> {
|
||||
/// `.into_inner()` immediately after a seek yields the underlying reader
|
||||
/// at the same position.
|
||||
///
|
||||
/// To seek without discarding the internal buffer, use [`Seek::seek_relative`].
|
||||
/// To seek without discarding the internal buffer, use [`BufReader::seek_relative`].
|
||||
///
|
||||
/// See [`std::io::Seek`] for more details.
|
||||
///
|
||||
@ -303,6 +303,9 @@ impl<R: Seek> Seek for BufReader<R> {
|
||||
/// seeks will be performed instead of one. If the second seek returns
|
||||
/// `Err`, the underlying reader will be left at the same position it would
|
||||
/// have if you called `seek` with `SeekFrom::Current(0)`.
|
||||
///
|
||||
/// [`BufReader::seek_relative`]: struct.BufReader.html#method.seek_relative
|
||||
/// [`std::io::Seek`]: trait.Seek.html
|
||||
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
||||
let result: u64;
|
||||
if let SeekFrom::Current(n) = pos {
|
||||
|
@ -225,6 +225,9 @@ impl From<ErrorKind> for Error {
|
||||
/// let error = Error::from(not_found);
|
||||
/// assert_eq!("entity not found", format!("{}", error));
|
||||
/// ```
|
||||
///
|
||||
/// [`ErrorKind`]: ../../std/io/enum.ErrorKind.html
|
||||
/// [`Error`]: ../../std/io/struct.Error.html
|
||||
#[inline]
|
||||
fn from(kind: ErrorKind) -> Error {
|
||||
Error {
|
||||
|
@ -222,6 +222,7 @@
|
||||
#![no_std]
|
||||
|
||||
#![deny(missing_docs)]
|
||||
#![deny(intra_doc_link_resolution_failure)]
|
||||
#![deny(missing_debug_implementations)]
|
||||
|
||||
// Tell the compiler to link to either panic_abort or panic_unwind
|
||||
|
@ -1461,7 +1461,7 @@ impl From<String> for PathBuf {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "path_from_str", since = "1.26.0")]
|
||||
#[stable(feature = "path_from_str", since = "1.32.0")]
|
||||
impl FromStr for PathBuf {
|
||||
type Err = ParseError;
|
||||
|
||||
|
@ -56,6 +56,14 @@ IMAGE_BASE:
|
||||
globvar CFGDATA_BASE 8
|
||||
/* Non-zero if debugging is enabled, zero otherwise */
|
||||
globvar DEBUG 1
|
||||
/* The base address (relative to enclave start) of the enclave text section */
|
||||
globvar TEXT_BASE 8
|
||||
/* The size in bytes of enclacve text section */
|
||||
globvar TEXT_SIZE 8
|
||||
/* The base address (relative to enclave start) of the enclave EH_FRM_HDR section */
|
||||
globvar EH_FRM_HDR_BASE 8
|
||||
/* The size in bytes of enclacve EH_FRM_HDR section */
|
||||
globvar EH_FRM_HDR_SIZE 8
|
||||
|
||||
.Lreentry_panic_msg:
|
||||
.asciz "Re-entered panicked enclave!"
|
||||
|
@ -9,14 +9,25 @@
|
||||
// except according to those terms.
|
||||
|
||||
use num::NonZeroUsize;
|
||||
use slice;
|
||||
use str;
|
||||
|
||||
use super::waitqueue::{WaitVariable, WaitQueue, SpinMutex, NotifiedTcs, try_lock_or_false};
|
||||
use super::waitqueue::{
|
||||
try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable,
|
||||
};
|
||||
use mem;
|
||||
|
||||
pub struct RWLock {
|
||||
readers: SpinMutex<WaitVariable<Option<NonZeroUsize>>>,
|
||||
writer: SpinMutex<WaitVariable<bool>>,
|
||||
}
|
||||
|
||||
// Below is to check at compile time, that RWLock has size of 128 bytes.
|
||||
#[allow(dead_code)]
|
||||
unsafe fn rw_lock_size_assert(r: RWLock) {
|
||||
mem::transmute::<RWLock, [u8; 128]>(r);
|
||||
}
|
||||
|
||||
//unsafe impl Send for RWLock {}
|
||||
//unsafe impl Sync for RWLock {} // FIXME
|
||||
|
||||
@ -24,7 +35,7 @@ impl RWLock {
|
||||
pub const fn new() -> RWLock {
|
||||
RWLock {
|
||||
readers: SpinMutex::new(WaitVariable::new(None)),
|
||||
writer: SpinMutex::new(WaitVariable::new(false))
|
||||
writer: SpinMutex::new(WaitVariable::new(false)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,9 +100,11 @@ impl RWLock {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn read_unlock(&self) {
|
||||
let mut rguard = self.readers.lock();
|
||||
let wguard = self.writer.lock();
|
||||
unsafe fn __read_unlock(
|
||||
&self,
|
||||
mut rguard: SpinMutexGuard<WaitVariable<Option<NonZeroUsize>>>,
|
||||
wguard: SpinMutexGuard<WaitVariable<bool>>,
|
||||
) {
|
||||
*rguard.lock_var_mut() = NonZeroUsize::new(rguard.lock_var().unwrap().get() - 1);
|
||||
if rguard.lock_var().is_some() {
|
||||
// There are other active readers
|
||||
@ -107,9 +120,18 @@ impl RWLock {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn write_unlock(&self) {
|
||||
pub unsafe fn read_unlock(&self) {
|
||||
let rguard = self.readers.lock();
|
||||
let wguard = self.writer.lock();
|
||||
self.__read_unlock(rguard, wguard);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn __write_unlock(
|
||||
&self,
|
||||
rguard: SpinMutexGuard<WaitVariable<Option<NonZeroUsize>>>,
|
||||
wguard: SpinMutexGuard<WaitVariable<bool>>,
|
||||
) {
|
||||
if let Err(mut wguard) = WaitQueue::notify_one(wguard) {
|
||||
// No writers waiting, release the write lock
|
||||
*wguard.lock_var_mut() = false;
|
||||
@ -128,6 +150,109 @@ impl RWLock {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn write_unlock(&self) {
|
||||
let rguard = self.readers.lock();
|
||||
let wguard = self.writer.lock();
|
||||
self.__write_unlock(rguard, wguard);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn unlock(&self) {
|
||||
let rguard = self.readers.lock();
|
||||
let wguard = self.writer.lock();
|
||||
if *wguard.lock_var() == true {
|
||||
self.__write_unlock(rguard, wguard);
|
||||
} else {
|
||||
self.__read_unlock(rguard, wguard);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn destroy(&self) {}
|
||||
}
|
||||
|
||||
const EINVAL: i32 = 22;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RWLock) -> i32 {
|
||||
if p.is_null() {
|
||||
return EINVAL;
|
||||
}
|
||||
(*p).read();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RWLock) -> i32 {
|
||||
if p.is_null() {
|
||||
return EINVAL;
|
||||
}
|
||||
(*p).write();
|
||||
return 0;
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RWLock) -> i32 {
|
||||
if p.is_null() {
|
||||
return EINVAL;
|
||||
}
|
||||
(*p).unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) {
|
||||
if s < 0 {
|
||||
return;
|
||||
}
|
||||
let buf = slice::from_raw_parts(m as *const u8, s as _);
|
||||
if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) {
|
||||
eprint!("{}", s);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __rust_abort() {
|
||||
::sys::abort_internal();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use core::array::FixedSizeArray;
|
||||
use mem::MaybeUninit;
|
||||
use {mem, ptr};
|
||||
|
||||
// The below test verifies that the bytes of initialized RWLock are the ones
|
||||
// we use in libunwind.
|
||||
// If they change we need to update src/UnwindRustSgx.h in libunwind.
|
||||
#[test]
|
||||
fn test_c_rwlock_initializer() {
|
||||
const RWLOCK_INIT: &[u8] = &[
|
||||
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
];
|
||||
|
||||
let mut init = MaybeUninit::<RWLock>::zeroed();
|
||||
init.set(RWLock::new());
|
||||
assert_eq!(
|
||||
mem::transmute::<_, [u8; 128]>(init.into_inner()).as_slice(),
|
||||
RWLOCK_INIT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -397,9 +397,6 @@ declare_features! (
|
||||
// Multiple patterns with `|` in `if let` and `while let`.
|
||||
(active, if_while_or_patterns, "1.26.0", Some(48215), None),
|
||||
|
||||
// Allows `#[repr(packed)]` attribute on structs.
|
||||
(active, repr_packed, "1.26.0", Some(33158), None),
|
||||
|
||||
// Allows macro invocations in `extern {}` blocks.
|
||||
(active, macros_in_extern, "1.27.0", Some(49476), None),
|
||||
|
||||
@ -684,17 +681,19 @@ declare_features! (
|
||||
// `extern crate foo as bar;` puts `bar` into extern prelude.
|
||||
(accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
|
||||
// Allows use of the `:literal` macro fragment specifier (RFC 1576).
|
||||
(accepted, macro_literal_matcher, "1.31.0", Some(35625), None),
|
||||
// Integer match exhaustiveness checking (RFC 2591)
|
||||
(accepted, exhaustive_integer_patterns, "1.32.0", Some(50907), None),
|
||||
(accepted, macro_literal_matcher, "1.32.0", Some(35625), None),
|
||||
// Use `?` as the Kleene "at most one" operator.
|
||||
(accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
|
||||
// `Self` struct constructor (RFC 2302)
|
||||
(accepted, self_struct_ctor, "1.32.0", Some(51994), None),
|
||||
// `Self` in type definitions (RFC 2300)
|
||||
(accepted, self_in_typedefs, "1.32.0", Some(49303), None),
|
||||
// Integer match exhaustiveness checking (RFC 2591)
|
||||
(accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
|
||||
// `use path as _;` and `extern crate c as _;`
|
||||
(accepted, underscore_imports, "1.33.0", Some(48216), None),
|
||||
// Allows `#[repr(packed(N))]` attribute on structs.
|
||||
(accepted, repr_packed, "1.33.0", Some(33158), None),
|
||||
);
|
||||
|
||||
// If you change this, please modify `src/doc/unstable-book` as well. You must
|
||||
@ -1588,13 +1587,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
gate_feature_post!(&self, repr_simd, attr.span,
|
||||
"SIMD types are experimental and possibly buggy");
|
||||
}
|
||||
if let Some((name, _)) = item.name_value_literal() {
|
||||
if name == "packed" {
|
||||
gate_feature_post!(&self, repr_packed, attr.span,
|
||||
"the `#[repr(packed(n))]` attribute \
|
||||
is experimental");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,10 +26,7 @@ mod macros;
|
||||
cfg_if! {
|
||||
if #[cfg(target_env = "msvc")] {
|
||||
// no extra unwinder support needed
|
||||
} else if #[cfg(any(
|
||||
all(target_arch = "wasm32", not(target_os = "emscripten")),
|
||||
target_env = "sgx"
|
||||
))] {
|
||||
} else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] {
|
||||
// no unwinder on the system!
|
||||
} else {
|
||||
extern crate libc;
|
||||
|
@ -13,7 +13,6 @@
|
||||
// min-llvm-version 7.0
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(repr_packed)]
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct Packed1 {
|
||||
|
@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
// run-pass
|
||||
#![feature(repr_packed)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use std::mem;
|
||||
|
@ -8,8 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(repr_packed)]
|
||||
|
||||
#[repr(packed)]
|
||||
pub struct P1S5 {
|
||||
a: u8,
|
||||
|
@ -12,8 +12,6 @@
|
||||
#![allow(dead_code)]
|
||||
// ignore-emscripten weird assertion?
|
||||
|
||||
#![feature(repr_packed)]
|
||||
|
||||
#[repr(packed)]
|
||||
struct Foo1 {
|
||||
bar: u8,
|
||||
|
@ -10,11 +10,8 @@
|
||||
|
||||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![allow(stable_features)]
|
||||
#![allow(unused_comparisons)]
|
||||
|
||||
#![feature(repr_packed)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
#[repr(packed)]
|
||||
|
@ -1,35 +1,35 @@
|
||||
warning: unnecessary path disambiguator
|
||||
--> $DIR/packed-struct-generic-size.rs:49:14
|
||||
--> $DIR/packed-struct-generic-size.rs:46:14
|
||||
|
|
||||
LL | check!(P1::<u8, u8>, 1, 3);
|
||||
| ^^ try removing `::`
|
||||
|
||||
warning: unnecessary path disambiguator
|
||||
--> $DIR/packed-struct-generic-size.rs:50:14
|
||||
--> $DIR/packed-struct-generic-size.rs:47:14
|
||||
|
|
||||
LL | check!(P1::<u64, u16>, 1, 11);
|
||||
| ^^ try removing `::`
|
||||
|
||||
warning: unnecessary path disambiguator
|
||||
--> $DIR/packed-struct-generic-size.rs:52:14
|
||||
--> $DIR/packed-struct-generic-size.rs:49:14
|
||||
|
|
||||
LL | check!(P2::<u8, u8>, 1, 3);
|
||||
| ^^ try removing `::`
|
||||
|
||||
warning: unnecessary path disambiguator
|
||||
--> $DIR/packed-struct-generic-size.rs:53:14
|
||||
--> $DIR/packed-struct-generic-size.rs:50:14
|
||||
|
|
||||
LL | check!(P2::<u64, u16>, 2, 12);
|
||||
| ^^ try removing `::`
|
||||
|
||||
warning: unnecessary path disambiguator
|
||||
--> $DIR/packed-struct-generic-size.rs:55:15
|
||||
--> $DIR/packed-struct-generic-size.rs:52:15
|
||||
|
|
||||
LL | check!(P4C::<u8, u8>, 1, 3);
|
||||
| ^^ try removing `::`
|
||||
|
||||
warning: unnecessary path disambiguator
|
||||
--> $DIR/packed-struct-generic-size.rs:56:15
|
||||
--> $DIR/packed-struct-generic-size.rs:53:15
|
||||
|
|
||||
LL | check!(P4C::<u16, u64>, 4, 12);
|
||||
| ^^ try removing `::`
|
||||
|
@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
// run-pass
|
||||
#![feature(repr_packed)]
|
||||
|
||||
#[repr(packed)]
|
||||
struct Foo1 {
|
||||
|
@ -13,9 +13,6 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
#![feature(repr_packed)]
|
||||
|
||||
|
||||
use std::mem;
|
||||
|
||||
#[repr(packed)]
|
||||
|
@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
// run-pass
|
||||
#![feature(repr_packed)]
|
||||
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
|
@ -12,8 +12,6 @@
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
#![feature(repr_packed)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
#[repr(packed)]
|
||||
|
@ -11,7 +11,6 @@
|
||||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(repr_packed)]
|
||||
|
||||
use std::mem;
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
#![feature(untagged_unions)]
|
||||
#![feature(repr_packed)]
|
||||
|
||||
use std::mem::{size_of, size_of_val, align_of, align_of_val};
|
||||
|
||||
|
24
src/test/rustdoc/static-root-path.rs
Normal file
24
src/test/rustdoc/static-root-path.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags:-Z unstable-options --static-root-path /cache/
|
||||
|
||||
// @has static_root_path/struct.SomeStruct.html
|
||||
// @matches - '"/cache/main\.js"'
|
||||
// @!matches - '"\.\./main\.js"'
|
||||
// @matches - '"\.\./search-index\.js"'
|
||||
// @!matches - '"/cache/search-index\.js"'
|
||||
pub struct SomeStruct;
|
||||
|
||||
// @has src/static_root_path/static-root-path.rs.html
|
||||
// @matches - '"/cache/source-script\.js"'
|
||||
// @!matches - '"\.\./\.\./source-script\.js"'
|
||||
// @matches - '"\.\./\.\./source-files.js"'
|
||||
// @!matches - '"/cache/source-files\.js"'
|
@ -10,9 +10,8 @@ LL | Foo::Y(_, ref mut b) => b,
|
||||
LL | *a += 1;
|
||||
| ------- borrow later used here
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
error[E0503]: cannot use `y` because it was mutably borrowed
|
||||
--> $DIR/borrowck-anon-fields-variant.rs:44:7
|
||||
|
@ -350,9 +350,8 @@ LL | let p: &'a u8 = &*block.current;
|
||||
LL | drop(x);
|
||||
| - mutable borrow later used here
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
warning[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable
|
||||
--> $DIR/borrowck-describe-lvalue.rs:260:33
|
||||
@ -365,9 +364,8 @@ LL | let p : *const u8 = &*(*block).current;
|
||||
LL | drop(x);
|
||||
| - mutable borrow later used here
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/borrowck-describe-lvalue.rs:318:22
|
||||
|
@ -4,7 +4,6 @@ warning[E0507]: cannot move out of borrowed content
|
||||
LL | (|| { let bar = foo; bar.take() })();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
|
@ -4,7 +4,6 @@ warning[E0507]: cannot move out of borrowed content
|
||||
LL | (|| { let bar = foo; bar.take() })();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![feature(repr_packed)]
|
||||
|
||||
#[repr(C)]
|
||||
enum A { A }
|
||||
|
@ -1,47 +1,47 @@
|
||||
warning[E0566]: conflicting representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:20:8
|
||||
--> $DIR/conflicting-repr-hints.rs:19:8
|
||||
|
|
||||
LL | #[repr(C, u64)] //~ WARNING conflicting representation hints
|
||||
| ^ ^^^
|
||||
|
||||
warning[E0566]: conflicting representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:23:8
|
||||
--> $DIR/conflicting-repr-hints.rs:22:8
|
||||
|
|
||||
LL | #[repr(u32, u64)] //~ WARNING conflicting representation hints
|
||||
| ^^^ ^^^
|
||||
|
||||
error[E0587]: type has conflicting packed and align representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:30:1
|
||||
--> $DIR/conflicting-repr-hints.rs:29:1
|
||||
|
|
||||
LL | struct F(i32); //~ ERROR type has conflicting packed and align representation hints
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0587]: type has conflicting packed and align representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:34:1
|
||||
--> $DIR/conflicting-repr-hints.rs:33:1
|
||||
|
|
||||
LL | struct G(i32); //~ ERROR type has conflicting packed and align representation hints
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0587]: type has conflicting packed and align representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:38:1
|
||||
--> $DIR/conflicting-repr-hints.rs:37:1
|
||||
|
|
||||
LL | struct H(i32); //~ ERROR type has conflicting packed and align representation hints
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0634]: type has conflicting packed representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:41:1
|
||||
--> $DIR/conflicting-repr-hints.rs:40:1
|
||||
|
|
||||
LL | struct I(i32); //~ ERROR type has conflicting packed representation hints
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0634]: type has conflicting packed representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:45:1
|
||||
--> $DIR/conflicting-repr-hints.rs:44:1
|
||||
|
|
||||
LL | struct J(i32); //~ ERROR type has conflicting packed representation hints
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0587]: type has conflicting packed and align representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:51:1
|
||||
--> $DIR/conflicting-repr-hints.rs:50:1
|
||||
|
|
||||
LL | / union X { //~ ERROR type has conflicting packed and align representation hints
|
||||
LL | | i: i32
|
||||
@ -49,7 +49,7 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error[E0587]: type has conflicting packed and align representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:57:1
|
||||
--> $DIR/conflicting-repr-hints.rs:56:1
|
||||
|
|
||||
LL | / union Y { //~ ERROR type has conflicting packed and align representation hints
|
||||
LL | | i: i32
|
||||
@ -57,7 +57,7 @@ LL | | }
|
||||
| |_^
|
||||
|
||||
error[E0587]: type has conflicting packed and align representation hints
|
||||
--> $DIR/conflicting-repr-hints.rs:63:1
|
||||
--> $DIR/conflicting-repr-hints.rs:62:1
|
||||
|
|
||||
LL | / union Z { //~ ERROR type has conflicting packed and align representation hints
|
||||
LL | | i: i32
|
||||
|
@ -199,9 +199,8 @@ LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
|
||||
| |temporary value created here
|
||||
| returns a reference to data owned by the current function
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
error: trait bounds other than `Sized` on const fn parameters are unstable
|
||||
--> $DIR/min_const_fn.rs:147:41
|
||||
|
@ -19,9 +19,8 @@ LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
|
||||
| |creates a temporary which is freed while still in use
|
||||
| cast requires that borrow lasts for `'static`
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
9
src/test/ui/consts/promoted_regression.rs
Normal file
9
src/test/ui/consts/promoted_regression.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// compile-pass
|
||||
|
||||
fn main() {
|
||||
let _ = &[("", ""); 3];
|
||||
}
|
||||
|
||||
const FOO: &[(&str, &str)] = &[("", ""); 3];
|
||||
const BAR: &[(&str, &str); 5] = &[("", ""); 5];
|
||||
const BAA: &[[&str; 12]; 11] = &[[""; 12]; 11];
|
@ -1,18 +0,0 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[repr(packed(1))] //~ error: the `#[repr(packed(n))]` attribute is experimental
|
||||
struct Foo(u64);
|
||||
|
||||
#[repr(C)]
|
||||
#[repr(packed(1))] //~ error: the `#[repr(packed(n))]` attribute is experimental
|
||||
struct Bar(u64);
|
||||
|
||||
fn main() {}
|
@ -1,19 +0,0 @@
|
||||
error[E0658]: the `#[repr(packed(n))]` attribute is experimental (see issue #33158)
|
||||
--> $DIR/feature-gate-repr_packed.rs:11:1
|
||||
|
|
||||
LL | #[repr(packed(1))] //~ error: the `#[repr(packed(n))]` attribute is experimental
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(repr_packed)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: the `#[repr(packed(n))]` attribute is experimental (see issue #33158)
|
||||
--> $DIR/feature-gate-repr_packed.rs:15:1
|
||||
|
|
||||
LL | #[repr(packed(1))] //~ error: the `#[repr(packed(n))]` attribute is experimental
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(repr_packed)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -8,7 +8,6 @@ LL | &mut x
|
||||
|
|
||||
= note: `FnMut` closures only have access to their captured variables while they are executing...
|
||||
= note: ...therefore, they cannot allow references to captured variables to escape
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
|
@ -10,7 +10,6 @@ LL | | }
|
||||
|
|
||||
= note: `FnMut` closures only have access to their captured variables while they are executing...
|
||||
= note: ...therefore, they cannot allow references to captured variables to escape
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: compilation successful
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:89:1
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:92:1
|
||||
|
|
||||
LL | / fn main() { //[ast]~ ERROR compilation successful
|
||||
LL | | //[migrate]~^ ERROR compilation successful
|
||||
|
@ -9,12 +9,11 @@ LL | &mut *s.0 //[nll]~ ERROR borrow may still be in use when destructor run
|
||||
LL | }
|
||||
| - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
warning[E0713]: borrow may still be in use when destructor runs
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:73:5
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:74:5
|
||||
|
|
||||
LL | fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
|
||||
| -- lifetime `'a` defined here
|
||||
@ -24,12 +23,11 @@ LL | &mut *(*s).0 //[nll]~ ERROR borrow may still be in use when destructor
|
||||
LL | }
|
||||
| - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
warning[E0713]: borrow may still be in use when destructor runs
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:83:5
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:85:5
|
||||
|
|
||||
LL | fn boxed_boxed_scribbled<'a>(s: Box<Box<Scribble<'a>>>) -> &'a mut u32 {
|
||||
| -- lifetime `'a` defined here
|
||||
@ -39,12 +37,11 @@ LL | &mut *(**s).0 //[nll]~ ERROR borrow may still be in use when destructor
|
||||
LL | }
|
||||
| - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
error: compilation successful
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:89:1
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:92:1
|
||||
|
|
||||
LL | / fn main() { //[ast]~ ERROR compilation successful
|
||||
LL | | //[migrate]~^ ERROR compilation successful
|
||||
|
@ -10,7 +10,7 @@ LL | }
|
||||
| - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
|
||||
error[E0713]: borrow may still be in use when destructor runs
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:73:5
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:74:5
|
||||
|
|
||||
LL | fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
|
||||
| -- lifetime `'a` defined here
|
||||
@ -21,7 +21,7 @@ LL | }
|
||||
| - here, drop of `s` needs exclusive access to `*s.0`, because the type `Scribble<'_>` implements the `Drop` trait
|
||||
|
||||
error[E0713]: borrow may still be in use when destructor runs
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:83:5
|
||||
--> $DIR/issue-45696-scribble-on-boxed-borrow.rs:85:5
|
||||
|
|
||||
LL | fn boxed_boxed_scribbled<'a>(s: Box<Box<Scribble<'a>>>) -> &'a mut u32 {
|
||||
| -- lifetime `'a` defined here
|
||||
|
@ -62,7 +62,8 @@ fn boxed_boxed_borrowed_scribble<'a>(s: Box<Box<&'a mut Scribble>>) -> &'a mut u
|
||||
fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 {
|
||||
&mut *s.0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
|
||||
//[migrate]~^ WARNING borrow may still be in use when destructor runs [E0713]
|
||||
//[migrate]~| WARNING This error has been downgraded to a warning for backwards compatibility
|
||||
//[migrate]~| WARNING this error has been downgraded to a warning for backwards compatibility
|
||||
//[migrate]~| WARNING this represents potential undefined behavior in your code
|
||||
}
|
||||
|
||||
// This, by analogy to previous case, is *also* not okay.
|
||||
@ -72,7 +73,8 @@ fn scribbled<'a>(s: Scribble<'a>) -> &'a mut u32 {
|
||||
fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
|
||||
&mut *(*s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
|
||||
//[migrate]~^ WARNING borrow may still be in use when destructor runs [E0713]
|
||||
//[migrate]~| WARNING This error has been downgraded to a warning for backwards compatibility
|
||||
//[migrate]~| WARNING this error has been downgraded to a warning for backwards compatibility
|
||||
//[migrate]~| WARNING this represents potential undefined behavior in your code
|
||||
}
|
||||
|
||||
// This, by analogy to previous case, is *also* not okay.
|
||||
@ -82,7 +84,8 @@ fn boxed_scribbled<'a>(s: Box<Scribble<'a>>) -> &'a mut u32 {
|
||||
fn boxed_boxed_scribbled<'a>(s: Box<Box<Scribble<'a>>>) -> &'a mut u32 {
|
||||
&mut *(**s).0 //[nll]~ ERROR borrow may still be in use when destructor runs [E0713]
|
||||
//[migrate]~^ WARNING borrow may still be in use when destructor runs [E0713]
|
||||
//[migrate]~| WARNING This error has been downgraded to a warning for backwards compatibility
|
||||
//[migrate]~| WARNING this error has been downgraded to a warning for backwards compatibility
|
||||
//[migrate]~| WARNING this represents potential undefined behavior in your code
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
|
@ -10,9 +10,8 @@ LL | | }
|
||||
|
|
||||
= note: `FnMut` closures only have access to their captured variables while they are executing...
|
||||
= note: ...therefore, they cannot allow references to captured variables to escape
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
error: compilation successful
|
||||
--> $DIR/issue-49824.rs:18:1
|
||||
|
18
src/test/ui/issues/issue-56762.rs
Normal file
18
src/test/ui/issues/issue-56762.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// only-x86_64
|
||||
const HUGE_SIZE: usize = !0usize / 8;
|
||||
|
||||
|
||||
pub struct TooBigArray {
|
||||
arr: [u8; HUGE_SIZE],
|
||||
}
|
||||
|
||||
impl TooBigArray {
|
||||
pub const fn new() -> Self {
|
||||
TooBigArray { arr: [0x00; HUGE_SIZE], }
|
||||
}
|
||||
}
|
||||
|
||||
static MY_TOO_BIG_ARRAY_1: TooBigArray = TooBigArray::new();
|
||||
static MY_TOO_BIG_ARRAY_2: [u8; HUGE_SIZE] = [0x00; HUGE_SIZE];
|
||||
|
||||
fn main() { }
|
4
src/test/ui/issues/issue-56762.stderr
Normal file
4
src/test/ui/issues/issue-56762.stderr
Normal file
@ -0,0 +1,4 @@
|
||||
error: the type `[u8; 2305843009213693951]` is too big for the current architecture
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -8,9 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags:-D bogus
|
||||
// compile-flags:-D bogus -D dead_cod
|
||||
|
||||
// error-pattern:unknown lint
|
||||
// error-pattern:unknown lint: `bogus`
|
||||
// error-pattern:requested on the command line with `-D bogus`
|
||||
// error-pattern:unknown lint: `dead_cod`
|
||||
// error-pattern:requested on the command line with `-D dead_cod`
|
||||
// error-pattern:did you mean: `dead_code`
|
||||
|
||||
fn main() { }
|
||||
|
@ -2,6 +2,11 @@ error[E0602]: unknown lint: `bogus`
|
||||
|
|
||||
= note: requested on the command line with `-D bogus`
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0602]: unknown lint: `dead_cod`
|
||||
|
|
||||
= help: did you mean: `dead_code`
|
||||
= note: requested on the command line with `-D dead_cod`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0602`.
|
||||
|
@ -8,6 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(not_a_real_lint)] //~ WARN unknown lint
|
||||
#![deny(unused)]
|
||||
fn main() { let unused = (); } //~ ERROR unused variable
|
||||
#![deny(unknown_lints)]
|
||||
|
||||
#![allow(not_a_real_lint)] //~ ERROR unknown lint
|
||||
|
||||
#![deny(dead_cod)] //~ ERROR unknown lint
|
||||
//~| HELP did you mean
|
||||
//~| SUGGESTION dead_code
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,23 +1,20 @@
|
||||
warning: unknown lint: `not_a_real_lint`
|
||||
--> $DIR/lint-unknown-lint.rs:11:10
|
||||
error: unknown lint: `not_a_real_lint`
|
||||
--> $DIR/lint-unknown-lint.rs:13:10
|
||||
|
|
||||
LL | #![allow(not_a_real_lint)] //~ WARN unknown lint
|
||||
LL | #![allow(not_a_real_lint)] //~ ERROR unknown lint
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: #[warn(unknown_lints)] on by default
|
||||
|
||||
error: unused variable: `unused`
|
||||
--> $DIR/lint-unknown-lint.rs:13:17
|
||||
|
|
||||
LL | fn main() { let unused = (); } //~ ERROR unused variable
|
||||
| ^^^^^^ help: consider using `_unused` instead
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/lint-unknown-lint.rs:12:9
|
||||
--> $DIR/lint-unknown-lint.rs:11:9
|
||||
|
|
||||
LL | #![deny(unused)]
|
||||
| ^^^^^^
|
||||
= note: #[deny(unused_variables)] implied by #[deny(unused)]
|
||||
LL | #![deny(unknown_lints)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error: unknown lint: `dead_cod`
|
||||
--> $DIR/lint-unknown-lint.rs:15:9
|
||||
|
|
||||
LL | #![deny(dead_cod)] //~ ERROR unknown lint
|
||||
| ^^^^^^^^ help: did you mean: `dead_code`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -10,11 +10,11 @@ warning: unknown lint: `DEAD_CODE`
|
||||
--> $DIR/not_found.rs:18:8
|
||||
|
|
||||
LL | #[warn(DEAD_CODE)]
|
||||
| ^^^^^^^^^ help: lowercase the lint name: `dead_code`
|
||||
| ^^^^^^^^^ help: did you mean: `dead_code`
|
||||
|
||||
warning: unknown lint: `Warnings`
|
||||
--> $DIR/not_found.rs:20:8
|
||||
|
|
||||
LL | #[deny(Warnings)]
|
||||
| ^^^^^^^^ help: lowercase the lint name: `warnings`
|
||||
| ^^^^^^^^ help: did you mean: `warnings`
|
||||
|
||||
|
@ -4,9 +4,8 @@ warning[E0507]: cannot move out of borrowed content
|
||||
LL | (|| { let bar = foo; bar.take() })();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
error: compilation successful
|
||||
--> $DIR/match-guards-always-borrow.rs:57:1
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![feature(start)]
|
||||
#![feature(repr_packed)]
|
||||
|
||||
#[derive(Default)]
|
||||
#[repr(packed)]
|
||||
|
@ -14,6 +14,11 @@
|
||||
// ignore-emscripten
|
||||
// ignore-mips
|
||||
// ignore-mips64
|
||||
// ignore-powerpc
|
||||
// ignore-powerpc64
|
||||
// ignore-powerpc64le
|
||||
// ignore-sparc
|
||||
// ignore-sparc64
|
||||
// gate-test-sse4a_target_feature
|
||||
// gate-test-powerpc_target_feature
|
||||
// gate-test-avx512_target_feature
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: the target feature `avx512bw` is currently unstable (see issue #44839)
|
||||
--> $DIR/target-feature-gate.rs:31:18
|
||||
--> $DIR/target-feature-gate.rs:36:18
|
||||
|
|
||||
LL | #[target_feature(enable = "avx512bw")]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -18,9 +18,8 @@ LL | static C: &u32 = &A;
|
||||
| |
|
||||
| thread-local variables cannot be borrowed beyond the end of the function
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
error[E0625]: thread-local statics cannot be accessed at compile-time
|
||||
--> $DIR/thread-local-in-ctfe.rs:22:16
|
||||
@ -42,9 +41,8 @@ LL | const E: &u32 = &A;
|
||||
| |
|
||||
| thread-local variables cannot be borrowed beyond the end of the function
|
||||
|
|
||||
= warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
|
||||
It represents potential unsoundness in your code.
|
||||
This warning will become a hard error in the future.
|
||||
= warning: this error has been downgraded to a warning for backwards compatibility with previous releases
|
||||
= warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
|
||||
|
||||
error[E0625]: thread-local statics cannot be accessed at compile-time
|
||||
--> $DIR/thread-local-in-ctfe.rs:29:5
|
||||
|
@ -205,7 +205,7 @@ impl EarlyProps {
|
||||
fn ignore_lldb(config: &Config, line: &str) -> bool {
|
||||
if let Some(ref actual_version) = config.lldb_version {
|
||||
if line.starts_with("min-lldb-version") {
|
||||
let min_version = line.trim_right()
|
||||
let min_version = line.trim_end()
|
||||
.rsplit(' ')
|
||||
.next()
|
||||
.expect("Malformed lldb version directive");
|
||||
@ -228,7 +228,7 @@ impl EarlyProps {
|
||||
}
|
||||
if let Some(ref actual_version) = config.llvm_version {
|
||||
if line.starts_with("min-llvm-version") {
|
||||
let min_version = line.trim_right()
|
||||
let min_version = line.trim_end()
|
||||
.rsplit(' ')
|
||||
.next()
|
||||
.expect("Malformed llvm version directive");
|
||||
@ -236,7 +236,7 @@ impl EarlyProps {
|
||||
// version
|
||||
&actual_version[..] < min_version
|
||||
} else if line.starts_with("min-system-llvm-version") {
|
||||
let min_version = line.trim_right()
|
||||
let min_version = line.trim_end()
|
||||
.rsplit(' ')
|
||||
.next()
|
||||
.expect("Malformed llvm version directive");
|
||||
@ -573,14 +573,14 @@ fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
|
||||
None => false,
|
||||
};
|
||||
if matches {
|
||||
it(ln[(close_brace + 1)..].trim_left());
|
||||
it(ln[(close_brace + 1)..].trim_start());
|
||||
}
|
||||
} else {
|
||||
panic!("malformed condition directive: expected `{}foo]`, found `{}`",
|
||||
comment_with_brace, ln)
|
||||
}
|
||||
} else if ln.starts_with(comment) {
|
||||
it(ln[comment.len() ..].trim_left());
|
||||
it(ln[comment.len() ..].trim_start());
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -1082,7 +1082,7 @@ impl<'test> TestCx<'test> {
|
||||
match line {
|
||||
Ok(line) => {
|
||||
let line = if line.starts_with("//") {
|
||||
line[2..].trim_left()
|
||||
line[2..].trim_start()
|
||||
} else {
|
||||
line.as_str()
|
||||
};
|
||||
@ -2146,8 +2146,8 @@ impl<'test> TestCx<'test> {
|
||||
.lines()
|
||||
.enumerate()
|
||||
.filter_map(|(line_nb, line)| {
|
||||
if (line.trim_left().starts_with("pub mod ")
|
||||
|| line.trim_left().starts_with("mod "))
|
||||
if (line.trim_start().starts_with("pub mod ")
|
||||
|| line.trim_start().starts_with("mod "))
|
||||
&& line.ends_with(';')
|
||||
{
|
||||
if let Some(ref mut other_files) = other_files {
|
||||
@ -2156,7 +2156,7 @@ impl<'test> TestCx<'test> {
|
||||
None
|
||||
} else {
|
||||
let sline = line.split("///").last().unwrap_or("");
|
||||
let line = sline.trim_left();
|
||||
let line = sline.trim_start();
|
||||
if line.starts_with("```") {
|
||||
if ignore {
|
||||
ignore = false;
|
||||
@ -3287,7 +3287,7 @@ fn normalize_mir_line(line: &str) -> String {
|
||||
fn nocomment_mir_line(line: &str) -> &str {
|
||||
if let Some(idx) = line.find("//") {
|
||||
let (l, _) = line.split_at(idx);
|
||||
l.trim_right()
|
||||
l.trim_end()
|
||||
} else {
|
||||
line
|
||||
}
|
||||
|
@ -26,7 +26,10 @@ function getNextStep(content, pos, stop) {
|
||||
return pos;
|
||||
}
|
||||
|
||||
// Stupid function extractor based on indent.
|
||||
// Stupid function extractor based on indent. Doesn't support block
|
||||
// comments. If someone puts a ' or an " in a block comment this
|
||||
// will blow up. Template strings are not tested and might also be
|
||||
// broken.
|
||||
function extractFunction(content, functionName) {
|
||||
var indent = 0;
|
||||
var splitter = "function " + functionName + "(";
|
||||
@ -51,7 +54,14 @@ function extractFunction(content, functionName) {
|
||||
continue;
|
||||
}
|
||||
while (pos < content.length) {
|
||||
if (content[pos] === '"' || content[pos] === "'") {
|
||||
// Eat single-line comments
|
||||
if (content[pos] === '/' && pos > 0 && content[pos-1] === '/') {
|
||||
do {
|
||||
pos += 1;
|
||||
} while (pos < content.length && content[pos] !== '\n');
|
||||
|
||||
// Eat quoted strings
|
||||
} else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") {
|
||||
var stop = content[pos];
|
||||
var is_escaped = false;
|
||||
do {
|
||||
@ -62,6 +72,8 @@ function extractFunction(content, functionName) {
|
||||
}
|
||||
} while (pos < content.length &&
|
||||
(content[pos] !== stop || content[pos - 1] === '\\'));
|
||||
|
||||
// Otherwise, check for indent
|
||||
} else if (content[pos] === '{') {
|
||||
indent += 1;
|
||||
} else if (content[pos] === '}') {
|
||||
|
Loading…
Reference in New Issue
Block a user