@@ -818,110 +818,114 @@ where
818818 let tcx = cx. tcx ( ) ;
819819 let param_env = cx. param_env ( ) ;
820820
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+ } ;
848849
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+ }
855856
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+ } ;
878879
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 ;
884884 }
885+ }
885886
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
908905 }
906+ } ) ;
907+ if result. is_some ( ) {
908+ break ;
909909 }
910910 }
911911 }
912+ }
912913
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+ } ) ;
919922 }
920923 }
921-
922- result
923924 }
924- } ;
925+
926+ result
927+ }
928+ } ;
925929
926930 debug ! (
927931 "pointee_info_at (offset={:?}, type kind: {:?}) => {:?}" ,
0 commit comments