Skip to content
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

Treat { new Foo() } as SynExpr.ObjExpr #17388

Merged
merged 14 commits into from
Jul 29, 2024

Conversation

edgarfgp
Copy link
Contributor

@edgarfgp edgarfgp commented Jul 7, 2024

Description

I propose we unify { new Foo }, { new Foo() } and { New Foo with ... } as SynExpr.ObjExpr

Before

fantomas tools

{ new Foo  }   // Parsed as SynExpr.ObjExpr

{ new Foo() }  // Parsed as SynExpr.ComputationExpr

{ new Foo() with member this.Bar() = () }  // Parsed as SynExpr.ObjExpr

After

{ new Foo() } will still be parsed as SynExpr.ComputationExpr but instead we will re-write this to SynExpr.ObjExpr e.g.

{ new Foo  }   // Parsed as SynExpr.ObjExpr

{ new Foo() }  // Still Parsed as SynExpr.ComputationExpr 

{ new Foo() with member this.Bar() = () }  // Parsed as SynExpr.ObjExpr

// We are re-writing to  SynExpr.ObjExpr  If a SynExpr.ComputationExpr body consists of a single SynExpr.New, we should convert it to a SynExpr.ObjExpr/
match .. with
 | SynExpr.ComputationExpr(false, SynExpr.New(_, targetType, expr, m), _) ->       
    false, SynExpr.ObjExpr(targetType, Some(expr, None), None, [], [], [], m, rhsExpr.Range), overallTy, overallTy

Motivation

[<AbstractClass>]
type Foo() = class end

let foo = { new Foo() }

The above snippet reports 3 different errors.

  • Invalid object expression. Objects without overrides or interfaces should use the expression form 'new Type(args)' without braces.
  • Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq { ... }'
  • Instances of this type cannot be created since it has been marked abstract or not all methods have been given implementations. Consider using an object expression '{ new ... with ... }' instead.

After this PR it will only report 1 error.

  • Invalid object expression. Objects without overrides or interfaces should use the expression form 'new Type(args)' without braces.

Checklist

  • Test cases added
  • Release notes entry updated

