Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
* Fix signature generation: backtick escaping for identifiers containing backticks. ([Issue #15389](https://github.com/dotnet/fsharp/issues/15389), [PR #19586](https://github.com/dotnet/fsharp/pull/19586))
* Fix signature generation: `private` keyword placement for prefix-style type abbreviations. ([Issue #15560](https://github.com/dotnet/fsharp/issues/15560), [PR #19586](https://github.com/dotnet/fsharp/pull/19586))
* Fix signature generation: missing `[<Class>]` attribute for types without visible constructors. ([Issue #16531](https://github.com/dotnet/fsharp/issues/16531), [PR #19586](https://github.com/dotnet/fsharp/pull/19586))
* Fix `let ... in` with explicit `in` keyword in light syntax: body is now scoped to the same line, preventing the parser from greedily capturing subsequent lines as part of the `let` body. ([Issue #7741](https://github.com/dotnet/fsharp/issues/7741), [PR #19501](https://github.com/dotnet/fsharp/pull/19501))

### Added

Expand All @@ -45,3 +46,4 @@
* Improvements in error and warning messages: new error FS3885 when `let!`/`use!` is the final expression in a computation expression; new warning FS3886 when a list literal contains a single tuple element (likely missing `;` separator); improved wording for FS0003, FS0025, FS0039, FS0072, FS0247, FS0597, FS0670, FS3082, and SRTP operator-not-in-scope hints. ([PR #19398](https://github.com/dotnet/fsharp/pull/19398))

### Breaking Changes
* `let ... in` with explicit `in` keyword in light syntax now scopes the body to the same line, preventing the parser from greedily capturing subsequent lines. Code that relied on the old multi-line scoping behavior may need adjustment. ([Issue #7741](https://github.com/dotnet/fsharp/issues/7741), [PR #19501](https://github.com/dotnet/fsharp/pull/19501))
2 changes: 2 additions & 0 deletions docs/release-notes/.Language/preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

### Fixed

* Fix `let ... in` with explicit `in` keyword in light syntax: body is now scoped to the same line, preventing the parser from greedily capturing subsequent lines. ([Issue #7741](https://github.com/dotnet/fsharp/issues/7741), [PR #19501](https://github.com/dotnet/fsharp/pull/19501))

### Changed
1 change: 1 addition & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,7 @@ featureWarnWhenFunctionValueUsedAsInterpolatedStringArg,"Warn when a function va
featureMethodOverloadsCache,"Support for caching method overload resolution results for improved compilation performance."
featureImplicitDIMCoverage,"Implicit dispatch slot coverage for default interface member implementations"
featurePreprocessorElif,"#elif preprocessor directive"
featureLetInBodyScoping,"Scope 'let ... in' body to the same line in sequence expressions"
3880,optsLangVersionOutOfSupport,"Language version '%s' is out of support. The last .NET SDK supporting it is available at https://dotnet.microsoft.com/en-us/download/dotnet/%s"
3881,optsUnrecognizedLanguageFeature,"Unrecognized language feature name: '%s'. Use a valid feature name such as 'NameOf' or 'StringInterpolation'."
3882,lexHashElifMustBeFirst,"#elif directive must appear as the first non-whitespace character on a line"
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/Facilities/LanguageFeatures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ type LanguageFeature =
| MethodOverloadsCache
| ImplicitDIMCoverage
| PreprocessorElif
| LetInBodyScoping

/// LanguageVersion management
type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array) =
Expand Down Expand Up @@ -251,6 +252,7 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array)
// Put stabilized features here for F# 11.0 previews via .NET SDK preview channels
LanguageFeature.WarnWhenFunctionValueUsedAsInterpolatedStringArg, languageVersion110
LanguageFeature.PreprocessorElif, languageVersion110
LanguageFeature.LetInBodyScoping, languageVersion110

// Difference between languageVersion110 and preview - 11.0 gets turned on automatically by picking a preview .NET 11 SDK
// previewVersion is only when "preview" is specified explicitly in project files and users also need a preview SDK
Expand Down Expand Up @@ -453,6 +455,7 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array)
| LanguageFeature.MethodOverloadsCache -> FSComp.SR.featureMethodOverloadsCache ()
| LanguageFeature.ImplicitDIMCoverage -> FSComp.SR.featureImplicitDIMCoverage ()
| LanguageFeature.PreprocessorElif -> FSComp.SR.featurePreprocessorElif ()
| LanguageFeature.LetInBodyScoping -> FSComp.SR.featureLetInBodyScoping ()

/// Get a version string associated with the given feature.
static member GetFeatureVersionString feature =
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Facilities/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ type LanguageFeature =
| MethodOverloadsCache
| ImplicitDIMCoverage
| PreprocessorElif
| LetInBodyScoping

/// LanguageVersion management
type LanguageVersion =
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Interactive/fsi.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1532,7 +1532,7 @@ type internal FsiConsoleInput

/// Try to get the first line, if we snarfed it while probing.
member _.TryGetFirstLine() =
let r = firstLine in
let r = firstLine
firstLine <- None
r

Expand Down
21 changes: 19 additions & 2 deletions src/Compiler/SyntaxTree/LexFilter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1680,8 +1680,25 @@ type LexFilterImpl (
if debug then dprintf "IN at %a (becomes %s)\n" outputPos tokenStartPos (if blockLet then "ODECLEND" else "IN")
if tokenStartCol < offsidePos.Column then warn tokenTup (FSComp.SR.lexfltIncorrentIndentationOfIn())
popCtxt()
// Make sure we queue a dummy token at this position to check if any other pop rules apply
delayToken(pool.UseLocation(tokenTup, ODUMMY token))

if blockLet && lexbuf.SupportsFeature LanguageFeature.LetInBodyScoping then
let nextTokenTup = peekNextTokenTup()
let nextTokenStartPos = startPosOfTokenTup nextTokenTup

if nextTokenStartPos.Line = tokenStartPos.Line then
// When the body expression starts on the same line as the 'in' keyword in light syntax,
// push a new seq block anchored at the body's start column. Offside rules then limit
// the body to the indented block starting on this line, preventing the parser from
// greedily capturing subsequent lines at lower indentation as part of the let body.
pushCtxtSeqBlock tokenTup AddBlockEnd
else
// Body starts on a new line after 'in' — the user intentionally placed the body
// on the next line, so use standard behavior.
delayToken(pool.UseLocation(tokenTup, ODUMMY token))
else
// Make sure we queue a dummy token at this position to check if any other pop rules apply
delayToken(pool.UseLocation(tokenTup, ODUMMY token))

returnToken tokenLexbufState (if blockLet then ODECLEND(mkSynRange tokenTup.StartPos tokenTup.EndPos, true) else token)

// Balancing rule. Encountering a 'done' balances with a 'do'. i.e. even a non-offside 'done' closes a 'do'
Expand Down
2 changes: 1 addition & 1 deletion src/Compiler/Utilities/HashMultiMap.fs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ type internal HashMultiMap<'Key, 'Value when 'Key: not null>(size: int, comparer
| _ -> false

member s.Remove(k: 'Key) =
let res = s.ContainsKey(k) in
let res = s.ContainsKey(k)
s.Remove(k)
res

Expand Down
6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.ru.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.tr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/Compiler/xlf/FSComp.txt.zh-Hans.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading