22
33use crate :: files:: Files ;
44use crate :: sema:: {
5- BuiltinType , ExternalSig , Field , IntType , ReturnKind , Term , TermEnv , TermId , Type , TypeEnv ,
5+ BuiltinType , ExternalSig , Fields , IntType , ReturnKind , Term , TermEnv , TermId , Type , TypeEnv ,
66 TypeId ,
77} ;
88use crate :: serialize:: { Block , ControlFlow , EvalStep , MatchArm } ;
99use crate :: stablemapset:: StableSet ;
1010use crate :: trie_again:: { Binding , BindingId , Constraint , RuleSet } ;
11+ use std:: borrow:: Cow ;
1112use std:: fmt:: Write ;
1213use std:: slice:: Iter ;
1314use std:: sync:: Arc ;
@@ -412,7 +413,7 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
412413
413414 // Generate the `derive`s.
414415 let debug_derive = if is_nodebug { "" } else { ", Debug" } ;
415- if variants. iter ( ) . all ( |v| v. fields . is_empty ( ) ) {
416+ if variants. iter ( ) . all ( |v| v. fields == Fields :: Unit ) {
416417 writeln ! ( code, "#[derive(Copy, Clone, PartialEq, Eq{debug_derive})]" )
417418 . unwrap ( ) ;
418419 } else {
@@ -422,18 +423,10 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
422423 writeln ! ( code, "pub enum {name} {{" ) . unwrap ( ) ;
423424 for variant in variants {
424425 let name = & self . typeenv . syms [ variant. name . index ( ) ] ;
425- if variant. fields . is_empty ( ) {
426- writeln ! ( code, " {name}," ) . unwrap ( ) ;
427- } else {
428- writeln ! ( code, " {name} {{" ) . unwrap ( ) ;
429- for field in & variant. fields {
430- let name = & self . typeenv . syms [ field. name . index ( ) ] ;
431- let ty_name =
432- self . typeenv . types [ field. ty . index ( ) ] . name ( self . typeenv ) ;
433- writeln ! ( code, " {name}: {ty_name}," ) . unwrap ( ) ;
434- }
435- writeln ! ( code, " }}," ) . unwrap ( ) ;
436- }
426+ write ! ( code, " {name}" ) . unwrap ( ) ;
427+ self . generate_fields ( & mut * code, & variant. fields , " " , false )
428+ . unwrap ( ) ;
429+ writeln ! ( code, "," ) . unwrap ( ) ;
437430 }
438431 writeln ! ( code, "}}" ) . unwrap ( ) ;
439432 }
@@ -456,26 +449,60 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
456449
457450 // Generate the `derive`s.
458451 let debug_derive = if is_nodebug { "" } else { ", Debug" } ;
459- if fields. is_empty ( ) {
460- writeln ! ( code, "#[derive(Copy, Clone, PartialEq, Eq{debug_derive})]" )
461- . unwrap ( ) ;
462- writeln ! ( code, "pub struct {name};" ) . unwrap ( ) ;
463- } else {
464- writeln ! ( code, "#[derive(Clone{debug_derive})]" ) . unwrap ( ) ;
465- writeln ! ( code, "pub struct {name} {{" ) . unwrap ( ) ;
466- for field in fields {
467- let name = & self . typeenv . syms [ field. name . index ( ) ] ;
468- let ty_name = self . typeenv . types [ field. ty . index ( ) ] . name ( self . typeenv ) ;
469- writeln ! ( code, " pub {name}: {ty_name}," ) . unwrap ( ) ;
452+ match fields {
453+ Fields :: Unit => {
454+ writeln ! ( code, "#[derive(Copy, Clone, PartialEq, Eq{debug_derive})]" )
455+ . unwrap ( ) ;
456+ writeln ! ( code, "pub struct {name};" ) . unwrap ( ) ;
457+ }
458+ Fields :: Tuple ( _) | Fields :: Struct ( _) => {
459+ writeln ! ( code, "#[derive(Clone{debug_derive})]" ) . unwrap ( ) ;
460+ write ! ( code, "pub struct {name}" ) . unwrap ( ) ;
461+ self . generate_fields ( & mut * code, & fields, "" , true ) . unwrap ( ) ;
462+ if matches ! ( fields, Fields :: Tuple ( _) ) {
463+ write ! ( code, ";" ) . unwrap ( ) ;
464+ }
470465 }
471- writeln ! ( code, "}}" ) . unwrap ( ) ;
472466 }
473467 }
474468 _ => { }
475469 }
476470 }
477471 }
478472
473+ fn generate_fields (
474+ & self ,
475+ code : & mut String ,
476+ fields : & Fields ,
477+ pad : & str ,
478+ allow_pub : bool ,
479+ ) -> std:: fmt:: Result {
480+ let _pub = if allow_pub { "pub " } else { "" } ;
481+ match fields {
482+ Fields :: Unit => Ok ( ( ) ) ,
483+ Fields :: Struct ( fields) => {
484+ writeln ! ( code, " {{" ) ?;
485+ for field in & fields. fields {
486+ let name = & self . typeenv . syms [ field. name . index ( ) ] ;
487+ let ty_name = self . typeenv . types [ field. ty . index ( ) ] . name ( self . typeenv ) ;
488+ writeln ! ( code, "{pad} {_pub}{name}: {ty_name}," ) ?;
489+ }
490+ write ! ( code, "{pad}}}" )
491+ }
492+ Fields :: Tuple ( fields) => {
493+ write ! ( code, "(" ) ?;
494+ for ( i, field) in fields. fields . iter ( ) . enumerate ( ) {
495+ let ty_name = self . typeenv . types [ field. ty . index ( ) ] . name ( self . typeenv ) ;
496+ write ! ( code, "{_pub}{ty_name}" ) ?;
497+ if i < fields. fields . len ( ) - 1 {
498+ write ! ( code, ", " ) ?;
499+ }
500+ }
501+ write ! ( code, ")" )
502+ }
503+ }
504+ }
505+
479506 fn type_name ( & self , typeid : TypeId , by_ref : bool ) -> String {
480507 match self . typeenv . types [ typeid. index ( ) ] {
481508 Type :: Builtin ( bt) => String :: from ( bt. name ( ) ) ,
@@ -926,17 +953,19 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
926953
927954 let extract_fields = |ctx : & mut BodyContext < W > ,
928955 field_bindings : & [ BindingId ] ,
929- type_fields : & [ Field ] |
956+ fields : & Fields |
930957 -> std:: fmt:: Result {
931958 if !field_bindings. is_empty ( ) {
932959 ctx. begin_block ( ) ?;
933- for ( field, value) in type_fields. iter ( ) . zip ( field_bindings. iter ( ) ) {
934- write ! (
935- ctx. out,
936- "{}{}: " ,
937- & ctx. indent,
938- & self . typeenv. syms[ field. name. index( ) ] ,
939- ) ?;
960+ for ( i, value) in field_bindings. iter ( ) . enumerate ( ) {
961+ let field_name = match fields {
962+ Fields :: Unit => panic ! ( ) ,
963+ Fields :: Struct ( fields) => {
964+ Cow :: Borrowed ( & self . typeenv . syms [ fields. fields [ i] . name . index ( ) ] )
965+ }
966+ Fields :: Tuple ( _) => Cow :: Owned ( format ! ( "{i}" ) ) ,
967+ } ;
968+ write ! ( ctx. out, "{}{field_name}: " , & ctx. indent) ?;
940969 self . emit_expr ( ctx, * value) ?;
941970 if ctx. is_ref . contains ( value) {
942971 write ! ( ctx. out, ".clone()" ) ?;
@@ -1095,20 +1124,24 @@ impl<L: Length, C> Length for ContextIterWrapper<L, C> {{
10951124 & self ,
10961125 ctx : & mut BodyContext < W > ,
10971126 bindings : & [ Option < BindingId > ] ,
1098- fields : & [ Field ] ,
1127+ fields : & Fields ,
10991128 ) -> std:: fmt:: Result {
11001129 if !bindings. is_empty ( ) {
11011130 ctx. begin_block ( ) ?;
11021131 let mut skipped_some = false ;
1103- for ( & binding , field ) in bindings. iter ( ) . zip ( fields . iter ( ) ) {
1132+ for ( i , & binding ) in bindings. iter ( ) . enumerate ( ) {
11041133 if let Some ( binding) = binding {
1105- write ! (
1106- ctx. out,
1107- "{}{}: " ,
1108- & ctx. indent,
1109- & self . typeenv. syms[ field. name. index( ) ]
1110- ) ?;
1111- let ( is_ref, _) = self . ty ( field. ty ) ;
1134+ let ( field_name, field_ty) = match fields {
1135+ Fields :: Unit => panic ! ( ) ,
1136+ Fields :: Struct ( fields) => {
1137+ let field = & fields. fields [ i] ;
1138+ let name = & self . typeenv . syms [ field. name . index ( ) ] ;
1139+ ( Cow :: Borrowed ( name) , field. ty )
1140+ }
1141+ Fields :: Tuple ( fields) => ( Cow :: Owned ( format ! ( "{i}" ) ) , fields. fields [ i] . ty ) ,
1142+ } ;
1143+ write ! ( ctx. out, "{}{field_name}: " , & ctx. indent) ?;
1144+ let ( is_ref, _) = self . ty ( field_ty) ;
11121145 if is_ref {
11131146 ctx. set_ref ( binding, true ) ;
11141147 write ! ( ctx. out, "ref " ) ?;
0 commit comments