@@ -79,7 +79,7 @@ use crate::ops::{self, Deref};
7979use crate :: rc:: Rc ;
8080use crate :: str:: FromStr ;
8181use crate :: sync:: Arc ;
82- use crate :: sys:: path:: { MAIN_SEP_STR , is_sep_byte, is_verbatim_sep, parse_prefix} ;
82+ use crate :: sys:: path:: { HAS_PREFIXES , MAIN_SEP_STR , is_sep_byte, is_verbatim_sep, parse_prefix} ;
8383use crate :: { cmp, fmt, fs, io, sys} ;
8484
8585////////////////////////////////////////////////////////////////////////////////
@@ -643,17 +643,26 @@ impl<'a> Components<'a> {
643643 // how long is the prefix, if any?
644644 #[ inline]
645645 fn prefix_len ( & self ) -> usize {
646+ if !HAS_PREFIXES {
647+ return 0 ;
648+ }
646649 self . prefix . as_ref ( ) . map ( Prefix :: len) . unwrap_or ( 0 )
647650 }
648651
649652 #[ inline]
650653 fn prefix_verbatim ( & self ) -> bool {
654+ if !HAS_PREFIXES {
655+ return false ;
656+ }
651657 self . prefix . as_ref ( ) . map ( Prefix :: is_verbatim) . unwrap_or ( false )
652658 }
653659
654660 /// how much of the prefix is left from the point of view of iteration?
655661 #[ inline]
656662 fn prefix_remaining ( & self ) -> usize {
663+ if !HAS_PREFIXES {
664+ return 0 ;
665+ }
657666 if self . front == State :: Prefix { self . prefix_len ( ) } else { 0 }
658667 }
659668
@@ -707,7 +716,7 @@ impl<'a> Components<'a> {
707716 if self . has_physical_root {
708717 return true ;
709718 }
710- if let Some ( p) = self . prefix {
719+ if HAS_PREFIXES && let Some ( p) = self . prefix {
711720 if p. has_implicit_root ( ) {
712721 return true ;
713722 }
@@ -732,7 +741,7 @@ impl<'a> Components<'a> {
732741 // corresponding path component
733742 unsafe fn parse_single_component < ' b > ( & self , comp : & ' b [ u8 ] ) -> Option < Component < ' b > > {
734743 match comp {
735- b"." if self . prefix_verbatim ( ) => Some ( Component :: CurDir ) ,
744+ b"." if HAS_PREFIXES && self . prefix_verbatim ( ) => Some ( Component :: CurDir ) ,
736745 b"." => None , // . components are normalized away, except at
737746 // the beginning of a path, which is treated
738747 // separately via `include_cur_dir`
@@ -889,26 +898,24 @@ impl<'a> Iterator for Components<'a> {
889898 fn next ( & mut self ) -> Option < Component < ' a > > {
890899 while !self . finished ( ) {
891900 match self . front {
892- State :: Prefix if self . prefix_len ( ) > 0 => {
893- self . front = State :: StartDir ;
894- debug_assert ! ( self . prefix_len( ) <= self . path. len( ) ) ;
895- let raw = & self . path [ ..self . prefix_len ( ) ] ;
896- self . path = & self . path [ self . prefix_len ( ) ..] ;
897- return Some ( Component :: Prefix ( PrefixComponent {
898- raw : unsafe { OsStr :: from_encoded_bytes_unchecked ( raw) } ,
899- parsed : self . prefix . unwrap ( ) ,
900- } ) ) ;
901+ // most likely case first
902+ State :: Body if !self . path . is_empty ( ) => {
903+ let ( size, comp) = self . parse_next_component ( ) ;
904+ self . path = & self . path [ size..] ;
905+ if comp. is_some ( ) {
906+ return comp;
907+ }
901908 }
902- State :: Prefix => {
903- self . front = State :: StartDir ;
909+ State :: Body => {
910+ self . front = State :: Done ;
904911 }
905912 State :: StartDir => {
906913 self . front = State :: Body ;
907914 if self . has_physical_root {
908915 debug_assert ! ( !self . path. is_empty( ) ) ;
909916 self . path = & self . path [ 1 ..] ;
910917 return Some ( Component :: RootDir ) ;
911- } else if let Some ( p) = self . prefix {
918+ } else if HAS_PREFIXES && let Some ( p) = self . prefix {
912919 if p. has_implicit_root ( ) && !p. is_verbatim ( ) {
913920 return Some ( Component :: RootDir ) ;
914921 }
@@ -918,15 +925,19 @@ impl<'a> Iterator for Components<'a> {
918925 return Some ( Component :: CurDir ) ;
919926 }
920927 }
921- State :: Body if !self . path . is_empty ( ) => {
922- let ( size, comp) = self . parse_next_component ( ) ;
923- self . path = & self . path [ size..] ;
924- if comp. is_some ( ) {
925- return comp;
926- }
928+ _ if const { !HAS_PREFIXES } => unreachable ! ( ) ,
929+ State :: Prefix if self . prefix_len ( ) == 0 => {
930+ self . front = State :: StartDir ;
927931 }
928- State :: Body => {
929- self . front = State :: Done ;
932+ State :: Prefix => {
933+ self . front = State :: StartDir ;
934+ debug_assert ! ( self . prefix_len( ) <= self . path. len( ) ) ;
935+ let raw = & self . path [ ..self . prefix_len ( ) ] ;
936+ self . path = & self . path [ self . prefix_len ( ) ..] ;
937+ return Some ( Component :: Prefix ( PrefixComponent {
938+ raw : unsafe { OsStr :: from_encoded_bytes_unchecked ( raw) } ,
939+ parsed : self . prefix . unwrap ( ) ,
940+ } ) ) ;
930941 }
931942 State :: Done => unreachable ! ( ) ,
932943 }
@@ -964,6 +975,7 @@ impl<'a> DoubleEndedIterator for Components<'a> {
964975 return Some ( Component :: CurDir ) ;
965976 }
966977 }
978+ _ if !HAS_PREFIXES => unreachable ! ( ) ,
967979 State :: Prefix if self . prefix_len ( ) > 0 => {
968980 self . back = State :: Done ;
969981 return Some ( Component :: Prefix ( PrefixComponent {
@@ -3116,7 +3128,9 @@ impl Path {
31163128 path : self . as_u8_slice ( ) ,
31173129 prefix,
31183130 has_physical_root : has_physical_root ( self . as_u8_slice ( ) , prefix) ,
3119- front : State :: Prefix ,
3131+ // use a platform-specific initial state to avoid one turn of
3132+ // the state-machine when the platform doesn't have a Prefix.
3133+ front : const { if HAS_PREFIXES { State :: Prefix } else { State :: StartDir } } ,
31203134 back : State :: Body ,
31213135 }
31223136 }
0 commit comments