Skip to content
Closed
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
6 changes: 3 additions & 3 deletions src/Compiler/AbstractIL/ilwrite.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
52 changes: 24 additions & 28 deletions src/Compiler/Driver/fsc.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -1186,7 +1182,7 @@ let main6
dumpDebugInfo = tcConfig.dumpDebugInfo
referenceAssemblyOnly = false
referenceAssemblyAttribOpt = None
referenceAssemblySignatureHash = None
referenceAssemblySignatureHash = refAssemblySignatureHash
pathMap = tcConfig.pathMap
},
ilxMainModule,
Expand Down
19 changes: 15 additions & 4 deletions src/Compiler/Utilities/TypeHashing.fs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,36 @@ type BAttribute() =

let a ([<B>] c: int) : int = 0 """)>]

[<InlineDataAttribute("UnitOfMeasureInRecordField",
(*BEFORE*)"""module MyTest
[<Measure>] type a
[<Measure>] type b
type MyRecord = { Value: int<a> }"""
(*AFTER*),"""module MyTest
[<Measure>] type a
[<Measure>] type b
type MyRecord = { Value: int<b> }""")>]

[<InlineDataAttribute("UnitOfMeasureInFunctionParameter",
(*BEFORE*)"""module MyTest
[<Measure>] type m
[<Measure>] type s
let calculateSpeed (distance: float<m>) (time: float<s>) = distance / time"""
(*AFTER*),"""module MyTest
[<Measure>] type m
[<Measure>] type s
let calculateSpeed (distance: float<s>) (time: float<m>) = distance / time""")>]

[<InlineDataAttribute("UnitOfMeasureInReturnType",
(*BEFORE*)"""module MyTest
[<Measure>] type kg
[<Measure>] type g
let getWeight () : float<kg> = 1.0<kg>"""
(*AFTER*),"""module MyTest
[<Measure>] type kg
[<Measure>] type g
let getWeight () : float<g> = 1.0<g>""")>]

//TODO add a lot more negative tests - in which cases should hash in fact change

[<Theory>]
Expand Down
Loading