未验证 提交 e7e32611 编写于 作者: K kennytm 提交者: GitHub

Rollup merge of #50863 - oli-obk:const_len, r=SimonSapin,Gankro

Make `[T]::len` and `str::len` const fn

r? @Gankro
......@@ -119,6 +119,9 @@
#![feature(powerpc_target_feature)]
#![feature(mips_target_feature)]
#![feature(aarch64_target_feature)]
#![feature(const_slice_len)]
#![feature(const_str_as_bytes)]
#![feature(const_str_len)]
#[prelude_import]
#[allow(unused)]
......
......@@ -59,9 +59,16 @@
mod sort;
#[repr(C)]
struct Repr<T> {
pub data: *const T,
pub len: usize,
union Repr<'a, T: 'a> {
rust: &'a [T],
rust_mut: &'a mut [T],
raw: FatPtr<T>,
}
#[repr(C)]
struct FatPtr<T> {
data: *const T,
len: usize,
}
//
......@@ -119,9 +126,10 @@ impl<T> [T] {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn len(&self) -> usize {
#[rustc_const_unstable(feature = "const_slice_len")]
pub const fn len(&self) -> usize {
unsafe {
mem::transmute::<&[T], Repr<T>>(self).len
Repr { rust: self }.raw.len
}
}
......@@ -135,7 +143,8 @@ pub fn len(&self) -> usize {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn is_empty(&self) -> bool {
#[rustc_const_unstable(feature = "const_slice_len")]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
......@@ -418,7 +427,8 @@ pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn as_ptr(&self) -> *const T {
#[rustc_const_unstable(feature = "const_slice_as_ptr")]
pub const fn as_ptr(&self) -> *const T {
self as *const [T] as *const T
}
......@@ -3856,8 +3866,8 @@ fn may_have_side_effect() -> bool { false }
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] {
mem::transmute(Repr { data: p, len: len })
pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
Repr { raw: FatPtr { data, len } }.rust
}
/// Performs the same functionality as `from_raw_parts`, except that a mutable
......@@ -3869,8 +3879,8 @@ pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] {
/// `from_raw_parts`.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
mem::transmute(Repr { data: p, len: len })
pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
Repr { raw: FatPtr { data, len} }.rust_mut
}
/// Converts a reference to T into a slice of length 1 (without copying).
......
......@@ -2166,7 +2166,8 @@ impl str {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn len(&self) -> usize {
#[rustc_const_unstable(feature = "const_str_len")]
pub const fn len(&self) -> usize {
self.as_bytes().len()
}
......@@ -2185,7 +2186,8 @@ pub fn len(&self) -> usize {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_empty(&self) -> bool {
#[rustc_const_unstable(feature = "const_str_len")]
pub const fn is_empty(&self) -> bool {
self.len() == 0
}
......@@ -2242,8 +2244,15 @@ pub fn is_char_boundary(&self, index: usize) -> bool {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline(always)]
pub fn as_bytes(&self) -> &[u8] {
unsafe { &*(self as *const str as *const [u8]) }
#[rustc_const_unstable(feature="const_str_as_bytes")]
pub const fn as_bytes(&self) -> &[u8] {
unsafe {
union Slices<'a> {
str: &'a str,
slice: &'a [u8],
}
Slices { str: self }.slice
}
}
/// Converts a mutable string slice to a mutable byte slice. To convert the
......@@ -2303,7 +2312,8 @@ pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn as_ptr(&self) -> *const u8 {
#[rustc_const_unstable(feature = "const_str_as_ptr")]
pub const fn as_ptr(&self) -> *const u8 {
self as *const str as *const u8
}
......
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// run-pass
#![feature(const_str_len, const_str_as_bytes)]
const S: &str = "foo";
pub const B: &[u8] = S.as_bytes();
pub fn foo() -> [u8; S.len()] {
let mut buf = [0; S.len()];
for (i, &c) in S.as_bytes().iter().enumerate() {
buf[i] = c;
}
buf
}
fn main() {
assert_eq!(&foo()[..], b"foo");
assert_eq!(foo().len(), S.len());
const LEN: usize = S.len();
assert_eq!(LEN, S.len());
assert_eq!(B, foo());
assert_eq!(B, b"foo");
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册