Skip to content

[WIP] Support --typecheck-only for fsi run (just typecheck, no execution) - #18687

Merged
T-Gro merged 16 commits into
mainfrom
copilot/fix-18686
Aug 4, 2025
Merged

[WIP] Support --typecheck-only for fsi run (just typecheck, no execution)#18687
T-Gro merged 16 commits into
mainfrom
copilot/fix-18686

Conversation

CopilotAI commented Jun 12, 2025

Copy link
Copy Markdown
Contributor

Thanks for assigning this issue to me. I'm starting to work on it and will keep this PR's description up to date as I form a plan and make progress.

Original issue description:

Instructions for Adding --typecheck-only Support to F# Interactive Scripts

Problem Statement

The --typecheck-only flag already exists for F# project compilation but is not supported for .fsx script files in F# Interactive (FSI). Currently, there's no way to type-check scripts without executing them through the FSI command line. This feature would allow developers to validate script syntax and types without running potentially side-effect-producing code.

Implementation Steps

1. Add Command Line Option

Add the --typecheck-only option to the FSI command line parser. Insert a new CompilerOption in the advanced options section:

CompilerOption("typecheck-only","", OptionUnit(fun()-> tcConfigB.typeCheckOnly <-true), None, Some("Type-check only, don't execute"))

This should be added alongside other advanced options like exec, gui, quiet, etc.

2. Modify ProcessInputs Function

The core implementation goes in the ProcessInputs function. In 2 , add a check after CheckClosedInputSet and before ProcessTypedImpl:

lettcState,topCustomAttrs,declaredImpls,tcEnvAtEndOfLastInput =
lock tcLockObject (fun _ ->
CheckClosedInputSet(
ctok,(fun()-> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings),
tcConfig,
tcImports,
tcGlobals,
Some prefixPath,
tcState,
eagerFormat,
inputs
))// Add this check after CheckClosedInputSetif tcConfig.typeCheckOnly then
raise StopProcessing
letcodegenResults,optEnv,fragName =
ProcessTypedImpl(...)

3. Exception Handling

The StopProcessing exception is already handled . This infrastructure will properly catch the exception and stop processing without executing the script.

Testing Implementation

Test Location and Structure

All tests should be added to the FSharp.Compiler.ComponentTests project.

Create a new test file:
tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs

Test Implementation

moduleFSharp.Compiler.ComponentTests.Scripting.TypeCheckOnlyTestsopenXunitopenFSharp.TestopenFSharp.Test.Compiler[<Fact>]let``typecheck-only flag works for valid script``()=
Fsx """let x = 42printfn "This should not execute""""|> withOptions ["--typecheck-only"]|> compile
|> shouldSucceed
[<Fact>]let``typecheck-only flag catches type errors``()=
Fsx """let x: int = "string" // Type error"""|> withOptions ["--typecheck-only"]|> compile
|> shouldFail
|> withDiagnostics [(Error 1, Line 2, Col 14, Line 2, Col 22,"This expression was expected to have type\n 'int' \nbut here has type\n 'string'")][<Fact>]let``typecheck-only flag prevents execution side effects``()=
Fsx """System.IO.File.WriteAllText("test-file.txt", "should not be created")let x = 42"""|> withOptions ["--typecheck-only"]|> compile
|> shouldSucceed
// Verify file was not created (test would need additional verification logic)

Project File Update

Add the new test file:

<CompileInclude="Scripting/TypeCheckOnlyTests.fs" />

Test Utilities

The ComponentTests project references Test utilities , which provides testing utilities like Fsx, withOptions, compile, shouldSucceed, and shouldFail.

Key Implementation Notes

  1. The --typecheck-only flag already exists in the core F# compiler configuration (TcConfigBuilder), so you're primarily adding FSI-specific handling.

  2. The ProcessInputs function is the correct location for this check because it occurs after parsing and type-checking but before code generation and execution.

  3. The StopProcessing exception mechanism is already established in FSI for handling compilation-stopping conditions.

  4. All new tests should use the ComponentTests project following modern F# testing practices.

This implementation will allow users to run fsi --typecheck-only script.fsx to validate script correctness without execution.

Fixes#18686.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@T-Gro

Copy link
Copy Markdown
Member

@copilot try again pls

@github-actions

github-actionsBot commented Jun 12, 2025

Copy link
Copy Markdown
Contributor

❗ Release notes required


✅ Found changes and release notes in following paths:

Warning

No PR link found in some release notes, please consider adding it.

