diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs index 33e652856e8..70945a791f6 100644 --- a/src/liballoc/slice.rs +++ b/src/liballoc/slice.rs @@ -1782,16 +1782,10 @@ impl [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!(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index ea7a46f44ae..88bd0444233 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -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)] diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index afb149f2997..4cda1c8778a 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -755,6 +755,71 @@ impl 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 ops::Index for [T] diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 3b37031cf46..f8cff8b186c 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -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; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index de570956622..7ba60f62791 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -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(); diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index d43ab0d3713..d7657bae8c5 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -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, + lang_def_id2: Option, 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 } _ => { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 32f23e923d9..4acd12e5862 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -290,6 +290,7 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec