Fix let-in scoping in light syntax via LexFilter change#19501
Fix let-in scoping in light syntax via LexFilter change#19501
Conversation
|
@copilot : Try again |
|
@copilot : Try again. |
|
@copilot Try again |
Implemented in 4c00982 and 6259b63. Added warning FS3885 (gated behind Changes:
All 520 ErrorMessages tests and 630 BasicGrammar tests pass. |
6259b63 to
e6a52d1
Compare
❗ Release notes required
|
b1c7950 to
10924f8
Compare
| match letOrUse with | ||
| | { Trivia = { InKeyword = Some inRange }; Body = SynExpr.Sequential(expr2 = expr2) } | ||
| when g.langVersion.SupportsFeature LanguageFeature.WarnOnLetInSequenceExpression | ||
| && expr2.Range.StartLine > inRange.StartLine -> | ||
| warning(Error(FSComp.SR.tcLetExpressionWithInHasMultiLineBody(), inRange)) | ||
| | _ -> () |
There was a problem hiding this comment.
@T-Gro Have you considered changing how this is handled by LexFilter? Can we detect a new line there and drop the let context?
There was a problem hiding this comment.
I think I would not be able to avoid breaking changes? A warning can still be silenced, a different decision in LexFilter would affect rest of the compilation process as well.
OR you think this can be done safely?
There was a problem hiding this comment.
I'd vote for a breaking change here. Similar to various cases in fsharp/fslang-suggestions#1273, I think there should be not many cases where such code was written intentionally and could be compiled successfully.
The initially reported issue comes from brute-force checking of various cases to test, not from real code 🙂
…sions Agent-Logs-Url: https://github.com/dotnet/fsharp/sessions/740bb677-5347-48ad-9001-278dfc1631e3 Co-authored-by: abonie <20281641+abonie@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/fsharp/sessions/740bb677-5347-48ad-9001-278dfc1631e3 Co-authored-by: abonie <20281641+abonie@users.noreply.github.com>
…tries - Remove explicit 'in' keyword in HashMultiMap.fs and fsi.fs that triggered the new FS3885 warning (treated as error in CI builds) - Add missing XLF translation entries for featureWarnOnLetInSequenceExpression and tcLetExpressionWithInHasMultiLineBody to all 13 locale files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ests.fs triggering FS3885, fix PR number in release notes, add .Language/preview.md entry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
a37539a to
f37cbfc
Compare
…a9e-b5d2-cc88eecabc17
|
@copilot : Lets try in a separate commit to implement a LexFilter change for I first want to see how it will look like. Do the work and the commit so that I can asses the impact. |
@copilot try this again |
When an explicit 'in' keyword is used with a block-scoped 'let' in light syntax and the body starts on the same line as 'in', push a new seq block context to limit the body scope based on indentation. This prevents the parser from greedily capturing subsequent lines as part of the let body. - Remove type-checking warning from CheckExpressions.fs - Add LexFilter logic: when blockLet=true and body is on same line as 'in', push CtxtSeqBlock with AddBlockEnd to scope the body - Update WarnExpressionTests to reflect new behavior (no FS3885, different parse tree produces different W20 ranges) - Update SyntaxTree baseline for minor range change Agent-Logs-Url: https://github.com/dotnet/fsharp/sessions/1c48edbc-5796-4d9b-a80d-3a3d423c2e3f Co-authored-by: abonie <20281641+abonie@users.noreply.github.com>
Implemented in eaa7a23. Moved the logic from a type-checking warning to a LexFilter change:
Test impact: Only 1 SyntaxTree baseline needed updating (minor range change in |
Addresses the long-standing issue where
let ... inwith an explicitinkeyword in indentation-sensitive F# code causes the parser to greedily capture all subsequent lines as part of theletbody, leading to unexpected scoping behavior.Problem
The parser creates
LetOrUse(let x = 1, Sequential(x + 1, x))instead of the expectedSequential(LetOrUse(let x = 1, x + 1), x), causingxon the second line to resolve to the local binding rather than the outer scope.Changes Made
LanguageFeature.WarnOnLetInSequenceExpressioninLanguageFeatures.fs/fsi, gated at F# 11.0LexFilter.fs, whenblockLet=trueand an explicitINtoken is encountered with the body expression starting on the same line asin, a newCtxtSeqBlockwithAddBlockEndis pushed. This creates anOBLOCKBEGIN/OBLOCKENDwrapper around the body, limiting its scope via indentation — tokens on the next line at a lower column are offside and close the block, preventing greedy capture.in(e.g., chainedlet ... in/let! ... in/and!patterns), standard behavior is preserved.WarnExpressionTests.fscovering scoping indoblocks, function bodies, no change for single-line usage, and no change on older language versions11.0.100.mdTesting
💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.