Merged
Conversation
Creates docs/feature-elif-preprocessor.md covering motivation, semantics, spec grammar changes, tooling impact, and compatibility for the #elif preprocessor directive (fslang-suggestions#1370).
Add #elif support to the F# lexer with IfDefElif stack entry tracking first-match-wins semantics. The lexer correctly handles: - Basic #if/#elif/#else/#endif chains - Multiple #elif directives - Nested #elif inside other #if blocks - Error cases (#elif after #else, #elif without #if) - Language version gating (requires --langversion:11.0) Fix IDE state serialization to use 2 bits per ifdef stack entry (00=if, 01=else, 10=elif) so IfDefElif state survives encodeLexCont/decodeLexCont round-trips correctly.
…Skip path Add CheckLanguageFeatureAndRecover for PreprocessorElif in the n > 0 branch of the ifdefSkip rule, matching the existing check in the n = 0 path. Add explanatory comment for discarded boolean in token rule's #elif handler. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Test exercises the ifdefSkip rule's n > 0 branch with --langversion:10.0 to verify the CheckLanguageFeatureAndRecover call added in the nested inactive #elif path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- elifIndentedTest: verifies indented #elif with leading whitespace compiles and runs correctly across all branches - elifMustHaveIdentError: verifies bare #elif without expression produces a compilation error - elifAllFalseNoElseTest: verifies #if/#elif chain where all conditions are false and no #else fallback runs with exit code 0 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- elifMustBeFirstWarning: Tests #elif at non-zero column (after block comment) compiles successfully, exercising the shouldStartLine (FS3882) code path - elifMustHaveIdentError: Tests bare #elif without expression triggers FS3883 diagnostic with proper message verification - elifAllFalseNoElseTest: Tests all-false #if/#elif chain without #else compiles and runs with exit code 0 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- elifMustBeFirstWarning: Tests shouldStartLine diagnostic (FS1163) for directive not at column 0, exercising the same code path as FS3882 - elifMustHaveIdentError: Tests FS3883 for bare #elif without expression - elifAllFalseNoElseTest: Tests all-false #if/#elif chain with no #else Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the #if-based proxy test (FS1163) with a proper #elif test that triggers FS3882. Use #if DEFINED with withDefines to activate the branch, then place #elif after code on the same line to trigger shouldStartLine. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- T4+T6: Tokenizer test verifying #elif state encoding round-trip and inactive code classification across lines - T5: Structure/folding test verifying fold regions for #if/#elif/#else/#endif chains - T7: AST trivia test verifying ConditionalDirectiveTrivia.Elif appears in parsed syntax tree Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Q1: Extract evalAndSaveElif helper in lex.fsl ifdefSkip rule - Q2: Merge Else/Elif arms in ServiceStructure.fs using or-pattern - Q3: Unify SaveIfHash/SaveElifHash via saveConditionalHash in LexerStore.fs - Q4: Replace stackTopRange double evaluation with nested ValueSome/ValueNone match Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- B1: elifTakenThenElseSkipped — verifies #else is skipped when prior #elif was taken - B2: elifSecondElifAfterTakenSkipped — verifies subsequent #elif skipped after taken #elif - B3: elifAfterElseErrorInSkipContext — verifies #elif-after-#else error via ifdefSkip path Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Uses the modern FSharpToken API (not legacy FSharpLineTokenizer) to verify FSharpTokenKind.HashElif is emitted for #elif directives. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove redundant `let m = lexbuf.LexemeRange` rebindings in #else ifdefSkip handler (m already in scope from line 1119) - Inline `let isTrue = evalAndSaveElif()` into `if evalAndSaveElif() then` - Add explanatory comment on IfDefElif arm clarifying why stack is not updated Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Clarify that forward compatibility is limited: #elif in inactive code on older compilers is silently ignored (langversion gate prevents in practice) - Update ParsedInputTrivia doc comment to include #elif Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
T-Gro
commented
Feb 18, 2026
Member
Author
|
/run fantomas |
Contributor
🔧 CLI Command Report
✅ Command succeeded, no changes needed. |
Member
Author
|
/run fantomas |
Contributor
🔧 CLI Command Report
✅ Command succeeded, no changes needed. |
Member
Author
|
/run ilverify |
Contributor
🔧 CLI Command Report
✅ Command succeeded, no changes needed. |
- Move 3882,lexHashElifMustBeFirst and 3883,lexHashElifMustHaveIdent to end of FSComp.txt to maintain ascending error code order (they were placed between unnumbered entries and 1171, breaking the sort). - Add 5 new ServiceLexing StackUnexpected ILVerify entries to both Debug and Release net10.0 baselines for the new #elif lexer paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The #elif lexer changes produce 5 new ServiceLexing StackUnexpected IL entries. These need to be added to the netstandard2.0 baselines (Debug + Release). The net10.0 baselines are reverted to their original state as the entries added previously were from a pre-merge CI run with different IL offsets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
netstandard2.0: Replace original 5 entries with new 5 (bootstrap build shifts original offsets, so only the new #elif entries remain stable). net10.0: Add 5 new entries alongside existing 5 (10 total). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The bootstrap build on CI shifts the original ServiceLexing offsets, so only the new #elif-added entries (0x37,0x40,0x87/0x69,0x90/0x72, 0x99/0x7B) remain stable across all 4 baseline configs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
abonie
reviewed
Feb 20, 2026
abonie
reviewed
Feb 20, 2026
abonie
approved these changes
Feb 20, 2026
Member
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
T-Gro
added a commit
that referenced
this pull request
Mar 6, 2026
* Type checker: recover on argument/overload checking (#19314) * [main] Update dependencies from dotnet/arcade (#19333) * Update dependencies from https://github.com/dotnet/arcade build 20260219.2 On relative base path root Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26117.6 -> To Version 10.0.0-beta.26119.2 * Update dependencies from https://github.com/dotnet/arcade build 20260223.2 On relative base path root Microsoft.DotNet.Arcade.Sdk From Version 10.0.0-beta.26117.6 -> To Version 10.0.0-beta.26123.2 --------- Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> * [main] Source code updates from dotnet/dotnet (#19343) * Backflow from https://github.com/dotnet/dotnet / 854c152 build 302768 [[ commit created by automation ]] * Update dependencies from build 302768 No dependency updates to commit [[ commit created by automation ]] * Backflow from https://github.com/dotnet/dotnet / 51587e2 build 302820 [[ commit created by automation ]] * Update dependencies from build 302820 No dependency updates to commit [[ commit created by automation ]] --------- Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: Tomas Grosup <Tomas.Grosup@gmail.com> * Update image used for insert into VS step (#19357) * Fix :: FAR :: Remove corrupted .ctor symbol reference (#19358) * DotNetBuildUseMonoRuntime stackguard (#19360) * Fsharp.Core :: {Array;List;Set;Array.Parallel} partitionWith (taking Choice<T,U> partitioner) (#19335) * Sort out some outstanding issues after xUnit upgrade (#19363) * Improve collection comparison diagnostics in tests (#19365) Added shouldBeEqualCollections to Assert.fs for detailed collection comparison, including reporting missing/unexpected items and positional differences. Updated Project25 symbol uses test to use this helper and print actual/expected values for easier debugging. * Enhance the compiler to produce a FS0750 error on let! or use! outside a CE (#19347) * Update to latest .NET 10 SDK patch (#19350) * Feature: `#elif` preprocessor directive (#19323) * Support #exit;; as alias to #quit;; in fsi (#19329) * Checker: prevent reporting optional parameter rewritten tree symbols (#19353) * Improve static compilation of state machines (#19297) * Add FSC compiler options tests (#19348) * Update dependencies from https://dev.azure.com/dnceng/internal/_git/dotnet-optimization build 20260226.1 (#19366) On relative base path root optimization.linux-arm64.MIBC.Runtime , optimization.linux-x64.MIBC.Runtime , optimization.windows_nt-arm64.MIBC.Runtime , optimization.windows_nt-x64.MIBC.Runtime , optimization.windows_nt-x86.MIBC.Runtime From Version 1.0.0-prerelease.26117.2 -> To Version 1.0.0-prerelease.26126.1 Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> * Fix Get-PrBuildIds.ps1 reporting SUCCESS while builds in progress (#19313) * Fix flaky Project25 TP test by replacing FSharp.Data NuGet with TestTP (#19364) (#19373) Replace FSharp.Data (resolved via NuGet at runtime) with the built-in TestTP type provider for the Project25 symbol API tests. This fixes non-deterministic test failures on Linux CI caused by Directory.GetFiles returning DLLs in random inode order on ext4, which varied whether the FSharp.Data namespace was tagged as 'provided' or not. Changes: - Replace 70-line NuGet restore/staging setup with 2-line TestTP reference - Update source to use ErasedWithConstructor.Provided.MyType instead of FSharp.Data.XmlProvider - Replace brittle exact-match symbol list with targeted assertions for provided types, methods, and namespaces - Remove FactSkipOnSignedBuild (TestTP is always available after build) - Rename test variables to match the types being tested Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add automatic merge flow from main to feature/net11-scouting (#19283) * Optimize Set.intersect symmetry and add release notes (#19292) Co-authored-by: Ahmed <w0lf@192.168.1.8> * Fix strong name signature size to align with Roslyn for public signing (#11887) (#19242) * Use culture-independent `IndexOf` in interpolated string parsing (#19370) * Rename "inline hints" to "inlay hints" (#19318) * Rename "inline hints" to "inlay hints" for LSP consistency Aligns F#-owned terminology with LSP and VS Code conventions. The Roslyn ExternalAccess types (IFSharpInlineHintsService, etc.) are left unchanged as they are owned by Roslyn. Fixes #16608 * Add release note for inline-to-inlay hints rename --------- Co-authored-by: Tomas Grosup <Tomas.Grosup@gmail.com> * FCS: capture additional types during analysis (#19305) * remove duplicate FlatErrors file (#19383) * Update dependencies from https://github.com/dotnet/arcade build 20260302.1 (#19379) [main] Update dependencies from dotnet/arcade * [main] Update dependencies from dotnet/msbuild (#19021) * Update dependencies from https://github.com/dotnet/msbuild build 20251021.3 On relative base path root Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.1.0-preview-25515-01 -> To Version 18.1.0-preview-25521-03 * Update dependencies from https://github.com/dotnet/msbuild build 20251023.2 On relative base path root Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.1.0-preview-25515-01 -> To Version 18.1.0-preview-25523-02 * Update dependencies from https://github.com/dotnet/msbuild build 20251024.3 On relative base path root Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.1.0-preview-25515-01 -> To Version 18.1.0-preview-25524-03 * Update dependencies from https://github.com/dotnet/msbuild build 20251027.5 On relative base path root Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.1.0-preview-25515-01 -> To Version 18.1.0-preview-25527-05 * Update dependencies from https://github.com/dotnet/msbuild build 20251027.6 On relative base path root Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.1.0-preview-25515-01 -> To Version 18.1.0-preview-25527-06 * Update dependencies from https://github.com/dotnet/msbuild build 20251104.4 On relative base path root Microsoft.Build , Microsoft.Build.Framework , Microsoft.Build.Tasks.Core , Microsoft.Build.Utilities.Core From Version 18.1.0-preview-25515-01 -> To Version 18.1.0-preview-25554-04 * Bump dependency versions in Version.Details.props Updated package versions for several dependencies. --------- Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: Tomas Grosup <Tomas.Grosup@gmail.com> * Add fsharp-release-announcement agent (#19390) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Seq.empty rendering as "EmptyEnumerable" in serializers (#19317) * Update FileContentMapping.fs (#19391) * Fix flaky help_options test: restore enableConsoleColoring after mutation (#19385) * Initial plan * Fix flaky help_options test by saving/restoring enableConsoleColoring global The `fsc --consolecolors switch` test mutates the global `enableConsoleColoring` via `--consolecolors-`. When help_options tests run after this test, the help output says "(off by default)" instead of "(on by default)", causing baseline mismatches. Fix: save and restore `enableConsoleColoring` around the test. Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com> Co-authored-by: Tomas Grosup <Tomas.Grosup@gmail.com> * isolate checker (#19393) Isolate type-provider tests with dedicated FSharpChecker Introduce Project25.checker to avoid shared state races in type-provider tests. All relevant test cases now use this dedicated instance, improving test isolation, reliability, and determinism without changing test functionality. * Introduce CallRelatedSymbolSink to avoid affect name resolution with related symbols (#19361) * Add RelatedSymbolUseKind flags enum and separate sink for related symbols Address auduchinok's review comments on PR #19252: related symbols (union case testers, copy-and-update record types) are now reported via a separate NotifyRelatedSymbolUse sink instead of abusing NotifyNameResolution. - Add [<Flags>] RelatedSymbolUseKind enum (None/UnionCaseTester/CopyAndUpdateRecord/All) - Add NotifyRelatedSymbolUse to ITypecheckResultsSink interface - Refactor RegisterUnionCaseTesterForProperty to use the new sink - Refactor copy-and-update in TcRecdExpr to use CallRelatedSymbolSink - Add ?relatedSymbolKinds parameter to GetUsesOfSymbolInFile (default: None) - Wire up VS FAR to pass relatedSymbolKinds=All - Write related symbols to ItemKeyStore for background FAR - Update semantic classification tests: tester properties now classified as Property (not UnionCase) since they're no longer in capturedNameResolutions * Add release notes for FSharp.Compiler.Service 11.0.100 --------- Co-authored-by: Eugene Auduchinok <eugene.auduchinok@gmail.com> Co-authored-by: dotnet-maestro[bot] <42748379+dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com> Co-authored-by: Tomas Grosup <Tomas.Grosup@gmail.com> Co-authored-by: Adam Boniecki <20281641+abonie@users.noreply.github.com> Co-authored-by: Jakub Majocha <1760221+majocha@users.noreply.github.com> Co-authored-by: Evgeny Tsvetkov <61620612+evgTSV@users.noreply.github.com> Co-authored-by: Youssef Victor <youssefvictor00@gmail.com> Co-authored-by: Bozhidar Batsov <bozhidar@batsov.dev> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Ahmed Waleed <ahmedwalidahmed.0@gmail.com> Co-authored-by: Ahmed <w0lf@192.168.1.8> Co-authored-by: Brian Rourke Boll <brianrourkeboll@users.noreply.github.com> Co-authored-by: Apoorv Darshan <ad13dtu@gmail.com> Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Inspired by and following up from #19045 by @Thorium.
RFC FS-1334 · Suggestion #1370
What
Supports
&&,||,!in conditions, nesting, and arbitrary chaining. Gated behind--langversion:11.0.Design decisions
IfDefElifstack entry (not reusingIfDefElse) — lets the lexer distinguish "a branch was taken" from "we are in #else". Uses 2-bit encoding in the IDE ifdef stack, reducing max nesting from 24 to 12 (plenty).lexHashElifNoMatchingIf,lexHashElifAfterElse,lexHashElifMustBeFirst,lexHashElifMustHaveIdent) instead of reusing #else error messages.ConditionalDirectiveTrivia.Elifcase added to syntax trivia — enables fold regions, colorization, and grayout in VS without any editor-side changes.Future work (other repos)
#elif(parse + format roundtrip)#elifgrayout, folding, and completion work end-to-end