diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md index 219ee92ba9f..c2358744c8f 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.0.md @@ -7,6 +7,7 @@ * Fix: warn FS0049 on upper union case label. ([PR #19003](https://github.com/dotnet/fsharp/pull/19003)) * Type relations cache: handle potentially "infinite" types ([PR #19010](https://github.com/dotnet/fsharp/pull/19010)) * Disallow recursive structs with lifted type parameters ([Issue #18993](https://github.com/dotnet/fsharp/issues/18993), [PR #19031](https://github.com/dotnet/fsharp/pull/19031)) +* Fix units-of-measure changes not invalidating incremental builds. ([Issue #19049](https://github.com/dotnet/fsharp/issues/19049)) ### Added diff --git a/src/Compiler/Utilities/TypeHashing.fs b/src/Compiler/Utilities/TypeHashing.fs index 8e3752d5d33..e026411ed71 100644 --- a/src/Compiler/Utilities/TypeHashing.fs +++ b/src/Compiler/Utilities/TypeHashing.fs @@ -188,13 +188,22 @@ module rec HashTypes = |> pipeToHash memberHash /// Hash a unit of measure expression - let private hashMeasure unt = - let measuresWithExponents = + let private hashMeasure g unt = + let measureVarsWithExponents = ListMeasureVarOccsWithNonZeroExponents unt |> List.sortBy (fun (tp: Typar, _) -> tp.DisplayName) - measuresWithExponents - |> hashListOrderIndependent (fun (typar, exp: Rational) -> hashTyparRef typar @@ hash exp) + let measureConsWithExponents = ListMeasureConOccsWithNonZeroExponents g false unt + + let varHash = + measureVarsWithExponents + |> hashListOrderIndependent (fun (typar, exp: Rational) -> hashTyparRef typar @@ hash exp) + + let conHash = + measureConsWithExponents + |> hashListOrderIndependent (fun (tcref, exp: Rational) -> hashTyconRef tcref @@ hash exp) + + varHash @@ conHash /// Hash a type, taking precedence into account to insert brackets where needed let hashTType (g: TcGlobals) ty = @@ -217,7 +226,7 @@ module rec HashTypes = let argTys, retTy = stripFunTy g ty argTys |> hashListOrderMatters (hashTType g) |> pipeToHash (hashTType g retTy) | TType_var(r, _) -> hashTyparRefWithInfo r - | TType_measure unt -> hashMeasure unt + | TType_measure unt -> hashMeasure g unt // Hash a single argument, including its name and type let private hashArgInfo (g: TcGlobals) (ty, argInfo: ArgReprInfo) = diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/ImpliedSignatureHashTests.fs b/tests/FSharp.Compiler.ComponentTests/Signatures/ImpliedSignatureHashTests.fs index a7ee96305ad..93ffca0d74c 100644 --- a/tests/FSharp.Compiler.ComponentTests/Signatures/ImpliedSignatureHashTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Signatures/ImpliedSignatureHashTests.fs @@ -288,6 +288,16 @@ type BAttribute() = let a ([] c: int) : int = 0 """)>] +[] type kg +[] type m +type MyRecord = { Mass: int }""" +(*AFTER*),"""module MyTest +[] type kg +[] type m +type MyRecord = { Mass: int }""")>] + //TODO add a lot more negative tests - in which cases should hash in fact change []