@@ -244,21 +244,21 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
244244 self . scope . to_scope ( body_expr) ,
245245 )
246246 }
247- core:: Term :: RecordType ( _span , labels, exprs )
248- if is_tuple_type ( labels , exprs , & self . interner . borrow ( ) ) =>
247+ core:: Term :: RecordType ( _ , labels, types )
248+ if is_tuple_type ( & mut self . interner . borrow_mut ( ) , labels , types ) =>
249249 {
250250 let scope = self . scope ;
251- let exprs = exprs . iter ( ) . map ( |expr| self . check ( expr) ) ;
252- Term :: Tuple ( ( ) , scope. to_scope_from_iter ( exprs ) )
251+ let types = types . iter ( ) . map ( |expr| self . check ( expr) ) ;
252+ Term :: Tuple ( ( ) , scope. to_scope_from_iter ( types ) )
253253 }
254- core:: Term :: RecordLit ( _span , labels, exprs)
255- if is_tuple_expr ( labels , & self . interner . borrow ( ) ) =>
254+ core:: Term :: RecordLit ( _ , labels, exprs)
255+ if self . interner . borrow_mut ( ) . is_tuple_labels ( labels ) =>
256256 {
257257 let scope = self . scope ;
258258 let exprs = exprs. iter ( ) . map ( |expr| self . check ( expr) ) ;
259259 Term :: Tuple ( ( ) , scope. to_scope_from_iter ( exprs) )
260260 }
261- core:: Term :: RecordLit ( _span , labels, exprs) => {
261+ core:: Term :: RecordLit ( _ , labels, exprs) => {
262262 let scope = self . scope ;
263263 let expr_fields =
264264 Iterator :: zip ( labels. iter ( ) , exprs. iter ( ) ) . map ( |( label, expr) | ExprField {
@@ -274,8 +274,8 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
274274
275275 Term :: ArrayLiteral ( ( ) , scope. to_scope_from_iter ( elem_exprs) )
276276 }
277- core:: Term :: FormatRecord ( _span , labels, formats)
278- if is_tuple_type ( labels , formats , & self . interner . borrow ( ) ) =>
277+ core:: Term :: FormatRecord ( _ , labels, formats)
278+ if is_tuple_type ( & mut self . interner . borrow_mut ( ) , labels , formats ) =>
279279 {
280280 let scope = self . scope ;
281281 let formats = formats. iter ( ) . map ( |format| self . check ( format) ) ;
@@ -516,12 +516,12 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
516516 )
517517 }
518518 } ,
519- core:: Term :: RecordType ( _span , labels, exprs )
520- if is_tuple_type ( labels , exprs , & self . interner . borrow ( ) ) =>
519+ core:: Term :: RecordType ( _ , labels, types )
520+ if is_tuple_type ( & mut self . interner . borrow_mut ( ) , labels , types ) =>
521521 {
522522 let initial_local_len = self . local_len ( ) ;
523523 let types = ( self . scope ) . to_scope_from_iter (
524- Iterator :: zip ( labels. iter ( ) , exprs . iter ( ) ) . map ( |( label, r#type) | {
524+ Iterator :: zip ( labels. iter ( ) , types . iter ( ) ) . map ( |( label, r#type) | {
525525 let r#type = self . check ( r#type) ;
526526 self . push_local ( Some ( * label) ) ;
527527 r#type
@@ -550,8 +550,8 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
550550
551551 Term :: RecordType ( ( ) , type_fields)
552552 }
553- core:: Term :: RecordLit ( _span , labels, exprs)
554- if is_tuple_expr ( labels , & self . interner . borrow ( ) ) =>
553+ core:: Term :: RecordLit ( _ , labels, exprs)
554+ if self . interner . borrow_mut ( ) . is_tuple_labels ( labels ) =>
555555 {
556556 let scope = self . scope ;
557557 let exprs = exprs. iter ( ) . map ( |expr| self . synth ( expr) ) ;
@@ -591,7 +591,7 @@ impl<'interner, 'arena, 'env> Context<'interner, 'arena, 'env> {
591591 Term :: ArrayLiteral ( ( ) , scope. to_scope_from_iter ( elem_exprs) )
592592 }
593593 core:: Term :: FormatRecord ( _span, labels, formats)
594- if is_tuple_type ( labels , formats , & self . interner . borrow ( ) ) =>
594+ if is_tuple_type ( & mut self . interner . borrow_mut ( ) , labels , formats ) =>
595595 {
596596 let scope = self . scope ;
597597 let formats = formats. iter ( ) . map ( |format| self . synth ( format) ) ;
@@ -781,27 +781,19 @@ fn match_if_then_else<'arena>(
781781 }
782782}
783783
784- // Return true if `labels` are all tuple labels
785- fn is_tuple_expr ( labels : & [ StringId ] , interner : & StringInterner ) -> bool {
786- labels
787- . iter ( )
788- . enumerate ( )
789- . all ( |( idx, label) | interner. resolve ( * label) == Some ( & format ! ( "_{}" , idx) ) )
790- }
791-
792- // Return true if `labels` are all tuple labels, and `exprs` do not depend on any of the expressions bound by `labels`
793- fn is_tuple_type ( labels : & [ StringId ] , exprs : & [ core:: Term < ' _ > ] , interner : & StringInterner ) -> bool {
794- let suffixes = ( 1 ..=exprs. len ( ) ) . rev ( ) . map ( move |idx| & exprs[ idx..] ) ;
795- labels
796- . iter ( )
797- . zip ( suffixes)
798- . enumerate ( )
799- . all ( |( idx, ( label, suffix) ) | {
800- interner. resolve ( * label) == Some ( & format ! ( "_{}" , idx) )
801- && suffix
802- . iter ( )
803- . zip ( env:: indices ( ) )
804- . all ( |( expr, idx) | !expr. binds_local ( idx) )
784+ /// Returns true if `labels` is a sequence of tuple labels (`_0`, `_1`, ...),
785+ /// and a telescope of `types` contains independent entries.
786+ fn is_tuple_type (
787+ interner : & mut StringInterner ,
788+ labels : & [ StringId ] ,
789+ types : & [ core:: Term < ' _ > ] ,
790+ ) -> bool {
791+ interner. is_tuple_labels ( labels)
792+ // For each type in the telescope, ensure that the subsequent types in
793+ // the telescope do not depend on the current field.
794+ && ( 1 ..=types. len ( ) ) . all ( |index| {
795+ Iterator :: zip ( types[ index..] . iter ( ) , env:: indices ( ) )
796+ . all ( |( expr, var) | !expr. binds_local ( var) )
805797 } )
806798}
807799
0 commit comments