Auto merge of #50629 - Mark-Simulacrum:stage-step, r=alexcrichton

Switch to bootstrapping from 1.27

It's possible the Float trait could be removed from core, but I couldn't tell whether it was intended to be removed or not. @SimonSapin may be able to comment more here; we can presumably also do that in a follow up PR as this one is already quite large.
This commit is contained in:
bors 2018-05-17 16:44:38 +00:00
commit 90463a6bdc
43 changed files with 665 additions and 1744 deletions

View File

@ -584,11 +584,10 @@ impl<'a> Builder<'a> {
cargo.env("RUST_CHECK", "1");
}
// If we were invoked from `make` then that's already got a jobserver
// set up for us so no need to tell Cargo about jobs all over again.
if env::var_os("MAKEFLAGS").is_none() && env::var_os("MFLAGS").is_none() {
cargo.arg("-j").arg(self.jobs().to_string());
}
cargo.arg("-j").arg(self.jobs().to_string());
// Remove make-related flags to ensure Cargo can correctly set things up
cargo.env_remove("MAKEFLAGS");
cargo.env_remove("MFLAGS");
// FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005
// Force cargo to output binaries with disambiguating hashes in the name

View File

@ -24,7 +24,7 @@ use Build;
use config::Config;
// The version number
pub const CFG_RELEASE_NUM: &str = "1.27.0";
pub const CFG_RELEASE_NUM: &str = "1.28.0";
pub struct GitInfo {
inner: Option<Info>,

View File

@ -972,7 +972,7 @@ impl Step for Assemble {
// Link the compiler binary itself into place
let out_dir = builder.cargo_out(build_compiler, Mode::Librustc, host);
let rustc = out_dir.join(exe("rustc", &*host));
let rustc = out_dir.join(exe("rustc_binary", &*host));
let bindir = sysroot.join("bin");
t!(fs::create_dir_all(&bindir));
let compiler = builder.rustc(target_compiler);

View File

@ -431,7 +431,7 @@ impl Step for Rustdoc {
// the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
// rustdoc a different name.
let tool_rustdoc = builder.cargo_out(build_compiler, Mode::Tool, target)
.join(exe("rustdoc-tool-binary", &target_compiler.host));
.join(exe("rustdoc_tool_binary", &target_compiler.host));
// don't create a stage0-sysroot/bin directory.
if target_compiler.stage > 0 {

View File

@ -2,6 +2,8 @@
authors = ["The Rust Project Developers"]
name = "alloc"
version = "0.0.0"
autotests = false
autobenches = false
[lib]
name = "alloc"

View File

@ -22,28 +22,6 @@ use core::usize;
#[doc(inline)]
pub use core::alloc::*;
#[cfg(stage0)]
extern "Rust" {
#[allocator]
#[rustc_allocator_nounwind]
fn __rust_alloc(size: usize, align: usize, err: *mut u8) -> *mut u8;
#[cold]
#[rustc_allocator_nounwind]
fn __rust_oom(err: *const u8) -> !;
#[rustc_allocator_nounwind]
fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
#[rustc_allocator_nounwind]
fn __rust_realloc(ptr: *mut u8,
old_size: usize,
old_align: usize,
new_size: usize,
new_align: usize,
err: *mut u8) -> *mut u8;
#[rustc_allocator_nounwind]
fn __rust_alloc_zeroed(size: usize, align: usize, err: *mut u8) -> *mut u8;
}
#[cfg(not(stage0))]
extern "Rust" {
#[allocator]
#[rustc_allocator_nounwind]
@ -74,10 +52,7 @@ pub const Heap: Global = Global;
unsafe impl GlobalAlloc for Global {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
#[cfg(not(stage0))]
let ptr = __rust_alloc(layout.size(), layout.align());
#[cfg(stage0)]
let ptr = __rust_alloc(layout.size(), layout.align(), &mut 0);
ptr as *mut Opaque
}
@ -88,20 +63,13 @@ unsafe impl GlobalAlloc for Global {
#[inline]
unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque {
#[cfg(not(stage0))]
let ptr = __rust_realloc(ptr as *mut u8, layout.size(), layout.align(), new_size);
#[cfg(stage0)]
let ptr = __rust_realloc(ptr as *mut u8, layout.size(), layout.align(),
new_size, layout.align(), &mut 0);
ptr as *mut Opaque
}
#[inline]
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque {
#[cfg(not(stage0))]
let ptr = __rust_alloc_zeroed(layout.size(), layout.align());
#[cfg(stage0)]
let ptr = __rust_alloc_zeroed(layout.size(), layout.align(), &mut 0);
ptr as *mut Opaque
}
}
@ -152,14 +120,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
}
}
#[cfg(stage0)]
#[lang = "box_free"]
#[inline]
unsafe fn old_box_free<T: ?Sized>(ptr: *mut T) {
box_free(Unique::new_unchecked(ptr))
}
#[cfg_attr(not(any(test, stage0)), lang = "box_free")]
#[cfg_attr(not(test), lang = "box_free")]
#[inline]
pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
let ptr = ptr.as_ptr();
@ -172,12 +133,6 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
}
}
#[cfg(stage0)]
pub fn oom() -> ! {
unsafe { ::core::intrinsics::abort() }
}
#[cfg(not(stage0))]
pub fn oom() -> ! {
extern {
#[lang = "oom"]

View File

@ -75,7 +75,6 @@
#![deny(missing_debug_implementations)]
#![cfg_attr(test, allow(deprecated))] // rand
#![cfg_attr(all(not(test), stage0), feature(float_internals))]
#![cfg_attr(not(test), feature(exact_size_is_empty))]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(rand, test))]
@ -90,13 +89,10 @@
#![feature(collections_range)]
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![cfg_attr(stage0, feature(core_slice_ext))]
#![cfg_attr(stage0, feature(core_str_ext))]
#![feature(custom_attribute)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(fmt_internals)]
#![cfg_attr(stage0, feature(fn_must_use))]
#![feature(from_ref)]
#![feature(fundamental)]
#![feature(lang_items)]
@ -122,7 +118,6 @@
#![feature(exact_chunks)]
#![feature(pointer_methods)]
#![feature(inclusive_range_methods)]
#![cfg_attr(stage0, feature(generic_param_attrs))]
#![feature(rustc_const_unstable)]
#![feature(const_vec_new)]
@ -157,15 +152,10 @@ pub mod alloc;
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_deprecated(since = "1.27.0", reason = "module renamed to `alloc`")]
/// Use the `alloc` module instead.
#[cfg(not(stage0))]
pub mod heap {
pub use alloc::*;
}
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_deprecated(since = "1.27.0", reason = "module renamed to `alloc`")]
#[cfg(stage0)]
pub mod heap;
// Primitive types using the heaps above

View File

@ -101,7 +101,6 @@ use core::cmp::Ordering::{self, Less};
use core::mem::size_of;
use core::mem;
use core::ptr;
#[cfg(stage0)] use core::slice::SliceExt;
use core::{u8, u16, u32};
use borrow::{Borrow, BorrowMut, ToOwned};
@ -171,13 +170,9 @@ mod hack {
}
}
#[cfg_attr(stage0, lang = "slice")]
#[cfg_attr(not(stage0), lang = "slice_alloc")]
#[lang = "slice_alloc"]
#[cfg(not(test))]
impl<T> [T] {
#[cfg(stage0)]
slice_core_methods!();
/// Sorts the slice.
///
/// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
@ -467,8 +462,7 @@ impl<T> [T] {
}
}
#[cfg_attr(stage0, lang = "slice_u8")]
#[cfg_attr(not(stage0), lang = "slice_u8_alloc")]
#[lang = "slice_u8_alloc"]
#[cfg(not(test))]
impl [u8] {
/// Returns a vector containing a copy of this slice where each byte
@ -504,9 +498,6 @@ impl [u8] {
me.make_ascii_lowercase();
me
}
#[cfg(stage0)]
slice_u8_core_methods!();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -40,7 +40,6 @@
use core::fmt;
use core::str as core_str;
#[cfg(stage0)] use core::str::StrExt;
use core::str::pattern::Pattern;
use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
use core::mem;
@ -158,13 +157,9 @@ impl ToOwned for str {
}
/// Methods for string slices.
#[cfg_attr(stage0, lang = "str")]
#[cfg_attr(not(stage0), lang = "str_alloc")]
#[lang = "str_alloc"]
#[cfg(not(test))]
impl str {
#[cfg(stage0)]
str_core_methods!();
/// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
///
/// # Examples

View File

@ -73,9 +73,6 @@ use core::intrinsics::{arith_offset, assume};
use core::iter::{FromIterator, FusedIterator, TrustedLen};
use core::marker::PhantomData;
use core::mem;
#[cfg(not(test))]
#[cfg(stage0)]
use core::num::Float;
use core::ops::Bound::{Excluded, Included, Unbounded};
use core::ops::{Index, IndexMut, RangeBounds};
use core::ops;

View File

@ -97,13 +97,6 @@ mod contents {
ptr
}
#[cfg(stage0)]
#[no_mangle]
#[rustc_std_internal_symbol]
pub unsafe extern fn __rde_oom() -> ! {
::core::intrinsics::abort();
}
#[no_mangle]
#[rustc_std_internal_symbol]
pub unsafe extern fn __rde_dealloc(ptr: *mut u8,

View File

@ -73,33 +73,6 @@ unsafe impl Alloc for System {
}
}
#[cfg(stage0)]
#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl<'a> Alloc for &'a System {
#[inline]
unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
NonNull::new(GlobalAlloc::alloc(*self, layout)).ok_or(AllocErr)
}
#[inline]
unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
NonNull::new(GlobalAlloc::alloc_zeroed(*self, layout)).ok_or(AllocErr)
}
#[inline]
unsafe fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout) {
GlobalAlloc::dealloc(*self, ptr.as_ptr(), layout)
}
#[inline]
unsafe fn realloc(&mut self,
ptr: NonNull<Opaque>,
layout: Layout,
new_size: usize) -> Result<NonNull<Opaque>, AllocErr> {
NonNull::new(GlobalAlloc::realloc(*self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
}
}
#[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))]
mod realloc_fallback {
use core::alloc::{GlobalAlloc, Opaque, Layout};

View File

@ -26,7 +26,6 @@
#![feature(alloc)]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
#![cfg_attr(stage0, feature(generic_param_attrs))]
#![cfg_attr(test, feature(test))]
#![allow(deprecated)]

View File

@ -2,6 +2,8 @@
authors = ["The Rust Project Developers"]
name = "core"
version = "0.0.0"
autotests = false
autobenches = false
[lib]
name = "core"

View File

@ -153,7 +153,6 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: ::marker::PhantomData<T
///
/// Implementations that cannot be described in Rust
/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
#[cfg(not(stage0))]
mod impls {
use super::Clone;

View File

@ -86,17 +86,3 @@ macro_rules! forward_ref_op_assign {
}
}
}
#[cfg(stage0)]
macro_rules! public_in_stage0 {
( { $(#[$attr:meta])* } $($Item: tt)*) => {
$(#[$attr])* pub $($Item)*
}
}
#[cfg(not(stage0))]
macro_rules! public_in_stage0 {
( { $(#[$attr:meta])* } $($Item: tt)*) => {
$(#[$attr])* pub(crate) $($Item)*
}
}

View File

@ -112,18 +112,13 @@
#![feature(unwind_attributes)]
#![feature(doc_alias)]
#![feature(inclusive_range_methods)]
#![cfg_attr(not(stage0), feature(mmx_target_feature))]
#![cfg_attr(not(stage0), feature(tbm_target_feature))]
#![cfg_attr(not(stage0), feature(sse4a_target_feature))]
#![cfg_attr(not(stage0), feature(arm_target_feature))]
#![cfg_attr(not(stage0), feature(powerpc_target_feature))]
#![cfg_attr(not(stage0), feature(mips_target_feature))]
#![cfg_attr(not(stage0), feature(aarch64_target_feature))]
#![cfg_attr(stage0, feature(target_feature))]
#![cfg_attr(stage0, feature(cfg_target_feature))]
#![cfg_attr(stage0, feature(fn_must_use))]
#![feature(mmx_target_feature)]
#![feature(tbm_target_feature)]
#![feature(sse4a_target_feature)]
#![feature(arm_target_feature)]
#![feature(powerpc_target_feature)]
#![feature(mips_target_feature)]
#![feature(aarch64_target_feature)]
#[prelude_import]
#[allow(unused)]

View File

@ -611,7 +611,6 @@ pub unsafe auto trait Unpin {}
///
/// Implementations that cannot be described in Rust
/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
#[cfg(not(stage0))]
mod copy_impls {
use super::Copy;

View File

@ -19,7 +19,7 @@
use mem;
use num::Float;
#[cfg(not(stage0))] use num::FpCategory;
use num::FpCategory;
use num::FpCategory as Fp;
/// The radix or base of the internal representation of `f32`.
@ -277,7 +277,6 @@ impl Float for f32 {
// FIXME: remove (inline) this macro and the Float trait
// when updating to a bootstrap compiler that has the new lang items.
#[cfg_attr(stage0, macro_export)]
#[unstable(feature = "core_float", issue = "32110")]
macro_rules! f32_core_methods { () => {
/// Returns `true` if this value is `NaN` and false otherwise.
@ -553,7 +552,6 @@ macro_rules! f32_core_methods { () => {
#[lang = "f32"]
#[cfg(not(test))]
#[cfg(not(stage0))]
impl f32 {
f32_core_methods!();
}

View File

@ -19,7 +19,7 @@
use mem;
use num::Float;
#[cfg(not(stage0))] use num::FpCategory;
use num::FpCategory;
use num::FpCategory as Fp;
/// The radix or base of the internal representation of `f64`.
@ -276,7 +276,6 @@ impl Float for f64 {
// FIXME: remove (inline) this macro and the Float trait
// when updating to a bootstrap compiler that has the new lang items.
#[cfg_attr(stage0, macro_export)]
#[unstable(feature = "core_float", issue = "32110")]
macro_rules! f64_core_methods { () => {
/// Returns `true` if this value is `NaN` and false otherwise.
@ -562,7 +561,6 @@ macro_rules! f64_core_methods { () => {
#[lang = "f64"]
#[cfg(not(test))]
#[cfg(not(stage0))]
impl f64 {
f64_core_methods!();
}

View File

@ -422,7 +422,6 @@ $EndFeature, "
/// assert_eq!(m, -22016);
/// ```
#[unstable(feature = "reverse_bits", issue = "48763")]
#[cfg(not(stage0))]
#[inline]
pub fn reverse_bits(self) -> Self {
(self as $UnsignedT).reverse_bits() as Self
@ -2194,7 +2193,6 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
/// assert_eq!(m, 43520);
/// ```
#[unstable(feature = "reverse_bits", issue = "48763")]
#[cfg(not(stage0))]
#[inline]
pub fn reverse_bits(self) -> Self {
unsafe { intrinsics::bitreverse(self as $ActualT) as Self }

View File

@ -335,18 +335,8 @@ pub struct RangeInclusive<Idx> {
// but it is known that LLVM is not able to optimize loops following that RFC.
// Consider adding an extra `bool` field to indicate emptiness of the range.
// See #45222 for performance test cases.
#[cfg(not(stage0))]
pub(crate) start: Idx,
#[cfg(not(stage0))]
pub(crate) end: Idx,
/// The lower bound of the range (inclusive).
#[cfg(stage0)]
#[unstable(feature = "inclusive_range_fields", issue = "49022")]
pub start: Idx,
/// The upper bound of the range (inclusive).
#[cfg(stage0)]
#[unstable(feature = "inclusive_range_fields", issue = "49022")]
pub end: Idx,
}
impl<Idx> RangeInclusive<Idx> {

View File

@ -54,13 +54,3 @@ pub use option::Option::{self, Some, None};
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
pub use result::Result::{self, Ok, Err};
// Re-exported extension traits for primitive types
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
#[cfg(stage0)]
pub use slice::SliceExt;
#[stable(feature = "core_prelude", since = "1.4.0")]
#[doc(no_inline)]
#[cfg(stage0)]
pub use str::StrExt;

File diff suppressed because it is too large Load Diff

View File

@ -2097,120 +2097,8 @@ mod traits {
(..self.end+1).index_mut(slice)
}
}
}
public_in_stage0! {
{
/// Methods for string slices
#[allow(missing_docs)]
#[doc(hidden)]
#[unstable(feature = "core_str_ext",
reason = "stable interface provided by `impl str` in later crates",
issue = "32110")]
}
trait StrExt {
// NB there are no docs here are they're all located on the StrExt trait in
// liballoc, not here.
#[stable(feature = "core", since = "1.6.0")]
fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
#[stable(feature = "core", since = "1.6.0")]
fn chars(&self) -> Chars;
#[stable(feature = "core", since = "1.6.0")]
fn bytes(&self) -> Bytes;
#[stable(feature = "core", since = "1.6.0")]
fn char_indices(&self) -> CharIndices;
#[stable(feature = "core", since = "1.6.0")]
fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P>;
#[stable(feature = "core", since = "1.6.0")]
fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
where P::Searcher: ReverseSearcher<'a>;
#[stable(feature = "core", since = "1.6.0")]
fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P>;
#[stable(feature = "core", since = "1.6.0")]
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a>;
#[stable(feature = "core", since = "1.6.0")]
fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
#[stable(feature = "core", since = "1.6.0")]
fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
where P::Searcher: ReverseSearcher<'a>;
#[stable(feature = "core", since = "1.6.0")]
fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P>;
#[stable(feature = "core", since = "1.6.0")]
fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
where P::Searcher: ReverseSearcher<'a>;
#[stable(feature = "core", since = "1.6.0")]
fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
#[stable(feature = "core", since = "1.6.0")]
fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
where P::Searcher: ReverseSearcher<'a>;
#[stable(feature = "core", since = "1.6.0")]
fn lines(&self) -> Lines;
#[stable(feature = "core", since = "1.6.0")]
#[rustc_deprecated(since = "1.6.0", reason = "use lines() instead now")]
#[allow(deprecated)]
fn lines_any(&self) -> LinesAny;
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output>;
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output>;
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output;
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output;
#[stable(feature = "core", since = "1.6.0")]
unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str;
#[stable(feature = "core", since = "1.6.0")]
unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str;
#[stable(feature = "core", since = "1.6.0")]
fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
#[stable(feature = "core", since = "1.6.0")]
fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
where P::Searcher: ReverseSearcher<'a>;
#[stable(feature = "core", since = "1.6.0")]
fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: DoubleEndedSearcher<'a>;
#[stable(feature = "core", since = "1.6.0")]
fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str;
#[stable(feature = "core", since = "1.6.0")]
fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: ReverseSearcher<'a>;
#[stable(feature = "is_char_boundary", since = "1.9.0")]
fn is_char_boundary(&self, index: usize) -> bool;
#[stable(feature = "core", since = "1.6.0")]
fn as_bytes(&self) -> &[u8];
#[stable(feature = "str_mut_extras", since = "1.20.0")]
unsafe fn as_bytes_mut(&mut self) -> &mut [u8];
#[stable(feature = "core", since = "1.6.0")]
fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
#[stable(feature = "core", since = "1.6.0")]
fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
where P::Searcher: ReverseSearcher<'a>;
fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
#[stable(feature = "core", since = "1.6.0")]
fn split_at(&self, mid: usize) -> (&str, &str);
#[stable(feature = "core", since = "1.6.0")]
fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str);
#[stable(feature = "core", since = "1.6.0")]
fn as_ptr(&self) -> *const u8;
#[stable(feature = "core", since = "1.6.0")]
fn len(&self) -> usize;
#[stable(feature = "core", since = "1.6.0")]
fn is_empty(&self) -> bool;
#[stable(feature = "core", since = "1.6.0")]
fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
#[stable(feature = "split_whitespace", since = "1.1.0")]
fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
#[stable(feature = "rust1", since = "1.0.0")]
fn trim(&self) -> &str;
#[stable(feature = "rust1", since = "1.0.0")]
fn trim_left(&self) -> &str;
#[stable(feature = "rust1", since = "1.0.0")]
fn trim_right(&self) -> &str;
}}
// truncate `&str` to length at most equal to `max`
// return `true` if it were truncated, and the new str.
fn truncate_to_char_boundary(s: &str, mut max: usize) -> (bool, &str) {
@ -2255,307 +2143,9 @@ fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
index, ch, char_range, s_trunc, ellipsis);
}
#[stable(feature = "core", since = "1.6.0")]
impl StrExt for str {
#[inline]
fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
pat.is_contained_in(self)
}
#[inline]
fn chars(&self) -> Chars {
Chars{iter: self.as_bytes().iter()}
}
#[inline]
fn bytes(&self) -> Bytes {
Bytes(self.as_bytes().iter().cloned())
}
#[inline]
fn char_indices(&self) -> CharIndices {
CharIndices { front_offset: 0, iter: self.chars() }
}
#[inline]
fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
Split(SplitInternal {
start: 0,
end: self.len(),
matcher: pat.into_searcher(self),
allow_trailing_empty: true,
finished: false,
})
}
#[inline]
fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
RSplit(self.split(pat).0)
}
#[inline]
fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> {
SplitN(SplitNInternal {
iter: self.split(pat).0,
count,
})
}
#[inline]
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
RSplitN(self.splitn(count, pat).0)
}
#[inline]
fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
SplitTerminator(SplitInternal {
allow_trailing_empty: false,
..self.split(pat).0
})
}
#[inline]
fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
RSplitTerminator(self.split_terminator(pat).0)
}
#[inline]
fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
Matches(MatchesInternal(pat.into_searcher(self)))
}
#[inline]
fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
RMatches(self.matches(pat).0)
}
#[inline]
fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
MatchIndices(MatchIndicesInternal(pat.into_searcher(self)))
}
#[inline]
fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
RMatchIndices(self.match_indices(pat).0)
}
#[inline]
fn lines(&self) -> Lines {
Lines(self.split_terminator('\n').map(LinesAnyMap))
}
#[inline]
#[allow(deprecated)]
fn lines_any(&self) -> LinesAny {
LinesAny(self.lines())
}
#[inline]
fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
i.get(self)
}
#[inline]
fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
i.get_mut(self)
}
#[inline]
unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
i.get_unchecked(self)
}
#[inline]
unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
i.get_unchecked_mut(self)
}
#[inline]
unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
(begin..end).get_unchecked(self)
}
#[inline]
unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
(begin..end).get_unchecked_mut(self)
}
#[inline]
fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
pat.is_prefix_of(self)
}
#[inline]
fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
where P::Searcher: ReverseSearcher<'a>
{
pat.is_suffix_of(self)
}
#[inline]
fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: DoubleEndedSearcher<'a>
{
let mut i = 0;
let mut j = 0;
let mut matcher = pat.into_searcher(self);
if let Some((a, b)) = matcher.next_reject() {
i = a;
j = b; // Remember earliest known match, correct it below if
// last match is different
}
if let Some((_, b)) = matcher.next_reject_back() {
j = b;
}
unsafe {
// Searcher is known to return valid indices
self.slice_unchecked(i, j)
}
}
#[inline]
fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
let mut i = self.len();
let mut matcher = pat.into_searcher(self);
if let Some((a, _)) = matcher.next_reject() {
i = a;
}
unsafe {
// Searcher is known to return valid indices
self.slice_unchecked(i, self.len())
}
}
#[inline]
fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: ReverseSearcher<'a>
{
let mut j = 0;
let mut matcher = pat.into_searcher(self);
if let Some((_, b)) = matcher.next_reject_back() {
j = b;
}
unsafe {
// Searcher is known to return valid indices
self.slice_unchecked(0, j)
}
}
#[inline]
fn is_char_boundary(&self, index: usize) -> bool {
// 0 and len are always ok.
// Test for 0 explicitly so that it can optimize out the check
// easily and skip reading string data for that case.
if index == 0 || index == self.len() { return true; }
match self.as_bytes().get(index) {
None => false,
// This is bit magic equivalent to: b < 128 || b >= 192
Some(&b) => (b as i8) >= -0x40,
}
}
#[inline]
fn as_bytes(&self) -> &[u8] {
unsafe { &*(self as *const str as *const [u8]) }
}
#[inline]
unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
&mut *(self as *mut str as *mut [u8])
}
fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
pat.into_searcher(self).next_match().map(|(i, _)| i)
}
fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
where P::Searcher: ReverseSearcher<'a>
{
pat.into_searcher(self).next_match_back().map(|(i, _)| i)
}
fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
self.find(pat)
}
#[inline]
fn split_at(&self, mid: usize) -> (&str, &str) {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
unsafe {
(self.slice_unchecked(0, mid),
self.slice_unchecked(mid, self.len()))
}
} else {
slice_error_fail(self, 0, mid)
}
}
fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
let len = self.len();
let ptr = self.as_ptr() as *mut u8;
unsafe {
(from_raw_parts_mut(ptr, mid),
from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
}
} else {
slice_error_fail(self, 0, mid)
}
}
#[inline]
fn as_ptr(&self) -> *const u8 {
self as *const str as *const u8
}
#[inline]
fn len(&self) -> usize {
self.as_bytes().len()
}
#[inline]
fn is_empty(&self) -> bool { self.len() == 0 }
#[inline]
fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) }
#[inline]
fn split_whitespace(&self) -> SplitWhitespace {
SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) }
}
#[inline]
fn trim(&self) -> &str {
self.trim_matches(|c: char| c.is_whitespace())
}
#[inline]
fn trim_left(&self) -> &str {
self.trim_left_matches(|c: char| c.is_whitespace())
}
#[inline]
fn trim_right(&self) -> &str {
self.trim_right_matches(|c: char| c.is_whitespace())
}
}
// FIXME: remove (inline) this macro and the SliceExt trait
// when updating to a bootstrap compiler that has the new lang items.
#[cfg_attr(stage0, macro_export)]
#[unstable(feature = "core_str_ext", issue = "32110")]
macro_rules! str_core_methods { () => {
#[lang = "str"]
#[cfg(not(test))]
impl str {
/// Returns the length of `self`.
///
/// This length is in bytes, not [`char`]s or graphemes. In other words,
@ -2577,7 +2167,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn len(&self) -> usize {
StrExt::len(self)
self.as_bytes().len()
}
/// Returns `true` if `self` has a length of zero bytes.
@ -2596,7 +2186,7 @@ macro_rules! str_core_methods { () => {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_empty(&self) -> bool {
StrExt::is_empty(self)
self.len() == 0
}
/// Checks that `index`-th byte lies at the start and/or end of a
@ -2626,7 +2216,15 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "is_char_boundary", since = "1.9.0")]
#[inline]
pub fn is_char_boundary(&self, index: usize) -> bool {
StrExt::is_char_boundary(self, index)
// 0 and len are always ok.
// Test for 0 explicitly so that it can optimize out the check
// easily and skip reading string data for that case.
if index == 0 || index == self.len() { return true; }
match self.as_bytes().get(index) {
None => false,
// This is bit magic equivalent to: b < 128 || b >= 192
Some(&b) => (b as i8) >= -0x40,
}
}
/// Converts a string slice to a byte slice. To convert the byte slice back
@ -2645,7 +2243,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline(always)]
pub fn as_bytes(&self) -> &[u8] {
StrExt::as_bytes(self)
unsafe { &*(self as *const str as *const [u8]) }
}
/// Converts a mutable string slice to a mutable byte slice. To convert the
@ -2684,7 +2282,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "str_mut_extras", since = "1.20.0")]
#[inline(always)]
pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
StrExt::as_bytes_mut(self)
&mut *(self as *mut str as *mut [u8])
}
/// Converts a string slice to a raw pointer.
@ -2706,7 +2304,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn as_ptr(&self) -> *const u8 {
StrExt::as_ptr(self)
self as *const str as *const u8
}
/// Returns a subslice of `str`.
@ -2733,7 +2331,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
#[inline]
pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
StrExt::get(self, i)
i.get(self)
}
/// Returns a mutable subslice of `str`.
@ -2767,7 +2365,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
#[inline]
pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
StrExt::get_mut(self, i)
i.get_mut(self)
}
/// Returns a unchecked subslice of `str`.
@ -2799,7 +2397,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
#[inline]
pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
StrExt::get_unchecked(self, i)
i.get_unchecked(self)
}
/// Returns a mutable, unchecked subslice of `str`.
@ -2831,7 +2429,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
#[inline]
pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
StrExt::get_unchecked_mut(self, i)
i.get_unchecked_mut(self)
}
/// Creates a string slice from another string slice, bypassing safety
@ -2880,7 +2478,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
StrExt::slice_unchecked(self, begin, end)
(begin..end).get_unchecked(self)
}
/// Creates a string slice from another string slice, bypassing safety
@ -2910,7 +2508,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "str_slice_mut", since = "1.5.0")]
#[inline]
pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
StrExt::slice_mut_unchecked(self, begin, end)
(begin..end).get_unchecked_mut(self)
}
/// Divide one string slice into two at an index.
@ -2946,7 +2544,15 @@ macro_rules! str_core_methods { () => {
#[inline]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at(&self, mid: usize) -> (&str, &str) {
StrExt::split_at(self, mid)
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
unsafe {
(self.slice_unchecked(0, mid),
self.slice_unchecked(mid, self.len()))
}
} else {
slice_error_fail(self, 0, mid)
}
}
/// Divide one mutable string slice into two at an index.
@ -2983,7 +2589,17 @@ macro_rules! str_core_methods { () => {
#[inline]
#[stable(feature = "str_split_at", since = "1.4.0")]
pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
StrExt::split_at_mut(self, mid)
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(mid) {
let len = self.len();
let ptr = self.as_ptr() as *mut u8;
unsafe {
(from_raw_parts_mut(ptr, mid),
from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
}
} else {
slice_error_fail(self, 0, mid)
}
}
/// Returns an iterator over the [`char`]s of a string slice.
@ -3035,8 +2651,9 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn chars(&self) -> Chars {
StrExt::chars(self)
Chars{iter: self.as_bytes().iter()}
}
/// Returns an iterator over the [`char`]s of a string slice, and their
/// positions.
///
@ -3091,7 +2708,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn char_indices(&self) -> CharIndices {
StrExt::char_indices(self)
CharIndices { front_offset: 0, iter: self.chars() }
}
/// An iterator over the bytes of a string slice.
@ -3116,7 +2733,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn bytes(&self) -> Bytes {
StrExt::bytes(self)
Bytes(self.as_bytes().iter().cloned())
}
/// Split a string slice by whitespace.
@ -3156,7 +2773,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "split_whitespace", since = "1.1.0")]
#[inline]
pub fn split_whitespace(&self) -> SplitWhitespace {
StrExt::split_whitespace(self)
SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) }
}
/// An iterator over the lines of a string, as string slices.
@ -3198,7 +2815,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn lines(&self) -> Lines {
StrExt::lines(self)
Lines(self.split_terminator('\n').map(LinesAnyMap))
}
/// An iterator over the lines of a string.
@ -3207,7 +2824,7 @@ macro_rules! str_core_methods { () => {
#[inline]
#[allow(deprecated)]
pub fn lines_any(&self) -> LinesAny {
StrExt::lines_any(self)
LinesAny(self.lines())
}
/// Returns an iterator of `u16` over the string encoded as UTF-16.
@ -3226,7 +2843,7 @@ macro_rules! str_core_methods { () => {
/// ```
#[stable(feature = "encode_utf16", since = "1.8.0")]
pub fn encode_utf16(&self) -> EncodeUtf16 {
EncodeUtf16::new(self)
EncodeUtf16 { chars: self.chars(), extra: 0 }
}
/// Returns `true` if the given pattern matches a sub-slice of
@ -3247,7 +2864,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
StrExt::contains(self, pat)
pat.is_contained_in(self)
}
/// Returns `true` if the given pattern matches a prefix of this
@ -3267,7 +2884,7 @@ macro_rules! str_core_methods { () => {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
StrExt::starts_with(self, pat)
pat.is_prefix_of(self)
}
/// Returns `true` if the given pattern matches a suffix of this
@ -3289,7 +2906,7 @@ macro_rules! str_core_methods { () => {
pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
where P::Searcher: ReverseSearcher<'a>
{
StrExt::ends_with(self, pat)
pat.is_suffix_of(self)
}
/// Returns the byte index of the first character of this string slice that
@ -3337,7 +2954,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
StrExt::find(self, pat)
pat.into_searcher(self).next_match().map(|(i, _)| i)
}
/// Returns the byte index of the last character of this string slice that
@ -3384,7 +3001,7 @@ macro_rules! str_core_methods { () => {
pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
where P::Searcher: ReverseSearcher<'a>
{
StrExt::rfind(self, pat)
pat.into_searcher(self).next_match_back().map(|(i, _)| i)
}
/// An iterator over substrings of this string slice, separated by
@ -3496,7 +3113,13 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
StrExt::split(self, pat)
Split(SplitInternal {
start: 0,
end: self.len(),
matcher: pat.into_searcher(self),
allow_trailing_empty: true,
finished: false,
})
}
/// An iterator over substrings of the given string slice, separated by
@ -3548,7 +3171,7 @@ macro_rules! str_core_methods { () => {
pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
StrExt::rsplit(self, pat)
RSplit(self.split(pat).0)
}
/// An iterator over substrings of the given string slice, separated by
@ -3593,7 +3216,10 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
StrExt::split_terminator(self, pat)
SplitTerminator(SplitInternal {
allow_trailing_empty: false,
..self.split(pat).0
})
}
/// An iterator over substrings of `self`, separated by characters
@ -3639,7 +3265,7 @@ macro_rules! str_core_methods { () => {
pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
StrExt::rsplit_terminator(self, pat)
RSplitTerminator(self.split_terminator(pat).0)
}
/// An iterator over substrings of the given string slice, separated by a
@ -3690,7 +3316,10 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
StrExt::splitn(self, n, pat)
SplitN(SplitNInternal {
iter: self.split(pat).0,
count: n,
})
}
/// An iterator over substrings of this string slice, separated by a
@ -3740,7 +3369,7 @@ macro_rules! str_core_methods { () => {
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
StrExt::rsplitn(self, n, pat)
RSplitN(self.splitn(n, pat).0)
}
/// An iterator over the disjoint matches of a pattern within the given string
@ -3779,7 +3408,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "str_matches", since = "1.2.0")]
#[inline]
pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
StrExt::matches(self, pat)
Matches(MatchesInternal(pat.into_searcher(self)))
}
/// An iterator over the disjoint matches of a pattern within this string slice,
@ -3818,7 +3447,7 @@ macro_rules! str_core_methods { () => {
pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
StrExt::rmatches(self, pat)
RMatches(self.matches(pat).0)
}
/// An iterator over the disjoint matches of a pattern within this string
@ -3862,7 +3491,7 @@ macro_rules! str_core_methods { () => {
#[stable(feature = "str_match_indices", since = "1.5.0")]
#[inline]
pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
StrExt::match_indices(self, pat)
MatchIndices(MatchIndicesInternal(pat.into_searcher(self)))
}
/// An iterator over the disjoint matches of a pattern within `self`,
@ -3907,7 +3536,7 @@ macro_rules! str_core_methods { () => {
pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
StrExt::rmatch_indices(self, pat)
RMatchIndices(self.match_indices(pat).0)
}
/// Returns a string slice with leading and trailing whitespace removed.
@ -3926,7 +3555,7 @@ macro_rules! str_core_methods { () => {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim(&self) -> &str {
StrExt::trim(self)
self.trim_matches(|c: char| c.is_whitespace())
}
/// Returns a string slice with leading whitespace removed.
@ -3962,7 +3591,7 @@ macro_rules! str_core_methods { () => {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_left(&self) -> &str {
StrExt::trim_left(self)
self.trim_left_matches(|c: char| c.is_whitespace())
}
/// Returns a string slice with trailing whitespace removed.
@ -3998,7 +3627,7 @@ macro_rules! str_core_methods { () => {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_right(&self) -> &str {
StrExt::trim_right(self)
self.trim_right_matches(|c: char| c.is_whitespace())
}
/// Returns a string slice with all prefixes and suffixes that match a
@ -4030,7 +3659,21 @@ macro_rules! str_core_methods { () => {
pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: DoubleEndedSearcher<'a>
{
StrExt::trim_matches(self, pat)
let mut i = 0;
let mut j = 0;
let mut matcher = pat.into_searcher(self);
if let Some((a, b)) = matcher.next_reject() {
i = a;
j = b; // Remember earliest known match, correct it below if
// last match is different
}
if let Some((_, b)) = matcher.next_reject_back() {
j = b;
}
unsafe {
// Searcher is known to return valid indices
self.slice_unchecked(i, j)
}
}
/// Returns a string slice with all prefixes that match a pattern
@ -4061,7 +3704,15 @@ macro_rules! str_core_methods { () => {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
StrExt::trim_left_matches(self, pat)
let mut i = self.len();
let mut matcher = pat.into_searcher(self);
if let Some((a, _)) = matcher.next_reject() {
i = a;
}
unsafe {
// Searcher is known to return valid indices
self.slice_unchecked(i, self.len())
}
}
/// Returns a string slice with all suffixes that match a pattern
@ -4100,7 +3751,15 @@ macro_rules! str_core_methods { () => {
pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
where P::Searcher: ReverseSearcher<'a>
{
StrExt::trim_right_matches(self, pat)
let mut j = 0;
let mut matcher = pat.into_searcher(self);
if let Some((_, b)) = matcher.next_reject_back() {
j = b;
}
unsafe {
// Searcher is known to return valid indices
self.slice_unchecked(0, j)
}
}
/// Parses this string slice into another type.
@ -4150,7 +3809,7 @@ macro_rules! str_core_methods { () => {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
StrExt::parse(self)
FromStr::from_str(self)
}
/// Checks if all characters in this string are within the ASCII range.
@ -4220,16 +3879,8 @@ macro_rules! str_core_methods { () => {
let me = unsafe { self.as_bytes_mut() };
me.make_ascii_lowercase()
}
}}
#[lang = "str"]
#[cfg(not(test))]
#[cfg(not(stage0))]
impl str {
str_core_methods!();
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<[u8]> for str {
#[inline]
@ -4332,17 +3983,6 @@ pub struct EncodeUtf16<'a> {
extra: u16,
}
// FIXME: remove (inline) this method
// when updating to a bootstrap compiler that has the new lang items.
// For grepping purpose: #[cfg(stage0)]
impl<'a> EncodeUtf16<'a> {
#[unstable(feature = "core_str_ext", issue = "32110")]
#[doc(hidden)]
pub fn new(s: &'a str) -> Self {
EncodeUtf16 { chars: s.chars(), extra: 0 }
}
}
#[stable(feature = "collection_debug", since = "1.17.0")]
impl<'a> fmt::Debug for EncodeUtf16<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

View File

@ -41,7 +41,6 @@
#![feature(try_from)]
#![feature(try_trait)]
#![feature(exact_chunks)]
#![cfg_attr(stage0, feature(atomic_nand))]
#![feature(reverse_bits)]
#![feature(inclusive_range_methods)]
#![feature(iterator_find_map)]

View File

@ -98,7 +98,6 @@ mod tests {
}
#[test]
#[cfg(not(stage0))]
fn test_reverse_bits() {
assert_eq!(A.reverse_bits().reverse_bits(), A);
assert_eq!(B.reverse_bits().reverse_bits(), B);

View File

@ -46,7 +46,6 @@
#![feature(core_intrinsics)]
#![feature(drain_filter)]
#![feature(entry_or_default)]
#![cfg_attr(stage0, feature(dyn_trait))]
#![feature(from_ref)]
#![feature(fs_read_write)]
#![feature(iterator_find_map)]

View File

@ -240,11 +240,11 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
});
// Also dump the inference graph constraints as a graphviz file.
let _: io::Result<()> = do_catch! {{
let _: io::Result<()> = do catch {
let mut file =
pretty::create_dump_file(infcx.tcx, "regioncx.dot", None, "nll", &0, source)?;
regioncx.dump_graphviz(&mut file)?;
}};
};
}
fn dump_annotation<'a, 'gcx, 'tcx>(

View File

@ -24,7 +24,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
#![feature(const_fn)]
#![feature(core_intrinsics)]
#![feature(decl_macro)]
#![cfg_attr(stage0, feature(dyn_trait))]
#![feature(fs_read_write)]
#![feature(macro_vis_matcher)]
#![feature(exhaustive_patterns)]
@ -34,7 +33,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
#![feature(crate_visibility_modifier)]
#![feature(never_type)]
#![feature(specialization)]
#![cfg_attr(stage0, feature(try_trait))]
#![feature(try_trait)]
extern crate arena;
#[macro_use]
@ -54,16 +53,6 @@ extern crate log_settings;
extern crate rustc_apfloat;
extern crate byteorder;
#[cfg(stage0)]
macro_rules! do_catch {
($t:expr) => { (|| ::std::ops::Try::from_ok($t) )() }
}
#[cfg(not(stage0))]
macro_rules! do_catch {
($t:expr) => { do catch { $t } }
}
mod diagnostics;
mod borrow_check;

View File

@ -137,7 +137,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
) where
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
{
let _: io::Result<()> = do_catch! {{
let _: io::Result<()> = do catch {
let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?;
writeln!(file, "// MIR for `{}`", node_path)?;
writeln!(file, "// source = {:?}", source)?;
@ -150,14 +150,14 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
extra_data(PassWhere::BeforeCFG, &mut file)?;
write_mir_fn(tcx, source, mir, &mut extra_data, &mut file)?;
extra_data(PassWhere::AfterCFG, &mut file)?;
}};
};
if tcx.sess.opts.debugging_opts.dump_mir_graphviz {
let _: io::Result<()> = do_catch! {{
let _: io::Result<()> = do catch {
let mut file =
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?;
}};
};
}
}

View File

@ -71,8 +71,6 @@ This API is completely unstable and subject to change.
#![allow(non_camel_case_types)]
#![cfg_attr(stage0, feature(dyn_trait))]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(crate_visibility_modifier)]

View File

@ -13,8 +13,6 @@
html_root_url = "https://doc.rust-lang.org/nightly/",
html_playground_url = "https://play.rust-lang.org/")]
#![cfg_attr(stage0, feature(dyn_trait))]
#![feature(ascii_ctype)]
#![feature(rustc_private)]
#![feature(box_patterns)]

View File

@ -17,7 +17,6 @@
#[doc(inline)] pub use alloc_system::System;
#[doc(inline)] pub use core::alloc::*;
#[cfg(not(stage0))]
#[cfg(not(test))]
#[doc(hidden)]
#[lang = "oom"]
@ -43,13 +42,6 @@ pub mod __default_lib_allocator {
System.alloc(layout) as *mut u8
}
#[cfg(stage0)]
#[no_mangle]
#[rustc_std_internal_symbol]
pub unsafe extern fn __rdl_oom() -> ! {
super::oom()
}
#[no_mangle]
#[rustc_std_internal_symbol]
pub unsafe extern fn __rdl_dealloc(ptr: *mut u8,
@ -74,57 +66,4 @@ pub mod __default_lib_allocator {
let layout = Layout::from_size_align_unchecked(size, align);
System.alloc_zeroed(layout) as *mut u8
}
#[cfg(stage0)]
pub mod stage0 {
#[no_mangle]
#[rustc_std_internal_symbol]
pub unsafe extern fn __rdl_usable_size(_layout: *const u8,
_min: *mut usize,
_max: *mut usize) {
unimplemented!()
}
#[no_mangle]
#[rustc_std_internal_symbol]
pub unsafe extern fn __rdl_alloc_excess(_size: usize,
_align: usize,
_excess: *mut usize,
_err: *mut u8) -> *mut u8 {
unimplemented!()
}
#[no_mangle]
#[rustc_std_internal_symbol]
pub unsafe extern fn __rdl_realloc_excess(_ptr: *mut u8,
_old_size: usize,
_old_align: usize,
_new_size: usize,
_new_align: usize,
_excess: *mut usize,
_err: *mut u8) -> *mut u8 {
unimplemented!()
}
#[no_mangle]
#[rustc_std_internal_symbol]
pub unsafe extern fn __rdl_grow_in_place(_ptr: *mut u8,
_old_size: usize,
_old_align: usize,
_new_size: usize,
_new_align: usize) -> u8 {
unimplemented!()
}
#[no_mangle]
#[rustc_std_internal_symbol]
pub unsafe extern fn __rdl_shrink_in_place(_ptr: *mut u8,
_old_size: usize,
_old_align: usize,
_new_size: usize,
_new_align: usize) -> u8 {
unimplemented!()
}
}
}

View File

@ -18,15 +18,9 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#[cfg(not(test))]
#[cfg(stage0)]
use core::num::Float;
#[cfg(not(test))]
use intrinsics;
#[cfg(not(test))]
#[cfg(stage0)]
use num::FpCategory;
#[cfg(not(test))]
use sys::cmath;
#[stable(feature = "rust1", since = "1.0.0")]
@ -41,12 +35,8 @@ pub use core::f32::{MIN, MIN_POSITIVE, MAX};
pub use core::f32::consts;
#[cfg(not(test))]
#[cfg_attr(stage0, lang = "f32")]
#[cfg_attr(not(stage0), lang = "f32_runtime")]
#[lang = "f32_runtime"]
impl f32 {
#[cfg(stage0)]
f32_core_methods!();
/// Returns the largest integer less than or equal to a number.
///
/// # Examples

View File

@ -18,15 +18,9 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
#[cfg(not(test))]
#[cfg(stage0)]
use core::num::Float;
#[cfg(not(test))]
use intrinsics;
#[cfg(not(test))]
#[cfg(stage0)]
use num::FpCategory;
#[cfg(not(test))]
use sys::cmath;
#[stable(feature = "rust1", since = "1.0.0")]
@ -41,12 +35,8 @@ pub use core::f64::{MIN, MIN_POSITIVE, MAX};
pub use core::f64::consts;
#[cfg(not(test))]
#[cfg_attr(stage0, lang = "f64")]
#[cfg_attr(not(stage0), lang = "f64_runtime")]
#[lang = "f64_runtime"]
impl f64 {
#[cfg(stage0)]
f64_core_methods!();
/// Returns the largest integer less than or equal to a number.
///
/// # Examples

View File

@ -252,7 +252,6 @@
#![feature(collections_range)]
#![feature(compiler_builtins_lib)]
#![feature(const_fn)]
#![cfg_attr(stage0, feature(core_float))]
#![feature(core_intrinsics)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
@ -260,10 +259,8 @@
#![feature(fs_read_write)]
#![feature(fixed_size_array)]
#![feature(float_from_str_radix)]
#![cfg_attr(stage0, feature(float_internals))]
#![feature(fn_traits)]
#![feature(fnbox)]
#![cfg_attr(stage0, feature(generic_param_attrs))]
#![feature(hashmap_internals)]
#![feature(heap_api)]
#![feature(int_error_internals)]
@ -319,6 +316,7 @@
#![cfg_attr(test, feature(update_panic_count))]
#![cfg_attr(windows, feature(used))]
#![feature(doc_alias)]
#![feature(float_internals)]
#![default_lib_allocator]
@ -364,11 +362,6 @@ extern crate libc;
#[allow(unused_extern_crates)]
extern crate unwind;
// compiler-rt intrinsics
#[doc(masked)]
#[cfg(stage0)]
extern crate compiler_builtins;
// During testing, this crate is not actually the "real" std library, but rather
// it links to the real std library, which was compiled from this same source
// code. So any lang items std defines are conditionally excluded (or else they

View File

@ -45,17 +45,6 @@ impl State {
}
}
macro_rules! span_err_if_not_stage0 {
($cx:expr, $sp:expr, $code:ident, $text:tt) => {
#[cfg(not(stage0))] {
span_err!($cx, $sp, $code, $text)
}
#[cfg(stage0)] {
$cx.span_err($sp, $text)
}
}
}
const OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
@ -100,7 +89,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
if asm_str_style.is_some() {
// If we already have a string with instructions,
// ending up in Asm state again is an error.
span_err_if_not_stage0!(cx, sp, E0660, "malformed inline assembly");
span_err!(cx, sp, E0660, "malformed inline assembly");
return DummyResult::expr(sp);
}
// Nested parser, stop before the first colon (see above).
@ -153,7 +142,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
Some(Symbol::intern(&format!("={}", ch.as_str())))
}
_ => {
span_err_if_not_stage0!(cx, span, E0661,
span_err!(cx, span, E0661,
"output operand constraint lacks '=' or '+'");
None
}
@ -179,10 +168,10 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
let (constraint, _str_style) = panictry!(p.parse_str());
if constraint.as_str().starts_with("=") {
span_err_if_not_stage0!(cx, p.prev_span, E0662,
span_err!(cx, p.prev_span, E0662,
"input operand constraint contains '='");
} else if constraint.as_str().starts_with("+") {
span_err_if_not_stage0!(cx, p.prev_span, E0663,
span_err!(cx, p.prev_span, E0663,
"input operand constraint contains '+'");
}
@ -205,7 +194,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
if OPTIONS.iter().any(|&opt| s == opt) {
cx.span_warn(p.prev_span, "expected a clobber, found an option");
} else if s.as_str().starts_with("{") || s.as_str().ends_with("}") {
span_err_if_not_stage0!(cx, p.prev_span, E0664,
span_err!(cx, p.prev_span, E0664,
"clobber should not be surrounded by braces");
}

View File

@ -18,7 +18,7 @@
#![feature(decl_macro)]
#![feature(str_escape)]
#![cfg_attr(not(stage0), feature(rustc_diagnostic_macros))]
#![feature(rustc_diagnostic_macros)]
extern crate fmt_macros;
#[macro_use]
@ -29,7 +29,6 @@ extern crate rustc_data_structures;
extern crate rustc_errors as errors;
extern crate rustc_target;
#[cfg(not(stage0))]
mod diagnostics;
mod assert;

View File

@ -23,7 +23,7 @@
// of other runtime components (registered via yet another special image section).
#![feature(no_core, lang_items, optin_builtin_traits)]
#![crate_type="rlib"]
#![crate_type = "rlib"]
#![no_core]
#![allow(non_camel_case_types)]
@ -43,7 +43,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
drop_in_place(to_drop);
}
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
#[cfg(all(target_os = "windows", target_arch = "x86", target_env = "gnu"))]
pub mod eh_frames {
#[no_mangle]
#[link_section = ".eh_frame"]
@ -54,6 +54,21 @@ pub mod eh_frames {
// This is defined as `struct object` in $GCC/libgcc/unwind-dw2-fde.h.
static mut OBJ: [isize; 6] = [0; 6];
macro_rules! impl_copy {
($($t:ty)*) => {
$(
impl ::Copy for $t {}
)*
}
}
impl_copy! {
usize u8 u16 u32 u64 u128
isize i8 i16 i32 i64 i128
f32 f64
bool char
}
// Unwind info registration/deregistration routines.
// See the docs of `unwind` module in libstd.
extern "C" {
@ -63,14 +78,18 @@ pub mod eh_frames {
unsafe fn init() {
// register unwind info on module startup
rust_eh_register_frames(&__EH_FRAME_BEGIN__ as *const u8,
&mut OBJ as *mut _ as *mut u8);
rust_eh_register_frames(
&__EH_FRAME_BEGIN__ as *const u8,
&mut OBJ as *mut _ as *mut u8,
);
}
unsafe fn uninit() {
// unregister on shutdown
rust_eh_unregister_frames(&__EH_FRAME_BEGIN__ as *const u8,
&mut OBJ as *mut _ as *mut u8);
rust_eh_unregister_frames(
&__EH_FRAME_BEGIN__ as *const u8,
&mut OBJ as *mut _ as *mut u8,
);
}
// MSVC-specific init/uninit routine registration

View File

@ -4,7 +4,7 @@ name = "rustc-main"
version = "0.0.0"
[[bin]]
name = "rustc"
name = "rustc_binary"
path = "rustc.rs"
[dependencies]

View File

@ -12,7 +12,7 @@
# source tarball for a stable release you'll likely see `1.x.0` for rustc and
# `0.x.0` for Cargo where they were released on `date`.
date: 2018-04-24
date: 2018-05-10
rustc: beta
cargo: beta

View File

@ -7,7 +7,7 @@ authors = ["The Rust Project Developers"]
# the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
# rustdoc a different name.
[[bin]]
name = "rustdoc-tool-binary"
name = "rustdoc_tool_binary"
path = "main.rs"
[dependencies]