diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index 54236b3864c..2e58a160d38 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -95,6 +95,7 @@ * Fix Debug-mode compilation when mixing resumable and standard computation expressions. ([Issue #19625](https://github.com/dotnet/fsharp/issues/19625), [PR #19630](https://github.com/dotnet/fsharp/pull/19630)) * IlxGen: fix missing CompilationMapping attribute for generic values ([PR #19643](https://github.com/dotnet/fsharp/pull/19643)) * Fix internal error `FS0192: encodeCustomAttrElemType` when using arrays of user-defined types as custom attribute arguments. Empty arrays (e.g. `[]`) now compile successfully; non-empty arrays of unencodable types report a proper diagnostic (FS3887) instead of an internal error. ([Issue #12796](https://github.com/dotnet/fsharp/issues/12796), [PR #19472](https://github.com/dotnet/fsharp/pull/19472)) +* Fix a compiler crash when calling an inherited base method on an external generic IL type, such as `base.OnDetaching()` on `Microsoft.Xaml.Interactivity.Behavior<'T>`. The IL base-call check now only applies the abstract-base guard when the method actually exists on the raw metadata type instead of crashing while trying to resolve an inherited method. ([Issue #20264](https://github.com/dotnet/fsharp/issues/20264)) * Fix internal compiler error in `use` bindings when a C#-style `Dispose` extension method is in scope alongside `IDisposable.Dispose`. ([Issue #19552](https://github.com/dotnet/fsharp/issues/19552), [PR #19568](https://github.com/dotnet/fsharp/pull/19568)) * Fix signature generation: single-case struct DU gets spurious bar causing FS0300. ([Issue #19597](https://github.com/dotnet/fsharp/issues/19597), [PR #19609](https://github.com/dotnet/fsharp/pull/19609)) * Fix signature generation: backticked active pattern case names lose escaping. ([Issue #19592](https://github.com/dotnet/fsharp/issues/19592), [PR #19609](https://github.com/dotnet/fsharp/pull/19609)) diff --git a/src/Compiler/AbstractIL/il.fsi b/src/Compiler/AbstractIL/il.fsi index aa2e7c69b2f..0f186dc5c09 100644 --- a/src/Compiler/AbstractIL/il.fsi +++ b/src/Compiler/AbstractIL/il.fsi @@ -1262,6 +1262,8 @@ type ILMethodDefs = member FindByName: string -> ILMethodDef list + member internal FindByNameAndArity: string * int -> ILMethodDef list + member TryFindInstanceByNameAndCallingSignature: string * ILCallingSignature -> ILMethodDef option /// Field definitions. diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs index 234783d7f3e..f737b5f43b5 100644 --- a/src/Compiler/Checking/PostInferenceChecks.fs +++ b/src/Compiler/Checking/PostInferenceChecks.fs @@ -1366,15 +1366,17 @@ and CheckILBaseCall cenv env (ilMethRef, enclTypeInst, methInst, retTypes, tyarg // Disallow calls to abstract base methods on IL types. match tryTcrefOfAppTy g baseVal.Type with | ValueSome tcref when tcref.IsILTycon -> - try - let mdef = - match tcref.ILTyconInfo with - | TILObjectReprData(scoref, _, _) -> - resolveILMethodRefWithRescope (rescopeILType scoref) tcref.ILTyconRawMetadata ilMethRef - - if mdef.IsAbstract then - errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(RichText.mkMethod mdef.Name), m)) - with _ -> () + match tcref.ILTyconInfo with + | TILObjectReprData(scoref, _, _) -> + if not (isNil (tcref.ILTyconRawMetadata.Methods.FindByNameAndArity(ilMethRef.Name, ilMethRef.ArgTypes.Length))) then + try + let mdef = + resolveILMethodRefWithRescope (rescopeILType scoref) tcref.ILTyconRawMetadata ilMethRef + + if mdef.IsAbstract then + errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(RichText.mkMethod mdef.Name), m)) + with _ -> + () | _ -> () CheckTypeInstNoByrefs cenv env m tyargs diff --git a/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs b/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs index 00a5781553f..e8b686f7fb8 100644 --- a/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs @@ -223,3 +223,35 @@ let main _ = |> asExe |> compileExeAndRun |> shouldSucceed + + [] + let ``Issue 20264 - inherited generic base method call does not crash`` () = + let csLib = + CSharp + """ +namespace External +{ + public class BehaviorBase { public virtual void OnDetaching() { } } + public class Behavior : BehaviorBase { } +} + """ + |> withName "ExternalBehavior" + + let fsLib = + FSharp + """ +module TestIssue20264 + +open External + +type MyBehavior() = + inherit Behavior() + + override _.OnDetaching() = + base.OnDetaching() + """ + |> withReferences [ csLib ] + + fsLib + |> compile + |> shouldSucceed