Change pathRelease notes pathDescription
src/Compilerdocs/release-notes/.FSharp.Compiler.Service/10.0.100.mdNo current pull request URL (#18687) found, please consider adding it

Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>

CopilotAI commented Jun 12, 2025

Copy link
Copy Markdown
ContributorAuthor

@copilot try again pls

I've implemented the --typecheck-only support for FSI as requested. The implementation includes:

  1. Added the --typecheck-only command line option to FSI advanced options
  2. Added the logic to stop processing after type checking when the flag is used
  3. Created comprehensive tests for the functionality

The changes are minimal and surgical, following the existing patterns in the codebase. Commit a8db5c6 contains the complete implementation.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • s8mvsblobprodcus38.vsblob.vsassets.io
    • Triggering command: /usr/share/dotnet/dotnet msbuild /m /nologo /clp:Summary /v:minimal /nr:true /warnaserror /p:TreatWarningsAsErrors=true /p:ContinuousIntegrationBuild=false /home/REDACTED/work/fsharp/fsharp/artifacts/toolset/restore.proj /t:__WriteToolsetLocation /clp:ErrorsOnly;NoSummary /p:__ToolsetLocationOutputFile=/home/REDACTED/work/fsharp/fsharp/artifacts/toolset/10.0.0-beta.25271.2.txt (dns block)
    • Triggering command: dotnet build tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj --verbosity quiet (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
@T-Gro

Copy link
Copy Markdown
Member

@copilot :

In the side effect test: rather than generating a file as the side effect which needs cleanup, just have the script print a string to the console. And use verifyOutput "MyCrazyString"

You will need to add a not contains version though.
perhaps:
VerifyNotInOutput "MyCrazyString"

…effects
Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>

CopilotAI commented Jun 16, 2025

Copy link
Copy Markdown
ContributorAuthor

@copilot :

In the side effect test: rather than generating a file as the side effect which needs cleanup, just have the script print a string to the console. And use verifyOutput "MyCrazyString"
...

Updated the tests to use console output with printfn "MyCrazyString" instead of file creation. Added the VerifyNotInOutput function for negative verification and updated the tests to use verifyOutput "MyCrazyString" for the positive case and VerifyNotInOutput "MyCrazyString" for the negative case. Commit bd5aa05 contains these changes.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • s8mvsblobprodcus38.vsblob.vsassets.io
    • Triggering command: dotnet test tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj --filter DisplayName~TypeCheckOnlyTests --verbosity normal (dns block)
    • Triggering command: dotnet build tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj --verbosity quiet (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Comment threadtests/FSharp.Test.Utilities/Compiler.fs
@T-Gro

Copy link
Copy Markdown
Member

/run ilverify

@github-actions

Copy link
Copy Markdown
Contributor

🔧 CLI Command Report

  • Command:/run ilverify
  • Outcome: failure

❌ Command failed — no patch applied.

@T-Gro

Copy link
Copy Markdown
Member

@copilot :

Add release notes to docs/release-notes/.FSharp.Compiler.Service/10.0.100.md please.
Keep existing format, put it under "Added" section.

Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>

CopilotAI commented Jul 29, 2025

Copy link
Copy Markdown
ContributorAuthor

@copilot :

Add release notes to docs/release-notes/.FSharp.Compiler.Service/10.0.100.md please.
...

Added release notes for the --typecheck-only flag in docs/release-notes/.FSharp.Compiler.Service/10.0.100.md under the "Added" section. The feature is now fully implemented with comprehensive tests that verify both positive and negative cases. Commit 0140ab0 includes the release notes.

@T-Gro

Copy link
Copy Markdown
Member

/run ilverify

@github-actions

Copy link
Copy Markdown
Contributor

🔧 CLI Command Report

  • Command:/run ilverify
  • Outcome: failure

❌ Command failed — no patch applied.

Comment threadsrc/Compiler/Driver/CompilerOptions.fs
Comment threadsrc/Compiler/Interactive/fsi.fs
- Update FSI help baselines to include new --typecheck-only option in help output
- Update ILVerify baselines to fix line number shifts caused by code additions
Co-authored-by: T-Gro <46543583+T-Gro@users.noreply.github.com>
CopilotAI requested a review from T-GroJuly 30, 2025 15:59
@T-Gro

Copy link
Copy Markdown
Member

/run ilverify

@github-actions

Copy link
Copy Markdown
Contributor

🔧 CLI Command Report

  • Command:/run ilverify
  • Outcome: failure

❌ Command failed — no patch applied.

@T-Gro

Copy link
Copy Markdown
Member

/run ilverify

@github-actions

Copy link
Copy Markdown
Contributor

🔧 CLI Command Report

  • Command:/run ilverify
  • Outcome: success

✅ Patch applied:
- Files changed: 4
- Lines changed: 114

@T-Gro
T-Gro merged commit 9d2797a into mainAug 4, 2025
36 checks passed
@T-Gro
T-Gro deleted the copilot/fix-18686 branch August 4, 2025 10:25
Sign up for freeto 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.

Support --typecheck-only for fsi run (just typecheck, no execution)

4 participants

@T-Gro@abonie@actions-user