Skip to content

Allow CE return and type annotations to play well together without needing parentheses #15788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Tracked by #11481
jwosty opened this issue Aug 11, 2023 · 1 comment · May be fixed by #18533
Open
Tracked by #11481

Allow CE return and type annotations to play well together without needing parentheses #15788

jwosty opened this issue Aug 11, 2023 · 1 comment · May be fixed by #18533
Assignees
Labels
Area-Compiler-Syntax lexfilter, indentation and parsing Feature Request
Milestone

Comments

@jwosty
Copy link
Contributor

jwosty commented Aug 11, 2023

Is your feature request related to a problem? Please describe.

I was surprised to learn that the parser doesn't like it when you use a type annotation with return in a CE:

open System

type MyType() =
    interface IDisposable with
        member this.Dispose () = ()

let f () = async {
    // Compile errors here
    return new MyType() : IDisposable
}

Describe the solution you'd like

It would be nice if this didn't result in a compile error. I understand that it's pretty low-impact (because workarounds are very easy here), and that the error probably has to do with parser precedence rules, but it would be a nice-to-have if the fix turns out to be simple. Otherwise, I'm not too broken up about it.

Describe alternatives you've considered

I was also surprised that :> (the upcast operator) works in the same situation:

let f () = async {
    return new MyType() :> IDisposable
}

Other workarounds:

let f () : Async<IDisposable> = async {
    return new MyType()
}
let f () = async {
    return (new MyType() : IDisposable)
}

Additional context

Related: #11481

@smoothdeveloper
Copy link
Contributor

smoothdeveloper commented Nov 12, 2023

@jwosty thanks for reporting this, I think as this is a change to the language, this has to follow suggestion -> RFC before considering changing the parser.

To me, the current behaviour makes sense, because the type annotation is not the same as a cast operator (or anything that expands the expression), there are other similar cases:

let a = async {
   // not ok
  let! b:int = Unchecked.defaultof<int Async>
  () 
}

@edgarfgp edgarfgp self-assigned this Apr 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compiler-Syntax lexfilter, indentation and parsing Feature Request
Projects
Status: New
Development

Successfully merging a pull request may close this issue.

4 participants