@@ -427,7 +427,7 @@ The solution is to use rewrite operations in a downward pass through the project
427427
428428 // retains information about the value that was deconstructed by a projection
429429 syntax Context ::= CtxField( Ty, VariantIdx, List, Int )
430- // | array context will be added here
430+ | CtxIndex( Ty, List , Int ) // array index constant or has been read before
431431
432432 syntax Contexts ::= List{Context, ""}
433433
@@ -440,6 +440,10 @@ The solution is to use rewrite operations in a downward pass through the project
440440 => #buildUpdate(typedValue(Aggregate(IDX, ARGS[I <- VAL]), TY, mutabilityMut), CTXS)
441441 [preserves-definedness] // valid list indexing checked upon context construction
442442
443+ rule #buildUpdate(VAL, CtxIndex(TY, ELEMS, I) CTXS)
444+ => #buildUpdate(typedValue(Range(ELEMS[I <- VAL]), TY, mutabilityMut), CTXS)
445+ [preserves-definedness] // valid list indexing checked upon context construction
446+
443447 rule <k> #projectedUpdate(
444448 DEST,
445449 typedValue(Aggregate(IDX, ARGS), TY, MUT),
@@ -457,6 +461,84 @@ The solution is to use rewrite operations in a downward pass through the project
457461 andBool (FORCE orBool MUT ==K mutabilityMut)
458462 [preserves-definedness] // valid list indexing checked
459463
464+ rule <k> #projectedUpdate(
465+ DEST,
466+ typedValue(Range(ELEMENTS), TY, MUT),
467+ projectionElemIndex(local(LOCAL)) PROJS,
468+ UPDATE,
469+ CTXTS,
470+ FORCE
471+ )
472+ =>
473+ #projectedUpdate(
474+ DEST,
475+ {ELEMENTS[#expectUsize({LOCALS[LOCAL]}:>TypedValue)]}:>TypedValue,
476+ PROJS,
477+ UPDATE,
478+ CtxIndex(TY, ELEMENTS, #expectUsize({LOCALS[LOCAL]}:>TypedValue)) CTXTS,
479+ FORCE)
480+ ...
481+ </k>
482+ <locals> LOCALS </locals>
483+ requires 0 <=Int LOCAL
484+ andBool LOCAL <Int size(LOCALS)
485+ andBool isTypedValue(LOCALS[LOCAL])
486+ andBool isInt(#expectUsize({LOCALS[LOCAL]}:>TypedValue))
487+ andBool 0 <=Int #expectUsize({LOCALS[LOCAL]}:>TypedValue)
488+ andBool #expectUsize({LOCALS[LOCAL]}:>TypedValue) <Int size(ELEMENTS)
489+ andBool isTypedValue(ELEMENTS[#expectUsize({LOCALS[LOCAL]}:>TypedValue)])
490+ andBool (FORCE orBool MUT ==K mutabilityMut)
491+ [preserves-definedness] // index checked, valid Int can be read, ELEMENT indexable and writeable or forced
492+
493+ rule <k> #projectedUpdate(
494+ DEST,
495+ typedValue(Range(ELEMENTS), TY, MUT),
496+ projectionElemConstantIndex(OFFSET:Int, _MINLEN, false) PROJS,
497+ UPDATE,
498+ CTXTS,
499+ FORCE
500+ )
501+ =>
502+ #projectedUpdate(
503+ DEST,
504+ {ELEMENTS[OFFSET]}:>TypedValue,
505+ PROJS,
506+ UPDATE,
507+ CtxIndex(TY, ELEMENTS, OFFSET) CTXTS,
508+ FORCE)
509+ ...
510+ </k>
511+ requires 0 <=Int OFFSET
512+ andBool OFFSET <Int size(ELEMENTS)
513+ andBool isTypedValue(ELEMENTS[OFFSET])
514+ andBool (FORCE orBool MUT ==K mutabilityMut)
515+ [preserves-definedness] // ELEMENT indexable and writeable or forced
516+
517+ rule <k> #projectedUpdate(
518+ DEST,
519+ typedValue(Range(ELEMENTS), TY, MUT),
520+ projectionElemConstantIndex(OFFSET:Int, MINLEN, true) PROJS, // from end
521+ UPDATE,
522+ CTXTS,
523+ FORCE
524+ )
525+ =>
526+ #projectedUpdate(
527+ DEST,
528+ {ELEMENTS[OFFSET]}:>TypedValue,
529+ PROJS,
530+ UPDATE,
531+ CtxIndex(TY, ELEMENTS, MINLEN -Int OFFSET) CTXTS,
532+ FORCE)
533+ ...
534+ </k>
535+ requires 0 <Int OFFSET
536+ andBool OFFSET <=Int MINLEN
537+ andBool MINLEN ==Int size(ELEMENTS) // assumed for valid MIR code
538+ andBool isTypedValue(ELEMENTS[MINLEN -Int OFFSET])
539+ andBool (FORCE orBool MUT ==K mutabilityMut)
540+ [preserves-definedness] // ELEMENT indexable and writeable or forced
541+
460542 rule <k> #projectedUpdate(
461543 _DEST,
462544 typedValue(Reference(OFFSET, place(LOCAL, PLACEPROJ), MUT), _, _),
0 commit comments