@@ -634,6 +634,107 @@ impl<T> NonNull<[T]> {
634634 }
635635}
636636
637+ #[ cfg( not( bootstrap) ) ]
638+ impl NonNull < str > {
639+ /// Returns the length of a non-null raw slice.
640+ ///
641+ /// The returned value is the number of **bytes**, not the number of characters.
642+ ///
643+ /// This function is safe, even when the non-null raw slice cannot be dereferenced to a slice
644+ /// because the pointer does not have a valid address.
645+ ///
646+ /// # Examples
647+ ///
648+ /// ```rust
649+ /// #![feature(str_ptr_len)]
650+ /// use std::ptr::NonNull;
651+ ///
652+ /// let slice: NonNull<str> = NonNull::from("abc");
653+ /// assert_eq!(slice.len(), 3);
654+ /// ```
655+ #[ unstable( feature = "str_ptr_len" , issue = "71146" ) ]
656+ #[ rustc_const_unstable( feature = "const_str_ptr_len" , issue = "71146" ) ]
657+ #[ inline]
658+ pub const fn len ( self ) -> usize {
659+ self . as_ptr ( ) . len ( )
660+ }
661+
662+ /// Returns a non-null pointer to the string slice's buffer.
663+ ///
664+ /// # Examples
665+ ///
666+ /// ```rust
667+ /// #![feature(str_ptr_as_ptr)]
668+ /// use std::ptr::NonNull;
669+ ///
670+ /// let s: &str = "abc";
671+ /// let str: NonNull<str> = NonNull::from("abc");
672+ /// assert_eq!(str.as_non_null_ptr(), NonNull::new(s.as_ptr() as *mut u8).unwrap());
673+ /// ```
674+ #[ inline]
675+ #[ unstable( feature = "str_ptr_as_ptr" , issue = "74265" ) ]
676+ #[ rustc_const_unstable( feature = "str_ptr_as_ptr" , issue = "74265" ) ]
677+ pub const fn as_non_null_ptr ( self ) -> NonNull < u8 > {
678+ // SAFETY: We know `self` is non-null.
679+ unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) . as_mut_ptr ( ) ) }
680+ }
681+
682+ /// Returns a raw pointer to the string slice's buffer.
683+ ///
684+ /// # Examples
685+ ///
686+ /// ```rust
687+ /// #![feature(str_ptr_as_ptr)]
688+ /// use std::ptr::NonNull;
689+ ///
690+ /// let s: &str = "abc";
691+ /// let str: NonNull<str> = NonNull::from("abc");
692+ /// assert_eq!(str.as_mut_ptr(), s.as_ptr() as *mut u8);
693+ /// ```
694+ #[ inline]
695+ #[ unstable( feature = "str_ptr_as_ptr" , issue = "74265" ) ]
696+ #[ rustc_const_unstable( feature = "str_ptr_as_ptr" , issue = "74265" ) ]
697+ pub const fn as_mut_ptr ( self ) -> * mut u8 {
698+ self . as_non_null_ptr ( ) . as_ptr ( )
699+ }
700+
701+ /// Returns a raw pointer to an element or substring, without doing bounds
702+ /// checking.
703+ ///
704+ /// # Safety
705+ ///
706+ /// Calling this method with an out-of-bounds index or when `self` is not dereferenceable
707+ /// is *[undefined behavior]* even if the resulting pointer is not used.
708+ ///
709+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
710+ ///
711+ /// Note that calling this function with an index that does not lie on an UTF-8 sequence boundaries
712+ /// is safe, but dereferencing the pointer returned by such call is unsound.
713+ ///
714+ /// # Examples
715+ ///
716+ /// ```
717+ /// #![feature(str_ptr_get, str_ptr_as_ptr)]
718+ /// use std::ptr::NonNull;
719+ ///
720+ /// let x = NonNull::from("abc");
721+ ///
722+ /// unsafe {
723+ /// assert_eq!(x.get_unchecked_mut(1..).as_mut_ptr(), x.as_mut_ptr().add(1));
724+ /// }
725+ /// ```
726+ #[ unstable( feature = "str_ptr_get" , issue = "74265" ) ]
727+ #[ inline]
728+ pub unsafe fn get_unchecked_mut < I > ( self , index : I ) -> NonNull < I :: Output >
729+ where
730+ I : SliceIndex < str > ,
731+ {
732+ // SAFETY: the caller ensures that `self` is dereferencable and `index` in-bounds.
733+ // As a consequence, the resulting pointer cannot be null.
734+ unsafe { NonNull :: new_unchecked ( self . as_ptr ( ) . get_unchecked_mut ( index) ) }
735+ }
736+ }
737+
637738#[ stable( feature = "nonnull" , since = "1.25.0" ) ]
638739impl < T : ?Sized > Clone for NonNull < T > {
639740 #[ inline]
0 commit comments