Auto merge of #75308 - JohnTitor:rollup-vnnny43, r=JohnTitor
Rollup of 15 pull requests Successful merges: - #74712 (Update E0271 explanation) - #74842 (adjust remaining targets) - #75151 (Consistent variable name alloc for raw_vec) - #75162 (Fix the documentation for move about Fn traits implementations) - #75248 (Add `as_mut_ptr` to `NonNull<[T]>`) - #75262 (Show multi extension example for Path in doctests) - #75266 (Add safety section to `NonNull::as_*` method docs) - #75284 (Show relative example for Path ancestors) - #75285 (Separate example for Path strip_prefix) - #75287 (Show Path extension example change multi extension) - #75288 (Use assert! for Path exists example to check bool) - #75289 (Remove ambiguity from PathBuf pop example) - #75290 (fix `min_const_generics` version) - #75291 (Clean up E0750) - #75292 (Clean up E0502) Failed merges: r? @ghost
This commit is contained in:
commit
dcf107728c
@ -203,13 +203,15 @@ impl<T, A: AllocRef> RawVec<T, A> {
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The `ptr` must be allocated (via the given allocator `a`), and with the given `capacity`.
|
||||
/// The `ptr` must be allocated (via the given allocator `alloc`), and with the given
|
||||
/// `capacity`.
|
||||
/// The `capacity` cannot exceed `isize::MAX` for sized types. (only a concern on 32-bit
|
||||
/// systems). ZST vectors may have a capacity up to `usize::MAX`.
|
||||
/// If the `ptr` and `capacity` come from a `RawVec` created via `a`, then this is guaranteed.
|
||||
/// If the `ptr` and `capacity` come from a `RawVec` created via `alloc`, then this is
|
||||
/// guaranteed.
|
||||
#[inline]
|
||||
pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self {
|
||||
Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap: capacity, alloc: a }
|
||||
pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, alloc: A) -> Self {
|
||||
Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap: capacity, alloc }
|
||||
}
|
||||
|
||||
/// Gets a raw pointer to the start of the allocation. Note that this is
|
||||
|
@ -117,6 +117,24 @@ impl<T: ?Sized> NonNull<T> {
|
||||
/// The resulting lifetime is bound to self so this behaves "as if"
|
||||
/// it were actually an instance of T that is getting borrowed. If a longer
|
||||
/// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// When calling this method, you have to ensure that all of the following is true:
|
||||
/// - `self` is properly aligned
|
||||
/// - `self` must point to an initialized instance of T; in particular, the pointer must be
|
||||
/// "dereferencable" in the sense defined [here].
|
||||
///
|
||||
/// This applies even if the result of this method is unused!
|
||||
/// (The part about being initialized is not yet fully decided, but until
|
||||
/// it is, the only safe approach is to ensure that they are indeed initialized.)
|
||||
///
|
||||
/// Additionally, the lifetime of `self` does not necessarily reflect the actual
|
||||
/// lifetime of the data. *You* must enforce Rust's aliasing rules. In particular,
|
||||
/// for the duration of this lifetime, the memory the pointer points to must not
|
||||
/// get mutated (except inside `UnsafeCell`).
|
||||
///
|
||||
/// [here]: crate::ptr#safety
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[inline]
|
||||
pub unsafe fn as_ref(&self) -> &T {
|
||||
@ -130,6 +148,24 @@ impl<T: ?Sized> NonNull<T> {
|
||||
/// The resulting lifetime is bound to self so this behaves "as if"
|
||||
/// it were actually an instance of T that is getting borrowed. If a longer
|
||||
/// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// When calling this method, you have to ensure that all of the following is true:
|
||||
/// - `self` is properly aligned
|
||||
/// - `self` must point to an initialized instance of T; in particular, the pointer must be
|
||||
/// "dereferenceable" in the sense defined [here].
|
||||
///
|
||||
/// This applies even if the result of this method is unused!
|
||||
/// (The part about being initialized is not yet fully decided, but until
|
||||
/// it is the only safe approach is to ensure that they are indeed initialized.)
|
||||
///
|
||||
/// Additionally, the lifetime of `self` does not necessarily reflect the actual
|
||||
/// lifetime of the data. *You* must enforce Rust's aliasing rules. In particular,
|
||||
/// for the duration of this lifetime, the memory this pointer points to must not
|
||||
/// get accessed (read or written) through any other pointer.
|
||||
///
|
||||
/// [here]: crate::ptr#safety
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
#[inline]
|
||||
pub unsafe fn as_mut(&mut self) -> &mut T {
|
||||
@ -224,6 +260,24 @@ impl<T> NonNull<[T]> {
|
||||
unsafe { NonNull::new_unchecked(self.as_ptr().as_mut_ptr()) }
|
||||
}
|
||||
|
||||
/// Returns a raw pointer to the slice's buffer.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(slice_ptr_get, nonnull_slice_from_raw_parts)]
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3);
|
||||
/// assert_eq!(slice.as_mut_ptr(), 1 as *mut i8);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "slice_ptr_get", issue = "74265")]
|
||||
#[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
|
||||
pub const fn as_mut_ptr(self) -> *mut T {
|
||||
self.as_non_null_ptr().as_ptr()
|
||||
}
|
||||
|
||||
/// Returns a raw pointer to an element or subslice, without doing bounds
|
||||
/// checking.
|
||||
///
|
||||
|
@ -943,8 +943,7 @@ mod mod_keyword {}
|
||||
/// Capture a [closure]'s environment by value.
|
||||
///
|
||||
/// `move` converts any variables captured by reference or mutable reference
|
||||
/// to owned by value variables. The three [`Fn` trait]'s mirror the ways to capture
|
||||
/// variables, when `move` is used, the closures is represented by the `FnOnce` trait.
|
||||
/// to owned by value variables.
|
||||
///
|
||||
/// ```rust
|
||||
/// let capture = "hello";
|
||||
@ -953,6 +952,23 @@ mod mod_keyword {}
|
||||
/// };
|
||||
/// ```
|
||||
///
|
||||
/// Note: `move` closures may still implement [`Fn`] or [`FnMut`], even though
|
||||
/// they capture variables by `move`. This is because the traits implemented by
|
||||
/// a closure type are determined by *what* the closure does with captured
|
||||
/// values, not *how* it captures them:
|
||||
///
|
||||
/// ```rust
|
||||
/// fn create_fn() -> impl Fn() {
|
||||
/// let text = "Fn".to_owned();
|
||||
///
|
||||
/// move || println!("This is a: {}", text)
|
||||
/// }
|
||||
///
|
||||
/// let fn_plain = create_fn();
|
||||
///
|
||||
/// fn_plain();
|
||||
/// ```
|
||||
///
|
||||
/// `move` is often used when [threads] are involved.
|
||||
///
|
||||
/// ```rust
|
||||
|
@ -1232,10 +1232,10 @@ impl PathBuf {
|
||||
/// ```
|
||||
/// use std::path::{Path, PathBuf};
|
||||
///
|
||||
/// let mut p = PathBuf::from("/test/test.rs");
|
||||
/// let mut p = PathBuf::from("/spirited/away.rs");
|
||||
///
|
||||
/// p.pop();
|
||||
/// assert_eq!(Path::new("/test"), p);
|
||||
/// assert_eq!(Path::new("/spirited"), p);
|
||||
/// p.pop();
|
||||
/// assert_eq!(Path::new("/"), p);
|
||||
/// ```
|
||||
@ -1992,6 +1992,13 @@ impl Path {
|
||||
/// assert_eq!(ancestors.next(), Some(Path::new("/foo")));
|
||||
/// assert_eq!(ancestors.next(), Some(Path::new("/")));
|
||||
/// assert_eq!(ancestors.next(), None);
|
||||
///
|
||||
/// let mut ancestors = Path::new("../foo/bar").ancestors();
|
||||
/// assert_eq!(ancestors.next(), Some(Path::new("../foo/bar")));
|
||||
/// assert_eq!(ancestors.next(), Some(Path::new("../foo")));
|
||||
/// assert_eq!(ancestors.next(), Some(Path::new("..")));
|
||||
/// assert_eq!(ancestors.next(), Some(Path::new("")));
|
||||
/// assert_eq!(ancestors.next(), None);
|
||||
/// ```
|
||||
///
|
||||
/// [`None`]: ../../std/option/enum.Option.html#variant.None
|
||||
@ -2053,8 +2060,9 @@ impl Path {
|
||||
/// assert_eq!(path.strip_prefix("/test/"), Ok(Path::new("haha/foo.txt")));
|
||||
/// assert_eq!(path.strip_prefix("/test/haha/foo.txt"), Ok(Path::new("")));
|
||||
/// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new("")));
|
||||
/// assert_eq!(path.strip_prefix("test").is_ok(), false);
|
||||
/// assert_eq!(path.strip_prefix("/haha").is_ok(), false);
|
||||
///
|
||||
/// assert!(path.strip_prefix("test").is_err());
|
||||
/// assert!(path.strip_prefix("/haha").is_err());
|
||||
///
|
||||
/// let prefix = PathBuf::from("/test/");
|
||||
/// assert_eq!(path.strip_prefix(prefix), Ok(Path::new("haha/foo.txt")));
|
||||
@ -2140,9 +2148,8 @@ impl Path {
|
||||
/// ```
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// let path = Path::new("foo.rs");
|
||||
///
|
||||
/// assert_eq!("foo", path.file_stem().unwrap());
|
||||
/// assert_eq!("foo", Path::new("foo.rs").file_stem().unwrap());
|
||||
/// assert_eq!("foo.tar", Path::new("foo.tar.gz").file_stem().unwrap());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn file_stem(&self) -> Option<&OsStr> {
|
||||
@ -2166,9 +2173,8 @@ impl Path {
|
||||
/// ```
|
||||
/// use std::path::Path;
|
||||
///
|
||||
/// let path = Path::new("foo.rs");
|
||||
///
|
||||
/// assert_eq!("rs", path.extension().unwrap());
|
||||
/// assert_eq!("rs", Path::new("foo.rs").extension().unwrap());
|
||||
/// assert_eq!("gz", Path::new("foo.tar.gz").extension().unwrap());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn extension(&self) -> Option<&OsStr> {
|
||||
@ -2247,6 +2253,8 @@ impl Path {
|
||||
///
|
||||
/// let path = Path::new("foo.tar.gz");
|
||||
/// assert_eq!(path.with_extension(""), PathBuf::from("foo.tar"));
|
||||
/// assert_eq!(path.with_extension("xz"), PathBuf::from("foo.tar.xz"));
|
||||
/// assert_eq!(path.with_extension("").with_extension("txt"), PathBuf::from("foo.txt"));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn with_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
|
||||
@ -2473,7 +2481,7 @@ impl Path {
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::path::Path;
|
||||
/// assert_eq!(Path::new("does_not_exist.txt").exists(), false);
|
||||
/// assert!(!Path::new("does_not_exist.txt").exists());
|
||||
/// ```
|
||||
///
|
||||
/// # See Also
|
||||
|
@ -106,7 +106,7 @@ pub unsafe extern "C" fn runtime_entry(
|
||||
argv: *const *const c_char,
|
||||
env: *const *const c_char,
|
||||
) -> ! {
|
||||
use crate::sys::hermit::fast_thread_local::run_dtors;
|
||||
use crate::sys::hermit::thread_local_dtor::run_dtors;
|
||||
extern "C" {
|
||||
fn main(argc: isize, argv: *const *const c_char) -> i32;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use crate::ffi::CStr;
|
||||
use crate::io;
|
||||
use crate::mem;
|
||||
use crate::sys::hermit::abi;
|
||||
use crate::sys::hermit::fast_thread_local::run_dtors;
|
||||
use crate::sys::hermit::thread_local_dtor::run_dtors;
|
||||
use crate::time::Duration;
|
||||
|
||||
pub type Tid = abi::Tid;
|
||||
|
@ -5,25 +5,6 @@ Erroneous code example:
|
||||
```compile_fail,E0271
|
||||
trait Trait { type AssociatedType; }
|
||||
|
||||
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
|
||||
println!("in foo");
|
||||
}
|
||||
|
||||
impl Trait for i8 { type AssociatedType = &'static str; }
|
||||
|
||||
foo(3_i8);
|
||||
```
|
||||
|
||||
This is because of a type mismatch between the associated type of some
|
||||
trait (e.g., `T::Bar`, where `T` implements `trait Quux { type Bar; }`)
|
||||
and another type `U` that is required to be equal to `T::Bar`, but is not.
|
||||
Examples follow.
|
||||
|
||||
Here is that same example again, with some explanatory comments:
|
||||
|
||||
```compile_fail,E0271
|
||||
trait Trait { type AssociatedType; }
|
||||
|
||||
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
|
||||
// ~~~~~~~~ ~~~~~~~~~~~~~~~~~~
|
||||
// | |
|
||||
@ -56,11 +37,9 @@ foo(3_i8);
|
||||
// therefore the type-checker complains with this error code.
|
||||
```
|
||||
|
||||
To avoid those issues, you have to make the types match correctly.
|
||||
So we can fix the previous examples like this:
|
||||
|
||||
The issue can be resolved by changing the associated type:
|
||||
1) in the `foo` implementation:
|
||||
```
|
||||
// Basic Example:
|
||||
trait Trait { type AssociatedType; }
|
||||
|
||||
fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> {
|
||||
@ -70,13 +49,17 @@ fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> {
|
||||
impl Trait for i8 { type AssociatedType = &'static str; }
|
||||
|
||||
foo(3_i8);
|
||||
|
||||
// For-Loop Example:
|
||||
let vs = vec![1, 2, 3, 4];
|
||||
for v in &vs {
|
||||
match v {
|
||||
&1 => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2) in the `Trait` implementation for `i8`:
|
||||
```
|
||||
trait Trait { type AssociatedType; }
|
||||
|
||||
fn foo<T>(t: T) where T: Trait<AssociatedType = u32> {
|
||||
println!("in foo");
|
||||
}
|
||||
|
||||
impl Trait for i8 { type AssociatedType = u32; }
|
||||
|
||||
foo(3_i8);
|
||||
```
|
||||
|
@ -5,7 +5,7 @@ Erroneous code example:
|
||||
```compile_fail,E0502
|
||||
fn bar(x: &mut i32) {}
|
||||
fn foo(a: &mut i32) {
|
||||
let ref y = a; // a is borrowed as immutable.
|
||||
let y = &a; // a is borrowed as immutable.
|
||||
bar(a); // error: cannot borrow `*a` as mutable because `a` is also borrowed
|
||||
// as immutable
|
||||
println!("{}", y);
|
||||
@ -19,7 +19,7 @@ variable before trying to access it mutably:
|
||||
fn bar(x: &mut i32) {}
|
||||
fn foo(a: &mut i32) {
|
||||
bar(a);
|
||||
let ref y = a; // ok!
|
||||
let y = &a; // ok!
|
||||
println!("{}", y);
|
||||
}
|
||||
```
|
||||
|
@ -1,4 +1,18 @@
|
||||
Negative impls cannot be default impls. A default impl supplies
|
||||
default values for the items within to be used by other impls, whereas
|
||||
a negative impl declares that there are no other impls. These don't
|
||||
make sense to combine.
|
||||
A negative impl was made default impl.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0750
|
||||
# #![feature(negative_impls)]
|
||||
# #![feature(specialization)]
|
||||
trait MyTrait {
|
||||
type Foo;
|
||||
}
|
||||
|
||||
default impl !MyTrait for u32 {} // error!
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Negative impls cannot be default impls. A default impl supplies default values
|
||||
for the items within to be used by other impls, whereas a negative impl declares
|
||||
that there are no other impls. Combining it does not make sense.
|
||||
|
@ -580,7 +580,7 @@ declare_features! (
|
||||
(active, const_fn_transmute, "1.46.0", Some(53605), None),
|
||||
|
||||
/// The smallest useful subset of `const_generics`.
|
||||
(active, min_const_generics, "1.46.0", Some(74878), None),
|
||||
(active, min_const_generics, "1.47.0", Some(74878), None),
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// feature-group-end: actual feature gates
|
||||
|
@ -16,8 +16,7 @@ const EXEMPTED_FROM_TEST: &[&str] = &[
|
||||
];
|
||||
|
||||
// Some error codes don't have any tests apparently...
|
||||
const IGNORE_EXPLANATION_CHECK: &[&str] =
|
||||
&["E0570", "E0601", "E0602", "E0639", "E0729", "E0749", "E0750"];
|
||||
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0639", "E0729", "E0749"];
|
||||
|
||||
fn check_error_code_explanation(
|
||||
f: &str,
|
||||
|
Loading…
x
Reference in New Issue
Block a user