7
7
//! [`std::str`]: ../../std/str/index.html
8
8
9
9
#![ stable( feature = "rust1" , since = "1.0.0" ) ]
10
+ #![ deny( unsafe_op_in_unsafe_fn) ]
10
11
11
12
use self :: pattern:: Pattern ;
12
13
use self :: pattern:: { DoubleEndedSearcher , ReverseSearcher , Searcher } ;
@@ -419,7 +420,11 @@ pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
419
420
#[ inline]
420
421
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
421
422
pub 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 ) }
423
428
}
424
429
425
430
/// Converts a slice of bytes to a string slice without checking
@@ -444,7 +449,11 @@ pub unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
444
449
#[ inline]
445
450
#[ stable( feature = "str_mut_extras" , since = "1.20.0" ) ]
446
451
pub 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 ) }
448
457
}
449
458
450
459
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
@@ -867,7 +876,9 @@ unsafe impl TrustedLen for Bytes<'_> {}
867
876
#[ doc( hidden) ]
868
877
unsafe impl TrustedRandomAccess for Bytes < ' _ > {
869
878
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) }
871
882
}
872
883
fn may_have_side_effect ( ) -> bool {
873
884
false
@@ -1904,15 +1915,27 @@ mod traits {
1904
1915
}
1905
1916
#[ inline]
1906
1917
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 ) } ;
1908
1921
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) ) }
1910
1929
}
1911
1930
#[ inline]
1912
1931
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 ) } ;
1914
1934
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) ) }
1916
1939
}
1917
1940
#[ inline]
1918
1941
fn index ( self , slice : & str ) -> & Self :: Output {
@@ -1974,12 +1997,21 @@ mod traits {
1974
1997
#[ inline]
1975
1998
unsafe fn get_unchecked ( self , slice : & str ) -> & Self :: Output {
1976
1999
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 ) ) }
1978
2007
}
1979
2008
#[ inline]
1980
2009
unsafe fn get_unchecked_mut ( self , slice : & mut str ) -> & mut Self :: Output {
1981
2010
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 ) ) }
1983
2015
}
1984
2016
#[ inline]
1985
2017
fn index ( self , slice : & str ) -> & Self :: Output {
@@ -2036,15 +2068,27 @@ mod traits {
2036
2068
}
2037
2069
#[ inline]
2038
2070
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 ) } ;
2040
2074
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) ) }
2042
2082
}
2043
2083
#[ inline]
2044
2084
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 ) } ;
2046
2087
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) ) }
2048
2092
}
2049
2093
#[ inline]
2050
2094
fn index ( self , slice : & str ) -> & Self :: Output {
@@ -2099,11 +2143,13 @@ mod traits {
2099
2143
}
2100
2144
#[ inline]
2101
2145
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) }
2103
2148
}
2104
2149
#[ inline]
2105
2150
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) }
2107
2153
}
2108
2154
#[ inline]
2109
2155
fn index ( self , slice : & str ) -> & Self :: Output {
@@ -2148,11 +2194,13 @@ mod traits {
2148
2194
}
2149
2195
#[ inline]
2150
2196
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) }
2152
2199
}
2153
2200
#[ inline]
2154
2201
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) }
2156
2204
}
2157
2205
#[ inline]
2158
2206
fn index ( self , slice : & str ) -> & Self :: Output {
@@ -2373,7 +2421,11 @@ impl str {
2373
2421
#[ stable( feature = "str_mut_extras" , since = "1.20.0" ) ]
2374
2422
#[ inline( always) ]
2375
2423
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 ] ) }
2377
2429
}
2378
2430
2379
2431
/// Converts a string slice to a raw pointer.
@@ -2509,7 +2561,8 @@ impl str {
2509
2561
#[ stable( feature = "str_checked_slicing" , since = "1.20.0" ) ]
2510
2562
#[ inline]
2511
2563
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 ) }
2513
2566
}
2514
2567
2515
2568
/// Returns a mutable, unchecked subslice of `str`.
@@ -2541,7 +2594,8 @@ impl str {
2541
2594
#[ stable( feature = "str_checked_slicing" , since = "1.20.0" ) ]
2542
2595
#[ inline]
2543
2596
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 ) }
2545
2599
}
2546
2600
2547
2601
/// Creates a string slice from another string slice, bypassing safety
@@ -2591,7 +2645,8 @@ impl str {
2591
2645
#[ rustc_deprecated( since = "1.29.0" , reason = "use `get_unchecked(begin..end)` instead" ) ]
2592
2646
#[ inline]
2593
2647
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 ) }
2595
2650
}
2596
2651
2597
2652
/// Creates a string slice from another string slice, bypassing safety
@@ -2622,7 +2677,8 @@ impl str {
2622
2677
#[ rustc_deprecated( since = "1.29.0" , reason = "use `get_unchecked_mut(begin..end)` instead" ) ]
2623
2678
#[ inline]
2624
2679
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 ) }
2626
2682
}
2627
2683
2628
2684
/// Divide one string slice into two at an index.
0 commit comments