diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 2abd7231711f3..247b636c808ac 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -203,13 +203,15 @@ impl RawVec { /// /// # 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 diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 9f843a570990d..d876ab23653f3 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -117,6 +117,24 @@ impl NonNull { /// 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 NonNull { /// 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 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. /// diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index c98008688ab4f..ff343625a19ed 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -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 diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 392c815ef2803..3ce48ce8799de 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -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>(&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 diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index 675b82ceb775f..8eaf07e52d69a 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -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; } diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index e11afed668728..7bd71e120de40 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -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; diff --git a/src/librustc_error_codes/error_codes/E0271.md b/src/librustc_error_codes/error_codes/E0271.md index 31334069ed8a4..ddd245b1a2b1b 100644 --- a/src/librustc_error_codes/error_codes/E0271.md +++ b/src/librustc_error_codes/error_codes/E0271.md @@ -5,25 +5,6 @@ Erroneous code example: ```compile_fail,E0271 trait Trait { type AssociatedType; } -fn foo(t: T) where T: Trait { - 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) where T: Trait { // ~~~~~~~~ ~~~~~~~~~~~~~~~~~~ // | | @@ -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) where T: Trait { @@ -70,13 +49,17 @@ fn foo(t: T) where T: Trait { 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) where T: Trait { + println!("in foo"); } + +impl Trait for i8 { type AssociatedType = u32; } + +foo(3_i8); ``` diff --git a/src/librustc_error_codes/error_codes/E0502.md b/src/librustc_error_codes/error_codes/E0502.md index b90c59f580737..dc3ffdfddd9de 100644 --- a/src/librustc_error_codes/error_codes/E0502.md +++ b/src/librustc_error_codes/error_codes/E0502.md @@ -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); } ``` diff --git a/src/librustc_error_codes/error_codes/E0750.md b/src/librustc_error_codes/error_codes/E0750.md index e0cf56f716f9d..905e852f8d579 100644 --- a/src/librustc_error_codes/error_codes/E0750.md +++ b/src/librustc_error_codes/error_codes/E0750.md @@ -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. diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 077f6cf3ca484..31aba8aba2515 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -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 diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs index 51f135d376161..9c36d853ef78d 100644 --- a/src/tools/tidy/src/error_codes_check.rs +++ b/src/tools/tidy/src/error_codes_check.rs @@ -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,