Skip to content

Commit 3f76113

Browse files
committed
test(smir): reproduce _projected_ty Subslice drop-glue pruning bug
Add unit test demonstrating that _projected_ty() returns the original array type for Subslice projections, causing call_edges to miss the drop_in_place::<[T; M]> edge and reduce_to() to incorrectly prune the required drop glue. Add integration test subslice-drop-partial-move.rs that generates Drop(arr.Subslice(1,3,false)) in the MIR — the exact pattern described in the Codex review comment.
1 parent 662427f commit 3f76113

2 files changed

Lines changed: 142 additions & 0 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Subslice projection in a Drop terminator's place.
2+
//
3+
// `let [first, ..] = arr` moves only `first`; the remaining elements
4+
// are dropped in place via Drop(arr.Subslice(1, 3, false)).
5+
// This exercises _projected_ty() resolving the Subslice to the correct
6+
// [Droppable; 2] type so reduce_to() preserves the drop glue.
7+
8+
struct Droppable(u8);
9+
10+
impl Drop for Droppable {
11+
fn drop(&mut self) {}
12+
}
13+
14+
fn consume(_: Droppable) {}
15+
16+
fn main() {
17+
let arr = [Droppable(1), Droppable(2), Droppable(3)];
18+
let [first, ..] = arr;
19+
consume(first);
20+
}

kmir/src/tests/unit/test_smir.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,125 @@ def test_drop_function_tys_accept_core_drop_in_place_names() -> None:
258258
)
259259

260260
assert smir_info.drop_function_tys == {2: 12}
261+
262+
263+
def test_call_edges_preserve_drop_glue_for_subslice_projection() -> None:
264+
# This SMIR models the pattern from `let [first, ..] = arr` where
265+
# arr: [Inner; 3]. The compiler generates:
266+
# Drop(local 1 . Subslice { from: 1, to: 3, from_end: false })
267+
# to drop the remaining [Inner; 2] subslice.
268+
#
269+
# _projected_ty() must resolve the Subslice to [Inner; 2] (ty 5),
270+
# not return the original [Inner; 3] (ty 1), so call_edges finds the
271+
# drop_in_place::<[Inner; 2]> edge.
272+
smir_info = SMIRInfo(
273+
{
274+
'name': 'drop-subslice',
275+
'allocs': [],
276+
'types': [
277+
[
278+
1,
279+
{
280+
'ArrayType': {
281+
'elem_type': 2,
282+
'size': {
283+
'kind': {'Value': [0, {'bytes': [3, 0, 0, 0, 0, 0, 0, 0], 'provenance': {'ptrs': []}, 'align': 8, 'mutability': 'Mut'}]},
284+
'id': 1,
285+
},
286+
}
287+
},
288+
], # [Inner; 3]
289+
[
290+
2,
291+
{
292+
'StructType': {
293+
'name': 'Inner',
294+
'adt_def': 2,
295+
'fields': [],
296+
'layout': None,
297+
}
298+
},
299+
],
300+
[3, {'PtrType': {'pointee_type': 2}}],
301+
[
302+
5,
303+
{
304+
'ArrayType': {
305+
'elem_type': 2,
306+
'size': {
307+
'kind': {'Value': [0, {'bytes': [2, 0, 0, 0, 0, 0, 0, 0], 'provenance': {'ptrs': []}, 'align': 8, 'mutability': 'Mut'}]},
308+
'id': 2,
309+
},
310+
}
311+
},
312+
], # [Inner; 2]
313+
[6, {'PtrType': {'pointee_type': 5}}],
314+
],
315+
'functions': [
316+
[10, {'NormalSym': 'caller'}],
317+
[12, {'NormalSym': 'drop_inner'}],
318+
[14, {'NormalSym': 'drop_inner_array2'}],
319+
],
320+
'items': [
321+
{
322+
'symbol_name': 'caller',
323+
'mono_item_kind': {
324+
'MonoItemFn': {
325+
'name': 'caller',
326+
'body': {
327+
'arg_count': 0,
328+
'locals': [{'ty': 0}, {'ty': 1}],
329+
'blocks': [
330+
{
331+
'terminator': {
332+
'kind': {
333+
'Drop': {
334+
'place': {
335+
'local': 1,
336+
'projection': [
337+
{'Subslice': {'from': 1, 'to': 3, 'from_end': False}}
338+
],
339+
},
340+
'target': 0,
341+
'unwind': 'Continue',
342+
}
343+
}
344+
}
345+
}
346+
],
347+
},
348+
}
349+
},
350+
},
351+
{
352+
'symbol_name': 'drop_inner',
353+
'mono_item_kind': {
354+
'MonoItemFn': {
355+
'name': 'std::ptr::drop_in_place::<Inner>',
356+
'body': {
357+
'arg_count': 1,
358+
'locals': [{'ty': 0}, {'ty': 3}],
359+
'blocks': [],
360+
},
361+
}
362+
},
363+
},
364+
{
365+
'symbol_name': 'drop_inner_array2',
366+
'mono_item_kind': {
367+
'MonoItemFn': {
368+
'name': 'std::ptr::drop_in_place::<[Inner; 2]>',
369+
'body': {
370+
'arg_count': 1,
371+
'locals': [{'ty': 0}, {'ty': 6}],
372+
'blocks': [],
373+
},
374+
}
375+
},
376+
},
377+
],
378+
'spans': [],
379+
}
380+
)
381+
382+
assert smir_info.call_edges == {10: {14}, 12: set(), 14: set()}

0 commit comments

Comments
 (0)