Special-case raising an exception with byrefs
Tracking as per here: https://github.com/dotnet/fsharp/issues/5776
We should allow raising exceptions in byref-returning functions and methods, like this:
type Ii<'T> =
abstract GetSpan : int -> ReadOnlySpan<'T>
[<Struct>]
type X(value : int) =
interface Ii<int> with
member _.GetSpan n = ReadOnlySpan()
[<Struct>]
type Y(value : int) =
interface Ii<int> with
member _.GetSpan n = failwith "Nope"
The existing way of approaching this problem in F# is to insert a dummy return value to satisfy the F# compiler:
[<Struct>]
type Y(value : int) =
interface Ii<int> with
member _.GetSpan n = failwith "Nope"; ReadOnlySpan()
The reason why this doesn't work is that the way you raise exceptions in F# is through the raise function, which returns a generic value. Same goes for the other helpers:
-
failwith -
invalidArg -
nullArg -
invalidOp -
reraise -
rethrow -
failwithf
~~Note that @dsyme is not in favor of special casing anything other than raise. I personally think all other than failwithf should be allowed, though that may be worth considering.~~
Pros and Cons
The advantages of making this adjustment to F# are:
- Allowing a fairly common pattern, since exceptions are normal in .NET
The disadvantages of making this adjustment to F# are:
- More special rules for
byrefandbyref-like types
Extra information
Estimated cost (XS, S, M, L, XL, XXL): M
Affidavit (please submit!)
Please tick this by placing a cross in the box:
- [x] This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
- [x] I have searched both open and closed suggestions on this site and believe this is not a duplicate
- [x] This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.
Please tick all that apply:
- [x] This is not a breaking change to the F# language design
- [x] I or my company would be willing to help implement and/or test this
Marking approved. I guess I don't really mind how many of those are special-cased.
Would this be extended to inline functions that raise an error unconditionally? It would make it possible to define custom error functions such as the following:
let inline notPositive name = raise (ArgumentOutOfRangeException(name, name + " must be greater than zero!"))
Never mind. I just realized #688 already addresses the issue.