Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@nojaf
Copy link
Contributor

@nojaf nojaf commented Nov 14, 2025

Description

As mentioned on #18825 (comment)
It would be most convenient if a SynBinding holds all the information to print itself on its own.

By extending SynLeadingKeyword we can do exactly that.

  • Test cases added

  • Performance benchmarks added in case of performance changes

  • Release notes entry updated:

    Please make sure to add an entry with short succinct description of the change as well as link to this pull request to the respective release notes file, if applicable.

    Release notes files:

    • If anything under src/Compiler has been changed, please make sure to make an entry in docs/release-notes/.FSharp.Compiler.Service/<version>.md, where <version> is usually "highest" one, e.g. 42.8.200
    • If language feature was added (i.e. LanguageFeatures.fsi was changed), please add it to docs/release-notes/.Language/preview.md
    • If a change to FSharp.Core was made, please make sure to edit docs/release-notes/.FSharp.Core/<version>.md where version is "highest" one, e.g. 8.0.200.

    Information about the release notes entries format can be found in the documentation.
    Example:

    If you believe that release notes are not necessary for this PR, please add NO_RELEASE_NOTES label to the pull request.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 14, 2025

❗ 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/11.0.0.md

Comment on lines 1112 to 1115
isRecursive = false,
isUse = isUse,
isFromSource = true,
isBang = true,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With completing the SynLeadingKeyword union, can't 3 of the boolean flags be computed from it (as calculated properties, so not even stored) ?

isRecursive,isUse,isBang

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that came to mind as well.
I'm quite sure if all these are used or not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isRecursive is not coming from the leading keyword, it's a separate one. The others can be computed, yes.

@nojaf
Copy link
Contributor Author

nojaf commented Nov 14, 2025

Another issue I saw is the in keyword is not longer preserved correctly in the case of

comp {
    let! a = b in
    and! c = d in
    and! e = f in
    ()
}

I made some changes for that as well so that any SynBinding now holds an InKeyword and not SynExpr.LetOrUse. This used to be part of SynExprAndBang.

@nojaf
Copy link
Contributor Author

nojaf commented Nov 14, 2025

Didn't take this into account yet but should the range of in be part of SynBinding?
Thoughts @auduchinok?

@auduchinok
Copy link
Member

auduchinok commented Nov 14, 2025

Didn't take this into account yet but should the range of in be part of SynBinding?

I'd say no. I see it as a part of a let-expression, not a binding. It's what connects a binding (or multiple recursive ones) with the expression where the bound names can be used.

Even though it only makes sense in let-expressions, it can appear in module- or type-level bindings as a terminator, but currently it's effectively ignored in the resulting tree, so I'd care about the expressions case the most.

I'd put it to SynExpr.LetOrUse and (optionally) to SynModuleDecl.Let and SynMemberDefn.LetBindings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

4 participants