@@ -1036,6 +1036,9 @@ where
1036
1036
this : TyAndLayout < ' tcx > ,
1037
1037
cx : & C ,
1038
1038
offset : Size ,
1039
+ // If true, assume that pointers are either null or valid (according to their type),
1040
+ // enabling extra optimizations.
1041
+ mut assume_valid_ptr : bool ,
1039
1042
) -> Option < PointeeInfo > {
1040
1043
let tcx = cx. tcx ( ) ;
1041
1044
let param_env = cx. param_env ( ) ;
@@ -1058,19 +1061,19 @@ where
1058
1061
// Freeze/Unpin queries, and can save time in the codegen backend (noalias
1059
1062
// attributes in LLVM have compile-time cost even in unoptimized builds).
1060
1063
let optimize = tcx. sess . opts . optimize != OptLevel :: No ;
1061
- let kind = match mt {
1062
- hir:: Mutability :: Not => PointerKind :: SharedRef {
1064
+ let safe = match ( assume_valid_ptr , mt ) {
1065
+ ( true , hir:: Mutability :: Not ) => Some ( PointerKind :: SharedRef {
1063
1066
frozen : optimize && ty. is_freeze ( tcx, cx. param_env ( ) ) ,
1064
- } ,
1065
- hir:: Mutability :: Mut => PointerKind :: MutableRef {
1067
+ } ) ,
1068
+ ( true , hir:: Mutability :: Mut ) => Some ( PointerKind :: MutableRef {
1066
1069
unpin : optimize && ty. is_unpin ( tcx, cx. param_env ( ) ) ,
1067
- } ,
1070
+ } ) ,
1071
+ ( false , _) => None ,
1068
1072
} ;
1069
-
1070
1073
tcx. layout_of ( param_env. and ( ty) ) . ok ( ) . map ( |layout| PointeeInfo {
1071
1074
size : layout. size ,
1072
1075
align : layout. align . abi ,
1073
- safe : Some ( kind ) ,
1076
+ safe,
1074
1077
} )
1075
1078
}
1076
1079
@@ -1079,20 +1082,21 @@ where
1079
1082
// Within the discriminant field, only the niche itself is
1080
1083
// always initialized, so we only check for a pointer at its
1081
1084
// offset.
1082
- //
1083
- // If the niche is a pointer, it's either valid (according
1084
- // to its type), or null (which the niche field's scalar
1085
- // validity range encodes). This allows using
1086
- // `dereferenceable_or_null` for e.g., `Option<&T>`, and
1087
- // this will continue to work as long as we don't start
1088
- // using more niches than just null (e.g., the first page of
1089
- // the address space, or unaligned pointers).
1090
- // FIXME(reference_niches): well, the day has come...
1091
1085
Variants :: Multiple {
1092
- tag_encoding : TagEncoding :: Niche { untagged_variant, .. } ,
1086
+ tag_encoding :
1087
+ TagEncoding :: Niche {
1088
+ untagged_variant,
1089
+ niche_variants : ref variants,
1090
+ niche_start,
1091
+ } ,
1093
1092
tag_field,
1094
1093
..
1095
1094
} if this. fields . offset ( tag_field) == offset => {
1095
+ // We can only continue assuming pointer validity if the only possible
1096
+ // discriminant value is null. The null special-case is permitted by LLVM's
1097
+ // `dereferenceable_or_null`, and allow types like `Option<&T>` to benefit
1098
+ // from optimizations.
1099
+ assume_valid_ptr &= niche_start == 0 && variants. start ( ) == variants. end ( ) ;
1096
1100
Some ( this. for_variant ( cx, untagged_variant) )
1097
1101
}
1098
1102
_ => Some ( this) ,
@@ -1118,9 +1122,12 @@ where
1118
1122
result = field. to_result ( ) . ok ( ) . and_then ( |field| {
1119
1123
if ptr_end <= field_start + field. size {
1120
1124
// We found the right field, look inside it.
1121
- let field_info =
1122
- field. pointee_info_at ( cx, offset - field_start) ;
1123
- field_info
1125
+ Self :: ty_and_layout_pointee_info_at (
1126
+ field,
1127
+ cx,
1128
+ offset - field_start,
1129
+ assume_valid_ptr,
1130
+ )
1124
1131
} else {
1125
1132
None
1126
1133
}
@@ -1135,7 +1142,7 @@ where
1135
1142
// FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
1136
1143
if let Some ( ref mut pointee) = result {
1137
1144
if let ty:: Adt ( def, _) = this. ty . kind ( ) {
1138
- if def. is_box ( ) && offset. bytes ( ) == 0 {
1145
+ if assume_valid_ptr && def. is_box ( ) && offset. bytes ( ) == 0 {
1139
1146
let optimize = tcx. sess . opts . optimize != OptLevel :: No ;
1140
1147
pointee. safe = Some ( PointerKind :: Box {
1141
1148
unpin : optimize && this. ty . boxed_ty ( ) . is_unpin ( tcx, cx. param_env ( ) ) ,
0 commit comments