@@ -709,7 +709,7 @@ impl Iterator for ReadDir {
709
709
// thread safety for readdir() as long an individual DIR* is not accessed
710
710
// concurrently, which is sufficient for Rust.
711
711
super :: os:: set_errno ( 0 ) ;
712
- let entry_ptr = readdir64 ( self . inner . dirp . 0 ) ;
712
+ let entry_ptr: * const dirent64 = readdir64 ( self . inner . dirp . 0 ) ;
713
713
if entry_ptr. is_null ( ) {
714
714
// We either encountered an error, or reached the end. Either way,
715
715
// the next call to next() should return None.
@@ -735,44 +735,34 @@ impl Iterator for ReadDir {
735
735
// contents were "simply" partially initialized data.
736
736
//
737
737
// Like for uninitialized contents, converting entry_ptr to `&dirent64`
738
- // would not be legal. However, unique to dirent64 is that we don't even
739
- // get to use `&raw const (*entry_ptr).d_name` because that operation
740
- // requires the full extent of *entry_ptr to be in bounds of the same
741
- // allocation, which is not necessarily the case here.
742
- //
743
- // Instead we must access fields individually through their offsets.
744
- macro_rules! offset_ptr {
745
- ( $entry_ptr: expr, $field: ident) => { {
746
- const OFFSET : isize = mem:: offset_of!( dirent64, $field) as isize ;
747
- if true {
748
- // Cast to the same type determined by the else branch.
749
- $entry_ptr. byte_offset( OFFSET ) . cast:: <_>( )
750
- } else {
751
- #[ allow( deref_nullptr) ]
752
- {
753
- & raw const ( * ptr:: null:: <dirent64>( ) ) . $field
754
- }
755
- }
756
- } } ;
738
+ // would not be legal. However, we can use `&raw const (*entry_ptr).d_name`
739
+ // to refer the fields individually, because that operation is equivalent
740
+ // to `byte_offset` and thus does not require the full extent of `*entry_ptr`
741
+ // to be in bounds of the same allocation, only the offset of the field
742
+ // being referenced.
743
+ macro_rules! entry_field_ptr {
744
+ ( $field: ident) => {
745
+ & raw const ( * entry_ptr) . $field
746
+ } ;
757
747
}
758
748
759
749
// d_name is guaranteed to be null-terminated.
760
- let name = CStr :: from_ptr ( offset_ptr ! ( entry_ptr , d_name) . cast ( ) ) ;
750
+ let name = CStr :: from_ptr ( entry_field_ptr ! ( d_name) . cast ( ) ) ;
761
751
let name_bytes = name. to_bytes ( ) ;
762
752
if name_bytes == b"." || name_bytes == b".." {
763
753
continue ;
764
754
}
765
755
766
756
#[ cfg( not( target_os = "vita" ) ) ]
767
757
let entry = dirent64_min {
768
- d_ino : * offset_ptr ! ( entry_ptr , d_ino) as u64 ,
758
+ d_ino : * entry_field_ptr ! ( d_ino) as u64 ,
769
759
#[ cfg( not( any(
770
760
target_os = "solaris" ,
771
761
target_os = "illumos" ,
772
762
target_os = "aix" ,
773
763
target_os = "nto" ,
774
764
) ) ) ]
775
- d_type : * offset_ptr ! ( entry_ptr , d_type) as u8 ,
765
+ d_type : * entry_field_ptr ! ( d_type) as u8 ,
776
766
} ;
777
767
778
768
#[ cfg( target_os = "vita" ) ]
0 commit comments