@@ -641,32 +641,38 @@ bool ContainsTyVar(TypeParameter tp, Type ty)
641641 wBody . WriteLine ( $ "return new { className } { uTypeArgs } ({ constructorArgs } );") ;
642642 }
643643
644+ // Emits getters for both named and unnamed destructors. The named ones are grouped across constructors by their
645+ // name and thus QDtorM = DtorM. This is not possible for unnamed ones, as there is no guarantee about shared return
646+ // types, so they are treated individually and their names (QDtorM) are qualified by their respective constructors.
644647 private void CompileDatatypeDestructorsAndAddToInterface ( DatatypeDecl dt , ConcreteSyntaxTree wr ,
645- ConcreteSyntaxTree interfaceTree , string DtT_TypeArgs ) {
648+ ConcreteSyntaxTree interfaceTree , string DtT_TypeArgs ) {
646649 foreach ( var ctor in dt . Ctors ) {
650+ var index = 0 ;
647651 foreach ( var dtor in ctor . Destructors ) {
648652 if ( dtor . EnclosingCtors [ 0 ] == ctor ) {
649653 var arg = dtor . CorrespondingFormals [ 0 ] ;
650- if ( ! arg . IsGhost && arg . HasName ) {
651- // T0 dtor_Dtor0 { get; }
652- interfaceTree . WriteLine ( $ "{ TypeName ( arg . Type , wr , arg . tok ) } dtor_{ arg . CompileName } {{ get; }}") ;
654+ if ( ! arg . IsGhost ) {
655+ var DtorM = arg . HasName ? arg . CompileName : FormalName ( arg , index ) ;
656+ // TN dtor_QDtorM { get; }
657+ interfaceTree . WriteLine ( $ "{ TypeName ( arg . Type , wr , arg . tok ) } { DestructorGetterName ( arg , ctor , index ) } {{ get; }}") ;
653658
654- // public T0 dtor_Dtor0 { get {
659+ // public TN dtor_QDtorM { get {
655660 // var d = this; // for inductive datatypes
656661 // var d = this._Get(); // for co-inductive datatypes
657- // if (d is DT_Ctor0) { return ((DT_Ctor0)d).Dtor0 ; }
658- // if (d is DT_Ctor1) { return ((DT_Ctor1)d).Dtor0 ; }
662+ // if (d is DT_Ctor0) { return ((DT_Ctor0)d).DtorM ; }
663+ // if (d is DT_Ctor1) { return ((DT_Ctor1)d).DtorM ; }
659664 // ...
660- // if (d is DT_Ctor(n-2)) { return ((DT_Ctor(n-2))d).Dtor0 ; }
661- // return ((DT_Ctor(n-1))d).Dtor0 ;
665+ // if (d is DT_Ctor(n-2)) { return ((DT_Ctor(n-2))d).DtorM ; }
666+ // return ((DT_Ctor(n-1))d).DtorM ;
662667 // }}
663- var wDtor = wr . NewNamedBlock ( $ "public { TypeName ( arg . Type , wr , arg . tok ) } dtor_{ arg . CompileName } ") ;
668+ var wDtor =
669+ wr . NewNamedBlock ( $ "public { TypeName ( arg . Type , wr , arg . tok ) } { DestructorGetterName ( arg , ctor , index ) } ") ;
664670 var wGet = wDtor . NewBlock ( "get" ) ;
665671 if ( dt . IsRecordType ) {
666672 if ( dt is CoDatatypeDecl ) {
667- wGet . WriteLine ( $ "return this._Get().{ IdName ( arg ) } ;") ;
673+ wGet . WriteLine ( $ "return this._Get().{ IdProtect ( DtorM ) } ;") ;
668674 } else {
669- wGet . WriteLine ( $ "return this.{ IdName ( arg ) } ;") ;
675+ wGet . WriteLine ( $ "return this.{ IdProtect ( DtorM ) } ;") ;
670676 }
671677 } else {
672678 if ( dt is CoDatatypeDecl ) {
@@ -681,13 +687,14 @@ private void CompileDatatypeDestructorsAndAddToInterface(DatatypeDecl dt, Concre
681687 Contract . Assert ( arg . CompileName == dtor . CorrespondingFormals [ i ] . CompileName ) ;
682688 var type = $ "{ dt . CompileName } _{ ctor_i . CompileName } { DtT_TypeArgs } ";
683689 // TODO use pattern matching to replace cast.
684- wGet . WriteLine ( $ "if (d is { type } ) {{ return (({ type } )d).{ IdName ( arg ) } ; }}") ;
690+ wGet . WriteLine ( $ "if (d is { type } ) {{ return (({ type } )d).{ IdProtect ( DtorM ) } ; }}") ;
685691 }
686692
687693 Contract . Assert ( arg . CompileName == dtor . CorrespondingFormals [ n - 1 ] . CompileName ) ;
688694 wGet . WriteLine (
689- $ "return (({ dt . CompileName } _{ dtor . EnclosingCtors [ n - 1 ] . CompileName } { DtT_TypeArgs } )d).{ IdName ( arg ) } ;") ;
695+ $ "return (({ dt . CompileName } _{ dtor . EnclosingCtors [ n - 1 ] . CompileName } { DtT_TypeArgs } )d).{ IdProtect ( DtorM ) } ;") ;
690696 }
697+ index ++ ;
691698 }
692699 }
693700 }
@@ -2614,8 +2621,11 @@ protected override ConcreteSyntaxTree EmitBetaRedex(List<string> boundVars, List
26142621 }
26152622
26162623 protected override void EmitDestructor ( string source , Formal dtor , int formalNonGhostIndex , DatatypeCtor ctor , List < Type > typeArgs , Type bvType , ConcreteSyntaxTree wr ) {
2617- var dtorName = FormalName ( dtor , formalNonGhostIndex ) ;
2618- wr . Write ( "(({0}){1}{2}).{3}" , DtCtorName ( ctor , typeArgs , wr ) , source , ctor . EnclosingDatatype is CoDatatypeDecl ? "._Get()" : "" , dtorName ) ;
2624+ wr . Write ( $ "{ source } .{ DestructorGetterName ( dtor , ctor , formalNonGhostIndex ) } ") ;
2625+ }
2626+
2627+ private string DestructorGetterName ( Formal dtor , DatatypeCtor ctor , int index ) {
2628+ return $ "dtor_{ ( dtor . HasName ? dtor . CompileName : ctor . CompileName + FormalName ( dtor , index ) ) } ";
26192629 }
26202630
26212631 protected override ConcreteSyntaxTree CreateLambda ( List < Type > inTypes , Bpl . IToken tok , List < string > inNames , Type resultType , ConcreteSyntaxTree wr , bool untyped = false ) {
0 commit comments