Skip to content

Commit 9d7db1a

Browse files
committed
Implement wide not-null pointer patterns
1 parent 52a5abd commit 9d7db1a

File tree

4 files changed

+83
-3
lines changed

4 files changed

+83
-3
lines changed

compiler/rustc_middle/src/ty/layout.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,11 +813,21 @@ where
813813
| ty::FnDef(..)
814814
| ty::CoroutineWitness(..)
815815
| ty::Foreign(..)
816-
| ty::Pat(_, _)
817816
| ty::Dynamic(_, _) => {
818817
bug!("TyAndLayout::field({:?}): not applicable", this)
819818
}
820819

820+
// May contain wide pointers
821+
ty::Pat(base, pat) => match *pat {
822+
ty::PatternKind::NotNull => {
823+
assert_eq!(i, 0);
824+
TyMaybeWithLayout::Ty(base)
825+
}
826+
ty::PatternKind::Range { .. } | ty::PatternKind::Or(_) => {
827+
bug!("TyAndLayout::field({this:?}): only applicable to !null patterns")
828+
}
829+
},
830+
821831
ty::UnsafeBinder(bound_ty) => {
822832
let ty = tcx.instantiate_bound_regions_with_erased(bound_ty.into());
823833
field_ty_or_layout(TyAndLayout { ty, ..this }, cx, i)

compiler/rustc_ty_utils/src/layout.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,12 @@ fn layout_of_uncached<'tcx>(
274274
};
275275

276276
layout.largest_niche = Some(niche);
277+
// Make wide pointer pattern types contain only a single field
278+
// of the wide pointer type itself.
279+
layout.fields = FieldsShape::Arbitrary {
280+
offsets: [Size::ZERO].into_iter().collect(),
281+
memory_index: [0].into_iter().collect(),
282+
}
277283
} else {
278284
bug!(
279285
"pattern type with `!null` pattern but not scalar/pair layout: {ty:?}, {layout:?}"

tests/ui/type/pattern_types/non_null.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ type NonNull<T> = pattern_type!(*const T is !null); //~ ERROR layout_of
1313
#[rustc_layout(debug)]
1414
type Test = Option<NonNull<()>>; //~ ERROR layout_of
1515

16+
#[rustc_layout(debug)]
17+
type Wide = pattern_type!(*const [u8] is !null); //~ ERROR layout_of
18+
1619
const _: () = assert!(size_of::<NonNull<()>>() == size_of::<Option<NonNull<()>>>());
1720

1821
fn main() {}

tests/ui/type/pattern_types/non_null.stderr

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ error: layout_of((*const T) is !null) = Layout {
1313
valid_range: 1..=18446744073709551615,
1414
},
1515
),
16-
fields: Primitive,
16+
fields: Arbitrary {
17+
offsets: [
18+
Size(0 bytes),
19+
],
20+
memory_index: [
21+
0,
22+
],
23+
},
1724
largest_niche: Some(
1825
Niche {
1926
offset: Size(0 bytes),
@@ -153,5 +160,59 @@ error: layout_of(Option<(*const ()) is !null>) = Layout {
153160
LL | type Test = Option<NonNull<()>>;
154161
| ^^^^^^^^^
155162

156-
error: aborting due to 2 previous errors
163+
error: layout_of((*const [u8]) is !null) = Layout {
164+
size: Size(16 bytes),
165+
align: AbiAlign {
166+
abi: Align(8 bytes),
167+
},
168+
backend_repr: ScalarPair(
169+
Initialized {
170+
value: Pointer(
171+
AddressSpace(
172+
0,
173+
),
174+
),
175+
valid_range: 1..=18446744073709551615,
176+
},
177+
Initialized {
178+
value: Int(
179+
I64,
180+
false,
181+
),
182+
valid_range: 0..=18446744073709551615,
183+
},
184+
),
185+
fields: Arbitrary {
186+
offsets: [
187+
Size(0 bytes),
188+
],
189+
memory_index: [
190+
0,
191+
],
192+
},
193+
largest_niche: Some(
194+
Niche {
195+
offset: Size(0 bytes),
196+
value: Pointer(
197+
AddressSpace(
198+
0,
199+
),
200+
),
201+
valid_range: 1..=18446744073709551615,
202+
},
203+
),
204+
uninhabited: false,
205+
variants: Single {
206+
index: 0,
207+
},
208+
max_repr_align: None,
209+
unadjusted_abi_align: Align(8 bytes),
210+
randomization_seed: $SEED,
211+
}
212+
--> $DIR/non_null.rs:17:1
213+
|
214+
LL | type Wide = pattern_type!(*const [u8] is !null);
215+
| ^^^^^^^^^
216+
217+
error: aborting due to 3 previous errors
157218

0 commit comments

Comments
 (0)