Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ positive.exe
/src/FSharp.DependencyManager.Nuget/StandardError.txt
/src/FSharp.DependencyManager.Nuget/StandardOutput.txt

# Test result files
tests/**/TestResults/*.trx

# Standard output/error files in root directory
StandardOutput.txt
StandardError.txt
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Fixed

* Fix SignatureHash to include constant values in hash computation ([Issue #18758](https://github.com/dotnet/fsharp/issues/18758))
* Fix parsing errors using anonymous records and units of measures ([PR #18543](https://github.com/dotnet/fsharp/pull/18543))
* Fix parsing errors using anonymous records and code quotations ([PR #18603](https://github.com/dotnet/fsharp/pull/18603))
* Better error message for attribute targets. ([PR #18641](https://github.com/dotnet/fsharp/pull/18641))
Expand Down
30 changes: 29 additions & 1 deletion src/Compiler/Utilities/TypeHashing.fs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,28 @@ module HashTastMemberOrVals =

combinedHash

/// Hash a constant value with exhaustive pattern matching over all Const cases
let private hashConst (constVal: Const) : Hash =
match constVal with
| Const.Bool b -> hash b
| Const.SByte x -> hash x
| Const.Byte x -> hash x
| Const.Int16 x -> hash x
| Const.UInt16 x -> hash x
| Const.Int32 x -> hash x
| Const.UInt32 x -> hash x
| Const.Int64 x -> hash x
| Const.UInt64 x -> hash x
| Const.IntPtr x -> hash x
| Const.UIntPtr x -> hash x
| Const.Single x -> hash x
| Const.Double x -> hash x
| Const.Char x -> hash x
| Const.String x -> hashText x
| Const.Decimal x -> hash x
| Const.Unit -> 0
| Const.Zero -> 0

let private hashNonMemberVal (g: TcGlobals, observer) (tps, v: Val, tau, cxs) =
if HashAccessibility.isHiddenToObserver v.Accessibility observer then
0
Expand All @@ -315,7 +337,13 @@ module HashTastMemberOrVals =
let attribsHash = hashAttributeList v.Attribs

let combinedHash = nameHash @@ typarHash @@ typeHash @@ flagsHash @@ attribsHash
combinedHash

// Include literal constant value in hash for deterministic builds
match v.LiteralValue with
| Some constVal ->
let constHash = hashConst constVal
combinedHash @@ constHash
| None -> combinedHash

let hashValOrMemberNoInst (g, obs) (vref: ValRef) =
match vref.MemberInfo with
Expand Down
18 changes: 18 additions & 0 deletions tests/fsharp/Compiler/CodeGen/EmittedIL/DeterministicTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,21 @@ let inline myFunc x y = x - y"""
Assert.Equal(mvid1,mvid2)
else
Assert.NotEqual(mvid1,mvid2)

[<Fact>]
let ``Reference assemblies MVID must change when literal constant value changes`` () =
let codeWithLiteral42 = """
module TestModule
[<Literal>]
let X = 42
"""

let codeWithLiteral43 = """
module TestModule
[<Literal>]
let X = 43
"""

let mvid1, mvid2 = calculateRefAssMvids codeWithLiteral42 codeWithLiteral43
// Different literal values should produce different MVIDs
Assert.NotEqual(mvid1, mvid2)
Loading