mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #76781 - RalfJung:rollup-ve66o2j, r=RalfJung
Rollup of 10 pull requests Successful merges: - #76056 (Add more info for Vec Drain doc) - #76062 (Vec slice example fix style and show type elision) - #76262 (Use inline(never) instead of cold) - #76335 (Make all methods of `Duration` unstably const) - #76366 (Add Arith Tests in Library) - #76369 (Move Various str tests in library) - #76534 (Add doc comments for From impls) - #76622 (Update bootstrap readme) - #76641 (Some cleanup changes and commenting) - #76662 (Fix liballoc test suite for Miri) Failed merges: r? `@ghost`
This commit is contained in:
commit
5fae56971d
@ -2280,6 +2280,12 @@ impl<'tcx> TyS<'tcx> {
|
||||
///
|
||||
/// Returning true means the type is known to be sized. Returning
|
||||
/// `false` means nothing -- could be sized, might not be.
|
||||
///
|
||||
/// Note that we could never rely on the fact that a type such as `[_]` is
|
||||
/// trivially `!Sized` because we could be in a type environment with a
|
||||
/// bound such as `[_]: Copy`. A function with such a bound obviously never
|
||||
/// can be called, but that doesn't mean it shouldn't typecheck. This is why
|
||||
/// this method doesn't return `Option<bool>`.
|
||||
pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
match self.kind() {
|
||||
ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
||||
|
@ -1512,12 +1512,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
// avoid inundating the user with unnecessary errors, but we now
|
||||
// check upstream for type errors and don't add the obligations to
|
||||
// begin with in those cases.
|
||||
if self
|
||||
.tcx
|
||||
.lang_items()
|
||||
.sized_trait()
|
||||
.map_or(false, |sized_id| sized_id == trait_ref.def_id())
|
||||
{
|
||||
if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
|
||||
self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit();
|
||||
return;
|
||||
}
|
||||
|
@ -110,25 +110,15 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||
.map(|i| chalk_ir::AssocTypeId(i.def_id))
|
||||
.collect();
|
||||
|
||||
let well_known = if self
|
||||
.interner
|
||||
.tcx
|
||||
.lang_items()
|
||||
.sized_trait()
|
||||
.map(|t| def_id == t)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
let well_known = if self.interner.tcx.lang_items().sized_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Sized)
|
||||
} else if self.interner.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false)
|
||||
{
|
||||
} else if self.interner.tcx.lang_items().copy_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Copy)
|
||||
} else if self.interner.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false)
|
||||
{
|
||||
} else if self.interner.tcx.lang_items().clone_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Clone)
|
||||
} else if self.interner.tcx.lang_items().drop_trait().map(|t| def_id == t).unwrap_or(false)
|
||||
{
|
||||
} else if self.interner.tcx.lang_items().drop_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Drop)
|
||||
} else if self.interner.tcx.lang_items().fn_trait().map(|t| def_id == t).unwrap_or(false) {
|
||||
} else if self.interner.tcx.lang_items().fn_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Fn)
|
||||
} else if self
|
||||
.interner
|
||||
|
@ -1343,6 +1343,10 @@ impl<T: Ord> From<Vec<T>> for BinaryHeap<T> {
|
||||
|
||||
#[stable(feature = "binary_heap_extras_15", since = "1.5.0")]
|
||||
impl<T> From<BinaryHeap<T>> for Vec<T> {
|
||||
/// Converts a `BinaryHeap<T>` into a `Vec<T>`.
|
||||
///
|
||||
/// This conversion requires no data movement or allocation, and has
|
||||
/// constant time complexity.
|
||||
fn from(heap: BinaryHeap<T>) -> Vec<T> {
|
||||
heap.data
|
||||
}
|
||||
|
@ -1089,11 +1089,7 @@ impl<T> VecDeque<T> {
|
||||
where
|
||||
R: RangeBounds<usize>,
|
||||
{
|
||||
// SAFETY: This buffer is only used to check the range. It might be partially
|
||||
// uninitialized, but `check_range` needs a contiguous slice.
|
||||
// https://github.com/rust-lang/rust/pull/75207#discussion_r471193682
|
||||
let buffer = unsafe { slice::from_raw_parts(self.ptr(), self.len()) };
|
||||
let Range { start, end } = buffer.check_range(range);
|
||||
let Range { start, end } = slice::check_range(self.len(), range);
|
||||
let tail = self.wrap_add(self.tail, start);
|
||||
let head = self.wrap_add(self.tail, end);
|
||||
(tail, head)
|
||||
|
@ -91,6 +91,8 @@ use crate::borrow::ToOwned;
|
||||
use crate::boxed::Box;
|
||||
use crate::vec::Vec;
|
||||
|
||||
#[unstable(feature = "slice_check_range", issue = "76393")]
|
||||
pub use core::slice::check_range;
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
pub use core::slice::ArrayChunks;
|
||||
#[unstable(feature = "array_chunks", issue = "74985")]
|
||||
|
@ -49,6 +49,7 @@ use core::iter::{FromIterator, FusedIterator};
|
||||
use core::ops::Bound::{Excluded, Included, Unbounded};
|
||||
use core::ops::{self, Add, AddAssign, Index, IndexMut, Range, RangeBounds};
|
||||
use core::ptr;
|
||||
use core::slice;
|
||||
use core::str::{lossy, pattern::Pattern};
|
||||
|
||||
use crate::borrow::{Cow, ToOwned};
|
||||
@ -1506,7 +1507,7 @@ impl String {
|
||||
// of the vector version. The data is just plain bytes.
|
||||
// Because the range removal happens in Drop, if the Drain iterator is leaked,
|
||||
// the removal will not happen.
|
||||
let Range { start, end } = self.as_bytes().check_range(range);
|
||||
let Range { start, end } = slice::check_range(self.len(), range);
|
||||
assert!(self.is_char_boundary(start));
|
||||
assert!(self.is_char_boundary(end));
|
||||
|
||||
|
@ -174,7 +174,9 @@ use crate::raw_vec::RawVec;
|
||||
///
|
||||
/// // ... and that's all!
|
||||
/// // you can also do it like this:
|
||||
/// let x : &[usize] = &v;
|
||||
/// let u: &[usize] = &v;
|
||||
/// // or like this:
|
||||
/// let u: &[_] = &v;
|
||||
/// ```
|
||||
///
|
||||
/// In Rust, it's more common to pass slices as arguments rather than vectors
|
||||
@ -1310,7 +1312,7 @@ impl<T> Vec<T> {
|
||||
// the hole, and the vector length is restored to the new length.
|
||||
//
|
||||
let len = self.len();
|
||||
let Range { start, end } = self.check_range(range);
|
||||
let Range { start, end } = slice::check_range(len, range);
|
||||
|
||||
unsafe {
|
||||
// set self.vec length's to start, to be safe in case Drain is leaked
|
||||
@ -3037,6 +3039,7 @@ impl<T> AsIntoIter for IntoIter<T> {
|
||||
/// A draining iterator for `Vec<T>`.
|
||||
///
|
||||
/// This `struct` is created by [`Vec::drain`].
|
||||
/// See its documentation for more.
|
||||
#[stable(feature = "drain", since = "1.6.0")]
|
||||
pub struct Drain<'a, T: 'a> {
|
||||
/// Index of tail to preserve
|
||||
|
@ -1921,3 +1921,24 @@ fn different_str_pattern_forwarding_lifetimes() {
|
||||
|
||||
foo::<&str>("x");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_str_multiline() {
|
||||
let a: String = "this \
|
||||
is a test"
|
||||
.to_string();
|
||||
let b: String = "this \
|
||||
is \
|
||||
another \
|
||||
test"
|
||||
.to_string();
|
||||
assert_eq!(a, "this is a test".to_string());
|
||||
assert_eq!(b, "this is another test".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_str_escapes() {
|
||||
let x = "\\\\\
|
||||
";
|
||||
assert_eq!(x, r"\\"); // extraneous whitespace stripped
|
||||
}
|
||||
|
@ -919,7 +919,7 @@ fn test_from_iter_partially_drained_in_place_specialization() {
|
||||
#[test]
|
||||
fn test_from_iter_specialization_with_iterator_adapters() {
|
||||
fn assert_in_place_trait<T: InPlaceIterable>(_: &T) {};
|
||||
let src: Vec<usize> = vec![0usize; 65535];
|
||||
let src: Vec<usize> = vec![0usize; 256];
|
||||
let srcptr = src.as_ptr();
|
||||
let iter = src
|
||||
.into_iter()
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Indexing implementations for `[T]`.
|
||||
|
||||
use crate::ops;
|
||||
use crate::ops::{self, Bound, Range, RangeBounds};
|
||||
use crate::ptr;
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -62,6 +62,79 @@ pub(super) fn slice_end_index_overflow_fail() -> ! {
|
||||
panic!("attempted to index slice up to maximum usize");
|
||||
}
|
||||
|
||||
/// Performs bounds-checking of the given range.
|
||||
/// The returned [`Range`] is safe to pass to [`get_unchecked`] and [`get_unchecked_mut`]
|
||||
/// for slices of the given length.
|
||||
///
|
||||
/// [`get_unchecked`]: ../../std/primitive.slice.html#method.get_unchecked
|
||||
/// [`get_unchecked_mut`]: ../../std/primitive.slice.html#method.get_unchecked_mut
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the range is out of bounds.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(slice_check_range)]
|
||||
/// use std::slice;
|
||||
///
|
||||
/// let v = [10, 40, 30];
|
||||
/// assert_eq!(1..2, slice::check_range(v.len(), 1..2));
|
||||
/// assert_eq!(0..2, slice::check_range(v.len(), ..2));
|
||||
/// assert_eq!(1..3, slice::check_range(v.len(), 1..));
|
||||
/// ```
|
||||
///
|
||||
/// Panics when [`Index::index`] would panic:
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(slice_check_range)]
|
||||
///
|
||||
/// std::slice::check_range(3, 2..1);
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(slice_check_range)]
|
||||
///
|
||||
/// std::slice::check_range(3, 1..4);
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(slice_check_range)]
|
||||
///
|
||||
/// std::slice::check_range(3, 1..=usize::MAX);
|
||||
/// ```
|
||||
///
|
||||
/// [`Index::index`]: ops::Index::index
|
||||
#[track_caller]
|
||||
#[unstable(feature = "slice_check_range", issue = "76393")]
|
||||
pub fn check_range<R: RangeBounds<usize>>(len: usize, range: R) -> Range<usize> {
|
||||
let start = match range.start_bound() {
|
||||
Bound::Included(&start) => start,
|
||||
Bound::Excluded(start) => {
|
||||
start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
|
||||
}
|
||||
Bound::Unbounded => 0,
|
||||
};
|
||||
|
||||
let end = match range.end_bound() {
|
||||
Bound::Included(end) => {
|
||||
end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
|
||||
}
|
||||
Bound::Excluded(&end) => end,
|
||||
Bound::Unbounded => len,
|
||||
};
|
||||
|
||||
if start > end {
|
||||
slice_index_order_fail(start, end);
|
||||
}
|
||||
if end > len {
|
||||
slice_end_index_len_fail(end, len);
|
||||
}
|
||||
|
||||
Range { start, end }
|
||||
}
|
||||
|
||||
mod private_slice_index {
|
||||
use super::ops;
|
||||
#[stable(feature = "slice_get_slice", since = "1.28.0")]
|
||||
|
@ -12,7 +12,7 @@ use crate::cmp::Ordering::{self, Equal, Greater, Less};
|
||||
use crate::intrinsics::assume;
|
||||
use crate::marker::{self, Copy};
|
||||
use crate::mem;
|
||||
use crate::ops::{Bound, FnMut, Range, RangeBounds};
|
||||
use crate::ops::{FnMut, Range, RangeBounds};
|
||||
use crate::option::Option;
|
||||
use crate::option::Option::{None, Some};
|
||||
use crate::ptr::{self, NonNull};
|
||||
@ -72,8 +72,8 @@ pub use sort::heapsort;
|
||||
#[stable(feature = "slice_get_slice", since = "1.28.0")]
|
||||
pub use index::SliceIndex;
|
||||
|
||||
use index::{slice_end_index_len_fail, slice_index_order_fail};
|
||||
use index::{slice_end_index_overflow_fail, slice_start_index_overflow_fail};
|
||||
#[unstable(feature = "slice_check_range", issue = "76393")]
|
||||
pub use index::check_range;
|
||||
|
||||
#[lang = "slice"]
|
||||
#[cfg(not(test))]
|
||||
@ -378,79 +378,6 @@ impl<T> [T] {
|
||||
unsafe { &mut *index.get_unchecked_mut(self) }
|
||||
}
|
||||
|
||||
/// Converts a range over this slice to [`Range`].
|
||||
///
|
||||
/// The returned range is safe to pass to [`get_unchecked`] and [`get_unchecked_mut`].
|
||||
///
|
||||
/// [`get_unchecked`]: #method.get_unchecked
|
||||
/// [`get_unchecked_mut`]: #method.get_unchecked_mut
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the range is out of bounds.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(slice_check_range)]
|
||||
///
|
||||
/// let v = [10, 40, 30];
|
||||
/// assert_eq!(1..2, v.check_range(1..2));
|
||||
/// assert_eq!(0..2, v.check_range(..2));
|
||||
/// assert_eq!(1..3, v.check_range(1..));
|
||||
/// ```
|
||||
///
|
||||
/// Panics when [`Index::index`] would panic:
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(slice_check_range)]
|
||||
///
|
||||
/// [10, 40, 30].check_range(2..1);
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(slice_check_range)]
|
||||
///
|
||||
/// [10, 40, 30].check_range(1..4);
|
||||
/// ```
|
||||
///
|
||||
/// ```should_panic
|
||||
/// #![feature(slice_check_range)]
|
||||
///
|
||||
/// [10, 40, 30].check_range(1..=usize::MAX);
|
||||
/// ```
|
||||
///
|
||||
/// [`Index::index`]: crate::ops::Index::index
|
||||
#[track_caller]
|
||||
#[unstable(feature = "slice_check_range", issue = "76393")]
|
||||
pub fn check_range<R: RangeBounds<usize>>(&self, range: R) -> Range<usize> {
|
||||
let start = match range.start_bound() {
|
||||
Bound::Included(&start) => start,
|
||||
Bound::Excluded(start) => {
|
||||
start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
|
||||
}
|
||||
Bound::Unbounded => 0,
|
||||
};
|
||||
|
||||
let len = self.len();
|
||||
let end = match range.end_bound() {
|
||||
Bound::Included(end) => {
|
||||
end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
|
||||
}
|
||||
Bound::Excluded(&end) => end,
|
||||
Bound::Unbounded => len,
|
||||
};
|
||||
|
||||
if start > end {
|
||||
slice_index_order_fail(start, end);
|
||||
}
|
||||
if end > len {
|
||||
slice_end_index_len_fail(end, len);
|
||||
}
|
||||
|
||||
Range { start, end }
|
||||
}
|
||||
|
||||
/// Returns a raw pointer to the slice's buffer.
|
||||
///
|
||||
/// The caller must ensure that the slice outlives the pointer this
|
||||
@ -2794,7 +2721,7 @@ impl<T> [T] {
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
let Range { start: src_start, end: src_end } = self.check_range(src);
|
||||
let Range { start: src_start, end: src_end } = check_range(self.len(), src);
|
||||
let count = src_end - src_start;
|
||||
assert!(dest <= self.len() - count, "dest is out of bounds");
|
||||
// SAFETY: the conditions for `ptr::copy` have all been checked above,
|
||||
|
@ -112,6 +112,14 @@ impl<T, E> Poll<Option<Result<T, E>>> {
|
||||
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
impl<T> From<T> for Poll<T> {
|
||||
/// Convert to a `Ready` variant.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use core::task::Poll;
|
||||
/// assert_eq!(Poll::from(true), Poll::Ready(true));
|
||||
/// ```
|
||||
fn from(t: T) -> Poll<T> {
|
||||
Poll::Ready(t)
|
||||
}
|
||||
|
@ -693,7 +693,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn from_secs_f64(secs: f64) -> Duration {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn from_secs_f64(secs: f64) -> Duration {
|
||||
const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f64;
|
||||
let nanos = secs * (NANOS_PER_SEC as f64);
|
||||
if !nanos.is_finite() {
|
||||
@ -727,7 +728,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn from_secs_f32(secs: f32) -> Duration {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn from_secs_f32(secs: f32) -> Duration {
|
||||
const MAX_NANOS_F32: f32 = ((u64::MAX as u128 + 1) * (NANOS_PER_SEC as u128)) as f32;
|
||||
let nanos = secs * (NANOS_PER_SEC as f32);
|
||||
if !nanos.is_finite() {
|
||||
@ -761,7 +763,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn mul_f64(self, rhs: f64) -> Duration {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn mul_f64(self, rhs: f64) -> Duration {
|
||||
Duration::from_secs_f64(rhs * self.as_secs_f64())
|
||||
}
|
||||
|
||||
@ -782,7 +785,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn mul_f32(self, rhs: f32) -> Duration {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn mul_f32(self, rhs: f32) -> Duration {
|
||||
Duration::from_secs_f32(rhs * self.as_secs_f32())
|
||||
}
|
||||
|
||||
@ -802,7 +806,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn div_f64(self, rhs: f64) -> Duration {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn div_f64(self, rhs: f64) -> Duration {
|
||||
Duration::from_secs_f64(self.as_secs_f64() / rhs)
|
||||
}
|
||||
|
||||
@ -824,7 +829,8 @@ impl Duration {
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[inline]
|
||||
pub fn div_f32(self, rhs: f32) -> Duration {
|
||||
#[rustc_const_unstable(feature = "duration_consts_2", issue = "72440")]
|
||||
pub const fn div_f32(self, rhs: f32) -> Duration {
|
||||
Duration::from_secs_f32(self.as_secs_f32() / rhs)
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,11 @@
|
||||
#![feature(core_private_diy_float)]
|
||||
#![feature(debug_non_exhaustive)]
|
||||
#![feature(dec2flt)]
|
||||
#![feature(div_duration)]
|
||||
#![feature(duration_consts_2)]
|
||||
#![feature(duration_constants)]
|
||||
#![feature(duration_saturating_ops)]
|
||||
#![feature(duration_zero)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(fixed_size_array)]
|
||||
#![feature(flt2dec)]
|
||||
|
@ -1 +1,30 @@
|
||||
int_module!(i32, i32);
|
||||
|
||||
#[test]
|
||||
fn test_arith_operation() {
|
||||
let a: isize = 10;
|
||||
assert_eq!(a * (a - 1), 90);
|
||||
let i32_a: isize = 10;
|
||||
assert_eq!(i32_a, 10);
|
||||
assert_eq!(i32_a - 10, 0);
|
||||
assert_eq!(i32_a / 10, 1);
|
||||
assert_eq!(i32_a - 20, -10);
|
||||
assert_eq!(i32_a << 10, 10240);
|
||||
assert_eq!(i32_a << 16, 655360);
|
||||
assert_eq!(i32_a * 16, 160);
|
||||
assert_eq!(i32_a * i32_a * i32_a, 1000);
|
||||
assert_eq!(i32_a * i32_a * i32_a * i32_a, 10000);
|
||||
assert_eq!(i32_a * i32_a / i32_a * i32_a, 100);
|
||||
assert_eq!(i32_a * (i32_a - 1) << (2 + i32_a as usize), 368640);
|
||||
let i32_b: isize = 0x10101010;
|
||||
assert_eq!(i32_b + 1 - 1, i32_b);
|
||||
assert_eq!(i32_b << 1, i32_b << 1);
|
||||
assert_eq!(i32_b >> 1, i32_b >> 1);
|
||||
assert_eq!(i32_b & i32_b << 1, 0);
|
||||
assert_eq!(i32_b | i32_b << 1, 0x30303030);
|
||||
let i32_c: isize = 0x10101010;
|
||||
assert_eq!(
|
||||
i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3),
|
||||
i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3)
|
||||
);
|
||||
}
|
||||
|
@ -321,3 +321,104 @@ fn debug_formatting_precision_high() {
|
||||
assert_eq!(format!("{:.10?}", Duration::new(4, 001_000_000)), "4.0010000000s");
|
||||
assert_eq!(format!("{:.20?}", Duration::new(4, 001_000_000)), "4.00100000000000000000s");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn duration_const() {
|
||||
// test that the methods of `Duration` are usable in a const context
|
||||
|
||||
const DURATION: Duration = Duration::new(0, 123_456_789);
|
||||
|
||||
const SUB_SEC_MILLIS: u32 = DURATION.subsec_millis();
|
||||
assert_eq!(SUB_SEC_MILLIS, 123);
|
||||
|
||||
const SUB_SEC_MICROS: u32 = DURATION.subsec_micros();
|
||||
assert_eq!(SUB_SEC_MICROS, 123_456);
|
||||
|
||||
const SUB_SEC_NANOS: u32 = DURATION.subsec_nanos();
|
||||
assert_eq!(SUB_SEC_NANOS, 123_456_789);
|
||||
|
||||
const ZERO: Duration = Duration::zero();
|
||||
assert_eq!(ZERO, Duration::new(0, 0));
|
||||
|
||||
const IS_ZERO: bool = ZERO.is_zero();
|
||||
assert!(IS_ZERO);
|
||||
|
||||
const ONE: Duration = Duration::new(1, 0);
|
||||
|
||||
const SECONDS: u64 = ONE.as_secs();
|
||||
assert_eq!(SECONDS, 1);
|
||||
|
||||
const FROM_SECONDS: Duration = Duration::from_secs(1);
|
||||
assert_eq!(FROM_SECONDS, ONE);
|
||||
|
||||
const SECONDS_F32: f32 = ONE.as_secs_f32();
|
||||
assert_eq!(SECONDS_F32, 1.0);
|
||||
|
||||
const FROM_SECONDS_F32: Duration = Duration::from_secs_f32(1.0);
|
||||
assert_eq!(FROM_SECONDS_F32, ONE);
|
||||
|
||||
const SECONDS_F64: f64 = ONE.as_secs_f64();
|
||||
assert_eq!(SECONDS_F64, 1.0);
|
||||
|
||||
const FROM_SECONDS_F64: Duration = Duration::from_secs_f64(1.0);
|
||||
assert_eq!(FROM_SECONDS_F64, ONE);
|
||||
|
||||
const MILLIS: u128 = ONE.as_millis();
|
||||
assert_eq!(MILLIS, 1_000);
|
||||
|
||||
const FROM_MILLIS: Duration = Duration::from_millis(1_000);
|
||||
assert_eq!(FROM_MILLIS, ONE);
|
||||
|
||||
const MICROS: u128 = ONE.as_micros();
|
||||
assert_eq!(MICROS, 1_000_000);
|
||||
|
||||
const FROM_MICROS: Duration = Duration::from_micros(1_000_000);
|
||||
assert_eq!(FROM_MICROS, ONE);
|
||||
|
||||
const NANOS: u128 = ONE.as_nanos();
|
||||
assert_eq!(NANOS, 1_000_000_000);
|
||||
|
||||
const FROM_NANOS: Duration = Duration::from_nanos(1_000_000_000);
|
||||
assert_eq!(FROM_NANOS, ONE);
|
||||
|
||||
const MAX: Duration = Duration::new(u64::MAX, 999_999_999);
|
||||
|
||||
const CHECKED_ADD: Option<Duration> = MAX.checked_add(ONE);
|
||||
assert_eq!(CHECKED_ADD, None);
|
||||
|
||||
const CHECKED_SUB: Option<Duration> = ZERO.checked_sub(ONE);
|
||||
assert_eq!(CHECKED_SUB, None);
|
||||
|
||||
const CHECKED_MUL: Option<Duration> = ONE.checked_mul(1);
|
||||
assert_eq!(CHECKED_MUL, Some(ONE));
|
||||
|
||||
const MUL_F32: Duration = ONE.mul_f32(1.0);
|
||||
assert_eq!(MUL_F32, ONE);
|
||||
|
||||
const MUL_F64: Duration = ONE.mul_f64(1.0);
|
||||
assert_eq!(MUL_F64, ONE);
|
||||
|
||||
const CHECKED_DIV: Option<Duration> = ONE.checked_div(1);
|
||||
assert_eq!(CHECKED_DIV, Some(ONE));
|
||||
|
||||
const DIV_F32: Duration = ONE.div_f32(1.0);
|
||||
assert_eq!(DIV_F32, ONE);
|
||||
|
||||
const DIV_F64: Duration = ONE.div_f64(1.0);
|
||||
assert_eq!(DIV_F64, ONE);
|
||||
|
||||
const DIV_DURATION_F32: f32 = ONE.div_duration_f32(ONE);
|
||||
assert_eq!(DIV_DURATION_F32, 1.0);
|
||||
|
||||
const DIV_DURATION_F64: f64 = ONE.div_duration_f64(ONE);
|
||||
assert_eq!(DIV_DURATION_F64, 1.0);
|
||||
|
||||
const SATURATING_ADD: Duration = MAX.saturating_add(ONE);
|
||||
assert_eq!(SATURATING_ADD, MAX);
|
||||
|
||||
const SATURATING_SUB: Duration = ZERO.saturating_sub(ONE);
|
||||
assert_eq!(SATURATING_SUB, ZERO);
|
||||
|
||||
const SATURATING_MUL: Duration = MAX.saturating_mul(2);
|
||||
assert_eq!(SATURATING_MUL, MAX);
|
||||
}
|
||||
|
@ -424,10 +424,9 @@ pub mod fast {
|
||||
// thread_local's, or it is being recursively initialized.
|
||||
//
|
||||
// Macos: Inlining this function can cause two `tlv_get_addr` calls to
|
||||
// be performed for every call to `Key::get`. The #[cold] hint makes
|
||||
// that less likely.
|
||||
// be performed for every call to `Key::get`.
|
||||
// LLVM issue: https://bugs.llvm.org/show_bug.cgi?id=41722
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
unsafe fn try_initialize<F: FnOnce() -> T>(&self, init: F) -> Option<&'static T> {
|
||||
if !mem::needs_drop::<T>() || self.try_register_dtor() {
|
||||
Some(self.inner.initialize(init))
|
||||
|
@ -26,10 +26,10 @@ The script accepts commands, flags, and arguments to determine what to do:
|
||||
|
||||
```
|
||||
# build the whole compiler
|
||||
./x.py build
|
||||
./x.py build --stage 2
|
||||
|
||||
# build the stage1 compiler
|
||||
./x.py build --stage 1
|
||||
./x.py build
|
||||
|
||||
# build stage0 libstd
|
||||
./x.py build --stage 0 library/std
|
||||
@ -43,8 +43,8 @@ The script accepts commands, flags, and arguments to determine what to do:
|
||||
that belong to stage n or earlier:
|
||||
|
||||
```
|
||||
# keep old build products for stage 0 and build stage 1
|
||||
./x.py build --keep-stage 0 --stage 1
|
||||
# build stage 1, keeping old build products for stage 0
|
||||
./x.py build --keep-stage 0
|
||||
```
|
||||
|
||||
* `test` - a command for executing unit tests. Like the `build` command this
|
||||
@ -123,24 +123,8 @@ that (b) leverage Rust as much as possible!
|
||||
|
||||
## Incremental builds
|
||||
|
||||
You can configure rustbuild to use incremental compilation. Because
|
||||
incremental is new and evolving rapidly, if you want to use it, it is
|
||||
recommended that you replace the snapshot with a locally installed
|
||||
nightly build of rustc. You will want to keep this up to date.
|
||||
|
||||
To follow this course of action, first thing you will want to do is to
|
||||
install a nightly, presumably using `rustup`. You will then want to
|
||||
configure your directory to use this build, like so:
|
||||
|
||||
```sh
|
||||
# configure to use local rust instead of downloading a beta.
|
||||
# `--local-rust-root` is optional here. If elided, we will
|
||||
# use whatever rustc we find on your PATH.
|
||||
$ ./configure --local-rust-root=~/.cargo/ --enable-local-rebuild
|
||||
```
|
||||
|
||||
After that, you can use the `--incremental` flag to actually do
|
||||
incremental builds:
|
||||
You can configure rustbuild to use incremental compilation with the
|
||||
`--incremental` flag:
|
||||
|
||||
```sh
|
||||
$ ./x.py build --incremental
|
||||
@ -150,9 +134,7 @@ The `--incremental` flag will store incremental compilation artifacts
|
||||
in `build/<host>/stage0-incremental`. Note that we only use incremental
|
||||
compilation for the stage0 -> stage1 compilation -- this is because
|
||||
the stage1 compiler is changing, and we don't try to cache and reuse
|
||||
incremental artifacts across different versions of the compiler. For
|
||||
this reason, `--incremental` defaults to `--stage 1` (though you can
|
||||
manually select a higher stage, if you prefer).
|
||||
incremental artifacts across different versions of the compiler.
|
||||
|
||||
You can always drop the `--incremental` to build as normal (but you
|
||||
will still be using the local nightly as your bootstrap).
|
||||
@ -331,8 +313,8 @@ are:
|
||||
`Config` struct.
|
||||
* Adding a sanity check? Take a look at `bootstrap/sanity.rs`.
|
||||
|
||||
If you have any questions feel free to reach out on `#infra` channel in the
|
||||
[Rust Discord server][rust-discord] or ask on internals.rust-lang.org. When
|
||||
If you have any questions feel free to reach out on the `#t-infra` channel in
|
||||
the [Rust Zulip server][rust-zulip] or ask on internals.rust-lang.org. When
|
||||
you encounter bugs, please file issues on the rust-lang/rust issue tracker.
|
||||
|
||||
[rust-discord]: https://discord.gg/rust-lang
|
||||
[rust-zulip]: https://rust-lang.zulipchat.com/#narrow/stream/242791-t-infra
|
||||
|
@ -840,7 +840,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
|
||||
let mut where_predicates =
|
||||
where_predicates.into_iter().flat_map(|p| p.clean(cx)).collect::<Vec<_>>();
|
||||
|
||||
// Type parameters and have a Sized bound by default unless removed with
|
||||
// Type parameters have a Sized bound by default unless removed with
|
||||
// ?Sized. Scan through the predicates and mark any type parameter with
|
||||
// a Sized bound, removing the bounds as we find them.
|
||||
//
|
||||
|
@ -1,67 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_panic)]
|
||||
#![feature(duration_consts_2)]
|
||||
#![feature(div_duration)]
|
||||
#![feature(duration_saturating_ops)]
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
fn duration() {
|
||||
const ZERO : Duration = Duration::new(0, 0);
|
||||
assert_eq!(ZERO, Duration::from_secs(0));
|
||||
|
||||
const ONE : Duration = Duration::new(0, 1);
|
||||
assert_eq!(ONE, Duration::from_nanos(1));
|
||||
|
||||
const MAX : Duration = Duration::new(u64::MAX, 1_000_000_000 - 1);
|
||||
|
||||
const MAX_CHECKED_ADD_ZERO : Option<Duration> = MAX.checked_add(ZERO);
|
||||
assert_eq!(MAX_CHECKED_ADD_ZERO, Some(MAX));
|
||||
|
||||
const MAX_CHECKED_ADD_ONE : Option<Duration> = MAX.checked_add(ONE);
|
||||
assert_eq!(MAX_CHECKED_ADD_ONE, None);
|
||||
|
||||
const ONE_CHECKED_SUB_ONE : Option<Duration> = ONE.checked_sub(ONE);
|
||||
assert_eq!(ONE_CHECKED_SUB_ONE, Some(ZERO));
|
||||
|
||||
const ZERO_CHECKED_SUB_ONE : Option<Duration> = ZERO.checked_sub(ONE);
|
||||
assert_eq!(ZERO_CHECKED_SUB_ONE, None);
|
||||
|
||||
const ONE_CHECKED_MUL_ONE : Option<Duration> = ONE.checked_mul(1);
|
||||
assert_eq!(ONE_CHECKED_MUL_ONE, Some(ONE));
|
||||
|
||||
const MAX_CHECKED_MUL_TWO : Option<Duration> = MAX.checked_mul(2);
|
||||
assert_eq!(MAX_CHECKED_MUL_TWO, None);
|
||||
|
||||
const ONE_CHECKED_DIV_ONE : Option<Duration> = ONE.checked_div(1);
|
||||
assert_eq!(ONE_CHECKED_DIV_ONE, Some(ONE));
|
||||
|
||||
const ONE_CHECKED_DIV_ZERO : Option<Duration> = ONE.checked_div(0);
|
||||
assert_eq!(ONE_CHECKED_DIV_ZERO, None);
|
||||
|
||||
const MAX_AS_F32 : f32 = MAX.as_secs_f32();
|
||||
assert_eq!(MAX_AS_F32, 18446744000000000000.0_f32);
|
||||
|
||||
const MAX_AS_F64 : f64 = MAX.as_secs_f64();
|
||||
assert_eq!(MAX_AS_F64, 18446744073709552000.0_f64);
|
||||
|
||||
const ONE_AS_F32 : f32 = ONE.div_duration_f32(ONE);
|
||||
assert_eq!(ONE_AS_F32, 1.0_f32);
|
||||
|
||||
const ONE_AS_F64 : f64 = ONE.div_duration_f64(ONE);
|
||||
assert_eq!(ONE_AS_F64, 1.0_f64);
|
||||
|
||||
const MAX_SATURATING_ADD_ONE : Duration = MAX.saturating_add(ONE);
|
||||
assert_eq!(MAX_SATURATING_ADD_ONE, MAX);
|
||||
|
||||
const ZERO_SATURATING_SUB_ONE : Duration = ZERO.saturating_sub(ONE);
|
||||
assert_eq!(ZERO_SATURATING_SUB_ONE, ZERO);
|
||||
|
||||
const MAX_SATURATING_MUL_TWO : Duration = MAX.saturating_mul(2);
|
||||
assert_eq!(MAX_SATURATING_MUL_TWO, MAX);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
duration();
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
|
||||
pub fn main() {
|
||||
let a: isize = 10;
|
||||
println!("{}", a);
|
||||
assert_eq!(a * (a - 1), 90);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
|
||||
pub fn main() {
|
||||
let i32_a: isize = 10;
|
||||
assert_eq!(i32_a, 10);
|
||||
assert_eq!(i32_a - 10, 0);
|
||||
assert_eq!(i32_a / 10, 1);
|
||||
assert_eq!(i32_a - 20, -10);
|
||||
assert_eq!(i32_a << 10, 10240);
|
||||
assert_eq!(i32_a << 16, 655360);
|
||||
assert_eq!(i32_a * 16, 160);
|
||||
assert_eq!(i32_a * i32_a * i32_a, 1000);
|
||||
assert_eq!(i32_a * i32_a * i32_a * i32_a, 10000);
|
||||
assert_eq!(i32_a * i32_a / i32_a * i32_a, 100);
|
||||
assert_eq!(i32_a * (i32_a - 1) << (2 + i32_a as usize), 368640);
|
||||
let i32_b: isize = 0x10101010;
|
||||
assert_eq!(i32_b + 1 - 1, i32_b);
|
||||
assert_eq!(i32_b << 1, i32_b << 1);
|
||||
assert_eq!(i32_b >> 1, i32_b >> 1);
|
||||
assert_eq!(i32_b & i32_b << 1, 0);
|
||||
println!("{}", i32_b | i32_b << 1);
|
||||
assert_eq!(i32_b | i32_b << 1, 0x30303030);
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
|
||||
|
||||
pub fn main() {
|
||||
let i32_c: isize = 0x10101010;
|
||||
assert_eq!(i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3),
|
||||
i32_c + i32_c * 2 / 3 * 2 + (i32_c - 7 % 3));
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
pub fn main() {
|
||||
let a: String = "this \
|
||||
is a test".to_string();
|
||||
let b: String =
|
||||
"this \
|
||||
is \
|
||||
another \
|
||||
test".to_string();
|
||||
assert_eq!(a, "this is a test".to_string());
|
||||
assert_eq!(b, "this is another test".to_string());
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
// run-pass
|
||||
|
||||
fn main() {
|
||||
let x = "\\\\\
|
||||
";
|
||||
assert_eq!(x, r"\\"); // extraneous whitespace stripped
|
||||
}
|
Loading…
Reference in New Issue
Block a user