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:
bors 2020-09-16 06:46:24 +00:00
commit 5fae56971d
26 changed files with 292 additions and 274 deletions

View File

@ -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(_))

View File

@ -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;
}

View File

@ -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

View File

@ -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
}

View File

@ -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)

View File

@ -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")]

View File

@ -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));

View File

@ -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

View File

@ -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
}

View File

@ -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()

View File

@ -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")]

View File

@ -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,

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)]

View File

@ -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)
);
}

View File

@ -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);
}

View File

@ -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))

View File

@ -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

View File

@ -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.
//

View File

@ -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();
}

View File

@ -1,8 +0,0 @@
// run-pass
pub fn main() {
let a: isize = 10;
println!("{}", a);
assert_eq!(a * (a - 1), 90);
}

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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());
}

View File

@ -1,7 +0,0 @@
// run-pass
fn main() {
let x = "\\\\\
";
assert_eq!(x, r"\\"); // extraneous whitespace stripped
}