77//! [`std::str`]: ../../std/str/index.html
88
99#![ stable( feature = "rust1" , since = "1.0.0" ) ]
10+ #![ deny( unsafe_op_in_unsafe_fn) ]
1011
1112use self :: pattern:: Pattern ;
1213use self :: pattern:: { DoubleEndedSearcher , ReverseSearcher , Searcher } ;
@@ -419,7 +420,11 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
419420#[ inline]
420421#[ stable( feature = "rust1" , since = "1.0.0" ) ]
421422pub unsafe fn from_utf8_unchecked ( v : & [ u8 ] ) -> & str {
422- & * ( v as * const [ u8 ] as * const str )
423+ // SAFETY: the caller must guarantee that the bytes `v`
424+ // are valid UTF-8, thus the cast to `*const str` is safe.
425+ // Also, the pointer dereference is safe because that pointer
426+ // comes from a reference which is guaranteed to be valid for reads.
427+ unsafe { & * ( v as * const [ u8 ] as * const str ) }
423428}
424429
425430/// Converts a slice of bytes to a string slice without checking
@@ -444,7 +449,11 @@ pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
444449#[ inline]
445450#[ stable( feature = "str_mut_extras" , since = "1.20.0" ) ]
446451pub unsafe fn from_utf8_unchecked_mut ( v : & mut [ u8 ] ) -> & mut str {
447- & mut * ( v as * mut [ u8 ] as * mut str )
452+ // SAFETY: the caller must guarantee that the bytes `v`
453+ // are valid UTF-8, thus the cast to `*mut str` is safe.
454+ // Also, the pointer dereference is safe because that pointer
455+ // comes from a reference which is guaranteed to be valid for writes.
456+ unsafe { & mut * ( v as * mut [ u8 ] as * mut str ) }
448457}
449458
450459#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -867,7 +876,9 @@ unsafe impl TrustedLen for Bytes<'_> {}
867876#[ doc( hidden) ]
868877unsafe impl TrustedRandomAccess for Bytes < ' _ > {
869878 unsafe fn get_unchecked ( & mut self , i : usize ) -> u8 {
870- self . 0 . get_unchecked ( i)
879+ // SAFETY: the caller must uphold the safety contract
880+ // for `TrustedRandomAccess::get_unchecked`.
881+ unsafe { self . 0 . get_unchecked ( i) }
871882 }
872883 fn may_have_side_effect ( ) -> bool {
873884 false
@@ -1904,15 +1915,27 @@ mod traits {
19041915 }
19051916 #[ inline]
19061917 unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
1907- let ptr = slice. as_ptr ( ) . add ( self . start ) ;
1918+ // SAFETY: the caller guarantees that `self` is in bounds of `slice`
1919+ // which satisfies all the conditions for `add`.
1920+ let ptr = unsafe { slice. as_ptr ( ) . add ( self . start ) } ;
19081921 let len = self . end - self . start ;
1909- super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, len) )
1922+ // SAFETY: as the caller guarantees that `self` is in bounds of `slice`,
1923+ // we can safely construct a subslice with `from_raw_parts` and use it
1924+ // since we return a shared thus immutable reference.
1925+ // The call to `from_utf8_unchecked` is safe since the data comes from
1926+ // a `str` which is guaranteed to be valid utf8, since the caller
1927+ // must guarantee that `self.start` and `self.end` are char boundaries.
1928+ unsafe { super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, len) ) }
19101929 }
19111930 #[ inline]
19121931 unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1913- let ptr = slice. as_mut_ptr ( ) . add ( self . start ) ;
1932+ // SAFETY: see comments for `get_unchecked`.
1933+ let ptr = unsafe { slice. as_mut_ptr ( ) . add ( self . start ) } ;
19141934 let len = self . end - self . start ;
1915- super :: from_utf8_unchecked_mut ( slice:: from_raw_parts_mut ( ptr, len) )
1935+ // SAFETY: mostly identical to the comments for `get_unchecked`, except that we
1936+ // can return a mutable reference since the caller passed a mutable reference
1937+ // and is thus guaranteed to have exclusive write access to `slice`.
1938+ unsafe { super :: from_utf8_unchecked_mut ( slice:: from_raw_parts_mut ( ptr, len) ) }
19161939 }
19171940 #[ inline]
19181941 fn index ( self , slice : & str ) -> & Self :: Output {
@@ -1974,12 +1997,21 @@ mod traits {
19741997 #[ inline]
19751998 unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
19761999 let ptr = slice. as_ptr ( ) ;
1977- super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, self . end ) )
2000+ // SAFETY: as the caller guarantees that `self` is in bounds of `slice`,
2001+ // we can safely construct a subslice with `from_raw_parts` and use it
2002+ // since we return a shared thus immutable reference.
2003+ // The call to `from_utf8_unchecked` is safe since the data comes from
2004+ // a `str` which is guaranteed to be valid utf8, since the caller
2005+ // must guarantee that `self.end` is a char boundary.
2006+ unsafe { super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, self . end ) ) }
19782007 }
19792008 #[ inline]
19802009 unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
19812010 let ptr = slice. as_mut_ptr ( ) ;
1982- super :: from_utf8_unchecked_mut ( slice:: from_raw_parts_mut ( ptr, self . end ) )
2011+ // SAFETY: mostly identical to `get_unchecked`, except that we can safely
2012+ // return a mutable reference since the caller passed a mutable reference
2013+ // and is thus guaranteed to have exclusive write access to `slice`.
2014+ unsafe { super :: from_utf8_unchecked_mut ( slice:: from_raw_parts_mut ( ptr, self . end ) ) }
19832015 }
19842016 #[ inline]
19852017 fn index ( self , slice : & str ) -> & Self :: Output {
@@ -2036,15 +2068,27 @@ mod traits {
20362068 }
20372069 #[ inline]
20382070 unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
2039- let ptr = slice. as_ptr ( ) . add ( self . start ) ;
2071+ // SAFETY: the caller guarantees that `self` is in bounds of `slice`
2072+ // which satisfies all the conditions for `add`.
2073+ let ptr = unsafe { slice. as_ptr ( ) . add ( self . start ) } ;
20402074 let len = slice. len ( ) - self . start ;
2041- super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, len) )
2075+ // SAFETY: as the caller guarantees that `self` is in bounds of `slice`,
2076+ // we can safely construct a subslice with `from_raw_parts` and use it
2077+ // since we return a shared thus immutable reference.
2078+ // The call to `from_utf8_unchecked` is safe since the data comes from
2079+ // a `str` which is guaranteed to be valid utf8, since the caller
2080+ // must guarantee that `self.start` is a char boundary.
2081+ unsafe { super :: from_utf8_unchecked ( slice:: from_raw_parts ( ptr, len) ) }
20422082 }
20432083 #[ inline]
20442084 unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
2045- let ptr = slice. as_mut_ptr ( ) . add ( self . start ) ;
2085+ // SAFETY: identical to `get_unchecked`.
2086+ let ptr = unsafe { slice. as_mut_ptr ( ) . add ( self . start ) } ;
20462087 let len = slice. len ( ) - self . start ;
2047- super :: from_utf8_unchecked_mut ( slice:: from_raw_parts_mut ( ptr, len) )
2088+ // SAFETY: mostly identical to `get_unchecked`, except that we can safely
2089+ // return a mutable reference since the caller passed a mutable reference
2090+ // and is thus guaranteed to have exclusive write access to `slice`.
2091+ unsafe { super :: from_utf8_unchecked_mut ( slice:: from_raw_parts_mut ( ptr, len) ) }
20482092 }
20492093 #[ inline]
20502094 fn index ( self , slice : & str ) -> & Self :: Output {
@@ -2099,11 +2143,13 @@ mod traits {
20992143 }
21002144 #[ inline]
21012145 unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
2102- ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked ( slice)
2146+ // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
2147+ unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked ( slice) }
21032148 }
21042149 #[ inline]
21052150 unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
2106- ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked_mut ( slice)
2151+ // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
2152+ unsafe { ( * self . start ( ) ..self . end ( ) + 1 ) . get_unchecked_mut ( slice) }
21072153 }
21082154 #[ inline]
21092155 fn index ( self , slice : & str ) -> & Self :: Output {
@@ -2148,11 +2194,13 @@ mod traits {
21482194 }
21492195 #[ inline]
21502196 unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
2151- ( ..self . end + 1 ) . get_unchecked ( slice)
2197+ // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
2198+ unsafe { ( ..self . end + 1 ) . get_unchecked ( slice) }
21522199 }
21532200 #[ inline]
21542201 unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
2155- ( ..self . end + 1 ) . get_unchecked_mut ( slice)
2202+ // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
2203+ unsafe { ( ..self . end + 1 ) . get_unchecked_mut ( slice) }
21562204 }
21572205 #[ inline]
21582206 fn index ( self , slice : & str ) -> & Self :: Output {
@@ -2373,7 +2421,11 @@ impl str {
23732421 #[ stable( feature = "str_mut_extras" , since = "1.20.0" ) ]
23742422 #[ inline( always) ]
23752423 pub unsafe fn as_bytes_mut ( & mut self ) -> & mut [ u8 ] {
2376- & mut * ( self as * mut str as * mut [ u8 ] )
2424+ // SAFETY: the cast from `&str` to `&[u8]` is safe since `str`
2425+ // has the same layout as `&[u8]` (only libstd can make this guarantee).
2426+ // The pointer dereference is safe since it comes from a mutable reference which
2427+ // is guaranteed to be valid for writes.
2428+ unsafe { & mut * ( self as * mut str as * mut [ u8 ] ) }
23772429 }
23782430
23792431 /// Converts a string slice to a raw pointer.
@@ -2509,7 +2561,8 @@ impl str {
25092561 #[ stable( feature = "str_checked_slicing" , since = "1.20.0" ) ]
25102562 #[ inline]
25112563 pub unsafe fn get_unchecked < I : SliceIndex < str > > ( & self , i : I ) -> & I :: Output {
2512- i. get_unchecked ( self )
2564+ // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
2565+ unsafe { i. get_unchecked ( self ) }
25132566 }
25142567
25152568 /// Returns a mutable, unchecked subslice of `str`.
@@ -2541,7 +2594,8 @@ impl str {
25412594 #[ stable( feature = "str_checked_slicing" , since = "1.20.0" ) ]
25422595 #[ inline]
25432596 pub unsafe fn get_unchecked_mut < I : SliceIndex < str > > ( & mut self , i : I ) -> & mut I :: Output {
2544- i. get_unchecked_mut ( self )
2597+ // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
2598+ unsafe { i. get_unchecked_mut ( self ) }
25452599 }
25462600
25472601 /// Creates a string slice from another string slice, bypassing safety
@@ -2591,7 +2645,8 @@ impl str {
25912645 #[ rustc_deprecated( since = "1.29.0" , reason = "use `get_unchecked(begin..end)` instead" ) ]
25922646 #[ inline]
25932647 pub unsafe fn slice_unchecked ( & self , begin : usize , end : usize ) -> & str {
2594- ( begin..end) . get_unchecked ( self )
2648+ // SAFETY: the caller must uphold the safety contract for `get_unchecked`.
2649+ unsafe { ( begin..end) . get_unchecked ( self ) }
25952650 }
25962651
25972652 /// Creates a string slice from another string slice, bypassing safety
@@ -2622,7 +2677,8 @@ impl str {
26222677 #[ rustc_deprecated( since = "1.29.0" , reason = "use `get_unchecked_mut(begin..end)` instead" ) ]
26232678 #[ inline]
26242679 pub unsafe fn slice_mut_unchecked ( & mut self , begin : usize , end : usize ) -> & mut str {
2625- ( begin..end) . get_unchecked_mut ( self )
2680+ // SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`.
2681+ unsafe { ( begin..end) . get_unchecked_mut ( self ) }
26262682 }
26272683
26282684 /// Divide one string slice into two at an index.
0 commit comments