Auto merge of #42780 - frewsxcv:rollup, r=frewsxcv
Rollup of 6 pull requests - Successful merges: #42271, #42717, #42728, #42749, #42756, #42772 - Failed merges:
This commit is contained in:
commit
445077963c
@ -0,0 +1,5 @@
|
||||
# `char_error_internals`
|
||||
|
||||
This feature is internal to the Rust compiler and is not intended for general use.
|
||||
|
||||
------------------------
|
@ -2124,10 +2124,12 @@ fn from(s: Box<[T]>) -> Vec<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "box_from_vec", since = "1.18.0")]
|
||||
impl<T> Into<Box<[T]>> for Vec<T> {
|
||||
fn into(self) -> Box<[T]> {
|
||||
self.into_boxed_slice()
|
||||
// note: test pulls in libstd, which causes errors here
|
||||
#[cfg(not(test))]
|
||||
#[stable(feature = "box_from_vec", since = "1.20.0")]
|
||||
impl<T> From<Vec<T>> for Box<[T]> {
|
||||
fn from(v: Vec<T>) -> Box<[T]> {
|
||||
v.into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
use convert::TryFrom;
|
||||
use fmt::{self, Write};
|
||||
use slice;
|
||||
use str::from_utf8_unchecked_mut;
|
||||
use str::{from_utf8_unchecked_mut, FromStr};
|
||||
use iter::FusedIterator;
|
||||
use mem::transmute;
|
||||
|
||||
@ -208,6 +208,63 @@ fn from(i: u8) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// An error which can be returned when parsing a char.
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ParseCharError {
|
||||
kind: CharErrorKind,
|
||||
}
|
||||
|
||||
impl ParseCharError {
|
||||
#[unstable(feature = "char_error_internals",
|
||||
reason = "this method should not be available publicly",
|
||||
issue = "0")]
|
||||
#[doc(hidden)]
|
||||
pub fn __description(&self) -> &str {
|
||||
match self.kind {
|
||||
CharErrorKind::EmptyString => {
|
||||
"cannot parse char from empty string"
|
||||
},
|
||||
CharErrorKind::TooManyChars => "too many characters in string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
enum CharErrorKind {
|
||||
EmptyString,
|
||||
TooManyChars,
|
||||
}
|
||||
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
impl fmt::Display for ParseCharError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.__description().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
impl FromStr for char {
|
||||
type Err = ParseCharError;
|
||||
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut chars = s.chars();
|
||||
match (chars.next(), chars.next()) {
|
||||
(None, _) => {
|
||||
Err(ParseCharError { kind: CharErrorKind::EmptyString })
|
||||
},
|
||||
(Some(c), None) => Ok(c),
|
||||
_ => {
|
||||
Err(ParseCharError { kind: CharErrorKind::TooManyChars })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
impl TryFrom<u32> for char {
|
||||
type Error = CharTryFromError;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
use std::{char,str};
|
||||
use std::convert::TryFrom;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn test_convert() {
|
||||
@ -28,6 +29,16 @@ fn test_convert() {
|
||||
assert!(char::try_from(0xFFFF_FFFF_u32).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
assert_eq!(char::from_str("a").unwrap(), 'a');
|
||||
assert_eq!(char::try_from("a").unwrap(), 'a');
|
||||
assert_eq!(char::from_str("\0").unwrap(), '\0');
|
||||
assert_eq!(char::from_str("\u{D7FF}").unwrap(), '\u{d7FF}');
|
||||
assert!(char::from_str("").is_err());
|
||||
assert!(char::from_str("abc").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_lowercase() {
|
||||
assert!('a'.is_lowercase());
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 03562b0cb26a00f49d4eaf18ca3e49608110b0c8
|
||||
Subproject commit 2015cf17a6a2a2280e93d9c57214ba92dbbaf42f
|
@ -8,6 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty;
|
||||
use rustc::ty::adjustment;
|
||||
use util::nodemap::FxHashMap;
|
||||
@ -144,20 +145,18 @@ fn check_stmt(&mut self, cx: &LateContext, s: &hir::Stmt) {
|
||||
ty::TyTuple(ref tys, _) if tys.is_empty() => return,
|
||||
ty::TyNever => return,
|
||||
ty::TyBool => return,
|
||||
ty::TyAdt(def, _) => {
|
||||
let attrs = cx.tcx.get_attrs(def.did);
|
||||
check_must_use(cx, &attrs, s.span)
|
||||
}
|
||||
ty::TyAdt(def, _) => check_must_use(cx, def.did, s.span),
|
||||
_ => false,
|
||||
};
|
||||
if !warned {
|
||||
cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
|
||||
}
|
||||
|
||||
fn check_must_use(cx: &LateContext, attrs: &[ast::Attribute], sp: Span) -> bool {
|
||||
for attr in attrs {
|
||||
fn check_must_use(cx: &LateContext, def_id: DefId, sp: Span) -> bool {
|
||||
for attr in cx.tcx.get_attrs(def_id).iter() {
|
||||
if attr.check_name("must_use") {
|
||||
let mut msg = "unused result which must be used".to_string();
|
||||
let mut msg = format!("unused `{}` which must be used",
|
||||
cx.tcx.item_path_str(def_id));
|
||||
// check for #[must_use="..."]
|
||||
if let Some(s) = attr.value_str() {
|
||||
msg.push_str(": ");
|
||||
|
@ -523,7 +523,10 @@ pub fn get_module(&mut self, def_id: DefId) -> Module<'a> {
|
||||
};
|
||||
|
||||
let kind = ModuleKind::Def(Def::Mod(def_id), name);
|
||||
self.arenas.alloc_module(ModuleData::new(parent, kind, def_id, Mark::root(), DUMMY_SP))
|
||||
let module =
|
||||
self.arenas.alloc_module(ModuleData::new(parent, kind, def_id, Mark::root(), DUMMY_SP));
|
||||
self.extern_module_map.insert((def_id, macros_only), module);
|
||||
module
|
||||
}
|
||||
|
||||
pub fn macro_def_scope(&mut self, expansion: Mark) -> Module<'a> {
|
||||
|
@ -438,6 +438,35 @@ pub struct JoinPathsError {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Joining paths on a Unix-like platform:
|
||||
///
|
||||
/// ```
|
||||
/// # if cfg!(unix) {
|
||||
/// use std::env;
|
||||
/// use std::ffi::OsString;
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// let paths = [Path::new("/bin"), Path::new("/usr/bin")];
|
||||
/// let path_os_string = env::join_paths(paths.iter()).unwrap();
|
||||
/// assert_eq!(path_os_string, OsString::from("/bin:/usr/bin"));
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Joining a path containing a colon on a Unix-like platform results in an error:
|
||||
///
|
||||
/// ```
|
||||
/// # if cfg!(unix) {
|
||||
/// use std::env;
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// let paths = [Path::new("/bin"), Path::new("/usr/bi:n")];
|
||||
/// assert!(env::join_paths(paths.iter()).is_err());
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// Using `env::join_paths` with `env::spit_paths` to append an item to the `PATH` environment
|
||||
/// variable:
|
||||
///
|
||||
/// ```
|
||||
/// use std::env;
|
||||
/// use std::path::PathBuf;
|
||||
|
@ -340,6 +340,14 @@ fn description(&self) -> &str {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
impl Error for char::ParseCharError {
|
||||
fn description(&self) -> &str {
|
||||
self.__description()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// copied from any.rs
|
||||
impl Error + 'static {
|
||||
/// Returns true if the boxed type is the same as `T`
|
||||
|
@ -152,6 +152,14 @@ pub struct CStr {
|
||||
/// in the vector provided.
|
||||
///
|
||||
/// [`CString::new`]: struct.CString.html#method.new
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ffi::{CString, NulError};
|
||||
///
|
||||
/// let _: NulError = CString::new(b"f\0oo".to_vec()).unwrap_err();
|
||||
/// ```
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct NulError(usize, Vec<u8>);
|
||||
@ -160,6 +168,14 @@ pub struct CStr {
|
||||
/// byte was found too early in the slice provided or one wasn't found at all.
|
||||
///
|
||||
/// [`CStr::from_bytes_with_nul`]: struct.CStr.html#method.from_bytes_with_nul
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ffi::{CStr, FromBytesWithNulError};
|
||||
///
|
||||
/// let _: FromBytesWithNulError = CStr::from_bytes_with_nul(b"f\0oo").unwrap_err();
|
||||
/// ```
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
||||
pub struct FromBytesWithNulError {
|
||||
@ -271,6 +287,27 @@ pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
|
||||
/// to undefined behavior or allocator corruption.
|
||||
///
|
||||
/// [`into_raw`]: #method.into_raw
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Create a `CString`, pass ownership to an `extern` function (via raw pointer), then retake
|
||||
/// ownership with `from_raw`:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::ffi::CString;
|
||||
/// use std::os::raw::c_char;
|
||||
///
|
||||
/// extern {
|
||||
/// fn some_extern_function(s: *mut c_char);
|
||||
/// }
|
||||
///
|
||||
/// let c_string = CString::new("Hello!").unwrap();
|
||||
/// let raw = c_string.into_raw();
|
||||
/// unsafe {
|
||||
/// some_extern_function(raw);
|
||||
/// let c_string = CString::from_raw(raw);
|
||||
/// }
|
||||
/// ```
|
||||
#[stable(feature = "cstr_memory", since = "1.4.0")]
|
||||
pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
|
||||
let len = libc::strlen(ptr) + 1; // Including the NUL byte
|
||||
@ -412,6 +449,18 @@ pub fn as_bytes_with_nul(&self) -> &[u8] {
|
||||
/// Extracts a [`CStr`] slice containing the entire string.
|
||||
///
|
||||
/// [`CStr`]: struct.CStr.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(as_c_str)]
|
||||
///
|
||||
/// use std::ffi::{CString, CStr};
|
||||
///
|
||||
/// let c_string = CString::new(b"foo".to_vec()).unwrap();
|
||||
/// let c_str = c_string.as_c_str();
|
||||
/// assert_eq!(c_str, CStr::from_bytes_with_nul(b"foo\0").unwrap());
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "as_c_str", issue = "40380")]
|
||||
pub fn as_c_str(&self) -> &CStr {
|
||||
@ -421,6 +470,18 @@ pub fn as_c_str(&self) -> &CStr {
|
||||
/// Converts this `CString` into a boxed [`CStr`].
|
||||
///
|
||||
/// [`CStr`]: struct.CStr.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(into_boxed_c_str)]
|
||||
///
|
||||
/// use std::ffi::{CString, CStr};
|
||||
///
|
||||
/// let c_string = CString::new(b"foo".to_vec()).unwrap();
|
||||
/// let boxed = c_string.into_boxed_c_str();
|
||||
/// assert_eq!(&*boxed, CStr::from_bytes_with_nul(b"foo\0").unwrap());
|
||||
/// ```
|
||||
#[unstable(feature = "into_boxed_c_str", issue = "40380")]
|
||||
pub fn into_boxed_c_str(self) -> Box<CStr> {
|
||||
unsafe { mem::transmute(self.into_inner()) }
|
||||
@ -708,6 +769,24 @@ pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
|
||||
/// let cstr = CStr::from_bytes_with_nul(b"hello\0");
|
||||
/// assert!(cstr.is_ok());
|
||||
/// ```
|
||||
///
|
||||
/// Creating a `CStr` without a trailing nul byte is an error:
|
||||
///
|
||||
/// ```
|
||||
/// use std::ffi::CStr;
|
||||
///
|
||||
/// let c_str = CStr::from_bytes_with_nul(b"hello");
|
||||
/// assert!(c_str.is_err());
|
||||
/// ```
|
||||
///
|
||||
/// Creating a `CStr` with an interior nul byte is an error:
|
||||
///
|
||||
/// ```
|
||||
/// use std::ffi::CStr;
|
||||
///
|
||||
/// let c_str = CStr::from_bytes_with_nul(b"he\0llo\0");
|
||||
/// assert!(c_str.is_err());
|
||||
/// ```
|
||||
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
|
||||
pub fn from_bytes_with_nul(bytes: &[u8])
|
||||
-> Result<&CStr, FromBytesWithNulError> {
|
||||
@ -800,6 +879,15 @@ pub fn as_ptr(&self) -> *const c_char {
|
||||
/// > **Note**: This method is currently implemented as a 0-cost cast, but
|
||||
/// > it is planned to alter its definition in the future to perform the
|
||||
/// > length calculation whenever this method is called.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ffi::CStr;
|
||||
///
|
||||
/// let c_str = CStr::from_bytes_with_nul(b"foo\0").unwrap();
|
||||
/// assert_eq!(c_str.to_bytes(), b"foo");
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn to_bytes(&self) -> &[u8] {
|
||||
@ -817,6 +905,15 @@ pub fn to_bytes(&self) -> &[u8] {
|
||||
/// > length calculation whenever this method is called.
|
||||
///
|
||||
/// [`to_bytes`]: #method.to_bytes
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ffi::CStr;
|
||||
///
|
||||
/// let c_str = CStr::from_bytes_with_nul(b"foo\0").unwrap();
|
||||
/// assert_eq!(c_str.to_bytes_with_nul(), b"foo\0");
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn to_bytes_with_nul(&self) -> &[u8] {
|
||||
@ -834,6 +931,15 @@ pub fn to_bytes_with_nul(&self) -> &[u8] {
|
||||
/// > check whenever this method is called.
|
||||
///
|
||||
/// [`&str`]: ../primitive.str.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ffi::CStr;
|
||||
///
|
||||
/// let c_str = CStr::from_bytes_with_nul(b"foo\0").unwrap();
|
||||
/// assert_eq!(c_str.to_str(), Ok("foo"));
|
||||
/// ```
|
||||
#[stable(feature = "cstr_to_str", since = "1.4.0")]
|
||||
pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
|
||||
// NB: When CStr is changed to perform the length check in .to_bytes()
|
||||
@ -857,6 +963,31 @@ pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
|
||||
///
|
||||
/// [`Cow`]: ../borrow/enum.Cow.html
|
||||
/// [`str`]: ../primitive.str.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Calling `to_string_lossy` on a `CStr` containing valid UTF-8:
|
||||
///
|
||||
/// ```
|
||||
/// use std::borrow::Cow;
|
||||
/// use std::ffi::CStr;
|
||||
///
|
||||
/// let c_str = CStr::from_bytes_with_nul(b"Hello World\0").unwrap();
|
||||
/// assert_eq!(c_str.to_string_lossy(), Cow::Borrowed("Hello World"));
|
||||
/// ```
|
||||
///
|
||||
/// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8:
|
||||
///
|
||||
/// ```
|
||||
/// use std::borrow::Cow;
|
||||
/// use std::ffi::CStr;
|
||||
///
|
||||
/// let c_str = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0").unwrap();
|
||||
/// assert_eq!(
|
||||
/// c_str.to_string_lossy(),
|
||||
/// Cow::Owned(String::from("Hello <20>World")) as Cow<str>
|
||||
/// );
|
||||
/// ```
|
||||
#[stable(feature = "cstr_to_str", since = "1.4.0")]
|
||||
pub fn to_string_lossy(&self) -> Cow<str> {
|
||||
String::from_utf8_lossy(self.to_bytes())
|
||||
@ -866,6 +997,18 @@ pub fn to_string_lossy(&self) -> Cow<str> {
|
||||
///
|
||||
/// [`Box`]: ../boxed/struct.Box.html
|
||||
/// [`CString`]: struct.CString.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(into_boxed_c_str)]
|
||||
///
|
||||
/// use std::ffi::CString;
|
||||
///
|
||||
/// let c_string = CString::new(b"foo".to_vec()).unwrap();
|
||||
/// let boxed = c_string.into_boxed_c_str();
|
||||
/// assert_eq!(boxed.into_c_string(), CString::new("foo").unwrap());
|
||||
/// ```
|
||||
#[unstable(feature = "into_boxed_c_str", issue = "40380")]
|
||||
pub fn into_c_string(self: Box<CStr>) -> CString {
|
||||
unsafe { mem::transmute(self) }
|
||||
|
@ -254,6 +254,7 @@
|
||||
#![feature(cfg_target_thread_local)]
|
||||
#![feature(cfg_target_vendor)]
|
||||
#![feature(char_escape_debug)]
|
||||
#![feature(char_error_internals)]
|
||||
#![feature(char_internals)]
|
||||
#![feature(collections_range)]
|
||||
#![feature(compiler_builtins_lib)]
|
||||
|
@ -38,6 +38,8 @@
|
||||
pub use core::char::{MAX, from_digit, from_u32, from_u32_unchecked};
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::char::{EscapeDebug, EscapeDefault, EscapeUnicode};
|
||||
#[stable(feature = "char_from_str", since = "1.19.0")]
|
||||
pub use core::char::ParseCharError;
|
||||
|
||||
// unstable reexports
|
||||
#[unstable(feature = "try_from", issue = "33417")]
|
||||
|
@ -26,8 +26,8 @@ fn foo<T>() -> T { panic!() }
|
||||
#[allow(unused_results)]
|
||||
fn test() {
|
||||
foo::<isize>();
|
||||
foo::<MustUse>(); //~ ERROR: unused result which must be used
|
||||
foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
|
||||
foo::<MustUse>(); //~ ERROR: unused `MustUse` which must be used
|
||||
foo::<MustUseMsg>(); //~ ERROR: unused `MustUseMsg` which must be used: some message
|
||||
}
|
||||
|
||||
#[allow(unused_results, unused_must_use)]
|
||||
@ -39,8 +39,8 @@ fn test2() {
|
||||
|
||||
fn main() {
|
||||
foo::<isize>(); //~ ERROR: unused result
|
||||
foo::<MustUse>(); //~ ERROR: unused result which must be used
|
||||
foo::<MustUseMsg>(); //~ ERROR: unused result which must be used: some message
|
||||
foo::<MustUse>(); //~ ERROR: unused `MustUse` which must be used
|
||||
foo::<MustUseMsg>(); //~ ERROR: unused `MustUseMsg` which must be used: some message
|
||||
|
||||
let _ = foo::<isize>();
|
||||
let _ = foo::<MustUse>();
|
||||
|
Loading…
Reference in New Issue
Block a user