diff --git a/src/Compiler/AbstractIL/ilwrite.fs b/src/Compiler/AbstractIL/ilwrite.fs index 1d5111daa50..1db7d846d44 100644 --- a/src/Compiler/AbstractIL/ilwrite.fs +++ b/src/Compiler/AbstractIL/ilwrite.fs @@ -4165,9 +4165,9 @@ let writeBinaryAux (stream: Stream, options: options, modul, normalizeAssemblyRe let deterministicId = [| hCode hData - match options.referenceAssemblyOnly, options.referenceAssemblySignatureHash with - | true, Some impliedSigHash -> System.BitConverter.GetBytes(impliedSigHash) - | _ -> sha.ComputeHash metadata |] + match options.referenceAssemblySignatureHash with + | Some impliedSigHash -> System.BitConverter.GetBytes(impliedSigHash) + | None -> sha.ComputeHash metadata |] |> Array.collect id |> sha.ComputeHash let deterministicMvid () = deterministicId[0..15] diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index 89f196c810f..99d7855d597 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -873,33 +873,29 @@ let main3 TailCallChecks.CheckImplFile(tcGlobals, tcImports.GetImportMap(), true, f.ImplFile.Contents) let refAssemblySignatureHash = - match tcConfig.emitMetadataAssembly with - | MetadataAssemblyGeneration.None -> None - | MetadataAssemblyGeneration.ReferenceOnly - | MetadataAssemblyGeneration.ReferenceOut _ -> - let hasIvt = - TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_InternalsVisibleToAttribute topAttrs.assemblyAttrs - |> Option.isSome - - let observer = if hasIvt then PublicAndInternal else PublicOnly - - let optDataHash = - optDataResources - |> List.map (fun ilResource -> - use s = ilResource.GetBytes().AsStream() - let sha256 = System.Security.Cryptography.SHA256.Create() - sha256.ComputeHash s) - |> List.sumBy (hash >> int64) - |> hash - - try - Fsharp.Compiler.SignatureHash.calculateSignatureHashOfFiles typedImplFiles tcGlobals observer - + Fsharp.Compiler.SignatureHash.calculateHashOfAssemblyTopAttributes topAttrs tcConfig.platform - + optDataHash - |> Some - with e -> - printfn "Unexpected error when hashing implied signature, will hash the all of .NET metadata instead. Error: %O " e - None + let hasIvt = + TryFindFSharpStringAttribute tcGlobals tcGlobals.attrib_InternalsVisibleToAttribute topAttrs.assemblyAttrs + |> Option.isSome + + let observer = if hasIvt then PublicAndInternal else PublicOnly + + let optDataHash = + optDataResources + |> List.map (fun ilResource -> + use s = ilResource.GetBytes().AsStream() + let sha256 = System.Security.Cryptography.SHA256.Create() + sha256.ComputeHash s) + |> List.sumBy (hash >> int64) + |> hash + + try + Fsharp.Compiler.SignatureHash.calculateSignatureHashOfFiles typedImplFiles tcGlobals observer + + Fsharp.Compiler.SignatureHash.calculateHashOfAssemblyTopAttributes topAttrs tcConfig.platform + + optDataHash + |> Some + with e -> + printfn "Unexpected error when hashing implied signature, will hash the all of .NET metadata instead. Error: %O " e + None // Pass on only the minimum information required for the next phase Args( @@ -1186,7 +1182,7 @@ let main6 dumpDebugInfo = tcConfig.dumpDebugInfo referenceAssemblyOnly = false referenceAssemblyAttribOpt = None - referenceAssemblySignatureHash = None + referenceAssemblySignatureHash = refAssemblySignatureHash pathMap = tcConfig.pathMap }, ilxMainModule, diff --git a/src/Compiler/Utilities/TypeHashing.fs b/src/Compiler/Utilities/TypeHashing.fs index 8e3752d5d33..aaa8c4d99e7 100644 --- a/src/Compiler/Utilities/TypeHashing.fs +++ b/src/Compiler/Utilities/TypeHashing.fs @@ -188,13 +188,24 @@ module rec HashTypes = |> pipeToHash memberHash /// Hash a unit of measure expression - let private hashMeasure unt = + let private hashMeasure g unt = let measuresWithExponents = ListMeasureVarOccsWithNonZeroExponents unt |> List.sortBy (fun (tp: Typar, _) -> tp.DisplayName) - measuresWithExponents - |> hashListOrderIndependent (fun (typar, exp: Rational) -> hashTyparRef typar @@ hash exp) + let measureConstsWithExponents = + ListMeasureConOccsWithNonZeroExponents g true unt + |> List.sortBy (fun (tcref: TyconRef, _) -> tcref.DisplayName) + + let varHash = + measuresWithExponents + |> hashListOrderIndependent (fun (typar, exp: Rational) -> hashTyparRef typar @@ hash exp) + + let constHash = + measureConstsWithExponents + |> hashListOrderIndependent (fun (tcref, exp: Rational) -> hashTyconRef tcref @@ hash exp) + + varHash @@ constHash /// Hash a type, taking precedence into account to insert brackets where needed let hashTType (g: TcGlobals) ty = @@ -217,7 +228,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..a26e0b9476e 100644 --- a/tests/FSharp.Compiler.ComponentTests/Signatures/ImpliedSignatureHashTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Signatures/ImpliedSignatureHashTests.fs @@ -288,6 +288,36 @@ type BAttribute() = let a ([] c: int) : int = 0 """)>] +[] type a +[] type b +type MyRecord = { Value: int }""" +(*AFTER*),"""module MyTest +[] type a +[] type b +type MyRecord = { Value: int }""")>] + +[] type m +[] type s +let calculateSpeed (distance: float) (time: float) = distance / time""" +(*AFTER*),"""module MyTest +[] type m +[] type s +let calculateSpeed (distance: float) (time: float) = distance / time""")>] + +[] type kg +[] type g +let getWeight () : float = 1.0""" +(*AFTER*),"""module MyTest +[] type kg +[] type g +let getWeight () : float = 1.0""")>] + //TODO add a lot more negative tests - in which cases should hash in fact change []