@@ -1346,12 +1346,9 @@ public bool HasMain(Program program, out Method mainMethod) {
13461346 continue ;
13471347 }
13481348 foreach ( var decl in module . TopLevelDecls ) {
1349- var c = decl as TopLevelDeclWithMembers ;
1350- if ( c != null ) {
1349+ if ( decl is TopLevelDeclWithMembers c ) {
13511350 foreach ( MemberDecl member in c . Members ) {
1352- var m = member as Method ;
1353- if ( m == null ) continue ;
1354- if ( member . FullDafnyName == name ) {
1351+ if ( member is Method m && member . FullDafnyName == name ) {
13551352 mainMethod = m ;
13561353 if ( ! IsPermittedAsMain ( mainMethod , out string reason ) ) {
13571354 Error ( mainMethod . tok , "The method \" {0}\" is not permitted as a main method ({1})." , null , name , reason ) ;
@@ -1471,13 +1468,26 @@ public static bool IsPermittedAsMain(Method m, out String reason) {
14711468 reason = "the method has type parameters" ;
14721469 return false ;
14731470 }
1474- if ( cl . TypeArgs . Count != 0 ) {
1475- reason = "the enclosing class has type parameters " ;
1471+ if ( cl is OpaqueTypeDecl ) {
1472+ reason = "the enclosing type is an opaque type " ;
14761473 return false ;
14771474 }
1478- if ( ! m . IsStatic && ! cl . Members . TrueForAll ( f => ! ( f is Constructor ) ) ) {
1479- reason = "the method is not static and the enclosing class has constructors" ;
1480- return false ;
1475+ if ( ! m . IsStatic ) {
1476+ if ( cl is TraitDecl ) {
1477+ reason = "the method is not static and the enclosing type does not support auto-initialization" ;
1478+ return false ;
1479+ } else if ( cl is ClassDecl ) {
1480+ if ( cl . Members . Exists ( f => f is Constructor ) ) {
1481+ reason = "the method is not static and the enclosing class has constructors" ;
1482+ return false ;
1483+ }
1484+ } else {
1485+ var ty = UserDefinedType . FromTopLevelDeclWithAllBooleanTypeParameters ( cl ) ;
1486+ if ( ! ty . HasCompilableValue ) {
1487+ reason = "the method is not static and the enclosing type does not support auto-initialization" ;
1488+ return false ;
1489+ }
1490+ }
14811491 }
14821492 if ( ! m . Ins . TrueForAll ( f => f . IsGhost ) ) {
14831493 reason = "the method has non-ghost parameters" ;
@@ -2196,21 +2206,43 @@ private void CompileMethod(Program program, Method m, IClassWriter cw, bool look
21962206
21972207 if ( m == program . MainMethod && IssueCreateStaticMain ( m ) ) {
21982208 w = CreateStaticMain ( cw ) ;
2209+ var ty = UserDefinedType . FromTopLevelDeclWithAllBooleanTypeParameters ( m . EnclosingClass ) ;
2210+ LocalVariable receiver = null ;
21992211 if ( ! m . IsStatic ) {
2200- var c = m . EnclosingClass ;
2201- var typeArgs = c . TypeArgs . ConvertAll ( tp => ( Type ) Type . Bool ) ;
2202- var ty = new UserDefinedType ( m . tok , c . Name , c , typeArgs ) ;
2203- var wRhs = DeclareLocalVar ( "b" , ty , m . tok , w ) ;
2204- EmitNew ( ty , m . tok , null , wRhs ) ;
2205- w . WriteLine ( "b.{0}();" , IdName ( m ) ) ;
2212+ receiver = new LocalVariable ( m . tok , m . tok , "b" , ty , false ) {
2213+ type = ty
2214+ } ;
2215+ if ( m . EnclosingClass is ClassDecl ) {
2216+ var wRhs = DeclareLocalVar ( IdName ( receiver ) , ty , m . tok , w ) ;
2217+ EmitNew ( ty , m . tok , null , wRhs ) ;
2218+ } else {
2219+ TrLocalVar ( receiver , true , w ) ;
2220+ }
2221+ }
2222+ var typeArgs = CombineAllTypeArguments ( m , ty . TypeArgs , m . TypeArgs . ConvertAll ( tp => ( Type ) Type . Bool ) ) ;
2223+ bool customReceiver = ! ( m . EnclosingClass is TraitDecl ) && NeedsCustomReceiver ( m ) ;
2224+
2225+ if ( receiver != null && ! customReceiver ) {
2226+ w . Write ( "{0}." , IdName ( receiver ) ) ;
22062227 } else {
2207- w . WriteLine ( "{0}();" , IdName ( m ) ) ;
2228+ var companion = TypeName_Companion ( UserDefinedType . FromTopLevelDeclWithAllBooleanTypeParameters ( m . EnclosingClass ) , w , m . tok , m ) ;
2229+ w . Write ( "{0}." , companion ) ;
2230+ }
2231+ EmitNameAndActualTypeArgs ( IdName ( m ) , TypeArgumentInstantiation . ToActuals ( ForTypeParameters ( typeArgs , m , false ) ) , m . tok , w ) ;
2232+ w . Write ( "(" ) ;
2233+ var sep = "" ;
2234+ if ( receiver != null && customReceiver ) {
2235+ w . Write ( "{0}" , IdName ( receiver ) ) ;
2236+ sep = ", " ;
22082237 }
2238+ EmitTypeDescriptorsActuals ( ForTypeDescriptors ( typeArgs , m , false ) , m . tok , w , ref sep ) ;
2239+ w . Write ( ")" ) ;
2240+ EndStmt ( w ) ;
22092241 }
22102242 }
22112243
22122244 protected virtual bool IssueCreateStaticMain ( Method m ) {
2213- return ! m . IsStatic ;
2245+ return ! m . IsStatic || m . EnclosingClass . TypeArgs . Count != 0 ;
22142246 }
22152247
22162248
0 commit comments