SE-0281 was accepted with the modification that the main function should
be allowed to be throwing. Here support for enabling that is added.
Support is implemented in two steps:
(1) The $main wrapper function is modified to be throwing
static func $main() throws {
return try main()
}
whenever the main function is throwing (it remains non-throwing when
$main is not throwing).
(2) The @main entry point is modified to be
sil [ossa] @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
entry(%argc : $Int32, %argv : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
%the_main_type = metatype $@thin TheMainType.Type
%the_main_func = function_ref @`TheMainType.main()` : $@convention(method) (@thin TheMainType.Type) -> @error Error
try_apply %the_main_func(%the_main_type) : $@convention(method) (@thin TheMainType.Type) -> @error Error, normal success, error failure
success(%_ : $()):
%success_code_builtin_int32 = integer_literal $Builtin.Int32, 0
br bb1(%success_code_builtin_int32 : $Builtin.Int32)
failure(%error : @owned $Error):
%_ = builtin "errorInMain"(%error : $Error) : $()
end_lifetime %error : $Error
%error_code_builtin_int32 = integer_literal $Builtin.Int32, 1
br bb1(%error_code_builtin_int32 : $Builtin.Int32)
exit(%code_builtin_int32 : $Builtin.Int32):
%code = struct $Int32 (%code_builtin_int32 : $Builtin.Int32)
return %code : $Int32
}
whenever the main function is throwing (and consequently $main also is).
In the non-throwing case, (a) the try_apply instruction is replaced with an
apply instruction, (b) the body of the success block is appended to the
entry block, and (c) the success and failure blocks are removed.
When a type (class, enum, or struct) is annotated @main, it is required
to provide a function with the following signature:
static func main() -> ()
That function will be called when the executable the type is defined
within is launched.