@@ -818,110 +818,114 @@ where
818
818
let tcx = cx. tcx ( ) ;
819
819
let param_env = cx. param_env ( ) ;
820
820
821
- let pointee_info =
822
- match * this. ty . kind ( ) {
823
- ty:: RawPtr ( mt) if offset. bytes ( ) == 0 => {
824
- tcx. layout_of ( param_env. and ( mt. ty ) ) . ok ( ) . map ( |layout| PointeeInfo {
825
- size : layout. size ,
826
- align : layout. align . abi ,
827
- safe : None ,
828
- } )
829
- }
830
- ty:: FnPtr ( fn_sig) if offset. bytes ( ) == 0 => {
831
- tcx. layout_of ( param_env. and ( tcx. mk_fn_ptr ( fn_sig) ) ) . ok ( ) . map ( |layout| {
832
- PointeeInfo { size : layout. size , align : layout. align . abi , safe : None }
833
- } )
834
- }
835
- ty:: Ref ( _, ty, mt) if offset. bytes ( ) == 0 => {
836
- // Use conservative pointer kind if not optimizing. This saves us the
837
- // Freeze/Unpin queries, and can save time in the codegen backend (noalias
838
- // attributes in LLVM have compile-time cost even in unoptimized builds).
839
- let optimize = tcx. sess . opts . optimize != OptLevel :: No ;
840
- let kind = match mt {
841
- hir:: Mutability :: Not => PointerKind :: SharedRef {
842
- frozen : optimize && ty. is_freeze ( tcx, cx. param_env ( ) ) ,
843
- } ,
844
- hir:: Mutability :: Mut => PointerKind :: MutableRef {
845
- unpin : optimize && ty. is_unpin ( tcx, cx. param_env ( ) ) ,
846
- } ,
847
- } ;
821
+ let pointee_info = match * this. ty . kind ( ) {
822
+ ty:: RawPtr ( mt) if offset. bytes ( ) == 0 => {
823
+ tcx. layout_of ( param_env. and ( mt. ty ) ) . ok ( ) . map ( |layout| PointeeInfo {
824
+ size : layout. size ,
825
+ align : layout. align . abi ,
826
+ safe : None ,
827
+ } )
828
+ }
829
+ ty:: FnPtr ( fn_sig) if offset. bytes ( ) == 0 => {
830
+ tcx. layout_of ( param_env. and ( tcx. mk_fn_ptr ( fn_sig) ) ) . ok ( ) . map ( |layout| PointeeInfo {
831
+ size : layout. size ,
832
+ align : layout. align . abi ,
833
+ safe : None ,
834
+ } )
835
+ }
836
+ ty:: Ref ( _, ty, mt) if offset. bytes ( ) == 0 => {
837
+ // Use conservative pointer kind if not optimizing. This saves us the
838
+ // Freeze/Unpin queries, and can save time in the codegen backend (noalias
839
+ // attributes in LLVM have compile-time cost even in unoptimized builds).
840
+ let optimize = tcx. sess . opts . optimize != OptLevel :: No ;
841
+ let kind = match mt {
842
+ hir:: Mutability :: Not => PointerKind :: SharedRef {
843
+ frozen : optimize && ty. is_freeze ( tcx, cx. param_env ( ) ) ,
844
+ } ,
845
+ hir:: Mutability :: Mut => PointerKind :: MutableRef {
846
+ unpin : optimize && ty. is_unpin ( tcx, cx. param_env ( ) ) ,
847
+ } ,
848
+ } ;
848
849
849
- tcx. layout_of ( param_env. and ( ty) ) . ok ( ) . map ( |layout| PointeeInfo {
850
- size : layout. size ,
851
- align : layout. align . abi ,
852
- safe : Some ( kind) ,
853
- } )
854
- }
850
+ tcx. layout_of ( param_env. and ( ty) ) . ok ( ) . map ( |layout| PointeeInfo {
851
+ size : layout. size ,
852
+ align : layout. align . abi ,
853
+ safe : Some ( kind) ,
854
+ } )
855
+ }
855
856
856
- _ => {
857
- let mut data_variant = match this. variants {
858
- // Within the discriminant field, only the niche itself is
859
- // always initialized, so we only check for a pointer at its
860
- // offset.
861
- //
862
- // If the niche is a pointer, it's either valid (according
863
- // to its type), or null (which the niche field's scalar
864
- // validity range encodes). This allows using
865
- // `dereferenceable_or_null` for e.g., `Option<&T>`, and
866
- // this will continue to work as long as we don't start
867
- // using more niches than just null (e.g., the first page of
868
- // the address space, or unaligned pointers).
869
- Variants :: Multiple {
870
- tag_encoding : TagEncoding :: Niche { untagged_variant, .. } ,
871
- tag_field,
872
- ..
873
- } if this. fields . offset ( tag_field) == offset => {
874
- Some ( this. for_variant ( cx, untagged_variant) )
875
- }
876
- _ => Some ( this) ,
877
- } ;
857
+ _ => {
858
+ let mut data_variant = match this. variants {
859
+ // Within the discriminant field, only the niche itself is
860
+ // always initialized, so we only check for a pointer at its
861
+ // offset.
862
+ //
863
+ // If the niche is a pointer, it's either valid (according
864
+ // to its type), or null (which the niche field's scalar
865
+ // validity range encodes). This allows using
866
+ // `dereferenceable_or_null` for e.g., `Option<&T>`, and
867
+ // this will continue to work as long as we don't start
868
+ // using more niches than just null (e.g., the first page of
869
+ // the address space, or unaligned pointers).
870
+ Variants :: Multiple {
871
+ tag_encoding : TagEncoding :: Niche { untagged_variant, .. } ,
872
+ tag_field,
873
+ ..
874
+ } if this. fields . offset ( tag_field) == offset => {
875
+ Some ( this. for_variant ( cx, untagged_variant) )
876
+ }
877
+ _ => Some ( this) ,
878
+ } ;
878
879
879
- if let Some ( variant) = data_variant {
880
- // We're not interested in any unions.
881
- if let FieldsShape :: Union ( _) = variant. fields {
882
- data_variant = None ;
883
- }
880
+ if let Some ( variant) = data_variant {
881
+ // We're not interested in any unions.
882
+ if let FieldsShape :: Union ( _) = variant. fields {
883
+ data_variant = None ;
884
884
}
885
+ }
885
886
886
- let mut result = None ;
887
-
888
- if let Some ( variant) = data_variant {
889
- // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
890
- // (requires passing in the expected address space from the caller)
891
- let ptr_end = offset + Pointer ( AddressSpace :: DATA ) . size ( cx) ;
892
- for i in 0 ..variant. fields . count ( ) {
893
- let field_start = variant. fields . offset ( i) ;
894
- if field_start <= offset {
895
- let field = variant. field ( cx, i) ;
896
- result = field. to_result ( ) . ok ( ) . and_then ( |field| {
897
- if ptr_end <= field_start + field. size {
898
- // We found the right field, look inside it.
899
- let field_info =
900
- field. pointee_info_at ( cx, offset - field_start) ;
901
- field_info
902
- } else {
903
- None
904
- }
905
- } ) ;
906
- if result. is_some ( ) {
907
- break ;
887
+ let mut result = None ;
888
+
889
+ if let Some ( variant) = data_variant {
890
+ // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
891
+ // (requires passing in the expected address space from the caller)
892
+ let ptr_end = offset + Pointer ( AddressSpace :: DATA ) . size ( cx) ;
893
+ for i in 0 ..variant. fields . count ( ) {
894
+ let field_start = variant. fields . offset ( i) ;
895
+ if field_start <= offset {
896
+ let field = variant. field ( cx, i) ;
897
+ result = field. to_result ( ) . ok ( ) . and_then ( |field| {
898
+ if ptr_end <= field_start + field. size {
899
+ // We found the right field, look inside it.
900
+ let field_info =
901
+ field. pointee_info_at ( cx, offset - field_start) ;
902
+ field_info
903
+ } else {
904
+ None
908
905
}
906
+ } ) ;
907
+ if result. is_some ( ) {
908
+ break ;
909
909
}
910
910
}
911
911
}
912
+ }
912
913
913
- // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
914
- if let Some ( ref mut pointee) = result {
915
- if let ty:: Adt ( def, _) = this. ty . kind ( ) {
916
- if def. is_box ( ) && offset. bytes ( ) == 0 {
917
- pointee. safe = Some ( PointerKind :: Box ) ;
918
- }
914
+ // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
915
+ if let Some ( ref mut pointee) = result {
916
+ if let ty:: Adt ( def, _) = this. ty . kind ( ) {
917
+ if def. is_box ( ) && offset. bytes ( ) == 0 {
918
+ let optimize = tcx. sess . opts . optimize != OptLevel :: No ;
919
+ pointee. safe = Some ( PointerKind :: Box {
920
+ unpin : optimize && this. ty . boxed_ty ( ) . is_unpin ( tcx, cx. param_env ( ) ) ,
921
+ } ) ;
919
922
}
920
923
}
921
-
922
- result
923
924
}
924
- } ;
925
+
926
+ result
927
+ }
928
+ } ;
925
929
926
930
debug ! (
927
931
"pointee_info_at (offset={:?}, type kind: {:?}) => {:?}" ,
0 commit comments