Skip to content

Commit 796b2d5

Browse files
authored
chore: merge from origin/master (#874)
- #871
2 parents d4e7dd3 + a9876cb commit 796b2d5

File tree

5 files changed

+66
-0
lines changed

5 files changed

+66
-0
lines changed

kmir/src/kmir/kdist/mir-semantics/rt/data.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,26 @@ This is done without consideration of the validity of the Downcast[^downcast].
450450
</k>
451451
```
452452

453+
In context with pointer casts, the semantics handles the special case of a _transparent wrapper struct_:
454+
A pointer to a struct containing a single element can be cast to a pointer to the single element itself.
455+
While the pointer cast tries to insert and remove field projections to the singleton field,
456+
it is still possible that a field projection occurs on a value which is not an Aggregate (nor a union).
457+
This necessitates a special rule which allows the semantics to perform a field projection to field 0 as a Noop.
458+
The situation typically arises when the stored value is a pointer (`NonNull`), therefore the rule is restricted to this case.
459+
The context is populated with the correct field access data, so that write-backs will correct the stored value to an Aggregate.
460+
461+
```k
462+
rule <k> #traverseProjection(
463+
DEST,
464+
PtrLocal(_, _, _, _) #as VALUE,
465+
projectionElemField(fieldIdx(0), TY) PROJS,
466+
CTXTS
467+
)
468+
=> #traverseProjection(DEST, VALUE, PROJS, CtxField(variantIdx(0), ListItem(VALUE), 0, TY) CTXTS) ... </k>
469+
[preserves-definedness, priority(100)]
470+
```
471+
472+
453473
#### Unions
454474
```k
455475
// Case: Union is in same state as field projection
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
struct Thing { payload: u16 }
2+
3+
fn main() {
4+
let a = [Thing{payload: 1}, Thing{payload: 2}, Thing{payload: 3}];
5+
6+
let mut i = a.iter();
7+
let elem = i.next();
8+
assert!(elem.unwrap().payload == 1);
9+
let elem = i.next();
10+
assert!(elem.unwrap().payload == 2);
11+
let elem = i.next();
12+
assert!(elem.unwrap().payload == 3);
13+
// let elem = i.next();
14+
// assert!(elem.is_none());
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
struct Thing { payload: u16 }
2+
3+
fn main() {
4+
let a = [Thing{payload: 1}, Thing{payload: 2}, Thing{payload: 3}];
5+
6+
let mut i = a.iter();
7+
let elem = i.next();
8+
assert!(elem.unwrap().payload == 1);
9+
let elem = i.next();
10+
assert!(elem.unwrap().payload == 2);
11+
let elem = i.next();
12+
assert!(elem.unwrap().payload == 3);
13+
let elem = i.next();
14+
assert!(elem.is_none());
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
┌─ 1 (root, init)
3+
│ #execTerminator ( terminator ( ... kind: terminatorKindCall ( ... func: operandC
4+
│ span: 0
5+
6+
│ (1990 steps)
7+
└─ 3 (stuck, leaf)
8+
#traverseProjection ( toStack ( 1 , local ( 1 ) ) , Range ( .List ) , .Projectio
9+
span: 146
10+
11+
12+
┌─ 2 (root, leaf, target, terminal)
13+
│ #EndProgram ~> .K
14+
15+

kmir/src/tests/integration/test_integration.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
'iterator-simple-fail',
6565
'unions-fail',
6666
'transmute-maybe-uninit-fail',
67+
'iter_next_2-fail',
6768
]
6869

6970

0 commit comments

Comments
 (0)