@edgarfgp edgarfgp changed the title `SynExpr.ObjExpr unification SynExpr.ObjExpr unification Jul 7, 2024
Copy link
Contributor

github-actions bot commented Jul 7, 2024

❗ Release notes required


✅ Found changes and release notes in following paths:

Change path Release notes path Description
src/Compiler docs/release-notes/.FSharp.Compiler.Service/9.0.100.md

@edgarfgp edgarfgp changed the title SynExpr.ObjExpr unification Treat { new Foo() } as SynExpr.ObjExpr Jul 7, 2024
@edgarfgp edgarfgp force-pushed the unify-syn-expr-obj-expr branch from 52d6f93 to bdc84e4 Compare July 7, 2024 12:28
@edgarfgp edgarfgp marked this pull request as ready for review July 7, 2024 14:04
@edgarfgp edgarfgp requested a review from a team as a code owner July 7, 2024 14:04
@psfinaki
Copy link
Member

psfinaki commented Jul 8, 2024

Naive question, how hard would it be to fix the problem in the parser, as in - stop parsing { new Foo() } as ComputationExpr? Or is it just about avoiding breaking changes here?

@edgarfgp
Copy link
Contributor Author

edgarfgp commented Jul 8, 2024

Naive question, how hard would it be to fix the problem in the parser, as in - stop parsing { new Foo() } as ComputationExpr? Or is it just about avoiding breaking changes here?

Yeah. That was first attempt(Update the parser and some how fix the described conflict here. But then realized the described rule conflict might out of date now that there are implicit yields.

If an expression like { new Foo() } were in function argument position, like expr { new Foo() } , and if the function expression's type were a computation expression builder type, then { new Foo() } should be parsed as a SynExpr.ComputationExpr with an implicit yield.

So I think our best bet for now is to re-write during type checking like proposed in this PR.

@edgarfgp
Copy link
Contributor Author

edgarfgp commented Jul 8, 2024

@vzarytovskii Do we also need to update the 9.0 release notes ?

@vzarytovskii
Copy link
Member

vzarytovskii commented Jul 8, 2024

@vzarytovskii Do we also need to update the 9.0 release notes ?

only 9.0.1xx, not 8.0.xxx as it's this time of the year when I locked the repo to bump version and change a bunch of defaults, so we can set up insertions in net9 only and bump TFM and language version

@T-Gro T-Gro self-requested a review July 8, 2024 17:14
@vzarytovskii vzarytovskii self-requested a review July 8, 2024 17:17
@edgarfgp
Copy link
Contributor Author

Would love some feedback. Thanks

@psfinaki
Copy link
Member

@edgarfgp we've discussed this in the team briefly recently - the motivation of the PR is good here, we need to think if there is any better approach. This one is reasonable, just not traditional. If we cannot think of anything better, we can probably get this in like it is now.

I understand this is a prior work and we appreciate you doing things in small chunks! That said, currently we are directing a lot of our time and energy into reviewing the nullness PR - we want to merge it ASAP to properly battletest it for .NET 9. You will help us a lot if you take a glance there also, since you've touched some of the code areas in your work :)

@edgarfgp
Copy link
Contributor Author

@edgarfgp we've discussed this in the team briefly recently - the motivation of the PR is good here, we need to think if there is any better approach. This one is reasonable, just not traditional. If we cannot think of anything better, we can probably get this in like it is now.

I understand this is a prior work and we appreciate you doing things in small chunks! That said, currently we are directing a lot of our time and energy into reviewing the nullness PR - we want to merge it ASAP to properly battletest it for .NET 9. You will help us a lot if you take a glance there also, since you've touched some of the code areas in your work :)

Thanks @psfinaki. My approach here is similar to what @brianrourkeboll took in #17352

@brianrourkeboll
Copy link
Contributor

@edgarfgp we've discussed this in the team briefly recently - the motivation of the PR is good here, we need to think if there is any better approach. This one is reasonable, just not traditional. If we cannot think of anything better, we can probably get this in like it is now.
I understand this is a prior work and we appreciate you doing things in small chunks! That said, currently we are directing a lot of our time and energy into reviewing the nullness PR - we want to merge it ASAP to properly battletest it for .NET 9. You will help us a lot if you take a glance there also, since you've touched some of the code areas in your work :)

Thanks @psfinaki. My approach here is similar to what @brianrourkeboll took in #17352

Right. In fact, if we updated the parser to treat { new Foo() } as SynExpr.ObjExpr instead of SynExpr.ComputationExpr, we'd still need to rewrite that to SynExpr.ComputationExpr in a scenario like builder { new Foo() } anyway. So I'm not sure there's an easy way to avoid AST adjustments during typechecking altogether.

@edgarfgp
Copy link
Contributor Author

This is a prior work to implement a lang suggestion see PR description. Let me know if this PR is clear or you need something else for me to address.

@edgarfgp edgarfgp force-pushed the unify-syn-expr-obj-expr branch from 3a23fe0 to 8a04c37 Compare July 18, 2024 19:00
@psfinaki
Copy link
Member

/azp run

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@edgarfgp edgarfgp closed this Jul 23, 2024
@edgarfgp edgarfgp reopened this Jul 23, 2024
@psfinaki
Copy link
Member

Hey @edgarfgp, sorry this takes time, we were busy with nullness PR for a while. As for this PR, @T-Gro wanted to take a deep look but is off now for a few days. We keep track of this.

I personally now cannot see any better way to do what you're trying to achieve and @brianrourkeboll's argumentation seems convincing to me. But please allow us some more time here.

@edgarfgp
Copy link
Contributor Author

Patience is not passive, on the contrary, it is concentrated strength. Bruce Lee

@vzarytovskii vzarytovskii enabled auto-merge (squash) July 27, 2024 21:13
auto-merge was automatically disabled July 28, 2024 14:01

Head branch was pushed to by a user without write access

@vzarytovskii vzarytovskii enabled auto-merge (squash) July 28, 2024 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants