@@ -618,6 +618,134 @@ impl<T> NonNull<[T]> {
618618 }
619619}
620620
621+ #[ cfg( not( bootstrap) ) ]
622+ impl NonNull < str > {
623+ /// Creates a non-null raw string slice from a thin pointer and a length.
624+ ///
625+ /// The `len` argument is the number of **bytes**, not the number of characters.
626+ ///
627+ /// This function is safe, but dereferencing the return value is unsafe.
628+ /// See the documentation of [`slice::from_raw_parts`] for slice safety requirements and [`str::from_utf8`] for string safety requirements.
629+ ///
630+ /// [`str::from_utf8`]: crate::str::from_utf8
631+ ///
632+ /// # Examples
633+ ///
634+ /// ```rust
635+ /// #![feature(nonnull_str_from_raw_parts)]
636+ ///
637+ /// use std::ptr::NonNull;
638+ ///
639+ /// // create a string slice pointer when starting out with a pointer to the first byte
640+ /// let mut x = [b'a', b'b', b'c'];
641+ /// let nonnull_pointer = NonNull::new(x.as_mut_ptr()).unwrap();
642+ /// let str = NonNull::str_from_raw_parts(nonnull_pointer, 3);
643+ /// assert_eq!(unsafe { str.as_ref() }, "abc");
644+ /// ```
645+ ///
646+ /// (Note that this example artificially demonstrates a use of this method,
647+ /// but `let str = NonNull::from(str::from_utf8_unchecked(&x[..]));` would be a better way to write code like this.)
648+ #[ unstable( feature = "nonnull_str_from_raw_parts" , issue = "none" ) ]
649+ #[ rustc_const_unstable( feature = "const_nonnull_str_from_raw_parts" , issue = "none" ) ]
650+ #[ inline]
651+ pub const fn str_from_raw_parts ( data : NonNull < u8 > , len : usize ) -> Self {
652+ // SAFETY: `data` is a `NonNull` pointer which is necessarily non-null
653+ unsafe { Self :: new_unchecked ( super :: str_from_raw_parts_mut ( data. as_ptr ( ) , len) ) }
654+ }
655+
656+ /// Returns the length of a non-null raw slice.
657+ ///
658+ /// The returned value is the number of **bytes**, not the number of characters.
659+ ///
660+ /// This function is safe, even when the non-null raw slice cannot be dereferenced to a slice
661+ /// because the pointer does not have a valid address.
662+ ///
663+ /// # Examples
664+ ///
665+ /// ```rust
666+ /// #![feature(str_ptr_len, nonnull_str_from_raw_parts)]
667+ /// use std::ptr::NonNull;
668+ ///
669+ /// let slice: NonNull<str> = NonNull::str_from_raw_parts(NonNull::dangling(), 3);
670+ /// assert_eq!(slice.len(), 3);
671+ /// ```
672+ #[ unstable( feature = "str_ptr_len" , issue = "none" ) ]
673+ #[ rustc_const_unstable( feature = "const_str_ptr_len" , issue = "none" ) ]
674+ #[ inline]
675+ pub const fn len ( self ) -> usize {
676+ self . as_ptr ( ) . len ( )
677+ }
678+
679+ /// Returns a non-null pointer to the string slice's buffer.
680+ ///
681+ /// # Examples
682+ ///
683+ /// ```rust
684+ /// #![feature(str_ptr_as_ptr, nonnull_str_from_raw_parts)]
685+ /// use std::ptr::NonNull;
686+ ///
687+ /// let str: NonNull<str> = NonNull::str_from_raw_parts(NonNull::dangling(), 3);
688+ /// assert_eq!(str.as_non_null_ptr(), NonNull::new(1 as *mut u8).unwrap());
689+ /// ```
690+ #[ inline]
691+ #[ unstable( feature = "str_ptr_as_ptr" , issue = "none" ) ]
692+ #[ rustc_const_unstable( feature = "str_ptr_as_ptr" , issue = "none" ) ]
693+ pub const fn as_non_null_ptr ( self ) -> NonNull < u8 > {
694+ // SAFETY: We know `self` is non-null.
695+ unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) . as_mut_ptr ( ) ) }
696+ }
697+
698+ /// Returns a raw pointer to the string slice's buffer.
699+ ///
700+ /// # Examples
701+ ///
702+ /// ```rust
703+ /// #![feature(str_ptr_as_ptr, nonnull_str_from_raw_parts)]
704+ /// use std::ptr::NonNull;
705+ ///
706+ /// let str: NonNull<str> = NonNull::str_from_raw_parts(NonNull::dangling(), 3);
707+ /// assert_eq!(str.as_mut_ptr(), 1 as *mut u8);
708+ /// ```
709+ #[ inline]
710+ #[ unstable( feature = "str_ptr_as_ptr" , issue = "none" ) ]
711+ #[ rustc_const_unstable( feature = "str_ptr_as_ptr" , issue = "none" ) ]
712+ pub const fn as_mut_ptr ( self ) -> * mut u8 {
713+ self . as_non_null_ptr ( ) . as_ptr ( )
714+ }
715+
716+ /// Returns a raw pointer to an element or substring, without doing bounds
717+ /// checking.
718+ ///
719+ /// Calling this method with an out-of-bounds index, index that does not lie on an UTF-8 sequence boundaries or when `self` is not dereferencable
720+ /// is *[undefined behavior]* even if the resulting pointer is not used.
721+ ///
722+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
723+ ///
724+ /// # Examples
725+ ///
726+ /// ```
727+ /// #![feature(str_ptr_get, str_ptr_as_ptr, nonnull_str_from_raw_parts)]
728+ /// use std::ptr::NonNull;
729+ ///
730+ /// let x = &mut [b'a', b'b', b'c'];
731+ /// let x = NonNull::str_from_raw_parts(NonNull::new(x.as_mut_ptr()).unwrap(), x.len());
732+ ///
733+ /// unsafe {
734+ /// assert_eq!(x.get_unchecked_mut(1..).as_mut_ptr(), x.as_non_null_ptr().as_ptr().add(1));
735+ /// }
736+ /// ```
737+ #[ unstable( feature = "str_ptr_get" , issue = "none" ) ]
738+ #[ inline]
739+ pub unsafe fn get_unchecked_mut < I > ( self , index : I ) -> NonNull < I :: Output >
740+ where
741+ I : SliceIndex < str > ,
742+ {
743+ // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
744+ // As a consequence, the resulting pointer cannot be null.
745+ unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) . get_unchecked_mut ( index) ) }
746+ }
747+ }
748+
621749#[ stable( feature = "nonnull" , since = "1.25.0" ) ]
622750impl < T : ?Sized > Clone for NonNull < T > {
623751 #[ inline]
0 commit comments