diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index b60c55240140e..d7e789b5a11f7 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -42,11 +42,11 @@ This flag prints out various information about the compiler. ## `-g`: include debug information -A synonym for `-C debug-level=2`. +A synonym for `-C debuginfo=2`, for more see [here](codegen-options/index.html#debuginfo). ## `-O`: optimize your code -A synonym for `-C opt-level=2`. +A synonym for `-C opt-level=2`, for more see [here](codegen-options/index.html#opt-level). ## `-o`: filename of the output diff --git a/src/doc/rustc/src/lints/levels.md b/src/doc/rustc/src/lints/levels.md index 072c7585934e8..d315e0f8ca9e5 100644 --- a/src/doc/rustc/src/lints/levels.md +++ b/src/doc/rustc/src/lints/levels.md @@ -90,7 +90,9 @@ This lint level gives you that. 'forbid' is a special lint level that's stronger than 'deny'. It's the same as 'deny' in that a lint at this level will produce an error, but unlike the 'deny' level, the 'forbid' level can not be overridden to be anything lower -than an error. +than an error. However, lint levels may still be capped with `--cap-lints` +(see below) so `rustc --cap-lints warn` will make lints set to 'forbid' just +warn. ## Configuring warning levels diff --git a/src/doc/rustdoc/src/documentation-tests.md b/src/doc/rustdoc/src/documentation-tests.md index dcc13f53493f4..242167aa91786 100644 --- a/src/doc/rustdoc/src/documentation-tests.md +++ b/src/doc/rustdoc/src/documentation-tests.md @@ -236,6 +236,23 @@ appears to the reader as the initial idea but works with doc tests: /// ``` ``` +As of version 1.34.0, one can also omit the `fn main()`, but you will have to +disambiguate the error type: + +```ignore +/// ``` +/// use std::io; +/// let mut input = String::new(); +/// io::stdin().read_line(&mut input)?; +/// # Ok::<(), io:Error>(()) +/// ``` +``` + +This is an unfortunate consequence of the `?` operator adding an implicit +conversion, so type inference fails because the type is not unique. Please note +that you must write the `(())` in one sequence without intermediate whitespace +so that rustdoc understands you want an implicit `Result`-returning function. + ## Documenting macros Here’s an example of documenting a macro: diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index f6de7566be914..e6098b1b24cc0 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -962,221 +962,6 @@ extern "rust-intrinsic" { /// value is not necessarily valid to be used to actually access memory. pub fn arith_offset(dst: *const T, offset: isize) -> *const T; - /// Copies `count * size_of::()` bytes from `src` to `dst`. The source - /// and destination must *not* overlap. - /// - /// For regions of memory which might overlap, use [`copy`] instead. - /// - /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but - /// with the argument order swapped. - /// - /// [`copy`]: ./fn.copy.html - /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy - /// - /// # Safety - /// - /// Behavior is undefined if any of the following conditions are violated: - /// - /// * `src` must be [valid] for reads of `count * size_of::()` bytes. - /// - /// * `dst` must be [valid] for writes of `count * size_of::()` bytes. - /// - /// * Both `src` and `dst` must be properly aligned. - /// - /// * The region of memory beginning at `src` with a size of `count * - /// size_of::()` bytes must *not* overlap with the region of memory - /// beginning at `dst` with the same size. - /// - /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of - /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values - /// in the region beginning at `*src` and the region beginning at `*dst` can - /// [violate memory safety][read-ownership]. - /// - /// Note that even if the effectively copied size (`count * size_of::()`) is - /// `0`, the pointers must be non-NULL and properly aligned. - /// - /// [`Copy`]: ../marker/trait.Copy.html - /// [`read`]: ../ptr/fn.read.html - /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value - /// [valid]: ../ptr/index.html#safety - /// - /// # Examples - /// - /// Manually implement [`Vec::append`]: - /// - /// ``` - /// use std::ptr; - /// - /// /// Moves all the elements of `src` into `dst`, leaving `src` empty. - /// fn append(dst: &mut Vec, src: &mut Vec) { - /// let src_len = src.len(); - /// let dst_len = dst.len(); - /// - /// // Ensure that `dst` has enough capacity to hold all of `src`. - /// dst.reserve(src_len); - /// - /// unsafe { - /// // The call to offset is always safe because `Vec` will never - /// // allocate more than `isize::MAX` bytes. - /// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize); - /// let src_ptr = src.as_ptr(); - /// - /// // Truncate `src` without dropping its contents. We do this first, - /// // to avoid problems in case something further down panics. - /// src.set_len(0); - /// - /// // The two regions cannot overlap because mutable references do - /// // not alias, and two different vectors cannot own the same - /// // memory. - /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len); - /// - /// // Notify `dst` that it now holds the contents of `src`. - /// dst.set_len(dst_len + src_len); - /// } - /// } - /// - /// let mut a = vec!['r']; - /// let mut b = vec!['u', 's', 't']; - /// - /// append(&mut a, &mut b); - /// - /// assert_eq!(a, &['r', 'u', 's', 't']); - /// assert!(b.is_empty()); - /// ``` - /// - /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append - #[stable(feature = "rust1", since = "1.0.0")] - pub fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); - - /// Copies `count * size_of::()` bytes from `src` to `dst`. The source - /// and destination may overlap. - /// - /// If the source and destination will *never* overlap, - /// [`copy_nonoverlapping`] can be used instead. - /// - /// `copy` is semantically equivalent to C's [`memmove`], but with the argument - /// order swapped. Copying takes place as if the bytes were copied from `src` - /// to a temporary array and then copied from the array to `dst`. - /// - /// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html - /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove - /// - /// # Safety - /// - /// Behavior is undefined if any of the following conditions are violated: - /// - /// * `src` must be [valid] for reads of `count * size_of::()` bytes. - /// - /// * `dst` must be [valid] for writes of `count * size_of::()` bytes. - /// - /// * Both `src` and `dst` must be properly aligned. - /// - /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of - /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values - /// in the region beginning at `*src` and the region beginning at `*dst` can - /// [violate memory safety][read-ownership]. - /// - /// Note that even if the effectively copied size (`count * size_of::()`) is - /// `0`, the pointers must be non-NULL and properly aligned. - /// - /// [`Copy`]: ../marker/trait.Copy.html - /// [`read`]: ../ptr/fn.read.html - /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value - /// [valid]: ../ptr/index.html#safety - /// - /// # Examples - /// - /// Efficiently create a Rust vector from an unsafe buffer: - /// - /// ``` - /// use std::ptr; - /// - /// # #[allow(dead_code)] - /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { - /// let mut dst = Vec::with_capacity(elts); - /// dst.set_len(elts); - /// ptr::copy(ptr, dst.as_mut_ptr(), elts); - /// dst - /// } - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn copy(src: *const T, dst: *mut T, count: usize); - - /// Sets `count * size_of::()` bytes of memory starting at `dst` to - /// `val`. - /// - /// `write_bytes` is similar to C's [`memset`], but sets `count * - /// size_of::()` bytes to `val`. - /// - /// [`memset`]: https://en.cppreference.com/w/c/string/byte/memset - /// - /// # Safety - /// - /// Behavior is undefined if any of the following conditions are violated: - /// - /// * `dst` must be [valid] for writes of `count * size_of::()` bytes. - /// - /// * `dst` must be properly aligned. - /// - /// Additionally, the caller must ensure that writing `count * - /// size_of::()` bytes to the given region of memory results in a valid - /// value of `T`. Using a region of memory typed as a `T` that contains an - /// invalid value of `T` is undefined behavior. - /// - /// Note that even if the effectively copied size (`count * size_of::()`) is - /// `0`, the pointer must be non-NULL and properly aligned. - /// - /// [valid]: ../ptr/index.html#safety - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::ptr; - /// - /// let mut vec = vec![0u32; 4]; - /// unsafe { - /// let vec_ptr = vec.as_mut_ptr(); - /// ptr::write_bytes(vec_ptr, 0xfe, 2); - /// } - /// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]); - /// ``` - /// - /// Creating an invalid value: - /// - /// ``` - /// use std::ptr; - /// - /// let mut v = Box::new(0i32); - /// - /// unsafe { - /// // Leaks the previously held value by overwriting the `Box` with - /// // a null pointer. - /// ptr::write_bytes(&mut v as *mut Box, 0, 1); - /// } - /// - /// // At this point, using or dropping `v` results in undefined behavior. - /// // drop(v); // ERROR - /// - /// // Even leaking `v` "uses" it, and hence is undefined behavior. - /// // mem::forget(v); // ERROR - /// - /// // In fact, `v` is invalid according to basic type layout invariants, so *any* - /// // operation touching it is undefined behavior. - /// // let v2 = v; // ERROR - /// - /// unsafe { - /// // Let us instead put in a valid value - /// ptr::write(&mut v as *mut Box, Box::new(42i32)); - /// } - /// - /// // Now the box is fine - /// assert_eq!(*v, 42); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - pub fn write_bytes(dst: *mut T, val: u8, count: usize); - /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with /// a size of `count` * `size_of::()` and an alignment of /// `min_align_of::()` @@ -1524,3 +1309,252 @@ extern "rust-intrinsic" { /// Probably will never become stable. pub fn nontemporal_store(ptr: *mut T, val: T); } + +mod real_intrinsics { + extern "rust-intrinsic" { + /// Copies `count * size_of::()` bytes from `src` to `dst`. The source + /// and destination must *not* overlap. + /// For the full docs, see the stabilized wrapper [`copy_nonoverlapping`]. + /// + /// [`copy_nonoverlapping`]: ../../std/ptr/fn.copy_nonoverlapping.html + pub fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize); + + /// Copies `count * size_of::()` bytes from `src` to `dst`. The source + /// and destination may overlap. + /// For the full docs, see the stabilized wrapper [`copy`]. + /// + /// [`copy`]: ../../std/ptr/fn.copy.html + pub fn copy(src: *const T, dst: *mut T, count: usize); + + /// Sets `count * size_of::()` bytes of memory starting at `dst` to + /// `val`. + /// For the full docs, see the stabilized wrapper [`write_bytes`]. + /// + /// [`write_bytes`]: ../../std/ptr/fn.write_bytes.html + pub fn write_bytes(dst: *mut T, val: u8, count: usize); + } +} + +/// Copies `count * size_of::()` bytes from `src` to `dst`. The source +/// and destination must *not* overlap. +/// +/// For regions of memory which might overlap, use [`copy`] instead. +/// +/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but +/// with the argument order swapped. +/// +/// [`copy`]: ./fn.copy.html +/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy +/// +/// # Safety +/// +/// Behavior is undefined if any of the following conditions are violated: +/// +/// * `src` must be [valid] for reads of `count * size_of::()` bytes. +/// +/// * `dst` must be [valid] for writes of `count * size_of::()` bytes. +/// +/// * Both `src` and `dst` must be properly aligned. +/// +/// * The region of memory beginning at `src` with a size of `count * +/// size_of::()` bytes must *not* overlap with the region of memory +/// beginning at `dst` with the same size. +/// +/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of +/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values +/// in the region beginning at `*src` and the region beginning at `*dst` can +/// [violate memory safety][read-ownership]. +/// +/// Note that even if the effectively copied size (`count * size_of::()`) is +/// `0`, the pointers must be non-NULL and properly aligned. +/// +/// [`Copy`]: ../marker/trait.Copy.html +/// [`read`]: ../ptr/fn.read.html +/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value +/// [valid]: ../ptr/index.html#safety +/// +/// # Examples +/// +/// Manually implement [`Vec::append`]: +/// +/// ``` +/// use std::ptr; +/// +/// /// Moves all the elements of `src` into `dst`, leaving `src` empty. +/// fn append(dst: &mut Vec, src: &mut Vec) { +/// let src_len = src.len(); +/// let dst_len = dst.len(); +/// +/// // Ensure that `dst` has enough capacity to hold all of `src`. +/// dst.reserve(src_len); +/// +/// unsafe { +/// // The call to offset is always safe because `Vec` will never +/// // allocate more than `isize::MAX` bytes. +/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize); +/// let src_ptr = src.as_ptr(); +/// +/// // Truncate `src` without dropping its contents. We do this first, +/// // to avoid problems in case something further down panics. +/// src.set_len(0); +/// +/// // The two regions cannot overlap because mutable references do +/// // not alias, and two different vectors cannot own the same +/// // memory. +/// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len); +/// +/// // Notify `dst` that it now holds the contents of `src`. +/// dst.set_len(dst_len + src_len); +/// } +/// } +/// +/// let mut a = vec!['r']; +/// let mut b = vec!['u', 's', 't']; +/// +/// append(&mut a, &mut b); +/// +/// assert_eq!(a, &['r', 'u', 's', 't']); +/// assert!(b.is_empty()); +/// ``` +/// +/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append +#[stable(feature = "rust1", since = "1.0.0")] +#[inline] +pub unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize) { + real_intrinsics::copy_nonoverlapping(src, dst, count); +} + +/// Copies `count * size_of::()` bytes from `src` to `dst`. The source +/// and destination may overlap. +/// +/// If the source and destination will *never* overlap, +/// [`copy_nonoverlapping`] can be used instead. +/// +/// `copy` is semantically equivalent to C's [`memmove`], but with the argument +/// order swapped. Copying takes place as if the bytes were copied from `src` +/// to a temporary array and then copied from the array to `dst`. +/// +/// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html +/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove +/// +/// # Safety +/// +/// Behavior is undefined if any of the following conditions are violated: +/// +/// * `src` must be [valid] for reads of `count * size_of::()` bytes. +/// +/// * `dst` must be [valid] for writes of `count * size_of::()` bytes. +/// +/// * Both `src` and `dst` must be properly aligned. +/// +/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of +/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values +/// in the region beginning at `*src` and the region beginning at `*dst` can +/// [violate memory safety][read-ownership]. +/// +/// Note that even if the effectively copied size (`count * size_of::()`) is +/// `0`, the pointers must be non-NULL and properly aligned. +/// +/// [`Copy`]: ../marker/trait.Copy.html +/// [`read`]: ../ptr/fn.read.html +/// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value +/// [valid]: ../ptr/index.html#safety +/// +/// # Examples +/// +/// Efficiently create a Rust vector from an unsafe buffer: +/// +/// ``` +/// use std::ptr; +/// +/// # #[allow(dead_code)] +/// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { +/// let mut dst = Vec::with_capacity(elts); +/// dst.set_len(elts); +/// ptr::copy(ptr, dst.as_mut_ptr(), elts); +/// dst +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +#[inline] +pub unsafe fn copy(src: *const T, dst: *mut T, count: usize) { + real_intrinsics::copy(src, dst, count) +} + +/// Sets `count * size_of::()` bytes of memory starting at `dst` to +/// `val`. +/// +/// `write_bytes` is similar to C's [`memset`], but sets `count * +/// size_of::()` bytes to `val`. +/// +/// [`memset`]: https://en.cppreference.com/w/c/string/byte/memset +/// +/// # Safety +/// +/// Behavior is undefined if any of the following conditions are violated: +/// +/// * `dst` must be [valid] for writes of `count * size_of::()` bytes. +/// +/// * `dst` must be properly aligned. +/// +/// Additionally, the caller must ensure that writing `count * +/// size_of::()` bytes to the given region of memory results in a valid +/// value of `T`. Using a region of memory typed as a `T` that contains an +/// invalid value of `T` is undefined behavior. +/// +/// Note that even if the effectively copied size (`count * size_of::()`) is +/// `0`, the pointer must be non-NULL and properly aligned. +/// +/// [valid]: ../ptr/index.html#safety +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::ptr; +/// +/// let mut vec = vec![0u32; 4]; +/// unsafe { +/// let vec_ptr = vec.as_mut_ptr(); +/// ptr::write_bytes(vec_ptr, 0xfe, 2); +/// } +/// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]); +/// ``` +/// +/// Creating an invalid value: +/// +/// ``` +/// use std::ptr; +/// +/// let mut v = Box::new(0i32); +/// +/// unsafe { +/// // Leaks the previously held value by overwriting the `Box` with +/// // a null pointer. +/// ptr::write_bytes(&mut v as *mut Box, 0, 1); +/// } +/// +/// // At this point, using or dropping `v` results in undefined behavior. +/// // drop(v); // ERROR +/// +/// // Even leaking `v` "uses" it, and hence is undefined behavior. +/// // mem::forget(v); // ERROR +/// +/// // In fact, `v` is invalid according to basic type layout invariants, so *any* +/// // operation touching it is undefined behavior. +/// // let v2 = v; // ERROR +/// +/// unsafe { +/// // Let us instead put in a valid value +/// ptr::write(&mut v as *mut Box, Box::new(42i32)); +/// } +/// +/// // Now the box is fine +/// assert_eq!(*v, 42); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +#[inline] +pub unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { + real_intrinsics::write_bytes(dst, val, count) +} diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0b9fbc81da626..3d4dba550b0e8 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -534,13 +534,19 @@ pub fn make_test(s: &str, } } - if dont_insert_main || already_has_main { + // FIXME: This code cannot yet handle no_std test cases yet + if dont_insert_main || already_has_main || prog.contains("![no_std]") { prog.push_str(everything_else); } else { - prog.push_str("fn main() {\n"); + let returns_result = everything_else.trim_end().ends_with("(())"); + let (main_pre, main_post) = if returns_result { + ("fn main() { fn _inner() -> Result<(), impl core::fmt::Debug> {", + "}\n_inner().unwrap() }") + } else { + ("fn main() {\n", "\n}") + }; + prog.extend([main_pre, everything_else, main_post].iter().cloned()); line_offset += 1; - prog.push_str(everything_else); - prog.push_str("\n}"); } debug!("final doctest:\n{}", prog); diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index f1e8619fc8ffc..def51c79a8562 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -254,10 +254,13 @@ fn initial_buffer_size(file: &File) -> usize { /// ``` #[stable(feature = "fs_read_write_bytes", since = "1.26.0")] pub fn read>(path: P) -> io::Result> { - let mut file = File::open(path)?; - let mut bytes = Vec::with_capacity(initial_buffer_size(&file)); - file.read_to_end(&mut bytes)?; - Ok(bytes) + fn inner(path: &Path) -> io::Result> { + let mut file = File::open(path)?; + let mut bytes = Vec::with_capacity(initial_buffer_size(&file)); + file.read_to_end(&mut bytes)?; + Ok(bytes) + } + inner(path.as_ref()) } /// Read the entire contents of a file into a string. @@ -296,10 +299,13 @@ pub fn read>(path: P) -> io::Result> { /// ``` #[stable(feature = "fs_read_write", since = "1.26.0")] pub fn read_to_string>(path: P) -> io::Result { - let mut file = File::open(path)?; - let mut string = String::with_capacity(initial_buffer_size(&file)); - file.read_to_string(&mut string)?; - Ok(string) + fn inner(path: &Path) -> io::Result { + let mut file = File::open(path)?; + let mut string = String::with_capacity(initial_buffer_size(&file)); + file.read_to_string(&mut string)?; + Ok(string) + } + inner(path.as_ref()) } /// Write a slice as the entire contents of a file. @@ -326,7 +332,10 @@ pub fn read_to_string>(path: P) -> io::Result { /// ``` #[stable(feature = "fs_read_write_bytes", since = "1.26.0")] pub fn write, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> { - File::create(path)?.write_all(contents.as_ref()) + fn inner(path: &Path, contents: &[u8]) -> io::Result<()> { + File::create(path)?.write_all(contents) + } + inner(path.as_ref(), contents.as_ref()) } impl File { diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 0a9796d1a9c20..735714aca104c 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1145,6 +1145,32 @@ impl PathBuf { PathBuf { inner: OsString::new() } } + /// Creates a new `PathBuf` with a given capacity used to create the + /// internal [`OsString`]. See [`with_capacity`] defined on [`OsString`]. + /// + /// # Examples + /// + /// ``` + /// use std::path::PathBuf; + /// + /// let path = PathBuf::with_capacity(10); + /// let capacity = path.capacity(); + /// + /// // This push is done without reallocating + /// path.push(r"C:\"); + /// + /// assert_eq!(capacity, path.capacity()); + /// ``` + /// + /// [`with_capacity`]: ../ffi/struct.OsString.html#method.with_capacity + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn with_capacity(capacity: usize) -> PathBuf { + PathBuf { + inner: OsString::with_capacity(capacity) + } + } + /// Coerces to a [`Path`] slice. /// /// [`Path`]: struct.Path.html @@ -1373,6 +1399,60 @@ impl PathBuf { let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path; unsafe { Box::from_raw(rw) } } + + /// Invokes [`capacity`] on the underlying instance of [`OsString`]. + /// + /// [`capacity`]: ../ffi/struct.OsString.html#method.capacity + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn capacity(&self) -> usize { + self.inner.capacity() + } + + /// Invokes [`clear`] on the underlying instance of [`OsString`]. + /// + /// [`clear`]: ../ffi/struct.OsString.html#method.clear + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn clear(&mut self) { + self.inner.clear() + } + + /// Invokes [`reserve`] on the underlying instance of [`OsString`]. + /// + /// [`reserve`]: ../ffi/struct.OsString.html#method.reserve + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn reserve(&mut self, additional: usize) { + self.inner.reserve(additional) + } + + /// Invokes [`reserve_exact`] on the underlying instance of [`OsString`]. + /// + /// [`reserve_exact`]: ../ffi/struct.OsString.html#method.reserve_exact + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn reserve_exact(&mut self, additional: usize) { + self.inner.reserve_exact(additional) + } + + /// Invokes [`shrink_to_fit`] on the underlying instance of [`OsString`]. + /// + /// [`shrink_to_fit`]: ../ffi/struct.OsString.html#method.shrink_to_fit + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn shrink_to_fit(&mut self) { + self.inner.shrink_to_fit() + } + + /// Invokes [`shrink_to`] on the underlying instance of [`OsString`]. + /// + /// [`shrink_to`]: ../ffi/struct.OsString.html#method.shrink_to + /// [`OsString`]: ../ffi/struct.OsString.html + #[unstable(feature = "path_buf_capacity", issue = "58234")] + pub fn shrink_to(&mut self, min_capacity: usize) { + self.inner.shrink_to(min_capacity) + } } #[stable(feature = "box_from_path", since = "1.17.0")] diff --git a/src/test/rustdoc/process-termination.rs b/src/test/rustdoc/process-termination.rs new file mode 100644 index 0000000000000..32258792b6e8b --- /dev/null +++ b/src/test/rustdoc/process-termination.rs @@ -0,0 +1,24 @@ +// compile-flags:--test + +/// A check of using various process termination strategies +/// +/// # Examples +/// +/// ```rust +/// assert!(true); // this returns `()`, all is well +/// ``` +/// +/// You can also simply return `Ok(())`, but you'll need to disambiguate the +/// type using turbofish, because we cannot infer the type: +/// +/// ```rust +/// Ok::<(), &'static str>(()) +/// ``` +/// +/// You can err with anything that implements `Debug`: +/// +/// ```rust,should_panic +/// Err("This is returned from `main`, leading to panic")?; +/// Ok::<(), &'static str>(()) +/// ``` +pub fn check_process_termination() {} diff --git a/src/test/ui/specialization/issue-39448.rs b/src/test/ui/specialization/issue-39448.rs new file mode 100644 index 0000000000000..8ac6d8e9311fc --- /dev/null +++ b/src/test/ui/specialization/issue-39448.rs @@ -0,0 +1,50 @@ +#![feature(specialization)] + +// Regression test for a specialization-related ICE (#39448). + +trait A: Sized { + fn foo(self, _: Self) -> Self { + self + } +} + +impl A for u8 {} +impl A for u16 {} + +impl FromA for u16 { + fn from(x: u8) -> u16 { + x as u16 + } +} + +trait FromA { + fn from(T) -> Self; +} + +impl> FromA for U { + default fn from(x: T) -> Self { + ToA::to(x) + } +} + +trait ToA { + fn to(self) -> T; +} + +impl ToA for T +where + U: FromA, +{ + fn to(self) -> U { + U::from(self) + } +} + +#[allow(dead_code)] +fn foo(x: T, y: U) -> U { + x.foo(y.to()).to() //~ ERROR overflow evaluating the requirement +} + +fn main() { + let z = foo(8u8, 1u16); +} diff --git a/src/test/ui/specialization/issue-39448.stderr b/src/test/ui/specialization/issue-39448.stderr new file mode 100644 index 0000000000000..0b0fd2c4af591 --- /dev/null +++ b/src/test/ui/specialization/issue-39448.stderr @@ -0,0 +1,12 @@ +error[E0275]: overflow evaluating the requirement `T: FromA` + --> $DIR/issue-39448.rs:45:13 + | +LL | x.foo(y.to()).to() //~ ERROR overflow evaluating the requirement + | ^^ + | + = note: required because of the requirements on the impl of `FromA` for `T` + = note: required because of the requirements on the impl of `ToA` for `U` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0275`.