On Wed, Mar 30, 2022 at 2:38 PM Brian Goetz <brian.go...@oracle.com> wrote: > > Another way to think about this is: > > - If any of the code that the user actually wrote (the RHS of case clauses, > or guards on case labels) throws, then the switch throws that > - If any of the machinery of the switch dispatch throws, it throws > MatchException. >
That's a reasonable way to factor this and makes the difference between the machinery and the direct user code clear, even when looking at stacktraces. And from your other response: > Another thing it gains is that it discourages people > from thinking they can use exceptions in dtors; having these laundered > through MatchException discourages using this as a side channel, though > that's a more minor thing. This is a stronger argument than you give it credit for being. Wrapping the exception adds a bit of friction to doing the wrong thing which will pay off in helping guide users to the intended behaviour. --Dan > On 3/30/2022 2:12 PM, Dan Heidinga wrote: > > The rules regarding NPE, ICCE and MatchException look reasonable to me. > > > As a separate but not-separate exception problem, we have to deal with at > least two additional sources of exceptions: > > - A dtor / record acessor may throw an arbitrary exception in the course of > evaluating whether a case matches. > > - User code in the switch may throw an arbitrary exception. > > For the latter, this has always been handled by having the switch terminate > abruptly with the same exception, and we should continue to do this. > > For the former, we surely do not want to swallow this exception (such an > exception indicates a bug). The choices here are to treat this the same way > we do with user code, throwing it out of the switch, or to wrap with > MatchException. > > I prefer the latter -- wrapping with MatchException -- because the exception > is thrown from synthetic code between the user code and the ultimate thrower, > which means the pattern matching feature is mediating access to the thrower. > I think we should handle this as "if a pattern invoked from pattern matching > completes abruptly by throwing X, pattern matching completes abruptly with > MatchException", because the specific X is not a detail we want the user to > bind to. (We don't want them to bind to anything, but if they do, we want > them to bind to the logical action, not the implementation details.) > > My intuition (and maybe I have the wrong mental model?) is that the > pattern matching calling a user written dtor / record accessor is akin > to calling a method. We don't wrap the exceptions thrown by methods > apart from some very narrow cases (ie: reflection), and I thought part > of reflection's behaviour was related to needing to ensure exceptions > (particularly checked ones) were converted to something explicitly > handled by the caller. > > If the dtor / record accessor can declare they throw checked > exceptions, then I can kind of see the rationale for wrapping them. > Otherwise, it seems clearer to me to let them be thrown without > wrapping. > > I don't think we expect users to explicitly handle MatchException when > using pattern matching so what does wrapping gain us here? > > --Dan > >