@@ -1813,12 +1813,190 @@ mod type_keyword {}
1813
1813
1814
1814
#[ doc( keyword = "unsafe" ) ]
1815
1815
//
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.
1817
1874
///
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
+ /// ```
1819
1911
///
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
1820
1993
/// [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
1822
2000
mod unsafe_keyword { }
1823
2001
1824
2002
#[ doc( keyword = "use" ) ]
0 commit comments