Move non-allocating [u8] inherent methods to libcore

Fixes #45803
This commit is contained in:
Simon Sapin 2018-04-07 11:45:22 +02:00
parent 572256772e
commit de8ed6a1d6
7 changed files with 101 additions and 56 deletions

View File

@ -1782,16 +1782,10 @@ impl<T> [T] {
}
}
#[lang = "slice_u8"]
#[cfg_attr(stage0, lang = "slice_u8")]
#[cfg_attr(not(stage0), lang = "slice_u8_alloc")]
#[cfg(not(test))]
impl [u8] {
/// Checks if all bytes in this slice are within the ASCII range.
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn is_ascii(&self) -> bool {
self.iter().all(|b| b.is_ascii())
}
/// Returns a vector containing a copy of this slice where each byte
/// is mapped to its ASCII upper case equivalent.
///
@ -1826,52 +1820,8 @@ impl [u8] {
me
}
/// Checks that two slices are an ASCII case-insensitive match.
///
/// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
/// but without allocating and copying temporaries.
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
self.len() == other.len() &&
self.iter().zip(other).all(|(a, b)| {
a.eq_ignore_ascii_case(b)
})
}
/// Converts this slice to its ASCII upper case equivalent in-place.
///
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
/// but non-ASCII letters are unchanged.
///
/// To return a new uppercased value without modifying the existing one, use
/// [`to_ascii_uppercase`].
///
/// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn make_ascii_uppercase(&mut self) {
for byte in self {
byte.make_ascii_uppercase();
}
}
/// Converts this slice to its ASCII lower case equivalent in-place.
///
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
/// but non-ASCII letters are unchanged.
///
/// To return a new lowercased value without modifying the existing one, use
/// [`to_ascii_lowercase`].
///
/// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn make_ascii_lowercase(&mut self) {
for byte in self {
byte.make_ascii_lowercase();
}
}
#[cfg(stage0)]
slice_u8_core_methods!();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -92,6 +92,7 @@
#![feature(rustc_attrs)]
#![feature(rustc_const_unstable)]
#![feature(simd_ffi)]
#![feature(core_slice_ext)]
#![feature(specialization)]
#![feature(staged_api)]
#![feature(stmt_expr_attributes)]

View File

@ -755,6 +755,71 @@ impl<T> SliceExt for [T] {
}
}
#[cfg_attr(stage0, macro_export)]
#[unstable(feature = "core_slice_ext", issue = "32110")]
macro_rules! slice_u8_core_methods { () => {
/// Checks if all bytes in this slice are within the ASCII range.
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn is_ascii(&self) -> bool {
self.iter().all(|b| b.is_ascii())
}
/// Checks that two slices are an ASCII case-insensitive match.
///
/// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
/// but without allocating and copying temporaries.
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool {
self.len() == other.len() &&
self.iter().zip(other).all(|(a, b)| {
a.eq_ignore_ascii_case(b)
})
}
/// Converts this slice to its ASCII upper case equivalent in-place.
///
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
/// but non-ASCII letters are unchanged.
///
/// To return a new uppercased value without modifying the existing one, use
/// [`to_ascii_uppercase`].
///
/// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn make_ascii_uppercase(&mut self) {
for byte in self {
byte.make_ascii_uppercase();
}
}
/// Converts this slice to its ASCII lower case equivalent in-place.
///
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
/// but non-ASCII letters are unchanged.
///
/// To return a new lowercased value without modifying the existing one, use
/// [`to_ascii_lowercase`].
///
/// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
#[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
#[inline]
pub fn make_ascii_lowercase(&mut self) {
for byte in self {
byte.make_ascii_lowercase();
}
}
}}
#[lang = "slice_u8"]
#[cfg(not(test))]
#[cfg(not(stage0))]
impl [u8] {
slice_u8_core_methods!();
}
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
impl<T, I> ops::Index<I> for [T]

View File

@ -214,6 +214,7 @@ language_item_table! {
StrImplItem, "str", str_impl;
SliceImplItem, "slice", slice_impl;
SliceU8ImplItem, "slice_u8", slice_u8_impl;
SliceU8AllocImplItem, "slice_u8_alloc", slice_u8_alloc_impl;
ConstPtrImplItem, "const_ptr", const_ptr_impl;
MutPtrImplItem, "mut_ptr", mut_ptr_impl;
I8ImplItem, "i8", i8_impl;

View File

@ -478,6 +478,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
let lang_def_id = lang_items.slice_u8_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
let lang_def_id = lang_items.slice_u8_alloc_impl();
self.assemble_inherent_impl_for_primitive(lang_def_id);
}
ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
let lang_def_id = lang_items.const_ptr_impl();

