@@ -276,6 +276,7 @@ impl NameMangling {
276276struct Emitter < ' a > {
277277 nm : NameMangling ,
278278 diags : & ' a mut Diagnostics ,
279+ in_spec : bool ,
279280}
280281
281282impl < ' a > Emitter < ' a > {
@@ -543,15 +544,36 @@ impl<'a> Emitter<'a> {
543544 }
544545 } ,
545546 ExprT :: Index ( arr, idx) => {
546- let arr_doc = self . emit_rvalue ( env, arr) ;
547- let idx_doc = self . emit_rvalue ( env, idx) ;
548- ExprKind :: RValue ( annotated (
549- v,
550- arr_doc
551- . append ( Doc :: text ( ".(" ) )
552- . append ( idx_doc)
553- . append ( Doc :: text ( ")" ) ) ,
554- ) )
547+ if self . in_spec {
548+ let arr_doc = self . emit_rvalue ( env, arr) ;
549+ let idx_doc = self . emit_rvalue ( env, idx) ;
550+ let idx_nat = match env. infer_expr ( idx) {
551+ Ok ( ty) if matches ! ( & ty. val, TypeT :: SizeT ) => {
552+ unaryfn ( Doc :: text ( "SizeT.v" ) , idx_doc)
553+ }
554+ _ => idx_doc,
555+ } ;
556+ ExprKind :: RValue ( annotated (
557+ v,
558+ parens (
559+ Doc :: text ( "Seq.index" )
560+ . append ( Doc :: line ( ) )
561+ . append ( unaryfn ( Doc :: text ( "value_of" ) , arr_doc) )
562+ . append ( Doc :: line ( ) )
563+ . append ( idx_nat) ,
564+ ) ,
565+ ) )
566+ } else {
567+ let arr_doc = self . emit_rvalue ( env, arr) ;
568+ let idx_doc = self . emit_rvalue ( env, idx) ;
569+ ExprKind :: RValue ( annotated (
570+ v,
571+ arr_doc
572+ . append ( Doc :: text ( ".(" ) )
573+ . append ( idx_doc)
574+ . append ( Doc :: text ( ")" ) ) ,
575+ ) )
576+ }
555577 }
556578 _ => ExprKind :: RValue ( self . emit_rvalue_inner ( env, v) ) ,
557579 }
@@ -1189,34 +1211,41 @@ impl<'a> Emitter<'a> {
11891211 requires,
11901212 ensures,
11911213 body,
1192- } => Doc :: text ( "while " )
1214+ } => {
1215+ self . in_spec = true ;
1216+ let inv_docs: Vec < _ > = inv. iter ( ) . map ( |inv| self . emit_rvalue ( env, inv) ) . collect ( ) ;
1217+ let req_docs: Vec < _ > = requires. iter ( ) . map ( |r| self . emit_rvalue ( env, r) ) . collect ( ) ;
1218+ let ens_docs: Vec < _ > = ensures. iter ( ) . map ( |e| self . emit_rvalue ( env, e) ) . collect ( ) ;
1219+ self . in_spec = false ;
1220+ Doc :: text ( "while " )
11931221 . append ( parens ( self . emit_rvalue ( env, cond) ) )
11941222 . append ( Doc :: line ( ) )
1195- . append ( Doc :: concat ( inv . iter ( ) . map ( |inv | {
1223+ . append ( Doc :: concat ( inv_docs . into_iter ( ) . map ( |d | {
11961224 Doc :: text ( "invariant " )
1197- . append ( self . emit_rvalue ( env , inv ) )
1225+ . append ( d )
11981226 . group ( )
11991227 . nest ( 2 )
12001228 . append ( Doc :: line ( ) )
12011229 } ) ) )
1202- . append ( Doc :: concat ( requires . iter ( ) . map ( |r | {
1230+ . append ( Doc :: concat ( req_docs . into_iter ( ) . map ( |d | {
12031231 Doc :: text ( "requires " )
1204- . append ( self . emit_rvalue ( env , r ) )
1232+ . append ( d )
12051233 . group ( )
12061234 . nest ( 2 )
12071235 . append ( Doc :: line ( ) )
12081236 } ) ) )
1209- . append ( Doc :: concat ( ensures . iter ( ) . map ( |e | {
1237+ . append ( Doc :: concat ( ens_docs . into_iter ( ) . map ( |d | {
12101238 Doc :: text ( "ensures " )
1211- . append ( self . emit_rvalue ( env , e ) )
1239+ . append ( d )
12121240 . group ( )
12131241 . nest ( 2 )
12141242 . append ( Doc :: line ( ) )
12151243 } ) ) )
12161244 . nest ( 2 )
12171245 . append ( self . emit_block ( env, body) )
12181246 . append ( ";" )
1219- . group ( ) ,
1247+ . group ( )
1248+ } ,
12201249 StmtT :: Break => Doc :: text ( "break;" ) ,
12211250 StmtT :: Continue => Doc :: text ( "continue;" ) ,
12221251 StmtT :: Return ( Some ( t) ) => Doc :: text ( "return" )
@@ -1745,7 +1774,9 @@ impl<'a> Emitter<'a> {
17451774 params. push ( Doc :: text ( "()" ) ) ;
17461775 }
17471776
1777+ self . in_spec = true ;
17481778 requires_props. extend ( requires. iter ( ) . map ( |r| self . emit_rvalue ( env, r) ) ) ;
1779+ self . in_spec = false ;
17491780
17501781 let return_id = env
17511782 . push_return ( ret_type. clone ( ) )
@@ -1759,7 +1790,9 @@ impl<'a> Emitter<'a> {
17591790 ) ;
17601791 let ret_type_doc = self . emit_type ( env, ret_type) ;
17611792
1793+ self . in_spec = true ;
17621794 ensures_props. extend ( ensures. iter ( ) . map ( |r| self . emit_rvalue ( env, r) ) ) ;
1795+ self . in_spec = false ;
17631796
17641797 let hdr = Doc :: group (
17651798 Doc :: text ( "fn" )
@@ -2113,6 +2146,7 @@ pub fn emit(
21132146 let emitter = & mut Emitter {
21142147 nm : NameMangling :: new ( ) ,
21152148 diags,
2149+ in_spec : false ,
21162150 } ;
21172151 let mut output: Vec < Doc > = vec ! [ ] ;
21182152 output. push ( Doc :: text ( format ! (
0 commit comments