The F# compiler throws an InternalError (ICE) during code generation for a use binding if the type has both a standard IDisposable implementation and a matching inline Dispose extension method. It seems BuildDisposableCleanup (or its surrounding logic) expects a single deterministic Dispose method and fails with a match failure or assertion when it finds multiple candidates.
Repro steps
open System
open System.Runtime.CompilerServices
type Disposable() =
interface IDisposable with
member _.Dispose() = ()
[<Extension>]
type PublicExtensions =
[<Extension>]
static member inline Dispose(this: #IDisposable) =
this
let foo() =
use a = new Disposable()
()
foo()
Expected behavior
The compiler should either:
- Apply standard priority rules (Intrinsic over Extension).
- Or, if it's truly ambiguous, report a standard error (e.g.,
FS0041: A unique overload for method 'Dispose' could not be determined).
- Never throw an ICE in a valid (even if ambiguous) scenario.
Actual behavior
The compiler crashes with an internal error instead of resolving the ambiguity or picking the intrinsic method.
Unexpected exception raised in compiler: Couldn't find Dispose on IDisposable, or it was overloaded
FSharp.Compiler.DiagnosticsLogger+InternalError: Couldn't find Dispose on IDisposable, or it was overloaded
Related information
Found it while working on the Issue #19349 in the PR #19536
Problem part:
|
let BuildDisposableCleanup (cenv: cenv) env m (v: Val) = |
|
let g = cenv.g |
|
let ad = env.eAccessRights |
|
|
|
v.SetHasBeenReferenced() |
|
|
|
let disposeMethod = |
|
match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AllResults cenv env m ad "Dispose" g.system_IDisposable_ty with |
|
| [x] -> x |
|
| _ -> error(InternalError(FSComp.SR.tcCouldNotFindIDisposable(), m)) |
- Operating system Win11
- .NET 10
The F# compiler throws an
InternalError (ICE)during code generation for ausebinding if the type has both a standardIDisposableimplementation and a matchinginline Disposeextension method. It seemsBuildDisposableCleanup(or its surrounding logic) expects a single deterministicDisposemethod and fails with a match failure or assertion when it finds multiple candidates.Repro steps
Expected behavior
The compiler should either:
FS0041: A unique overload for method 'Dispose' could not be determined).Actual behavior
The compiler crashes with an internal error instead of resolving the ambiguity or picking the intrinsic method.
Related information
Found it while working on the Issue #19349 in the PR #19536
Problem part:
fsharp/src/Compiler/Checking/Expressions/CheckExpressions.fs
Lines 3145 to 3154 in d507366