View File

@ -114,6 +114,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyChar => {
self.check_primitive_impl(def_id,
lang_items.char_impl(),
None,
"char",
"char",
item.span);
@ -121,6 +122,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyStr => {
self.check_primitive_impl(def_id,
lang_items.str_impl(),
None,
"str",
"str",
item.span);
@ -128,6 +130,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TySlice(slice_item) if slice_item == self.tcx.types.u8 => {
self.check_primitive_impl(def_id,
lang_items.slice_u8_impl(),
lang_items.slice_u8_alloc_impl(),
"slice_u8",
"[u8]",
item.span);
@ -135,6 +138,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TySlice(_) => {
self.check_primitive_impl(def_id,
lang_items.slice_impl(),
None,
"slice",
"[T]",
item.span);
@ -142,6 +146,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
self.check_primitive_impl(def_id,
lang_items.const_ptr_impl(),
None,
"const_ptr",
"*const T",
item.span);
@ -149,6 +154,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyRawPtr(ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
self.check_primitive_impl(def_id,
lang_items.mut_ptr_impl(),
None,
"mut_ptr",
"*mut T",
item.span);
@ -156,6 +162,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I8) => {
self.check_primitive_impl(def_id,
lang_items.i8_impl(),
None,
"i8",
"i8",
item.span);
@ -163,6 +170,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I16) => {
self.check_primitive_impl(def_id,
lang_items.i16_impl(),
None,
"i16",
"i16",
item.span);
@ -170,6 +178,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I32) => {
self.check_primitive_impl(def_id,
lang_items.i32_impl(),
None,
"i32",
"i32",
item.span);
@ -177,6 +186,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I64) => {
self.check_primitive_impl(def_id,
lang_items.i64_impl(),
None,
"i64",
"i64",
item.span);
@ -184,6 +194,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::I128) => {
self.check_primitive_impl(def_id,
lang_items.i128_impl(),
None,
"i128",
"i128",
item.span);
@ -191,6 +202,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyInt(ast::IntTy::Isize) => {
self.check_primitive_impl(def_id,
lang_items.isize_impl(),
None,
"isize",
"isize",
item.span);
@ -198,6 +210,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U8) => {
self.check_primitive_impl(def_id,
lang_items.u8_impl(),
None,
"u8",
"u8",
item.span);
@ -205,6 +218,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U16) => {
self.check_primitive_impl(def_id,
lang_items.u16_impl(),
None,
"u16",
"u16",
item.span);
@ -212,6 +226,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U32) => {
self.check_primitive_impl(def_id,
lang_items.u32_impl(),
None,
"u32",
"u32",
item.span);
@ -219,6 +234,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U64) => {
self.check_primitive_impl(def_id,
lang_items.u64_impl(),
None,
"u64",
"u64",
item.span);
@ -226,6 +242,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::U128) => {
self.check_primitive_impl(def_id,
lang_items.u128_impl(),
None,
"u128",
"u128",
item.span);
@ -233,6 +250,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyUint(ast::UintTy::Usize) => {
self.check_primitive_impl(def_id,
lang_items.usize_impl(),
None,
"usize",
"usize",
item.span);
@ -240,6 +258,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyFloat(ast::FloatTy::F32) => {
self.check_primitive_impl(def_id,
lang_items.f32_impl(),
None,
"f32",
"f32",
item.span);
@ -247,6 +266,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for InherentCollect<'a, 'tcx> {
ty::TyFloat(ast::FloatTy::F64) => {
self.check_primitive_impl(def_id,
lang_items.f64_impl(),
None,
"f64",
"f64",
item.span);
@ -305,11 +325,15 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> {
fn check_primitive_impl(&self,
impl_def_id: DefId,
lang_def_id: Option<DefId>,
lang_def_id2: Option<DefId>,
lang: &str,
ty: &str,
span: Span) {
match lang_def_id {
Some(lang_def_id) if lang_def_id == impl_def_id => {
match (lang_def_id, lang_def_id2) {
(Some(lang_def_id), _) if lang_def_id == impl_def_id => {
// OK
}
(_, Some(lang_def_id)) if lang_def_id == impl_def_id => {
// OK
}
_ => {

View File

@ -290,6 +290,7 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean:
lang_items.str_impl(),
lang_items.slice_impl(),
lang_items.slice_u8_impl(),
lang_items.slice_u8_alloc_impl(),
lang_items.const_ptr_impl(),
lang_items.mut_ptr_impl(),
];