@@ -1813,12 +1813,190 @@ mod type_keyword {}
18131813
18141814#[ doc( keyword = "unsafe" ) ]
18151815//
1816- /// Code or interfaces whose [memory safety] cannot be verified by the type system.
1816+ /// Code or interfaces whose [memory safety] cannot be verified by the type
1817+ /// system.
1818+ ///
1819+ /// The `unsafe` keyword has two uses: to declare the existence of contracts the
1820+ /// compiler can't check (`unsafe fn` and `unsafe trait`), and to declare that a
1821+ /// programmer has checked that these contracts have been upheld (`unsafe {}`
1822+ /// and `unsafe impl`, but also `unsafe fn` -- see below). They are not mutually
1823+ /// exclusive, as can be seen in `unsafe fn`.
1824+ ///
1825+ /// # Unsafe abilities
1826+ ///
1827+ /// **No matter what, Safe Rust can't cause Undefined Behavior**. This is
1828+ /// referred to as [soundness]: a well-typed program actually has the desired
1829+ /// properties. The [Nomicon][nomicon-soundness] has a more detailed explanation
1830+ /// on the subject.
1831+ ///
1832+ /// To ensure soundness, Safe Rust is restricted enough that it can be
1833+ /// automatically checked. Sometimes, however, it is necessary to write code
1834+ /// that is correct for reasons which are too clever for the compiler to
1835+ /// understand. In those cases, you need to use Unsafe Rust.
1836+ ///
1837+ /// Here are the abilities Unsafe Rust has in addition to Safe Rust:
1838+ ///
1839+ /// - Dereference [raw pointers]
1840+ /// - Implement `unsafe` [`trait`]s
1841+ /// - Call `unsafe` functions
1842+ /// - Mutate [`static`]s (including [`extern`]al ones)
1843+ /// - Access fields of [`union`]s
1844+ ///
1845+ /// However, this extra power comes with extra responsibilities: it is now up to
1846+ /// you to ensure soundness. The `unsafe` keyword helps by clearly marking the
1847+ /// pieces of code that need to worry about this.
1848+ ///
1849+ /// ## The different meanings of `unsafe`
1850+ ///
1851+ /// Not all uses of `unsafe` are equivalent: some are here to mark the existence
1852+ /// of a contract the programmer must check, others are to say "I have checked
1853+ /// the contract, go ahead and do this". The following
1854+ /// [discussion on Rust Internals] has more in-depth explanations about this but
1855+ /// here is a summary of the main points:
1856+ ///
1857+ /// - `unsafe fn`: calling this function means abiding by a contract the
1858+ /// compiler cannot enforce.
1859+ /// - `unsafe trait`: implementing the [`trait`] means abiding by a
1860+ /// contract the compiler cannot enforce.
1861+ /// - `unsafe {}`: the contract necessary to call the operations inside the
1862+ /// block has been checked by the programmer and is guaranteed to be respected.
1863+ /// - `unsafe impl`: the contract necessary to implement the trait has been
1864+ /// checked by the programmer and is guaranteed to be respected.
1865+ ///
1866+ /// `unsafe fn` also acts like an `unsafe {}` block
1867+ /// around the code inside the function. This means it is not just a signal to
1868+ /// the caller, but also promises that the preconditions for the operations
1869+ /// inside the function are upheld. Mixing these two meanings can be confusing
1870+ /// and [proposal]s exist to use `unsafe {}` blocks inside such functions when
1871+ /// making `unsafe` operations.
1872+ ///
1873+ /// See the [Rustnomicon] and the [Reference] for more informations.
18171874///
1818- /// The documentation for this keyword is [not yet complete]. Pull requests welcome!
1875+ /// # Examples
1876+ ///
1877+ /// ## Marking elements as `unsafe`
1878+ ///
1879+ /// `unsafe` can be used on functions. Note that functions and statics declared
1880+ /// in [`extern`] blocks are implicitly marked as `unsafe` (but not functions
1881+ /// declared as `extern "something" fn ...`). Mutable statics are always unsafe,
1882+ /// wherever they are declared. Methods can also be declared as `unsafe`:
1883+ ///
1884+ /// ```rust
1885+ /// # #![allow(dead_code)]
1886+ /// static mut FOO: &str = "hello";
1887+ ///
1888+ /// unsafe fn unsafe_fn() {}
1889+ ///
1890+ /// extern "C" {
1891+ /// fn unsafe_extern_fn();
1892+ /// static BAR: *mut u32;
1893+ /// }
1894+ ///
1895+ /// trait SafeTraitWithUnsafeMethod {
1896+ /// unsafe fn unsafe_method(&self);
1897+ /// }
1898+ ///
1899+ /// struct S;
1900+ ///
1901+ /// impl S {
1902+ /// unsafe fn unsafe_method_on_struct() {}
1903+ /// }
1904+ /// ```
1905+ ///
1906+ /// Traits can also be declared as `unsafe`:
1907+ ///
1908+ /// ```rust
1909+ /// unsafe trait UnsafeTrait {}
1910+ /// ```
18191911///
1912+ /// Since `unsafe fn` and `unsafe trait` indicate that there is a safety
1913+ /// contract that the compiler cannot enforce, documenting it is important. The
1914+ /// standard library has many examples of this, like the following which is an
1915+ /// extract from [`Vec::set_len`]. The `# Safety` section explains the contract
1916+ /// that must be fulfilled to safely call the function.
1917+ ///
1918+ /// ```rust,ignore (stub-to-show-doc-example)
1919+ /// /// Forces the length of the vector to `new_len`.
1920+ /// ///
1921+ /// /// This is a low-level operation that maintains none of the normal
1922+ /// /// invariants of the type. Normally changing the length of a vector
1923+ /// /// is done using one of the safe operations instead, such as
1924+ /// /// `truncate`, `resize`, `extend`, or `clear`.
1925+ /// ///
1926+ /// /// # Safety
1927+ /// ///
1928+ /// /// - `new_len` must be less than or equal to `capacity()`.
1929+ /// /// - The elements at `old_len..new_len` must be initialized.
1930+ /// pub unsafe fn set_len(&mut self, new_len: usize)
1931+ /// ```
1932+ ///
1933+ /// ## Using `unsafe {}` blocks and `impl`s
1934+ ///
1935+ /// Performing `unsafe` operations requires an `unsafe {}` block:
1936+ ///
1937+ /// ```rust
1938+ /// # #![allow(dead_code)]
1939+ /// /// Dereference the given pointer.
1940+ /// ///
1941+ /// /// # Safety
1942+ /// ///
1943+ /// /// `ptr` must be aligned and must not be dangling.
1944+ /// unsafe fn deref_unchecked(ptr: *const i32) -> i32 {
1945+ /// *ptr
1946+ /// }
1947+ ///
1948+ /// let a = 3;
1949+ /// let b = &a as *const _;
1950+ /// // SAFETY: `a` has not been dropped and references are always aligned,
1951+ /// // so `b` is a valid address.
1952+ /// unsafe { assert_eq!(*b, deref_unchecked(b)); };
1953+ /// ```
1954+ ///
1955+ /// Traits marked as `unsafe` must be [`impl`]emented using `unsafe impl`. This
1956+ /// makes a guarantee to other `unsafe` code that the implementation satisfies
1957+ /// the trait's safety contract. The [Send] and [Sync] traits are examples of
1958+ /// this behaviour in the standard library.
1959+ ///
1960+ /// ```rust
1961+ /// /// Implementors of this trait must guarantee an element is always
1962+ /// /// accessible with index 3.
1963+ /// unsafe trait ThreeIndexable<T> {
1964+ /// /// Returns a reference to the element with index 3 in `&self`.
1965+ /// fn three(&self) -> &T;
1966+ /// }
1967+ ///
1968+ /// // The implementation of `ThreeIndexable` for `[T; 4]` is `unsafe`
1969+ /// // because the implementor must abide by a contract the compiler cannot
1970+ /// // check but as a programmer we know there will always be a valid element
1971+ /// // at index 3 to access.
1972+ /// unsafe impl<T> ThreeIndexable<T> for [T; 4] {
1973+ /// fn three(&self) -> &T {
1974+ /// // SAFETY: implementing the trait means there always is an element
1975+ /// // with index 3 accessible.
1976+ /// unsafe { self.get_unchecked(3) }
1977+ /// }
1978+ /// }
1979+ ///
1980+ /// let a = [1, 2, 4, 8];
1981+ /// assert_eq!(a.three(), &8);
1982+ /// ```
1983+ ///
1984+ /// [`extern`]: keyword.extern.html
1985+ /// [`trait`]: keyword.trait.html
1986+ /// [`static`]: keyword.static.html
1987+ /// [`union`]: keyword.union.html
1988+ /// [`impl`]: keyword.impl.html
1989+ /// [Send]: marker/trait.Send.html
1990+ /// [Sync]: marker/trait.Sync.html
1991+ /// [`Vec::set_len`]: vec/struct.Vec.html#method.set_len
1992+ /// [raw pointers]: ../reference/types/pointer.html
18201993/// [memory safety]: ../book/ch19-01-unsafe-rust.html
1821- /// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
1994+ /// [Rustnomicon]: ../nomicon/index.html
1995+ /// [nomicon-soundness]: ../nomicon/safe-unsafe-meaning.html
1996+ /// [soundness]: https://rust-lang.github.io/unsafe-code-guidelines/glossary.html#soundness-of-code--of-a-library
1997+ /// [Reference]: ../reference/unsafety.html
1998+ /// [proposal]: https://github.com/rust-lang/rfcs/pull/2585
1999+ /// [discussion on Rust Internals]: https://internals.rust-lang.org/t/what-does-unsafe-mean/6696
18222000mod unsafe_keyword { }
18232001
18242002#[ doc( keyword = "use" ) ]
0 commit comments