Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
9e37b2c
Add regression test for #6750: Mutually recursive DU values initializ…
T-Gro Mar 24, 2026
1cd0ca0
Add regression tests for #14308 and #14310: Signature generation impr…
T-Gro Mar 24, 2026
5ee6d09
Add regression test for #16410: no spurious FS3570 with KeyValue acti…
T-Gro Mar 24, 2026
632a0ab
Add regression test for #3841: Hash directive indentation in nested m…
T-Gro Mar 24, 2026
fb1ca7e
Add regression test for #14152: nowarn directive before module declar…
T-Gro Mar 25, 2026
0db49dd
Add regression test: #6929, Literal bindings preserve units of measur…
T-Gro Mar 25, 2026
251aaf2
Add regression test: #3660, array of functions invocation correctness…
T-Gro Mar 25, 2026
a02a655
Infra: Update gh aw (#19495)
T-Gro Mar 26, 2026
880dda8
Fix CLIEvent properties to be recognized as events in Symbol API (#18…
Copilot Mar 26, 2026
2292274
Add regression test: #12067, signature generation preserves FSharp. p…
T-Gro Mar 26, 2026
f647072
Add regression test for #11331: accessibility error for internal type…
T-Gro Mar 26, 2026
1dafcf3
Add regression test for #14216: No FS2303 warning for DU in FSI (#19465)
T-Gro Mar 26, 2026
cbab748
Add regression test for #13697: typeof in attribute should report FS0…
T-Gro Mar 26, 2026
01fe483
Add regression test for #9382: SRTP stress test with matrix inverse (…
T-Gro Mar 26, 2026
a21c12f
Add regression test: #12023, FSI can load System.Drawing.Common via n…
T-Gro Mar 26, 2026
63294d7
Add documentation and tests that maxBy/minBy return the first max/min…
Copilot Mar 27, 2026
0b80769
Bugfix :: Fix type definition metadata: duplicate methods, event flag…
T-Gro Mar 27, 2026
a0cce49
resolve integrity issues in gh aw (#19510)
T-Gro Mar 27, 2026
0c868a5
Add Regression PR Shepherd workflow (#19500)
T-Gro Mar 30, 2026
2adf45d
Improve repo-assist: regression test verification, windows-only revis…
T-Gro Mar 30, 2026
bf62ec0
Update dependencies from https://github.com/dotnet/arcade build 20260…
dotnet-maestro[bot] Mar 30, 2026
df38aef
[main] Update dependencies from dotnet/msbuild (#19493)
dotnet-maestro[bot] Mar 30, 2026
358d088
Add regression test for #3532: FSharpEntity.IsByRef is false for byre…
T-Gro Mar 30, 2026
3ee2a3e
Add regression test for #15655: error codes 999 and 3217 are distinct…
T-Gro Mar 30, 2026
f540da5
Add regression test: #13519, C# optional parameters from F# (#19473)
T-Gro Mar 30, 2026
68fb63d
Add regression test: #6648, DU of DUs with inline static members (#19…
T-Gro Mar 31, 2026
f3b6407
Fix repo-assist: add safe output discipline and iteration limits (#19…
Copilot Mar 31, 2026
7d031d3
Update dependencies from https://github.com/dotnet/msbuild build 2026…
dotnet-maestro[bot] Mar 31, 2026
b0bb2f0
Update dependencies from https://dev.azure.com/dnceng/internal/_git/d…
dotnet-maestro[bot] Mar 31, 2026
8254128
Add aw-auto-update workflow + upgrade to v0.64.4 (#19519)
T-Gro Mar 31, 2026
1775f42
Add regression test for #6715: land is a valid identifier (#19478)
T-Gro Mar 31, 2026
4e25902
[main] Update dependencies from dotnet/roslyn (#19494)
dotnet-maestro[bot] Apr 1, 2026
4b57615
Add regression test: #15987, SRTP overload resolution returns correct…
github-actions[bot] Apr 1, 2026
af3a8eb
Add regression test: #15070, hash-load with dot-slash prefix no longe…
github-actions[bot] Apr 1, 2026
7e0ab7a
Add regression test: #16056, auto property DeclarationLocation correc…
github-actions[bot] Apr 1, 2026
af6c784
Add regression test: #19456, nested let bang in plain let inside task…
github-actions[bot] Apr 1, 2026
02b1081
Add regression test: #16007, SRTP ctor constraint no longer causes va…
github-actions[bot] Apr 1, 2026
9b016f5
Add regression test: #7177, never-matched warning with active pattern…
github-actions[bot] Apr 1, 2026
7580b31
Tests: prevent in-proc fsi from killing test host with "exit" (#19407)
majocha Apr 1, 2026
3550f3c
Add regression test: #9878, SRTP with phantom type parameter (#19467)
T-Gro Apr 1, 2026
6a5df48
Fix FS0452 for empty string pattern matching in quotations (#19532)
Copilot Apr 1, 2026
599a99f
Fix regression-pr-shepherd: bound PR processing per run to prevent co…
Copilot Apr 1, 2026
d507366
Make fsharp-diagnostics skill a directive, not a suggestion (#19520)
T-Gro Apr 1, 2026
d85a74c
Update agentic workflows to v0.67.2 and fix merge conflict (#19556)
T-Gro Apr 8, 2026
6f0e1ed
Fix Regression PR Shepherd: restrict push scope and strengthen PR sel…
Copilot Apr 9, 2026
1f46886
[main] Source code updates from dotnet/dotnet (#19546)
dotnet-maestro[bot] Apr 9, 2026
a88269a
[main] Update dependencies from dotnet/roslyn (#19544)
dotnet-maestro[bot] Apr 10, 2026
85d7cb1
[main] Update dependencies from dotnet/msbuild (#19543)
dotnet-maestro[bot] Apr 10, 2026
0539af7
Add regression test: #16154, task CE with IQueryable filters no longe…
github-actions[bot] Apr 10, 2026
ead77d1
[main] Update dependencies from dotnet/arcade (#19542)
dotnet-maestro[bot] Apr 10, 2026
98c4774
Add regression tests for #10043: backtick, @, and ! in type annotatio…
T-Gro Apr 10, 2026
5bcca43
Fix wrong warning 20 range in sequential expressions (#5735) (#19504)
Copilot Apr 11, 2026
bd2823e
Fix completion inconsistently filtering obsolete fields and events (#…
Copilot Apr 11, 2026
f1b1a57
Map this branch to rel/insiders, set VSMinorVersion=7
abonie May 6, 2026
dba9a97
Merge branch 'release/dev18.6' into release/dev18.6
abonie May 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Bugfix :: Fix type definition metadata: duplicate methods, event flags (
  • Loading branch information
T-Gro authored Mar 27, 2026
commit 0b8076968c6e6d567fe1bd1dd2977de9edd764cf
3 changes: 3 additions & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
### Fixed

* Fix DU case names matching IWSAM member names no longer cause duplicate property entries. (Issue [#14321](https://github.com/dotnet/fsharp/issues/14321), [PR #19341](https://github.com/dotnet/fsharp/pull/19341))
* Fix DefaultAugmentation(false) duplicate entry in method table. (Issue [#16565](https://github.com/dotnet/fsharp/issues/16565), [PR #19341](https://github.com/dotnet/fsharp/pull/19341))
* Fix abstract event accessors now have SpecialName flag. (Issue [#5834](https://github.com/dotnet/fsharp/issues/5834), [PR #19341](https://github.com/dotnet/fsharp/pull/19341))
* Fix CLIEvent properties to be correctly recognized as events: `IsEvent` returns `true` and `XmlDocSig` uses `E:` prefix instead of `P:`. ([Issue #10273](https://github.com/dotnet/fsharp/issues/10273), [PR #18584](https://github.com/dotnet/fsharp/pull/18584))
* Fix extra sequence point at the end of match expressions. ([Issue #12052](https://github.com/dotnet/fsharp/issues/12052), [PR #19278](https://github.com/dotnet/fsharp/pull/19278))
* Fix wrong sequence point range for `return`/`yield`/`return!`/`yield!` inside computation expressions. ([Issue #19248](https://github.com/dotnet/fsharp/issues/19248), [PR #19278](https://github.com/dotnet/fsharp/pull/19278))
Expand Down
6 changes: 5 additions & 1 deletion src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -13146,7 +13146,11 @@ let TcAndPublishValSpec (cenv: cenv, env, containerInfo: ContainerInfo, declKind

let checkXmlDocs = cenv.diagnosticOptions.CheckXmlDocs
let xmlDoc = xmlDoc.ToXmlDoc(checkXmlDocs, paramNames)
let vspec = MakeAndPublishVal cenv env (altActualParent, true, declKind, ValNotInRecScope, valscheme, attrs, xmlDoc, literalValue, false)
let isGeneratedEventVal =
CompileAsEvent g attrs
&& (id.idText.StartsWithOrdinal("add_") || id.idText.StartsWithOrdinal("remove_"))

let vspec = MakeAndPublishVal cenv env (altActualParent, true, declKind, ValNotInRecScope, valscheme, attrs, xmlDoc, literalValue, isGeneratedEventVal)

PublishArguments cenv env vspec synValSig allDeclaredTypars.Length

Expand Down
29 changes: 27 additions & 2 deletions src/Compiler/CodeGen/IlxGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10903,6 +10903,13 @@ and GenAbstractBinding cenv eenv tref (vref: ValRef) =
| SynMemberKind.Constructor
| SynMemberKind.Member ->
let mdef = mdef.With(customAttrs = mkILCustomAttrs ilAttrs)

let mdef =
if vref.Deref.val_flags.IsGeneratedEventVal then
mdef.WithSpecialName
else
mdef

[ mdef ], [], []
| SynMemberKind.PropertyGetSet -> error (Error(FSComp.SR.ilUnexpectedGetSetAnnotation (), m))
| SynMemberKind.PropertySet
Expand Down Expand Up @@ -11927,6 +11934,17 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option
//
// Also discard the F#-compiler supplied implementation of the Empty, IsEmpty, Value and None properties.

let nullaryCaseNames =
if cuinfo.HasHelpers = AllHelpers || cuinfo.HasHelpers = NoHelpers then
cuinfo.UnionCases
|> Array.choose (fun alt -> if alt.IsNullary then Some alt.Name else None)
|> Set.ofArray
else
Set.empty

let isNullaryCaseClash name =
not nullaryCaseNames.IsEmpty && nullaryCaseNames.Contains name

let tdefDiscards =
Some(
(fun (md: ILMethodDef) ->
Expand All @@ -11935,15 +11953,22 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option
|| (cuinfo.HasHelpers = SpecialFSharpOptionHelpers
&& (md.Name = "get_Value" || md.Name = "get_None" || md.Name = "Some"))
|| (cuinfo.HasHelpers = AllHelpers
&& (md.Name.StartsWith("get_Is") && not (tdef2.Methods.FindByName(md.Name).IsEmpty)))),
&& (md.Name.StartsWith("get_Is") && not (tdef2.Methods.FindByName(md.Name).IsEmpty)))
|| (md.Name.StartsWith("get_")
&& md.Name.Length > 4
&& isNullaryCaseClash (md.Name.Substring(4))
&& not (tdef2.Methods.FindByName(md.Name).IsEmpty))),

(fun (pd: ILPropertyDef) ->
(cuinfo.HasHelpers = SpecialFSharpListHelpers
&& (pd.Name = "Empty" || pd.Name = "IsEmpty"))
|| (cuinfo.HasHelpers = SpecialFSharpOptionHelpers
&& (pd.Name = "Value" || pd.Name = "None"))
|| (cuinfo.HasHelpers = AllHelpers
&& (pd.Name.StartsWith("Is") && not (tdef2.Properties.LookupByName(pd.Name).IsEmpty))))
&& (pd.Name.StartsWith("Is") && not (tdef2.Properties.LookupByName(pd.Name).IsEmpty)))
|| (isNullaryCaseClash pd.Name
&& (not (tdef2.Properties.LookupByName(pd.Name).IsEmpty)
|| not (tdef2.Methods.FindByName("get_" + pd.Name).IsEmpty))))
)

tdef2, tdefDiscards
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace EmittedIL

open Xunit
open FSharp.Test
open FSharp.Test.Compiler

module CodeGenRegressions_TypeDefs =

// https://github.com/dotnet/fsharp/issues/16565
[<Fact>]
let ``Issue_16565_DefaultAugmentationFalseDuplicateEntry`` () =
let source = """
module Test

open System

[<DefaultAugmentation(false)>]
type Option<'T> =
| Some of Value: 'T
| None

member x.Value =
match x with
| Some x -> x
| None -> raise (new InvalidOperationException("Option.Value"))

static member None : Option<'T> = None

and 'T option = Option<'T>

let v = Option.Some 42
printfn "Value: %d" v.Value
let n = Option<int>.None
printfn "None created successfully"
"""
FSharp source
|> asExe
|> compile
|> shouldSucceed
|> run
|> shouldSucceed
|> ignore

// https://github.com/dotnet/fsharp/issues/14321
[<Fact>]
let ``Issue_14321_DuAndIWSAMNames`` () =
let source = """
module Test

#nowarn "3535" // IWSAM warning

type EngineError<'e> =
static abstract Overheated : 'e
static abstract LowOil : 'e

type CarError =
| Overheated
| LowOil
| DeviceNotPaired

interface EngineError<CarError> with
static member Overheated = Overheated
static member LowOil = LowOil
"""
FSharp source
|> asLibrary
|> compile
|> shouldSucceed
|> ignore

// https://github.com/dotnet/fsharp/issues/14321
// Runtime test: type must load without "duplicate entry in method table"
[<Fact>]
let ``Issue_14321_DuAndIWSAMNames_Runtime`` () =
let source = """
module Test

#nowarn "3535"

type EngineError<'e> =
static abstract Overheated : 'e
static abstract LowOil : 'e

type CarError =
| Overheated
| LowOil
| DeviceNotPaired

interface EngineError<CarError> with
static member Overheated = Overheated
static member LowOil = LowOil

[<EntryPoint>]
let main _ =
let err = CarError.Overheated
match err with
| Overheated -> printfn "Got Overheated"
| LowOil -> printfn "Got LowOil"
| DeviceNotPaired -> printfn "Got DeviceNotPaired"
0
"""
FSharp source
|> asExe
|> compile
|> shouldSucceed
|> run
|> shouldSucceed
|> ignore

// https://github.com/dotnet/fsharp/issues/5834
[<Fact>]
let ``Issue_5834_EventSpecialname`` () =
let source = """
module Test

open System
open System.Reflection

type IAbstract1 =
[<CLIEvent>]
abstract member Event : IEvent<EventHandler, EventArgs>

type IAbstract2 =
[<CLIEvent>]
abstract member Event : IDelegateEvent<EventHandler>

[<AbstractClass>]
type Abstract3() =
[<CLIEvent>]
abstract member Event : IDelegateEvent<EventHandler>

type Concrete1() =
let event = new Event<EventHandler, EventArgs>()
[<CLIEvent>]
member this.Event = event.Publish

type Concrete2() =
[<CLIEvent>]
member this.Event = { new IDelegateEvent<EventHandler> with
member this.AddHandler _ = ()
member this.RemoveHandler _ = () }

type ConcreteWithObsolete() =
let evt = new Event<EventHandler, EventArgs>()
[<Obsolete("deprecated")>]
[<CLIEvent>]
member this.MyEvent = evt.Publish

[<EntryPoint>]
let main _ =
let mutable failures = 0
let check (t: Type) =
t.GetMethods(BindingFlags.Public ||| BindingFlags.Instance ||| BindingFlags.DeclaredOnly)
|> Array.filter (fun m -> m.Name.Contains("Event"))
|> Array.iter (fun m ->
if not m.IsSpecialName then
printfn "FAIL: %s.%s missing specialname" t.Name m.Name
failures <- failures + 1)

check typeof<IAbstract1>
check typeof<IAbstract2>
check typeof<Abstract3>
check typeof<Concrete1>
check typeof<Concrete2>
check typeof<ConcreteWithObsolete>

if failures > 0 then
failwithf "BUG: %d event accessors missing specialname" failures
printfn "SUCCESS: All event accessors have specialname"
0
"""
FSharp source
|> asExe
|> compile
|> shouldSucceed
|> run
|> shouldSucceed
|> ignore

// https://github.com/dotnet/fsharp/issues/5834
// IL verification: abstract event accessors must have specialname flag
[<Fact>]
let ``Issue_5834_EventSpecialname_IL`` () =
let source = """
module Test

open System

type IAbstract1 =
[<CLIEvent>]
abstract member Event : IEvent<EventHandler, EventArgs>

[<AbstractClass>]
type Abstract2() =
[<CLIEvent>]
abstract member Event : IDelegateEvent<EventHandler>
"""
FSharp source
|> asLibrary
|> compile
|> shouldSucceed
|> verifyIL [
// Interface abstract event accessors have specialname
""".method public hidebysig specialname abstract virtual instance void add_Event(class [runtime]System.EventHandler A_1) cil managed"""

""".method public hidebysig specialname abstract virtual instance void remove_Event(class [runtime]System.EventHandler A_1) cil managed"""

// IAbstract1 event references its accessors
""".addon instance void Test/IAbstract1::add_Event(class [runtime]System.EventHandler)"""
""".removeon instance void Test/IAbstract1::remove_Event(class [runtime]System.EventHandler)"""

// Abstract2 event also references its specialname accessors
""".addon instance void Test/Abstract2::add_Event(class [runtime]System.EventHandler)"""
""".removeon instance void Test/Abstract2::remove_Event(class [runtime]System.EventHandler)"""
]
|> ignore

// https://github.com/dotnet/fsharp/issues/14321
// IL verification: DU case properties and IWSAM implementations coexist without duplicates
[<Fact>]
let ``Issue_14321_DuAndIWSAMNames_IL`` () =
let source = """
module Test

#nowarn "3535"

type EngineError<'e> =
static abstract Overheated : 'e
static abstract LowOil : 'e

type CarError =
| Overheated
| LowOil
| DeviceNotPaired

interface EngineError<CarError> with
static member Overheated = Overheated
static member LowOil = LowOil
"""
FSharp source
|> asLibrary
|> compile
|> shouldSucceed
|> verifyIL [
// DU case property getter exists on CarError
""".method public static class Test/CarError get_Overheated() cil managed"""

// Explicit IWSAM implementation uses mangled name
""".method public hidebysig specialname static class Test/CarError 'Test.EngineError<Test.CarError>.get_Overheated'() cil managed"""

// Explicit IWSAM for LowOil also present
""".method public hidebysig specialname static class Test/CarError 'Test.EngineError<Test.CarError>.get_LowOil'() cil managed"""
]
|> ignore

// https://github.com/dotnet/fsharp/issues/16565
// IL verification: DefaultAugmentation(false) produces no duplicate method table entries
[<Fact>]
let ``Issue_16565_DefaultAugmentationFalseDuplicateEntry_IL`` () =
let source = """
module Test

[<DefaultAugmentation(false)>]
type MyOption<'T> =
| Some of Value: 'T
| None

member x.Value =
match x with
| Some x -> x
| None -> failwith "no value"

static member None : MyOption<'T> = None
"""
FSharp source
|> asLibrary
|> compile
|> shouldSucceed
|> verifyIL [
// The user-defined get_Value method exists on the main type with specialname
""".method public hidebysig specialname instance !T get_Value() cil managed"""

// The static get_None method exists
""".method public static class Test/MyOption`1<!T> get_None() cil managed"""
]
|> ignore

Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@
<Compile Include="EmittedIL\Nullness\NullnessMetadata.fs" />
<Compile Include="EmittedIL\FixedBindings\FixedBindings.fs" />
<Compile Include="EmittedIL\CodeGenRegressions\CodeGenRegressions_Observations.fs" />
<Compile Include="EmittedIL\CodeGenRegressions\CodeGenRegressions_TypeDefs.fs" />
<Compile Include="EmittedIL\CodeGenRegressions\CodeGenRegressions_Signatures.fs" />
<Compile Include="EmittedIL\CodeGenRegressions\CodeGenRegressions_Closures.fs" />
<Compile Include="ErrorMessages\TypedInterpolatedStringsTests.fs" />
Expand Down
Loading