-
Notifications
You must be signed in to change notification settings - Fork 851
[ICE] Internal error in BuildDisposableCleanup when multiple Dispose candidates are found #19552
Description
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:
fsharp/src/Compiler/Checking/Expressions/CheckExpressions.fs
Lines 3145 to 3154 in d507366
| 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
Metadata
Metadata
Assignees
Labels
Type
Projects
Status