Edit: Sorry if this is a bit rambly; it’s hot and I only just woke up. Brain might not be in completely working order just yet.
I think it would be a mistake to have ?
behave differently in main
. All that does is trade the possibility that some copy+paste coding will work versus now having to explain that the behaviour of ?
is context-dependent, and having the behaviour of ?
be context-dependent.
If this is principally based around helping new users and people who are copy+pasting code from examples without understanding what’s going on, and then being confused when it doesn’t work, then I don’t think any of the proposals actually address that.
First of all, let’s say we allow main
to have a different signature that permits errors to be returned. Given a user who is blindly copy+pasting code, or trying to write error handling without understanding how error handling works, how do they know they need to change the signature of main
? This is almost the same as just using a try_main
function and having main
call that: it only works if you know to do it.
If we give main
special, magical properties (which includes giving ?
magical properties inside main
), we now have a new problem: the moment the user tries to move code that works in main
to some other function, it’ll stop working. At that point, we’re back to square one again. Plus, we now need to explain this magic behaviour, and users need to remember it.
Any solution to this needs to be global and consistent across all functions: it cannot just affect main
. It also has to be something that requires no knowledge or action from new users.
Given that, I can only think of one solution to the novice user problem (that doesn’t involve completely changing how error handling works): add a diagnostic that specifically detects “tried to use ?
in a function without a Result
return type” and tells the user what to do. As in, it flat-out tells the user the return type they should use, as accurately as possible. The user should be able to copy+paste from the error message into their code. This should work everywhere, no matter the function, not just main
.
At that point, having main
allow for Result<(), _>
as a return type is a logical next step, so that users can act on what the diagnostic tells them. I also think it should be Result
: even if the compiler internally uses some trait to wire this up, we should probably only ever mention Result
to new users, or it might confuse matters (“so I can return ExitStatus
from main
instead of Result
, why can’t I do that for other functions?”).
That said, I think the important part is the diagnostic. Changing the return status of main
is a nice little improvement, but it only improves one function, and only helps in the specific case of trying to blindly copy error handling code into main
as opposed to any other function the user may be writing.