Note: Exceptions and panics aren’t quite the same thing. Exceptions are typed and are generally used to return common errors. Panics are an untyped way to say “something went really wrong and I just want to bail”.
Treat any function that can panic but doesn’t return an error or result have it’s type signature implicitly change from -> Foo to -> Result<Foo,!>any Result<Foo,MyErr> types would have their Error types implicitly be converted to enum AnonMyErrWrapper { Die(!),Error}
(Technical Digression 1) Errors and results aren’t special in any way; they’re just conventions. The compiler can’t know if a function already returns an “error” because the compiler can’t distinguish between an error and a normal return type (they look the same).
(Technical Digression 2) ! is just a type for things that cannot be “instantiated” (no value of that type can exist). The only relation to panic!() is that panic “returns” ! because panic!() never returns. This means that, logically, value(a) is (type(A) OR type(!)) reduces to value(a) is type(A). So, if you tried to statically analyse Result<Foo, !>, your static analysis program would just reduce it to Foo and you’d be back where you started.
The benefit, of course, being that exceptions are effectively lifted into the type system, and it would be possible to reason about them, perform static analysis on them, etc.
One usually can’t (or doesn’t want to) reason about panics. That’s the entire point of having them; they’re an escape hatch to let the programmer toss in the proverbial towel.
So, it looks like you want a way to statically prove constraints about your program. Instead of a runtime panic!(), you want a compile-time statically_unreachable!() (one could use ! as a value to indicate that some block of code is unreachable). Unfortunately, this is impossible to do in the general case (due to the halting problem) and hard to do even in limited cases. This is generally called certified programming and often requires the programmer to either write their programs in non turing complete languages or manually prove their programs correct. If you’re interested in this subject, take a look at Coq.