[RFCs FS-1051, FS-1052, FS-1053] support for span, readonly refs, byref-like structs (#4888)

* initial support for span, readonly refs, byref-like structs

* fix proto build

* make proto work with previous FSharp.Core

* make proto work with previous FSharp.Core

* update baselines

* integrate code cleanup

* integrate code cleanup

* integrate code cleanup

* integrate code cleanup

* fix build

* fix build

* implicit deref of byref returns

* add tests for Memory, ReadOnlySpan and ReadOnlyMemory

* fix tests

* simplify diff

* simplify diff

* remove duplicate error messages

* fix build

* test updates

* fix build

* fix build

* update baselines

* fix uses of NativePtr.toByRef

* switch to inference using byref pointer capabilities

* fix proto build

* update baselines, byref extension methods

* fix test errors

* emit in,out,modreq attributes correctly

* update tests

* fix build

* fix build

* fix tests

* fix tests

* get it right silly boy

* fix test

* minor cleanup

* add more tests

* clarify overloading behaviour + test case

* fix build break

* fix build of tests

* update tests

* add more tests

* byref fixes

* updates for subsumption calls, error message, assign-to-return-byref

* test updates, implicit deref on byref return for normal functions

* update baseline

* improve debug formatting, better error message on implicit deref, improve error messages

* add more tests for recursive functions

* update baselines

* fix baselines

* updates for new test cases

* updates for new test cases

* test updates and byref-to-byreflike

* deal with 'M() <- expr'

* restrict addresses of immutable top-level things

* fix IsByRefLike on struct

* update tests

* fix test

* fix test

* improve check for no-return-of-struct-field-addresses

* fix test case
This commit is contained in:
Don Syme 2018-06-04 16:35:46 +01:00 коммит произвёл Will Smith
Родитель e21c296355
Коммит 5bfd9fcd38
90 изменённых файлов: 6843 добавлений и 2734 удалений

Просмотреть файл

@ -223,7 +223,6 @@ To do this, build the non-buildfromsource version of FSharp.Compiler.Private (sr
.\build net40 .\build net40
copy /y src\fsharp\FSharp.Compiler.Private\obj\release\net40\FSComp.* src\buildfromsource\FSharp.Compiler.Private\ copy /y src\fsharp\FSharp.Compiler.Private\obj\release\net40\FSComp.* src\buildfromsource\FSharp.Compiler.Private\
#### Configuring proxy server #### Configuring proxy server

Просмотреть файл

@ -38,6 +38,11 @@
<package id="Microsoft.FSharp.TupleSample" version="1.0.0-alpha-161121"/> <package id="Microsoft.FSharp.TupleSample" version="1.0.0-alpha-161121"/>
<package id="Microsoft.VSSDK.BuildTools" version="15.1.192" /> <package id="Microsoft.VSSDK.BuildTools" version="15.1.192" />
<!-- Testing Span -->
<package id="System.Memory" version="4.5.0-rc1" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.0-rc1" />
<package id="NETStandard.Library.NETFramework" version="2.0.0-preview2-25405-01" />
<!-- Annoyingly the build of FSharp.Compiler.Server.Shared references a Visual Studio-specific attribute --> <!-- Annoyingly the build of FSharp.Compiler.Server.Shared references a Visual Studio-specific attribute -->
<!-- That DLL is logically part of the F# Compiler and F# Interactive but is shipped as part of the Visual F# IDE Tools --> <!-- That DLL is logically part of the F# Compiler and F# Interactive but is shipped as part of the Visual F# IDE Tools -->
<package id="Microsoft.VisualStudio.Shell.Immutable.10.0" version="10.0.30319" targetFramework="net46" /> <package id="Microsoft.VisualStudio.Shell.Immutable.10.0" version="10.0.30319" targetFramework="net46" />

Просмотреть файл

@ -8,6 +8,7 @@ module Microsoft.FSharp.Compiler.AbstractIL.IL
open System open System
open System.Diagnostics
open System.IO open System.IO
open System.Collections open System.Collections
open System.Collections.Generic open System.Collections.Generic
@ -568,7 +569,7 @@ type ILBoxity =
| AsValue | AsValue
// IL type references have a pre-computed hash code to enable quick lookup tables during binary generation. // IL type references have a pre-computed hash code to enable quick lookup tables during binary generation.
[<CustomEquality; CustomComparison>] [<CustomEquality; CustomComparison; StructuredFormatDisplay("{DebugText}")>]
type ILTypeRef = type ILTypeRef =
{ trefScope: ILScopeRef { trefScope: ILScopeRef
trefEnclosing: string list trefEnclosing: string list
@ -637,11 +638,15 @@ type ILTypeRef =
member tref.QualifiedName = member tref.QualifiedName =
tref.AddQualifiedNameExtension(tref.BasicQualifiedName) tref.AddQualifiedNameExtension(tref.BasicQualifiedName)
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
/// For debugging
override x.ToString() = x.FullName override x.ToString() = x.FullName
and and [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
[<StructuralEquality; StructuralComparison>]
ILTypeSpec = ILTypeSpec =
{ tspecTypeRef: ILTypeRef { tspecTypeRef: ILTypeRef
/// The type instantiation if the type is generic. /// The type instantiation if the type is generic.
@ -671,9 +676,13 @@ and
member x.FullName=x.TypeRef.FullName member x.FullName=x.TypeRef.FullName
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = x.TypeRef.ToString() + if isNil x.GenericArgs then "" else "<...>" override x.ToString() = x.TypeRef.ToString() + if isNil x.GenericArgs then "" else "<...>"
and [<RequireQualifiedAccess; StructuralEquality; StructuralComparison>] and [<RequireQualifiedAccess; StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
ILType = ILType =
| Void | Void
| Array of ILArrayShape * ILType | Array of ILArrayShape * ILType
@ -740,6 +749,10 @@ and [<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]
match x with match x with
| ILType.TypeVar _ -> true | _ -> false | ILType.TypeVar _ -> true | _ -> false
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = x.QualifiedName override x.ToString() = x.QualifiedName
and [<StructuralEquality; StructuralComparison>] and [<StructuralEquality; StructuralComparison>]
@ -756,6 +769,7 @@ let mkILCallSig (cc, args, ret) = { ArgTypes=args; CallingConv=cc; ReturnType=re
let mkILBoxedType (tspec:ILTypeSpec) = tspec.TypeRef.AsBoxedType tspec let mkILBoxedType (tspec:ILTypeSpec) = tspec.TypeRef.AsBoxedType tspec
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
type ILMethodRef = type ILMethodRef =
{ mrefParent: ILTypeRef { mrefParent: ILTypeRef
mrefCallconv: ILCallingConv mrefCallconv: ILCallingConv
@ -783,18 +797,26 @@ type ILMethodRef =
static member Create(a, b, c, d, e, f) = static member Create(a, b, c, d, e, f) =
{ mrefParent= a;mrefCallconv=b;mrefName=c;mrefGenericArity=d; mrefArgs=e;mrefReturn=f } { mrefParent= a;mrefCallconv=b;mrefName=c;mrefGenericArity=d; mrefArgs=e;mrefReturn=f }
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = x.DeclaringTypeRef.ToString() + "::" + x.Name + "(...)" override x.ToString() = x.DeclaringTypeRef.ToString() + "::" + x.Name + "(...)"
[<StructuralEquality; StructuralComparison>] [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
type ILFieldRef = type ILFieldRef =
{ DeclaringTypeRef: ILTypeRef { DeclaringTypeRef: ILTypeRef
Name: string Name: string
Type: ILType } Type: ILType }
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = x.DeclaringTypeRef.ToString() + "::" + x.Name override x.ToString() = x.DeclaringTypeRef.ToString() + "::" + x.Name
[<StructuralEquality; StructuralComparison>] [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
type ILMethodSpec = type ILMethodSpec =
{ mspecMethodRef: ILMethodRef { mspecMethodRef: ILMethodRef
@ -802,7 +824,7 @@ type ILMethodSpec =
mspecMethodInst: ILGenericArgs } mspecMethodInst: ILGenericArgs }
static member Create(a, b, c) = { mspecDeclaringType=a; mspecMethodRef =b; mspecMethodInst=c } static member Create(a, b, c) = { mspecDeclaringType=a; mspecMethodRef=b; mspecMethodInst=c }
member x.MethodRef = x.mspecMethodRef member x.MethodRef = x.mspecMethodRef
@ -820,8 +842,13 @@ type ILMethodSpec =
member x.FormalReturnType = x.MethodRef.ReturnType member x.FormalReturnType = x.MethodRef.ReturnType
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = x.MethodRef.ToString() + "(...)" override x.ToString() = x.MethodRef.ToString() + "(...)"
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
type ILFieldSpec = type ILFieldSpec =
{ FieldRef: ILFieldRef { FieldRef: ILFieldRef
DeclaringType: ILType } DeclaringType: ILType }
@ -832,6 +859,10 @@ type ILFieldSpec =
member x.DeclaringTypeRef = x.FieldRef.DeclaringTypeRef member x.DeclaringTypeRef = x.FieldRef.DeclaringTypeRef
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = x.FieldRef.ToString() override x.ToString() = x.FieldRef.ToString()
// -------------------------------------------------------------------- // --------------------------------------------------------------------
@ -865,6 +896,7 @@ type ILSourceDocument =
member x.File=x.sourceFile member x.File=x.sourceFile
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
type ILSourceMarker = type ILSourceMarker =
{ sourceDocument: ILSourceDocument { sourceDocument: ILSourceDocument
sourceLine: int sourceLine: int
@ -889,6 +921,10 @@ type ILSourceMarker =
member x.EndColumn=x.sourceEndColumn member x.EndColumn=x.sourceEndColumn
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = sprintf "(%d, %d)-(%d, %d)" x.Line x.Column x.EndLine x.EndColumn override x.ToString() = sprintf "(%d, %d)-(%d, %d)" x.Line x.Column x.EndLine x.EndColumn
type ILAttribElem = type ILAttribElem =
@ -912,11 +948,16 @@ type ILAttribElem =
type ILAttributeNamedArg = (string * ILType * bool * ILAttribElem) type ILAttributeNamedArg = (string * ILType * bool * ILAttribElem)
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
type ILAttribute = type ILAttribute =
{ Method: ILMethodSpec { Method: ILMethodSpec
Data: byte[] Data: byte[]
Elements: ILAttribElem list } Elements: ILAttribElem list }
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = x.Method.ToString() + "(...)" override x.ToString() = x.Method.ToString() + "(...)"
[<NoEquality; NoComparison; Struct>] [<NoEquality; NoComparison; Struct>]
@ -1424,6 +1465,8 @@ type ILReturn =
member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
member x.WithCustomAttrs(customAttrs) = { x with CustomAttrsStored = storeILCustomAttrs customAttrs }
type ILOverridesSpec = type ILOverridesSpec =
| OverridesSpec of ILMethodRef * ILType | OverridesSpec of ILMethodRef * ILType
@ -1475,6 +1518,7 @@ type ILGenericVariance =
| CoVariant | CoVariant
| ContraVariant | ContraVariant
[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
type ILGenericParameterDef = type ILGenericParameterDef =
{ Name: string { Name: string
Constraints: ILTypes Constraints: ILTypes
@ -1487,6 +1531,10 @@ type ILGenericParameterDef =
member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = x.Name override x.ToString() = x.Name
type ILGenericParameterDefs = ILGenericParameterDef list type ILGenericParameterDefs = ILGenericParameterDef list
@ -1665,7 +1713,7 @@ type ILMethodDefs(f : (unit -> ILMethodDef[])) =
member x.FindByNameAndArity (nm, arity) = x.FindByName nm |> List.filter (fun x -> List.length x.Parameters = arity) member x.FindByNameAndArity (nm, arity) = x.FindByName nm |> List.filter (fun x -> List.length x.Parameters = arity)
[<NoComparison; NoEquality>] [<NoComparison; NoEquality; StructuredFormatDisplay("{DebugText}")>]
type ILEventDef(eventType: ILType option, name: string, attributes: EventAttributes, addMethod: ILMethodRef, removeMethod: ILMethodRef, fireMethod: ILMethodRef option, otherMethods: ILMethodRef list, customAttrsStored: ILAttributesStored, metadataIndex: int32) = type ILEventDef(eventType: ILType option, name: string, attributes: EventAttributes, addMethod: ILMethodRef, removeMethod: ILMethodRef, fireMethod: ILMethodRef option, otherMethods: ILMethodRef list, customAttrsStored: ILAttributesStored, metadataIndex: int32) =
new (eventType, name, attributes, addMethod, removeMethod, fireMethod, otherMethods, customAttrs) = new (eventType, name, attributes, addMethod, removeMethod, fireMethod, otherMethods, customAttrs) =
@ -1695,6 +1743,10 @@ type ILEventDef(eventType: ILType option, name: string, attributes: EventAttribu
member x.IsSpecialName = (x.Attributes &&& EventAttributes.SpecialName) <> enum<_>(0) member x.IsSpecialName = (x.Attributes &&& EventAttributes.SpecialName) <> enum<_>(0)
member x.IsRTSpecialName = (x.Attributes &&& EventAttributes.RTSpecialName) <> enum<_>(0) member x.IsRTSpecialName = (x.Attributes &&& EventAttributes.RTSpecialName) <> enum<_>(0)
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = "event " + x.Name override x.ToString() = "event " + x.Name
[<NoEquality; NoComparison>] [<NoEquality; NoComparison>]
@ -1705,7 +1757,7 @@ type ILEventDefs =
member x.LookupByName s = let (ILEvents t) = x in t.[s] member x.LookupByName s = let (ILEvents t) = x in t.[s]
[<NoComparison; NoEquality>] [<NoComparison; NoEquality; StructuredFormatDisplay("{DebugText}")>]
type ILPropertyDef(name: string, attributes: PropertyAttributes, setMethod: ILMethodRef option, getMethod: ILMethodRef option, callingConv: ILThisConvention, propertyType: ILType, init: ILFieldInit option, args: ILTypes, customAttrsStored: ILAttributesStored, metadataIndex: int32) = type ILPropertyDef(name: string, attributes: PropertyAttributes, setMethod: ILMethodRef option, getMethod: ILMethodRef option, callingConv: ILThisConvention, propertyType: ILType, init: ILFieldInit option, args: ILTypes, customAttrsStored: ILAttributesStored, metadataIndex: int32) =
new (name, attributes, setMethod, getMethod, callingConv, propertyType, init, args, customAttrs) = new (name, attributes, setMethod, getMethod, callingConv, propertyType, init, args, customAttrs) =
@ -1737,6 +1789,11 @@ type ILPropertyDef(name: string, attributes: PropertyAttributes, setMethod: ILMe
member x.IsSpecialName = (x.Attributes &&& PropertyAttributes.SpecialName) <> enum<_>(0) member x.IsSpecialName = (x.Attributes &&& PropertyAttributes.SpecialName) <> enum<_>(0)
member x.IsRTSpecialName = (x.Attributes &&& PropertyAttributes.RTSpecialName) <> enum<_>(0) member x.IsRTSpecialName = (x.Attributes &&& PropertyAttributes.RTSpecialName) <> enum<_>(0)
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = "property " + x.Name override x.ToString() = "property " + x.Name
// Index table by name. // Index table by name.
@ -2469,7 +2526,7 @@ let tname_IntPtr = "System.IntPtr"
[<Literal>] [<Literal>]
let tname_UIntPtr = "System.UIntPtr" let tname_UIntPtr = "System.UIntPtr"
[<NoEquality; NoComparison>] [<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
// This data structure needs an entirely delayed implementation // This data structure needs an entirely delayed implementation
type ILGlobals(primaryScopeRef) = type ILGlobals(primaryScopeRef) =
@ -2514,6 +2571,11 @@ type ILGlobals(primaryScopeRef) =
member x.typ_Double = m_typ_Double member x.typ_Double = m_typ_Double
member x.typ_Bool = m_typ_Bool member x.typ_Bool = m_typ_Bool
member x.typ_Char = m_typ_Char member x.typ_Char = m_typ_Char
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
override x.ToString() = "<ILGlobals>" override x.ToString() = "<ILGlobals>"
let mkILGlobals primaryScopeRef = ILGlobals primaryScopeRef let mkILGlobals primaryScopeRef = ILGlobals primaryScopeRef

Просмотреть файл

@ -796,6 +796,8 @@ type ILReturn =
member CustomAttrs: ILAttributes member CustomAttrs: ILAttributes
member WithCustomAttrs: customAttrs: ILAttributes -> ILReturn
[<RequireQualifiedAccess>] [<RequireQualifiedAccess>]
type ILSecurityAction = type ILSecurityAction =
| Request | Request

Просмотреть файл

@ -135,6 +135,9 @@ module Array =
loop p l 0 loop p l 0
let existsTrue (arr: bool[]) =
let rec loop n = (n < arr.Length) && (arr.[n] || loop (n+1))
loop 0
let findFirstIndexWhereTrue (arr: _[]) p = let findFirstIndexWhereTrue (arr: _[]) p =
let rec look lo hi = let rec look lo hi =
@ -263,6 +266,10 @@ module List =
let rec loop i xs = match xs with [] -> false | h::t -> f i h || loop (i+1) t let rec loop i xs = match xs with [] -> false | h::t -> f i h || loop (i+1) t
loop 0 xs loop 0 xs
let existsTrue (xs: bool list) =
let rec loop i xs = match xs with [] -> false | h::t -> h || loop (i+1) t
loop 0 xs
let lengthsEqAndForall2 p l1 l2 = let lengthsEqAndForall2 p l1 l2 =
List.length l1 = List.length l2 && List.length l1 = List.length l2 &&
List.forall2 p l1 l2 List.forall2 p l1 l2

Просмотреть файл

@ -7,27 +7,22 @@
module internal Microsoft.FSharp.Compiler.AbstractIL.ILRuntimeWriter module internal Microsoft.FSharp.Compiler.AbstractIL.ILRuntimeWriter
open Internal.Utilities open System
open System.Reflection
open System.Reflection.Emit
open System.Runtime.InteropServices
open System.Collections.Generic
open Microsoft.FSharp.Compiler.AbstractIL open Microsoft.FSharp.Compiler.AbstractIL
open Microsoft.FSharp.Compiler.AbstractIL.Internal open Microsoft.FSharp.Compiler.AbstractIL.Internal
open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics
open Microsoft.FSharp.Compiler.AbstractIL.Extensions
open Microsoft.FSharp.Compiler.AbstractIL.Extensions.ILX
open Microsoft.FSharp.Compiler.AbstractIL.Extensions.ILX.Types
open Microsoft.FSharp.Compiler.AbstractIL.IL open Microsoft.FSharp.Compiler.AbstractIL.IL
open Microsoft.FSharp.Compiler.ErrorLogger open Microsoft.FSharp.Compiler.ErrorLogger
open Microsoft.FSharp.Compiler.Range open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Core.Printf open Microsoft.FSharp.Core.Printf
open System
open System.IO
open System.Reflection
open System.Reflection.Emit
open System.Runtime.InteropServices
open System.Collections.Generic
#if FX_RESHAPED_REFLECTION #if FX_RESHAPED_REFLECTION
open Microsoft.FSharp.Core.ReflectionAdapters open Microsoft.FSharp.Core.ReflectionAdapters
#endif #endif
@ -121,13 +116,9 @@ type System.Reflection.Emit.MethodBuilder with
if logRefEmitCalls then printfn "methodBuilder%d.SetImplementationFlags(enum %d)" (abs <| hash methB) (LanguagePrimitives.EnumToValue attrs) if logRefEmitCalls then printfn "methodBuilder%d.SetImplementationFlags(enum %d)" (abs <| hash methB) (LanguagePrimitives.EnumToValue attrs)
methB.SetImplementationFlags(attrs) methB.SetImplementationFlags(attrs)
member methB.SetReturnTypeAndLog(rt:System.Type) = member methB.SetSignatureAndLog(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers) =
if logRefEmitCalls then printfn "methodBuilder%d.SetReturnType(typeof<%s>)" (abs <| hash methB) rt.FullName if logRefEmitCalls then printfn "methodBuilder%d.SetSignature(...)" (abs <| hash methB)
methB.SetReturnType(rt) methB.SetSignature(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers)
member methB.SetParametersAndLog(ps) =
if logRefEmitCalls then printfn "methodBuilder%d.SetParameters(%A)" (abs <| hash methB) ps
methB.SetParameters(ps)
member methB.DefineParameterAndLog(n, attr, nm) = member methB.DefineParameterAndLog(n, attr, nm) =
if logRefEmitCalls then printfn "methodBuilder%d.DefineParameter(%d, enum %d, %A)" (abs <| hash methB) n (LanguagePrimitives.EnumToValue attr) nm if logRefEmitCalls then printfn "methodBuilder%d.DefineParameter(%d, enum %d, %A)" (abs <| hash methB) n (LanguagePrimitives.EnumToValue attr) nm
@ -558,11 +549,11 @@ and convTypeAux cenv emEnv preferCreated typ =
baseT.MakeByRefType() baseT.MakeByRefType()
| ILType.TypeVar tv -> envGetTyvar emEnv tv | ILType.TypeVar tv -> envGetTyvar emEnv tv
// Consider completing the following cases: // Consider completing the following cases:
| ILType.Modified (false, _, modifiedTy) -> | ILType.Modified (_, _, modifiedTy) ->
// Note, "modreq" are not being emitted. This is
convTypeAux cenv emEnv preferCreated modifiedTy convTypeAux cenv emEnv preferCreated modifiedTy
| ILType.Modified (true, _, _) -> failwith "convType: modreq"
| ILType.FunctionPointer _callsig -> failwith "convType: fptr"
| ILType.FunctionPointer _callsig -> failwith "convType: fptr"
// [Bug 4063]. // [Bug 4063].
// The convType functions convert AbsIL types into concrete Type values. // The convType functions convert AbsIL types into concrete Type values.
@ -598,6 +589,25 @@ let convTypesToArray cenv emEnv (typs:ILTypes) = convTypes cenv emEnv typs |> Li
let convCreatedType cenv emEnv typ = convTypeAux cenv emEnv true typ let convCreatedType cenv emEnv typ = convTypeAux cenv emEnv true typ
let convCreatedTypeRef cenv emEnv typ = convTypeRef cenv emEnv true typ let convCreatedTypeRef cenv emEnv typ = convTypeRef cenv emEnv true typ
let rec convParamModifiersOfType cenv emEnv (pty: ILType) =
[| match pty with
| ILType.Modified (modreq, ty, modifiedTy) ->
yield (modreq, convTypeRef cenv emEnv false ty)
yield! convParamModifiersOfType cenv emEnv modifiedTy
| _ -> () |]
let splitModifiers mods =
let reqd = mods |> Array.choose (function (true, ty) -> Some ty | _ -> None)
let optional = mods |> Array.choose (function (false, ty) -> Some ty | _ -> None)
reqd, optional
let convParamModifiers cenv emEnv (p: ILParameter) =
let mods = convParamModifiersOfType cenv emEnv p.Type
splitModifiers mods
let convReturnModifiers cenv emEnv (p: ILReturn) =
let mods = convParamModifiersOfType cenv emEnv p.Type
splitModifiers mods
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// convFieldInit // convFieldInit
@ -1537,11 +1547,22 @@ let rec buildMethodPass2 cenv tref (typB:TypeBuilder) emEnv (mdef : ILMethodDef)
let genArgs = getGenericArgumentsOfMethod methB let genArgs = getGenericArgumentsOfMethod methB
let emEnv = envPushTyvars emEnv (Array.append (getGenericArgumentsOfType (typB.AsType())) genArgs) let emEnv = envPushTyvars emEnv (Array.append (getGenericArgumentsOfType (typB.AsType())) genArgs)
buildGenParamsPass1b cenv emEnv genArgs mdef.GenericParams; buildGenParamsPass1b cenv emEnv genArgs mdef.GenericParams;
// Set parameter and return types (may depend on generic args) // Set parameter and return types (may depend on generic args)
methB.SetParametersAndLog(convTypesToArray cenv emEnv mdef.ParameterTypes); let parameterTypes = convTypesToArray cenv emEnv mdef.ParameterTypes
methB.SetReturnTypeAndLog(convType cenv emEnv mdef.Return.Type); let parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers =
mdef.Parameters
|> List.toArray
|> Array.map (convParamModifiers cenv emEnv)
|> Array.unzip
let returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers = mdef.Return |> convReturnModifiers cenv emEnv
let returnType = convType cenv emEnv mdef.Return.Type
methB.SetSignatureAndLog(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers);
let emEnv = envPopTyvars emEnv let emEnv = envPopTyvars emEnv
methB.SetImplementationFlagsAndLog(implflags); methB.SetImplementationFlagsAndLog(implflags)
envBindMethodRef emEnv mref methB envBindMethodRef emEnv mref methB

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -181,7 +181,7 @@
<value>All branches of an 'if' expression must have the same type. This expression was expected to have type '{0}', but here has type '{1}'.</value> <value>All branches of an 'if' expression must have the same type. This expression was expected to have type '{0}', but here has type '{1}'.</value>
</data> </data>
<data name="followingPatternMatchClauseHasWrongType" xml:space="preserve"> <data name="followingPatternMatchClauseHasWrongType" xml:space="preserve">
<value>All branches of a pattern match expression must have the same type. This expression was expected to have type '{0}', but here has type '{1}'.</value> <value>All branches of a pattern match expression must return values of the same type. The first branch returned a value of type '{0}', but this branch returned a value of type '{1}'.</value>
</data> </data>
<data name="patternMatchGuardIsNotBool" xml:space="preserve"> <data name="patternMatchGuardIsNotBool" xml:space="preserve">
<value>A pattern match guard must be of type 'bool', but this 'when' expression is of type '{0}'.</value> <value>A pattern match guard must be of type 'bool', but this 'when' expression is of type '{0}'.</value>
@ -4029,8 +4029,8 @@
<data name="tcCouldNotFindOffsetToStringData" xml:space="preserve"> <data name="tcCouldNotFindOffsetToStringData" xml:space="preserve">
<value>Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression.</value> <value>Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression.</value>
</data> </data>
<data name="chkNoByrefReturnOfLocal" xml:space="preserve"> <data name="chkNoByrefAddressOfLocal" xml:space="preserve">
<value>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</value> <value>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</value>
</data> </data>
<data name="tcNamedActivePattern" xml:space="preserve"> <data name="tcNamedActivePattern" xml:space="preserve">
<value>{0} is an active pattern and cannot be treated as a discriminated union case with named fields.</value> <value>{0} is an active pattern and cannot be treated as a discriminated union case with named fields.</value>
@ -4315,4 +4315,34 @@
<data name="ilreadFileChanged" xml:space="preserve"> <data name="ilreadFileChanged" xml:space="preserve">
<value>The file '{0}' changed on disk unexpectedly, please reload.</value> <value>The file '{0}' changed on disk unexpectedly, please reload.</value>
</data> </data>
<data name="writeToReadOnlyByref" xml:space="preserve">
<value>The byref pointer is readonly, so this write is not permitted.</value>
</data>
<data name="readOnlyAttributeOnStructWithMutableField" xml:space="preserve">
<value>A ReadOnly attribute has been applied to a struct type with a mutable field.</value>
</data>
<data name="tcByrefReturnImplicitlyDereferenced" xml:space="preserve">
<value>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</value>
</data>
<data name="tcByRefLikeNotStruct" xml:space="preserve">
<value>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</value>
</data>
<data name="chkNoByrefReturnOfLocal" xml:space="preserve">
<value>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</value>
</data>
<data name="chkNoReturnOfLimitedSpan" xml:space="preserve">
<value>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</value>
</data>
<data name="chkNoWriteToLimitedSpan" xml:space="preserve">
<value>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</value>
</data>
<data name="tastValueMustBeLocal" xml:space="preserve">
<value>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</value>
</data>
<data name="tcIsReadOnlyNotStruct" xml:space="preserve">
<value>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</value>
</data>
<data name="chkStructsMayNotReturnAddressesOfContents" xml:space="preserve">
<value>Struct members cannot return 'this' or fields by reference</value>
</data>
</root> </root>

Просмотреть файл

@ -248,21 +248,21 @@ let MethInfoHasAttribute g m attribSpec minfo =
/// Check IL attributes for 'ObsoleteAttribute', returning errors and warnings as data /// Check IL attributes for 'ObsoleteAttribute', returning errors and warnings as data
let private CheckILAttributes (g: TcGlobals) cattrs m = let private CheckILAttributes (g: TcGlobals) isByrefLikeTyconRef cattrs m =
let (AttribInfo(tref, _)) = g.attrib_SystemObsolete let (AttribInfo(tref,_)) = g.attrib_SystemObsolete
match TryDecodeILAttribute g tref cattrs with match TryDecodeILAttribute g tref cattrs with
| Some ([ILAttribElem.String (Some msg) ], _) -> | Some ([ILAttribElem.String (Some msg) ], _) when not isByrefLikeTyconRef ->
WarnD(ObsoleteWarning(msg, m)) WarnD(ObsoleteWarning(msg, m))
| Some ([ILAttribElem.String (Some msg); ILAttribElem.Bool isError ], _) -> | Some ([ILAttribElem.String (Some msg); ILAttribElem.Bool isError ], _) when not isByrefLikeTyconRef ->
if isError then if isError then
ErrorD (ObsoleteError(msg, m)) ErrorD (ObsoleteError(msg, m))
else else
WarnD (ObsoleteWarning(msg, m)) WarnD (ObsoleteWarning(msg, m))
| Some ([ILAttribElem.String None ], _) -> | Some ([ILAttribElem.String None ], _) when not isByrefLikeTyconRef ->
WarnD(ObsoleteWarning("", m)) WarnD(ObsoleteWarning("", m))
| Some _ -> | Some _ when not isByrefLikeTyconRef ->
WarnD(ObsoleteWarning("", m)) WarnD(ObsoleteWarning("", m))
| None -> | _ ->
CompleteD CompleteD
/// Check F# attributes for 'ObsoleteAttribute', 'CompilerMessageAttribute' and 'ExperimentalAttribute', /// Check F# attributes for 'ObsoleteAttribute', 'CompilerMessageAttribute' and 'ExperimentalAttribute',
@ -374,7 +374,7 @@ let CheckProvidedAttributesForUnseen (provAttribs: Tainted<IProvidedCustomAttrib
/// Check the attributes associated with a property, returning warnings and errors as data. /// Check the attributes associated with a property, returning warnings and errors as data.
let CheckPropInfoAttributes pinfo m = let CheckPropInfoAttributes pinfo m =
match pinfo with match pinfo with
| ILProp(ILPropInfo(_, pdef)) -> CheckILAttributes pinfo.TcGlobals pdef.CustomAttrs m | ILProp(ILPropInfo(_, pdef)) -> CheckILAttributes pinfo.TcGlobals false pdef.CustomAttrs m
| FSProp(g, _, Some vref, _) | FSProp(g, _, Some vref, _)
| FSProp(g, _, _, Some vref) -> CheckFSharpAttributes g vref.Attribs m | FSProp(g, _, _, Some vref) -> CheckFSharpAttributes g vref.Attribs m
| FSProp _ -> failwith "CheckPropInfoAttributes: unreachable" | FSProp _ -> failwith "CheckPropInfoAttributes: unreachable"
@ -389,7 +389,7 @@ let CheckPropInfoAttributes pinfo m =
let CheckILFieldAttributes g (finfo:ILFieldInfo) m = let CheckILFieldAttributes g (finfo:ILFieldInfo) m =
match finfo with match finfo with
| ILFieldInfo(_, pd) -> | ILFieldInfo(_, pd) ->
CheckILAttributes g pd.CustomAttrs m |> CommitOperationResult CheckILAttributes g false pd.CustomAttrs m |> CommitOperationResult
#if !NO_EXTENSIONTYPING #if !NO_EXTENSIONTYPING
| ProvidedField (amap, fi, m) -> | ProvidedField (amap, fi, m) ->
CheckProvidedAttributes amap.g m (fi.PApply((fun st -> (st :> IProvidedCustomAttributeProvider)), m)) |> CommitOperationResult CheckProvidedAttributes amap.g m (fi.PApply((fun st -> (st :> IProvidedCustomAttributeProvider)), m)) |> CommitOperationResult
@ -399,7 +399,7 @@ let CheckILFieldAttributes g (finfo:ILFieldInfo) m =
let CheckMethInfoAttributes g m tyargsOpt minfo = let CheckMethInfoAttributes g m tyargsOpt minfo =
let search = let search =
BindMethInfoAttributes m minfo BindMethInfoAttributes m minfo
(fun ilAttribs -> Some(CheckILAttributes g ilAttribs m)) (fun ilAttribs -> Some(CheckILAttributes g false ilAttribs m))
(fun fsAttribs -> (fun fsAttribs ->
let res = let res =
CheckFSharpAttributes g fsAttribs m ++ (fun () -> CheckFSharpAttributes g fsAttribs m ++ (fun () ->
@ -481,7 +481,7 @@ let PropInfoIsUnseen m pinfo =
/// Check the attributes on an entity, returning errors and warnings as data. /// Check the attributes on an entity, returning errors and warnings as data.
let CheckEntityAttributes g (x:TyconRef) m = let CheckEntityAttributes g (x:TyconRef) m =
if x.IsILTycon then if x.IsILTycon then
CheckILAttributes g x.ILTyconRawMetadata.CustomAttrs m CheckILAttributes g (isByrefLikeTyconRef g m x) x.ILTyconRawMetadata.CustomAttrs m
else else
CheckFSharpAttributes g x.Attribs m CheckFSharpAttributes g x.Attribs m

Просмотреть файл

@ -44,14 +44,19 @@ let mkEqualsSlotSig (g: TcGlobals) =
let mkThisTy g ty = if isStructTy g ty then mkByrefTy g ty else ty let mkThisTy g ty = if isStructTy g ty then mkByrefTy g ty else ty
let mkCompareObjTy g ty = (mkThisTy g ty) --> (g.obj_ty --> g.int_ty) let mkCompareObjTy g ty = (mkThisTy g ty) --> (g.obj_ty --> g.int_ty)
let mkCompareTy g ty = (mkThisTy g ty) --> (ty --> g.int_ty) let mkCompareTy g ty = (mkThisTy g ty) --> (ty --> g.int_ty)
let mkCompareWithComparerTy g ty = (mkThisTy g ty) --> ((mkRefTupledTy g [g.obj_ty ; g.IComparer_ty]) --> g.int_ty) let mkCompareWithComparerTy g ty = (mkThisTy g ty) --> ((mkRefTupledTy g [g.obj_ty ; g.IComparer_ty]) --> g.int_ty)
let mkEqualsObjTy g ty = (mkThisTy g ty) --> (g.obj_ty --> g.bool_ty) let mkEqualsObjTy g ty = (mkThisTy g ty) --> (g.obj_ty --> g.bool_ty)
let mkEqualsTy g ty = (mkThisTy g ty) --> (ty --> g.bool_ty) let mkEqualsTy g ty = (mkThisTy g ty) --> (ty --> g.bool_ty)
let mkEqualsWithComparerTy g ty = (mkThisTy g ty) --> ((mkRefTupledTy g [g.obj_ty ; g.IEqualityComparer_ty]) --> g.bool_ty) let mkEqualsWithComparerTy g ty = (mkThisTy g ty) --> ((mkRefTupledTy g [g.obj_ty ; g.IEqualityComparer_ty]) --> g.bool_ty)
let mkHashTy g ty = (mkThisTy g ty) --> (g.unit_ty --> g.int_ty) let mkHashTy g ty = (mkThisTy g ty) --> (g.unit_ty --> g.int_ty)
let mkHashWithComparerTy g ty = (mkThisTy g ty) --> (g.IEqualityComparer_ty --> g.int_ty) let mkHashWithComparerTy g ty = (mkThisTy g ty) --> (g.IEqualityComparer_ty --> g.int_ty)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -59,7 +64,9 @@ let mkHashWithComparerTy g ty = (mkThisTy g ty) --> (g.IEqualityComparer_ty -->
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
let mkRelBinOp (g: TcGlobals) op m e1 e2 = mkAsmExpr ([ op ],[], [e1; e2],[g.bool_ty],m) let mkRelBinOp (g: TcGlobals) op m e1 e2 = mkAsmExpr ([ op ],[], [e1; e2],[g.bool_ty],m)
let mkClt g m e1 e2 = mkRelBinOp g IL.AI_clt m e1 e2 let mkClt g m e1 e2 = mkRelBinOp g IL.AI_clt m e1 e2
let mkCgt g m e1 e2 = mkRelBinOp g IL.AI_cgt m e1 e2 let mkCgt g m e1 e2 = mkRelBinOp g IL.AI_cgt m e1 e2
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -84,7 +91,9 @@ let mkILCallGetEqualityComparer (g: TcGlobals) m =
let mkThisVar g m ty = mkCompGenLocal m "this" (mkThisTy g ty) let mkThisVar g m ty = mkCompGenLocal m "this" (mkThisTy g ty)
let mkShl g m acce n = mkAsmExpr([ IL.AI_shl ],[],[acce; mkInt g m n],[g.int_ty],m) let mkShl g m acce n = mkAsmExpr([ IL.AI_shl ],[],[acce; mkInt g m n],[g.int_ty],m)
let mkShr g m acce n = mkAsmExpr([ IL.AI_shr ],[],[acce; mkInt g m n],[g.int_ty],m) let mkShr g m acce n = mkAsmExpr([ IL.AI_shr ],[],[acce; mkInt g m n],[g.int_ty],m)
let mkAdd (g: TcGlobals) m e1 e2 = mkAsmExpr([ IL.AI_add ],[],[e1;e2],[g.int_ty],m) let mkAdd (g: TcGlobals) m e1 e2 = mkAsmExpr([ IL.AI_add ],[],[e1;e2],[g.int_ty],m)
let mkAddToHashAcc g m e accv acce = let mkAddToHashAcc g m e accv acce =
@ -101,6 +110,7 @@ let mkCombineHashGenerators g m exprs accv acce =
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
let mkThatAddrLocal g m ty = mkCompGenLocal m "obj" (mkThisTy g ty) let mkThatAddrLocal g m ty = mkCompGenLocal m "obj" (mkThisTy g ty)
let mkThatAddrLocalIfNeeded g m tcve ty = let mkThatAddrLocalIfNeeded g m tcve ty =
if isStructTy g ty then if isStructTy g ty then
let thataddrv, thataddre = mkCompGenLocal m "obj" (mkThisTy g ty) let thataddrv, thataddre = mkCompGenLocal m "obj" (mkThisTy g ty)
@ -115,13 +125,13 @@ let mkThisVarThatVar g m ty =
let mkThatVarBind g m ty thataddrv expr = let mkThatVarBind g m ty thataddrv expr =
if isStructTy g ty then if isStructTy g ty then
let thatv2,_ = mkMutableCompGenLocal m "obj" ty let thatv2,_ = mkMutableCompGenLocal m "obj" ty
thatv2,mkCompGenLet m thataddrv (mkValAddr m (mkLocalValRef thatv2)) expr thatv2,mkCompGenLet m thataddrv (mkValAddr m false (mkLocalValRef thatv2)) expr
else thataddrv,expr else thataddrv,expr
let mkBindThatAddr g m ty thataddrv thatv thate expr = let mkBindThatAddr g m ty thataddrv thatv thate expr =
if isStructTy g ty then if isStructTy g ty then
// let thataddrv = &thatv // let thataddrv = &thatv
mkCompGenLet m thataddrv (mkValAddr m (mkLocalValRef thatv)) expr mkCompGenLet m thataddrv (mkValAddr m false (mkLocalValRef thatv)) expr
else else
// let thataddrv = that // let thataddrv = that
mkCompGenLet m thataddrv thate expr mkCompGenLet m thataddrv thate expr
@ -131,7 +141,7 @@ let mkBindThatAddrIfNeeded m thataddrvOpt thatv expr =
| None -> expr | None -> expr
| Some thataddrv -> | Some thataddrv ->
// let thataddrv = &thatv // let thataddrv = &thatv
mkCompGenLet m thataddrv (mkValAddr m (mkLocalValRef thatv)) expr mkCompGenLet m thataddrv (mkValAddr m false (mkLocalValRef thatv)) expr
let mkDerefThis g m (thisv: Val) thise = let mkDerefThis g m (thisv: Val) thise =
if isByrefTy g thisv.Type then mkAddrGet m (mkLocalValRef thisv) if isByrefTy g thisv.Type then mkAddrGet m (mkLocalValRef thisv)
@ -506,7 +516,6 @@ let mkUnionEquality g tcref (tycon:Tycon) =
let expr = if tycon.IsStructOrEnumTycon then expr else mkBindThatNullEquals g m thise thataddre expr let expr = if tycon.IsStructOrEnumTycon then expr else mkBindThatNullEquals g m thise thataddre expr
thisv,thatv,expr thisv,thatv,expr
/// Build the equality implementation for a union type when parameterized by a comparer /// Build the equality implementation for a union type when parameterized by a comparer
let mkUnionEqualityWithComparer g tcref (tycon:Tycon) (_thisv,thise) thatobje (thatv,thate) compe = let mkUnionEqualityWithComparer g tcref (tycon:Tycon) (_thisv,thise) thatobje (thatv,thate) compe =
let m = tycon.Range let m = tycon.Range
@ -817,7 +826,7 @@ let TyconIsCandidateForAugmentationWithCompare (g: TcGlobals) (tycon:Tycon) =
// This type gets defined in prim-types, before we can add attributes to F# type definitions // This type gets defined in prim-types, before we can add attributes to F# type definitions
let isUnit = g.compilingFslib && tycon.DisplayName = "Unit" let isUnit = g.compilingFslib && tycon.DisplayName = "Unit"
not isUnit && not isUnit &&
not (TyconRefHasAttribute g tycon.Range g.attrib_IsByRefLikeAttribute (mkLocalTyconRef tycon)) &&
match getAugmentationAttribs g tycon with match getAugmentationAttribs g tycon with
// [< >] // [< >]
| true, true, None, None, None, None , None, None, None | true, true, None, None, None, None , None, None, None
@ -832,6 +841,7 @@ let TyconIsCandidateForAugmentationWithEquals (g: TcGlobals) (tycon:Tycon) =
// This type gets defined in prim-types, before we can add attributes to F# type definitions // This type gets defined in prim-types, before we can add attributes to F# type definitions
let isUnit = g.compilingFslib && tycon.DisplayName = "Unit" let isUnit = g.compilingFslib && tycon.DisplayName = "Unit"
not isUnit && not isUnit &&
not (TyconRefHasAttribute g tycon.Range g.attrib_IsByRefLikeAttribute (mkLocalTyconRef tycon)) &&
match getAugmentationAttribs g tycon with match getAugmentationAttribs g tycon with
// [< >] // [< >]

Просмотреть файл

@ -80,6 +80,12 @@ let NewInferenceType () = mkTyparTy (NewTypar (TyparKind.Type, TyparRigidity.Fle
let NewErrorType () = mkTyparTy (NewErrorTypar ()) let NewErrorType () = mkTyparTy (NewErrorTypar ())
let NewErrorMeasure () = Measure.Var (NewErrorMeasureVar ()) let NewErrorMeasure () = Measure.Var (NewErrorMeasureVar ())
let NewByRefKindInferenceType (g: TcGlobals) m =
let tp = NewTypar (TyparKind.Type, TyparRigidity.Flexible, Typar(compgenId, HeadTypeStaticReq, true), false, TyparDynamicReq.No, [], false, false)
if g.byrefkind_InOut_tcr.CanDeref then
tp.SetConstraints [TyparConstraint.DefaultsTo(10, TType_app(g.byrefkind_InOut_tcr, []), m)]
mkTyparTy tp
let NewInferenceTypes l = l |> List.map (fun _ -> NewInferenceType ()) let NewInferenceTypes l = l |> List.map (fun _ -> NewInferenceType ())
// QUERY: should 'rigid' ever really be 'true'? We set this when we know // QUERY: should 'rigid' ever really be 'true'? We set this when we know
@ -878,6 +884,18 @@ and SolveTypSubsumesTyp (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTra
| (TType_app (tc2, [ms]), _) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms])) | (TType_app (tc2, [ms]), _) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms]))
-> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One) -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms (TType_measure Measure.One)
// Special subsumption rule for byref tags
| TType_app (tc1, l1) , TType_app (tc2, l2) when tyconRefEq g tc1 tc2 && g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tc1 ->
match l1, l2 with
| [ h1; tag1 ], [ h2; tag2 ] ->
SolveTypEqualsTyp csenv ndeep m2 trace None h1 h2 ++ (fun () ->
match stripTyEqnsA csenv.g canShortcut tag1, stripTyEqnsA csenv.g canShortcut tag2 with
| TType_app(tagc1, []), TType_app(tagc2, choices)
when (tyconRefEq g tagc2 g.choice2_tcr &&
choices |> List.exists (function AppTy g (choicetc, []) -> tyconRefEq g tagc1 choicetc | _ -> false)) -> CompleteD
| _ -> SolveTypEqualsTyp csenv ndeep m2 trace cxsln tag1 tag2)
| _ -> SolveTypEqualsTypEqns csenv ndeep m2 trace cxsln l1 l2
| TType_app (tc1, l1) , TType_app (tc2, l2) when tyconRefEq g tc1 tc2 -> | TType_app (tc1, l1) , TType_app (tc2, l2) when tyconRefEq g tc1 tc2 ->
SolveTypEqualsTypEqns csenv ndeep m2 trace cxsln l1 l2 SolveTypEqualsTypEqns csenv ndeep m2 trace cxsln l1 l2
@ -1901,7 +1919,7 @@ and CanMemberSigsMatchUpToCheck
if not (permitOptArgs || isNil unnamedCalledOptArgs) then ErrorD(Error(FSComp.SR.csOptionalArgumentNotPermittedHere(), m)) else if not (permitOptArgs || isNil unnamedCalledOptArgs) then ErrorD(Error(FSComp.SR.csOptionalArgumentNotPermittedHere(), m)) else
let calledObjArgTys = minfo.GetObjArgTypes(amap, m, minst) let calledObjArgTys = calledMeth.CalledObjArgTys(m)
// Check all the argument types. // Check all the argument types.
@ -1919,7 +1937,7 @@ and CanMemberSigsMatchUpToCheck
if isArray1DTy g calledArg.CalledArgumentType then if isArray1DTy g calledArg.CalledArgumentType then
let paramArrayElemTy = destArrayTy g calledArg.CalledArgumentType let paramArrayElemTy = destArrayTy g calledArg.CalledArgumentType
let reflArgInfo = calledArg.ReflArgInfo // propgate the reflected-arg info to each param array argument let reflArgInfo = calledArg.ReflArgInfo // propgate the reflected-arg info to each param array argument
calledMeth.ParamArrayCallerArgs |> OptionD (IterateD (fun callerArg -> subsumeArg (CalledArg((0, 0), false, NotOptional, NoCallerInfo, false, None, reflArgInfo, paramArrayElemTy)) callerArg)) calledMeth.ParamArrayCallerArgs |> OptionD (IterateD (fun callerArg -> subsumeArg (CalledArg((0, 0), false, NotOptional, NoCallerInfo, false, false, None, reflArgInfo, paramArrayElemTy)) callerArg))
else else
CompleteD) CompleteD)
@ -1942,7 +1960,7 @@ and CanMemberSigsMatchUpToCheck
let calledArgTy = rfinfo.FieldType let calledArgTy = rfinfo.FieldType
rfinfo.Name, calledArgTy rfinfo.Name, calledArgTy
subsumeArg (CalledArg((-1, 0), false, NotOptional, NoCallerInfo, false, Some (mkSynId m name), ReflectedArgInfo.None, calledArgTy)) caller) )) ++ (fun () -> subsumeArg (CalledArg((-1, 0), false, NotOptional, NoCallerInfo, false, false, Some (mkSynId m name), ReflectedArgInfo.None, calledArgTy)) caller) )) ++ (fun () ->
// - Always take the return type into account for // - Always take the return type into account for
// -- op_Explicit, op_Implicit // -- op_Explicit, op_Implicit
@ -1953,11 +1971,17 @@ and CanMemberSigsMatchUpToCheck
| Some _ when minfo.IsConstructor -> CompleteD | Some _ when minfo.IsConstructor -> CompleteD
| Some _ when not alwaysCheckReturn && isNil unnamedCalledOutArgs -> CompleteD | Some _ when not alwaysCheckReturn && isNil unnamedCalledOutArgs -> CompleteD
| Some reqdRetTy -> | Some reqdRetTy ->
let methodRetTy = calledMeth.ReturnTypeAfterOutArgTupling let methodRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling
unifyTypes reqdRetTy methodRetTy ))))) unifyTypes reqdRetTy methodRetTy )))))
// Assert a subtype constraint, and wrap an ErrorsFromAddingSubsumptionConstraint error around any failure // Assert a subtype constraint, and wrap an ErrorsFromAddingSubsumptionConstraint error around any failure
// to allow us to report the outer types involved in the constraint // to allow us to report the outer types involved in the constraint
//
// ty1: expected
// ty2: actual
//
// "ty2 casts to ty1"
// "a value of type ty2 can be used where a value of type ty1 is expected"
and private SolveTypSubsumesTypWithReport (csenv:ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 = and private SolveTypSubsumesTypWithReport (csenv:ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 =
TryD (fun () -> SolveTypSubsumesTypKeepAbbrevs csenv ndeep m trace cxsln ty1 ty2) TryD (fun () -> SolveTypSubsumesTypKeepAbbrevs csenv ndeep m trace cxsln ty1 ty2)
(function (function
@ -1973,11 +1997,11 @@ and private SolveTypSubsumesTypWithReport (csenv:ConstraintSolverEnv) ndeep m tr
// ty1: actual // ty1: actual
// ty2: expected // ty2: expected
and private SolveTypEqualsTypWithReport (csenv:ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 = and private SolveTypEqualsTypWithReport (csenv:ConstraintSolverEnv) ndeep m trace cxsln actual expected =
TryD (fun () -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m trace cxsln ty1 ty2) TryD (fun () -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m trace cxsln actual expected)
(function (function
| LocallyAbortOperationThatFailsToResolveOverload -> CompleteD | LocallyAbortOperationThatFailsToResolveOverload -> CompleteD
| res -> ErrorD (ErrorFromAddingTypeEquation(csenv.g, csenv.DisplayEnv, ty1, ty2, res, m))) | res -> ErrorD (ErrorFromAddingTypeEquation(csenv.g, csenv.DisplayEnv, actual, expected, res, m)))
and ArgsMustSubsumeOrConvert and ArgsMustSubsumeOrConvert
(csenv:ConstraintSolverEnv) (csenv:ConstraintSolverEnv)
@ -2276,15 +2300,21 @@ and ResolveOverloading
let c = compareTypes calledArg1.CalledArgumentType calledArg2.CalledArgumentType let c = compareTypes calledArg1.CalledArgumentType calledArg2.CalledArgumentType
if c <> 0 then c else if c <> 0 then c else
// Func<_> is always considered better than any other delegate type
let c = let c =
(calledArg1.CalledArgumentType, calledArg2.CalledArgumentType) ||> compareCond (fun ty1 ty2 -> (calledArg1.CalledArgumentType, calledArg2.CalledArgumentType) ||> compareCond (fun ty1 ty2 ->
// Func<_> is always considered better than any other delegate type
match tryDestAppTy csenv.g ty1 with match tryDestAppTy csenv.g ty1 with
| Some tcref1 -> | Some tcref1 when
tcref1.DisplayName = "Func" && tcref1.DisplayName = "Func" &&
(match tcref1.PublicPath with Some p -> p.EnclosingPath = [| "System" |] | _ -> false) && (match tcref1.PublicPath with Some p -> p.EnclosingPath = [| "System" |] | _ -> false) &&
isDelegateTy g ty1 && isDelegateTy g ty1 &&
isDelegateTy g ty2 isDelegateTy g ty2 -> true
// T is always better than inref<T>
| _ when isInByrefTy csenv.g ty2 && typeEquiv csenv.g ty1 (destByrefTy csenv.g ty2) ->
true
| _ -> false) | _ -> false)
if c <> 0 then c else if c <> 0 then c else
@ -2438,8 +2468,11 @@ and ResolveOverloading
| None -> CompleteD | None -> CompleteD
| Some _ when calledMeth.Method.IsConstructor -> CompleteD | Some _ when calledMeth.Method.IsConstructor -> CompleteD
| Some reqdRetTy -> | Some reqdRetTy ->
let actualRetTy = calledMeth.ReturnTypeAfterOutArgTupling let actualRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling
MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy) if isByrefTy g reqdRetTy then
ErrorD(Error(FSComp.SR.tcByrefReturnImplicitlyDereferenced(), m))
else
MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy)
| None -> | None ->
None, errors None, errors
@ -2649,7 +2682,7 @@ let CodegenWitnessThatTypSupportsTraitConstraint tcVal g amap m (traitInfo:Trait
// the address of the object then go do that // the address of the object then go do that
if minfo.IsStruct && minfo.IsInstance && (match argExprs with [] -> false | h :: _ -> not (isByrefTy g (tyOfExpr g h))) then if minfo.IsStruct && minfo.IsInstance && (match argExprs with [] -> false | h :: _ -> not (isByrefTy g (tyOfExpr g h))) then
let h, t = List.headAndTail argExprs let h, t = List.headAndTail argExprs
let wrap, h' = mkExprAddrOfExpr g true false PossiblyMutates h None m let wrap, h', _readonly = mkExprAddrOfExpr g true false PossiblyMutates h None m
ResultD (Some (wrap (Expr.Op(TOp.TraitCall(traitInfo), [], (h' :: t), m)))) ResultD (Some (wrap (Expr.Op(TOp.TraitCall(traitInfo), [], (h' :: t), m))))
else else
ResultD (Some (MakeMethInfoCall amap m minfo methArgTys argExprs )) ResultD (Some (MakeMethInfoCall amap m minfo methArgTys argExprs ))
@ -2664,7 +2697,7 @@ let CodegenWitnessThatTypSupportsTraitConstraint tcVal g amap m (traitInfo:Trait
// the address of the object then go do that // the address of the object then go do that
if rfref.Tycon.IsStructOrEnumTycon && not (isByrefTy g (tyOfExpr g argExprs.[0])) then if rfref.Tycon.IsStructOrEnumTycon && not (isByrefTy g (tyOfExpr g argExprs.[0])) then
let h = List.head argExprs let h = List.head argExprs
let wrap, h' = mkExprAddrOfExpr g true false DefinitelyMutates h None m let wrap, h', _readonly = mkExprAddrOfExpr g true false DefinitelyMutates h None m
Some (wrap (mkRecdFieldSetViaExprAddr (h', rfref, tinst, argExprs.[1], m))) Some (wrap (mkRecdFieldSetViaExprAddr (h', rfref, tinst, argExprs.[1], m)))
else else
Some (mkRecdFieldSetViaExprAddr (argExprs.[0], rfref, tinst, argExprs.[1], m)) Some (mkRecdFieldSetViaExprAddr (argExprs.[0], rfref, tinst, argExprs.[1], m))

Просмотреть файл

@ -22,6 +22,9 @@ val NewAnonTypar : TyparKind * range * TyparRigidity * TyparStaticReq * TyparDyn
/// Create an inference type variable /// Create an inference type variable
val NewInferenceType : unit -> TType val NewInferenceType : unit -> TType
/// Create an inference type variable for the kind of a byref pointer
val NewByRefKindInferenceType : TcGlobals -> range -> TType
/// Create an inference type variable representing an error condition when checking an expression /// Create an inference type variable representing an error condition when checking an expression
val NewErrorType : unit -> TType val NewErrorType : unit -> TType

Просмотреть файл

@ -584,10 +584,10 @@ let decideTransform g z v callPatterns (m, tps, vss:Val list list, rty) =
// Public f could be used beyond assembly. // Public f could be used beyond assembly.
// For now, suppressing any transforms on these. // For now, suppressing any transforms on these.
// Later, could transform f and fix up local calls and provide an f wrapper for beyond. // Later, could transform f and fix up local calls and provide an f wrapper for beyond.
let eligibleVal g (v:Val) = let eligibleVal g m (v:Val) =
let dllImportStubOrOtherNeverInline = (v.InlineInfo = ValInline.Never) let dllImportStubOrOtherNeverInline = (v.InlineInfo = ValInline.Never)
let mutableVal = v.IsMutable let mutableVal = v.IsMutable
let byrefVal = isByrefLikeTy g v.Type let byrefVal = isByrefLikeTy g m v.Type
not dllImportStubOrOtherNeverInline && not dllImportStubOrOtherNeverInline &&
not byrefVal && not byrefVal &&
not mutableVal && not mutableVal &&
@ -595,8 +595,8 @@ let eligibleVal g (v:Val) =
not v.IsCompiledAsTopLevel not v.IsCompiledAsTopLevel
let determineTransforms g (z : GlobalUsageAnalysis.Results) = let determineTransforms g (z : GlobalUsageAnalysis.Results) =
let selectTransform f sites = let selectTransform (f: Val) sites =
if not (eligibleVal g f) then None else if not (eligibleVal g f.Range f) then None else
// Consider f, if it has top-level lambda (meaning has term args) // Consider f, if it has top-level lambda (meaning has term args)
match Zmap.tryFind f z.Defns with match Zmap.tryFind f z.Defns with
| None -> None // no binding site, so no transform | None -> None // no binding site, so no transform

Просмотреть файл

@ -1331,7 +1331,7 @@ tcTupleStructMismatch,"One tuple type is a struct tuple, the other is a referenc
3206,CallerMemberNameIsOverriden,"The CallerMemberNameAttribute applied to parameter '%s' will have no effect. It is overridden by the CallerFilePathAttribute." 3206,CallerMemberNameIsOverriden,"The CallerMemberNameAttribute applied to parameter '%s' will have no effect. It is overridden by the CallerFilePathAttribute."
3207,tcFixedNotAllowed,"Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'" 3207,tcFixedNotAllowed,"Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'"
3208,tcCouldNotFindOffsetToStringData,"Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression." 3208,tcCouldNotFindOffsetToStringData,"Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression."
3209,chkNoByrefReturnOfLocal,"The address of the variable '%s' cannot be used at this point. A method or function may not return the address of this local value." 3209,chkNoByrefAddressOfLocal,"The address of the variable '%s' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope."
3210,tcNamedActivePattern,"%s is an active pattern and cannot be treated as a discriminated union case with named fields." 3210,tcNamedActivePattern,"%s is an active pattern and cannot be treated as a discriminated union case with named fields."
3211,DefaultParameterValueNotAppropriateForArgument,"The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'." 3211,DefaultParameterValueNotAppropriateForArgument,"The default value does not have the same type as the argument. The DefaultParameterValue attribute and any Optional attribute will be ignored. Note: 'null' needs to be annotated with the correct type, e.g. 'DefaultParameterValue(null:obj)'."
tcGlobalsSystemTypeNotFound,"The system type '%s' was required but no referenced system DLL contained this type" tcGlobalsSystemTypeNotFound,"The system type '%s' was required but no referenced system DLL contained this type"
@ -1425,4 +1425,14 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl
3220,tcTupleMemberNotNormallyUsed,"This method or property is not normally used from F# code, use an explicit tuple pattern for deconstruction instead." 3220,tcTupleMemberNotNormallyUsed,"This method or property is not normally used from F# code, use an explicit tuple pattern for deconstruction instead."
3221,implicitlyDiscardedInSequenceExpression,"This expression returns a value of type '%s' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield'." 3221,implicitlyDiscardedInSequenceExpression,"This expression returns a value of type '%s' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield'."
3222,implicitlyDiscardedSequenceInSequenceExpression,"This expression returns a value of type '%s' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield!'." 3222,implicitlyDiscardedSequenceInSequenceExpression,"This expression returns a value of type '%s' but is implicitly discarded. Consider using 'let' to bind the result to a name, e.g. 'let result = expression'. If you intended to use the expression as a value in the sequence then use an explicit 'yield!'."
3223,ilreadFileChanged,"The file '%s' changed on disk unexpectedly, please reload." 3223,ilreadFileChanged,"The file '%s' changed on disk unexpectedly, please reload."
3224,writeToReadOnlyByref,"The byref pointer is readonly, so this write is not permitted."
3225,readOnlyAttributeOnStructWithMutableField,"A ReadOnly attribute has been applied to a struct type with a mutable field."
3226,tcByrefReturnImplicitlyDereferenced,"A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'."
3227,tcByRefLikeNotStruct,"A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type."
3228,chkNoByrefReturnOfLocal,"The address of the variable '%s' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope."
3229,chkNoReturnOfLimitedSpan,"The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope."
3230,chkNoWriteToLimitedSpan,"This value can't be assigned because the target '%s' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope."
3231,tastValueMustBeLocal,"A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'"
3232,tcIsReadOnlyNotStruct,"A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type."
3234,chkStructsMayNotReturnAddressesOfContents,"Struct members cannot return the address of fields of the struct by reference"

Просмотреть файл

@ -25,6 +25,14 @@ module NativePtr =
[<CompiledName("ToNativeIntInlined")>] [<CompiledName("ToNativeIntInlined")>]
let inline toNativeInt (address: nativeptr<'T>) = (# "" address : nativeint #) let inline toNativeInt (address: nativeptr<'T>) = (# "" address : nativeint #)
[<NoDynamicInvocation>]
[<CompiledName("ToVoidPtrInlined")>]
let inline toVoidPtr (address: nativeptr<'T>) = (# "" address : voidptr #)
[<NoDynamicInvocation>]
[<CompiledName("OfVoidPtrInlined")>]
let inline ofVoidPtr (address: voidptr) = (# "" address : nativeptr<'T> #)
[<NoDynamicInvocation>] [<NoDynamicInvocation>]
[<CompiledName("AddPointerInlined")>] [<CompiledName("AddPointerInlined")>]
let inline add (address : nativeptr<'T>) (index:int) : nativeptr<'T> = toNativeInt address + nativeint index * (# "sizeof !0" type('T) : nativeint #) |> ofNativeInt let inline add (address : nativeptr<'T>) (index:int) : nativeptr<'T> = toNativeInt address + nativeint index * (# "sizeof !0" type('T) : nativeint #) |> ofNativeInt

Просмотреть файл

@ -19,6 +19,22 @@ namespace Microsoft.FSharp.NativeInterop
/// <returns>A typed pointer.</returns> /// <returns>A typed pointer.</returns>
val inline ofNativeInt : address:nativeint -> nativeptr<'T> val inline ofNativeInt : address:nativeint -> nativeptr<'T>
[<Unverifiable>]
[<NoDynamicInvocation>]
[<CompiledName("ToVoidPtrInlined")>]
/// <summary>Returns an untyped native pointer for a given typed pointer.</summary>
/// <param name="address">The pointer address.</param>
/// <returns>A typed pointer.</returns>
val inline toVoidPtr : address:nativeptr<'T> -> voidptr
[<Unverifiable>]
[<NoDynamicInvocation>]
[<CompiledName("OfVoidPtrInlined")>]
/// <summary>Returns a typed native pointer for a untyped native pointer.</summary>
/// <param name="address">The untyped pointer.</param>
/// <returns>A typed pointer.</returns>
val inline ofVoidPtr : voidptr -> nativeptr<'T>
[<Unverifiable>] [<Unverifiable>]
[<NoDynamicInvocation>] [<NoDynamicInvocation>]
[<CompiledName("ToNativeIntInlined")>] [<CompiledName("ToNativeIntInlined")>]

Просмотреть файл

@ -64,8 +64,14 @@ namespace Microsoft.FSharp.Core
type array<'T> = 'T[] type array<'T> = 'T[]
/// <summary>Represents a managed pointer in F# code.</summary>
type byref<'T, 'Kind> = (# "!0&" #)
/// <summary>Represents a managed pointer in F# code. For F# 4.5+ this is considered equivalent to <c>byref&lt'T, ByRefKinds.InOut&gt</c></summary>
type byref<'T> = (# "!0&" #) type byref<'T> = (# "!0&" #)
type nativeptr<'T when 'T : unmanaged> = (# "native int" #) type nativeptr<'T when 'T : unmanaged> = (# "native int" #)
type ilsigptr<'T> = (# "!0*" #)
type voidptr = (# "void*" #)
type ilsigptr<'T> = (# "!0*" #)

Просмотреть файл

@ -228,8 +228,10 @@ namespace Microsoft.FSharp.Core
/// values.</remarks> /// values.</remarks>
type 'T array = 'T[] type 'T array = 'T[]
/// <summary>Represents a managed pointer in F# code.</summary> /// <summary>Represents a managed pointer in F# code.</summary>
type byref<'T, 'Kind> = (# "!0&" #)
/// <summary>Represents a managed pointer in F# code. For F# 4.5+ this is considered equivalent to <c>byref&lt'T, ByRefKinds.InOut&gt</c></summary>
type byref<'T> = (# "!0&" #) type byref<'T> = (# "!0&" #)
/// <summary>Represents an unmanaged pointer in F# code.</summary> /// <summary>Represents an unmanaged pointer in F# code.</summary>
@ -241,6 +243,15 @@ namespace Microsoft.FSharp.Core
/// by the functions in the <c>NativeInterop.NativePtr</c> module.</remarks> /// by the functions in the <c>NativeInterop.NativePtr</c> module.</remarks>
type nativeptr<'T when 'T : unmanaged> = (# "native int" #) type nativeptr<'T when 'T : unmanaged> = (# "native int" #)
/// <summary>Represents an untyped unmanaged pointer in F# code.</summary>
///
/// <remarks>This type should only be used when writing F# code that interoperates
/// with native code. Use of this type in F# code may result in
/// unverifiable code being generated. Conversions to and from the
/// <c>nativeint</c> type may be required. Values of this type can be generated
/// by the functions in the <c>NativeInterop.NativePtr</c> module.</remarks>
type voidptr = (# "void*" #)
/// <summary>This type is for internal use by the F# code generator.</summary> /// <summary>This type is for internal use by the F# code generator.</summary>
type ilsigptr<'T> = (# "!0*" #) type ilsigptr<'T> = (# "!0*" #)

Просмотреть файл

@ -5649,6 +5649,24 @@ namespace Microsoft.FSharp.Core
if n >= 0 then PowDecimal x n else 1.0M / PowDecimal x n) if n >= 0 then PowDecimal x n else 1.0M / PowDecimal x n)
/// Represents the types of byrefs in F# 4.5+
module ByRefKinds =
/// Represents a byref that can be written
type Out() = class end
/// Represents a byref that can be read
type In() = class end
/// Represents a byref that can be both read and written
type InOut = Choice<In, Out>
/// <summary>Represents a in-argument or readonly managed pointer in F# code. This type should only be used with F# 4.5+.</summary>
type inref<'T> = byref<'T, ByRefKinds.In>
/// <summary>Represents a out-argument managed pointer in F# code. This type should only be used with F# 4.5+.</summary>
type outref<'T> = byref<'T, ByRefKinds.Out>
namespace Microsoft.FSharp.Control namespace Microsoft.FSharp.Control
open System open System

Просмотреть файл

@ -1659,6 +1659,24 @@ namespace Microsoft.FSharp.Core
/// <returns>The optimized function.</returns> /// <returns>The optimized function.</returns>
new : unit -> FSharpFunc<'T1,'T2,'T3,'T4,'T5,'U> new : unit -> FSharpFunc<'T1,'T2,'T3,'T4,'T5,'U>
/// Represents the types of byrefs in F# 4.5+
module ByRefKinds =
/// Represents a byref that can be written
type Out = class end
/// Represents a byref that can be read
type In = class end
/// Represents a byref that can be both read and written
type InOut = Choice<In, Out>
/// <summary>Represents a in-argument or readonly managed pointer in F# code. This type should only be used with F# 4.5+.</summary>
type inref<'T> = byref<'T, ByRefKinds.In>
/// <summary>Represents a out-argument managed pointer in F# code. This type should only be used with F# 4.5+.</summary>
type outref<'T> = byref<'T, ByRefKinds.Out>
/// <summary>The type of mutable references. Use the functions [!] and [:=] to get and /// <summary>The type of mutable references. Use the functions [!] and [:=] to get and
/// set values of this type.</summary> /// set values of this type.</summary>
[<StructuralEquality; StructuralComparison>] [<StructuralEquality; StructuralComparison>]
@ -3195,6 +3213,7 @@ namespace Microsoft.FSharp.Core
[<CompiledName("ToChar")>] [<CompiledName("ToChar")>]
val inline char : value:^T -> char when ^T : (static member op_Explicit : ^T -> char) and default ^T : int val inline char : value:^T -> char when ^T : (static member op_Explicit : ^T -> char) and default ^T : int
namespace Microsoft.FSharp.Control namespace Microsoft.FSharp.Control
open Microsoft.FSharp.Core open Microsoft.FSharp.Core

Просмотреть файл

@ -363,14 +363,30 @@ let voidCheck m g permits ty =
error(InternalError("System.Void unexpectedly detected in IL code generation. This should not occur.",m)) error(InternalError("System.Void unexpectedly detected in IL code generation. This should not occur.",m))
#endif #endif
// When generating parameter and return types generate precise .NET IL pointer types /// When generating parameter and return types generate precise .NET IL pointer types.
// These can't be generated for generic instantiations, since .NET generics doesn't /// These can't be generated for generic instantiations, since .NET generics doesn't
// permit this. But for 'naked' values (locals, parameters, return values etc.) machine /// permit this. But for 'naked' values (locals, parameters, return values etc.) machine
// integer values and native pointer values are compatible (though the code is unverifiable). /// integer values and native pointer values are compatible (though the code is unverifiable).
type PtrsOK = type PtrsOK =
| PtrTypesOK | PtrTypesOK
| PtrTypesNotOK | PtrTypesNotOK
let GenReadOnlyAttributeIfNecessary (g: TcGlobals) ty =
let add = isInByrefTy g ty && g.attrib_IsReadOnlyAttribute.TyconRef.CanDeref
if add then
let attr = mkILCustomAttribute g.ilg (g.attrib_IsReadOnlyAttribute.TypeRef, [], [], [])
Some attr
else
None
/// Generate "modreq([mscorlib]System.Runtime.InteropServices.InAttribute)" on inref types.
let GenReadOnlyModReqIfNecessary (g: TcGlobals) ty ilTy =
let add = isInByrefTy g ty && g.attrib_InAttribute.TyconRef.CanDeref
if add then
ILType.Modified(true, g.attrib_InAttribute.TypeRef, ilTy)
else
ilTy
let rec GenTypeArgAux amap m tyenv tyarg = let rec GenTypeArgAux amap m tyenv tyarg =
GenTypeAux amap m tyenv VoidNotOK PtrTypesNotOK tyarg GenTypeAux amap m tyenv VoidNotOK PtrTypesNotOK tyarg
@ -395,6 +411,7 @@ and GenTyAppAux amap m tyenv repr tinst =
and GenNamedTyAppAux (amap:ImportMap) m tyenv ptrsOK tcref tinst = and GenNamedTyAppAux (amap:ImportMap) m tyenv ptrsOK tcref tinst =
let g = amap.g let g = amap.g
let tinst = DropErasedTyargs tinst let tinst = DropErasedTyargs tinst
// See above note on ptrsOK // See above note on ptrsOK
if ptrsOK = PtrTypesOK && tyconRefEq g tcref g.nativeptr_tcr && (freeInTypes CollectTypars tinst).FreeTypars.IsEmpty then if ptrsOK = PtrTypesOK && tyconRefEq g tcref g.nativeptr_tcr && (freeInTypes CollectTypars tinst).FreeTypars.IsEmpty then
GenNamedTyAppAux amap m tyenv ptrsOK g.ilsigptr_tcr tinst GenNamedTyAppAux amap m tyenv ptrsOK g.ilsigptr_tcr tinst
@ -417,7 +434,10 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty =
#endif #endif
match stripTyEqnsAndMeasureEqns g ty with match stripTyEqnsAndMeasureEqns g ty with
| TType_app (tcref, tinst) -> GenNamedTyAppAux amap m tyenv ptrsOK tcref tinst | TType_app (tcref, tinst) -> GenNamedTyAppAux amap m tyenv ptrsOK tcref tinst
| TType_tuple (tupInfo, args) -> GenTypeAux amap m tyenv VoidNotOK ptrsOK (mkCompiledTupleTy g (evalTupInfoIsStruct tupInfo) args) | TType_tuple (tupInfo, args) -> GenTypeAux amap m tyenv VoidNotOK ptrsOK (mkCompiledTupleTy g (evalTupInfoIsStruct tupInfo) args)
| TType_fun (dty, returnTy) -> EraseClosures.mkILFuncTy g.ilxPubCloEnv (GenTypeArgAux amap m tyenv dty) (GenTypeArgAux amap m tyenv returnTy) | TType_fun (dty, returnTy) -> EraseClosures.mkILFuncTy g.ilxPubCloEnv (GenTypeArgAux amap m tyenv dty) (GenTypeArgAux amap m tyenv returnTy)
| TType_ucase (ucref, args) -> | TType_ucase (ucref, args) ->
@ -428,7 +448,9 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty =
let tps = DropErasedTypars tps let tps = DropErasedTypars tps
if tps.IsEmpty then GenTypeAux amap m tyenv VoidNotOK ptrsOK tau if tps.IsEmpty then GenTypeAux amap m tyenv VoidNotOK ptrsOK tau
else EraseClosures.mkILTyFuncTy g.ilxPubCloEnv else EraseClosures.mkILTyFuncTy g.ilxPubCloEnv
| TType_var tp -> mkILTyvarTy tyenv.[tp,m] | TType_var tp -> mkILTyvarTy tyenv.[tp,m]
| TType_measure _ -> g.ilg.typ_Int32 | TType_measure _ -> g.ilg.typ_Int32
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@ -504,13 +526,19 @@ and GenNamedTyApp amap m tyenv tcref tinst = GenNamedTyAppAux amap m tyenv PtrTy
and GenReturnType amap m tyenv returnTyOpt = and GenReturnType amap m tyenv returnTyOpt =
match returnTyOpt with match returnTyOpt with
| None -> ILType.Void | None -> ILType.Void
| Some returnTy -> GenTypeAux amap m tyenv VoidNotOK(*1*) PtrTypesOK returnTy (*1: generate void from unit, but not accept void *) | Some returnTy ->
let ilTy = GenTypeAux amap m tyenv VoidNotOK(*1*) PtrTypesOK returnTy (*1: generate void from unit, but not accept void *)
GenReadOnlyModReqIfNecessary amap.g returnTy ilTy
and GenParamType amap m tyenv ty = and GenParamType amap m tyenv isSlotSig ty =
ty |> GenTypeAux amap m tyenv VoidNotOK PtrTypesOK let ilTy = GenTypeAux amap m tyenv VoidNotOK PtrTypesOK ty
if isSlotSig then
GenReadOnlyModReqIfNecessary amap.g ty ilTy
else
ilTy
and GenParamTypes amap m tyenv tys = and GenParamTypes amap m tyenv isSlotSig tys =
tys |> List.map (GenTypeAux amap m tyenv VoidNotOK PtrTypesOK) tys |> List.map (GenParamType amap m tyenv isSlotSig)
and GenTypeArgs amap m tyenv tyargs = GenTypeArgsAux amap m tyenv tyargs and GenTypeArgs amap m tyenv tyargs = GenTypeArgsAux amap m tyenv tyargs
@ -607,7 +635,7 @@ type ValStorage =
| StaticProperty of ILMethodSpec * OptionalShadowLocal | StaticProperty of ILMethodSpec * OptionalShadowLocal
/// Indicates the value is "stored" as a IL static method (in a "main" class for a F# /// Indicates the value is "stored" as a IL static method (in a "main" class for a F#
/// compilation unit, or as a member) according to its inferred or specified arity. /// compilation unit, or as a member) according to its inferred or specified arity.
| Method of ValReprInfo * ValRef * ILMethodSpec * Range.range * ArgReprInfo list * ArgReprInfo | Method of ValReprInfo * ValRef * ILMethodSpec * Range.range * ArgReprInfo list * TType list * ArgReprInfo
/// Indicates the value is stored at the given position in the closure environment accessed via "ldarg 0" /// Indicates the value is stored at the given position in the closure environment accessed via "ldarg 0"
| Env of ILType * int * ILFieldSpec * NamedLocalIlxClosureInfo ref option | Env of ILType * int * ILFieldSpec * NamedLocalIlxClosureInfo ref option
/// Indicates that the value is an argument of a method being generated /// Indicates that the value is an argument of a method being generated
@ -775,7 +803,9 @@ let GetMethodSpecForMemberVal amap g (memberInfo:ValMemberInfo) (vref:ValRef) =
let ilActualRetTy = let ilActualRetTy =
let ilRetTy = GenReturnType amap m tyenvUnderTypars returnTy let ilRetTy = GenReturnType amap m tyenvUnderTypars returnTy
if isCtor || cctor then ILType.Void else ilRetTy if isCtor || cctor then ILType.Void else ilRetTy
let ilTy = GenType amap m tyenvUnderTypars (mkAppTy parentTcref (List.map mkTyparTy ctps)) let ilTy = GenType amap m tyenvUnderTypars (mkAppTy parentTcref (List.map mkTyparTy ctps))
if isCompiledAsInstance || isCtor then if isCompiledAsInstance || isCtor then
// Find the 'this' argument type if any // Find the 'this' argument type if any
let thisTy,flatArgInfos = let thisTy,flatArgInfos =
@ -797,18 +827,19 @@ let GetMethodSpecForMemberVal amap g (memberInfo:ValMemberInfo) (vref:ValRef) =
ctps ctps
thisArgTys thisArgTys
let methodArgTys,paramInfos = List.unzip flatArgInfos let methodArgTys,paramInfos = List.unzip flatArgInfos
let ilMethodArgTys = GenParamTypes amap m tyenvUnderTypars methodArgTys let isSlotSig = memberInfo.MemberFlags.IsDispatchSlot || memberInfo.MemberFlags.IsOverrideOrExplicitImpl
let ilMethodArgTys = GenParamTypes amap m tyenvUnderTypars isSlotSig methodArgTys
let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy mtps) let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy mtps)
let mspec = mkILInstanceMethSpecInTy (ilTy,vref.CompiledName,ilMethodArgTys,ilActualRetTy,ilMethodInst) let mspec = mkILInstanceMethSpecInTy (ilTy,vref.CompiledName,ilMethodArgTys,ilActualRetTy,ilMethodInst)
mspec,ctps,mtps,paramInfos,retInfo mspec,ctps,mtps,paramInfos,retInfo,methodArgTys
else else
let methodArgTys,paramInfos = List.unzip flatArgInfos let methodArgTys,paramInfos = List.unzip flatArgInfos
let ilMethodArgTys = GenParamTypes amap m tyenvUnderTypars methodArgTys let ilMethodArgTys = GenParamTypes amap m tyenvUnderTypars false methodArgTys
let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy mtps) let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy mtps)
let mspec = mkILStaticMethSpecInTy (ilTy,vref.CompiledName,ilMethodArgTys,ilActualRetTy,ilMethodInst) let mspec = mkILStaticMethSpecInTy (ilTy,vref.CompiledName,ilMethodArgTys,ilActualRetTy,ilMethodInst)
mspec,ctps,mtps,paramInfos,retInfo mspec,ctps,mtps,paramInfos,retInfo,methodArgTys
// Generate the ILFieldSpec for a top-level value // Generate the ILFieldSpec for a top-level value
@ -894,18 +925,18 @@ let ComputeStorageForTopVal (amap, g, optIntraAssemblyInfo:IlxGenIntraAssemblyIn
| _ -> | _ ->
match vref.MemberInfo with match vref.MemberInfo with
| Some memberInfo when not vref.IsExtensionMember -> | Some memberInfo when not vref.IsExtensionMember ->
let mspec,_,_,paramInfos,retInfo = GetMethodSpecForMemberVal amap g memberInfo vref let mspec,_,_,paramInfos,retInfo,methodArgTys = GetMethodSpecForMemberVal amap g memberInfo vref
Method (topValInfo, vref, mspec, m, paramInfos, retInfo) Method (topValInfo, vref, mspec, m, paramInfos, methodArgTys, retInfo)
| _ -> | _ ->
let (tps, curriedArgInfos, returnTy, retInfo) = GetTopValTypeInCompiledForm g topValInfo vref.Type m let (tps, curriedArgInfos, returnTy, retInfo) = GetTopValTypeInCompiledForm g topValInfo vref.Type m
let tyenvUnderTypars = TypeReprEnv.ForTypars tps let tyenvUnderTypars = TypeReprEnv.ForTypars tps
let (methodArgTys,paramInfos) = curriedArgInfos |> List.concat |> List.unzip let (methodArgTys,paramInfos) = curriedArgInfos |> List.concat |> List.unzip
let ilMethodArgTys = GenParamTypes amap m tyenvUnderTypars methodArgTys let ilMethodArgTys = GenParamTypes amap m tyenvUnderTypars false methodArgTys
let ilRetTy = GenReturnType amap m tyenvUnderTypars returnTy let ilRetTy = GenReturnType amap m tyenvUnderTypars returnTy
let ilLocTy = mkILTyForCompLoc cloc let ilLocTy = mkILTyForCompLoc cloc
let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy tps) let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy tps)
let mspec = mkILStaticMethSpecInTy (ilLocTy, nm, ilMethodArgTys, ilRetTy, ilMethodInst) let mspec = mkILStaticMethSpecInTy (ilLocTy, nm, ilMethodArgTys, ilRetTy, ilMethodInst)
Method (topValInfo, vref, mspec, m, paramInfos, retInfo) Method (topValInfo, vref, mspec, m, paramInfos, methodArgTys, retInfo)
let ComputeAndAddStorageForLocalTopVal (amap, g, intraAssemblyFieldTable, isInteractive, optShadowLocal) cloc (v:Val) eenv = let ComputeAndAddStorageForLocalTopVal (amap, g, intraAssemblyFieldTable, isInteractive, optShadowLocal) cloc (v:Val) eenv =
let storage = ComputeStorageForTopVal (amap, g, Some intraAssemblyFieldTable, isInteractive, optShadowLocal, mkLocalValRef v, cloc) let storage = ComputeStorageForTopVal (amap, g, Some intraAssemblyFieldTable, isInteractive, optShadowLocal, mkLocalValRef v, cloc)
@ -1881,7 +1912,7 @@ let rec GenExpr (cenv:cenv) (cgbuf:CodeGenBuffer) eenv sp expr sequel =
GenGetExnField cenv cgbuf eenv (e,ecref,n,m) sequel GenGetExnField cenv cgbuf eenv (e,ecref,n,m) sequel
| TOp.UnionCaseFieldGet(ucref,n),[e],_ -> | TOp.UnionCaseFieldGet(ucref,n),[e],_ ->
GenGetUnionCaseField cenv cgbuf eenv (e,ucref,tyargs,n,m) sequel GenGetUnionCaseField cenv cgbuf eenv (e,ucref,tyargs,n,m) sequel
| TOp.UnionCaseFieldGetAddr(ucref,n),[e],_ -> | TOp.UnionCaseFieldGetAddr(ucref,n,_readonly),[e],_ ->
GenGetUnionCaseFieldAddr cenv cgbuf eenv (e,ucref,tyargs,n,m) sequel GenGetUnionCaseFieldAddr cenv cgbuf eenv (e,ucref,tyargs,n,m) sequel
| TOp.UnionCaseTagGet ucref,[e],_ -> | TOp.UnionCaseTagGet ucref,[e],_ ->
GenGetUnionCaseTag cenv cgbuf eenv (e,ucref,tyargs,m) sequel GenGetUnionCaseTag cenv cgbuf eenv (e,ucref,tyargs,m) sequel
@ -1895,9 +1926,9 @@ let rec GenExpr (cenv:cenv) (cgbuf:CodeGenBuffer) eenv sp expr sequel =
GenGetRecdField cenv cgbuf eenv (e,f,tyargs,m) sequel GenGetRecdField cenv cgbuf eenv (e,f,tyargs,m) sequel
| TOp.ValFieldGet f,[],_ -> | TOp.ValFieldGet f,[],_ ->
GenGetStaticField cenv cgbuf eenv (f,tyargs,m) sequel GenGetStaticField cenv cgbuf eenv (f,tyargs,m) sequel
| TOp.ValFieldGetAddr f,[e],_ -> | TOp.ValFieldGetAddr (f, _readonly),[e],_ ->
GenGetRecdFieldAddr cenv cgbuf eenv (e,f,tyargs,m) sequel GenGetRecdFieldAddr cenv cgbuf eenv (e,f,tyargs,m) sequel
| TOp.ValFieldGetAddr f,[],_ -> | TOp.ValFieldGetAddr (f, _readonly),[],_ ->
GenGetStaticFieldAddr cenv cgbuf eenv (f,tyargs,m) sequel GenGetStaticFieldAddr cenv cgbuf eenv (f,tyargs,m) sequel
| TOp.ValFieldSet f,[e1;e2],_ -> | TOp.ValFieldSet f,[e1;e2],_ ->
GenSetRecdField cenv cgbuf eenv (e1,f,tyargs,e2,m) sequel GenSetRecdField cenv cgbuf eenv (e1,f,tyargs,e2,m) sequel
@ -1917,14 +1948,14 @@ let rec GenExpr (cenv:cenv) (cgbuf:CodeGenBuffer) eenv sp expr sequel =
GenTryCatch cenv cgbuf eenv (e1,vf,ef,vh,eh,m,resty,spTry,spWith) sequel GenTryCatch cenv cgbuf eenv (e1,vf,ef,vh,eh,m,resty,spTry,spWith) sequel
| TOp.ILCall(virt,_,valu,newobj,valUseFlags,_,isDllImport,ilMethRef,enclArgTys,methArgTys,returnTys),args,[] -> | TOp.ILCall(virt,_,valu,newobj,valUseFlags,_,isDllImport,ilMethRef,enclArgTys,methArgTys,returnTys),args,[] ->
GenILCall cenv cgbuf eenv (virt,valu,newobj,valUseFlags,isDllImport,ilMethRef,enclArgTys,methArgTys,args,returnTys,m) sequel GenILCall cenv cgbuf eenv (virt,valu,newobj,valUseFlags,isDllImport,ilMethRef,enclArgTys,methArgTys,args,returnTys,m) sequel
| TOp.RefAddrGet,[e],[ty] -> GenGetAddrOfRefCellField cenv cgbuf eenv (e,ty,m) sequel | TOp.RefAddrGet _readonly,[e],[ty] -> GenGetAddrOfRefCellField cenv cgbuf eenv (e,ty,m) sequel
| TOp.Coerce,[e],[tgty;srcty] -> GenCoerce cenv cgbuf eenv (e,tgty,m,srcty) sequel | TOp.Coerce,[e],[tgty;srcty] -> GenCoerce cenv cgbuf eenv (e,tgty,m,srcty) sequel
| TOp.Reraise,[],[rtnty] -> GenReraise cenv cgbuf eenv (rtnty,m) sequel | TOp.Reraise,[],[rtnty] -> GenReraise cenv cgbuf eenv (rtnty,m) sequel
| TOp.TraitCall(ss),args,[] -> GenTraitCall cenv cgbuf eenv (ss,args, m) expr sequel | TOp.TraitCall(ss),args,[] -> GenTraitCall cenv cgbuf eenv (ss,args, m) expr sequel
| TOp.LValueOp(LSet,v),[e],[] -> GenSetVal cenv cgbuf eenv (v,e,m) sequel | TOp.LValueOp(LSet,v),[e],[] -> GenSetVal cenv cgbuf eenv (v,e,m) sequel
| TOp.LValueOp(LByrefGet,v),[],[] -> GenGetByref cenv cgbuf eenv (v,m) sequel | TOp.LValueOp(LByrefGet,v),[],[] -> GenGetByref cenv cgbuf eenv (v,m) sequel
| TOp.LValueOp(LByrefSet,v),[e],[] -> GenSetByref cenv cgbuf eenv (v,e,m) sequel | TOp.LValueOp(LByrefSet,v),[e],[] -> GenSetByref cenv cgbuf eenv (v,e,m) sequel
| TOp.LValueOp(LGetAddr,v),[],[] -> GenGetValAddr cenv cgbuf eenv (v,m) sequel | TOp.LValueOp(LAddrOf _,v),[],[] -> GenGetValAddr cenv cgbuf eenv (v,m) sequel
| TOp.Array,elems,[elemTy] -> GenNewArray cenv cgbuf eenv (elems,elemTy,m) sequel | TOp.Array,elems,[elemTy] -> GenNewArray cenv cgbuf eenv (elems,elemTy,m) sequel
| TOp.Bytes bytes,[],[] -> | TOp.Bytes bytes,[],[] ->
if cenv.opts.emitConstantArraysUsingStaticDataBlobs then if cenv.opts.emitConstantArraysUsingStaticDataBlobs then
@ -2546,7 +2577,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
let storage = StorageForValRef m vref eenv let storage = StorageForValRef m vref eenv
match storage with match storage with
| Method (_,_,mspec,_,_,_) -> | Method (_,_,mspec,_,_,_,_) ->
CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.iltyp_RuntimeMethodHandle]) (I_ldtoken (ILToken.ILMethod mspec)) CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.iltyp_RuntimeMethodHandle]) (I_ldtoken (ILToken.ILMethod mspec))
| _ -> | _ ->
errorR(Error(FSComp.SR.ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen(), m)) errorR(Error(FSComp.SR.ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen(), m))
@ -2573,7 +2604,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
when when
(let storage = StorageForValRef m vref eenv (let storage = StorageForValRef m vref eenv
match storage with match storage with
| Method (topValInfo,vref,_,_,_,_) -> | Method (topValInfo,vref,_,_,_,_,_) ->
(let tps,argtys,_,_ = GetTopValTypeInFSharpForm cenv.g topValInfo vref.Type m (let tps,argtys,_,_ = GetTopValTypeInFSharpForm cenv.g topValInfo vref.Type m
tps.Length = tyargs.Length && tps.Length = tyargs.Length &&
argtys.Length <= args.Length) argtys.Length <= args.Length)
@ -2581,7 +2612,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
let storage = StorageForValRef m vref eenv let storage = StorageForValRef m vref eenv
match storage with match storage with
| Method (topValInfo,vref,mspec,_,_,_) -> | Method (topValInfo,vref,mspec,_,_,_,_) ->
let nowArgs,laterArgs = let nowArgs,laterArgs =
let _,curriedArgInfos,_,_ = GetTopValTypeInFSharpForm cenv.g topValInfo vref.Type m let _,curriedArgInfos,_,_ = GetTopValTypeInFSharpForm cenv.g topValInfo vref.Type m
List.chop curriedArgInfos.Length args List.chop curriedArgInfos.Length args
@ -3356,7 +3387,8 @@ and GenGetAddrOfRefCellField cenv cgbuf eenv (e,ty,m) sequel =
and GenGetValAddr cenv cgbuf eenv (v: ValRef, m) sequel = and GenGetValAddr cenv cgbuf eenv (v: ValRef, m) sequel =
let vspec = v.Deref let vspec = v.Deref
let ilTy = GenTypeOfVal cenv eenv vspec let ilTy = GenTypeOfVal cenv eenv vspec
match StorageForValRef m v eenv with let storage = StorageForValRef m v eenv
match storage with
| Local (idx,None) -> | Local (idx,None) ->
CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldloca (uint16 idx) ] CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldloca (uint16 idx) ]
| Arg idx -> | Arg idx ->
@ -3465,16 +3497,24 @@ and GenGenericParam cenv eenv (tp:Typar) =
/// Generates the data used for parameters at definitions of abstract method slots such as interface methods or override methods. /// Generates the data used for parameters at definitions of abstract method slots such as interface methods or override methods.
and GenSlotParam m cenv eenv (TSlotParam(nm,ty,inFlag,outFlag,optionalFlag,attribs)) : ILParameter = and GenSlotParam m cenv eenv (TSlotParam(nm,ty,inFlag,outFlag,optionalFlag,attribs)) : ILParameter =
let inFlag2,outFlag2,optionalFlag2,defaultParamValue,paramMarshal2,attribs = GenParamAttribs cenv attribs let ilTy = GenParamType cenv.amap m eenv.tyenv true ty
let inFlag2,outFlag2,optionalFlag2,defaultParamValue,paramMarshal2,attribs = GenParamAttribs cenv ty attribs
let ilAttribs = GenAttrs cenv eenv attribs
let ilAttribs =
match GenReadOnlyAttributeIfNecessary cenv.g ty with
| Some attr -> ilAttribs @ [attr]
| None -> ilAttribs
{ Name=nm { Name=nm
Type= GenParamType cenv.amap m eenv.tyenv ty Type= ilTy
Default=defaultParamValue Default=defaultParamValue
Marshal=paramMarshal2 Marshal=paramMarshal2
IsIn=inFlag || inFlag2 IsIn=inFlag || inFlag2
IsOut=outFlag || outFlag2 IsOut=outFlag || outFlag2
IsOptional=optionalFlag || optionalFlag2 IsOptional=optionalFlag || optionalFlag2
CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs (GenAttrs cenv eenv attribs)) CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs ilAttribs)
MetadataIndex = NoMetadataIdx } MetadataIndex = NoMetadataIdx }
and GenFormalSlotsig m cenv eenv (TSlotSig(_,typ,ctps,mtps,paraml,returnTy)) = and GenFormalSlotsig m cenv eenv (TSlotSig(_,typ,ctps,mtps,paraml,returnTy)) =
@ -3484,6 +3524,13 @@ and GenFormalSlotsig m cenv eenv (TSlotSig(_,typ,ctps,mtps,paraml,returnTy)) =
let ilParams = paraml |> List.map (GenSlotParam m cenv eenvForSlotSig) let ilParams = paraml |> List.map (GenSlotParam m cenv eenvForSlotSig)
let ilRetTy = GenReturnType cenv.amap m eenvForSlotSig.tyenv returnTy let ilRetTy = GenReturnType cenv.amap m eenvForSlotSig.tyenv returnTy
let ilRet = mkILReturn ilRetTy let ilRet = mkILReturn ilRetTy
let ilRet =
match returnTy with
| None -> ilRet
| Some ty ->
match GenReadOnlyAttributeIfNecessary cenv.g ty with
| Some attr -> ilRet.WithCustomAttrs (mkILCustomAttrs (ilRet.CustomAttrs.AsList @ [attr]))
| None -> ilRet
ilTy, ilParams, ilRet ilTy, ilParams, ilRet
and instSlotParam inst (TSlotParam(nm,ty,inFlag,fl2,fl3,attrs)) = TSlotParam(nm,instType inst ty,inFlag,fl2,fl3,attrs) and instSlotParam inst (TSlotParam(nm,ty,inFlag,fl2,fl3,attrs)) = TSlotParam(nm,instType inst ty,inFlag,fl2,fl3,attrs)
@ -4697,11 +4744,11 @@ and GenBindingAfterSequencePoint cenv cgbuf eenv sp (TBind(vspec,rhsExpr,_)) sta
CommitStartScope cgbuf startScopeMarkOpt CommitStartScope cgbuf startScopeMarkOpt
GenExpr cenv cgbuf eenv SPSuppress cctorBody discard GenExpr cenv cgbuf eenv SPSuppress cctorBody discard
| Method (topValInfo,_,mspec,_,paramInfos,retInfo) -> | Method (topValInfo,_,mspec,_,paramInfos,methodArgTys,retInfo) ->
let tps,ctorThisValOpt,baseValOpt,vsl,body',bodyty = IteratedAdjustArityOfLambda cenv.g cenv.amap topValInfo rhsExpr let tps,ctorThisValOpt,baseValOpt,vsl,body',bodyty = IteratedAdjustArityOfLambda cenv.g cenv.amap topValInfo rhsExpr
let methodVars = List.concat vsl let methodVars = List.concat vsl
CommitStartScope cgbuf startScopeMarkOpt CommitStartScope cgbuf startScopeMarkOpt
GenMethodForBinding cenv cgbuf eenv (vspec,mspec,access,paramInfos,retInfo) (topValInfo,ctorThisValOpt,baseValOpt,tps,methodVars, body', bodyty) GenMethodForBinding cenv cgbuf eenv (vspec,mspec,access,paramInfos,retInfo) (topValInfo,ctorThisValOpt,baseValOpt,tps,methodVars, methodArgTys, body', bodyty)
| StaticProperty (ilGetterMethSpec, optShadowLocal) -> | StaticProperty (ilGetterMethSpec, optShadowLocal) ->
@ -4948,9 +4995,9 @@ and GenMarshal cenv attribs =
// No MarshalAs detected // No MarshalAs detected
None, attribs None, attribs
and GenParamAttribs cenv attribs = and GenParamAttribs cenv paramTy attribs =
let inFlag = HasFSharpAttributeOpt cenv.g cenv.g.attrib_InAttribute attribs let inFlag = HasFSharpAttribute cenv.g cenv.g.attrib_InAttribute attribs || isInByrefTy cenv.g paramTy
let outFlag = HasFSharpAttribute cenv.g cenv.g.attrib_OutAttribute attribs let outFlag = HasFSharpAttribute cenv.g cenv.g.attrib_OutAttribute attribs || isOutByrefTy cenv.g paramTy
let optionalFlag = HasFSharpAttributeOpt cenv.g cenv.g.attrib_OptionalAttribute attribs let optionalFlag = HasFSharpAttributeOpt cenv.g cenv.g.attrib_OptionalAttribute attribs
let defaultValue = TryFindFSharpAttributeOpt cenv.g cenv.g.attrib_DefaultParameterValueAttribute attribs let defaultValue = TryFindFSharpAttributeOpt cenv.g cenv.g.attrib_DefaultParameterValueAttribute attribs
@ -4959,7 +5006,7 @@ and GenParamAttribs cenv attribs =
// as custom attributes in the code - they are implicit from the IL bits for these // as custom attributes in the code - they are implicit from the IL bits for these
let attribs = let attribs =
attribs attribs
|> List.filter (IsMatchingFSharpAttributeOpt cenv.g cenv.g.attrib_InAttribute >> not) |> List.filter (IsMatchingFSharpAttribute cenv.g cenv.g.attrib_InAttribute >> not)
|> List.filter (IsMatchingFSharpAttribute cenv.g cenv.g.attrib_OutAttribute >> not) |> List.filter (IsMatchingFSharpAttribute cenv.g cenv.g.attrib_OutAttribute >> not)
|> List.filter (IsMatchingFSharpAttributeOpt cenv.g cenv.g.attrib_OptionalAttribute >> not) |> List.filter (IsMatchingFSharpAttributeOpt cenv.g cenv.g.attrib_OptionalAttribute >> not)
|> List.filter (IsMatchingFSharpAttributeOpt cenv.g cenv.g.attrib_DefaultParameterValueAttribute >> not) |> List.filter (IsMatchingFSharpAttributeOpt cenv.g cenv.g.attrib_DefaultParameterValueAttribute >> not)
@ -4967,7 +5014,7 @@ and GenParamAttribs cenv attribs =
let Marshal,attribs = GenMarshal cenv attribs let Marshal,attribs = GenMarshal cenv attribs
inFlag,outFlag,optionalFlag,defaultValue,Marshal,attribs inFlag,outFlag,optionalFlag,defaultValue,Marshal,attribs
and GenParams cenv eenv (mspec:ILMethodSpec) (attribs:ArgReprInfo list) (implValsOpt: Val list option) = and GenParams cenv eenv (mspec:ILMethodSpec) (attribs:ArgReprInfo list) methodArgTys (implValsOpt: Val list option) =
let ilArgTys = mspec.FormalArgTypes let ilArgTys = mspec.FormalArgTypes
let argInfosAndTypes = let argInfosAndTypes =
if List.length attribs = List.length ilArgTys then List.zip ilArgTys attribs if List.length attribs = List.length ilArgTys then List.zip ilArgTys attribs
@ -4980,9 +5027,9 @@ and GenParams cenv eenv (mspec:ILMethodSpec) (attribs:ArgReprInfo list) (implVal
| _ -> | _ ->
List.map (fun x -> x,None) argInfosAndTypes List.map (fun x -> x,None) argInfosAndTypes
(Set.empty,argInfosAndTypes) (Set.empty,List.zip methodArgTys argInfosAndTypes)
||> List.mapFold (fun takenNames ((ilArgTy,topArgInfo),implValOpt) -> ||> List.mapFold (fun takenNames (methodArgTy, ((ilArgTy,topArgInfo),implValOpt)) ->
let inFlag,outFlag,optionalFlag,defaultParamValue,Marshal,attribs = GenParamAttribs cenv topArgInfo.Attribs let inFlag,outFlag,optionalFlag,defaultParamValue,Marshal,attribs = GenParamAttribs cenv methodArgTy topArgInfo.Attribs
let idOpt = (match topArgInfo.Name with let idOpt = (match topArgInfo.Name with
| Some v -> Some v | Some v -> Some v
@ -4998,6 +5045,14 @@ and GenParams cenv eenv (mspec:ILMethodSpec) (attribs:ArgReprInfo list) (implVal
| None -> | None ->
None, takenNames None, takenNames
let ilAttribs = GenAttrs cenv eenv attribs
let ilAttribs =
match GenReadOnlyAttributeIfNecessary cenv.g methodArgTy with
| Some attr -> ilAttribs @ [attr]
| None -> ilAttribs
let param : ILParameter = let param : ILParameter =
{ Name=nmOpt { Name=nmOpt
Type= ilArgTy Type= ilArgTy
@ -5006,17 +5061,17 @@ and GenParams cenv eenv (mspec:ILMethodSpec) (attribs:ArgReprInfo list) (implVal
IsIn=inFlag IsIn=inFlag
IsOut=outFlag IsOut=outFlag
IsOptional=optionalFlag IsOptional=optionalFlag
CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs (GenAttrs cenv eenv attribs)) CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs ilAttribs)
MetadataIndex = NoMetadataIdx } MetadataIndex = NoMetadataIdx }
param, takenNames) param, takenNames)
|> fst |> fst
and GenReturnInfo cenv eenv ilRetTy (retInfo : ArgReprInfo) : ILReturn = and GenReturnInfo cenv eenv ilRetTy (retInfo : ArgReprInfo) : ILReturn =
let marshal,attrs = GenMarshal cenv retInfo.Attribs let marshal,attribs = GenMarshal cenv retInfo.Attribs
{ Type=ilRetTy { Type=ilRetTy
Marshal=marshal Marshal=marshal
CustomAttrsStored= storeILCustomAttrs (mkILCustomAttrs (GenAttrs cenv eenv attrs)) CustomAttrsStored= storeILCustomAttrs (mkILCustomAttrs (GenAttrs cenv eenv attribs))
MetadataIndex = NoMetadataIdx } MetadataIndex = NoMetadataIdx }
and GenPropertyForMethodDef compileAsInstance tref mdef (v:Val) (memberInfo:ValMemberInfo) ilArgTys ilPropTy ilAttrs compiledName = and GenPropertyForMethodDef compileAsInstance tref mdef (v:Val) (memberInfo:ValMemberInfo) ilArgTys ilPropTy ilAttrs compiledName =
@ -5108,7 +5163,7 @@ and ComputeMethodImplAttribs cenv (_v:Val) attrs =
and GenMethodForBinding and GenMethodForBinding
cenv cgbuf eenv cenv cgbuf eenv
(v:Val,mspec,access,paramInfos,retInfo) (v:Val,mspec,access,paramInfos,retInfo)
(topValInfo,ctorThisValOpt,baseValOpt,tps,methodVars, body, returnTy) = (topValInfo,ctorThisValOpt,baseValOpt,tps,methodVars, methodArgTys, body, returnTy) =
let m = v.Range let m = v.Range
let selfMethodVars,nonSelfMethodVars,compileAsInstance = let selfMethodVars,nonSelfMethodVars,compileAsInstance =
@ -5122,6 +5177,7 @@ and GenMethodForBinding
let nonUnitNonSelfMethodVars,body = BindUnitVars cenv.g (nonSelfMethodVars,paramInfos,body) let nonUnitNonSelfMethodVars,body = BindUnitVars cenv.g (nonSelfMethodVars,paramInfos,body)
let nonUnitMethodVars = selfMethodVars@nonUnitNonSelfMethodVars let nonUnitMethodVars = selfMethodVars@nonUnitNonSelfMethodVars
let cmtps,curriedArgInfos,_,_ = GetTopValTypeInCompiledForm cenv.g topValInfo v.Type v.Range let cmtps,curriedArgInfos,_,_ = GetTopValTypeInCompiledForm cenv.g topValInfo v.Type v.Range
let eenv = bindBaseOrThisVarOpt cenv eenv ctorThisValOpt let eenv = bindBaseOrThisVarOpt cenv eenv ctorThisValOpt
let eenv = bindBaseOrThisVarOpt cenv eenv baseValOpt let eenv = bindBaseOrThisVarOpt cenv eenv baseValOpt
@ -5204,7 +5260,7 @@ and GenMethodForBinding
yield! GenCompilationArgumentCountsAttr cenv v ] yield! GenCompilationArgumentCountsAttr cenv v ]
let ilTypars = GenGenericParams cenv eenvUnderMethLambdaTypars tps let ilTypars = GenGenericParams cenv eenvUnderMethLambdaTypars tps
let ilParams = GenParams cenv eenv mspec paramInfos (Some(nonUnitNonSelfMethodVars)) let ilParams = GenParams cenv eenv mspec paramInfos methodArgTys (Some(nonUnitNonSelfMethodVars))
let ilReturn = GenReturnInfo cenv eenv mspec.FormalReturnType retInfo let ilReturn = GenReturnInfo cenv eenv mspec.FormalReturnType retInfo
let methName = mspec.Name let methName = mspec.Name
let tref = mspec.MethodRef.DeclaringTypeRef let tref = mspec.MethodRef.DeclaringTypeRef
@ -5432,7 +5488,7 @@ and GenSetStorage m cgbuf storage =
CG.EmitInstr cgbuf (pop 1) Push0 (I_call(Normalcall,mkILMethSpecForMethRefInTy(ilSetterMethRef,ilContainerTy,[]),None)) CG.EmitInstr cgbuf (pop 1) Push0 (I_call(Normalcall,mkILMethSpecForMethRefInTy(ilSetterMethRef,ilContainerTy,[]),None))
| StaticProperty (ilGetterMethSpec,_) -> | StaticProperty (ilGetterMethSpec,_) ->
error(Error(FSComp.SR.ilStaticMethodIsNotLambda(ilGetterMethSpec.Name),m)) error(Error(FSComp.SR.ilStaticMethodIsNotLambda(ilGetterMethSpec.Name),m))
| Method (_,_,mspec,m,_,_) -> | Method (_,_,mspec,m,_,_,_) ->
error(Error(FSComp.SR.ilStaticMethodIsNotLambda(mspec.Name),m)) error(Error(FSComp.SR.ilStaticMethodIsNotLambda(mspec.Name),m))
| Null -> CG.EmitInstr cgbuf (pop 1) Push0 AI_pop | Null -> CG.EmitInstr cgbuf (pop 1) Push0 AI_pop
| Arg _ -> error(Error(FSComp.SR.ilMutableVariablesCannotEscapeMethod(),m)) | Arg _ -> error(Error(FSComp.SR.ilMutableVariablesCannotEscapeMethod(),m))
@ -5471,7 +5527,7 @@ and GenGetStorageAndSequel cenv cgbuf eenv m (typ,ilTy) storage storeSequel =
CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call (Normalcall, ilGetterMethSpec, None)) CG.EmitInstr cgbuf (pop 0) (Push [ilTy]) (I_call (Normalcall, ilGetterMethSpec, None))
CommitGetStorageSequel cenv cgbuf eenv m typ None storeSequel CommitGetStorageSequel cenv cgbuf eenv m typ None storeSequel
| Method (topValInfo,vref,mspec,_,_,_) -> | Method (topValInfo,vref,mspec,_,_,_,_) ->
// Get a toplevel value as a first-class value. // Get a toplevel value as a first-class value.
// We generate a lambda expression and that simply calls // We generate a lambda expression and that simply calls
// the toplevel method. However we optimize the case where we are // the toplevel method. However we optimize the case where we are
@ -5724,7 +5780,7 @@ and GenAttr amap g eenv (Attrib(_,k,args,props,_,_,_)) =
| ILAttrib(mref) -> mkILMethSpec(mref,AsObject,[],[]) | ILAttrib(mref) -> mkILMethSpec(mref,AsObject,[],[])
| FSAttrib(vref) -> | FSAttrib(vref) ->
assert(vref.IsMember) assert(vref.IsMember)
let mspec,_,_,_,_ = GetMethodSpecForMemberVal amap g (Option.get vref.MemberInfo) vref let mspec,_,_,_,_,_ = GetMethodSpecForMemberVal amap g (Option.get vref.MemberInfo) vref
mspec mspec
let ilArgs = List.map2 (fun (AttribExpr(_,vexpr)) ty -> GenAttribArg amap g eenv vexpr ty) args mspec.FormalArgTypes let ilArgs = List.map2 (fun (AttribExpr(_,vexpr)) ty -> GenAttribArg amap g eenv vexpr ty) args mspec.FormalArgTypes
mkILCustomAttribMethRef g.ilg (mspec,ilArgs, props) mkILCustomAttribMethRef g.ilg (mspec,ilArgs, props)
@ -6053,11 +6109,11 @@ and GenAbstractBinding cenv eenv tref (vref:ValRef) =
[ yield! GenAttrs cenv eenv attribs [ yield! GenAttrs cenv eenv attribs
yield! GenCompilationArgumentCountsAttr cenv vref.Deref ] yield! GenCompilationArgumentCountsAttr cenv vref.Deref ]
let mspec,ctps,mtps,argInfos,retInfo = GetMethodSpecForMemberVal cenv.amap cenv.g memberInfo vref let mspec,ctps,mtps,argInfos,retInfo,methodArgTys = GetMethodSpecForMemberVal cenv.amap cenv.g memberInfo vref
let eenvForMeth = EnvForTypars (ctps@mtps) eenv let eenvForMeth = EnvForTypars (ctps@mtps) eenv
let ilMethTypars = GenGenericParams cenv eenvForMeth mtps let ilMethTypars = GenGenericParams cenv eenvForMeth mtps
let ilReturn = GenReturnInfo cenv eenvForMeth mspec.FormalReturnType retInfo let ilReturn = GenReturnInfo cenv eenvForMeth mspec.FormalReturnType retInfo
let ilParams = GenParams cenv eenvForMeth mspec argInfos None let ilParams = GenParams cenv eenvForMeth mspec argInfos methodArgTys None
let compileAsInstance = ValRefIsCompiledAsInstanceMember cenv.g vref let compileAsInstance = ValRefIsCompiledAsInstanceMember cenv.g vref
let mdef = mkILGenericVirtualMethod (vref.CompiledName,ILMemberAccess.Public,ilMethTypars,ilParams,ilReturn,MethodBody.Abstract) let mdef = mkILGenericVirtualMethod (vref.CompiledName,ILMemberAccess.Public,ilMethTypars,ilParams,ilReturn,MethodBody.Abstract)
@ -6099,7 +6155,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
[ [
match (eenv.valsInScope.TryFind cenv.g.sprintf_vref.Deref, match (eenv.valsInScope.TryFind cenv.g.sprintf_vref.Deref,
eenv.valsInScope.TryFind cenv.g.new_format_vref.Deref) with eenv.valsInScope.TryFind cenv.g.new_format_vref.Deref) with
| Some(Lazy(Method(_,_,sprintfMethSpec,_,_,_))), Some(Lazy(Method(_,_,newFormatMethSpec,_,_,_))) -> | Some(Lazy(Method(_,_,sprintfMethSpec,_,_,_,_))), Some(Lazy(Method(_,_,newFormatMethSpec,_,_,_,_))) ->
// The type returned by the 'sprintf' call // The type returned by the 'sprintf' call
let funcTy = EraseClosures.mkILFuncTy cenv.g.ilxPubCloEnv ilThisTy cenv.g.ilg.typ_String let funcTy = EraseClosures.mkILFuncTy cenv.g.ilxPubCloEnv ilThisTy cenv.g.ilg.typ_String
// Give the instantiation of the printf format object, i.e. a Format`5 object compatible with StringFormat<ilThisTy> // Give the instantiation of the printf format object, i.e. a Format`5 object compatible with StringFormat<ilThisTy>
@ -6428,7 +6484,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
let (|Lazy|) (x:Lazy<_>) = x.Force() let (|Lazy|) (x:Lazy<_>) = x.Force()
match (eenv.valsInScope.TryFind cenv.g.sprintf_vref.Deref, match (eenv.valsInScope.TryFind cenv.g.sprintf_vref.Deref,
eenv.valsInScope.TryFind cenv.g.new_format_vref.Deref) with eenv.valsInScope.TryFind cenv.g.new_format_vref.Deref) with
| Some(Lazy(Method(_,_,sprintfMethSpec,_,_,_))), Some(Lazy(Method(_,_,newFormatMethSpec,_,_,_))) -> | Some(Lazy(Method(_,_,sprintfMethSpec,_,_,_,_))), Some(Lazy(Method(_,_,newFormatMethSpec,_,_,_,_))) ->
// The type returned by the 'sprintf' call // The type returned by the 'sprintf' call
let funcTy = EraseClosures.mkILFuncTy cenv.g.ilxPubCloEnv ilThisTy cenv.g.ilg.typ_String let funcTy = EraseClosures.mkILFuncTy cenv.g.ilxPubCloEnv ilThisTy cenv.g.ilg.typ_String
// Give the instantiation of the printf format object, i.e. a Format`5 object compatible with StringFormat<ilThisTy> // Give the instantiation of the printf format object, i.e. a Format`5 object compatible with StringFormat<ilThisTy>
@ -6968,7 +7024,7 @@ let defaultOf =
let LookupGeneratedValue (amap:ImportMap) (ctxt: ExecutionContext) eenv (v:Val) = let LookupGeneratedValue (amap:ImportMap) (ctxt: ExecutionContext) eenv (v:Val) =
try try
// Convert the v.Type into a System.Type according to ilxgen and ilreflect. // Convert the v.Type into a System.Type according to ilxgen and ilreflect.
let objTyp = let objTyp() =
let ilTy = GenType amap v.Range TypeReprEnv.Empty v.Type (* TypeReprEnv.Empty ok, not expecting typars *) let ilTy = GenType amap v.Range TypeReprEnv.Empty v.Type (* TypeReprEnv.Empty ok, not expecting typars *)
ctxt.LookupType ilTy ctxt.LookupType ilTy
// Lookup the compiled v value (as an object). // Lookup the compiled v value (as an object).
@ -6986,7 +7042,7 @@ let LookupGeneratedValue (amap:ImportMap) (ctxt: ExecutionContext) eenv (v:Val)
// Rather, we look for the getter MethodInfo from the built type and .Invoke on that. // Rather, we look for the getter MethodInfo from the built type and .Invoke on that.
let methInfo = staticTyp.GetMethod(ilGetterMethRef.Name, BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) let methInfo = staticTyp.GetMethod(ilGetterMethRef.Name, BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic)
methInfo.Invoke((null:obj),(null:obj[])) methInfo.Invoke((null:obj),(null:obj[]))
Some (obj,objTyp) Some (obj,objTyp())
| StaticProperty (ilGetterMethSpec, _) -> | StaticProperty (ilGetterMethSpec, _) ->
let obj = let obj =
@ -6996,10 +7052,10 @@ let LookupGeneratedValue (amap:ImportMap) (ctxt: ExecutionContext) eenv (v:Val)
// Rather, we look for the getter MethodInfo from the built type and .Invoke on that. // Rather, we look for the getter MethodInfo from the built type and .Invoke on that.
let methInfo = staticTyp.GetMethod(ilGetterMethSpec.Name, BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic) let methInfo = staticTyp.GetMethod(ilGetterMethSpec.Name, BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic)
methInfo.Invoke((null:obj),(null:obj[])) methInfo.Invoke((null:obj),(null:obj[]))
Some (obj,objTyp) Some (obj,objTyp())
| Null -> | Null ->
Some (null,objTyp) Some (null,objTyp())
| Local _ -> None | Local _ -> None
| Method _ -> None | Method _ -> None
| Arg _ -> None | Arg _ -> None

Просмотреть файл

@ -149,7 +149,7 @@ let IsRefusedTLR g (f:Val) =
// things marked ValInline.Never are special // things marked ValInline.Never are special
let dllImportStubOrOtherNeverInline = (f.InlineInfo = ValInline.Never) let dllImportStubOrOtherNeverInline = (f.InlineInfo = ValInline.Never)
// Cannot have static fields of byref type // Cannot have static fields of byref type
let byrefVal = isByrefLikeTy g f.Type let byrefVal = isByrefLikeTy g f.Range f.Type
// Special values are instance methods etc. on .NET types. For now leave these alone // Special values are instance methods etc. on .NET types. For now leave these alone
let specialVal = f.MemberInfo.IsSome let specialVal = f.MemberInfo.IsSome
let alreadyChosen = f.ValReprInfo.IsSome let alreadyChosen = f.ValReprInfo.IsSome
@ -162,10 +162,9 @@ let IsMandatoryTopLevel (f:Val) =
specialVal || isModulBinding specialVal || isModulBinding
let IsMandatoryNonTopLevel g (f:Val) = let IsMandatoryNonTopLevel g (f:Val) =
let byrefVal = isByrefLikeTy g f.Type let byrefVal = isByrefLikeTy g f.Range f.Type
byrefVal byrefVal
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// pass1: decide which f are to be TLR? and if so, arity(f) // pass1: decide which f are to be TLR? and if so, arity(f)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -727,7 +726,7 @@ let FlatEnvPacks g fclassM topValS declist (reqdItemsMap: Zmap<BindingGroupShari
// temp // temp
let vals = vals |> List.filter (fun v -> not (isByrefLikeTy g v.Type)) let vals = vals |> List.filter (fun v -> not (isByrefLikeTy g v.Range v.Type))
// Remove values which have been labelled TLR, no need to close over these // Remove values which have been labelled TLR, no need to close over these
let vals = vals |> List.filter (Zset.memberOf topValS >> not) let vals = vals |> List.filter (Zset.memberOf topValS >> not)

Просмотреть файл

@ -56,16 +56,18 @@ type CalledArg =
IsParamArray : bool IsParamArray : bool
OptArgInfo : OptionalArgInfo OptArgInfo : OptionalArgInfo
CallerInfoInfo : CallerInfoInfo CallerInfoInfo : CallerInfoInfo
IsInArg: bool
IsOutArg: bool IsOutArg: bool
ReflArgInfo: ReflectedArgInfo ReflArgInfo: ReflectedArgInfo
NameOpt: Ident option NameOpt: Ident option
CalledArgumentType : TType } CalledArgumentType : TType }
let CalledArg(pos, isParamArray, optArgInfo, callerInfoInfo, isOutArg, nameOpt, reflArgInfo, calledArgTy) = let CalledArg (pos, isParamArray, optArgInfo, callerInfoInfo, isInArg, isOutArg, nameOpt, reflArgInfo, calledArgTy) =
{ Position=pos { Position=pos
IsParamArray=isParamArray IsParamArray=isParamArray
OptArgInfo =optArgInfo OptArgInfo =optArgInfo
CallerInfoInfo = callerInfoInfo CallerInfoInfo = callerInfoInfo
IsInArg=isInArg
IsOutArg=isOutArg IsOutArg=isOutArg
ReflArgInfo=reflArgInfo ReflArgInfo=reflArgInfo
NameOpt=nameOpt NameOpt=nameOpt
@ -126,48 +128,59 @@ let AdjustCalledArgType (infoReader:InfoReader) isConstraint (calledArg: CalledA
let calledArgTy = calledArg.CalledArgumentType let calledArgTy = calledArg.CalledArgumentType
let callerArgTy = callerArg.Type let callerArgTy = callerArg.Type
let m = callerArg.Range let m = callerArg.Range
if isConstraint then calledArgTy else if isConstraint then
// If the called method argument is a byref type, then the caller may provide a byref or ref calledArgTy
if isByrefTy g calledArgTy then else
if isByrefTy g callerArgTy then
calledArgTy // If the called method argument is an inref type, then the caller may provide a byref or value
if isInByrefTy g calledArgTy then
if isByrefTy g callerArgTy then
calledArgTy
else
destByrefTy g calledArgTy
// If the called method argument is a (non inref) byref type, then the caller may provide a byref or ref.
elif isByrefTy g calledArgTy then
if isByrefTy g callerArgTy then
calledArgTy
else
mkRefCellTy g (destByrefTy g calledArgTy)
else else
mkRefCellTy g (destByrefTy g calledArgTy) // If the called method argument is a delegate type, then the caller may provide a function
else let calledArgTy =
// If the called method argument is a delegate type, then the caller may provide a function let adjustDelegateTy calledTy =
let calledArgTy = let (SigOfFunctionForDelegate(_, delArgTys, _, fty)) = GetSigOfFunctionForDelegate infoReader calledTy m AccessibleFromSomewhere
let adjustDelegateTy calledTy = let delArgTys = if isNil delArgTys then [g.unit_ty] else delArgTys
let (SigOfFunctionForDelegate(_, delArgTys, _, fty)) = GetSigOfFunctionForDelegate infoReader calledTy m AccessibleFromSomewhere if (fst (stripFunTy g callerArgTy)).Length = delArgTys.Length
let delArgTys = if isNil delArgTys then [g.unit_ty] else delArgTys then fty
if (fst (stripFunTy g callerArgTy)).Length = delArgTys.Length else calledArgTy
then fty
else calledArgTy
if isDelegateTy g calledArgTy && isFunTy g callerArgTy then if isDelegateTy g calledArgTy && isFunTy g callerArgTy then
adjustDelegateTy calledArgTy
elif isLinqExpressionTy g calledArgTy && isFunTy g callerArgTy then
let origArgTy = calledArgTy
let calledArgTy = destLinqExpressionTy g calledArgTy
if isDelegateTy g calledArgTy then
adjustDelegateTy calledArgTy adjustDelegateTy calledArgTy
else
// BUG 435170: called arg is Expr<'t> where 't is not delegate - such conversion is not legal -> return original type
origArgTy
elif calledArg.ReflArgInfo.AutoQuote && isQuotedExprTy g calledArgTy && not (isQuotedExprTy g callerArgTy) then elif isLinqExpressionTy g calledArgTy && isFunTy g callerArgTy then
destQuotedExprTy g calledArgTy let origArgTy = calledArgTy
let calledArgTy = destLinqExpressionTy g calledArgTy
if isDelegateTy g calledArgTy then
adjustDelegateTy calledArgTy
else
// BUG 435170: called arg is Expr<'t> where 't is not delegate - such conversion is not legal -> return original type
origArgTy
else calledArgTy elif calledArg.ReflArgInfo.AutoQuote && isQuotedExprTy g calledArgTy && not (isQuotedExprTy g callerArgTy) then
destQuotedExprTy g calledArgTy
// Adjust the called argument type to take into account whether the caller's argument is M(?arg=Some(3)) or M(arg=1) else calledArgTy
// If the called method argument is optional with type Option<T>, then the caller may provide a T, unless their argument is propagating-optional (i.e. isOptCallerArg)
let calledArgTy = // Adjust the called argument type to take into account whether the caller's argument is M(?arg=Some(3)) or M(arg=1)
match calledArg.OptArgInfo with // If the called method argument is optional with type Option<T>, then the caller may provide a T, unless their argument is propagating-optional (i.e. isOptCallerArg)
| NotOptional -> calledArgTy let calledArgTy =
| CalleeSide when not callerArg.IsOptional && isOptionTy g calledArgTy -> destOptionTy g calledArgTy match calledArg.OptArgInfo with
| CalleeSide | CallerSide _ -> calledArgTy | NotOptional -> calledArgTy
calledArgTy | CalleeSide when not callerArg.IsOptional && isOptionTy g calledArgTy -> destOptionTy g calledArgTy
| CalleeSide | CallerSide _ -> calledArgTy
calledArgTy
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -193,11 +206,12 @@ type CalledMethArgSet<'T> =
let MakeCalledArgs amap m (minfo:MethInfo) minst = let MakeCalledArgs amap m (minfo:MethInfo) minst =
// Mark up the arguments with their position, so we can sort them back into order later // Mark up the arguments with their position, so we can sort them back into order later
let paramDatas = minfo.GetParamDatas(amap, m, minst) let paramDatas = minfo.GetParamDatas(amap, m, minst)
paramDatas |> List.mapiSquared (fun i j (ParamData(isParamArrayArg, isOutArg, optArgInfo, callerInfoFlags, nmOpt, reflArgInfo, typeOfCalledArg)) -> paramDatas |> List.mapiSquared (fun i j (ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoFlags, nmOpt, reflArgInfo, typeOfCalledArg)) ->
{ Position=(i, j) { Position=(i,j)
IsParamArray=isParamArrayArg IsParamArray=isParamArrayArg
OptArgInfo=optArgInfo OptArgInfo=optArgInfo
CallerInfoInfo = callerInfoFlags CallerInfoInfo = callerInfoFlags
IsInArg=isInArg
IsOutArg=isOutArg IsOutArg=isOutArg
ReflArgInfo=reflArgInfo ReflArgInfo=reflArgInfo
NameOpt=nmOpt NameOpt=nmOpt
@ -350,6 +364,7 @@ type CalledMeth<'T>
let unnamedCalledOutArgs = argSetInfos |> List.collect (fun (_, _, _, _, _, x) -> x) let unnamedCalledOutArgs = argSetInfos |> List.collect (fun (_, _, _, _, _, x) -> x)
member x.infoReader = infoReader member x.infoReader = infoReader
member x.amap = infoReader.amap member x.amap = infoReader.amap
/// the method we're attempting to call /// the method we're attempting to call
@ -372,12 +387,14 @@ type CalledMeth<'T>
/// The argument analysis for each set of curried arguments /// The argument analysis for each set of curried arguments
member x.ArgSets = argSets member x.ArgSets = argSets
/// return type /// return type after implicit deference of byref returns is taken into account
member x.ReturnType = methodRetTy member x.CalledReturnTypeAfterByrefDeref =
let retTy = methodRetTy
if isByrefTy g retTy then destByrefTy g retTy else retTy
/// return type after tupling of out args is taken into account /// return type after tupling of out args is taken into account
member x.ReturnTypeAfterOutArgTupling = member x.CalledReturnTypeAfterOutArgTupling =
let retTy = x.ReturnType let retTy = x.CalledReturnTypeAfterByrefDeref
if isNil unnamedCalledOutArgs then if isNil unnamedCalledOutArgs then
retTy retTy
else else
@ -405,19 +422,31 @@ type CalledMeth<'T>
static member GetMethod (x:CalledMeth<'T>) = x.Method static member GetMethod (x:CalledMeth<'T>) = x.Method
member x.NumArgSets = x.ArgSets.Length member x.NumArgSets = x.ArgSets.Length
member x.HasOptArgs = not (isNil x.UnnamedCalledOptArgs)
member x.HasOutArgs = not (isNil x.UnnamedCalledOutArgs)
member x.HasOptArgs = not (isNil x.UnnamedCalledOptArgs)
member x.HasOutArgs = not (isNil x.UnnamedCalledOutArgs)
member x.UsesParamArrayConversion = x.ArgSets |> List.exists (fun argSet -> argSet.ParamArrayCalledArgOpt.IsSome) member x.UsesParamArrayConversion = x.ArgSets |> List.exists (fun argSet -> argSet.ParamArrayCalledArgOpt.IsSome)
member x.ParamArrayCalledArgOpt = x.ArgSets |> List.tryPick (fun argSet -> argSet.ParamArrayCalledArgOpt) member x.ParamArrayCalledArgOpt = x.ArgSets |> List.tryPick (fun argSet -> argSet.ParamArrayCalledArgOpt)
member x.ParamArrayCallerArgs = x.ArgSets |> List.tryPick (fun argSet -> if Option.isSome argSet.ParamArrayCalledArgOpt then Some argSet.ParamArrayCallerArgs else None ) member x.ParamArrayCallerArgs = x.ArgSets |> List.tryPick (fun argSet -> if Option.isSome argSet.ParamArrayCalledArgOpt then Some argSet.ParamArrayCallerArgs else None )
member x.ParamArrayElementType = member x.ParamArrayElementType =
assert (x.UsesParamArrayConversion) assert (x.UsesParamArrayConversion)
x.ParamArrayCalledArgOpt.Value.CalledArgumentType |> destArrayTy x.amap.g x.ParamArrayCalledArgOpt.Value.CalledArgumentType |> destArrayTy x.amap.g
member x.NumAssignedProps = x.AssignedItemSetters.Length member x.NumAssignedProps = x.AssignedItemSetters.Length
member x.CalledObjArgTys(m) = x.Method.GetObjArgTypes(x.amap, m, x.CalledTyArgs)
member x.CalledObjArgTys(m) =
match x.Method.GetObjArgTypes(x.amap, m, x.CalledTyArgs) with
| [ thisArgTy ] when isByrefTy g thisArgTy -> [ destByrefTy g thisArgTy ]
| res -> res
member x.NumCalledTyArgs = x.CalledTyArgs.Length member x.NumCalledTyArgs = x.CalledTyArgs.Length
member x.NumCallerTyArgs = x.CallerTyArgs.Length member x.NumCallerTyArgs = x.CallerTyArgs.Length
member x.AssignsAllNamedArgs = isNil x.UnassignedNamedArgs member x.AssignsAllNamedArgs = isNil x.UnassignedNamedArgs
@ -451,8 +480,11 @@ type CalledMeth<'T>
x.ArgSets |> List.map (fun argSet -> argSet.AssignedNamedArgs) x.ArgSets |> List.map (fun argSet -> argSet.AssignedNamedArgs)
member x.AllUnnamedCalledArgs = x.ArgSets |> List.collect (fun x -> x.UnnamedCalledArgs) member x.AllUnnamedCalledArgs = x.ArgSets |> List.collect (fun x -> x.UnnamedCalledArgs)
member x.TotalNumUnnamedCalledArgs = x.ArgSets |> List.sumBy (fun x -> x.NumUnnamedCalledArgs) member x.TotalNumUnnamedCalledArgs = x.ArgSets |> List.sumBy (fun x -> x.NumUnnamedCalledArgs)
member x.TotalNumUnnamedCallerArgs = x.ArgSets |> List.sumBy (fun x -> x.NumUnnamedCallerArgs) member x.TotalNumUnnamedCallerArgs = x.ArgSets |> List.sumBy (fun x -> x.NumUnnamedCallerArgs)
member x.TotalNumAssignedNamedArgs = x.ArgSets |> List.sumBy (fun x -> x.NumAssignedNamedArgs) member x.TotalNumAssignedNamedArgs = x.ArgSets |> List.sumBy (fun x -> x.NumAssignedNamedArgs)
let NamesOfCalledArgs (calledArgs: CalledArg list) = let NamesOfCalledArgs (calledArgs: CalledArg list) =
@ -547,15 +579,13 @@ let TakeObjAddrForMethodCall g amap (minfo:MethInfo) isMutable m objArgs f =
match objArgs with match objArgs with
| [objArgExpr] -> | [objArgExpr] ->
let hasCallInfo = ccallInfo.IsSome let hasCallInfo = ccallInfo.IsSome
let mustTakeAddress = let mustTakeAddress = hasCallInfo || minfo.ObjArgNeedsAddress(amap, m)
(minfo.IsStruct && not minfo.IsExtensionMember) // don't take the address of a struct when passing to an extension member
|| hasCallInfo
let objArgTy = tyOfExpr g objArgExpr let objArgTy = tyOfExpr g objArgExpr
let wrap, objArgExpr' = mkExprAddrOfExpr g mustTakeAddress hasCallInfo isMutable objArgExpr None m let wrap, objArgExpr', _readonly = mkExprAddrOfExpr g mustTakeAddress hasCallInfo isMutable objArgExpr None m
// Extension members and calls to class constraints may need a coercion for their object argument // Extension members and calls to class constraints may need a coercion for their object argument
let objArgExpr' = let objArgExpr' =
if not hasCallInfo && // minfo.IsExtensionMember && minfo.IsStruct && if not hasCallInfo &&
not (TypeDefinitelySubsumesTypeNoCoercion 0 g amap m minfo.ApparentEnclosingType objArgTy) then not (TypeDefinitelySubsumesTypeNoCoercion 0 g amap m minfo.ApparentEnclosingType objArgTy) then
mkCoerceExpr(objArgExpr', minfo.ApparentEnclosingType, m, objArgTy) mkCoerceExpr(objArgExpr', minfo.ApparentEnclosingType, m, objArgTy)
else else
@ -1074,7 +1104,7 @@ module ProvidedMethodCalls =
match ea.PApplyOption((function ProvidedAddressOfExpr x -> Some x | _ -> None), m) with match ea.PApplyOption((function ProvidedAddressOfExpr x -> Some x | _ -> None), m) with
| Some e -> | Some e ->
let eT = exprToExpr e let eT = exprToExpr e
let wrap, ce = mkExprAddrOfExpr g true false DefinitelyMutates eT None m let wrap,ce, _readonly = mkExprAddrOfExpr g true false DefinitelyMutates eT None m
let ce = wrap ce let ce = wrap ce
None, (ce, tyOfExpr g ce) None, (ce, tyOfExpr g ce)
| None -> | None ->

Просмотреть файл

@ -467,7 +467,7 @@ let private GetCSharpStyleIndexedExtensionMembersForTyconRef (amap:Import.Import
// So we need to go and crack the type of the 'this' argument. // So we need to go and crack the type of the 'this' argument.
let thisTy = minfo.GetParamTypes(amap,m,generalizeTypars minfo.FormalMethodTypars).Head.Head let thisTy = minfo.GetParamTypes(amap,m,generalizeTypars minfo.FormalMethodTypars).Head.Head
match thisTy with match thisTy with
| AppTy amap.g (tcrefOfTypeExtended, _) -> Some tcrefOfTypeExtended | AppTy g (tcrefOfTypeExtended, _) when not (isByrefTy g thisTy) -> Some tcrefOfTypeExtended
| _ -> None | _ -> None
Some rs Some rs

Просмотреть файл

@ -906,15 +906,28 @@ module private PrintTypes =
| [arg] -> layoutTypeWithInfoAndPrec denv env 2 arg ^^ tcL | [arg] -> layoutTypeWithInfoAndPrec denv env 2 arg ^^ tcL
| args -> bracketIfL (prec <= 1) (bracketL (layoutTypesWithInfoAndPrec denv env 2 (sepL (tagPunctuation ",")) args) --- tcL) | args -> bracketIfL (prec <= 1) (bracketL (layoutTypesWithInfoAndPrec denv env 2 (sepL (tagPunctuation ",")) args) --- tcL)
/// Layout a type, taking precedence into account to insert brackets where needed *) /// Layout a type, taking precedence into account to insert brackets where needed
and layoutTypeWithInfoAndPrec denv env prec typ = and layoutTypeWithInfoAndPrec denv env prec typ =
match stripTyparEqns typ with match stripTyparEqns typ with
// Layout a type application // Always prefer to format 'byref<ty,ByRefKind.In>' as 'inref<ty>'
| typ when isInByrefTy denv.g typ && (match typ with TType_app (tc, _) when denv.g.inref_tcr.CanDeref && tyconRefEq denv.g tc denv.g.byref2_tcr -> true | _ -> false) ->
layoutTypeWithInfoAndPrec denv env prec (mkInByrefTy denv.g (destByrefTy denv.g typ))
// Always prefer to format 'byref<ty,ByRefKind.Out>' as 'outref<ty>'
| typ when isOutByrefTy denv.g typ && (match typ with TType_app (tc, _) when denv.g.outref_tcr.CanDeref && tyconRefEq denv.g tc denv.g.byref2_tcr -> true | _ -> false) ->
layoutTypeWithInfoAndPrec denv env prec (mkOutByrefTy denv.g (destByrefTy denv.g typ))
// Always prefer to format 'byref<ty,ByRefKind.InOut>' as 'byref<ty>'
| typ when isByrefTy denv.g typ && (match typ with TType_app (tc, _) when denv.g.byref_tcr.CanDeref && tyconRefEq denv.g tc denv.g.byref2_tcr -> true | _ -> false) ->
layoutTypeWithInfoAndPrec denv env prec (mkByrefTy denv.g (destByrefTy denv.g typ))
// Always prefer 'float' to 'float<1>'
| TType_app (tc,args) when tc.IsMeasureableReprTycon && List.forall (isDimensionless denv.g) args -> | TType_app (tc,args) when tc.IsMeasureableReprTycon && List.forall (isDimensionless denv.g) args ->
layoutTypeWithInfoAndPrec denv env prec (reduceTyconRefMeasureableOrProvided denv.g tc args) layoutTypeWithInfoAndPrec denv env prec (reduceTyconRefMeasureableOrProvided denv.g tc args)
// Layout a type application
| TType_app (tc,args) -> | TType_app (tc,args) ->
layoutTypeAppWithInfoAndPrec denv env (layoutTyconRef denv tc) prec tc.IsPrefixDisplay args layoutTypeAppWithInfoAndPrec denv env (layoutTyconRef denv tc) prec tc.IsPrefixDisplay args
@ -1228,7 +1241,7 @@ module InfoMemberPrinting =
/// Format the arguments of a method to a buffer. /// Format the arguments of a method to a buffer.
/// ///
/// This uses somewhat "old fashioned" printf-style buffer printing. /// This uses somewhat "old fashioned" printf-style buffer printing.
let layoutParamData denv (ParamData(isParamArray, _isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty)) = let layoutParamData denv (ParamData(isParamArray, _isInArg, _isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty)) =
let isOptArg = optArgInfo.IsOptional let isOptArg = optArgInfo.IsOptional
match isParamArray, nmOpt, isOptArg, tryDestOptionTy denv.g pty with match isParamArray, nmOpt, isOptArg, tryDestOptionTy denv.g pty with
// Layout an optional argument // Layout an optional argument

Просмотреть файл

@ -1248,7 +1248,7 @@ let rec ExprHasEffect g expr =
| Expr.Const _ -> false | Expr.Const _ -> false
/// type applications do not have effects, with the exception of type functions /// type applications do not have effects, with the exception of type functions
| Expr.App(f0, _, _, [], _) -> (IsTyFuncValRefExpr f0) || ExprHasEffect g f0 | Expr.App(f0, _, _, [], _) -> (IsTyFuncValRefExpr f0) || ExprHasEffect g f0
| Expr.Op(op, _, args, _) -> ExprsHaveEffect g args || OpHasEffect g op | Expr.Op(op, _, args, m) -> ExprsHaveEffect g args || OpHasEffect g m op
| Expr.LetRec(binds, body, _, _) -> BindingsHaveEffect g binds || ExprHasEffect g body | Expr.LetRec(binds, body, _, _) -> BindingsHaveEffect g binds || ExprHasEffect g body
| Expr.Let(bind, body, _, _) -> BindingHasEffect g bind || ExprHasEffect g body | Expr.Let(bind, body, _, _) -> BindingHasEffect g bind || ExprHasEffect g body
// REVIEW: could add Expr.Obj on an interface type - these are similar to records of lambda expressions // REVIEW: could add Expr.Obj on an interface type - these are similar to records of lambda expressions
@ -1256,35 +1256,35 @@ let rec ExprHasEffect g expr =
and ExprsHaveEffect g exprs = List.exists (ExprHasEffect g) exprs and ExprsHaveEffect g exprs = List.exists (ExprHasEffect g) exprs
and BindingsHaveEffect g binds = List.exists (BindingHasEffect g) binds and BindingsHaveEffect g binds = List.exists (BindingHasEffect g) binds
and BindingHasEffect g bind = bind.Expr |> ExprHasEffect g and BindingHasEffect g bind = bind.Expr |> ExprHasEffect g
and OpHasEffect g op = and OpHasEffect g m op =
match op with match op with
| TOp.Tuple _ -> false | TOp.Tuple _ -> false
| TOp.Recd (ctor, tcref) -> | TOp.Recd (ctor, tcref) ->
match ctor with match ctor with
| RecdExprIsObjInit -> true | RecdExprIsObjInit -> true
| RecdExpr -> isRecdOrUnionOrStructTyconRefDefinitelyMutable g tcref | RecdExpr -> not (isRecdOrStructTyconRefReadOnly g m tcref)
| TOp.UnionCase ucref -> isRecdOrUnionOrStructTyconRefDefinitelyMutable g ucref.TyconRef | TOp.UnionCase ucref -> isRecdOrUnionOrStructTyconRefDefinitelyMutable ucref.TyconRef
| TOp.ExnConstr ecref -> isExnDefinitelyMutable ecref | TOp.ExnConstr ecref -> isExnDefinitelyMutable ecref
| TOp.Bytes _ | TOp.UInt16s _ | TOp.Array -> true (* alloc observable *) | TOp.Bytes _ | TOp.UInt16s _ | TOp.Array -> true // mutable
| TOp.UnionCaseTagGet _ -> false | TOp.UnionCaseTagGet _ -> false
| TOp.UnionCaseProof _ -> false | TOp.UnionCaseProof _ -> false
| TOp.UnionCaseFieldGet (ucref, n) -> isUnionCaseFieldMutable g ucref n | TOp.UnionCaseFieldGet (ucref, n) -> isUnionCaseFieldMutable g ucref n
| TOp.ILAsm(instrs, _) -> IlAssemblyCodeHasEffect instrs | TOp.ILAsm(instrs, _) -> IlAssemblyCodeHasEffect instrs
| TOp.TupleFieldGet(_) -> false | TOp.TupleFieldGet(_) -> false
| TOp.ExnFieldGet(ecref, n) -> isExnFieldMutable ecref n | TOp.ExnFieldGet(ecref, n) -> isExnFieldMutable ecref n
| TOp.RefAddrGet -> false | TOp.RefAddrGet _ -> false
| TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some(true)) | TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some true)
| TOp.ValFieldGetAddr rfref -> rfref.RecdField.IsMutable (* data is immutable, so taking address is ok *) | TOp.ValFieldGetAddr (rfref, _readonly) -> rfref.RecdField.IsMutable
| TOp.UnionCaseFieldGetAddr _ -> false (* data is immutable, so taking address is ok *) | TOp.UnionCaseFieldGetAddr _ -> false // union case fields are immutable
| TOp.LValueOp (LGetAddr, lv) -> lv.IsMutable | TOp.LValueOp (LAddrOf _, lv) -> lv.IsMutable
| TOp.UnionCaseFieldSet _ | TOp.UnionCaseFieldSet _
| TOp.ExnFieldSet _ | TOp.ExnFieldSet _
| TOp.Coerce | TOp.Coerce
| TOp.Reraise | TOp.Reraise
| TOp.For _ | TOp.For _
| TOp.While _ | TOp.While _
| TOp.TryCatch _ | TOp.TryCatch _ (* conservative *)
| TOp.TryFinally _ (* note: these really go through a different path anyway *) | TOp.TryFinally _ (* conservative *)
| TOp.TraitCall _ | TOp.TraitCall _
| TOp.Goto _ | TOp.Goto _
| TOp.Label _ | TOp.Label _
@ -1791,17 +1791,17 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) =
MightMakeCriticalTailcall=false MightMakeCriticalTailcall=false
Info=UnknownValue } Info=UnknownValue }
(* Handle addresses *) (* Handle addresses *)
| TOp.LValueOp (LGetAddr, lv), _, _ -> | TOp.LValueOp ((LAddrOf _ as lop), lv), _, _ ->
let e, _ = OptimizeExpr cenv env (exprForValRef m lv) let e, _ = OptimizeExpr cenv env (exprForValRef m lv)
let op' = let op' =
match e with match e with
// Do not optimize if it's a top level static binding. // Do not optimize if it's a top level static binding.
| Expr.Val (v, _, _) when not v.IsCompiledAsTopLevel -> TOp.LValueOp (LGetAddr, v) | Expr.Val (v, _, _) when not v.IsCompiledAsTopLevel -> TOp.LValueOp (lop, v)
| _ -> op | _ -> op
Expr.Op (op', tyargs, args, m), Expr.Op (op', tyargs, args, m),
{ TotalSize = 1 { TotalSize = 1
FunctionSize = 1 FunctionSize = 1
HasEffect = OpHasEffect cenv.g op' HasEffect = OpHasEffect cenv.g m op'
MightMakeCriticalTailcall = false MightMakeCriticalTailcall = false
Info = UnknownValue } Info = UnknownValue }
(* Handle these as special cases since mutables are allowed inside their bodies *) (* Handle these as special cases since mutables are allowed inside their bodies *)
@ -1850,7 +1850,7 @@ and OptimizeExprOpFallback cenv env (op, tyargs, args', m) arginfos valu =
let argsFSize = AddFunctionSizes arginfos let argsFSize = AddFunctionSizes arginfos
let argEffects = OrEffects arginfos let argEffects = OrEffects arginfos
let argValues = List.map (fun x -> x.Info) arginfos let argValues = List.map (fun x -> x.Info) arginfos
let effect = OpHasEffect cenv.g op let effect = OpHasEffect cenv.g m op
let cost, valu = let cost, valu =
match op with match op with
| TOp.UnionCase c -> 2, MakeValueInfoForUnionCase c (Array.ofList argValues) | TOp.UnionCase c -> 2, MakeValueInfoForUnionCase c (Array.ofList argValues)
@ -1882,7 +1882,7 @@ and OptimizeExprOpFallback cenv env (op, tyargs, args', m) arginfos valu =
| TOp.ValFieldGetAddr _ | TOp.ValFieldGetAddr _
| TOp.Array | TOp.For _ | TOp.While _ | TOp.TryCatch _ | TOp.TryFinally _ | TOp.Array | TOp.For _ | TOp.While _ | TOp.TryCatch _ | TOp.TryFinally _
| TOp.ILCall _ | TOp.TraitCall _ | TOp.LValueOp _ | TOp.ValFieldSet _ | TOp.ILCall _ | TOp.TraitCall _ | TOp.LValueOp _ | TOp.ValFieldSet _
| TOp.UnionCaseFieldSet _ | TOp.RefAddrGet | TOp.Coerce | TOp.Reraise | TOp.UnionCaseFieldSet _ | TOp.RefAddrGet _ | TOp.Coerce | TOp.Reraise
| TOp.UnionCaseFieldGetAddr _ | TOp.UnionCaseFieldGetAddr _
| TOp.ExnFieldSet _ -> 1, valu | TOp.ExnFieldSet _ -> 1, valu
| TOp.Recd (ctorInfo, tcref) -> | TOp.Recd (ctorInfo, tcref) ->
@ -2277,7 +2277,7 @@ and TakeAddressOfStructArgumentIfNeeded cenv (vref:ValRef) ty args m =
// known calls to known generated F# code for CompareTo, Equals and GetHashCode. // known calls to known generated F# code for CompareTo, Equals and GetHashCode.
// If we ever reuse DevirtualizeApplication to transform an arbitrary virtual call into a // If we ever reuse DevirtualizeApplication to transform an arbitrary virtual call into a
// direct call then this assumption is not valid. // direct call then this assumption is not valid.
let wrap, objArgAddress = mkExprAddrOfExpr cenv.g true false NeverMutates objArg None m let wrap, objArgAddress, _readonly = mkExprAddrOfExpr cenv.g true false NeverMutates objArg None m
wrap, (objArgAddress::rest) wrap, (objArgAddress::rest)
| _ -> | _ ->
// no wrapper, args stay the same // no wrapper, args stay the same
@ -2760,7 +2760,7 @@ and OptimizeExprThenConsiderSplit cenv env e =
// Decide whether to List.unzip a sub-expression into a new method // Decide whether to List.unzip a sub-expression into a new method
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
and ComputeSplitToMethodCondition flag threshold cenv env (e, einfo) = and ComputeSplitToMethodCondition flag threshold cenv env (e:Expr, einfo) =
flag && flag &&
// REVIEW: The method splitting optimization is completely disabled if we are not taking tailcalls. // REVIEW: The method splitting optimization is completely disabled if we are not taking tailcalls.
// REVIEW: This should only apply to methods that actually make self-tailcalls (tested further below). // REVIEW: This should only apply to methods that actually make self-tailcalls (tested further below).
@ -2771,6 +2771,7 @@ and ComputeSplitToMethodCondition flag threshold cenv env (e, einfo) =
// We can only split an expression out as a method if certain conditions are met. // We can only split an expression out as a method if certain conditions are met.
// It can't use any protected or base calls, rethrow(), byrefs etc. // It can't use any protected or base calls, rethrow(), byrefs etc.
let m = e.Range
(let fvs = freeInExpr CollectLocals e (let fvs = freeInExpr CollectLocals e
not fvs.UsesUnboundRethrow && not fvs.UsesUnboundRethrow &&
not fvs.UsesMethodLocalConstructs && not fvs.UsesMethodLocalConstructs &&
@ -2781,12 +2782,12 @@ and ComputeSplitToMethodCondition flag threshold cenv env (e, einfo) =
// All the free variables (apart from things with an arity, i.e. compiled as methods) should be normal, i.e. not base/this etc. // All the free variables (apart from things with an arity, i.e. compiled as methods) should be normal, i.e. not base/this etc.
(v.BaseOrThisInfo = NormalVal && (v.BaseOrThisInfo = NormalVal &&
// None of them should be byrefs // None of them should be byrefs
not (isByrefLikeTy cenv.g v.Type) && not (isByrefLikeTy cenv.g m v.Type) &&
// None of them should be local polymorphic constrained values // None of them should be local polymorphic constrained values
not (IsGenericValWithGenericContraints cenv.g v) && not (IsGenericValWithGenericContraints cenv.g v) &&
// None of them should be mutable // None of them should be mutable
not v.IsMutable)))) && not v.IsMutable)))) &&
not (isByrefLikeTy cenv.g (tyOfExpr cenv.g e)) not (isByrefLikeTy cenv.g m (tyOfExpr cenv.g e))
and ConsiderSplitToMethod flag threshold cenv env (e, einfo) = and ConsiderSplitToMethod flag threshold cenv env (e, einfo) =
if ComputeSplitToMethodCondition flag threshold cenv env (e, einfo) then if ComputeSplitToMethodCondition flag threshold cenv env (e, einfo) then

Просмотреть файл

@ -904,7 +904,7 @@ let CompilePatternBasic
when isNil topgtvs && ucref.Tycon.IsStructRecordOrUnionTycon -> when isNil topgtvs && ucref.Tycon.IsStructRecordOrUnionTycon ->
let argexp = GetSubExprOfInput subexpr let argexp = GetSubExprOfInput subexpr
let vOpt,addrexp = mkExprAddrOfExprAux g true false NeverMutates argexp None matchm let vOpt, addrexp, _readonly = mkExprAddrOfExprAux g true false NeverMutates argexp None matchm
match vOpt with match vOpt with
| None -> Some addrexp, None | None -> Some addrexp, None
| Some (v,e) -> | Some (v,e) ->

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -426,7 +426,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.
| TOp.UnionCaseFieldGet (ucref,n),tyargs,[e] -> | TOp.UnionCaseFieldGet (ucref,n),tyargs,[e] ->
ConvUnionFieldGet cenv env m ucref n tyargs e ConvUnionFieldGet cenv env m ucref n tyargs e
| TOp.ValFieldGetAddr(_rfref),_tyargs,_ -> | TOp.ValFieldGetAddr(_rfref, _readonly),_tyargs,_ ->
wfail(Error(FSComp.SR.crefQuotationsCantContainAddressOf(), m)) wfail(Error(FSComp.SR.crefQuotationsCantContainAddressOf(), m))
| TOp.UnionCaseFieldGetAddr _,_tyargs,_ -> | TOp.UnionCaseFieldGetAddr _,_tyargs,_ ->
@ -518,7 +518,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.
// rebuild reraise<T>() and Convert // rebuild reraise<T>() and Convert
mkReraiseLibCall cenv.g toTy m |> ConvExpr cenv env mkReraiseLibCall cenv.g toTy m |> ConvExpr cenv env
| TOp.LValueOp(LGetAddr,vref),[],[] -> | TOp.LValueOp(LAddrOf _,vref),[],[] ->
QP.mkAddressOf(ConvValRef false cenv env m vref []) QP.mkAddressOf(ConvValRef false cenv env m vref [])
| TOp.LValueOp(LByrefSet,vref),[],[e] -> | TOp.LValueOp(LByrefSet,vref),[],[e] ->
@ -586,7 +586,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.
| TOp.UnionCaseTagGet _tycr,_tinst,[_cx] -> wfail(Error(FSComp.SR.crefQuotationsCantFetchUnionIndexes(), m)) | TOp.UnionCaseTagGet _tycr,_tinst,[_cx] -> wfail(Error(FSComp.SR.crefQuotationsCantFetchUnionIndexes(), m))
| TOp.UnionCaseFieldSet (_c,_i),_tinst,[_cx;_x] -> wfail(Error(FSComp.SR.crefQuotationsCantSetUnionFields(), m)) | TOp.UnionCaseFieldSet (_c,_i),_tinst,[_cx;_x] -> wfail(Error(FSComp.SR.crefQuotationsCantSetUnionFields(), m))
| TOp.ExnFieldSet(_tcref,_i),[],[_ex;_x] -> wfail(Error(FSComp.SR.crefQuotationsCantSetExceptionFields(), m)) | TOp.ExnFieldSet(_tcref,_i),[],[_ex;_x] -> wfail(Error(FSComp.SR.crefQuotationsCantSetExceptionFields(), m))
| TOp.RefAddrGet,_,_ -> wfail(Error(FSComp.SR.crefQuotationsCantRequireByref(), m)) | TOp.RefAddrGet _,_,_ -> wfail(Error(FSComp.SR.crefQuotationsCantRequireByref(), m))
| TOp.TraitCall (_ss),_,_ -> wfail(Error(FSComp.SR.crefQuotationsCantCallTraitMembers(), m)) | TOp.TraitCall (_ss),_,_ -> wfail(Error(FSComp.SR.crefQuotationsCantCallTraitMembers(), m))
| _ -> | _ ->
wfail(InternalError( "Unexpected expression shape",m)) wfail(InternalError( "Unexpected expression shape",m))
@ -665,9 +665,9 @@ and ConvLValueExprCore cenv env expr =
match expr with match expr with
| Expr.Op(op,tyargs,args,m) -> | Expr.Op(op,tyargs,args,m) ->
match op, args, tyargs with match op, args, tyargs with
| TOp.LValueOp(LGetAddr,vref),_,_ -> ConvValRef false cenv env m vref [] | TOp.LValueOp(LAddrOf _,vref),_,_ -> ConvValRef false cenv env m vref []
| TOp.ValFieldGetAddr(rfref),_,_ -> ConvClassOrRecdFieldGet cenv env m rfref tyargs args | TOp.ValFieldGetAddr(rfref, _),_,_ -> ConvClassOrRecdFieldGet cenv env m rfref tyargs args
| TOp.UnionCaseFieldGetAddr(ucref,n),[e],_ -> ConvUnionFieldGet cenv env m ucref n tyargs e | TOp.UnionCaseFieldGetAddr(ucref,n, _),[e],_ -> ConvUnionFieldGet cenv env m ucref n tyargs e
| TOp.ILAsm([ I_ldflda(fspec) ],_rtys),_,_ -> ConvLdfld cenv env m fspec tyargs args | TOp.ILAsm([ I_ldflda(fspec) ],_rtys),_,_ -> ConvLdfld cenv env m fspec tyargs args
| TOp.ILAsm([ I_ldsflda(fspec) ],_rtys),_,_ -> ConvLdfld cenv env m fspec tyargs args | TOp.ILAsm([ I_ldsflda(fspec) ],_rtys),_,_ -> ConvLdfld cenv env m fspec tyargs args
| TOp.ILAsm(([ I_ldelema(_ro,_isNativePtr,shape,_tyarg) ] ),_), (arr::idxs), [elemty] -> | TOp.ILAsm(([ I_ldelema(_ro,_isNativePtr,shape,_tyarg) ] ),_), (arr::idxs), [elemty] ->

Просмотреть файл

@ -560,8 +560,45 @@ let tryNormalizeMeasureInType g ty =
// Some basic type builders // Some basic type builders
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
let mkNativePtrTy (g:TcGlobals) ty = TType_app (g.nativeptr_tcr, [ty]) let mkNativePtrTy (g:TcGlobals) ty =
let mkByrefTy (g:TcGlobals) ty = TType_app (g.byref_tcr, [ty]) assert g.nativeptr_tcr.CanDeref // this should always be available, but check anyway
TType_app (g.nativeptr_tcr, [ty])
let mkByrefTy (g:TcGlobals) ty =
assert g.byref_tcr.CanDeref // this should always be available, but check anyway
TType_app (g.byref_tcr, [ty])
let mkInByrefTy (g:TcGlobals) ty =
if g.inref_tcr.CanDeref then // If not using sufficient FSharp.Core, then inref<T> = byref<T>, see RFC FS-1053.md
TType_app (g.inref_tcr, [ty])
else
mkByrefTy g ty
let mkOutByrefTy (g:TcGlobals) ty =
if g.outref_tcr.CanDeref then // If not using sufficient FSharp.Core, then outref<T> = byref<T>, see RFC FS-1053.md
TType_app (g.outref_tcr, [ty])
else
mkByrefTy g ty
let mkByrefTyWithFlag g readonly ty =
if readonly then
mkInByrefTy g ty
else
mkByrefTy g ty
let mkByref2Ty (g:TcGlobals) ty1 ty2 =
assert g.byref2_tcr.CanDeref // check we are using sufficient FSharp.Core, caller should check this
TType_app (g.byref2_tcr, [ty1; ty2])
let mkVoidPtrTy (g:TcGlobals) =
assert g.voidptr_tcr.CanDeref // check we are using sufficient FSharp.Core , caller should check this
TType_app (g.voidptr_tcr, [])
let mkByrefTyWithInference (g:TcGlobals) ty1 ty2 =
if g.byref2_tcr.CanDeref then // If not using sufficient FSharp.Core, then inref<T> = byref<T>, see RFC FS-1053.md
TType_app (g.byref2_tcr, [ty1; ty2])
else
TType_app (g.byref_tcr, [ty1])
let mkArrayTy (g:TcGlobals) rank ty m = let mkArrayTy (g:TcGlobals) rank ty m =
if rank < 1 || rank > 32 then if rank < 1 || rank > 32 then
@ -675,7 +712,16 @@ let rec stripTyEqnsA g canShortcut ty =
| Some abbrevTy -> | Some abbrevTy ->
stripTyEqnsA g canShortcut (applyTyconAbbrev abbrevTy tycon tinst) stripTyEqnsA g canShortcut (applyTyconAbbrev abbrevTy tycon tinst)
| None -> | None ->
if tycon.IsMeasureableReprTycon && List.forall (isDimensionless g) tinst then // This is the point where we get to add additional coditional normalizing equations
// into the type system. Such power!
//
// Add the equation byref<'T> = byref<'T, ByRefKinds.InOut> for when using sufficient FSharp.Core
// See RFC FS-1053.md
if tyconRefEq g tcref g.byref_tcr && g.byref2_tcr.CanDeref && g.byrefkind_InOut_tcr.CanDeref then
mkByref2Ty g tinst.[0] (TType_app(g.byrefkind_InOut_tcr, []))
// Add the equation double<1> = double for units of measure.
elif tycon.IsMeasureableReprTycon && List.forall (isDimensionless g) tinst then
stripTyEqnsA g canShortcut (reduceTyconMeasureableOrProvided g tycon tinst) stripTyEqnsA g canShortcut (reduceTyconMeasureableOrProvided g tycon tinst)
else else
ty ty
@ -782,11 +828,6 @@ let (|StripNullableTy|) g ty =
| AppTy g (tcr, [tyarg]) when tyconRefEq g tcr g.system_Nullable_tcref -> tyarg | AppTy g (tcr, [tyarg]) when tyconRefEq g tcr g.system_Nullable_tcref -> tyarg
| _ -> ty | _ -> ty
let (|ByrefTy|_|) g ty =
match ty with
| AppTy g (tcr, [tyarg]) when tyconRefEq g tcr g.byref_tcr -> Some tyarg
| _ -> None
let mkInstForAppTy g typ = let mkInstForAppTy g typ =
match typ with match typ with
| AppTy g (tcref, tinst) -> mkTyconRefInst tcref tinst | AppTy g (tcref, tinst) -> mkTyconRefInst tcref tinst
@ -1231,13 +1272,14 @@ let mkExnExpr(uc, args, m) = Expr.Op (TOp.ExnConstr uc,
let mkTupleFieldGetViaExprAddr(tupInfo, e, tinst, i, m) = Expr.Op (TOp.TupleFieldGet(tupInfo, i), tinst, [e], m) let mkTupleFieldGetViaExprAddr(tupInfo, e, tinst, i, m) = Expr.Op (TOp.TupleFieldGet(tupInfo, i), tinst, [e], m)
let mkRecdFieldGetViaExprAddr(e, fref, tinst, m) = Expr.Op (TOp.ValFieldGet(fref), tinst, [e], m) let mkRecdFieldGetViaExprAddr(e, fref, tinst, m) = Expr.Op (TOp.ValFieldGet(fref), tinst, [e], m)
let mkRecdFieldGetAddrViaExprAddr(e, fref, tinst, m) = Expr.Op (TOp.ValFieldGetAddr(fref), tinst, [e], m) let mkRecdFieldGetAddrViaExprAddr(readonly, e, fref, tinst, m) = Expr.Op (TOp.ValFieldGetAddr(fref, readonly), tinst, [e], m)
let mkStaticRecdFieldGetAddr(fref, tinst, m) = Expr.Op (TOp.ValFieldGetAddr(fref), tinst, [], m) let mkStaticRecdFieldGetAddr(readonly, fref, tinst, m) = Expr.Op (TOp.ValFieldGetAddr(fref, readonly), tinst, [], m)
let mkStaticRecdFieldGet(fref, tinst, m) = Expr.Op (TOp.ValFieldGet(fref), tinst, [], m) let mkStaticRecdFieldGet(fref, tinst, m) = Expr.Op (TOp.ValFieldGet(fref), tinst, [], m)
let mkStaticRecdFieldSet(fref, tinst, e, m) = Expr.Op (TOp.ValFieldSet(fref), tinst, [e], m) let mkStaticRecdFieldSet(fref, tinst, e, m) = Expr.Op (TOp.ValFieldSet(fref), tinst, [e], m)
let mkArrayElemAddress g (readonly, isNativePtr, shape, elemTy, aexpr, nexpr, m) = Expr.Op (TOp.ILAsm ([IL.I_ldelema(readonly, isNativePtr, shape, mkILTyvarTy 0us)], [mkByrefTy g elemTy]), [elemTy], [aexpr;nexpr], m) let mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, exprs, m) =
Expr.Op (TOp.ILAsm ([IL.I_ldelema(ilInstrReadOnlyAnnotation, isNativePtr, shape, mkILTyvarTy 0us)], [mkByrefTyWithFlag g readonly elemTy]), [elemTy], exprs, m)
let mkRecdFieldSetViaExprAddr (e1, fref, tinst, e2, m) = Expr.Op (TOp.ValFieldSet(fref), tinst, [e1;e2], m) let mkRecdFieldSetViaExprAddr (e1, fref, tinst, e2, m) = Expr.Op (TOp.ValFieldSet(fref), tinst, [e1;e2], m)
@ -1254,7 +1296,7 @@ let mkUnionCaseFieldGetProvenViaExprAddr (e1, cref, tinst, j, m) = Expr.Op (TO
/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions, /// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions,
/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, /// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions,
/// the input should be the address of the expression. /// the input should be the address of the expression.
let mkUnionCaseFieldGetAddrProvenViaExprAddr (e1, cref, tinst, j, m) = Expr.Op (TOp.UnionCaseFieldGetAddr(cref, j), tinst, [e1], m) let mkUnionCaseFieldGetAddrProvenViaExprAddr (readonly, e1, cref, tinst, j, m) = Expr.Op (TOp.UnionCaseFieldGetAddr(cref, j, readonly), tinst, [e1], m)
/// Build a 'get' expression for something we've already determined to be a particular union case, but where /// Build a 'get' expression for something we've already determined to be a particular union case, but where
/// the static type of the input is not yet proven to be that particular union case. This requires a type /// the static type of the input is not yet proven to be that particular union case. This requires a type
@ -1287,7 +1329,7 @@ let mkDefault (m, ty) = Expr.Const(Const.Zero, m, ty)
let mkValSet m v e = Expr.Op (TOp.LValueOp (LSet, v), [], [e], m) let mkValSet m v e = Expr.Op (TOp.LValueOp (LSet, v), [], [e], m)
let mkAddrSet m v e = Expr.Op (TOp.LValueOp (LByrefSet, v), [], [e], m) let mkAddrSet m v e = Expr.Op (TOp.LValueOp (LByrefSet, v), [], [e], m)
let mkAddrGet m v = Expr.Op (TOp.LValueOp (LByrefGet, v), [], [], m) let mkAddrGet m v = Expr.Op (TOp.LValueOp (LByrefGet, v), [], [], m)
let mkValAddr m v = Expr.Op (TOp.LValueOp (LGetAddr, v), [], [], m) let mkValAddr m readonly v = Expr.Op (TOp.LValueOp (LAddrOf readonly, v), [], [], m)
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Maps tracking extra information for values // Maps tracking extra information for values
@ -1315,14 +1357,21 @@ type ValHash<'T> =
[<Struct; NoEquality; NoComparison>] [<Struct; NoEquality; NoComparison>]
type ValMultiMap<'T>(contents: StampMap<'T list>) = type ValMultiMap<'T>(contents: StampMap<'T list>) =
member m.ContainsKey (v: Val) =
contents.ContainsKey v.Stamp
member m.Find (v: Val) = member m.Find (v: Val) =
match contents |> Map.tryFind v.Stamp with match contents |> Map.tryFind v.Stamp with
| Some vals -> vals | Some vals -> vals
| _ -> [] | _ -> []
member m.Add (v:Val, x) = ValMultiMap<'T>(contents.Add (v.Stamp, x :: m.Find v)) member m.Add (v:Val, x) = ValMultiMap<'T>(contents.Add (v.Stamp, x :: m.Find v))
member m.Remove (v: Val) = ValMultiMap<'T>(contents.Remove v.Stamp) member m.Remove (v: Val) = ValMultiMap<'T>(contents.Remove v.Stamp)
member m.Contents = contents member m.Contents = contents
static member Empty = ValMultiMap<'T>(Map.empty) static member Empty = ValMultiMap<'T>(Map.empty)
[<Struct; NoEquality; NoComparison>] [<Struct; NoEquality; NoComparison>]
@ -1529,17 +1578,11 @@ let destListTy (g:TcGlobals) ty =
| AppTy g (tcref, [ty]) when tyconRefEq g tcref g.list_tcr_canon -> ty | AppTy g (tcref, [ty]) when tyconRefEq g tcref g.list_tcr_canon -> ty
| _ -> failwith "destListTy" | _ -> failwith "destListTy"
let isTypeConstructorEqualToOptional g tcOpt tc = let tyconRefEqOpt g tcOpt tc =
match tcOpt with match tcOpt with
| None -> false | None -> false
| Some tc2 -> tyconRefEq g tc2 tc | Some tc2 -> tyconRefEq g tc2 tc
let isByrefLikeTyconRef g tcref =
tyconRefEq g g.byref_tcr tcref ||
isTypeConstructorEqualToOptional g g.system_TypedReference_tcref tcref ||
isTypeConstructorEqualToOptional g g.system_ArgIterator_tcref tcref ||
isTypeConstructorEqualToOptional g g.system_RuntimeArgumentHandle_tcref tcref
let isStringTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.system_String_tcref | _ -> false) let isStringTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.system_String_tcref | _ -> false)
let isListTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.list_tcr_canon | _ -> false) let isListTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g tcref g.list_tcr_canon | _ -> false)
let isArrayTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isArrayTyconRef g tcref | _ -> false) let isArrayTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isArrayTyconRef g tcref | _ -> false)
@ -1549,8 +1592,25 @@ let isObjTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) ->
let isVoidTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.system_Void_tcref tcref | _ -> false) let isVoidTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.system_Void_tcref tcref | _ -> false)
let isILAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsILTycon | _ -> false) let isILAppTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.IsILTycon | _ -> false)
let isNativePtrTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.nativeptr_tcr tcref | _ -> false) let isNativePtrTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.nativeptr_tcr tcref | _ -> false)
let isByrefTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tyconRefEq g g.byref_tcr tcref | _ -> false)
let isByrefLikeTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isByrefLikeTyconRef g tcref | _ -> false) let isByrefTy g ty =
ty |> stripTyEqns g |> (function
| TType_app(tcref, _) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref
| TType_app(tcref, _) -> tyconRefEq g g.byref_tcr tcref
| _ -> false)
let isInByrefTag g ty = ty |> stripTyEqns g |> (function TType_app(tcref, []) -> tyconRefEq g g.byrefkind_In_tcr tcref | _ -> false)
let isInByrefTy g ty =
ty |> stripTyEqns g |> (function
| TType_app(tcref, [_; tag]) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref && isInByrefTag g tag
| _ -> false)
let isOutByrefTag g ty = ty |> stripTyEqns g |> (function TType_app(tcref, []) -> tyconRefEq g g.byrefkind_Out_tcr tcref | _ -> false)
let isOutByrefTy g ty =
ty |> stripTyEqns g |> (function
| TType_app(tcref, [_; tag]) when g.byref2_tcr.CanDeref -> tyconRefEq g g.byref2_tcr tcref && isOutByrefTag g tag
| _ -> false)
#if !NO_EXTENSIONTYPING #if !NO_EXTENSIONTYPING
let extensionInfoOfTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.TypeReprInfo | _ -> TNoRepr) let extensionInfoOfTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.TypeReprInfo | _ -> TNoRepr)
#endif #endif
@ -2754,7 +2814,7 @@ let isILAttribByName (tencl:string list, tname: string) (attr: ILAttribute) =
(attr.Method.DeclaringType.TypeSpec.Name = tname) && (attr.Method.DeclaringType.TypeSpec.Name = tname) &&
(attr.Method.DeclaringType.TypeSpec.Enclosing = tencl) (attr.Method.DeclaringType.TypeSpec.Enclosing = tencl)
// AbsIL view of attributes (we read these from .NET binaries) // AbsIL view of attributes (we read these from .NET binaries). The comparison is done by name.
let isILAttrib (tref:ILTypeRef) (attr: ILAttribute) = let isILAttrib (tref:ILTypeRef) (attr: ILAttribute) =
isILAttribByName (tref.Enclosing, tref.Name) attr isILAttribByName (tref.Enclosing, tref.Name) attr
@ -2762,18 +2822,12 @@ let isILAttrib (tref:ILTypeRef) (attr: ILAttribute) =
// These linear iterations cost us a fair bit when there are lots of attributes // These linear iterations cost us a fair bit when there are lots of attributes
// on imported types. However this is fairly rare and can also be solved by caching the // on imported types. However this is fairly rare and can also be solved by caching the
// results of attribute lookups in the TAST // results of attribute lookups in the TAST
let HasILAttribute tref (attrs: ILAttributes) = Array.exists (isILAttrib tref) attrs.AsArray let HasILAttribute tref (attrs: ILAttributes) =
attrs.AsArray |> Array.exists (isILAttrib tref)
let HasILAttributeByName tname (attrs: ILAttributes) = Array.exists (isILAttribByName ([], tname)) attrs.AsArray
let TryDecodeILAttribute (g:TcGlobals) tref (attrs: ILAttributes) = let TryDecodeILAttribute (g:TcGlobals) tref (attrs: ILAttributes) =
attrs.AsArray |> Array.tryPick (fun x -> if isILAttrib tref x then Some(decodeILAttribData g.ilg x) else None) attrs.AsArray |> Array.tryPick (fun x -> if isILAttrib tref x then Some(decodeILAttribData g.ilg x) else None)
// This one is done by name to ensure the compiler doesn't take a dependency on dereferencing a type that only exists in .NET 3.5
let ILThingHasExtensionAttribute (attrs : ILAttributes) =
attrs.AsArray
|> Array.exists (fun attr -> attr.Method.DeclaringType.TypeSpec.Name = "System.Runtime.CompilerServices.ExtensionAttribute")
// F# view of attributes (these get converted to AbsIL attributes in ilxgen) // F# view of attributes (these get converted to AbsIL attributes in ilxgen)
let IsMatchingFSharpAttribute g (AttribInfo(_, tcref)) (Attrib(tcref2, _, _, _, _, _, _)) = tyconRefEq g tcref tcref2 let IsMatchingFSharpAttribute g (AttribInfo(_, tcref)) (Attrib(tcref2, _, _, _, _, _, _)) = tyconRefEq g tcref tcref2
let HasFSharpAttribute g tref attrs = List.exists (IsMatchingFSharpAttribute g tref) attrs let HasFSharpAttribute g tref attrs = List.exists (IsMatchingFSharpAttribute g tref) attrs
@ -2881,15 +2935,44 @@ let TyconRefHasAttribute g m attribSpec tcref =
(fun _ -> Some ()) (fun _ -> Some ())
|> Option.isSome |> Option.isSome
let isByrefTyconRef (g: TcGlobals) (tcref: TyconRef) =
(g.byref_tcr.CanDeref && tyconRefEq g g.byref_tcr tcref) ||
(g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref) ||
(g.inref_tcr.CanDeref && tyconRefEq g g.inref_tcr tcref) ||
(g.outref_tcr.CanDeref && tyconRefEq g g.outref_tcr tcref) ||
tyconRefEqOpt g g.system_TypedReference_tcref tcref ||
tyconRefEqOpt g g.system_ArgIterator_tcref tcref ||
tyconRefEqOpt g g.system_RuntimeArgumentHandle_tcref tcref
// See RFC FS-1053.md
let isByrefLikeTyconRef (g: TcGlobals) m (tcref: TyconRef) =
tcref.CanDeref &&
match tcref.TryIsByRefLike with
| Some res -> res
| None ->
let res =
isByrefTyconRef g tcref ||
TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref
tcref.SetIsByRefLike res
res
let isByrefLikeTy g m ty =
ty |> stripTyEqns g |> (function TType_app(tcref, _) -> isByrefLikeTyconRef g m tcref | _ -> false)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// List and reference types... // List and reference types...
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
let destByrefTy g ty = let destByrefTy g ty =
match ty |> stripTyEqns g with match ty |> stripTyEqns g with
| TType_app(tcref, [x]) when tyconRefEq g g.byref_tcr tcref -> x | TType_app(tcref, [x; _]) when g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref -> x // Check sufficient FSharp.Core
| TType_app(tcref, [x]) when tyconRefEq g g.byref_tcr tcref -> x // all others
| _ -> failwith "destByrefTy: not a byref type" | _ -> failwith "destByrefTy: not a byref type"
let (|ByrefTy|_|) g ty =
// Because of byref = byref2<ty,tags> it is better to write this using is/dest
if isByrefTy g ty then Some (destByrefTy g ty) else None
let destNativePtrTy g ty = let destNativePtrTy g ty =
match ty |> stripTyEqns g with match ty |> stripTyEqns g with
| TType_app(tcref, [x]) when tyconRefEq g g.nativeptr_tcr tcref -> x | TType_app(tcref, [x]) when tyconRefEq g g.nativeptr_tcr tcref -> x
@ -3062,7 +3145,7 @@ module DebugPrint = begin
let lvalopL x = let lvalopL x =
match x with match x with
| LGetAddr -> wordL (tagText "LGetAddr") | LAddrOf readonly -> wordL (tagText (sprintf "LAddrOf(%b)" readonly))
| LByrefGet -> wordL (tagText "LByrefGet") | LByrefGet -> wordL (tagText "LByrefGet")
| LSet -> wordL (tagText "LSet") | LSet -> wordL (tagText "LSet")
| LByrefSet -> wordL (tagText "LByrefSet") | LByrefSet -> wordL (tagText "LByrefSet")
@ -3539,9 +3622,9 @@ module DebugPrint = begin
(atomL rx ^^ rightL(tagText ".#") ^^ recdFieldRefL rf) (atomL rx ^^ rightL(tagText ".#") ^^ recdFieldRefL rf)
| Expr.Op (TOp.ValFieldGet rf, _, [], _) -> | Expr.Op (TOp.ValFieldGet rf, _, [], _) ->
recdFieldRefL rf recdFieldRefL rf
| Expr.Op (TOp.ValFieldGetAddr rf, _, [rx], _) -> | Expr.Op (TOp.ValFieldGetAddr (rf, _), _, [rx], _) ->
leftL(tagText "&") ^^ bracketL (atomL rx ^^ rightL(tagText ".!") ^^ recdFieldRefL rf) leftL(tagText "&") ^^ bracketL (atomL rx ^^ rightL(tagText ".!") ^^ recdFieldRefL rf)
| Expr.Op (TOp.ValFieldGetAddr rf, _, [], _) -> | Expr.Op (TOp.ValFieldGetAddr (rf, _), _, [], _) ->
leftL(tagText "&") ^^ (recdFieldRefL rf) leftL(tagText "&") ^^ (recdFieldRefL rf)
| Expr.Op (TOp.UnionCaseTagGet tycr, _, [x], _) -> | Expr.Op (TOp.UnionCaseTagGet tycr, _, [x], _) ->
wordL (tagText ("#" + tycr.LogicalName + ".tag")) ^^ atomL x wordL (tagText ("#" + tycr.LogicalName + ".tag")) ^^ atomL x
@ -3584,7 +3667,7 @@ module DebugPrint = begin
| Expr.Op (TOp.Bytes _, _ , _ , _) -> | Expr.Op (TOp.Bytes _, _ , _ , _) ->
wordL(tagText "bytes++") wordL(tagText "bytes++")
| Expr.Op (TOp.UInt16s _, _ , _ , _) -> wordL(tagText "uint16++") | Expr.Op (TOp.UInt16s _, _ , _ , _) -> wordL(tagText "uint16++")
| Expr.Op (TOp.RefAddrGet, _tyargs, _args, _) -> wordL(tagText "GetRefLVal...") | Expr.Op (TOp.RefAddrGet _, _tyargs, _args, _) -> wordL(tagText "GetRefLVal...")
| Expr.Op (TOp.TraitCall _, _tyargs, _args, _) -> wordL(tagText "traitcall...") | Expr.Op (TOp.TraitCall _, _tyargs, _args, _) -> wordL(tagText "traitcall...")
| Expr.Op (TOp.ExnFieldGet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldGet...") | Expr.Op (TOp.ExnFieldGet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldGet...")
| Expr.Op (TOp.ExnFieldSet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldSet...") | Expr.Op (TOp.ExnFieldSet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldSet...")
@ -4307,7 +4390,7 @@ and accFreeInOp opts op acc =
| TOp.TryFinally _ | TOp.TryFinally _
| TOp.For _ | TOp.For _
| TOp.Coerce | TOp.Coerce
| TOp.RefAddrGet | TOp.RefAddrGet _
| TOp.Array | TOp.Array
| TOp.While _ | TOp.While _
| TOp.Goto _ | TOp.Label _ | TOp.Return | TOp.Goto _ | TOp.Label _ | TOp.Return
@ -4320,7 +4403,7 @@ and accFreeInOp opts op acc =
// Things containing just a union case reference // Things containing just a union case reference
| TOp.UnionCaseProof cr | TOp.UnionCaseProof cr
| TOp.UnionCase cr | TOp.UnionCase cr
| TOp.UnionCaseFieldGetAddr (cr, _) | TOp.UnionCaseFieldGetAddr (cr, _, _)
| TOp.UnionCaseFieldGet (cr, _) | TOp.UnionCaseFieldGet (cr, _)
| TOp.UnionCaseFieldSet (cr, _) -> accFreeUnionCaseRef opts cr acc | TOp.UnionCaseFieldSet (cr, _) -> accFreeUnionCaseRef opts cr acc
@ -4330,7 +4413,7 @@ and accFreeInOp opts op acc =
| TOp.ExnFieldSet (ecr, _) -> accFreeExnRef ecr acc | TOp.ExnFieldSet (ecr, _) -> accFreeExnRef ecr acc
| TOp.ValFieldGet fr | TOp.ValFieldGet fr
| TOp.ValFieldGetAddr fr | TOp.ValFieldGetAddr (fr, _)
| TOp.ValFieldSet fr -> accFreeRecdFieldRef opts fr acc | TOp.ValFieldSet fr -> accFreeRecdFieldRef opts fr acc
| TOp.Recd (kind, tcr) -> | TOp.Recd (kind, tcr) ->
@ -4756,23 +4839,23 @@ and remapExpr (g: TcGlobals) (compgen:ValCopyFlag) (tmenv:Remap) x =
// of a temporary local, e.g. // of a temporary local, e.g.
// &(E.RF) --> let mutable v = E.RF in &v // &(E.RF) --> let mutable v = E.RF in &v
| Expr.Op (TOp.ValFieldGetAddr rfref, tinst, [arg], m) when | Expr.Op (TOp.ValFieldGetAddr (rfref, readonly), tinst, [arg], m) when
not rfref.RecdField.IsMutable && not rfref.RecdField.IsMutable &&
not (entityRefInThisAssembly g.compilingFslib rfref.TyconRef) -> not (entityRefInThisAssembly g.compilingFslib rfref.TyconRef) ->
let tinst = remapTypes tmenv tinst let tinst = remapTypes tmenv tinst
let arg = remapExpr g compgen tmenv arg let arg = remapExpr g compgen tmenv arg
let tmp, _ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfRecdFieldRef rfref tinst) let tmp, _ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfRecdFieldRef rfref tinst)
mkCompGenLet m tmp (mkRecdFieldGetViaExprAddr(arg, rfref, tinst, m)) (mkValAddr m (mkLocalValRef tmp)) mkCompGenLet m tmp (mkRecdFieldGetViaExprAddr(arg, rfref, tinst, m)) (mkValAddr m readonly (mkLocalValRef tmp))
| Expr.Op (TOp.UnionCaseFieldGetAddr (uref, cidx), tinst, [arg], m) when | Expr.Op (TOp.UnionCaseFieldGetAddr (uref, cidx, readonly), tinst, [arg], m) when
not (uref.FieldByIndex(cidx).IsMutable) && not (uref.FieldByIndex(cidx).IsMutable) &&
not (entityRefInThisAssembly g.compilingFslib uref.TyconRef) -> not (entityRefInThisAssembly g.compilingFslib uref.TyconRef) ->
let tinst = remapTypes tmenv tinst let tinst = remapTypes tmenv tinst
let arg = remapExpr g compgen tmenv arg let arg = remapExpr g compgen tmenv arg
let tmp, _ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfUnionFieldRef uref cidx tinst) let tmp, _ = mkMutableCompGenLocal m "copyOfStruct" (actualTyOfUnionFieldRef uref cidx tinst)
mkCompGenLet m tmp (mkUnionCaseFieldGetProvenViaExprAddr(arg, uref, tinst, cidx, m)) (mkValAddr m (mkLocalValRef tmp)) mkCompGenLet m tmp (mkUnionCaseFieldGetProvenViaExprAddr(arg, uref, tinst, cidx, m)) (mkValAddr m readonly (mkLocalValRef tmp))
| Expr.Op (op, tinst, args, m) -> | Expr.Op (op, tinst, args, m) ->
let op' = remapOp tmenv op let op' = remapOp tmenv op
@ -4842,8 +4925,9 @@ and remapOp tmenv op =
| TOp.ExnFieldSet(ec, n) -> TOp.ExnFieldSet(remapTyconRef tmenv.tyconRefRemap ec, n) | TOp.ExnFieldSet(ec, n) -> TOp.ExnFieldSet(remapTyconRef tmenv.tyconRefRemap ec, n)
| TOp.ValFieldSet rfref -> TOp.ValFieldSet(remapRecdFieldRef tmenv.tyconRefRemap rfref) | TOp.ValFieldSet rfref -> TOp.ValFieldSet(remapRecdFieldRef tmenv.tyconRefRemap rfref)
| TOp.ValFieldGet rfref -> TOp.ValFieldGet(remapRecdFieldRef tmenv.tyconRefRemap rfref) | TOp.ValFieldGet rfref -> TOp.ValFieldGet(remapRecdFieldRef tmenv.tyconRefRemap rfref)
| TOp.ValFieldGetAddr rfref -> TOp.ValFieldGetAddr(remapRecdFieldRef tmenv.tyconRefRemap rfref) | TOp.ValFieldGetAddr (rfref, readonly) -> TOp.ValFieldGetAddr(remapRecdFieldRef tmenv.tyconRefRemap rfref, readonly)
| TOp.UnionCaseFieldGet(ucref, n) -> TOp.UnionCaseFieldGet(remapUnionCaseRef tmenv.tyconRefRemap ucref, n) | TOp.UnionCaseFieldGet(ucref, n) -> TOp.UnionCaseFieldGet(remapUnionCaseRef tmenv.tyconRefRemap ucref, n)
| TOp.UnionCaseFieldGetAddr(ucref, n, readonly) -> TOp.UnionCaseFieldGetAddr(remapUnionCaseRef tmenv.tyconRefRemap ucref, n, readonly)
| TOp.UnionCaseFieldSet(ucref, n) -> TOp.UnionCaseFieldSet(remapUnionCaseRef tmenv.tyconRefRemap ucref, n) | TOp.UnionCaseFieldSet(ucref, n) -> TOp.UnionCaseFieldSet(remapUnionCaseRef tmenv.tyconRefRemap ucref, n)
| TOp.ILAsm (instrs, tys) -> | TOp.ILAsm (instrs, tys) ->
let tys2 = remapTypes tmenv tys let tys2 = remapTypes tmenv tys
@ -5236,15 +5320,16 @@ let isUnionCaseDefinitelyMutable (uc:UnionCase) = uc.FieldTable.FieldsByIndex |>
let isUnionCaseRefDefinitelyMutable (uc:UnionCaseRef) = uc.UnionCase |> isUnionCaseDefinitelyMutable let isUnionCaseRefDefinitelyMutable (uc:UnionCaseRef) = uc.UnionCase |> isUnionCaseDefinitelyMutable
/// This is an incomplete check for .NET struct types. Returning 'false' doesn't mean the thing is immutable. /// This is an incomplete check for .NET struct types. Returning 'false' doesn't mean the thing is immutable.
let isRecdOrUnionOrStructTyconDefinitelyMutable (_g:TcGlobals) (tycon:Tycon) = let isRecdOrUnionOrStructTyconRefDefinitelyMutable (tcref: TyconRef) =
let tycon = tcref.Deref
if tycon.IsUnionTycon then if tycon.IsUnionTycon then
tycon.UnionCasesArray |> Array.exists isUnionCaseDefinitelyMutable tycon.UnionCasesArray |> Array.exists isUnionCaseDefinitelyMutable
elif tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then elif tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then
// Note: This only looks at the F# fields, causing oddities.
// See https://github.com/Microsoft/visualfsharp/pull/4576
tycon.AllFieldsArray |> Array.exists isRecdOrStructFieldDefinitelyMutable tycon.AllFieldsArray |> Array.exists isRecdOrStructFieldDefinitelyMutable
else else
false false
let isRecdOrUnionOrStructTyconRefDefinitelyMutable g (tcr : TyconRef) = isRecdOrUnionOrStructTyconDefinitelyMutable g tcr.Deref
// Although from the pure F# perspective exception values cannot be changed, the .NET // Although from the pure F# perspective exception values cannot be changed, the .NET
// implementation of exception objects attaches a whole bunch of stack information to // implementation of exception objects attaches a whole bunch of stack information to
@ -5255,7 +5340,7 @@ let isExnDefinitelyMutable (_ecref:TyconRef) = true
// of the cons cell. These cells are always private, i.e. not accessible by any other // of the cons cell. These cells are always private, i.e. not accessible by any other
// code until the construction of the entire return list has been completed. // code until the construction of the entire return list has been completed.
// However, within the implementation code reads of the tail cell must in theory be treated // However, within the implementation code reads of the tail cell must in theory be treated
// with caution. Hence we are conservative and within fslib we don't treat list // with caution. Hence we are conservative and within FSharp.Core we don't treat list
// reads as if they were pure. // reads as if they were pure.
let isUnionCaseFieldMutable (g: TcGlobals) (ucref:UnionCaseRef) n = let isUnionCaseFieldMutable (g: TcGlobals) (ucref:UnionCaseRef) n =
(g.compilingFslib && tyconRefEq g ucref.TyconRef g.list_tcr_canon && n = 1) || (g.compilingFslib && tyconRefEq g ucref.TyconRef g.list_tcr_canon && n = 1) ||
@ -5331,16 +5416,16 @@ let rec tyOfExpr g e =
| (TOp.For _ | TOp.While _) -> g.unit_ty | (TOp.For _ | TOp.While _) -> g.unit_ty
| TOp.Array -> (match tinst with [ty] -> mkArrayType g ty | _ -> failwith "bad TOp.Array node") | TOp.Array -> (match tinst with [ty] -> mkArrayType g ty | _ -> failwith "bad TOp.Array node")
| (TOp.TryCatch _ | TOp.TryFinally _) -> (match tinst with [ty] -> ty | _ -> failwith "bad TOp_try node") | (TOp.TryCatch _ | TOp.TryFinally _) -> (match tinst with [ty] -> ty | _ -> failwith "bad TOp_try node")
| TOp.ValFieldGetAddr(fref) -> mkByrefTy g (actualTyOfRecdFieldRef fref tinst) | TOp.ValFieldGetAddr(fref, readonly) -> mkByrefTyWithFlag g readonly (actualTyOfRecdFieldRef fref tinst)
| TOp.ValFieldGet(fref) -> actualTyOfRecdFieldRef fref tinst | TOp.ValFieldGet(fref) -> actualTyOfRecdFieldRef fref tinst
| (TOp.ValFieldSet _ | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ | TOp.LValueOp ((LSet | LByrefSet), _)) ->g.unit_ty | (TOp.ValFieldSet _ | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ | TOp.LValueOp ((LSet | LByrefSet), _)) ->g.unit_ty
| TOp.UnionCaseTagGet _ -> g.int_ty | TOp.UnionCaseTagGet _ -> g.int_ty
| TOp.UnionCaseFieldGetAddr(cref, j) -> mkByrefTy g (actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j)) | TOp.UnionCaseFieldGetAddr(cref, j, readonly) -> mkByrefTyWithFlag g readonly (actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j))
| TOp.UnionCaseFieldGet(cref, j) -> actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j) | TOp.UnionCaseFieldGet(cref, j) -> actualTyOfRecdField (mkTyconRefInst cref.TyconRef tinst) (cref.FieldByIndex j)
| TOp.ExnFieldGet(ecref, j) -> recdFieldTyOfExnDefRefByIdx ecref j | TOp.ExnFieldGet(ecref, j) -> recdFieldTyOfExnDefRefByIdx ecref j
| TOp.LValueOp (LByrefGet, v) -> destByrefTy g v.Type | TOp.LValueOp (LByrefGet, v) -> destByrefTy g v.Type
| TOp.LValueOp (LGetAddr, v) -> mkByrefTy g v.Type | TOp.LValueOp (LAddrOf readonly, v) -> mkByrefTyWithFlag g readonly v.Type
| TOp.RefAddrGet -> (match tinst with [ty] -> mkByrefTy g ty | _ -> failwith "bad TOp.RefAddrGet node") | TOp.RefAddrGet readonly -> (match tinst with [ty] -> mkByrefTyWithFlag g readonly ty | _ -> failwith "bad TOp.RefAddrGet node")
| TOp.TraitCall (TTrait(_, _, _, _, ty, _)) -> GetFSharpViewOfReturnType g ty | TOp.TraitCall (TTrait(_, _, _, _, ty, _)) -> GetFSharpViewOfReturnType g ty
| TOp.Reraise -> (match tinst with [rtn_ty] -> rtn_ty | _ -> failwith "bad TOp.Reraise node") | TOp.Reraise -> (match tinst with [rtn_ty] -> rtn_ty | _ -> failwith "bad TOp.Reraise node")
| TOp.Goto _ | TOp.Label _ | TOp.Return -> | TOp.Goto _ | TOp.Label _ | TOp.Return ->
@ -5565,16 +5650,38 @@ let mkAndSimplifyMatch spBind exprm matchm ty tree targets =
// mkExprAddrOfExprAux // mkExprAddrOfExprAux
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
type Mutates = DefinitelyMutates | PossiblyMutates | NeverMutates type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates
exception DefensiveCopyWarning of string * range exception DefensiveCopyWarning of string * range
let isRecdOrStructTyReadOnly g ty = let isRecdOrStructTyconRefAssumedImmutable (g: TcGlobals) (tcref: TyconRef) =
tcref.CanDeref &&
not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) ||
tyconRefEq g tcref g.decimal_tcr ||
tyconRefEq g tcref g.date_tcr
let isRecdOrStructTyconRefReadOnly (g: TcGlobals) m (tcref: TyconRef) =
tcref.CanDeref &&
match tcref.TryIsReadOnly with
| Some res -> res
| None ->
let isImmutable = isRecdOrStructTyconRefAssumedImmutable g tcref
let hasAttrib = TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref
let res = isImmutable || hasAttrib
tcref.SetIsReadOnly res
res
let isRecdOrStructTyReadOnly (g: TcGlobals) m ty =
match tryDestAppTy g ty with match tryDestAppTy g ty with
| None -> false | None -> false
| Some tcref -> | Some tcref -> isRecdOrStructTyconRefReadOnly g m tcref
not (isRecdOrUnionOrStructTyconRefDefinitelyMutable g tcref) ||
tyconRefEq g tcref g.decimal_tcr ||
tyconRefEq g tcref g.date_tcr let CanTakeAddressOf g m typ mut =
match mut with
| NeverMutates -> true
| PossiblyMutates -> isRecdOrStructTyReadOnly g m typ
| DefinitelyMutates -> false
| AddressOfOp -> true // you can take the address but you might get a (readonly) inref<T> as a result
// We can take the address of values of struct type even if the value is immutable // We can take the address of values of struct type even if the value is immutable
// under certain conditions // under certain conditions
@ -5591,144 +5698,184 @@ let isRecdOrStructTyReadOnly g ty =
// //
// We only do this for true local or closure fields because we can't take addresses of immutable static // We only do this for true local or closure fields because we can't take addresses of immutable static
// fields across assemblies. // fields across assemblies.
let CanTakeAddressOfImmutableVal g (v:ValRef) mut = let CanTakeAddressOfImmutableVal (g: TcGlobals) m (vref:ValRef) mut =
// We can take the address of values of struct type if the operation doesn't mutate // We can take the address of values of struct type if the operation doesn't mutate
// and the value is a true local or closure field. // and the value is a true local or closure field.
not v.IsMutable && not vref.IsMutable &&
not v.IsMemberOrModuleBinding && not vref.IsMemberOrModuleBinding &&
(match mut with // Note: We can't add this:
| NeverMutates -> true // || valRefInThisAssembly g.compilingFslib vref
| PossiblyMutates -> isRecdOrStructTyReadOnly g v.Type // This is because we don't actually guarantee to generate static backing fields for all values like these, e.g. simple constants "let x = 1".
| DefinitelyMutates -> false) // We always generate a static property but there is no field to take an address of
CanTakeAddressOf g m vref.Type mut
let MustTakeAddressOfVal (g:TcGlobals) (v:ValRef) = let MustTakeAddressOfVal (g:TcGlobals) (vref:ValRef) =
v.IsMutable && vref.IsMutable &&
// We can only take the address of mutable values in the same assembly // We can only take the address of mutable values in the same assembly
valRefInThisAssembly g.compilingFslib v valRefInThisAssembly g.compilingFslib vref
let MustTakeAddressOfRecdField (rf: RecdField) = let MustTakeAddressOfByrefGet (g:TcGlobals) (vref:ValRef) =
isByrefTy g vref.Type && not (isInByrefTy g vref.Type)
let CanTakeAddressOfByrefGet (g:TcGlobals) (vref:ValRef) mut =
isInByrefTy g vref.Type &&
CanTakeAddressOf g vref.Range (destByrefTy g vref.Type) mut
let MustTakeAddressOfRecdField (rfref: RecdField) =
// Static mutable fields must be private, hence we don't have to take their address // Static mutable fields must be private, hence we don't have to take their address
not rf.IsStatic && not rfref.IsStatic &&
rf.IsMutable rfref.IsMutable
let MustTakeAddressOfRecdFieldRef (rfref: RecdFieldRef) = MustTakeAddressOfRecdField rfref.RecdField let MustTakeAddressOfRecdFieldRef (rfref: RecdFieldRef) = MustTakeAddressOfRecdField rfref.RecdField
let CanTakeAddressOfRecdFieldRef (g:TcGlobals) (rfref: RecdFieldRef) mut tinst = let CanTakeAddressOfRecdFieldRef (g:TcGlobals) m (rfref: RecdFieldRef) tinst mut =
mut <> DefinitelyMutates &&
// We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields
entityRefInThisAssembly g.compilingFslib rfref.TyconRef && entityRefInThisAssembly g.compilingFslib rfref.TyconRef &&
isRecdOrStructTyReadOnly g (actualTyOfRecdFieldRef rfref tinst) not rfref.RecdField.IsMutable &&
CanTakeAddressOf g m (actualTyOfRecdFieldRef rfref tinst) mut
let CanTakeAddressOfUnionFieldRef (g:TcGlobals) (uref: UnionCaseRef) mut tinst cidx = let CanTakeAddressOfUnionFieldRef (g:TcGlobals) m (uref: UnionCaseRef) cidx tinst mut =
mut <> DefinitelyMutates &&
// We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields
entityRefInThisAssembly g.compilingFslib uref.TyconRef && entityRefInThisAssembly g.compilingFslib uref.TyconRef &&
isRecdOrStructTyReadOnly g (actualTyOfUnionFieldRef uref cidx tinst) let rfref = uref.FieldByIndex cidx
not rfref.IsMutable &&
CanTakeAddressOf g m (actualTyOfUnionFieldRef uref cidx tinst) mut
/// Make the address-of expression and return a wrapper that adds any allocated locals at an appropriate scope.
/// Also return a flag that indicates if the resulting pointer is a not a pointer where writing is allowed and will
/// have intended effect (i.e. is a readonly pointer and/or a defensive copy).
let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut expr addrExprVal m =
if mustTakeAddress then
match expr with
// LVALUE of "*x" where "x" is byref is just the byref itself
| Expr.Op (TOp.LValueOp (LByrefGet, vref), _, [], m) when MustTakeAddressOfByrefGet g vref || CanTakeAddressOfByrefGet g vref mut ->
let readonly = not (MustTakeAddressOfByrefGet g vref)
None, exprForValRef m vref, readonly
let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m = // LVALUE of "x" where "x" is mutable local, mutable intra-assembly module/static binding, or operation doesn't mutate.
if not mustTakeAddress then None, e else // Note: we can always take the address of mutable intra-assembly values
match e with | Expr.Val(vref, _, m) when MustTakeAddressOfVal g vref || CanTakeAddressOfImmutableVal g m vref mut ->
// LVALUE: "x" where "x" is byref let readonly = not (MustTakeAddressOfVal g vref)
| Expr.Op (TOp.LValueOp (LByrefGet, v), _, [], m) -> None, mkValAddr m readonly vref, readonly
None, exprForValRef m v
// LVALUE: "x" where "x" is mutable local, mutable intra-assembly module/static binding, or operation doesn't mutate
// Note: we can always take the address of mutable values
| Expr.Val(v, _, m) when MustTakeAddressOfVal g v || CanTakeAddressOfImmutableVal g v mut ->
None, mkValAddr m v
// LVALUE: "x" where "e.x" is record field.
| Expr.Op (TOp.ValFieldGet rfref, tinst, [e], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g rfref mut tinst ->
let exprty = tyOfExpr g e
let wrap, expra = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m
wrap, mkRecdFieldGetAddrViaExprAddr(expra, rfref, tinst, m)
// LVALUE: "x" where "e.x" is union field
| Expr.Op (TOp.UnionCaseFieldGet (uref, cidx), tinst, [e], m) when MustTakeAddressOfRecdField (uref.FieldByIndex(cidx)) || CanTakeAddressOfUnionFieldRef g uref mut tinst cidx ->
let exprty = tyOfExpr g e
let wrap, expra = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m
wrap, mkUnionCaseFieldGetAddrProvenViaExprAddr(expra, uref, tinst, cidx, m)
// LVALUE: "x" where "e.x" is a .NET static field. // LVALUE of "e.f" where "f" is record field.
| Expr.Op (TOp.ILAsm ([IL.I_ldsfld(_vol, fspec)], [ty2]), tinst, [], m) -> | Expr.Op (TOp.ValFieldGet rfref, tinst, [obje], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref tinst mut ->
None, Expr.Op (TOp.ILAsm ([IL.I_ldsflda(fspec)], [mkByrefTy g ty2]), tinst, [], m) let exprty = tyOfExpr g obje
let wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut obje None m
let readonly = readonly || not (MustTakeAddressOfRecdFieldRef rfref)
wrap, mkRecdFieldGetAddrViaExprAddr(readonly, expra, rfref, tinst, m), readonly
// LVALUE: "x" where "e.x" is a .NET instance field. "e" may be an lvalue // LVALUE of "e.f" where "f" is union field.
| Expr.Op (TOp.ILAsm ([IL.I_ldfld(_align, _vol, fspec)], [ty2]), tinst, [e], m) | Expr.Op (TOp.UnionCaseFieldGet (uref, cidx), tinst, [obje], m) when MustTakeAddressOfRecdField (uref.FieldByIndex(cidx)) || CanTakeAddressOfUnionFieldRef g m uref cidx tinst mut ->
-> let exprty = tyOfExpr g obje
let exprty = tyOfExpr g e let wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut obje None m
let wrap, expra = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m let readonly = readonly || not (MustTakeAddressOfRecdField (uref.FieldByIndex(cidx)))
wrap, Expr.Op (TOp.ILAsm ([IL.I_ldflda(fspec)], [mkByrefTy g ty2]), tinst, [expra], m) wrap, mkUnionCaseFieldGetAddrProvenViaExprAddr(readonly, expra, uref, tinst, cidx, m), readonly
// LVALUE: "x" where "x" is mutable static field. // LVALUE of "f" where "f" is a .NET static field.
| Expr.Op (TOp.ValFieldGet rfref, tinst, [], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g rfref mut tinst -> | Expr.Op (TOp.ILAsm ([IL.I_ldsfld(_vol, fspec)], [ty2]), tinst, [], m) ->
None, mkStaticRecdFieldGetAddr(rfref, tinst, m) let readonly = false // we never consider taking the address of a .NET static field to give an inref pointer
None, Expr.Op (TOp.ILAsm ([IL.I_ldsflda(fspec)], [mkByrefTy g ty2]), tinst, [], m), readonly
// LVALUE: "e.[n]" where e is an array of structs // LVALUE of "e.f" where "f" is a .NET instance field.
| Expr.App(Expr.Val(vf, _, _), _, [elemTy], [aexpr;nexpr], _) | Expr.Op (TOp.ILAsm ([IL.I_ldfld(_align, _vol, fspec)], [ty2]), tinst, [obje], m) ->
when (valRefEq g vf g.array_get_vref) -> let exprty = tyOfExpr g obje
// we never consider taking the address of an .NET instance field to give an inref pointer, unless the object pointer is an inref pointer
let wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut obje None m
wrap, Expr.Op (TOp.ILAsm ([IL.I_ldflda(fspec)], [mkByrefTyWithFlag g readonly ty2]), tinst, [expra], m), readonly
// LVALUE of "f" where "f" is a static F# field.
| Expr.Op (TOp.ValFieldGet rfref, tinst, [], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref tinst mut ->
let readonly = not (MustTakeAddressOfRecdFieldRef rfref)
None, mkStaticRecdFieldGetAddr(readonly, rfref, tinst, m), readonly
// LVALUE of "e.[n]" where e is an array of structs
| Expr.App(Expr.Val(vf, _, _), _, [elemTy], [aexpr;nexpr], _) when (valRefEq g vf g.array_get_vref) ->
let shape = ILArrayShape.SingleDimensional let readonly = false // array address is never forced to be readonly
let readonly = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress let shape = ILArrayShape.SingleDimensional
let isNativePtr = let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress
match addrExprVal with let isNativePtr =
| Some(vf) -> valRefEq g vf g.addrof2_vref match addrExprVal with
| _ -> false | Some(vf) -> valRefEq g vf g.addrof2_vref
None, mkArrayElemAddress g (readonly, isNativePtr, shape, elemTy, aexpr, nexpr, m) | _ -> false
None, mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, [aexpr; nexpr], m), readonly
// LVALUE: "e.[n1, n2]", "e.[n1, n2, n3]", "e.[n1, n2, n3, n4]" where e is an array of structs // LVALUE of "e.[n1, n2]", "e.[n1, n2, n3]", "e.[n1, n2, n3, n4]" where e is an array of structs
| Expr.App(Expr.Val(vf, _, _), _, [elemTy], (aexpr::args), _) | Expr.App(Expr.Val(vref, _, _), _, [elemTy], (aexpr::args), _)
when (valRefEq g vf g.array2D_get_vref || valRefEq g vf g.array3D_get_vref || valRefEq g vf g.array4D_get_vref) -> when (valRefEq g vref g.array2D_get_vref || valRefEq g vref g.array3D_get_vref || valRefEq g vref g.array4D_get_vref) ->
let shape = ILArrayShape.FromRank args.Length let readonly = false // array address is never forced to be readonly
let readonly = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress let shape = ILArrayShape.FromRank args.Length
let isNativePtr = let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress
match addrExprVal with let isNativePtr =
| Some(vf) -> valRefEq g vf g.addrof2_vref match addrExprVal with
| _ -> false | Some(vf) -> valRefEq g vf g.addrof2_vref
| _ -> false
None, Expr.Op (TOp.ILAsm ([IL.I_ldelema(readonly, isNativePtr, shape, mkILTyvarTy 0us)], [mkByrefTy g elemTy]), [elemTy], (aexpr::args), m) None, mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, (aexpr::args), m), readonly
// Give a nice error message for DefinitelyMutates on immutable values, or mutable values in other assemblies // LVALUE: "&meth(args)" where meth has a byref or inref return. Includes "&span.[idx]".
| Expr.Val(v, _, m) when mut = DefinitelyMutates | Expr.Let(TBind(vref, e, _), Expr.Op(TOp.LValueOp (LByrefGet, vref2), _, _, _), _, _) when (valRefEq g (mkLocalValRef vref) vref2) && (MustTakeAddressOfByrefGet g vref2 || CanTakeAddressOfByrefGet g vref2 mut) ->
-> let readonly = isInByrefTy g (tyOfExpr g e)
if isByrefTy g v.Type then error(Error(FSComp.SR.tastUnexpectedByRef(), m)); None, e, readonly
if v.IsMutable then
error(Error(FSComp.SR.tastInvalidAddressOfMutableAcrossAssemblyBoundary(), m)); // Give a nice error message for address-of-byref
else | Expr.Val(vref, _, m) when isByrefTy g vref.Type ->
error(Error(FSComp.SR.tastValueMustBeMutable(), m)); error(Error(FSComp.SR.tastUnexpectedByRef(), m))
// Give a nice error message for DefinitelyMutates of address-of on mutable values in other assemblies
| Expr.Val(vref, _, m) when (mut = DefinitelyMutates || mut = AddressOfOp) && vref.IsMutable ->
error(Error(FSComp.SR.tastInvalidAddressOfMutableAcrossAssemblyBoundary(), m))
// Give a nice error message for AddressOfOp on immutable values
| Expr.Val _ when mut = AddressOfOp ->
error(Error(FSComp.SR.tastValueMustBeLocal(), m))
| _ -> // Give a nice error message for mutating a value we can't take the address of
let ty = tyOfExpr g e | Expr.Val _ when mut = DefinitelyMutates ->
if isStructTy g ty then error(Error(FSComp.SR.tastValueMustBeMutable(), m))
match mut with
| NeverMutates -> () | _ ->
| DefinitelyMutates -> let ty = tyOfExpr g expr
errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(), m)); if isStructTy g ty then
| PossiblyMutates -> match mut with
warning(DefensiveCopyWarning(FSComp.SR.tastValueHasBeenCopied(), m)); | NeverMutates -> ()
let tmp, _ = | AddressOfOp -> () // we get an inref
match mut with | DefinitelyMutates ->
| NeverMutates -> mkCompGenLocal m "copyOfStruct" ty // Give a nice error message for mutating something we can't take the address of
| _ -> mkMutableCompGenLocal m "copyOfStruct" ty errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(), m))
Some (tmp, e), (mkValAddr m (mkLocalValRef tmp)) | PossiblyMutates ->
// Warn on defensive copy of something we can't take the address of
warning(DefensiveCopyWarning(FSComp.SR.tastValueHasBeenCopied(), m))
// Take a defensive copy
let tmp, _ =
match mut with
| NeverMutates -> mkCompGenLocal m "copyOfStruct" ty
| _ -> mkMutableCompGenLocal m "copyOfStruct" ty
let readonly = true
Some (tmp, expr), (mkValAddr m readonly (mkLocalValRef tmp)), readonly
else
None, expr, false
let mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m = let mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m =
let optBind, addre = mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m let optBind, addre, readonly = mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m
match optBind with match optBind with
| None -> (fun x -> x), addre | None -> (fun x -> x), addre, readonly
| Some (tmp, rval) -> (fun x -> mkCompGenLet m tmp rval x), addre | Some (tmp, rval) -> (fun x -> mkCompGenLet m tmp rval x), addre, readonly
let mkTupleFieldGet g (tupInfo, e, tinst, i, m) = let mkTupleFieldGet g (tupInfo, e, tinst, i, m) =
let wrap, e' = mkExprAddrOfExpr g (evalTupInfoIsStruct tupInfo) false NeverMutates e None m let wrap, e', _readonly = mkExprAddrOfExpr g (evalTupInfoIsStruct tupInfo) false NeverMutates e None m
wrap (mkTupleFieldGetViaExprAddr(tupInfo, e', tinst, i, m)) wrap (mkTupleFieldGetViaExprAddr(tupInfo, e', tinst, i, m))
let mkRecdFieldGet g (e, fref:RecdFieldRef, tinst, m) = let mkRecdFieldGet g (e, fref:RecdFieldRef, tinst, m) =
assert (not (isByrefTy g (tyOfExpr g e))) assert (not (isByrefTy g (tyOfExpr g e)))
let wrap, e' = mkExprAddrOfExpr g fref.Tycon.IsStructOrEnumTycon false NeverMutates e None m let wrap, e', _readonly = mkExprAddrOfExpr g fref.Tycon.IsStructOrEnumTycon false NeverMutates e None m
wrap (mkRecdFieldGetViaExprAddr(e', fref, tinst, m)) wrap (mkRecdFieldGetViaExprAddr(e', fref, tinst, m))
let mkUnionCaseFieldGetUnproven g (e, cref:UnionCaseRef, tinst, j, m) = let mkUnionCaseFieldGetUnproven g (e, cref:UnionCaseRef, tinst, j, m) =
assert (not (isByrefTy g (tyOfExpr g e))) assert (not (isByrefTy g (tyOfExpr g e)))
let wrap, e' = mkExprAddrOfExpr g cref.Tycon.IsStructOrEnumTycon false NeverMutates e None m let wrap, e', _readonly = mkExprAddrOfExpr g cref.Tycon.IsStructOrEnumTycon false NeverMutates e None m
wrap (mkUnionCaseFieldGetUnprovenViaExprAddr (e', cref, tinst, j, m)) wrap (mkUnionCaseFieldGetUnprovenViaExprAddr (e', cref, tinst, j, m))

Просмотреть файл

@ -164,6 +164,9 @@ val isBeingGeneralized : Typar -> TypeScheme -> bool
val mkLazyAnd : TcGlobals -> range -> Expr -> Expr -> Expr val mkLazyAnd : TcGlobals -> range -> Expr -> Expr -> Expr
val mkLazyOr : TcGlobals -> range -> Expr -> Expr -> Expr val mkLazyOr : TcGlobals -> range -> Expr -> Expr -> Expr
val mkByrefTy : TcGlobals -> TType -> TType val mkByrefTy : TcGlobals -> TType -> TType
val mkByrefTyWithInference : TcGlobals -> TType -> TType -> TType
val mkInByrefTy : TcGlobals -> TType -> TType
val mkOutByrefTy : TcGlobals -> TType -> TType
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Make construction operations // Make construction operations
@ -182,12 +185,12 @@ val mkReraiseLibCall : TcGlobals -> TType -> range -> Expr
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
val mkTupleFieldGet : TcGlobals -> TupInfo * Expr * TypeInst * int * range -> Expr val mkTupleFieldGet : TcGlobals -> TupInfo * Expr * TypeInst * int * range -> Expr
val mkRecdFieldGetViaExprAddr : Expr * RecdFieldRef * TypeInst * range -> Expr val mkRecdFieldGetViaExprAddr : Expr * RecdFieldRef * TypeInst * range -> Expr
val mkRecdFieldGetAddrViaExprAddr : Expr * RecdFieldRef * TypeInst * range -> Expr val mkRecdFieldGetAddrViaExprAddr : readonly: bool * Expr * RecdFieldRef * TypeInst * range -> Expr
val mkStaticRecdFieldGet : RecdFieldRef * TypeInst * range -> Expr val mkStaticRecdFieldGet : RecdFieldRef * TypeInst * range -> Expr
val mkStaticRecdFieldSet : RecdFieldRef * TypeInst * Expr * range -> Expr val mkStaticRecdFieldSet : RecdFieldRef * TypeInst * Expr * range -> Expr
val mkStaticRecdFieldGetAddr : RecdFieldRef * TypeInst * range -> Expr val mkStaticRecdFieldGetAddr : readonly: bool * RecdFieldRef * TypeInst * range -> Expr
val mkRecdFieldSetViaExprAddr : Expr * RecdFieldRef * TypeInst * Expr * range -> Expr val mkRecdFieldSetViaExprAddr : Expr * RecdFieldRef * TypeInst * Expr * range -> Expr
val mkUnionCaseTagGetViaExprAddr : Expr * TyconRef * TypeInst * range -> Expr val mkUnionCaseTagGetViaExprAddr : Expr * TyconRef * TypeInst * range -> Expr
/// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions) /// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions)
@ -201,7 +204,7 @@ val mkUnionCaseFieldGetProvenViaExprAddr : Expr * UnionCaseRef * TypeInst * in
/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions, /// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions,
/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, /// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions,
/// the input should be the address of the expression. /// the input should be the address of the expression.
val mkUnionCaseFieldGetAddrProvenViaExprAddr : Expr * UnionCaseRef * TypeInst * int * range -> Expr val mkUnionCaseFieldGetAddrProvenViaExprAddr : readonly: bool * Expr * UnionCaseRef * TypeInst * int * range -> Expr
/// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions, /// Build a 'TOp.UnionCaseFieldGetAddr' expression for a field of a union when we've already determined the value to be a particular union case. For ref-unions,
/// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions, /// the input expression has 'TType_ucase', which is an F# compiler internal "type" corresponding to the union case. For struct-unions,
@ -219,7 +222,7 @@ val mkUnionCaseFieldGetUnproven : TcGlobals -> Expr * UnionCaseRef * TypeIn
val mkExnCaseFieldGet : Expr * TyconRef * int * range -> Expr val mkExnCaseFieldGet : Expr * TyconRef * int * range -> Expr
val mkExnCaseFieldSet : Expr * TyconRef * int * Expr * range -> Expr val mkExnCaseFieldSet : Expr * TyconRef * int * Expr * range -> Expr
val mkArrayElemAddress : TcGlobals -> ILReadonly * bool * ILArrayShape * TType * Expr * Expr * range -> Expr val mkArrayElemAddress : TcGlobals -> readonly: bool * ILReadonly * bool * ILArrayShape * TType * Expr list * range -> Expr
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Compiled view of tuples // Compiled view of tuples
@ -263,9 +266,9 @@ val convertToTypeWithMetadataIfPossible : TcGlobals -> TType -> TType
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
exception DefensiveCopyWarning of string * range exception DefensiveCopyWarning of string * range
type Mutates = DefinitelyMutates | PossiblyMutates | NeverMutates type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates
val mkExprAddrOfExprAux : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Val * Expr) option * Expr val mkExprAddrOfExprAux : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Val * Expr) option * Expr * bool
val mkExprAddrOfExpr : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Expr -> Expr) * Expr val mkExprAddrOfExpr : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Expr -> Expr) * Expr * bool
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Tables keyed on values and/or type parameters // Tables keyed on values and/or type parameters
@ -296,41 +299,64 @@ type ValHash<'T> =
/// Maps Val's to list of T based on stamp keys /// Maps Val's to list of T based on stamp keys
[<Struct; NoEquality; NoComparison>] [<Struct; NoEquality; NoComparison>]
type ValMultiMap<'T> = type ValMultiMap<'T> =
member ContainsKey : Val -> bool
member Find : Val -> 'T list member Find : Val -> 'T list
member Add : Val * 'T -> ValMultiMap<'T> member Add : Val * 'T -> ValMultiMap<'T>
member Remove : Val -> ValMultiMap<'T> member Remove : Val -> ValMultiMap<'T>
member Contents : StampMap<'T list> member Contents : StampMap<'T list>
static member Empty : ValMultiMap<'T> static member Empty : ValMultiMap<'T>
[<Sealed>] [<Sealed>]
/// Maps Typar to T based on stamp keys /// Maps Typar to T based on stamp keys
type TyparMap<'T> = type TyparMap<'T> =
member Item : Typar -> 'T with get member Item : Typar -> 'T with get
member ContainsKey : Typar -> bool member ContainsKey : Typar -> bool
member TryFind : Typar -> 'T option member TryFind : Typar -> 'T option
member Add : Typar * 'T -> TyparMap<'T> member Add : Typar * 'T -> TyparMap<'T>
static member Empty : TyparMap<'T> static member Empty : TyparMap<'T>
[<NoEquality; NoComparison;Sealed>] [<NoEquality; NoComparison;Sealed>]
/// Maps TyconRef to T based on stamp keys /// Maps TyconRef to T based on stamp keys
type TyconRefMap<'T> = type TyconRefMap<'T> =
member Item : TyconRef -> 'T with get member Item : TyconRef -> 'T with get
member TryFind : TyconRef -> 'T option member TryFind : TyconRef -> 'T option
member ContainsKey : TyconRef -> bool member ContainsKey : TyconRef -> bool
member Add : TyconRef -> 'T -> TyconRefMap<'T> member Add : TyconRef -> 'T -> TyconRefMap<'T>
member Remove : TyconRef -> TyconRefMap<'T> member Remove : TyconRef -> TyconRefMap<'T>
member IsEmpty : bool member IsEmpty : bool
static member Empty : TyconRefMap<'T> static member Empty : TyconRefMap<'T>
static member OfList : (TyconRef * 'T) list -> TyconRefMap<'T> static member OfList : (TyconRef * 'T) list -> TyconRefMap<'T>
/// Maps TyconRef to list of T based on stamp keys /// Maps TyconRef to list of T based on stamp keys
[<Struct; NoEquality; NoComparison>] [<Struct; NoEquality; NoComparison>]
type TyconRefMultiMap<'T> = type TyconRefMultiMap<'T> =
member Find : TyconRef -> 'T list
member Add : TyconRef * 'T -> TyconRefMultiMap<'T>
static member Empty : TyconRefMultiMap<'T>
static member OfList : (TyconRef * 'T) list -> TyconRefMultiMap<'T>
member Find : TyconRef -> 'T list
member Add : TyconRef * 'T -> TyconRefMultiMap<'T>
static member Empty : TyconRefMultiMap<'T>
static member OfList : (TyconRef * 'T) list -> TyconRefMultiMap<'T>
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Orderings on Tycon, Val, RecdFieldRef, Typar // Orderings on Tycon, Val, RecdFieldRef, Typar
@ -874,7 +900,7 @@ val mkAddrSet : range -> ValRef -> Expr -> Expr
/// *localv_ptr /// *localv_ptr
val mkAddrGet : range -> ValRef -> Expr val mkAddrGet : range -> ValRef -> Expr
/// &localv /// &localv
val mkValAddr : range -> ValRef -> Expr val mkValAddr : range -> readonly: bool -> ValRef -> Expr
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Note these take the address of the record expression if it is a struct, and // Note these take the address of the record expression if it is a struct, and
@ -978,6 +1004,7 @@ val ExprStats : Expr -> string
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
val mkNativePtrTy : TcGlobals -> TType -> TType val mkNativePtrTy : TcGlobals -> TType -> TType
val mkVoidPtrTy : TcGlobals -> TType
val mkArrayType : TcGlobals -> TType -> TType val mkArrayType : TcGlobals -> TType -> TType
val isOptionTy : TcGlobals -> TType -> bool val isOptionTy : TcGlobals -> TType -> bool
val destOptionTy : TcGlobals -> TType -> TType val destOptionTy : TcGlobals -> TType -> TType
@ -1095,10 +1122,13 @@ val TypeHasDefaultValue : TcGlobals -> range -> TType -> bool
val isAbstractTycon : Tycon -> bool val isAbstractTycon : Tycon -> bool
val isUnionCaseRefDefinitelyMutable : UnionCaseRef -> bool val isUnionCaseRefDefinitelyMutable : UnionCaseRef -> bool
val isRecdOrUnionOrStructTyconRefDefinitelyMutable : TcGlobals -> TyconRef -> bool val isRecdOrUnionOrStructTyconRefDefinitelyMutable : TyconRef -> bool
val isExnDefinitelyMutable : TyconRef -> bool val isExnDefinitelyMutable : TyconRef -> bool
val isUnionCaseFieldMutable : TcGlobals -> UnionCaseRef -> int -> bool val isUnionCaseFieldMutable : TcGlobals -> UnionCaseRef -> int -> bool
val isExnFieldMutable : TyconRef -> int -> bool val isExnFieldMutable : TyconRef -> int -> bool
val isRecdOrStructTyconRefReadOnly: TcGlobals -> range -> TyconRef -> bool
val isRecdOrStructTyconRefAssumedImmutable: TcGlobals -> TyconRef -> bool
val isRecdOrStructTyReadOnly: TcGlobals -> range -> TType -> bool
val useGenuineField : Tycon -> RecdField -> bool val useGenuineField : Tycon -> RecdField -> bool
val ComputeFieldName : Tycon -> RecdField -> string val ComputeFieldName : Tycon -> RecdField -> string
@ -1377,7 +1407,6 @@ val TryFindAttributeUsageAttribute : TcGlobals -> range -> TyconRef -> bool opti
val TryDecodeTypeProviderAssemblyAttr : ILGlobals -> ILAttribute -> string option val TryDecodeTypeProviderAssemblyAttr : ILGlobals -> ILAttribute -> string option
#endif #endif
val IsSignatureDataVersionAttr : ILAttribute -> bool val IsSignatureDataVersionAttr : ILAttribute -> bool
val ILThingHasExtensionAttribute : ILAttributes -> bool
val TryFindAutoOpenAttr : IL.ILGlobals -> ILAttribute -> string option val TryFindAutoOpenAttr : IL.ILGlobals -> ILAttribute -> string option
val TryFindInternalsVisibleToAttr : IL.ILGlobals -> ILAttribute -> string option val TryFindInternalsVisibleToAttr : IL.ILGlobals -> ILAttribute -> string option
val IsMatchingSignatureDataVersionAttr : IL.ILGlobals -> ILVersionInfo -> ILAttribute -> bool val IsMatchingSignatureDataVersionAttr : IL.ILGlobals -> ILVersionInfo -> ILAttribute -> bool
@ -1396,13 +1425,17 @@ val mkCompilerGeneratedAttr : TcGlobals -> int -> ILAtt
// More common type construction // More common type construction
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
val isInByrefTy : TcGlobals -> TType -> bool
val isOutByrefTy : TcGlobals -> TType -> bool
val isByrefTy : TcGlobals -> TType -> bool val isByrefTy : TcGlobals -> TType -> bool
val isNativePtrTy : TcGlobals -> TType -> bool val isNativePtrTy : TcGlobals -> TType -> bool
val destByrefTy : TcGlobals -> TType -> TType val destByrefTy : TcGlobals -> TType -> TType
val destNativePtrTy : TcGlobals -> TType -> TType val destNativePtrTy : TcGlobals -> TType -> TType
val isByrefLikeTyconRef : TcGlobals -> TyconRef -> bool val isByrefTyconRef : TcGlobals -> TyconRef -> bool
val isByrefLikeTy : TcGlobals -> TType -> bool val isByrefLikeTyconRef : TcGlobals -> range -> TyconRef -> bool
val isByrefLikeTy : TcGlobals -> range -> TType -> bool
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Tuple constructors/destructors // Tuple constructors/destructors

Просмотреть файл

@ -2221,7 +2221,7 @@ and p_target (TTarget(a,b,_)) st = p_tup2 p_Vals p_expr (a,b) st
and p_bind (TBind(a,b,_)) st = p_tup2 p_Val p_expr (a,b) st and p_bind (TBind(a,b,_)) st = p_tup2 p_Val p_expr (a,b) st
and p_lval_op_kind x st = and p_lval_op_kind x st =
p_byte (match x with LGetAddr -> 0 | LByrefGet -> 1 | LSet -> 2 | LByrefSet -> 3) st p_byte (match x with LAddrOf _ -> 0 | LByrefGet -> 1 | LSet -> 2 | LByrefSet -> 3) st
and p_recdInfo x st = and p_recdInfo x st =
match x with match x with
@ -2254,7 +2254,7 @@ and u_bind st = let a = u_Val st in let b = u_expr st in TBind(a,b,NoSequencePoi
and u_lval_op_kind st = and u_lval_op_kind st =
match u_byte st with match u_byte st with
| 0 -> LGetAddr | 0 -> LAddrOf false
| 1 -> LByrefGet | 1 -> LByrefGet
| 2 -> LSet | 2 -> LSet
| 3 -> LByrefSet | 3 -> LByrefSet
@ -2283,8 +2283,8 @@ and p_op x st =
p_byte 30 st; p_int a st p_byte 30 st; p_int a st
else else
p_byte 11 st; p_int a st p_byte 11 st; p_int a st
| TOp.ILAsm (a,b) -> p_byte 12 st; p_tup2 (p_list p_ILInstr) p_typs (a,b) st | TOp.ILAsm (a,b) -> p_byte 12 st; p_tup2 (p_list p_ILInstr) p_typs (a,b) st
| TOp.RefAddrGet -> p_byte 13 st | TOp.RefAddrGet _ -> p_byte 13 st
| TOp.UnionCaseProof (a) -> p_byte 14 st; p_ucref a st | TOp.UnionCaseProof (a) -> p_byte 14 st; p_ucref a st
| TOp.Coerce -> p_byte 15 st | TOp.Coerce -> p_byte 15 st
| TOp.TraitCall (b) -> p_byte 16 st; p_trait b st | TOp.TraitCall (b) -> p_byte 16 st; p_trait b st
@ -2297,10 +2297,10 @@ and p_op x st =
| TOp.Bytes bytes -> p_byte 22 st; p_bytes bytes st | TOp.Bytes bytes -> p_byte 22 st; p_bytes bytes st
| TOp.TryCatch _ -> p_byte 23 st | TOp.TryCatch _ -> p_byte 23 st
| TOp.TryFinally _ -> p_byte 24 st | TOp.TryFinally _ -> p_byte 24 st
| TOp.ValFieldGetAddr (a) -> p_byte 25 st; p_rfref a st | TOp.ValFieldGetAddr (a, _) -> p_byte 25 st; p_rfref a st
| TOp.UInt16s arr -> p_byte 26 st; p_array p_uint16 arr st | TOp.UInt16s arr -> p_byte 26 st; p_array p_uint16 arr st
| TOp.Reraise -> p_byte 27 st | TOp.Reraise -> p_byte 27 st
| TOp.UnionCaseFieldGetAddr (a,b) -> p_byte 28 st; p_tup2 p_ucref p_int (a,b) st | TOp.UnionCaseFieldGetAddr (a,b, _) -> p_byte 28 st; p_tup2 p_ucref p_int (a,b) st
// Note tag byte 29 is taken for struct tuples, see above // Note tag byte 29 is taken for struct tuples, see above
// Note tag byte 30 is taken for struct tuples, see above // Note tag byte 30 is taken for struct tuples, see above
| TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST" | TOp.Goto _ | TOp.Label _ | TOp.Return -> failwith "unexpected backend construct in pickled TAST"
@ -2338,7 +2338,7 @@ and u_op st =
| 12 -> let a = (u_list u_ILInstr) st | 12 -> let a = (u_list u_ILInstr) st
let b = u_typs st let b = u_typs st
TOp.ILAsm (a,b) TOp.ILAsm (a,b)
| 13 -> TOp.RefAddrGet | 13 -> TOp.RefAddrGet false // ok to set the 'readonly' flag on these operands to false on re-read since the flag is only used for typechecking purposes
| 14 -> let a = u_ucref st | 14 -> let a = u_ucref st
TOp.UnionCaseProof a TOp.UnionCaseProof a
| 15 -> TOp.Coerce | 15 -> TOp.Coerce
@ -2360,12 +2360,12 @@ and u_op st =
| 23 -> TOp.TryCatch(NoSequencePointAtTry,NoSequencePointAtWith) | 23 -> TOp.TryCatch(NoSequencePointAtTry,NoSequencePointAtWith)
| 24 -> TOp.TryFinally(NoSequencePointAtTry,NoSequencePointAtFinally) | 24 -> TOp.TryFinally(NoSequencePointAtTry,NoSequencePointAtFinally)
| 25 -> let a = u_rfref st | 25 -> let a = u_rfref st
TOp.ValFieldGetAddr a TOp.ValFieldGetAddr (a, false)
| 26 -> TOp.UInt16s (u_array u_uint16 st) | 26 -> TOp.UInt16s (u_array u_uint16 st)
| 27 -> TOp.Reraise | 27 -> TOp.Reraise
| 28 -> let a = u_ucref st | 28 -> let a = u_ucref st
let b = u_int st let b = u_int st
TOp.UnionCaseFieldGetAddr (a,b) TOp.UnionCaseFieldGetAddr (a,b, false)
| 29 -> TOp.Tuple tupInfoStruct | 29 -> TOp.Tuple tupInfoStruct
| 30 -> let a = u_int st | 30 -> let a = u_int st
TOp.TupleFieldGet (tupInfoStruct, a) TOp.TupleFieldGet (tupInfoStruct, a)
@ -2523,7 +2523,7 @@ let _ = fill_u_Vals (u_list u_Val)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
let pickleModuleOrNamespace mspec st = p_tycon_spec mspec st let pickleModuleOrNamespace mspec st = p_tycon_spec mspec st
let pickleCcuInfo minfo st = let pickleCcuInfo (minfo: PickledCcuInfo) st =
p_tup4 pickleModuleOrNamespace p_string p_bool (p_space 3) (minfo.mspec, minfo.compileTimeWorkingDir, minfo.usesQuotations,()) st p_tup4 pickleModuleOrNamespace p_string p_bool (p_space 3) (minfo.mspec, minfo.compileTimeWorkingDir, minfo.usesQuotations,()) st
let unpickleModuleOrNamespace st = u_tycon_spec st let unpickleModuleOrNamespace st = u_tycon_spec st

Просмотреть файл

@ -8,7 +8,9 @@
/// comparison and hashing functions. /// comparison and hashing functions.
module internal Microsoft.FSharp.Compiler.TcGlobals module internal Microsoft.FSharp.Compiler.TcGlobals
open Internal.Utilities open System.Collections.Generic
open System.Diagnostics
open Microsoft.FSharp.Compiler open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.AbstractIL open Microsoft.FSharp.Compiler.AbstractIL
open Microsoft.FSharp.Compiler.AbstractIL.IL open Microsoft.FSharp.Compiler.AbstractIL.IL
@ -21,13 +23,25 @@ open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.Lib open Microsoft.FSharp.Compiler.Lib
open Microsoft.FSharp.Compiler.PrettyNaming open Microsoft.FSharp.Compiler.PrettyNaming
open System.Collections.Generic open Internal.Utilities
let internal DummyFileNameForRangesWithoutASpecificLocation = "startup" let internal DummyFileNameForRangesWithoutASpecificLocation = "startup"
let private envRange = rangeN DummyFileNameForRangesWithoutASpecificLocation 0 let private envRange = rangeN DummyFileNameForRangesWithoutASpecificLocation 0
type public IntrinsicValRef = IntrinsicValRef of NonLocalEntityRef * string * bool * TType * ValLinkageFullKey /// Represents an intrinsic value from FSharp.Core known to the compiler
[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
type IntrinsicValRef =
| IntrinsicValRef of NonLocalEntityRef * string * bool * TType * ValLinkageFullKey
member x.Name = (let (IntrinsicValRef(_, nm, _, _, _)) = x in nm)
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
/// For debugging
override x.ToString() = x.Name
let ValRefForIntrinsic (IntrinsicValRef(mvr, _, _, _, key)) = mkNonLocalValRef mvr key let ValRefForIntrinsic (IntrinsicValRef(mvr, _, _, _, key)) = mkNonLocalValRef mvr key
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -37,7 +51,6 @@ let ValRefForIntrinsic (IntrinsicValRef(mvr, _, _, _, key)) = mkNonLocalValRef
[<AutoOpen>] [<AutoOpen>]
module FSharpLib = module FSharpLib =
let CoreOperatorsName = FSharpLib.Root + ".Core.Operators"
let CoreOperatorsCheckedName = FSharpLib.Root + ".Core.Operators.Checked" let CoreOperatorsCheckedName = FSharpLib.Root + ".Core.Operators.Checked"
let ControlName = FSharpLib.Root + ".Control" let ControlName = FSharpLib.Root + ".Control"
let LinqName = FSharpLib.Root + ".Linq" let LinqName = FSharpLib.Root + ".Linq"
@ -47,22 +60,18 @@ module FSharpLib =
let LinqRuntimeHelpersName = FSharpLib.Root + ".Linq.RuntimeHelpers" let LinqRuntimeHelpersName = FSharpLib.Root + ".Linq.RuntimeHelpers"
let RuntimeHelpersName = FSharpLib.Root + ".Core.CompilerServices.RuntimeHelpers" let RuntimeHelpersName = FSharpLib.Root + ".Core.CompilerServices.RuntimeHelpers"
let ExtraTopLevelOperatorsName = FSharpLib.Root + ".Core.ExtraTopLevelOperators" let ExtraTopLevelOperatorsName = FSharpLib.Root + ".Core.ExtraTopLevelOperators"
let HashCompareName = FSharpLib.Root + ".Core.LanguagePrimitives.HashCompare" let NativeInteropName = FSharpLib.Root + ".NativeInterop"
let QuotationsName = FSharpLib.Root + ".Quotations" let QuotationsName = FSharpLib.Root + ".Quotations"
let OperatorsPath = IL.splitNamespace CoreOperatorsName |> Array.ofList
let OperatorsCheckedPath = IL.splitNamespace CoreOperatorsCheckedName |> Array.ofList
let ControlPath = IL.splitNamespace ControlName let ControlPath = IL.splitNamespace ControlName
let LinqPath = IL.splitNamespace LinqName let LinqPath = IL.splitNamespace LinqName
let CollectionsPath = IL.splitNamespace CollectionsName let CollectionsPath = IL.splitNamespace CollectionsName
let LanguagePrimitivesPath = IL.splitNamespace LanguagePrimitivesName |> Array.ofList let NativeInteropPath = IL.splitNamespace NativeInteropName |> Array.ofList
let HashComparePath = IL.splitNamespace HashCompareName |> Array.ofList
let CompilerServicesPath = IL.splitNamespace CompilerServicesName |> Array.ofList let CompilerServicesPath = IL.splitNamespace CompilerServicesName |> Array.ofList
let LinqRuntimeHelpersPath = IL.splitNamespace LinqRuntimeHelpersName |> Array.ofList let LinqRuntimeHelpersPath = IL.splitNamespace LinqRuntimeHelpersName |> Array.ofList
let RuntimeHelpersPath = IL.splitNamespace RuntimeHelpersName |> Array.ofList let RuntimeHelpersPath = IL.splitNamespace RuntimeHelpersName |> Array.ofList
let QuotationsPath = IL.splitNamespace QuotationsName |> Array.ofList let QuotationsPath = IL.splitNamespace QuotationsName |> Array.ofList
let ExtraTopLevelOperatorsPath = IL.splitNamespace ExtraTopLevelOperatorsName |> Array.ofList
let RootPathArray = FSharpLib.RootPath |> Array.ofList let RootPathArray = FSharpLib.RootPath |> Array.ofList
let CorePathArray = FSharpLib.CorePath |> Array.ofList let CorePathArray = FSharpLib.CorePath |> Array.ofList
@ -87,11 +96,23 @@ let mk_MFRuntimeHelpers_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.Runtim
let mk_MFControl_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.ControlPathArray n let mk_MFControl_tcref ccu n = mkNonLocalTyconRef2 ccu FSharpLib.ControlPathArray n
type public BuiltinAttribInfo = type
[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
BuiltinAttribInfo =
| AttribInfo of ILTypeRef * TyconRef | AttribInfo of ILTypeRef * TyconRef
member this.TyconRef = let (AttribInfo(_, tcref)) = this in tcref member this.TyconRef = let (AttribInfo(_, tcref)) = this in tcref
member this.TypeRef = let (AttribInfo(tref, _)) = this in tref member this.TypeRef = let (AttribInfo(tref, _)) = this in tref
/// For debugging
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
member x.DebugText = x.ToString()
/// For debugging
override x.ToString() = x.TyconRef.ToString()
[<Literal>] [<Literal>]
let tname_DebuggerNonUserCodeAttribute = "System.Diagnostics.DebuggerNonUserCodeAttribute" let tname_DebuggerNonUserCodeAttribute = "System.Diagnostics.DebuggerNonUserCodeAttribute"
[<Literal>] [<Literal>]
@ -201,7 +222,11 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
let v_pint16_tcr = mk_MFCore_tcref fslibCcu "int16`1" let v_pint16_tcr = mk_MFCore_tcref fslibCcu "int16`1"
let v_pint64_tcr = mk_MFCore_tcref fslibCcu "int64`1" let v_pint64_tcr = mk_MFCore_tcref fslibCcu "int64`1"
let v_byref_tcr = mk_MFCore_tcref fslibCcu "byref`1" let v_byref_tcr = mk_MFCore_tcref fslibCcu "byref`1"
let v_byref2_tcr = mk_MFCore_tcref fslibCcu "byref`2"
let v_outref_tcr = mk_MFCore_tcref fslibCcu "outref`1"
let v_inref_tcr = mk_MFCore_tcref fslibCcu "inref`1"
let v_nativeptr_tcr = mk_MFCore_tcref fslibCcu "nativeptr`1" let v_nativeptr_tcr = mk_MFCore_tcref fslibCcu "nativeptr`1"
let v_voidptr_tcr = mk_MFCore_tcref fslibCcu "voidptr"
let v_ilsigptr_tcr = mk_MFCore_tcref fslibCcu "ilsigptr`1" let v_ilsigptr_tcr = mk_MFCore_tcref fslibCcu "ilsigptr`1"
let v_fastFunc_tcr = mk_MFCore_tcref fslibCcu "FSharpFunc`2" let v_fastFunc_tcr = mk_MFCore_tcref fslibCcu "FSharpFunc`2"
let v_refcell_tcr_canon = mk_MFCore_tcref fslibCcu "Ref`1" let v_refcell_tcr_canon = mk_MFCore_tcref fslibCcu "Ref`1"
@ -384,12 +409,14 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
let fslib_MFCompilerServices_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.CompilerServicesPath let fslib_MFCompilerServices_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.CompilerServicesPath
let fslib_MFLinqRuntimeHelpers_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.LinqRuntimeHelpersPath let fslib_MFLinqRuntimeHelpers_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.LinqRuntimeHelpersPath
let fslib_MFControl_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.ControlPathArray let fslib_MFControl_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.ControlPathArray
let fslib_MFNativeInterop_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.NativeInteropPath
let fslib_MFLanguagePrimitives_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "LanguagePrimitives" let fslib_MFLanguagePrimitives_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "LanguagePrimitives"
let fslib_MFIntrinsicOperators_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicOperators" let fslib_MFIntrinsicOperators_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicOperators"
let fslib_MFIntrinsicFunctions_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicFunctions" let fslib_MFIntrinsicFunctions_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicFunctions"
let fslib_MFHashCompare_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "HashCompare" let fslib_MFHashCompare_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "HashCompare"
let fslib_MFOperators_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "Operators" let fslib_MFOperators_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "Operators"
let fslib_MFByRefKinds_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "ByRefKinds"
let fslib_MFOperatorIntrinsics_nleref = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "OperatorIntrinsics" let fslib_MFOperatorIntrinsics_nleref = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "OperatorIntrinsics"
let fslib_MFOperatorsUnchecked_nleref = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "Unchecked" let fslib_MFOperatorsUnchecked_nleref = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "Unchecked"
let fslib_MFOperatorsChecked_nleref = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "Checked" let fslib_MFOperatorsChecked_nleref = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "Checked"
@ -408,6 +435,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
let fslib_MFSetModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "SetModule" let fslib_MFSetModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "SetModule"
let fslib_MFMapModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "MapModule" let fslib_MFMapModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "MapModule"
let fslib_MFStringModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "StringModule" let fslib_MFStringModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "StringModule"
let fslib_MFNativePtrModule_nleref = mkNestedNonLocalEntityRef fslib_MFNativeInterop_nleref "NativePtrModule"
let fslib_MFOptionModule_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "OptionModule" let fslib_MFOptionModule_nleref = mkNestedNonLocalEntityRef fslib_MFCore_nleref "OptionModule"
let fslib_MFRuntimeHelpers_nleref = mkNestedNonLocalEntityRef fslib_MFCompilerServices_nleref "RuntimeHelpers" let fslib_MFRuntimeHelpers_nleref = mkNestedNonLocalEntityRef fslib_MFCompilerServices_nleref "RuntimeHelpers"
let fslib_MFQuotations_nleref = mkNestedNonLocalEntityRef fslib_MF_nleref "Quotations" let fslib_MFQuotations_nleref = mkNestedNonLocalEntityRef fslib_MF_nleref "Quotations"
@ -471,6 +499,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
fslib_MFSetModule_nleref fslib_MFSetModule_nleref
fslib_MFMapModule_nleref fslib_MFMapModule_nleref
fslib_MFStringModule_nleref fslib_MFStringModule_nleref
fslib_MFNativePtrModule_nleref
fslib_MFOptionModule_nleref fslib_MFOptionModule_nleref
fslib_MFRuntimeHelpers_nleref ] do fslib_MFRuntimeHelpers_nleref ] do
@ -650,6 +679,8 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
let v_array3D_set_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "SetArray3D" , None , None , [vara], ([[mkArrayType 3 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [varaTy]], v_unit_ty)) let v_array3D_set_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "SetArray3D" , None , None , [vara], ([[mkArrayType 3 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [varaTy]], v_unit_ty))
let v_array4D_set_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "SetArray4D" , None , None , [vara], ([[mkArrayType 4 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [v_int_ty]; [varaTy]], v_unit_ty)) let v_array4D_set_info = makeIntrinsicValRef(fslib_MFIntrinsicFunctions_nleref, "SetArray4D" , None , None , [vara], ([[mkArrayType 4 varaTy];[v_int_ty]; [v_int_ty]; [v_int_ty]; [v_int_ty]; [varaTy]], v_unit_ty))
let v_nativeptr_tobyref_info = makeIntrinsicValRef(fslib_MFNativePtrModule_nleref, "toByRef" , None , Some "ToByRefInlined", [vara], ([[mkNativePtrTy varaTy]], mkByrefTy varaTy))
let v_seq_collect_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "collect" , None , Some "Collect", [vara;varb;varc], ([[varaTy --> varbTy]; [mkSeqTy varaTy]], mkSeqTy varcTy)) let v_seq_collect_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "collect" , None , Some "Collect", [vara;varb;varc], ([[varaTy --> varbTy]; [mkSeqTy varaTy]], mkSeqTy varcTy))
let v_seq_delay_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "delay" , None , Some "Delay" , [varb], ([[v_unit_ty --> mkSeqTy varbTy]], mkSeqTy varbTy)) let v_seq_delay_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "delay" , None , Some "Delay" , [varb], ([[v_unit_ty --> mkSeqTy varbTy]], mkSeqTy varbTy))
let v_seq_append_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "append" , None , Some "Append" , [varb], ([[mkSeqTy varbTy]; [mkSeqTy varbTy]], mkSeqTy varbTy)) let v_seq_append_info = makeIntrinsicValRef(fslib_MFSeqModule_nleref, "append" , None , Some "Append" , [varb], ([[mkSeqTy varbTy]; [mkSeqTy varbTy]], mkSeqTy varbTy))
@ -915,7 +946,11 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
member __.pint16_tcr = v_pint16_tcr member __.pint16_tcr = v_pint16_tcr
member __.pint64_tcr = v_pint64_tcr member __.pint64_tcr = v_pint64_tcr
member __.byref_tcr = v_byref_tcr member __.byref_tcr = v_byref_tcr
member __.byref2_tcr = v_byref2_tcr
member __.outref_tcr = v_outref_tcr
member __.inref_tcr = v_inref_tcr
member __.nativeptr_tcr = v_nativeptr_tcr member __.nativeptr_tcr = v_nativeptr_tcr
member __.voidptr_tcr = v_voidptr_tcr
member __.ilsigptr_tcr = v_ilsigptr_tcr member __.ilsigptr_tcr = v_ilsigptr_tcr
member __.fastFunc_tcr = v_fastFunc_tcr member __.fastFunc_tcr = v_fastFunc_tcr
member __.tcref_IQueryable = v_tcref_IQueryable member __.tcref_IQueryable = v_tcref_IQueryable
@ -925,6 +960,9 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
member __.fslib_IDelegateEvent_tcr = v_fslib_IDelegateEvent_tcr member __.fslib_IDelegateEvent_tcr = v_fslib_IDelegateEvent_tcr
member __.seq_tcr = v_seq_tcr member __.seq_tcr = v_seq_tcr
member val seq_base_tcr = mk_MFCompilerServices_tcref fslibCcu "GeneratedSequenceBase`1" member val seq_base_tcr = mk_MFCompilerServices_tcref fslibCcu "GeneratedSequenceBase`1"
member val byrefkind_In_tcr = mkNonLocalTyconRef fslib_MFByRefKinds_nleref "In"
member val byrefkind_Out_tcr = mkNonLocalTyconRef fslib_MFByRefKinds_nleref "Out"
member val byrefkind_InOut_tcr = mkNonLocalTyconRef fslib_MFByRefKinds_nleref "InOut"
member val measureproduct_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureProduct`2" member val measureproduct_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureProduct`2"
member val measureinverse_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureInverse`1" member val measureinverse_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureInverse`1"
member val measureone_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureOne" member val measureone_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureOne"
@ -1073,6 +1111,11 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
member val attrib_ParamArrayAttribute = findSysAttrib "System.ParamArrayAttribute" member val attrib_ParamArrayAttribute = findSysAttrib "System.ParamArrayAttribute"
member val attrib_IDispatchConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IDispatchConstantAttribute" member val attrib_IDispatchConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IDispatchConstantAttribute"
member val attrib_IUnknownConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IUnknownConstantAttribute" member val attrib_IUnknownConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IUnknownConstantAttribute"
// We use 'findSysAttrib' here because lookup on attribute is done by name comparison, and can proceed
// even if the type is not found in a system assembly.
member val attrib_IsByRefLikeAttribute = findSysAttrib "System.Runtime.CompilerServices.IsByRefLikeAttribute"
member val attrib_IsReadOnlyAttribute = findSysAttrib "System.Runtime.CompilerServices.IsReadOnlyAttribute"
member val attrib_SystemObsolete = findSysAttrib "System.ObsoleteAttribute" member val attrib_SystemObsolete = findSysAttrib "System.ObsoleteAttribute"
member val attrib_DllImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DllImportAttribute" member val attrib_DllImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DllImportAttribute"
@ -1082,7 +1125,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
member val attrib_ComImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.ComImportAttribute" member val attrib_ComImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.ComImportAttribute"
member val attrib_FieldOffsetAttribute = findSysAttrib "System.Runtime.InteropServices.FieldOffsetAttribute" member val attrib_FieldOffsetAttribute = findSysAttrib "System.Runtime.InteropServices.FieldOffsetAttribute"
member val attrib_MarshalAsAttribute = tryFindSysAttrib "System.Runtime.InteropServices.MarshalAsAttribute" member val attrib_MarshalAsAttribute = tryFindSysAttrib "System.Runtime.InteropServices.MarshalAsAttribute"
member val attrib_InAttribute = tryFindSysAttrib "System.Runtime.InteropServices.InAttribute" member val attrib_InAttribute = findSysAttrib "System.Runtime.InteropServices.InAttribute"
member val attrib_OutAttribute = findSysAttrib "System.Runtime.InteropServices.OutAttribute" member val attrib_OutAttribute = findSysAttrib "System.Runtime.InteropServices.OutAttribute"
member val attrib_OptionalAttribute = tryFindSysAttrib "System.Runtime.InteropServices.OptionalAttribute" member val attrib_OptionalAttribute = tryFindSysAttrib "System.Runtime.InteropServices.OptionalAttribute"
member val attrib_DefaultParameterValueAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DefaultParameterValueAttribute" member val attrib_DefaultParameterValueAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DefaultParameterValueAttribute"
@ -1299,6 +1342,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
member val array4D_get_vref = ValRefForIntrinsic v_array4D_get_info member val array4D_get_vref = ValRefForIntrinsic v_array4D_get_info
member val seq_singleton_vref = ValRefForIntrinsic v_seq_singleton_info member val seq_singleton_vref = ValRefForIntrinsic v_seq_singleton_info
member val seq_collect_vref = ValRefForIntrinsic v_seq_collect_info member val seq_collect_vref = ValRefForIntrinsic v_seq_collect_info
member val nativeptr_tobyref_vref = ValRefForIntrinsic v_nativeptr_tobyref_info
member val seq_using_vref = ValRefForIntrinsic v_seq_using_info member val seq_using_vref = ValRefForIntrinsic v_seq_using_info
member val seq_delay_vref = ValRefForIntrinsic v_seq_delay_info member val seq_delay_vref = ValRefForIntrinsic v_seq_delay_info
member val seq_append_vref = ValRefForIntrinsic v_seq_append_info member val seq_append_vref = ValRefForIntrinsic v_seq_append_info

Просмотреть файл

@ -537,8 +537,8 @@ type cenv =
let CopyAndFixupTypars m rigid tpsorig = let CopyAndFixupTypars m rigid tpsorig =
ConstraintSolver.FreshenAndFixupTypars m rigid [] [] tpsorig ConstraintSolver.FreshenAndFixupTypars m rigid [] [] tpsorig
let UnifyTypes cenv (env: TcEnv) m expectedTy actualTy = let UnifyTypes cenv (env: TcEnv) m actualTy expectedTy =
ConstraintSolver.AddCxTypeEqualsType env.eContextInfo env.DisplayEnv cenv.css m (tryNormalizeMeasureInType cenv.g expectedTy) (tryNormalizeMeasureInType cenv.g actualTy) ConstraintSolver.AddCxTypeEqualsType env.eContextInfo env.DisplayEnv cenv.css m (tryNormalizeMeasureInType cenv.g actualTy) (tryNormalizeMeasureInType cenv.g expectedTy)
/// Make the initial type checking environment for a single file with an empty accumulator for the overall contents for the file /// Make the initial type checking environment for a single file with an empty accumulator for the overall contents for the file
let MakeInitialEnv env = let MakeInitialEnv env =
@ -864,7 +864,7 @@ let TcConst cenv ty m env c =
| SynMeasure.Anon _ -> error(Error(FSComp.SR.tcUnexpectedMeasureAnon(), m)) | SynMeasure.Anon _ -> error(Error(FSComp.SR.tcUnexpectedMeasureAnon(), m))
| SynMeasure.Var(_, m) -> error(Error(FSComp.SR.tcNonZeroConstantCannotHaveGenericUnit(), m)) | SynMeasure.Var(_, m) -> error(Error(FSComp.SR.tcNonZeroConstantCannotHaveGenericUnit(), m))
let unif ty2 = UnifyTypes cenv env m ty ty2 let unif expected = UnifyTypes cenv env m ty expected
let unifyMeasureArg iszero tcr c = let unifyMeasureArg iszero tcr c =
let measureTy = let measureTy =
@ -2100,32 +2100,37 @@ module GeneralizationHelpers =
let rec IsGeneralizableValue g t = let rec IsGeneralizableValue g t =
match t with match t with
| Expr.Lambda _ | Expr.TyLambda _ | Expr.Const _ | Expr.Val _ -> true | Expr.Lambda _ | Expr.TyLambda _ | Expr.Const _ -> true
// let f(x: byref<int>) = let v = &x in ... shouldn't generalize "v"
| Expr.Val (vref, _, m) -> not (isByrefLikeTy g m vref.Type)
// Look through coercion nodes corresponding to introduction of subsumption // Look through coercion nodes corresponding to introduction of subsumption
| Expr.Op(TOp.Coerce, [inputTy;actualTy], [e1], _) when isFunTy g actualTy && isFunTy g inputTy -> | Expr.Op(TOp.Coerce, [inputTy;actualTy], [e1], _) when isFunTy g actualTy && isFunTy g inputTy ->
IsGeneralizableValue g e1 IsGeneralizableValue g e1
| Expr.Op(op, _, args, _) -> | Expr.Op(op, _, args, _) ->
match op with
| TOp.Tuple _ -> true
| TOp.UnionCase uc -> not (isUnionCaseRefDefinitelyMutable uc)
| TOp.Recd(ctorInfo, tcref) ->
match ctorInfo with
| RecdExpr -> not (isRecdOrUnionOrStructTyconRefDefinitelyMutable g tcref)
| RecdExprIsObjInit -> false
| TOp.Array -> isNil args
| TOp.ExnConstr ec -> not (isExnDefinitelyMutable ec)
| TOp.ILAsm([], _) -> true let canGeneralizeOp =
match op with
| TOp.Tuple _ -> true
| TOp.UnionCase uc -> not (isUnionCaseRefDefinitelyMutable uc)
| TOp.Recd(ctorInfo, tcref) ->
match ctorInfo with
| RecdExpr -> not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref)
| RecdExprIsObjInit -> false
| TOp.Array -> isNil args
| TOp.ExnConstr ec -> not (isExnDefinitelyMutable ec)
| TOp.ILAsm([], _) -> true
| _ -> false
| _ -> false canGeneralizeOp && List.forall (IsGeneralizableValue g) args
&& List.forall (IsGeneralizableValue g) args
| Expr.LetRec(binds, body, _, _) -> | Expr.LetRec(binds, body, _, _) ->
binds |> List.forall (fun b -> not b.Var.IsMutable) && binds |> List.forall (fun b -> not b.Var.IsMutable) &&
binds |> List.forall (fun b -> IsGeneralizableValue g b.Expr) && binds |> List.forall (fun b -> IsGeneralizableValue g b.Expr) &&
IsGeneralizableValue g body IsGeneralizableValue g body
| Expr.Let(bind, body, _, _) -> | Expr.Let(bind, body, _, _) ->
not bind.Var.IsMutable && not bind.Var.IsMutable &&
IsGeneralizableValue g bind.Expr && IsGeneralizableValue g bind.Expr &&
@ -2639,7 +2644,10 @@ let FreshenObjectArgType cenv m rigid tcref isExtrinsic declaredTyconTypars =
// Struct members have a byref 'this' type (unless they are extrinsic extension members) // Struct members have a byref 'this' type (unless they are extrinsic extension members)
let thisTy = let thisTy =
if not isExtrinsic && tcref.IsStructOrEnumTycon then if not isExtrinsic && tcref.IsStructOrEnumTycon then
mkByrefTy cenv.g objTy if isRecdOrStructTyReadOnly cenv.g m objTy then
mkInByrefTy cenv.g objTy
else
mkByrefTy cenv.g objTy
else else
objTy objTy
tcrefObjTy, enclosingDeclaredTypars, renaming, objTy, thisTy tcrefObjTy, enclosingDeclaredTypars, renaming, objTy, thisTy
@ -3058,7 +3066,7 @@ let BuildILFieldGet g amap m objExpr (finfo:ILFieldInfo) =
Expr.Const(TcFieldInit m lit, m, fieldType) Expr.Const(TcFieldInit m lit, m, fieldType)
| _ -> | _ ->
#endif #endif
let wrap, objExpr = mkExprAddrOfExpr g isValueType false NeverMutates objExpr None m let wrap, objExpr, _readonly = mkExprAddrOfExpr g isValueType false NeverMutates objExpr None m
// The empty instantiation on the AbstractIL fspec is OK, since we make the correct fspec in IlxGen.GenAsm // The empty instantiation on the AbstractIL fspec is OK, since we make the correct fspec in IlxGen.GenAsm
// This ensures we always get the type instantiation right when doing this from // This ensures we always get the type instantiation right when doing this from
// polymorphic code, after inlining etc. * // polymorphic code, after inlining etc. *
@ -3076,7 +3084,7 @@ let BuildILFieldSet g m objExpr (finfo:ILFieldInfo) argExpr =
// polymorphic code, after inlining etc. * // polymorphic code, after inlining etc. *
let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef []) let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef [])
if finfo.IsInitOnly then error (Error (FSComp.SR.tcFieldIsReadonly(), m)) if finfo.IsInitOnly then error (Error (FSComp.SR.tcFieldIsReadonly(), m))
let wrap, objExpr = mkExprAddrOfExpr g isValueType false DefinitelyMutates objExpr None m let wrap, objExpr, _readonly = mkExprAddrOfExpr g isValueType false DefinitelyMutates objExpr None m
wrap (mkAsmExpr ([ mkNormalStfld fspec ], tinst, [objExpr; argExpr], [], m)) wrap (mkAsmExpr ([ mkNormalStfld fspec ], tinst, [objExpr; argExpr], [], m))
let BuildILStaticFieldSet m (finfo:ILFieldInfo) argExpr = let BuildILStaticFieldSet m (finfo:ILFieldInfo) argExpr =
@ -3095,7 +3103,7 @@ let BuildRecdFieldSet g m objExpr (rfinfo:RecdFieldInfo) argExpr =
let tgty = rfinfo.DeclaringType let tgty = rfinfo.DeclaringType
let valu = isStructTy g tgty let valu = isStructTy g tgty
let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgty, m, tyOfExpr g objExpr) let objExpr = if valu then objExpr else mkCoerceExpr(objExpr, tgty, m, tyOfExpr g objExpr)
let wrap, objExpr = mkExprAddrOfExpr g valu false DefinitelyMutates objExpr None m let wrap, objExpr, _readonly = mkExprAddrOfExpr g valu false DefinitelyMutates objExpr None m
wrap (mkRecdFieldSetViaExprAddr (objExpr, rfinfo.RecdFieldRef, rfinfo.TypeInst, argExpr, m) ) wrap (mkRecdFieldSetViaExprAddr (objExpr, rfinfo.RecdFieldRef, rfinfo.TypeInst, argExpr, m) )
@ -3952,30 +3960,75 @@ let CheckAndRewriteObjectCtor g env (ctorLambaExpr:Expr) =
/// Post-typechecking normalizations to enforce semantic constraints /// Post-typechecking normalizations to enforce semantic constraints
/// lazy and, lazy or, rethrow, address-of /// lazy and, lazy or, rethrow, address-of
let buildApp cenv expr exprty arg m = let buildApp cenv expr resultTy arg m =
let g = cenv.g let g = cenv.g
match expr, arg with match expr, arg with
// Special rule for building applications of the 'x && y' operator
| ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [x0], _), _) , _ | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [x0], _), _) , _
when valRefEq g vf g.and_vref when valRefEq g vf g.and_vref
|| valRefEq g vf g.and2_vref -> || valRefEq g vf g.and2_vref ->
MakeApplicableExprNoFlex cenv (mkLazyAnd g m x0 arg) MakeApplicableExprNoFlex cenv (mkLazyAnd g m x0 arg), resultTy
// Special rule for building applications of the 'x || y' operator
| ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [x0], _), _), _ | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [x0], _), _), _
when valRefEq g vf g.or_vref when valRefEq g vf g.or_vref
|| valRefEq g vf g.or2_vref -> || valRefEq g vf g.or2_vref ->
MakeApplicableExprNoFlex cenv (mkLazyOr g m x0 arg ) MakeApplicableExprNoFlex cenv (mkLazyOr g m x0 arg ), resultTy
// Special rule for building applications of the 'reraise' operator
| ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _
when valRefEq g vf g.reraise_vref -> when valRefEq g vf g.reraise_vref ->
// exprty is of type: "unit -> 'a". Break it and store the 'a type here, used later as return type. // exprty is of type: "unit -> 'a". Break it and store the 'a type here, used later as return type.
let _unit_ty, rtn_ty = destFunTy g exprty MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m resultTy)), resultTy
MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m rtn_ty))
// Special rules for NativePtr.ofByRef to generalize result.
// See RFC FS-1053.md
| ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _
when (valRefEq g vf g.addrof_vref || when (valRefEq g vf g.nativeptr_tobyref_vref) ->
valRefEq g vf g.addrof2_vref) ->
if valRefEq g vf g.addrof2_vref then warning(UseOfAddressOfOperator(m)) let argty = NewInferenceType()
let wrap, e1a' = mkExprAddrOfExpr g true false DefinitelyMutates arg (Some(vf)) m let resultTy = mkByrefTyWithInference g argty (NewByRefKindInferenceType g m)
MakeApplicableExprNoFlex cenv (wrap(e1a')) expr.SupplyArgument(arg, m), resultTy
// Special rules for building applications of the '&expr' operator, which gets the
// address of an expression.
//
// See also RFC FS-1053.md
| ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _
when valRefEq g vf g.addrof_vref ->
let wrap, e1a', readonly = mkExprAddrOfExpr g true false AddressOfOp arg (Some(vf)) m
// Assert the result type to be readonly if we couldn't take the address
let resultTy =
let argTy = tyOfExpr g arg
if readonly then
mkInByrefTy g argTy
else
mkByrefTyWithInference g argTy (NewByRefKindInferenceType g m)
MakeApplicableExprNoFlex cenv (wrap(e1a')), resultTy
// Special rules for building applications of the &&expr' operators, which gets the
// address of an expression.
| ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _
when valRefEq g vf g.addrof2_vref ->
warning(UseOfAddressOfOperator(m))
let wrap, e1a', _readonly = mkExprAddrOfExpr g true false AddressOfOp arg (Some(vf)) m
MakeApplicableExprNoFlex cenv (wrap(e1a')), resultTy
| _ when isByrefTy g resultTy ->
// Handle byref returns, byref-typed returns get implicitly dereferenced
let v, _ = mkCompGenLocal m "byrefReturn" resultTy
let expr = expr.SupplyArgument(arg, m)
let expr = mkCompGenLet m v expr.Expr (mkAddrGet m (mkLocalValRef v))
let resultTy = destByrefTy g resultTy
MakeApplicableExprNoFlex cenv expr, resultTy
| _ -> | _ ->
expr.SupplyArgument(arg, m) expr.SupplyArgument(arg, m), resultTy
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// Additional data structures used by type checking // Additional data structures used by type checking
@ -5959,6 +6012,10 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) =
let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId) let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId)
TcExprThen cenv overallTy env tpenv e1 [DelayedDotLookup(longId, mExprAndDotLookup); MakeDelayedSet(e2, mStmt)] TcExprThen cenv overallTy env tpenv e1 [DelayedDotLookup(longId, mExprAndDotLookup); MakeDelayedSet(e2, mStmt)]
/// e1 <- e2
| SynExpr.Set (e1, e2, mStmt) ->
TcExprThen cenv overallTy env tpenv e1 [MakeDelayedSet(e2, mStmt)]
/// e1.longId(e2) <- e3, very rarely used named property setters /// e1.longId(e2) <- e3, very rarely used named property setters
| SynExpr.DotNamedIndexedPropertySet (e1, (LongIdentWithDots(longId, _) as lidwd), e2, e3, mStmt) -> | SynExpr.DotNamedIndexedPropertySet (e1, (LongIdentWithDots(longId, _) as lidwd), e2, e3, mStmt) ->
if lidwd.ThereIsAnExtraDotAtTheEnd then if lidwd.ThereIsAnExtraDotAtTheEnd then
@ -6159,7 +6216,7 @@ and TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv wholeExpr e1 indexArg
let f, fty, tpenv = TcExprOfUnknownType cenv env tpenv operPath let f, fty, tpenv = TcExprOfUnknownType cenv env tpenv operPath
let domainTy, resultTy = UnifyFunctionType (Some mWholeExpr) cenv env.DisplayEnv mWholeExpr fty let domainTy, resultTy = UnifyFunctionType (Some mWholeExpr) cenv env.DisplayEnv mWholeExpr fty
UnifyTypes cenv env mWholeExpr domainTy e1ty UnifyTypes cenv env mWholeExpr domainTy e1ty
let f' = buildApp cenv (MakeApplicableExprNoFlex cenv f) fty e1' mWholeExpr let f', resultTy = buildApp cenv (MakeApplicableExprNoFlex cenv f) resultTy e1' mWholeExpr
let delayed = List.foldBack (fun idx acc -> DelayedApp(ExprAtomicFlag.Atomic, idx, mWholeExpr) :: acc) indexArgs delayed // atomic, otherwise no ar.[1] <- xyz let delayed = List.foldBack (fun idx acc -> DelayedApp(ExprAtomicFlag.Atomic, idx, mWholeExpr) :: acc) indexArgs delayed // atomic, otherwise no ar.[1] <- xyz
Some (PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr f' resultTy ExprAtomicFlag.Atomic delayed ) Some (PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr f' resultTy ExprAtomicFlag.Atomic delayed )
else None else None
@ -6292,7 +6349,7 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m =
match optOrigExpr with match optOrigExpr with
| None -> [], id | None -> [], id
| Some (_, _, oldve) -> | Some (_, _, oldve) ->
let wrap, oldveaddr = mkExprAddrOfExpr cenv.g tycon.IsStructOrEnumTycon false NeverMutates oldve None m let wrap, oldveaddr, _readonly = mkExprAddrOfExpr cenv.g tycon.IsStructOrEnumTycon false NeverMutates oldve None m
let fieldNameUnbound nom = List.forall (fun (name, _) -> name <> nom) fldsList let fieldNameUnbound nom = List.forall (fun (name, _) -> name <> nom) fldsList
let flds = let flds =
fspecs |> List.choose (fun rfld -> fspecs |> List.choose (fun rfld ->
@ -8264,24 +8321,50 @@ and TcSequenceExpression cenv env tpenv comp overallTy m =
/// of function application syntax unambiguously implies that 'overallTy' is a function type. /// of function application syntax unambiguously implies that 'overallTy' is a function type.
and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed =
let rec propagate delayedList mExpr exprty = let rec propagate isAddrOf delayedList mExpr exprty =
match delayedList with match delayedList with
| [] -> | [] ->
// Avoid unifying twice: we're about to unify in TcDelayed
if not (isNil delayed) then if not (isNil delayed) then
// We generate a tag inference parameter to the return type for "&x" and 'NativePtr.toByRef'
// See RFC FS-1053.md
let exprty =
if isAddrOf && isByrefTy cenv.g exprty then
mkByrefTyWithInference cenv.g (destByrefTy cenv.g exprty) (NewByRefKindInferenceType cenv.g mExpr)
elif isByrefTy cenv.g exprty then
// Implicit dereference on byref on return
if isByrefTy cenv.g overallTy then
errorR(Error(FSComp.SR.tcByrefReturnImplicitlyDereferenced(), mExpr))
destByrefTy cenv.g exprty
else
exprty
UnifyTypesAndRecover cenv env mExpr overallTy exprty UnifyTypesAndRecover cenv env mExpr overallTy exprty
| DelayedDot :: _ | DelayedDot :: _
| DelayedSet _ :: _ | DelayedSet _ :: _
| DelayedDotLookup _ :: _ -> () | DelayedDotLookup _ :: _ -> ()
| DelayedTypeApp (_, _mTypeArgs, mExprAndTypeArgs) :: delayedList' -> | DelayedTypeApp (_, _mTypeArgs, mExprAndTypeArgs) :: delayedList' ->
// Note this case should not occur: would eventually give an "Unexpected type application" error in TcDelayed // Note this case should not occur: would eventually give an "Unexpected type application" error in TcDelayed
propagate delayedList' mExprAndTypeArgs exprty propagate isAddrOf delayedList' mExprAndTypeArgs exprty
| DelayedApp (_, arg, mExprAndArg) :: delayedList' -> | DelayedApp (_, arg, mExprAndArg) :: delayedList' ->
let denv = env.DisplayEnv let denv = env.DisplayEnv
match UnifyFunctionTypeUndoIfFailed cenv denv mExpr exprty with match UnifyFunctionTypeUndoIfFailed cenv denv mExpr exprty with
| Some (_, resultTy) -> | Some (_, resultTy) ->
propagate delayedList' mExprAndArg resultTy
// We add tag parameter to the return type for "&x" and 'NativePtr.toByRef'
// See RFC FS-1053.md
let isAddrOf =
match expr with
| ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _)
when (valRefEq cenv.g vf cenv.g.addrof_vref ||
valRefEq cenv.g vf cenv.g.nativeptr_tobyref_vref) -> true
| _ -> false
propagate isAddrOf delayedList' mExprAndArg resultTy
| None -> | None ->
let mArg = arg.Range let mArg = arg.Range
match arg with match arg with
@ -8302,7 +8385,7 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed =
RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed
error (NotAFunction(denv, overallTy, mExpr, mArg)) error (NotAFunction(denv, overallTy, mExpr, mArg))
propagate delayed expr.Range exprty propagate false delayed expr.Range exprty
and PropagateThenTcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag:ExprAtomicFlag) delayed = and PropagateThenTcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag:ExprAtomicFlag) delayed =
Propagate cenv overallTy env tpenv expr exprty delayed Propagate cenv overallTy env tpenv expr exprty delayed
@ -8327,15 +8410,23 @@ and TcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag:ExprAtomicF
// expr.M<tyargs>(args) where x.M is a .NET method or index property // expr.M<tyargs>(args) where x.M is a .NET method or index property
// expr.M where x.M is a .NET method or index property // expr.M where x.M is a .NET method or index property
| DelayedDotLookup (longId, mDotLookup) :: otherDelayed -> | DelayedDotLookup (longId, mDotLookup) :: otherDelayed ->
TcLookupThen cenv overallTy env tpenv mExpr expr.Expr exprty longId otherDelayed mDotLookup TcLookupThen cenv overallTy env tpenv mExpr expr.Expr exprty longId otherDelayed mDotLookup
// f x // f x
| DelayedApp (hpa, arg, mExprAndArg) :: otherDelayed -> | DelayedApp (hpa, arg, mExprAndArg) :: otherDelayed ->
TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty arg hpa otherDelayed TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty arg hpa otherDelayed
// f<tyargs> // f<tyargs>
| DelayedTypeApp (_, mTypeArgs, _mExprAndTypeArgs) :: _ -> | DelayedTypeApp (_, mTypeArgs, _mExprAndTypeArgs) :: _ ->
error(Error(FSComp.SR.tcUnexpectedTypeArguments(), mTypeArgs)) error(Error(FSComp.SR.tcUnexpectedTypeArguments(), mTypeArgs))
| DelayedSet _ :: _ -> | DelayedSet (synExpr2, mStmt) :: otherDelayed ->
error(Error(FSComp.SR.tcInvalidAssignment(), mExpr)) if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mExpr))
UnifyTypes cenv env mExpr overallTy cenv.g.unit_ty
let expr = expr.Expr
let _wrap, exprAddress, _readonly = mkExprAddrOfExpr cenv.g true false DefinitelyMutates expr None mExpr
let vty = tyOfExpr cenv.g expr
// Always allow subsumption on assignment to fields
let expr2, tpenv = TcExprFlex cenv true vty env tpenv synExpr2
let v, _ve = mkCompGenLocal mExpr "addr" (mkByrefTy cenv.g vty)
mkCompGenLet mStmt v exprAddress (mkAddrSet mStmt (mkLocalValRef v) expr2), tpenv
/// Convert the delayed identifiers to a dot-lookup. /// Convert the delayed identifiers to a dot-lookup.
@ -8377,7 +8468,7 @@ and TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty (
| _ -> () | _ -> ()
let arg, tpenv = TcExpr cenv domainTy env tpenv synArg let arg, tpenv = TcExpr cenv domainTy env tpenv synArg
let exprAndArg = buildApp cenv expr exprty arg mExprAndArg let exprAndArg, resultTy = buildApp cenv expr resultTy arg mExprAndArg
TcDelayed cenv overallTy env tpenv mExprAndArg exprAndArg resultTy atomicFlag delayed TcDelayed cenv overallTy env tpenv mExprAndArg exprAndArg resultTy atomicFlag delayed
| None -> | None ->
// OK, 'expr' doesn't have function type, but perhaps 'expr' is a computation expression builder, and 'arg' is '{ ... }' // OK, 'expr' doesn't have function type, but perhaps 'expr' is a computation expression builder, and 'arg' is '{ ... }'
@ -8766,6 +8857,7 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del
| SynExpr.DotSet _ | SynExpr.DotSet _
| SynExpr.DotIndexedSet _ | SynExpr.DotIndexedSet _
| SynExpr.LongIdentSet _ | SynExpr.LongIdentSet _
| SynExpr.Set _
| SynExpr.JoinIn _ | SynExpr.JoinIn _
| SynExpr.NamedIndexedPropertySet _ | SynExpr.NamedIndexedPropertySet _
| SynExpr.DotNamedIndexedPropertySet _ | SynExpr.DotNamedIndexedPropertySet _
@ -8839,10 +8931,13 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del
// Always allow subsumption on assignment to fields // Always allow subsumption on assignment to fields
let e2', tpenv = TcExprFlex cenv true vty2 env tpenv e2 let e2', tpenv = TcExprFlex cenv true vty2 env tpenv e2
let vexp = let vexp =
if isByrefTy cenv.g vty then if isInByrefTy cenv.g vty then
mkAddrSet mStmt vref e2' errorR(Error(FSComp.SR.writeToReadOnlyByref(), mStmt))
mkAddrSet mStmt vref e2'
elif isByrefTy cenv.g vty then
mkAddrSet mStmt vref e2'
else else
mkValSet mStmt vref e2' mkValSet mStmt vref e2'
PropagateThenTcDelayed cenv overallTy env tpenv mStmt (MakeApplicableExprNoFlex cenv vexp) (tyOfExpr cenv.g vexp) ExprAtomicFlag.NonAtomic otherDelayed PropagateThenTcDelayed cenv overallTy env tpenv mStmt (MakeApplicableExprNoFlex cenv vexp) (tyOfExpr cenv.g vexp) ExprAtomicFlag.NonAtomic otherDelayed
@ -8877,14 +8972,24 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del
if not pinfo.IsStatic then error (Error (FSComp.SR.tcPropertyIsNotStatic(nm), mItem)) if not pinfo.IsStatic then error (Error (FSComp.SR.tcPropertyIsNotStatic(nm), mItem))
match delayed with match delayed with
| DelayedSet(e2, mStmt) :: otherDelayed -> | DelayedSet(e2, mStmt) :: otherDelayed ->
let args = if pinfo.IsIndexer then args else []
if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt))
// Static Property Set (possibly indexer) // Static Property Set (possibly indexer)
UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty
let meths = pinfos |> SettersOfPropInfos let meths = pinfos |> SettersOfPropInfos
if isNil meths then error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem)) if meths.IsEmpty then
// Note: static calls never mutate a struct object argument let meths = pinfos |> GettersOfPropInfos
TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mStmt mItem nm ad NeverMutates true meths afterResolution NormalValUse (args@[e2]) ExprAtomicFlag.NonAtomic otherDelayed let isByrefMethReturnSetter = meths |> List.exists (function (_,Some pinfo) -> isByrefTy cenv.g (pinfo.GetPropertyType(cenv.amap,mItem)) | _ -> false)
if isByrefMethReturnSetter then
// x.P <- ... byref setter
if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable(nm), mItem))
TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mItem mItem nm ad NeverMutates true meths afterResolution NormalValUse args ExprAtomicFlag.Atomic delayed
else
error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem))
else
let args = if pinfo.IsIndexer then args else []
if isNil meths then error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem))
// Note: static calls never mutate a struct object argument
TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt [] mStmt mItem nm ad NeverMutates true meths afterResolution NormalValUse (args@[e2]) ExprAtomicFlag.NonAtomic otherDelayed
| _ -> | _ ->
// Static Property Get (possibly indexer) // Static Property Get (possibly indexer)
let meths = pinfos |> GettersOfPropInfos let meths = pinfos |> GettersOfPropInfos
@ -9052,14 +9157,23 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela
match delayed with match delayed with
| DelayedSet(e2, mStmt) :: otherDelayed -> | DelayedSet(e2, mStmt) :: otherDelayed ->
let args = if pinfo.IsIndexer then args else []
if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt))
// Instance property setter // Instance property setter
UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty
let meths = SettersOfPropInfos pinfos let meths = SettersOfPropInfos pinfos
if isNil meths then error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem)) if meths.IsEmpty then
let mut = (if isStructTy cenv.g (tyOfExpr cenv.g objExpr) then DefinitelyMutates else PossiblyMutates) let meths = pinfos |> GettersOfPropInfos
TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mStmt mItem nm ad mut true meths afterResolution NormalValUse (args @ [e2]) atomicFlag [] let isByrefMethReturnSetter = meths |> List.exists (function (_,Some pinfo) -> isByrefTy cenv.g (pinfo.GetPropertyType(cenv.amap,mItem)) | _ -> false)
if isByrefMethReturnSetter then
// x.P <- ... byref setter
if isNil meths then error (Error (FSComp.SR.tcPropertyIsNotReadable(nm), mItem))
TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mExprAndItem mItem nm ad PossiblyMutates true meths afterResolution NormalValUse args atomicFlag delayed
else
error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem))
else
let args = if pinfo.IsIndexer then args else []
let mut = (if isStructTy cenv.g (tyOfExpr cenv.g objExpr) then DefinitelyMutates else PossiblyMutates)
TcMethodApplicationThen cenv env overallTy None tpenv tyargsOpt objArgs mStmt mItem nm ad mut true meths afterResolution NormalValUse (args @ [e2]) atomicFlag []
| _ -> | _ ->
// Instance property getter // Instance property getter
let meths = GettersOfPropInfos pinfos let meths = GettersOfPropInfos pinfos
@ -9213,7 +9327,7 @@ and TcMethodApplicationThen
and GetNewInferenceTypeForMethodArg cenv env tpenv x = and GetNewInferenceTypeForMethodArg cenv env tpenv x =
match x with match x with
| SynExprParen(a, _, _, _) -> GetNewInferenceTypeForMethodArg cenv env tpenv a | SynExprParen(a, _, _, _) -> GetNewInferenceTypeForMethodArg cenv env tpenv a
| SynExpr.AddressOf(true, a, _, _) -> mkByrefTy cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) | SynExpr.AddressOf(true, a, _, m) -> mkByrefTyWithInference cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) (NewByRefKindInferenceType cenv.g m)
| SynExpr.Lambda(_, _, _, a, _) -> mkFunTy (NewInferenceType ()) (GetNewInferenceTypeForMethodArg cenv env tpenv a) | SynExpr.Lambda(_, _, _, a, _) -> mkFunTy (NewInferenceType ()) (GetNewInferenceTypeForMethodArg cenv env tpenv a)
| SynExpr.Quote(_, raw, a, _, _) -> | SynExpr.Quote(_, raw, a, _, _) ->
if raw then mkRawQuotedExprTy cenv.g if raw then mkRawQuotedExprTy cenv.g
@ -9245,7 +9359,7 @@ and TcMethodApplication
let denv = env.DisplayEnv let denv = env.DisplayEnv
let isSimpleFormalArg (isParamArrayArg, isOutArg, optArgInfo: OptionalArgInfo, callerInfoInfo: CallerInfoInfo, _reflArgInfo: ReflectedArgInfo) = let isSimpleFormalArg (isParamArrayArg, _isInArg, isOutArg, optArgInfo: OptionalArgInfo, callerInfoInfo: CallerInfoInfo, _reflArgInfo: ReflectedArgInfo) =
not isParamArrayArg && not isOutArg && not optArgInfo.IsOptional && callerInfoInfo = NoCallerInfo not isParamArrayArg && not isOutArg && not optArgInfo.IsOptional && callerInfoInfo = NoCallerInfo
let callerObjArgTys = objArgs |> List.map (tyOfExpr cenv.g) let callerObjArgTys = objArgs |> List.map (tyOfExpr cenv.g)
@ -9367,7 +9481,7 @@ and TcMethodApplication
resultTy) resultTy)
curriedArgTys, returnTy curriedArgTys, returnTy
if isProp && Option.isNone curriedCallerArgsOpt then if isProp && Option.isNone curriedCallerArgsOpt then
error(Error(FSComp.SR.parsIndexerPropertyRequiresAtLeastOneArgument(), mItem)) error(Error(FSComp.SR.parsIndexerPropertyRequiresAtLeastOneArgument(), mItem))
// STEP 1. UnifyUniqueOverloading. This happens BEFORE we type check the arguments. // STEP 1. UnifyUniqueOverloading. This happens BEFORE we type check the arguments.
@ -9624,7 +9738,7 @@ and TcMethodApplication
if HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_Dictionary finalCalledMethInfo.ApparentEnclosingType && if HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_Dictionary finalCalledMethInfo.ApparentEnclosingType &&
finalCalledMethInfo.IsConstructor && finalCalledMethInfo.IsConstructor &&
not (finalCalledMethInfo.GetParamDatas(cenv.amap, mItem, finalCalledMeth.CalledTyArgs) not (finalCalledMethInfo.GetParamDatas(cenv.amap, mItem, finalCalledMeth.CalledTyArgs)
|> List.existsSquared (fun (ParamData(_, _, _, _, _, _, ty)) -> |> List.existsSquared (fun (ParamData(_, _, _, _, _, _, _, ty)) ->
HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_IEqualityComparer ty)) then HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_IEqualityComparer ty)) then
match argsOfAppTy cenv.g finalCalledMethInfo.ApparentEnclosingType with match argsOfAppTy cenv.g finalCalledMethInfo.ApparentEnclosingType with
@ -9659,53 +9773,65 @@ and TcMethodApplication
// Handle adhoc argument conversions // Handle adhoc argument conversions
let coerceExpr isOutArg calledArgTy (reflArgInfo: ReflectedArgInfo) callerArgTy m callerArgExpr = let coerceExpr isOutArg calledArgTy (reflArgInfo: ReflectedArgInfo) callerArgTy m callerArgExpr =
let g = cenv.g
if isByrefTy cenv.g calledArgTy && isRefCellTy cenv.g callerArgTy then if isByrefTy g calledArgTy && isRefCellTy g callerArgTy then
Expr.Op(TOp.RefAddrGet, [destRefCellTy cenv.g callerArgTy], [callerArgExpr], m) None, Expr.Op(TOp.RefAddrGet false, [destRefCellTy g callerArgTy], [callerArgExpr], m)
elif isInByrefTy g calledArgTy && not (isByrefTy cenv.g callerArgTy) then
let wrap, callerArgExprAddress, _readonly = mkExprAddrOfExpr g true false NeverMutates callerArgExpr None m
Some wrap, callerArgExprAddress
elif isDelegateTy cenv.g calledArgTy && isFunTy cenv.g callerArgTy then elif isDelegateTy cenv.g calledArgTy && isFunTy cenv.g callerArgTy then
CoerceFromFSharpFuncToDelegate cenv.g cenv.amap cenv.infoReader ad callerArgTy m callerArgExpr calledArgTy None, CoerceFromFSharpFuncToDelegate cenv.g cenv.amap cenv.infoReader ad callerArgTy m callerArgExpr calledArgTy
elif isLinqExpressionTy cenv.g calledArgTy && isDelegateTy cenv.g (destLinqExpressionTy cenv.g calledArgTy) && isFunTy cenv.g callerArgTy then elif isLinqExpressionTy cenv.g calledArgTy && isDelegateTy cenv.g (destLinqExpressionTy cenv.g calledArgTy) && isFunTy cenv.g callerArgTy then
let delegateTy = destLinqExpressionTy cenv.g calledArgTy let delegateTy = destLinqExpressionTy cenv.g calledArgTy
let expr = CoerceFromFSharpFuncToDelegate cenv.g cenv.amap cenv.infoReader ad callerArgTy m callerArgExpr delegateTy let expr = CoerceFromFSharpFuncToDelegate cenv.g cenv.amap cenv.infoReader ad callerArgTy m callerArgExpr delegateTy
mkCallQuoteToLinqLambdaExpression cenv.g m delegateTy (Expr.Quote(expr, ref None, false, m, mkQuotedExprTy cenv.g delegateTy)) None, mkCallQuoteToLinqLambdaExpression cenv.g m delegateTy (Expr.Quote(expr, ref None, false, m, mkQuotedExprTy cenv.g delegateTy))
// auto conversions to quotations (to match auto conversions to LINQ expressions) // auto conversions to quotations (to match auto conversions to LINQ expressions)
elif reflArgInfo.AutoQuote && isQuotedExprTy cenv.g calledArgTy && not (isQuotedExprTy cenv.g callerArgTy) then elif reflArgInfo.AutoQuote && isQuotedExprTy cenv.g calledArgTy && not (isQuotedExprTy cenv.g callerArgTy) then
match reflArgInfo with match reflArgInfo with
| ReflectedArgInfo.Quote true -> | ReflectedArgInfo.Quote true ->
mkCallLiftValueWithDefn cenv.g m calledArgTy callerArgExpr None, mkCallLiftValueWithDefn cenv.g m calledArgTy callerArgExpr
| ReflectedArgInfo.Quote false -> | ReflectedArgInfo.Quote false ->
Expr.Quote(callerArgExpr, ref None, false, m, calledArgTy) None, Expr.Quote(callerArgExpr, ref None, false, m, calledArgTy)
| ReflectedArgInfo.None -> failwith "unreachable" // unreachable due to reflArgInfo.AutoQuote condition | ReflectedArgInfo.None -> failwith "unreachable" // unreachable due to reflArgInfo.AutoQuote condition
// Note: out args do not need to be coerced // Note: out args do not need to be coerced
elif isOutArg then elif isOutArg then
callerArgExpr None, callerArgExpr
// Note: not all these casts are reported in quotations // Note: not all these casts are reported in quotations
else else
mkCoerceIfNeeded cenv.g calledArgTy callerArgTy callerArgExpr None, mkCoerceIfNeeded cenv.g calledArgTy callerArgTy callerArgExpr
// Handle optional arguments // Handle param array and optional arguments
let optArgPreBinder, allArgs, outArgExprs, outArgTmpBinds = let optArgPreBinder, paramArrayPreBinders, allArgs, outArgExprs, outArgTmpBinds =
let normalUnnamedArgs = let normalUnnamedArgs =
(finalUnnamedCalledArgs, finalUnnamedCallerArgs) ||> List.map2 (fun called caller -> { NamedArgIdOpt = None; CalledArg=called; CallerArg=caller }) (finalUnnamedCalledArgs, finalUnnamedCallerArgs) ||> List.map2 (fun called caller -> { NamedArgIdOpt = None; CalledArg=called; CallerArg=caller })
let paramArrayArgs = let paramArrayPreBinders, paramArrayArgs =
match finalCalledMeth.ParamArrayCalledArgOpt with match finalCalledMeth.ParamArrayCalledArgOpt with
| None -> [] | None ->
| Some paramArrayCalledArg -> [], []
let paramArrayCalledArgElementType = destArrayTy cenv.g paramArrayCalledArg.CalledArgumentType | Some paramArrayCalledArg ->
let paramArrayCalledArgElementType = destArrayTy cenv.g paramArrayCalledArg.CalledArgumentType
let es = let paramArrayPreBinders, es =
finalParamArrayCallerArgs |> List.map (fun callerArg -> finalParamArrayCallerArgs
let (CallerArg(callerArgTy, m, isOutArg, callerArgExpr)) = callerArg |> List.map (fun callerArg ->
coerceExpr isOutArg paramArrayCalledArgElementType paramArrayCalledArg.ReflArgInfo callerArgTy m callerArgExpr) let (CallerArg(callerArgTy, m, isOutArg, callerArgExpr)) = callerArg
coerceExpr isOutArg paramArrayCalledArgElementType paramArrayCalledArg.ReflArgInfo callerArgTy m callerArgExpr)
|> List.unzip
[ { NamedArgIdOpt = None; CalledArg=paramArrayCalledArg; CallerArg=CallerArg(paramArrayCalledArg.CalledArgumentType, mMethExpr, false, Expr.Op(TOp.Array, [paramArrayCalledArgElementType], es , mMethExpr)) } ] let arg =
[ { NamedArgIdOpt = None
CalledArg=paramArrayCalledArg
CallerArg=CallerArg(paramArrayCalledArg.CalledArgumentType, mMethExpr, false, Expr.Op(TOp.Array, [paramArrayCalledArgElementType], es , mMethExpr)) } ]
paramArrayPreBinders, arg
// CLEANUP: Move all this code into some isolated file, e.g. "optional.fs" // CLEANUP: Move all this code into some isolated file, e.g. "optional.fs"
// //
@ -9782,7 +9908,7 @@ and TcMethodApplication
| PassByRef (ty, dfltVal2) -> | PassByRef (ty, dfltVal2) ->
let v, _ = mkCompGenLocal mMethExpr "defaultByrefArg" ty let v, _ = mkCompGenLocal mMethExpr "defaultByrefArg" ty
let wrapper2, rhs = build currCalledArgTy dfltVal2 let wrapper2, rhs = build currCalledArgTy dfltVal2
(wrapper2 >> mkCompGenLet mMethExpr v rhs), mkValAddr mMethExpr (mkLocalValRef v) (wrapper2 >> mkCompGenLet mMethExpr v rhs), mkValAddr mMethExpr false (mkLocalValRef v)
build calledArgTy dfltVal build calledArgTy dfltVal
| CalleeSide -> | CalleeSide ->
let calledNonOptTy = let calledNonOptTy =
@ -9849,7 +9975,7 @@ and TcMethodApplication
let outArgTy = destByrefTy cenv.g calledArgTy let outArgTy = destByrefTy cenv.g calledArgTy
let outv, outArgExpr = mkMutableCompGenLocal mMethExpr "outArg" outArgTy // mutable! let outv, outArgExpr = mkMutableCompGenLocal mMethExpr "outArg" outArgTy // mutable!
let expr = mkDefault(mMethExpr, outArgTy) let expr = mkDefault(mMethExpr, outArgTy)
let callerArg = CallerArg(calledArgTy, mMethExpr, false, mkValAddr mMethExpr (mkLocalValRef outv)) let callerArg = CallerArg(calledArgTy, mMethExpr, false, mkValAddr mMethExpr false (mkLocalValRef outv))
let outArg = { NamedArgIdOpt=None;CalledArg=calledArg;CallerArg=callerArg } let outArg = { NamedArgIdOpt=None;CalledArg=calledArg;CallerArg=callerArg }
(outArg, outArgExpr), mkCompGenBind outv expr) (outArg, outArgExpr), mkCompGenBind outv expr)
|> List.unzip |> List.unzip
@ -9866,7 +9992,7 @@ and TcMethodApplication
let allArgs = let allArgs =
allArgs |> List.sortBy (fun x -> x.Position) allArgs |> List.sortBy (fun x -> x.Position)
optArgPreBinder, allArgs, outArgExprs, outArgTmpBinds optArgPreBinder, paramArrayPreBinders, allArgs, outArgExprs, outArgTmpBinds
let coerce (assignedArg: AssignedCalledArg<_>) = let coerce (assignedArg: AssignedCalledArg<_>) =
let isOutArg = assignedArg.CalledArg.IsOutArg let isOutArg = assignedArg.CalledArg.IsOutArg
@ -9884,13 +10010,21 @@ and TcMethodApplication
let item = Item.ArgName (defaultArg assignedArg.CalledArg.NameOpt id, assignedArg.CalledArg.CalledArgumentType, Some(ArgumentContainer.Method(finalCalledMethInfo))) let item = Item.ArgName (defaultArg assignedArg.CalledArg.NameOpt id, assignedArg.CalledArg.CalledArgumentType, Some(ArgumentContainer.Method(finalCalledMethInfo)))
CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad)) CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad))
let allArgsCoerced = List.map coerce allArgs let allArgsPreBinders, allArgsCoerced = List.map coerce allArgs |> List.unzip
// Make the call expression // Make the call expression
let expr, exprty = let expr, exprty =
BuildPossiblyConditionalMethodCall cenv env mut mMethExpr isProp finalCalledMethInfo isSuperInit finalCalledMethInst objArgs allArgsCoerced BuildPossiblyConditionalMethodCall cenv env mut mMethExpr isProp finalCalledMethInfo isSuperInit finalCalledMethInst objArgs allArgsCoerced
// Handle byref returns
let expr =
// byref-typed returns get implicitly dereferenced
let vty = tyOfExpr cenv.g expr
if isByrefTy cenv.g vty then
let v, _ = mkCompGenLocal mMethExpr "byrefReturn" vty
mkCompGenLet mMethExpr v expr (mkAddrGet mMethExpr (mkLocalValRef v))
else
expr
// Bind "out" parameters as part of the result tuple // Bind "out" parameters as part of the result tuple
let expr, exprty = let expr, exprty =
@ -9903,51 +10037,54 @@ and TcMethodApplication
expr, tyOfExpr cenv.g expr expr, tyOfExpr cenv.g expr
// Handle post-hoc property assignments // Handle post-hoc property assignments
let expr = let setterExprPrebinders, expr =
if isCheckingAttributeCall then expr else if isCheckingAttributeCall then
if isNil finalAssignedItemSetters then expr else [], expr
elif isNil finalAssignedItemSetters then
[], expr
else
// This holds the result of the call // This holds the result of the call
let objv, objExpr = mkMutableCompGenLocal mMethExpr "returnVal" exprty // mutable in case it's a struct let objv, objExpr = mkMutableCompGenLocal mMethExpr "returnVal" exprty // mutable in case it's a struct
// This expression mutates the properties on the result of the call // This expression mutates the properties on the result of the call
let propSetExpr = let setterExprPrebinders, propSetExpr =
(mkUnit cenv.g mMethExpr, finalAssignedItemSetters) ||> List.fold (fun acc (AssignedItemSetter(id, setter, CallerArg(callerArgTy, m, isOptCallerArg, argExpr))) -> (mkUnit cenv.g mMethExpr, finalAssignedItemSetters) ||> List.mapFold (fun acc (AssignedItemSetter(id, setter, CallerArg(callerArgTy, m, isOptCallerArg, argExpr))) ->
if isOptCallerArg then error(Error(FSComp.SR.tcInvalidOptionalAssignmentToPropertyOrField(), m)) if isOptCallerArg then error(Error(FSComp.SR.tcInvalidOptionalAssignmentToPropertyOrField(), m))
let action, defnItem = let argExprPrebinder, action, defnItem =
match setter with match setter with
| AssignedPropSetter (pinfo, pminfo, pminst) -> | AssignedPropSetter (pinfo, pminfo, pminst) ->
MethInfoChecks cenv.g cenv.amap true None [objExpr] ad m pminfo MethInfoChecks cenv.g cenv.amap true None [objExpr] ad m pminfo
let calledArgTy = List.head (List.head (pminfo.GetParamTypes(cenv.amap, m, pminst))) let calledArgTy = List.head (List.head (pminfo.GetParamTypes(cenv.amap, m, pminst)))
let argExpr = coerceExpr false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr let argExprPrebinder, argExpr = coerceExpr false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr
let mut = (if isStructTy cenv.g (tyOfExpr cenv.g objExpr) then DefinitelyMutates else PossiblyMutates) let mut = (if isStructTy cenv.g (tyOfExpr cenv.g objExpr) then DefinitelyMutates else PossiblyMutates)
let action = BuildPossiblyConditionalMethodCall cenv env mut m true pminfo NormalValUse pminst [objExpr] [argExpr] |> fst let action = BuildPossiblyConditionalMethodCall cenv env mut m true pminfo NormalValUse pminst [objExpr] [argExpr] |> fst
action, Item.Property (pinfo.PropertyName, [pinfo]) argExprPrebinder, action, Item.Property (pinfo.PropertyName, [pinfo])
| AssignedILFieldSetter finfo -> | AssignedILFieldSetter finfo ->
// Get or set instance IL field // Get or set instance IL field
ILFieldInstanceChecks cenv.g cenv.amap ad m finfo ILFieldInstanceChecks cenv.g cenv.amap ad m finfo
let calledArgTy = finfo.FieldType (cenv.amap, m) let calledArgTy = finfo.FieldType (cenv.amap, m)
let argExpr = coerceExpr false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr let argExprPrebinder, argExpr = coerceExpr false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr
let action = BuildILFieldSet cenv.g m objExpr finfo argExpr let action = BuildILFieldSet cenv.g m objExpr finfo argExpr
action, Item.ILField finfo argExprPrebinder, action, Item.ILField finfo
| AssignedRecdFieldSetter rfinfo -> | AssignedRecdFieldSetter rfinfo ->
RecdFieldInstanceChecks cenv.g cenv.amap ad m rfinfo RecdFieldInstanceChecks cenv.g cenv.amap ad m rfinfo
let calledArgTy = rfinfo.FieldType let calledArgTy = rfinfo.FieldType
CheckRecdFieldMutation m denv rfinfo CheckRecdFieldMutation m denv rfinfo
let argExpr = coerceExpr false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr let argExprPrebinder, argExpr = coerceExpr false calledArgTy ReflectedArgInfo.None callerArgTy m argExpr
let action = BuildRecdFieldSet cenv.g m objExpr rfinfo argExpr let action = BuildRecdFieldSet cenv.g m objExpr rfinfo argExpr
action, Item.RecdField rfinfo argExprPrebinder, action, Item.RecdField rfinfo
// Record the resolution for the Language Service // Record the resolution for the Language Service
let item = Item.SetterArg (id, defnItem) let item = Item.SetterArg (id, defnItem)
CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad) CallNameResolutionSink cenv.tcSink (id.idRange, env.NameEnv, item, item, emptyTyparInst, ItemOccurence.Use, env.DisplayEnv, ad)
mkCompGenSequential m acc action) argExprPrebinder, mkCompGenSequential m acc action)
// now put them together // now put them together
let expr = mkCompGenLet mMethExpr objv expr (mkCompGenSequential mMethExpr propSetExpr objExpr) let expr = mkCompGenLet mMethExpr objv expr (mkCompGenSequential mMethExpr propSetExpr objExpr)
expr setterExprPrebinders, expr
// Build the lambda expression if any // Build the lambda expression if any
let expr = let expr =
@ -9973,6 +10110,10 @@ and TcMethodApplication
expr, tpenv expr, tpenv
// Apply the PreBinders, if any // Apply the PreBinders, if any
let expr = (expr, setterExprPrebinders) ||> List.fold (fun expr argPreBinder -> match argPreBinder with None -> expr | Some f -> f expr)
let expr = (expr, paramArrayPreBinders) ||> List.fold (fun expr argPreBinder -> match argPreBinder with None -> expr | Some f -> f expr)
let expr = (expr, allArgsPreBinders) ||> List.fold (fun expr argPreBinder -> match argPreBinder with None -> expr | Some f -> f expr)
let expr = optArgPreBinder expr let expr = optArgPreBinder expr
let expr = objArgPreBinder expr let expr = objArgPreBinder expr
@ -10181,7 +10322,7 @@ and TcAndBuildFixedExpr cenv env (overallPatTy, fixedExpr, overallExprTy, mBindi
match stripExpr fixedExpr with match stripExpr fixedExpr with
| Expr.Op (op, tyargs, args, _) -> | Expr.Op (op, tyargs, args, _) ->
match op, tyargs, args with match op, tyargs, args with
| TOp.ValFieldGetAddr rfref, _, [_] -> not rfref.Tycon.IsStructOrEnumTycon | TOp.ValFieldGetAddr (rfref, _), _, [_] -> not rfref.Tycon.IsStructOrEnumTycon
| TOp.ILAsm ([ I_ldflda (fspec)], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject | TOp.ILAsm ([ I_ldflda (fspec)], _), _, _ -> fspec.DeclaringType.Boxity = ILBoxity.AsObject
| TOp.ILAsm ([ I_ldelema _], _), _, _ -> true | TOp.ILAsm ([ I_ldelema _], _), _, _ -> true
| TOp.RefAddrGet _, _, _ -> true | TOp.RefAddrGet _, _, _ -> true
@ -10230,7 +10371,7 @@ and TcAndBuildFixedExpr cenv env (overallPatTy, fixedExpr, overallExprTy, mBindi
// //
mkCompGenLetIn mBinding "tmpArray" overallExprTy fixedExpr (fun (_, ve) -> mkCompGenLetIn mBinding "tmpArray" overallExprTy fixedExpr (fun (_, ve) ->
// This is &arr.[0] // This is &arr.[0]
let elemZeroAddress = mkArrayElemAddress cenv.g (ILReadonly.NormalAddress, false, ILArrayShape.SingleDimensional, elemTy, ve, mkInt32 cenv.g mBinding 0, mBinding) let elemZeroAddress = mkArrayElemAddress cenv.g (false, ILReadonly.NormalAddress, false, ILArrayShape.SingleDimensional, elemTy, [ve; mkInt32 cenv.g mBinding 0], mBinding)
// check for non-null and non-empty // check for non-null and non-empty
let zero = mkConvToNativeInt cenv.g (mkInt32 cenv.g mBinding 0) mBinding let zero = mkConvToNativeInt cenv.g (mkInt32 cenv.g mBinding 0) mBinding
// This is arr.Length // This is arr.Length
@ -12418,6 +12559,12 @@ module IncrClassChecking =
| InVar false -> true | InVar false -> true
| _ -> false | _ -> false
member localRep.IsValRepresentedAsMethod (v:Val) =
localRep.IsValWithRepresentation(v) &&
match localRep.LookupRepr(v) with
| InMethod _ -> true
| _ -> false
/// Make the elaborated expression that represents a use of a /// Make the elaborated expression that represents a use of a
/// a "let v = ..." class binding /// a "let v = ..." class binding
member localRep.MakeValueLookup thisValOpt tinst safeStaticInitInfo v tyargs m = member localRep.MakeValueLookup thisValOpt tinst safeStaticInitInfo v tyargs m =
@ -12463,19 +12610,19 @@ module IncrClassChecking =
| InMethod _, _ -> | InMethod _, _ ->
error(InternalError("Local was given method storage, yet later it's been assigned to", m)) error(InternalError("Local was given method storage, yet later it's been assigned to", m))
member localRep.MakeValueGetAddress thisValOpt tinst safeStaticInitInfo v m = member localRep.MakeValueGetAddress readonly thisValOpt tinst safeStaticInitInfo v m =
let g = localRep.RepInfoTcGlobals let g = localRep.RepInfoTcGlobals
match localRep.LookupRepr v, thisValOpt with match localRep.LookupRepr v, thisValOpt with
| InField(false, _, rfref), Some(thisVal) -> | InField(false, _, rfref), Some(thisVal) ->
let thise = exprForVal m thisVal let thise = exprForVal m thisVal
mkRecdFieldGetAddrViaExprAddr(thise, rfref, tinst, m) mkRecdFieldGetAddrViaExprAddr(readonly, thise, rfref, tinst, m)
| InField(false, _, _rfref), None -> | InField(false, _, _rfref), None ->
error(InternalError("Unexpected missing 'this' variable in MakeValueGetAddress", m)) error(InternalError("Unexpected missing 'this' variable in MakeValueGetAddress", m))
| InField(true, idx, rfref), _ -> | InField(true, idx, rfref), _ ->
let expr = mkStaticRecdFieldGetAddr(rfref, tinst, m) let expr = mkStaticRecdFieldGetAddr(readonly, rfref, tinst, m)
MakeCheckSafeInit g tinst safeStaticInitInfo (mkInt g m idx) expr MakeCheckSafeInit g tinst safeStaticInitInfo (mkInt g m idx) expr
| InVar _, _ -> | InVar _, _ ->
mkValAddr m (mkLocalValRef v) mkValAddr m readonly (mkLocalValRef v)
| InMethod _, _ -> | InMethod _, _ ->
error(InternalError("Local was given method storage, yet later it's address was required", m)) error(InternalError("Local was given method storage, yet later it's address was required", m))
@ -12515,42 +12662,42 @@ module IncrClassChecking =
/// Fix up the references to the locals, e.g. /// Fix up the references to the locals, e.g.
/// v -> this.fieldv /// v -> this.fieldv
/// f x -> this.method x /// f x -> this.method x
member localRep.FixupIncrClassExprPhase2C thisValOpt safeStaticInitInfo (thisTyInst:TypeInst) expr = member localRep.FixupIncrClassExprPhase2C cenv thisValOpt safeStaticInitInfo (thisTyInst:TypeInst) expr =
// fixup: intercept and expr rewrite // fixup: intercept and expr rewrite
let FixupExprNode rw e = let FixupExprNode rw e =
//dprintfn "Fixup %s" (showL (exprL e)) //dprintfn "Fixup %s" (showL (exprL e))
let g = localRep.RepInfoTcGlobals
let e = NormalizeAndAdjustPossibleSubsumptionExprs g e
match e with match e with
// Rewrite references to applied let-bound-functions-compiled-as-methods // Rewrite references to applied let-bound-functions-compiled-as-methods
| Expr.App(Expr.Val (ValDeref(v), _, _), _, tyargs, args, m) // Rewrite references to applied recursive let-bound-functions-compiled-as-methods
when (localRep.IsValWithRepresentation(v) && // Rewrite references to applied recursive generic let-bound-functions-compiled-as-methods
(match localRep.LookupRepr(v) with | Expr.App(Expr.Val (ValDeref v, _, _), _, tyargs, args, m)
| InMethod _ -> true //(methodVal.Typars.Length > thisTyInst.Length) | Expr.App(Expr.Link {contents = Expr.Val (ValDeref v, _, _) }, _, tyargs, args, m)
| _ -> false )) -> | Expr.App(Expr.Link {contents = Expr.App(Expr.Val (ValDeref v, _, _), _, tyargs, [], _) }, _, [], args, m)
when localRep.IsValRepresentedAsMethod(v) && not (cenv.recUses.ContainsKey v) ->
//dprintfn "Found application of %s" v.LogicalName
let g = localRep.RepInfoTcGlobals
let expr = localRep.MakeValueLookup thisValOpt thisTyInst safeStaticInitInfo v tyargs m let expr = localRep.MakeValueLookup thisValOpt thisTyInst safeStaticInitInfo v tyargs m
let args = args |> List.map rw let args = args |> List.map rw
Some (MakeApplicationAndBetaReduce g (expr, (tyOfExpr g expr), [], args, m)) Some (MakeApplicationAndBetaReduce g (expr, (tyOfExpr g expr), [], args, m))
// Rewrite references to values stored as fields and first class uses of method values // Rewrite references to values stored as fields and first class uses of method values
| Expr.Val (ValDeref(v), _, m) | Expr.Val (ValDeref v, _, m)
when localRep.IsValWithRepresentation(v) -> when localRep.IsValWithRepresentation(v) ->
//dprintfn "Found use of %s" v.LogicalName //dprintfn "Found use of %s" v.LogicalName
Some (localRep.MakeValueLookup thisValOpt thisTyInst safeStaticInitInfo v [] m) Some (localRep.MakeValueLookup thisValOpt thisTyInst safeStaticInitInfo v [] m)
// Rewrite assignments to mutable values stored as fields // Rewrite assignments to mutable values stored as fields
| Expr.Op(TOp.LValueOp (LSet, ValDeref(v)) , [], [arg], m) | Expr.Op(TOp.LValueOp (LSet, ValDeref v) , [], [arg], m)
when localRep.IsValWithRepresentation(v) -> when localRep.IsValWithRepresentation(v) ->
let arg = rw arg let arg = rw arg
Some (localRep.MakeValueAssign thisValOpt thisTyInst safeStaticInitInfo v arg m) Some (localRep.MakeValueAssign thisValOpt thisTyInst safeStaticInitInfo v arg m)
// Rewrite taking the address of mutable values stored as fields // Rewrite taking the address of mutable values stored as fields
| Expr.Op(TOp.LValueOp (LGetAddr, ValDeref(v)), [], [] , m) | Expr.Op(TOp.LValueOp (LAddrOf readonly, ValDeref v), [], [] , m)
when localRep.IsValWithRepresentation(v) -> when localRep.IsValWithRepresentation(v) ->
Some (localRep.MakeValueGetAddress thisValOpt thisTyInst safeStaticInitInfo v m) Some (localRep.MakeValueGetAddress readonly thisValOpt thisTyInst safeStaticInitInfo v m)
| _ -> None | _ -> None
Tastops.RewriteExpr { PreIntercept = Some FixupExprNode Tastops.RewriteExpr { PreIntercept = Some FixupExprNode
@ -12657,7 +12804,7 @@ module IncrClassChecking =
let TransBind (reps:IncrClassReprInfo) (TBind(v, rhsExpr, spBind)) = let TransBind (reps:IncrClassReprInfo) (TBind(v, rhsExpr, spBind)) =
if v.MustInline then if v.MustInline then
error(Error(FSComp.SR.tcLocalClassBindingsCannotBeInline(), v.Range)) error(Error(FSComp.SR.tcLocalClassBindingsCannotBeInline(), v.Range))
let rhsExpr = reps.FixupIncrClassExprPhase2C (Some thisVal) safeStaticInitInfo thisTyInst rhsExpr let rhsExpr = reps.FixupIncrClassExprPhase2C cenv (Some thisVal) safeStaticInitInfo thisTyInst rhsExpr
// The initialization of the 'ref cell' variable for 'this' is the only binding which comes prior to the super init // The initialization of the 'ref cell' variable for 'this' is the only binding which comes prior to the super init
let isPriorToSuperInit = let isPriorToSuperInit =
@ -12709,7 +12856,7 @@ module IncrClassChecking =
match safeStaticInitInfo with match safeStaticInitInfo with
| SafeInitField (rfref, _) -> | SafeInitField (rfref, _) ->
let setExpr = mkStaticRecdFieldSet (rfref, thisTyInst, mkInt cenv.g m idx, m) let setExpr = mkStaticRecdFieldSet (rfref, thisTyInst, mkInt cenv.g m idx, m)
let setExpr = reps.FixupIncrClassExprPhase2C (Some(thisVal)) NoSafeInitInfo thisTyInst setExpr let setExpr = reps.FixupIncrClassExprPhase2C cenv (Some(thisVal)) NoSafeInitInfo thisTyInst setExpr
Some setExpr Some setExpr
| NoSafeInitInfo -> | NoSafeInitInfo ->
None None
@ -12745,7 +12892,7 @@ module IncrClassChecking =
([], actions, methodBinds), reps ([], actions, methodBinds), reps
| IncrClassDo (doExpr, isStatic) -> | IncrClassDo (doExpr, isStatic) ->
let doExpr = reps.FixupIncrClassExprPhase2C (Some(thisVal)) safeStaticInitInfo thisTyInst doExpr let doExpr = reps.FixupIncrClassExprPhase2C cenv (Some(thisVal)) safeStaticInitInfo thisTyInst doExpr
let binder = (fun e -> mkSequential SequencePointsAtSeq doExpr.Range doExpr e) let binder = (fun e -> mkSequential SequencePointsAtSeq doExpr.Range doExpr e)
let isPriorToSuperInit = false let isPriorToSuperInit = false
if isStatic then if isStatic then
@ -12765,7 +12912,7 @@ module IncrClassChecking =
| None -> () | None -> ()
| Some v -> | Some v ->
let setExpr = mkRefCellSet cenv.g m ctorInfo.InstanceCtorThisVal.Type (exprForVal m v) (exprForVal m ctorInfo.InstanceCtorThisVal) let setExpr = mkRefCellSet cenv.g m ctorInfo.InstanceCtorThisVal.Type (exprForVal m v) (exprForVal m ctorInfo.InstanceCtorThisVal)
let setExpr = reps.FixupIncrClassExprPhase2C (Some(thisVal)) safeStaticInitInfo thisTyInst setExpr let setExpr = reps.FixupIncrClassExprPhase2C cenv (Some(thisVal)) safeStaticInitInfo thisTyInst setExpr
let binder = (fun e -> mkSequential SequencePointsAtSeq setExpr.Range setExpr e) let binder = (fun e -> mkSequential SequencePointsAtSeq setExpr.Range setExpr e)
let isPriorToSuperInit = false let isPriorToSuperInit = false
yield (isPriorToSuperInit, binder) ] yield (isPriorToSuperInit, binder) ]
@ -12779,7 +12926,7 @@ module IncrClassChecking =
[ match ctorInfo.InstanceCtorSafeInitInfo with [ match ctorInfo.InstanceCtorSafeInitInfo with
| SafeInitField (rfref, _) -> | SafeInitField (rfref, _) ->
let setExpr = mkRecdFieldSetViaExprAddr (exprForVal m thisVal, rfref, thisTyInst, mkOne cenv.g m, m) let setExpr = mkRecdFieldSetViaExprAddr (exprForVal m thisVal, rfref, thisTyInst, mkOne cenv.g m, m)
let setExpr = reps.FixupIncrClassExprPhase2C (Some(thisVal)) safeStaticInitInfo thisTyInst setExpr let setExpr = reps.FixupIncrClassExprPhase2C cenv (Some(thisVal)) safeStaticInitInfo thisTyInst setExpr
let binder = (fun e -> mkSequential SequencePointsAtSeq setExpr.Range setExpr e) let binder = (fun e -> mkSequential SequencePointsAtSeq setExpr.Range setExpr e)
let isPriorToSuperInit = false let isPriorToSuperInit = false
yield (isPriorToSuperInit, binder) yield (isPriorToSuperInit, binder)
@ -12862,7 +13009,7 @@ module IncrClassChecking =
// Rewrite the expression to convert it to a load of a field if needed. // Rewrite the expression to convert it to a load of a field if needed.
// We are allowed to load fields from our own object even though we haven't called // We are allowed to load fields from our own object even though we haven't called
// the super class constructor yet. // the super class constructor yet.
let ldexpr = reps.FixupIncrClassExprPhase2C (Some(thisVal)) safeStaticInitInfo thisTyInst (exprForVal m v) let ldexpr = reps.FixupIncrClassExprPhase2C cenv (Some(thisVal)) safeStaticInitInfo thisTyInst (exprForVal m v)
mkInvisibleLet m v ldexpr inheritsExpr mkInvisibleLet m v ldexpr inheritsExpr
| _ -> | _ ->
inheritsExpr inheritsExpr
@ -13536,7 +13683,7 @@ module MutRecBindingChecking =
// Members have at least as many type parameters as the enclosing class. Just grab the type variables for the type. // Members have at least as many type parameters as the enclosing class. Just grab the type variables for the type.
let thisTyInst = List.map mkTyparTy (List.take (tcref.Typars(v.Range).Length) v.Typars) let thisTyInst = List.map mkTyparTy (List.take (tcref.Typars(v.Range).Length) v.Typars)
let x = localReps.FixupIncrClassExprPhase2C thisValOpt safeStaticInitInfo thisTyInst x let x = localReps.FixupIncrClassExprPhase2C cenv thisValOpt safeStaticInitInfo thisTyInst x
{ pgrbind with Binding = TBind(v, x, spBind) } ) { pgrbind with Binding = TBind(v, x, spBind) } )
@ -14197,7 +14344,7 @@ module TyconConstraintInference =
// If the type was excluded, say why // If the type was excluded, say why
if not res then if not res then
match TryFindFSharpBoolAttribute g g.attrib_StructuralEqualityAttribute tycon.Attribs with match TryFindFSharpBoolAttribute g g.attrib_StructuralEqualityAttribute tycon.Attribs with
| Some(true) -> | Some true ->
if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon then if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon then
match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsEquality tycon >> not) with match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsEquality tycon >> not) with
| None -> | None ->

Просмотреть файл

@ -629,6 +629,9 @@ and
/// F# syntax: expr.ident...ident <- expr /// F# syntax: expr.ident...ident <- expr
| DotSet of SynExpr * longDotId:LongIdentWithDots * SynExpr * range:range | DotSet of SynExpr * longDotId:LongIdentWithDots * SynExpr * range:range
/// F# syntax: expr <- expr
| Set of SynExpr * SynExpr * range:range
/// F# syntax: expr.[expr,...,expr] /// F# syntax: expr.[expr,...,expr]
| DotIndexedGet of SynExpr * SynIndexerArg list * range * range:range | DotIndexedGet of SynExpr * SynIndexerArg list * range * range:range
@ -763,6 +766,7 @@ and
| SynExpr.DotIndexedSet (range=m) | SynExpr.DotIndexedSet (range=m)
| SynExpr.DotGet (range=m) | SynExpr.DotGet (range=m)
| SynExpr.DotSet (range=m) | SynExpr.DotSet (range=m)
| SynExpr.Set (range=m)
| SynExpr.DotNamedIndexedPropertySet (range=m) | SynExpr.DotNamedIndexedPropertySet (range=m)
| SynExpr.LibraryOnlyUnionCaseFieldGet (range=m) | SynExpr.LibraryOnlyUnionCaseFieldGet (range=m)
| SynExpr.LibraryOnlyUnionCaseFieldSet (range=m) | SynExpr.LibraryOnlyUnionCaseFieldSet (range=m)
@ -824,6 +828,7 @@ and
| SynExpr.DotIndexedGet (range=m) | SynExpr.DotIndexedGet (range=m)
| SynExpr.DotIndexedSet (range=m) | SynExpr.DotIndexedSet (range=m)
| SynExpr.DotSet (range=m) | SynExpr.DotSet (range=m)
| SynExpr.Set (range=m)
| SynExpr.DotNamedIndexedPropertySet (range=m) | SynExpr.DotNamedIndexedPropertySet (range=m)
| SynExpr.LibraryOnlyUnionCaseFieldGet (range=m) | SynExpr.LibraryOnlyUnionCaseFieldGet (range=m)
| SynExpr.LibraryOnlyUnionCaseFieldSet (range=m) | SynExpr.LibraryOnlyUnionCaseFieldSet (range=m)
@ -887,6 +892,7 @@ and
| SynExpr.DotIndexedSet (range=m) | SynExpr.DotIndexedSet (range=m)
| SynExpr.DotGet (range=m) | SynExpr.DotGet (range=m)
| SynExpr.DotSet (range=m) | SynExpr.DotSet (range=m)
| SynExpr.Set (range=m)
| SynExpr.DotNamedIndexedPropertySet (range=m) | SynExpr.DotNamedIndexedPropertySet (range=m)
| SynExpr.LibraryOnlyUnionCaseFieldGet (range=m) | SynExpr.LibraryOnlyUnionCaseFieldGet (range=m)
| SynExpr.LibraryOnlyUnionCaseFieldSet (range=m) | SynExpr.LibraryOnlyUnionCaseFieldSet (range=m)
@ -1857,7 +1863,8 @@ let mkSynAssign (l: SynExpr) (r: SynExpr) =
mkSynDotParenSet m a b r mkSynDotParenSet m a b r
| SynExpr.App (_, _, SynExpr.LongIdent(false,v,None,_),x,_) -> SynExpr.NamedIndexedPropertySet (v,x,r,m) | SynExpr.App (_, _, SynExpr.LongIdent(false,v,None,_),x,_) -> SynExpr.NamedIndexedPropertySet (v,x,r,m)
| SynExpr.App (_, _, SynExpr.DotGet(e,_,v,_),x,_) -> SynExpr.DotNamedIndexedPropertySet (e,v,x,r,m) | SynExpr.App (_, _, SynExpr.DotGet(e,_,v,_),x,_) -> SynExpr.DotNamedIndexedPropertySet (e,v,x,r,m)
| _ -> errorR(Error(FSComp.SR.astInvalidExprLeftHandOfAssignment(), m)); l // return just the LHS, so the typechecker can see it and capture expression typings that may be useful for dot lookups | l -> SynExpr.Set (l,r,m)
//| _ -> errorR(Error(FSComp.SR.astInvalidExprLeftHandOfAssignment(), m)); l // return just the LHS, so the typechecker can see it and capture expression typings that may be useful for dot lookups
let rec mkSynDot dotm m l r = let rec mkSynDot dotm m l r =
match l with match l with
@ -2356,6 +2363,7 @@ let rec synExprContainsError inpExpr =
| SynExpr.NamedIndexedPropertySet (_,e1,e2,_) | SynExpr.NamedIndexedPropertySet (_,e1,e2,_)
| SynExpr.DotSet (e1,_,e2,_) | SynExpr.DotSet (e1,_,e2,_)
| SynExpr.Set (e1,e2,_)
| SynExpr.LibraryOnlyUnionCaseFieldSet (e1,_,_,e2,_) | SynExpr.LibraryOnlyUnionCaseFieldSet (e1,_,_,e2,_)
| SynExpr.JoinIn (e1,_,e2,_) | SynExpr.JoinIn (e1,_,e2,_)
| SynExpr.App (_,_,e1,e2,_) -> | SynExpr.App (_,_,e1,e2,_) ->

Просмотреть файл

@ -140,16 +140,16 @@ let TransformExpr g (nvs: ValMap<_>) exprF expr =
Some (mkRefCellGet g m v.Type nve) Some (mkRefCellGet g m v.Type nve)
// Rewrite assignments to mutable values // Rewrite assignments to mutable values
| Expr.Op(TOp.LValueOp (LSet, ValDeref(v)) , [], [arg], m) when nvs.ContainsVal v -> | Expr.Op(TOp.LValueOp (LSet, ValDeref(v)), [], [arg], m) when nvs.ContainsVal v ->
let _nv, nve = nvs.[v] let _nv, nve = nvs.[v]
let arg = exprF arg let arg = exprF arg
Some (mkRefCellSet g m v.Type nve arg) Some (mkRefCellSet g m v.Type nve arg)
// Rewrite taking the address of mutable values // Rewrite taking the address of mutable values
| Expr.Op(TOp.LValueOp (LGetAddr, ValDeref(v)), [], [] , m) when nvs.ContainsVal v -> | Expr.Op(TOp.LValueOp (LAddrOf readonly, ValDeref(v)), [], [], m) when nvs.ContainsVal v ->
let _nv, nve = nvs.[v] let _nv,nve = nvs.[v]
Some (mkRecdFieldGetAddrViaExprAddr (nve, mkRefCellContentsRef g, [v.Type], m)) Some (mkRecdFieldGetAddrViaExprAddr (readonly, nve, mkRefCellContentsRef g, [v.Type], m))
| _ -> None | _ -> None
@ -183,9 +183,10 @@ let TransformImplFile g amap implFile =
|> ValMap.OfList |> ValMap.OfList
implFile |> implFile |>
RewriteImplFile { PreIntercept = Some(TransformExpr g nvs) RewriteImplFile
PreInterceptBinding = Some(TransformBinding g nvs) { PreIntercept = Some(TransformExpr g nvs)
PostTransform = (fun _ -> None) PreInterceptBinding = Some(TransformBinding g nvs)
IsUnderQuotations = false } PostTransform = (fun _ -> None)
IsUnderQuotations = false }

Просмотреть файл

@ -168,7 +168,9 @@ let rec ImportILType (env:ImportMap) m tinst typ =
let inst = tspec.GenericArgs |> List.map (ImportILType env m tinst) let inst = tspec.GenericArgs |> List.map (ImportILType env m tinst)
ImportTyconRefApp env tcref inst ImportTyconRefApp env tcref inst
| ILType.Modified(_,tref,ILType.Byref ty) when tref.Name = "System.Runtime.InteropServices.InAttribute" -> mkInByrefTy env.g (ImportILType env m tinst ty)
| ILType.Byref ty -> mkByrefTy env.g (ImportILType env m tinst ty) | ILType.Byref ty -> mkByrefTy env.g (ImportILType env m tinst ty)
| ILType.Ptr ILType.Void when env.g.voidptr_tcr.CanDeref -> mkVoidPtrTy env.g
| ILType.Ptr ty -> mkNativePtrTy env.g (ImportILType env m tinst ty) | ILType.Ptr ty -> mkNativePtrTy env.g (ImportILType env m tinst ty)
| ILType.FunctionPointer _ -> env.g.nativeint_ty (* failwith "cannot import this kind of type (ptr, fptr)" *) | ILType.FunctionPointer _ -> env.g.nativeint_ty (* failwith "cannot import this kind of type (ptr, fptr)" *)
| ILType.Modified(_,_,ty) -> | ILType.Modified(_,_,ty) ->
@ -260,7 +262,10 @@ let rec ImportProvidedType (env:ImportMap) (m:range) (* (tinst:TypeInst) *) (st:
mkByrefTy g elemTy mkByrefTy g elemTy
elif st.PUntaint((fun st -> st.IsPointer),m) then elif st.PUntaint((fun st -> st.IsPointer),m) then
let elemTy = (ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()),m))) let elemTy = (ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()),m)))
mkNativePtrTy g elemTy if isUnitTy g elemTy || isVoidTy g elemTy && g.voidptr_tcr.CanDeref then
mkVoidPtrTy g
else
mkNativePtrTy g elemTy
else else
// REVIEW: Extension type could try to be its own generic arg (or there could be a type loop) // REVIEW: Extension type could try to be its own generic arg (or there could be a type loop)

Просмотреть файл

@ -573,7 +573,7 @@ type ParamNameAndType =
/// Full information about a parameter returned for use by the type checker and language service. /// Full information about a parameter returned for use by the type checker and language service.
type ParamData = type ParamData =
/// ParamData(isParamArray, isOut, optArgInfo, callerInfoInfo, nameOpt, reflArgInfo, ttype) /// ParamData(isParamArray, isOut, optArgInfo, callerInfoInfo, nameOpt, reflArgInfo, ttype)
ParamData of bool * bool * OptionalArgInfo * CallerInfoInfo * Ident option * ReflectedArgInfo * TType ParamData of bool * bool * bool * OptionalArgInfo * CallerInfoInfo * Ident option * ReflectedArgInfo * TType
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -1182,6 +1182,13 @@ type MethInfo =
| ILMeth (_,_,Some _) -> true | ILMeth (_,_,Some _) -> true
| _ -> false | _ -> false
/// Indicates if this is an extension member (e.g. on a struct) that takes a byref arg
member x.ObjArgNeedsAddress (amap: Import.ImportMap, m) =
(x.IsStruct && not x.IsExtensionMember) ||
match x.GetObjArgTypes (amap, m, x.FormalMethodInst) with
| [h] -> isByrefTy amap.g h
| _ -> false
/// Indicates if this is an F# extension member. /// Indicates if this is an F# extension member.
member x.IsFSharpStyleExtensionMember = member x.IsFSharpStyleExtensionMember =
match x with FSMeth (_,_,vref,_) -> vref.IsExtensionMember | _ -> false match x with FSMeth (_,_,vref,_) -> vref.IsExtensionMember | _ -> false
@ -1350,6 +1357,7 @@ type MethInfo =
| Some _ -> ReflectedArgInfo.Quote false | Some _ -> ReflectedArgInfo.Quote false
| _ -> ReflectedArgInfo.None | _ -> ReflectedArgInfo.None
let isOutArg = (p.IsOut && not p.IsIn) let isOutArg = (p.IsOut && not p.IsIn)
let isInArg = (p.IsIn && not p.IsOut)
// Note: we get default argument values from VB and other .NET language metadata // Note: we get default argument values from VB and other .NET language metadata
let optArgInfo = OptionalArgInfo.FromILParameter g amap m ilMethInfo.MetadataScope ilMethInfo.DeclaringTypeInst p let optArgInfo = OptionalArgInfo.FromILParameter g amap m ilMethInfo.MetadataScope ilMethInfo.DeclaringTypeInst p
@ -1369,7 +1377,7 @@ type MethInfo =
if p.Type.TypeRef.FullName = "System.Int32" then CallerFilePath if p.Type.TypeRef.FullName = "System.Int32" then CallerFilePath
else CallerLineNumber else CallerLineNumber
yield (isParamArrayArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo) ] ] yield (isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo) ] ]
| FSMeth(g,_,vref,_) -> | FSMeth(g,_,vref,_) ->
GetArgInfosOfMember x.IsCSharpStyleExtensionMember g vref GetArgInfosOfMember x.IsCSharpStyleExtensionMember g vref
@ -1379,7 +1387,8 @@ type MethInfo =
match TryFindFSharpBoolAttributeAssumeFalse g g.attrib_ReflectedDefinitionAttribute argInfo.Attribs with match TryFindFSharpBoolAttributeAssumeFalse g g.attrib_ReflectedDefinitionAttribute argInfo.Attribs with
| Some b -> ReflectedArgInfo.Quote b | Some b -> ReflectedArgInfo.Quote b
| None -> ReflectedArgInfo.None | None -> ReflectedArgInfo.None
let isOutArg = HasFSharpAttribute g g.attrib_OutAttribute argInfo.Attribs && isByrefTy g ty let isOutArg = (HasFSharpAttribute g g.attrib_OutAttribute argInfo.Attribs && isByrefTy g ty) || isOutByrefTy g ty
let isInArg = (HasFSharpAttribute g g.attrib_InAttribute argInfo.Attribs && isByrefTy g ty) || isInByrefTy g ty
let isCalleeSideOptArg = HasFSharpAttribute g g.attrib_OptionalArgumentAttribute argInfo.Attribs let isCalleeSideOptArg = HasFSharpAttribute g g.attrib_OptionalArgumentAttribute argInfo.Attribs
let isCallerSideOptArg = HasFSharpAttributeOpt g g.attrib_OptionalAttribute argInfo.Attribs let isCallerSideOptArg = HasFSharpAttributeOpt g g.attrib_OptionalAttribute argInfo.Attribs
let optArgInfo = let optArgInfo =
@ -1430,7 +1439,7 @@ type MethInfo =
| Some optTy when typeEquiv g g.int32_ty optTy -> CallerFilePath | Some optTy when typeEquiv g g.int32_ty optTy -> CallerFilePath
| _ -> CallerLineNumber | _ -> CallerLineNumber
(isParamArrayArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo)) (isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo))
| DefaultStructCtor _ -> | DefaultStructCtor _ ->
[[]] [[]]
@ -1446,7 +1455,9 @@ type MethInfo =
| Some ([ Some (:? bool as b) ], _) -> ReflectedArgInfo.Quote b | Some ([ Some (:? bool as b) ], _) -> ReflectedArgInfo.Quote b
| Some _ -> ReflectedArgInfo.Quote false | Some _ -> ReflectedArgInfo.Quote false
| None -> ReflectedArgInfo.None | None -> ReflectedArgInfo.None
yield (isParamArrayArg, p.PUntaint((fun p -> p.IsOut), m), optArgInfo, NoCallerInfo, reflArgInfo)] ] let isOutArg = p.PUntaint((fun p -> p.IsOut && not p.IsIn), m)
let isInArg = p.PUntaint((fun p -> p.IsIn && not p.IsOut), m)
yield (isParamArrayArg, isInArg, isOutArg, optArgInfo, NoCallerInfo, reflArgInfo)] ]
#endif #endif
@ -1546,12 +1557,12 @@ type MethInfo =
#endif #endif
let paramAttribs = x.GetParamAttribs(amap, m) let paramAttribs = x.GetParamAttribs(amap, m)
(paramAttribs,paramNamesAndTypes) ||> List.map2 (List.map2 (fun (isParamArrayArg,isOutArg,optArgInfo,callerInfoInfo,reflArgInfo) (ParamNameAndType(nmOpt,pty)) -> (paramAttribs,paramNamesAndTypes) ||> List.map2 (List.map2 (fun (isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo) (ParamNameAndType(nmOpt,pty)) ->
ParamData(isParamArrayArg,isOutArg,optArgInfo,callerInfoInfo,nmOpt,reflArgInfo,pty))) ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, nmOpt, reflArgInfo, pty)))
/// Get the ParamData objects for the parameters of a MethInfo /// Get the ParamData objects for the parameters of a MethInfo
member x.HasParamArrayArg(amap, m, minst) = member x.HasParamArrayArg(amap, m, minst) =
x.GetParamDatas(amap, m, minst) |> List.existsSquared (fun (ParamData(isParamArrayArg,_,_,_,_,_,_)) -> isParamArrayArg) x.GetParamDatas(amap, m, minst) |> List.existsSquared (fun (ParamData(isParamArrayArg,_,_,_,_,_,_,_)) -> isParamArrayArg)
/// Select all the type parameters of the declaring type of a method. /// Select all the type parameters of the declaring type of a method.
@ -2134,7 +2145,7 @@ type PropInfo =
/// Get the details of the indexer parameters associated with the property /// Get the details of the indexer parameters associated with the property
member x.GetParamDatas(amap,m) = member x.GetParamDatas(amap,m) =
x.GetParamNamesAndTypes(amap,m) x.GetParamNamesAndTypes(amap,m)
|> List.map (fun (ParamNameAndType(nmOpt,pty)) -> ParamData(false, false, NotOptional, NoCallerInfo, nmOpt, ReflectedArgInfo.None, pty)) |> List.map (fun (ParamNameAndType(nmOpt,pty)) -> ParamData(false, false, false, NotOptional, NoCallerInfo, nmOpt, ReflectedArgInfo.None, pty))
/// Get the types of the indexer parameters associated with the property /// Get the types of the indexer parameters associated with the property
member x.GetParamTypes(amap,m) = member x.GetParamTypes(amap,m) =

Просмотреть файл

@ -663,6 +663,9 @@ module ParsedInput =
walkExpr e1 walkExpr e1
addLongIdentWithDots idents addLongIdentWithDots idents
walkExpr e2 walkExpr e2
| SynExpr.Set (e1, e2, _) ->
walkExpr e1
walkExpr e2
| SynExpr.DotIndexedGet (e, args, _, _) -> | SynExpr.DotIndexedGet (e, args, _, _) ->
walkExpr e walkExpr e
List.iter walkIndexerArg args List.iter walkIndexerArg args

Просмотреть файл

@ -85,14 +85,14 @@ module internal DescriptionListsImpl =
else else
// TODO: in this case ucinst is ignored - it gives the instantiation of the type parameters of // TODO: in this case ucinst is ignored - it gives the instantiation of the type parameters of
// the union type containing this case. // the union type containing this case.
NicePrint.layoutOfParamData denv (ParamData(false, false, NotOptional, NoCallerInfo, Some f.Id, ReflectedArgInfo.None, f.FormalType)) NicePrint.layoutOfParamData denv (ParamData(false, false, false, NotOptional, NoCallerInfo, Some f.Id, ReflectedArgInfo.None, f.FormalType))
FSharpMethodGroupItemParameter( FSharpMethodGroupItemParameter(
name=initial.ParameterName, name=initial.ParameterName,
canonicalTypeTextForSorting=initial.CanonicalTypeTextForSorting, canonicalTypeTextForSorting=initial.CanonicalTypeTextForSorting,
display=display, display=display,
isOptional=false) isOptional=false)
let ParamOfParamData g denv (ParamData(_isParamArrayArg, _isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty) as paramData) = let ParamOfParamData g denv (ParamData(_isParamArrayArg, _isInArg, _isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty) as paramData) =
FSharpMethodGroupItemParameter( FSharpMethodGroupItemParameter(
name = (match nmOpt with None -> "" | Some pn -> pn.idText), name = (match nmOpt with None -> "" | Some pn -> pn.idText),
canonicalTypeTextForSorting = printCanonicalizedTypeName g denv pty, canonicalTypeTextForSorting = printCanonicalizedTypeName g denv pty,
@ -103,7 +103,7 @@ module internal DescriptionListsImpl =
let PrettyParamsOfParamDatas g denv typarInst (paramDatas:ParamData list) rty = let PrettyParamsOfParamDatas g denv typarInst (paramDatas:ParamData list) rty =
let paramInfo,paramTypes = let paramInfo,paramTypes =
paramDatas paramDatas
|> List.map (fun (ParamData(isParamArrayArg, _isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty)) -> |> List.map (fun (ParamData(isParamArrayArg, _isInArg, _isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty)) ->
let isOptArg = optArgInfo.IsOptional let isOptArg = optArgInfo.IsOptional
match nmOpt, isOptArg, tryDestOptionTy denv.g pty with match nmOpt, isOptArg, tryDestOptionTy denv.g pty with
// Layout an optional argument // Layout an optional argument
@ -237,7 +237,7 @@ module internal DescriptionListsImpl =
let firstCurriedParamDatas = let firstCurriedParamDatas =
firstCurriedArgInfo firstCurriedArgInfo
|> List.map ParamNameAndType.FromArgInfo |> List.map ParamNameAndType.FromArgInfo
|> List.map (fun (ParamNameAndType(nmOpt, pty)) -> ParamData(false, false, NotOptional, NoCallerInfo, nmOpt, ReflectedArgInfo.None, pty)) |> List.map (fun (ParamNameAndType(nmOpt, pty)) -> ParamData(false, false, false, NotOptional, NoCallerInfo, nmOpt, ReflectedArgInfo.None, pty))
// Adjust the return type so it only strips the first argument // Adjust the return type so it only strips the first argument
let curriedRetTy = let curriedRetTy =
@ -321,7 +321,7 @@ module internal DescriptionListsImpl =
| None -> | None ->
let argNamesAndTys = SymbolHelpers.ParamNameAndTypesOfUnaryCustomOperation g minfo let argNamesAndTys = SymbolHelpers.ParamNameAndTypesOfUnaryCustomOperation g minfo
let argTys, _ = PrettyTypes.PrettifyTypes g (argNamesAndTys |> List.map (fun (ParamNameAndType(_,ty)) -> ty)) let argTys, _ = PrettyTypes.PrettifyTypes g (argNamesAndTys |> List.map (fun (ParamNameAndType(_,ty)) -> ty))
let paramDatas = (argNamesAndTys, argTys) ||> List.map2 (fun (ParamNameAndType(nmOpt, _)) argTy -> ParamData(false, false, NotOptional, NoCallerInfo, nmOpt, ReflectedArgInfo.None,argTy)) let paramDatas = (argNamesAndTys, argTys) ||> List.map2 (fun (ParamNameAndType(nmOpt, _)) argTy -> ParamData(false, false, false, NotOptional, NoCallerInfo, nmOpt, ReflectedArgInfo.None,argTy))
let rty = minfo.GetFSharpReturnTy(amap, m, minfo.FormalMethodInst) let rty = minfo.GetFSharpReturnTy(amap, m, minfo.FormalMethodInst)
let _prettyTyparInst, prettyParams, prettyRetTyL, _prettyConstraintsL = PrettyParamsOfParamDatas g denv item.TyparInst paramDatas rty let _prettyTyparInst, prettyParams, prettyRetTyL, _prettyConstraintsL = PrettyParamsOfParamDatas g denv item.TyparInst paramDatas rty
@ -342,7 +342,7 @@ module internal DescriptionListsImpl =
let (SigOfFunctionForDelegate(_, _, _, fty)) = GetSigOfFunctionForDelegate infoReader delty m AccessibleFromSomewhere let (SigOfFunctionForDelegate(_, _, _, fty)) = GetSigOfFunctionForDelegate infoReader delty m AccessibleFromSomewhere
// No need to pass more generic type information in here since the instanitations have already been applied // No need to pass more generic type information in here since the instanitations have already been applied
let _prettyTyparInst, prettyParams, prettyRetTyL, _prettyConstraintsL = PrettyParamsOfParamDatas g denv item.TyparInst [ParamData(false, false, NotOptional, NoCallerInfo, None, ReflectedArgInfo.None, fty)] delty let _prettyTyparInst, prettyParams, prettyRetTyL, _prettyConstraintsL = PrettyParamsOfParamDatas g denv item.TyparInst [ParamData(false, false, false, NotOptional, NoCallerInfo, None, ReflectedArgInfo.None, fty)] delty
// FUTURE: prettyTyparInst is the pretty version of the known instantiations of type parameters in the output. It could be returned // FUTURE: prettyTyparInst is the pretty version of the known instantiations of type parameters in the output. It could be returned
// for display as part of the method group // for display as part of the method group

Просмотреть файл

@ -840,17 +840,22 @@ module internal InterfaceStubGenerator =
| SynExpr.Ident(_ident) -> | SynExpr.Ident(_ident) ->
None None
| SynExpr.LongIdent(_, _longIdent, _altNameRefCell, _range) -> | SynExpr.LongIdent(_, _longIdent, _altNameRefCell, _range) ->
None None
| SynExpr.LongIdentSet(_longIdent, synExpr, _range) -> | SynExpr.LongIdentSet(_longIdent, synExpr, _range) ->
walkExpr synExpr walkExpr synExpr
| SynExpr.DotGet(synExpr, _dotm, _longIdent, _range) -> | SynExpr.DotGet(synExpr, _dotm, _longIdent, _range) ->
walkExpr synExpr walkExpr synExpr
| SynExpr.DotSet(synExpr1, _longIdent, synExpr2, _range) -> | SynExpr.DotSet(synExpr1, _longIdent, synExpr2, _range) ->
List.tryPick walkExpr [synExpr1; synExpr2] List.tryPick walkExpr [synExpr1; synExpr2]
| SynExpr.Set(synExpr1, synExpr2, _range) ->
List.tryPick walkExpr [synExpr1; synExpr2]
| SynExpr.DotIndexedGet(synExpr, IndexerArgList synExprList, _range, _range2) -> | SynExpr.DotIndexedGet(synExpr, IndexerArgList synExprList, _range, _range2) ->
Option.orElse (walkExpr synExpr) (List.tryPick walkExpr synExprList) Option.orElse (walkExpr synExpr) (List.tryPick walkExpr synExprList)

Просмотреть файл

@ -394,7 +394,8 @@ module public AstTraversal =
| SynExpr.LongIdent(_, _longIdent, _altNameRefCell, _range) -> None | SynExpr.LongIdent(_, _longIdent, _altNameRefCell, _range) -> None
| SynExpr.LongIdentSet(_longIdent, synExpr, _range) -> traverseSynExpr synExpr | SynExpr.LongIdentSet(_longIdent, synExpr, _range) -> traverseSynExpr synExpr
| SynExpr.DotGet(synExpr, _dotm, _longIdent, _range) -> traverseSynExpr synExpr | SynExpr.DotGet(synExpr, _dotm, _longIdent, _range) -> traverseSynExpr synExpr
| SynExpr.DotSet(synExpr, _longIdent, synExpr2, _range) -> | SynExpr.Set(synExpr, synExpr2, _)
| SynExpr.DotSet(synExpr, _, synExpr2, _) ->
[dive synExpr synExpr.Range traverseSynExpr [dive synExpr synExpr.Range traverseSynExpr
dive synExpr2 synExpr2.Range traverseSynExpr] dive synExpr2 synExpr2.Range traverseSynExpr]
|> pick expr |> pick expr

Просмотреть файл

@ -223,10 +223,14 @@ module Structure =
| SynExpr.InferredUpcast (e,_) | SynExpr.InferredUpcast (e,_)
| SynExpr.DotGet (e,_,_,_) | SynExpr.DotGet (e,_,_,_)
| SynExpr.Do (e,_) | SynExpr.Do (e,_)
| SynExpr.DotSet (e,_,_,_)
| SynExpr.Typed (e,_,_) | SynExpr.Typed (e,_,_)
| SynExpr.DotIndexedGet (e,_,_,_) | SynExpr.DotIndexedGet (e,_,_,_) ->
| SynExpr.DotIndexedSet (e,_,_,_,_,_) -> parseExpr e parseExpr e
| SynExpr.Set (e1,e2,_)
| SynExpr.DotSet (e1,_,e2,_)
| SynExpr.DotIndexedSet (e1,_,e2,_,_,_) ->
parseExpr e1
parseExpr e2
| SynExpr.New (_,_,expr,r) -> | SynExpr.New (_,_,expr,r) ->
rcheck Scope.New Collapse.Below r expr.Range rcheck Scope.New Collapse.Below r expr.Range
parseExpr expr parseExpr expr

Просмотреть файл

@ -212,6 +212,7 @@ type FSharpParseFileResults(errors: FSharpErrorInfo[], input: Ast.ParsedInput op
| SynExpr.NamedIndexedPropertySet (_,e1,e2,_) | SynExpr.NamedIndexedPropertySet (_,e1,e2,_)
| SynExpr.DotSet (e1,_,e2,_) | SynExpr.DotSet (e1,_,e2,_)
| SynExpr.Set (e1,e2,_)
| SynExpr.LibraryOnlyUnionCaseFieldSet (e1,_,_,e2,_) | SynExpr.LibraryOnlyUnionCaseFieldSet (e1,_,_,e2,_)
| SynExpr.App (_,_,e1,e2,_) -> | SynExpr.App (_,_,e1,e2,_) ->
yield! walkExpr false e1 yield! walkExpr false e1
@ -480,6 +481,13 @@ module UntypedParseImpl =
else else
// see comment below for SynExpr.DotSet // see comment below for SynExpr.DotSet
Some((unionRanges synExpr.Range r)) Some((unionRanges synExpr.Range r))
| SynExpr.Set(synExpr, synExpr2, range) ->
if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then
traverseSynExpr synExpr
elif AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr2.Range pos then
traverseSynExpr synExpr2
else
Some(range)
| SynExpr.DotSet(synExpr, LongIdentWithDots(longIdent,_), synExpr2, _range) -> | SynExpr.DotSet(synExpr, LongIdentWithDots(longIdent,_), synExpr2, _range) ->
if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then
traverseSynExpr synExpr traverseSynExpr synExpr
@ -642,6 +650,10 @@ module UntypedParseImpl =
dive lidwd lidwd.Range (traverseLidOrElse(Some exprLeft)) dive lidwd lidwd.Range (traverseLidOrElse(Some exprLeft))
dive exprRhs exprRhs.Range traverseSynExpr dive exprRhs exprRhs.Range traverseSynExpr
] |> pick expr ] |> pick expr
| SynExpr.Set(exprLeft, exprRhs, _m) ->
[ dive exprLeft exprLeft.Range traverseSynExpr
dive exprRhs exprRhs.Range traverseSynExpr
] |> pick expr
| SynExpr.NamedIndexedPropertySet(lidwd, exprIndexer, exprRhs, _m) -> | SynExpr.NamedIndexedPropertySet(lidwd, exprIndexer, exprRhs, _m) ->
[ dive lidwd lidwd.Range (traverseLidOrElse None) [ dive lidwd lidwd.Range (traverseLidOrElse None)
dive exprIndexer exprIndexer.Range traverseSynExpr dive exprIndexer exprIndexer.Range traverseSynExpr
@ -843,6 +855,7 @@ module UntypedParseImpl =
| SynExpr.LongIdentSet(_, e, _) -> walkExprWithKind parentKind e | SynExpr.LongIdentSet(_, e, _) -> walkExprWithKind parentKind e
| SynExpr.DotGet(e, _, _, _) -> walkExprWithKind parentKind e | SynExpr.DotGet(e, _, _, _) -> walkExprWithKind parentKind e
| SynExpr.DotSet(e, _, _, _) -> walkExprWithKind parentKind e | SynExpr.DotSet(e, _, _, _) -> walkExprWithKind parentKind e
| SynExpr.Set(e, _, _) -> walkExprWithKind parentKind e
| SynExpr.DotIndexedGet(e, args, _, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkIndexerArg args) | SynExpr.DotIndexedGet(e, args, _, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkIndexerArg args)
| SynExpr.DotIndexedSet(e, args, _, _, _, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkIndexerArg args) | SynExpr.DotIndexedSet(e, args, _, _, _, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkIndexerArg args)
| SynExpr.NamedIndexedPropertySet(_, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2] | SynExpr.NamedIndexedPropertySet(_, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2]

Просмотреть файл

@ -353,7 +353,7 @@ type TypeCheckInfo
methods methods
|> List.collect (fun meth -> |> List.collect (fun meth ->
match meth.GetParamDatas(amap, m, meth.FormalMethodInst) with match meth.GetParamDatas(amap, m, meth.FormalMethodInst) with
| x::_ -> x |> List.choose(fun (ParamData(_isParamArray, _isOut, _optArgInfo, _callerInfoInfo, name, _, ty)) -> | x::_ -> x |> List.choose(fun (ParamData(_isParamArray, _isInArg, _isOutArg, _optArgInfo, _callerInfoInfo, name, _, ty)) ->
match name with match name with
| Some n -> Some (Item.ArgName(n, ty, Some (ArgumentContainer.Method meth))) | Some n -> Some (Item.ArgName(n, ty, Some (ArgumentContainer.Method meth)))
| None -> None | None -> None

Просмотреть файл

@ -302,10 +302,10 @@ module FSharpExprConvert =
match expr with match expr with
| Expr.Op(op, tyargs, args, m) -> | Expr.Op(op, tyargs, args, m) ->
match op, args, tyargs with match op, args, tyargs with
| TOp.LValueOp(LGetAddr, vref), _, _ -> exprForValRef m vref | TOp.LValueOp(LAddrOf _, vref), _, _ -> exprForValRef m vref
| TOp.ValFieldGetAddr(rfref), [], _ -> mkStaticRecdFieldGet(rfref, tyargs, m) | TOp.ValFieldGetAddr(rfref, _), [], _ -> mkStaticRecdFieldGet(rfref, tyargs, m)
| TOp.ValFieldGetAddr(rfref), [arg], _ -> mkRecdFieldGetViaExprAddr(exprOfExprAddr cenv arg, rfref, tyargs, m) | TOp.ValFieldGetAddr(rfref, _), [arg], _ -> mkRecdFieldGetViaExprAddr(exprOfExprAddr cenv arg, rfref, tyargs, m)
| TOp.UnionCaseFieldGetAddr(uref, n), [arg], _ -> mkUnionCaseFieldGetProvenViaExprAddr(exprOfExprAddr cenv arg, uref, tyargs, n, m) | TOp.UnionCaseFieldGetAddr(uref, n, _), [arg], _ -> mkUnionCaseFieldGetProvenViaExprAddr(exprOfExprAddr cenv arg, uref, tyargs, n, m)
| TOp.ILAsm([ I_ldflda(fspec) ], rtys), [arg], _ -> mkAsmExpr([ mkNormalLdfld(fspec) ], tyargs, [exprOfExprAddr cenv arg], rtys, m) | TOp.ILAsm([ I_ldflda(fspec) ], rtys), [arg], _ -> mkAsmExpr([ mkNormalLdfld(fspec) ], tyargs, [exprOfExprAddr cenv arg], rtys, m)
| TOp.ILAsm([ I_ldsflda(fspec) ], rtys), _, _ -> mkAsmExpr([ mkNormalLdsfld(fspec) ], tyargs, args, rtys, m) | TOp.ILAsm([ I_ldsflda(fspec) ], rtys), _, _ -> mkAsmExpr([ mkNormalLdsfld(fspec) ], tyargs, args, rtys, m)
| TOp.ILAsm(([ I_ldelema(_ro, _isNativePtr, shape, _tyarg) ] ), _), (arr::idxs), [elemty] -> | TOp.ILAsm(([ I_ldelema(_ro, _isNativePtr, shape, _tyarg) ] ), _), (arr::idxs), [elemty] ->
@ -581,10 +581,10 @@ module FSharpExprConvert =
let projR = FSharpField(cenv, ucref, n) let projR = FSharpField(cenv, ucref, n)
E.UnionCaseSet(ConvExpr cenv env e1, typR, mkR, projR, ConvExpr cenv env e2) E.UnionCaseSet(ConvExpr cenv env e1, typR, mkR, projR, ConvExpr cenv env e2)
| TOp.UnionCaseFieldGetAddr (_ucref, _n), _tyargs, _ -> | TOp.UnionCaseFieldGetAddr _, _tyargs, _ ->
E.AddressOf(ConvLValueExpr cenv env expr) E.AddressOf(ConvLValueExpr cenv env expr)
| TOp.ValFieldGetAddr(_rfref), _tyargs, _ -> | TOp.ValFieldGetAddr _, _tyargs, _ ->
E.AddressOf(ConvLValueExpr cenv env expr) E.AddressOf(ConvLValueExpr cenv env expr)
| TOp.ValFieldGet(rfref), tyargs, [] -> | TOp.ValFieldGet(rfref), tyargs, [] ->
@ -755,7 +755,7 @@ module FSharpExprConvert =
// rebuild reraise<T>() and Convert // rebuild reraise<T>() and Convert
mkReraiseLibCall cenv.g toTy m |> ConvExprPrim cenv env mkReraiseLibCall cenv.g toTy m |> ConvExprPrim cenv env
| TOp.LValueOp(LGetAddr, vref), [], [] -> | TOp.LValueOp(LAddrOf _, vref), [], [] ->
E.AddressOf(ConvExpr cenv env (exprForValRef m vref)) E.AddressOf(ConvExpr cenv env (exprForValRef m vref))
| TOp.LValueOp(LByrefSet, vref), [], [e] -> | TOp.LValueOp(LByrefSet, vref), [], [e] ->
@ -815,8 +815,8 @@ module FSharpExprConvert =
let argsR = ConvExprs cenv env args let argsR = ConvExprs cenv env args
E.TraitCall(tysR, nm, memFlags, argtysR, tyargsR, argsR) E.TraitCall(tysR, nm, memFlags, argtysR, tyargsR, argsR)
| TOp.RefAddrGet, [ty], [e] -> | TOp.RefAddrGet readonly, [ty], [e] ->
let replExpr = mkRecdFieldGetAddrViaExprAddr(e, mkRefCellContentsRef cenv.g, [ty], m) let replExpr = mkRecdFieldGetAddrViaExprAddr(readonly, e, mkRefCellContentsRef cenv.g, [ty], m)
ConvExprPrim cenv env replExpr ConvExprPrim cenv env replExpr
| _ -> wfail (sprintf "unhandled construct in AST", m) | _ -> wfail (sprintf "unhandled construct in AST", m)

Просмотреть файл

@ -285,7 +285,7 @@ type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol -
FSharpActivePatternCase(cenv, apinfo, typ, n, None, item) :> _ FSharpActivePatternCase(cenv, apinfo, typ, n, None, item) :> _
| Item.ArgName(id, ty, _) -> | Item.ArgName(id, ty, _) ->
FSharpParameter(cenv, ty, {Attribs=[]; Name=Some id}, Some id.idRange, isParamArrayArg=false, isOutArg=false, isOptionalArg=false) :> _ FSharpParameter(cenv, ty, {Attribs=[]; Name=Some id}, Some id.idRange, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false) :> _
// TODO: the following don't currently return any interesting subtype // TODO: the following don't currently return any interesting subtype
| Item.ImplicitOp _ | Item.ImplicitOp _
@ -1747,11 +1747,11 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
match d with match d with
| P p -> | P p ->
[ [ for (ParamData(isParamArrayArg, isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty)) in p.GetParamDatas(cenv.amap, range0) do [ [ for (ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty)) in p.GetParamDatas(cenv.amap, range0) do
// INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for // INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for
// either .NET or F# parameters // either .NET or F# parameters
let argInfo: ArgReprInfo = { Name=nmOpt; Attribs= [] } let argInfo: ArgReprInfo = { Name=nmOpt; Attribs= [] }
yield FSharpParameter(cenv, pty, argInfo, x.DeclarationLocationOpt, isParamArrayArg, isOutArg, optArgInfo.IsOptional) ] yield FSharpParameter(cenv, pty, argInfo, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional) ]
|> makeReadOnlyCollection ] |> makeReadOnlyCollection ]
|> makeReadOnlyCollection |> makeReadOnlyCollection
@ -1759,11 +1759,11 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
| M m | C m -> | M m | C m ->
[ for argtys in m.GetParamDatas(cenv.amap, range0, m.FormalMethodInst) do [ for argtys in m.GetParamDatas(cenv.amap, range0, m.FormalMethodInst) do
yield yield
[ for (ParamData(isParamArrayArg, isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty)) in argtys do [ for (ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, _callerInfoInfo, nmOpt, _reflArgInfo, pty)) in argtys do
// INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for // INCOMPLETENESS: Attribs is empty here, so we can't look at attributes for
// either .NET or F# parameters // either .NET or F# parameters
let argInfo: ArgReprInfo = { Name=nmOpt; Attribs= [] } let argInfo: ArgReprInfo = { Name=nmOpt; Attribs= [] }
yield FSharpParameter(cenv, pty, argInfo, x.DeclarationLocationOpt, isParamArrayArg, isOutArg, optArgInfo.IsOptional) ] yield FSharpParameter(cenv, pty, argInfo, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, optArgInfo.IsOptional) ]
|> makeReadOnlyCollection ] |> makeReadOnlyCollection ]
|> makeReadOnlyCollection |> makeReadOnlyCollection
@ -1780,7 +1780,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
else [typ] else [typ]
yield yield
allArguments allArguments
|> List.map (fun arg -> FSharpParameter(cenv, arg, { Name=None; Attribs= [] }, x.DeclarationLocationOpt, false, false, false)) |> List.map (fun arg -> FSharpParameter(cenv, arg, { Name=None; Attribs= [] }, x.DeclarationLocationOpt, false, false, false, false))
|> makeReadOnlyCollection ] |> makeReadOnlyCollection ]
|> makeReadOnlyCollection |> makeReadOnlyCollection
else makeReadOnlyCollection [] else makeReadOnlyCollection []
@ -1792,9 +1792,10 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
yield yield
[ for argty, argInfo in argtys do [ for argty, argInfo in argtys do
let isParamArrayArg = HasFSharpAttribute cenv.g cenv.g.attrib_ParamArrayAttribute argInfo.Attribs let isParamArrayArg = HasFSharpAttribute cenv.g cenv.g.attrib_ParamArrayAttribute argInfo.Attribs
let isInArg = HasFSharpAttribute cenv.g cenv.g.attrib_InAttribute argInfo.Attribs && isByrefTy cenv.g argty
let isOutArg = HasFSharpAttribute cenv.g cenv.g.attrib_OutAttribute argInfo.Attribs && isByrefTy cenv.g argty let isOutArg = HasFSharpAttribute cenv.g cenv.g.attrib_OutAttribute argInfo.Attribs && isByrefTy cenv.g argty
let isOptionalArg = HasFSharpAttribute cenv.g cenv.g.attrib_OptionalArgumentAttribute argInfo.Attribs let isOptionalArg = HasFSharpAttribute cenv.g cenv.g.attrib_OptionalArgumentAttribute argInfo.Attribs
yield FSharpParameter(cenv, argty, argInfo, x.DeclarationLocationOpt, isParamArrayArg, isOutArg, isOptionalArg) ] yield FSharpParameter(cenv, argty, argInfo, x.DeclarationLocationOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg) ]
|> makeReadOnlyCollection ] |> makeReadOnlyCollection ]
|> makeReadOnlyCollection |> makeReadOnlyCollection
@ -1810,29 +1811,29 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
// For non-standard events, just use the delegate type as the ReturnParameter type // For non-standard events, just use the delegate type as the ReturnParameter type
e.GetDelegateType(cenv.amap, range0) e.GetDelegateType(cenv.amap, range0)
FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isOutArg=false, isOptionalArg=false) FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false)
| P p -> | P p ->
// INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods // INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods
let retInfo: ArgReprInfo = { Name=None; Attribs= [] } let retInfo: ArgReprInfo = { Name=None; Attribs= [] }
let rty = p.GetPropertyType(cenv.amap, range0) let rty = p.GetPropertyType(cenv.amap, range0)
FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isOutArg=false, isOptionalArg=false) FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false)
| M m | C m -> | M m | C m ->
// INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods // INCOMPLETENESS: Attribs is empty here, so we can't look at return attributes for .NET or F# methods
let retInfo: ArgReprInfo = { Name=None; Attribs= [] } let retInfo: ArgReprInfo = { Name=None; Attribs= [] }
let rty = m.GetFSharpReturnTy(cenv.amap, range0, m.FormalMethodInst) let rty = m.GetFSharpReturnTy(cenv.amap, range0, m.FormalMethodInst)
FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isOutArg=false, isOptionalArg=false) FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false)
| V v -> | V v ->
match v.ValReprInfo with match v.ValReprInfo with
| None -> | None ->
let _, tau = v.TypeScheme let _, tau = v.TypeScheme
let _argtysl, rty = stripFunTy cenv.g tau let _argtysl, rty = stripFunTy cenv.g tau
let empty: ArgReprInfo = { Name=None; Attribs= [] } let empty: ArgReprInfo = { Name=None; Attribs= [] }
FSharpParameter(cenv, rty, empty, x.DeclarationLocationOpt, isParamArrayArg=false, isOutArg=false, isOptionalArg=false) FSharpParameter(cenv, rty, empty, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false)
| Some (ValReprInfo(_typars, argInfos, retInfo)) -> | Some (ValReprInfo(_typars, argInfos, retInfo)) ->
let tau = v.TauType let tau = v.TauType
let _c, rty = GetTopTauTypeInFSharpForm cenv.g argInfos tau range0 let _c, rty = GetTopTauTypeInFSharpForm cenv.g argInfos tau range0
FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isOutArg=false, isOptionalArg=false) FSharpParameter(cenv, rty, retInfo, x.DeclarationLocationOpt, isParamArrayArg=false, isInArg=false, isOutArg=false, isOptionalArg=false)
member __.Attributes = member __.Attributes =
@ -2228,7 +2229,7 @@ and FSharpStaticParameter(cenv, sp: Tainted< ExtensionTyping.ProvidedParameterIn
override x.ToString() = override x.ToString() =
"static parameter " + x.Name "static parameter " + x.Name
#endif #endif
and FSharpParameter(cenv, typ:TType, topArgInfo:ArgReprInfo, mOpt, isParamArrayArg, isOutArg, isOptionalArg) = and FSharpParameter(cenv, typ:TType, topArgInfo:ArgReprInfo, mOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg) =
inherit FSharpSymbol(cenv, inherit FSharpSymbol(cenv,
(fun () -> (fun () ->
let m = match mOpt with Some m -> m | None -> range0 let m = match mOpt with Some m -> m | None -> range0
@ -2242,7 +2243,7 @@ and FSharpParameter(cenv, typ:TType, topArgInfo:ArgReprInfo, mOpt, isParamArrayA
member __.cenv: SymbolEnv = cenv member __.cenv: SymbolEnv = cenv
member __.AdjustType(t) = FSharpParameter(cenv, t, topArgInfo, mOpt, isParamArrayArg, isOutArg, isOptionalArg) member __.AdjustType(t) = FSharpParameter(cenv, t, topArgInfo, mOpt, isParamArrayArg, isInArg, isOutArg, isOptionalArg)
member __.Type: FSharpType = FSharpType(cenv, typ) member __.Type: FSharpType = FSharpType(cenv, typ)
@ -2255,6 +2256,8 @@ and FSharpParameter(cenv, typ:TType, topArgInfo:ArgReprInfo, mOpt, isParamArrayA
member __.IsParamArrayArg = isParamArrayArg member __.IsParamArrayArg = isParamArrayArg
member __.IsInArg = isInArg
member __.IsOutArg = isOutArg member __.IsOutArg = isOutArg
member __.IsOptionalArg = isOptionalArg member __.IsOptionalArg = isOptionalArg

Просмотреть файл

@ -850,6 +850,9 @@ and [<Class>] public FSharpParameter =
/// Indicate this is an out argument /// Indicate this is an out argument
member IsOutArg: bool member IsOutArg: bool
/// Indicate this is an in argument
member IsInArg: bool
/// Indicate this is an optional argument /// Indicate this is an optional argument
member IsOptionalArg: bool member IsOptionalArg: bool

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">Neočekávané použití proměnné typu ByRef.</target> <target state="translated">Neočekávané použití proměnné typu ByRef.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">Hodnota musí být proměnlivá, aby se dal změnit obsah nebo aby se dala převzít adresa typu hodnoty, třeba let mutable x = ...</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">Neplatná mutace konstantního výrazu. Zvažte možnost zkopírovat výraz do lokální proměnné, třeba let mutable x = ...</target> <target state="translated">Neplatná mutace konstantního výrazu. Zvažte možnost zkopírovat výraz do lokální proměnné, třeba let mutable x = ...</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">Adresa proměnné {0} se na tomto místě nedá použít. Metoda nebo funkce možná nebude vracet adresu této místní hodnoty.</target> <target state="needs-review-translation">Adresa proměnné {0} se na tomto místě nedá použít. Metoda nebo funkce možná nebude vracet adresu této místní hodnoty.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">Soubor {0} se na disku neočekávaně změnil, opakujte prosím načtení.</target> <target state="translated">Soubor {0} se na disku neočekávaně změnil, opakujte prosím načtení.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">Unerwartete Verwendung einer Variablen vom Typ "byref".</target> <target state="translated">Unerwartete Verwendung einer Variablen vom Typ "byref".</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">Ein Wert muss änderbar sein, um die Inhalte eines Werttyps zu mutieren oder seine Adresse zu übernehmen, z.B. "let mutable x = ...".</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">Ungültige Mutation eines konstanten Ausdrucks. Kopieren Sie den Ausdruck in eine änderbare lokale Variable, z.B. "let mutable x = ...".</target> <target state="translated">Ungültige Mutation eines konstanten Ausdrucks. Kopieren Sie den Ausdruck in eine änderbare lokale Variable, z.B. "let mutable x = ...".</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">Die Adresse der Variablen "{0}" kann an dieser Stelle nicht verwendet werden. Eine Methode oder Funktion gibt ggf. nicht die Adresse dieses lokalen Werts zurück.</target> <target state="needs-review-translation">Die Adresse der Variablen "{0}" kann an dieser Stelle nicht verwendet werden. Eine Methode oder Funktion gibt ggf. nicht die Adresse dieses lokalen Werts zurück.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">Die Datei "{0}" wurde auf dem Datenträger unerwartet geändert. Laden Sie sie erneut.</target> <target state="translated">Die Datei "{0}" wurde auf dem Datenträger unerwartet geändert. Laden Sie sie erneut.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="new">Unexpected use of a byref-typed variable</target> <target state="new">Unexpected use of a byref-typed variable</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="new">Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</target> <target state="new">Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</target> <target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="new">The file '{0}' changed on disk unexpectedly, please reload.</target> <target state="new">The file '{0}' changed on disk unexpectedly, please reload.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">Uso inesperado de una variable de tipo byref.</target> <target state="translated">Uso inesperado de una variable de tipo byref.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">Un valor debe ser mutable para poder mutar el contenido o tomar la dirección de un tipo de valor; por ejemplo, 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">Mutación no válida de una expresión constante. Considere copiar la expresión en un local mutable; por ejemplo, 'let mutable x = ...'.</target> <target state="translated">Mutación no válida de una expresión constante. Considere copiar la expresión en un local mutable; por ejemplo, 'let mutable x = ...'.</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">La dirección de la variable '{0}' no se puede usar en este punto. Puede que el método o la función no devuelvan la dirección de este valor local.</target> <target state="needs-review-translation">La dirección de la variable '{0}' no se puede usar en este punto. Puede que el método o la función no devuelvan la dirección de este valor local.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">El archivo "{0}" cambió en el disco de manera inesperada; cárguelo de nuevo.</target> <target state="translated">El archivo "{0}" cambió en el disco de manera inesperada; cárguelo de nuevo.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">Utilisation inattendue d'une variable typée byref</target> <target state="translated">Utilisation inattendue d'une variable typée byref</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">Une valeur doit être mutable pour pouvoir muter le contenu ou accepter l'adresse d'un type valeur, par exemple 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">Mutation non valide d'une expression constante. Copiez l'expression dans une variable locale mutable, par exemple 'let mutable x = ...'.</target> <target state="translated">Mutation non valide d'une expression constante. Copiez l'expression dans une variable locale mutable, par exemple 'let mutable x = ...'.</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">Impossible d'utiliser l'adresse de la variable '{0}'. Une méthode ou une fonction ne doit pas retourner l'adresse de cette valeur locale.</target> <target state="needs-review-translation">Impossible d'utiliser l'adresse de la variable '{0}'. Une méthode ou une fonction ne doit pas retourner l'adresse de cette valeur locale.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">Changement inattendu du fichier '{0}' sur le disque. Rechargez le fichier.</target> <target state="translated">Changement inattendu du fichier '{0}' sur le disque. Rechargez le fichier.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">Utilizzo non previsto di una variabile di tipo byref</target> <target state="translated">Utilizzo non previsto di una variabile di tipo byref</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">Un valore deve essere modificabile per poter modificare i contenuti oppure utilizzare l'indirizzo di un tipo di valore, ad esempio 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">Modifica non valida di un'espressione costante. Provare a copiare l'espressione in un locale modificabile, ad esempio 'let mutable x = ...'.</target> <target state="translated">Modifica non valida di un'espressione costante. Provare a copiare l'espressione in un locale modificabile, ad esempio 'let mutable x = ...'.</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">In questo punto non è possibile usare l'indirizzo della variabile '{0}'. Un metodo o una funzione potrebbero non restituire l'indirizzo di questo valore di variabile locale.</target> <target state="needs-review-translation">In questo punto non è possibile usare l'indirizzo della variabile '{0}'. Un metodo o una funzione potrebbero non restituire l'indirizzo di questo valore di variabile locale.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">Il file '{0}' è stato modificato su disco in modo imprevisto. Ricaricare.</target> <target state="translated">Il file '{0}' è stato modificato su disco in modo imprevisto. Ricaricare.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">byref 型変数の予期しない使用方法です:</target> <target state="translated">byref 型変数の予期しない使用方法です:</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">値の型の内容を変更するか、値の型のアドレスを使用するために、値は変更可能にする必要があります (たとえば、'let mutable x = ...')</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">定数式の変更は無効です。変更可能なローカルに式をコピーしてください (たとえば、'let mutable x = ...')。</target> <target state="translated">定数式の変更は無効です。変更可能なローカルに式をコピーしてください (たとえば、'let mutable x = ...')。</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">変数 '{0}' のアドレスはこのポイントでは使用できません。メソッドまたは関数がこのローカル値のアドレスを返さない可能性があります。</target> <target state="needs-review-translation">変数 '{0}' のアドレスはこのポイントでは使用できません。メソッドまたは関数がこのローカル値のアドレスを返さない可能性があります。</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">ファイル '{0}' がディスク上で予期せず変更されました。再度読み込んでください。</target> <target state="translated">ファイル '{0}' がディスク上で予期せず変更されました。再度読み込んでください。</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">예기치 않은 byref 형식 변수의 사용입니다.</target> <target state="translated">예기치 않은 byref 형식 변수의 사용입니다.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">내용을 변경하거나 값 형식의 주소를 사용하려면 값을 변경할 수 있어야 합니다(예: 'let mutable x = ...').</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">상수 식을 잘못 변경했습니다. 식을 변경할 수 있는 로컬로 복사하십시오(예: 'let mutable x = ...').</target> <target state="translated">상수 식을 잘못 변경했습니다. 식을 변경할 수 있는 로컬로 복사하십시오(예: 'let mutable x = ...').</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">지금은 '{0}' 변수의 주소를 사용할 수 없습니다. 메서드 또는 함수가 이 로컬 값의 주소를 반환할 수 없습니다.</target> <target state="needs-review-translation">지금은 '{0}' 변수의 주소를 사용할 수 없습니다. 메서드 또는 함수가 이 로컬 값의 주소를 반환할 수 없습니다.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">'{0}' 파일이 디스크에서 예기치 않게 변경되었습니다. 다시 로드하세요.</target> <target state="translated">'{0}' 파일이 디스크에서 예기치 않게 변경되었습니다. 다시 로드하세요.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">Nieoczekiwane użycie zmiennej typu byref</target> <target state="translated">Nieoczekiwane użycie zmiennej typu byref</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">Aby można było zmodyfikować zawartość lub pobrać adres typu wartości, wartość musi być modyfikowalna, na przykład „let mutable x = ...”</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">Nieprawidłowa mutacja wyrażenia stałej. Rozważ skopiowanie wyrażenia do modyfikowalnej wartości lokalnej, na przykład „let mutable x = ...”.</target> <target state="translated">Nieprawidłowa mutacja wyrażenia stałej. Rozważ skopiowanie wyrażenia do modyfikowalnej wartości lokalnej, na przykład „let mutable x = ...”.</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">Adres zmiennej „{0}” nie może być użyty w tym punkcie. Metoda lub funkcja może nie zwrócić adresu tej wartości lokalnej.</target> <target state="needs-review-translation">Adres zmiennej „{0}” nie może być użyty w tym punkcie. Metoda lub funkcja może nie zwrócić adresu tej wartości lokalnej.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">Plik „{0}” nieoczekiwanie uległ zmianie na dysku. Załaduj go ponownie.</target> <target state="translated">Plik „{0}” nieoczekiwanie uległ zmianie na dysku. Załaduj go ponownie.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">Uso inesperado de uma variável do tipo byref</target> <target state="translated">Uso inesperado de uma variável do tipo byref</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">Um valor deve ser mutável para que seja possível mudar o conteúdo ou pegar o endereço de um tipo de valor, por exemplo: 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">Mutação inválida de uma expressão constante. Considere copiar a expressão para um local mutável, por exemplo: 'let mutable x = ...'.</target> <target state="translated">Mutação inválida de uma expressão constante. Considere copiar a expressão para um local mutável, por exemplo: 'let mutable x = ...'.</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">O endereço da variável '{0}' não pode ser usado neste momento. Um método ou uma função pode não retornar o endereço deste valor local.</target> <target state="needs-review-translation">O endereço da variável '{0}' não pode ser usado neste momento. Um método ou uma função pode não retornar o endereço deste valor local.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">O arquivo '{0}' foi alterado no disco inesperadamente. Recarregue-o.</target> <target state="translated">O arquivo '{0}' foi alterado no disco inesperadamente. Recarregue-o.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">Недопустимое использование переменной типа byref</target> <target state="translated">Недопустимое использование переменной типа byref</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">Чтобы изменить содержимое или получить адрес типа значения, значение должно быть изменяемым, например, "let mutable x = ..."</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">Недопустимое изменение константного выражения. Рекомендуется скопировать выражение в изменяемую локальную переменную, например, "let mutable x = ...".</target> <target state="translated">Недопустимое изменение константного выражения. Рекомендуется скопировать выражение в изменяемую локальную переменную, например, "let mutable x = ...".</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">Адрес переменной "{0}" сейчас невозможно использовать. Метод или функция могут не возвратить адрес этого локального значения.</target> <target state="needs-review-translation">Адрес переменной "{0}" сейчас невозможно использовать. Метод или функция могут не возвратить адрес этого локального значения.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">Файл "{0}" был неожиданно изменен на диске, повторите загрузку.</target> <target state="translated">Файл "{0}" был неожиданно изменен на диске, повторите загрузку.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">Beklenmeyen byref olarak belirtilmiş değişken kullanımı</target> <target state="translated">Beklenmeyen byref olarak belirtilmiş değişken kullanımı</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">İçeriği değiştirmek veya değer türünün adresini almak için bir değerin değiştirilebilir olması gerekir, örn. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">Sabit ifadesinin geçersiz olarak değiştirilmesi. İfadeyi değiştirilebilir bir yerel değere kopyalamayı düşünün, örn. 'let mutable x = ...'.</target> <target state="translated">Sabit ifadesinin geçersiz olarak değiştirilmesi. İfadeyi değiştirilebilir bir yerel değere kopyalamayı düşünün, örn. 'let mutable x = ...'.</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">'{0}' değişkeninin adresi bu noktada kullanılamaz. Bir metot veya işlev, bu yerel değerin adresini döndüremez.</target> <target state="needs-review-translation">'{0}' değişkeninin adresi bu noktada kullanılamaz. Bir metot veya işlev, bu yerel değerin adresini döndüremez.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">Diskte '{0}' dosyası beklenmedik şekilde değiştirildi. Lütfen yeniden yükleyin.</target> <target state="translated">Diskte '{0}' dosyası beklenmedik şekilde değiştirildi. Lütfen yeniden yükleyin.</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">对 byref 类型化变量的意外使用</target> <target state="translated">对 byref 类型化变量的意外使用</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">值必须是可变的以便更改内容或采用值类型的地址例如“let mutable x = ...”</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">常数表达式的变化无效。请考虑将该表达式复制一个可变的本地变量例如“let mutable x = ...”。</target> <target state="translated">常数表达式的变化无效。请考虑将该表达式复制一个可变的本地变量例如“let mutable x = ...”。</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">当前无法使用变量 {0} 的地址。方法或函数可能没有返回该本地值的地址。</target> <target state="needs-review-translation">当前无法使用变量 {0} 的地址。方法或函数可能没有返回该本地值的地址。</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">文件“{0}”在磁盘上意外更改,请重新加载。</target> <target state="translated">文件“{0}”在磁盘上意外更改,请重新加载。</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -412,11 +412,6 @@
<target state="translated">未預期的 ByRef 類型變數用法</target> <target state="translated">未預期的 ByRef 類型變數用法</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="translated">值必須是可變動的,才能變動內容或接受實值類型的位址,例如 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tastInvalidMutationOfConstant"> <trans-unit id="tastInvalidMutationOfConstant">
<source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source> <source>Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.</source>
<target state="translated">常數運算式無效的變動。請考慮將運算式複製到可變動的區域變數,例如 'let mutable x = ...'。</target> <target state="translated">常數運算式無效的變動。請考慮將運算式複製到可變動的區域變數,例如 'let mutable x = ...'。</target>
@ -6523,8 +6518,8 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="chkNoByrefReturnOfLocal"> <trans-unit id="chkNoByrefReturnOfLocal">
<source>The address of the variable '{0}' cannot be used at this point. A method or function may not return the address of this local value.</source> <source>The address of the variable '{0}' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.</source>
<target state="translated">目前無法使用變數 '{0}' 的位址。方法或函式無法傳回此本機值的位址。</target> <target state="needs-review-translation">目前無法使用變數 '{0}' 的位址。方法或函式無法傳回此本機值的位址。</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="tcNamedActivePattern"> <trans-unit id="tcNamedActivePattern">
@ -6992,6 +6987,61 @@
<target state="translated">檔案 '{0}' 在磁碟上意外變更,請重新載入。</target> <target state="translated">檔案 '{0}' 在磁碟上意外變更,請重新載入。</target>
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="writeToReadOnlyByref">
<source>The byref pointer is readonly, so this write is not permitted.</source>
<target state="new">The byref pointer is readonly, so this write is not permitted.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeMutable">
<source>A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</source>
<target state="new">A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="readOnlyAttributeOnStructWithMutableField">
<source>A ReadOnly attribute has been applied to a struct type with a mutable field.</source>
<target state="new">A ReadOnly attribute has been applied to a struct type with a mutable field.</target>
<note />
</trans-unit>
<trans-unit id="tcByrefReturnImplicitlyDereferenced">
<source>A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</source>
<target state="new">A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&amp;f(x)' or '&amp;obj.Method(arg1, arg2)'.</target>
<note />
</trans-unit>
<trans-unit id="tcByRefLikeNotStruct">
<source>A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkNoByrefAddressOfLocal">
<source>The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</source>
<target state="new">The address of the variable '{0}' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoReturnOfLimitedSpan">
<source>The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</source>
<target state="new">The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope.</target>
<note />
</trans-unit>
<trans-unit id="chkNoWriteToLimitedSpan">
<source>This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</source>
<target state="new">This value can't be assigned because the target '{0}' may refer to non-stack-local memory, while the expression being assigned is assessed to potentially refer to stack-local memory. This is to help prevent pointers to stack-bound memory escaping their scope.</target>
<note />
</trans-unit>
<trans-unit id="tastValueMustBeLocal">
<source>A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</source>
<target state="new">A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'</target>
<note />
</trans-unit>
<trans-unit id="tcIsReadOnlyNotStruct">
<source>A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</source>
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [&lt;Struct&gt;] attribute to the type.</target>
<note />
</trans-unit>
<trans-unit id="chkStructsMayNotReturnAddressesOfContents">
<source>Struct members cannot return the address of fields of the struct by reference</source>
<target state="new">Struct members cannot return the address of fields of the struct by reference</target>
<note />
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

Просмотреть файл

@ -7,6 +7,7 @@ namespace global
open System open System
open System.IO open System.IO
open System.Text
open System.Diagnostics open System.Diagnostics
[<AutoOpen>] [<AutoOpen>]
@ -117,15 +118,23 @@ module Scripting =
let p = new Process() let p = new Process()
p.EnableRaisingEvents <- true p.EnableRaisingEvents <- true
p.StartInfo <- processInfo p.StartInfo <- processInfo
let out = StringBuilder()
let err = StringBuilder()
cmdArgs.RedirectOutput|> Option.iter (fun f -> cmdArgs.RedirectOutput|> Option.iter (fun f ->
processInfo.RedirectStandardOutput <- true processInfo.RedirectStandardOutput <- true
p.OutputDataReceived.Add (fun ea -> if ea.Data <> null then f ea.Data) p.OutputDataReceived.Add (fun ea ->
if ea.Data <> null then
out.Append(ea.Data + Environment.NewLine) |> ignore
f ea.Data)
) )
cmdArgs.RedirectError |> Option.iter (fun f -> cmdArgs.RedirectError |> Option.iter (fun f ->
processInfo.RedirectStandardError <- true processInfo.RedirectStandardError <- true
p.ErrorDataReceived.Add (fun ea -> if ea.Data <> null then f ea.Data) p.ErrorDataReceived.Add (fun ea ->
if ea.Data <> null then
err.Append(ea.Data + Environment.NewLine) |> ignore
f ea.Data)
) )
cmdArgs.RedirectInput cmdArgs.RedirectInput
@ -151,7 +160,7 @@ module Scripting =
match p.ExitCode with match p.ExitCode with
| 0 -> Success | 0 -> Success
| err -> | err ->
let msg = sprintf "Error running command '%s' with args '%s' in directory '%s'" exePath arguments workDir let msg = sprintf "Error running command '%s' with args '%s' in directory '%s'.\n---- stdout below --- \n%s\n---- stderr below --- \n%s " exePath arguments workDir (out.ToString()) (err.ToString())
ErrorLevel (msg, err) ErrorLevel (msg, err)
type OutPipe (writer: TextWriter) = type OutPipe (writer: TextWriter) =

Просмотреть файл

@ -796,6 +796,20 @@ Microsoft.FSharp.Core.AutoSerializableAttribute: Int32 GetHashCode()
Microsoft.FSharp.Core.AutoSerializableAttribute: System.String ToString() Microsoft.FSharp.Core.AutoSerializableAttribute: System.String ToString()
Microsoft.FSharp.Core.AutoSerializableAttribute: System.Type GetType() Microsoft.FSharp.Core.AutoSerializableAttribute: System.Type GetType()
Microsoft.FSharp.Core.AutoSerializableAttribute: Void .ctor(Boolean) Microsoft.FSharp.Core.AutoSerializableAttribute: Void .ctor(Boolean)
Microsoft.FSharp.Core.ByRefKinds+In: Boolean Equals(System.Object)
Microsoft.FSharp.Core.ByRefKinds+In: Int32 GetHashCode()
Microsoft.FSharp.Core.ByRefKinds+In: System.String ToString()
Microsoft.FSharp.Core.ByRefKinds+In: System.Type GetType()
Microsoft.FSharp.Core.ByRefKinds+Out: Boolean Equals(System.Object)
Microsoft.FSharp.Core.ByRefKinds+Out: Int32 GetHashCode()
Microsoft.FSharp.Core.ByRefKinds+Out: System.String ToString()
Microsoft.FSharp.Core.ByRefKinds+Out: System.Type GetType()
Microsoft.FSharp.Core.ByRefKinds: Boolean Equals(System.Object)
Microsoft.FSharp.Core.ByRefKinds: Int32 GetHashCode()
Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+In
Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+Out
Microsoft.FSharp.Core.ByRefKinds: System.String ToString()
Microsoft.FSharp.Core.ByRefKinds: System.Type GetType()
Microsoft.FSharp.Core.CLIEventAttribute: Boolean Equals(System.Object) Microsoft.FSharp.Core.CLIEventAttribute: Boolean Equals(System.Object)
Microsoft.FSharp.Core.CLIEventAttribute: Boolean Match(System.Object) Microsoft.FSharp.Core.CLIEventAttribute: Boolean Match(System.Object)
Microsoft.FSharp.Core.CLIEventAttribute: Int32 GetHashCode() Microsoft.FSharp.Core.CLIEventAttribute: Int32 GetHashCode()
@ -3195,6 +3209,8 @@ Microsoft.FSharp.NativeInterop.NativePtrModule: T GetPointerInlined[T](IntPtr, I
Microsoft.FSharp.NativeInterop.NativePtrModule: T ReadPointerInlined[T](IntPtr) Microsoft.FSharp.NativeInterop.NativePtrModule: T ReadPointerInlined[T](IntPtr)
Microsoft.FSharp.NativeInterop.NativePtrModule: Void SetPointerInlined[T](IntPtr, Int32, T) Microsoft.FSharp.NativeInterop.NativePtrModule: Void SetPointerInlined[T](IntPtr, Int32, T)
Microsoft.FSharp.NativeInterop.NativePtrModule: Void WritePointerInlined[T](IntPtr, T) Microsoft.FSharp.NativeInterop.NativePtrModule: Void WritePointerInlined[T](IntPtr, T)
Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr OfVoidPtrInlined[T](Void*)
Microsoft.FSharp.NativeInterop.NativePtrModule: Void* ToVoidPtrInlined[T](IntPtr)
Microsoft.FSharp.Quotations.DerivedPatternsModule: Boolean Equals(System.Object) Microsoft.FSharp.Quotations.DerivedPatternsModule: Boolean Equals(System.Object)
Microsoft.FSharp.Quotations.DerivedPatternsModule: Int32 GetHashCode() Microsoft.FSharp.Quotations.DerivedPatternsModule: Int32 GetHashCode()
Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Collections.FSharpList`1[System.Type],Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] SpecificCallPattern(Microsoft.FSharp.Quotations.FSharpExpr) Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Collections.FSharpList`1[System.Type],Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] SpecificCallPattern(Microsoft.FSharp.Quotations.FSharpExpr)

Просмотреть файл

@ -800,6 +800,20 @@ Microsoft.FSharp.Core.AutoSerializableAttribute: System.Object get_TypeId()
Microsoft.FSharp.Core.AutoSerializableAttribute: System.String ToString() Microsoft.FSharp.Core.AutoSerializableAttribute: System.String ToString()
Microsoft.FSharp.Core.AutoSerializableAttribute: System.Type GetType() Microsoft.FSharp.Core.AutoSerializableAttribute: System.Type GetType()
Microsoft.FSharp.Core.AutoSerializableAttribute: Void .ctor(Boolean) Microsoft.FSharp.Core.AutoSerializableAttribute: Void .ctor(Boolean)
Microsoft.FSharp.Core.ByRefKinds+In: Boolean Equals(System.Object)
Microsoft.FSharp.Core.ByRefKinds+In: Int32 GetHashCode()
Microsoft.FSharp.Core.ByRefKinds+In: System.String ToString()
Microsoft.FSharp.Core.ByRefKinds+In: System.Type GetType()
Microsoft.FSharp.Core.ByRefKinds+Out: Boolean Equals(System.Object)
Microsoft.FSharp.Core.ByRefKinds+Out: Int32 GetHashCode()
Microsoft.FSharp.Core.ByRefKinds+Out: System.String ToString()
Microsoft.FSharp.Core.ByRefKinds+Out: System.Type GetType()
Microsoft.FSharp.Core.ByRefKinds: Boolean Equals(System.Object)
Microsoft.FSharp.Core.ByRefKinds: Int32 GetHashCode()
Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+In
Microsoft.FSharp.Core.ByRefKinds: Microsoft.FSharp.Core.ByRefKinds+Out
Microsoft.FSharp.Core.ByRefKinds: System.String ToString()
Microsoft.FSharp.Core.ByRefKinds: System.Type GetType()
Microsoft.FSharp.Core.CLIEventAttribute: Boolean Equals(System.Object) Microsoft.FSharp.Core.CLIEventAttribute: Boolean Equals(System.Object)
Microsoft.FSharp.Core.CLIEventAttribute: Boolean IsDefaultAttribute() Microsoft.FSharp.Core.CLIEventAttribute: Boolean IsDefaultAttribute()
Microsoft.FSharp.Core.CLIEventAttribute: Boolean Match(System.Object) Microsoft.FSharp.Core.CLIEventAttribute: Boolean Match(System.Object)
@ -3342,6 +3356,8 @@ Microsoft.FSharp.NativeInterop.NativePtrModule: T GetPointerInlined[T](IntPtr, I
Microsoft.FSharp.NativeInterop.NativePtrModule: T ReadPointerInlined[T](IntPtr) Microsoft.FSharp.NativeInterop.NativePtrModule: T ReadPointerInlined[T](IntPtr)
Microsoft.FSharp.NativeInterop.NativePtrModule: Void SetPointerInlined[T](IntPtr, Int32, T) Microsoft.FSharp.NativeInterop.NativePtrModule: Void SetPointerInlined[T](IntPtr, Int32, T)
Microsoft.FSharp.NativeInterop.NativePtrModule: Void WritePointerInlined[T](IntPtr, T) Microsoft.FSharp.NativeInterop.NativePtrModule: Void WritePointerInlined[T](IntPtr, T)
Microsoft.FSharp.NativeInterop.NativePtrModule: IntPtr OfVoidPtrInlined[T](Void*)
Microsoft.FSharp.NativeInterop.NativePtrModule: Void* ToVoidPtrInlined[T](IntPtr)
Microsoft.FSharp.Quotations.DerivedPatternsModule: Boolean Equals(System.Object) Microsoft.FSharp.Quotations.DerivedPatternsModule: Boolean Equals(System.Object)
Microsoft.FSharp.Quotations.DerivedPatternsModule: Int32 GetHashCode() Microsoft.FSharp.Quotations.DerivedPatternsModule: Int32 GetHashCode()
Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Collections.FSharpList`1[System.Type],Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] SpecificCallPattern(Microsoft.FSharp.Quotations.FSharpExpr) Microsoft.FSharp.Quotations.DerivedPatternsModule: Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Quotations.FSharpExpr,Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`3[Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Quotations.FSharpExpr],Microsoft.FSharp.Collections.FSharpList`1[System.Type],Microsoft.FSharp.Collections.FSharpList`1[Microsoft.FSharp.Quotations.FSharpExpr]]]] SpecificCallPattern(Microsoft.FSharp.Quotations.FSharpExpr)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -50,11 +50,26 @@ namespace CustomExtensions
{ {
/// Extend an F# type /// Extend an F# type
static public ref readonly DateTime ExtendCSharpTypeWithInRefReturnExtension(in this DateTime inp) { return ref inp; }
static public ref DateTime ExtendCSharpTypeWithRefReturnExtension(ref this DateTime inp) { return ref inp; }
static public void ExtendCSharpTypeWithOutRefExtension(ref this DateTime inp) { inp = inp.Date; }
static public int ExtendCSharpTypeWithInRefExtension(ref this DateTime inp) { return inp.Year; }
static public int ExtendFSharpType(this Lib.recd1 recd) { return 5; } static public int ExtendFSharpType(this Lib.recd1 recd) { return 5; }
static public int ExtendCSharpType(this Lib2 recd) { return 4; } static public int ExtendCSharpType(this Lib2 recd) { return 4; }
} }
} }
namespace Fields
{
public class Fields
{
/// Extend an F# type
static public int StaticIntField => 3;
static public System.DateTime StaticDateTimeField => System.DateTime.Now.Date;
}
}
namespace Newtonsoft.Json.Converters namespace Newtonsoft.Json.Converters
{ {
internal class SomeClass internal class SomeClass

Просмотреть файл

@ -16,6 +16,11 @@ let test (s : string) b =
if b then stderr.WriteLine " OK" if b then stderr.WriteLine " OK"
else report_failure (s) else report_failure (s)
let check (s : string) x y =
stderr.Write(s)
if x = y then stderr.WriteLine " OK"
else report_failure (sprintf "%s: expected %A, got %A" s y x)
#if NO_LIB_REFERENCE // Test for https://github.com/Microsoft/visualfsharp/issues/2453#issuecomment-280946177 #if NO_LIB_REFERENCE // Test for https://github.com/Microsoft/visualfsharp/issues/2453#issuecomment-280946177
module TestExtensions = module TestExtensions =
open CustomExtensions open CustomExtensions
@ -154,8 +159,19 @@ let TestAccessibility() =
module TestExtensions = module TestExtensions =
open CustomExtensions open CustomExtensions
test "dfeweeon" (r1.ExtendFSharpType() = 5) check "dfeweeon" (r1.ExtendFSharpType()) 5
test "dfeweeon" (Lib2().ExtendCSharpType() = 4) check "dfeweeon" (Lib2().ExtendCSharpType()) 4
let x = System.DateTime.Now
check "dfeweeon1" (System.DateTime.Now.ExtendCSharpTypeWithInRefReturnExtension()).Date x.Date
check "dfeweeon2" (x.ExtendCSharpTypeWithInRefReturnExtension()).Date x.Date
check "dfeweeon3" (x.ExtendCSharpTypeWithRefReturnExtension()).Date x.Date
let mutable mx = x
check "dfeweeon4" (mx.ExtendCSharpTypeWithOutRefExtension(); mx) x.Date
check "dfeweeon5" (x.ExtendCSharpTypeWithInRefExtension()) x.Year
#endif #endif

Просмотреть файл

@ -31,4 +31,6 @@ try
asmBuilder.Save(filename) asmBuilder.Save(filename)
exit 0 exit 0
with _ -> exit 1 with err ->
printfn "Error: %A" err
exit 1

Просмотреть файл

@ -0,0 +1,401 @@
#r @"..\..\..\..\packages\System.Memory.4.5.0-rc1\lib\netstandard2.0\System.Memory.dll"
#r @"..\..\..\..\packages\NETStandard.Library.NETFramework.2.0.0-preview2-25405-01\build\net461\ref\netstandard.dll"
namespace System.Runtime.CompilerServices
open System
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
[<AttributeUsage(AttributeTargets.All,AllowMultiple=false)>]
[<Sealed>]
type IsReadOnlyAttribute() =
inherit System.Attribute()
[<AttributeUsage(AttributeTargets.All,AllowMultiple=false)>]
[<Sealed>]
type IsByRefLikeAttribute() =
inherit System.Attribute()
namespace Tests
open System
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
open FSharp.NativeInterop
[<AutoOpen>]
module Helpers =
let failures = ref false
let report_failure (s) =
stderr.WriteLine ("NO: " + s);
failures := true
let test s b = if b then () else report_failure(s)
(* TEST SUITE FOR Int32 *)
let out r (s:string) = r := !r @ [s]
let check s actual expected =
if actual = expected then printfn "%s: OK" s
else report_failure (sprintf "%s: FAILED, expected %A, got %A" s expected actual)
let check2 s expected actual = check s actual expected
[<IsReadOnly; Struct>]
type ReadOnlyStruct(count1: int, count2: int) =
member x.Count1 = count1
member x.Count2 = count2
[<IsByRefLike; Struct>]
type ByRefLikeStruct(count1: int, count2: int) =
member x.Count1 = count1
member x.Count2 = count2
module TypeRefTests =
let f1 (x: ByRefLikeStruct) = ()
let f2 (x: ReadOnlyStruct) = x.Count1
let f3 (x: ReadOnlyStruct) = x
let f4 (x: Span<int>) = ()
let f5 (x: Memory<int>) = ()
let f6 (x: ReadOnlySpan<int>) = ()
let f7 (x: ReadOnlyMemory<int>) = ()
module Sample1 =
open FSharp.NativeInterop
open System.Runtime.InteropServices
// this method does not care what kind of memory it works on
let SafeSum(bytes: Span<byte>) =
let mutable sum = 0
for i in 0 .. bytes.Length - 1 do
sum <- sum + int bytes.[i]
sum
let SafeSum2(bytes: Span<byte>) =
let mutable sum = 0
for i in 0 .. bytes.Length - 1 do
let byteAddr = &bytes.[i]
sum <- sum + int byteAddr
sum
let SafeSum3(bytes: Memory<byte>) =
let bytes = bytes.Span
let mutable sum = 0
for i in 0 .. bytes.Length - 1 do
let byteAddr = &bytes.[i]
sum <- sum + int byteAddr
sum
let SafeSum4(bytes: Memory<byte>) =
let bytes = bytes.Span
let mutable sum = 0
for i in 0 .. bytes.Length - 1 do
sum <- sum + int bytes.[i]
sum
let SafeSum5(bytes: ReadOnlySpan<byte>) =
let mutable sum = 0
for i in 0 .. bytes.Length - 1 do
sum <- sum + int bytes.[i]
sum
let SafeSum6(bytes: ReadOnlySpan<byte>) =
let mutable sum = 0
for i in 0 .. bytes.Length - 1 do
let byteAddr = &bytes.[i]
sum <- sum + int byteAddr
sum
let SafeSum7(bytes: ReadOnlyMemory<byte>) =
let bytes = bytes.Span
let mutable sum = 0
for i in 0 .. bytes.Length - 1 do
let byteAddr = &bytes.[i]
sum <- sum + int byteAddr
sum
let SafeSum8(bytes: ReadOnlyMemory<byte>) =
let bytes = bytes.Span
let mutable sum = 0
for i in 0 .. bytes.Length - 1 do
sum <- sum + int bytes.[i]
sum
let f6() =
// managed memory
let arrayMemory = Array.zeroCreate<byte>(100)
let arraySpan = new Span<byte>(arrayMemory)
for i in 0 .. 99 do arrayMemory.[i] <- byte i
SafeSum(arraySpan)|> printfn "res = %d"
// native memory
let nativeMemory = Marshal.AllocHGlobal(100)
let nativeSpan = new Span<byte>(nativeMemory.ToPointer(), 100)
for i in 0 .. 99 do Marshal.WriteByte(nativeMemory, i, byte i)
SafeSum(nativeSpan)|> printfn "res = %d"
Marshal.FreeHGlobal(nativeMemory)
// stack memory
let mem = NativePtr.stackalloc<byte>(100)
let mem2 = mem |> NativePtr.toVoidPtr
for i in 0 .. 99 do NativePtr.set mem i (byte i)
let stackSpan = Span<byte>(mem2, 100)
SafeSum(stackSpan) |> printfn "res = %d"
f6()
[<Struct>]
type AllowedEvilStruct =
[<DefaultValue>]
val mutable v : int
member x.Replace(y:AllowedEvilStruct) = x <- y
module SubsumptionOnMember =
type Doot() = class end
[<Sealed>]
type GiantDad() =
let test (data: Span<byte>) (doot: Doot) =
()
member __.Test(data: Span<byte>) =
test data Unchecked.defaultof<Doot>
module AssignToByrefReturn =
type C() =
static let mutable v = System.DateTime.Now
static member M() = &v
let F1() =
C.M() <- System.DateTime.Now
module AssignToSpanItem =
let F2() =
let data = Span<byte>.Empty
data.[0] <- 1uy
module AssignToSpanItemGeneric =
let F2<'T>() =
let data = Span<'T>.Empty
data.[0] <- Unchecked.defaultof<'T>
module CheckReturnOfSpan1 =
let test () =
let s = Span<byte>.Empty
s
module CheckReturnOfSpan2 =
type Jopac() =
member this.Create() =
let mutable x = 1
this.Create(&x)
member __.Create(x: byref<int>) =
Span<int>.Empty
module CheckReturnOfSpan3 =
type Jopac_NotCompile_WhichIsMightBeIncorrect() =
member __.Create(x: byref<int>) =
Span<int>.Empty
member this.Create() =
let mutable x = 1
let x = this.Create(&x)
x
member this.CreateAgain() =
let mutable x = 1
this.Create(&x)
module ByRefSpanParam =
type C() =
static member M(x: byref<Span<int>>) = x.[0] <- 5
let Test() =
let mutable res = 9
let mutable span = Span<int>(NativePtr.toVoidPtr &&res,1)
let v = C.M(&span)
check "cwvereweoiwekl4" res 5
let minfo = typeof<C>.GetMethod("M")
check "cwnoreeker1" (minfo.GetParameters().[0].IsIn) false
check "cwnoreeker2" (minfo.GetParameters().[0].IsOut) false
check "cwnoreeker3" (minfo.ReturnParameter.IsIn) false
check "cwnoreeker4" (minfo.ReturnParameter.IsOut) false
Test()
module SpanByRefReturn =
type C() =
static member M(x: byref<Span<int>>) = x.[0] <- x.[0] + 1; &x
let Test() =
let mutable res = 9
let mutable span = Span<int>(NativePtr.toVoidPtr &&res,1)
let v = &C.M(&span)
check "cwvereweoiwvw4" v.[0] 10
let minfo = typeof<C>.GetMethod("M")
check "cwnoreeker6d" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0
check "cwnoreekerr" (minfo.ReturnParameter.IsIn) false
check "cwnoreekert" (minfo.ReturnParameter.IsOut) false
Test()
module SpanReturn =
type C() =
static member M(x: byref<Span<int>>) = x.[0] <- x.[0] + 1; x
let Test() =
let mutable res = 9
let mutable span = Span<int>(NativePtr.toVoidPtr &&res,1)
let v = C.M(&span)
check "cwvereweoiwvw4" v.[0] 10
let minfo = typeof<C>.GetMethod("M")
check "cwnoreeker6d" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0
check "cwnoreekerr" (minfo.ReturnParameter.IsIn) false
check "cwnoreekert" (minfo.ReturnParameter.IsOut) false
Test()
module SpanSafetyTests0 =
type SpanLikeType = Span<int>
let m1 (x: byref<Span<int>>) (y: Span<byte>) =
// this is all valid, unconcerned with stack-referring stuff
let local = SpanLikeType()
x <- local
x
module SpanSafetyTests1 =
type SpanLikeType = Span<int>
let m1 (x: byref<Span<int>>) (y: Span<byte>) =
// this is all valid, unconcerned with stack-referring stuff
let local = SpanLikeType()
x <- local
x
let test1 (param1: byref<Span<int>>) (param2: Span<byte>) =
let mutable stackReferringBecauseMutable1 = Span<byte>()
//let stackReferringBecauseMutable1 = Span<byte>(NativePtr.toVoidPtr(&&x), 1)
//let stackReferringBecauseMutable1 = Span<byte>(NativePtr.toVoidPtr(NativePtr.ofByRef(&&x)), 1)
//let stackReferring1 = Span<byte>(NativePtr.toVoidPtr(NativePtr.stackalloc< byte>(100), 1)
let mutable stackReferringBecauseMutable2 = Span<int>()
// this is allowed
stackReferringBecauseMutable2 <- m1 &stackReferringBecauseMutable2 stackReferringBecauseMutable1
// this is allowed
stackReferringBecauseMutable2 <- m1 &param1 stackReferringBecauseMutable1
#if NEGATIVE
// this is NOT allowed
param1 <- m1 &stackReferringBecauseMutable2 stackReferringBecauseMutable1
// this is NOT allowed
param1 <- stackReferringBecauseMutable2.Slice(10)
#endif
// this is allowed
param1 <- Span<int>()
// this is allowed
stackReferringBecauseMutable2 <- param1
module SpanSafetyTests2 =
let m2 (x: byref<Span<int>>) =
// should compile
&x
module SpanSafetyTests3 =
type SpanLikeType = Span<int>
let m1 (x: byref<Span<int>>) (y: Span<byte>) =
// this is all valid, unconcerned with stack-referring stuff
let local = SpanLikeType()
x <- local
x
let m2 (x: byref<Span<int>>) =
// should compile
&x
let test2 (param1: byref<Span<int>>) (param2: Span<byte>) =
let mutable stackReferringBecauseMutable1 = Span<byte>()
let mutable stackReferringBecauseMutable2 = Span<int>()
let stackReferring3 = &(m2 &stackReferringBecauseMutable2)
// this is allowed
stackReferring3 <- m1 &stackReferringBecauseMutable2 stackReferringBecauseMutable1
// this is allowed
m2(&stackReferring3) <- stackReferringBecauseMutable2
#if NEGATIVE2
// this is NOT allowed
m1(&param1) <- stackReferringBecauseMutable2
// this is NOT allowed
param1 <- stackReferring3
// this is NOT allowed
&stackReferring3
#endif
// this is allowed
//&param1 - uncomment to test return
module SpanSafetyTests4 =
let test2 (param1: byref<Span<int>>) (param2: Span<byte>) =
// this is allowed
&param1 // uncomment to test return
#if NEGATIVE
module CheckReturnOfSpan4 =
type Jopac_NotCompile_WhichIsCorrect() =
member __.Create(x: byref<int>) =
&x
member this.Create() =
let mutable x = 1
let x = &this.Create(&x)
&x
member this.CreateAgain() =
let mutable x = 1
&this.Create(&x)
#endif
#if NOT_YET
// Disallow this:
[<IsReadOnly; Struct>]
type DisallowedIsReadOnlyStruct =
[<DefaultValue>]
val mutable X : int
// Allow this:
[<IsByRefLike; Struct>]
type ByRefLikeStructWithSpanField(count1: Span, count2: int) =
member x.Count1 = count1
member x.Count2 = count2
[<IsByRefLike; Struct>]
type ByRefLikeStructWithByrefField(count1: Span<int>, count2: int) =
member x.Count1 = count1
member x.Count2 = count2
#endif

Просмотреть файл

@ -0,0 +1,15 @@
namespace System.Runtime.CompilerServices
open System
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
[<AttributeUsage(AttributeTargets.All,AllowMultiple=false)>]
[<Sealed>]
type IsReadOnlyAttribute() =
inherit System.Attribute()
[<AttributeUsage(AttributeTargets.All,AllowMultiple=false)>]
[<Sealed>]
type IsByRefLikeAttribute() =
inherit System.Attribute()

Просмотреть файл

@ -1,5 +1,5 @@
#if INTERACTIVE // vvvvvvvvvvvvv To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test vvvvvvvvvvvvvvvv
//#r @"../../release/net40/bin/FSharp.Compiler.dll" #if INTERACTIVE
#r @"../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll" #r @"../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#load "../../src/scripts/scriptlib.fsx" #load "../../src/scripts/scriptlib.fsx"
#load "test-framework.fs" #load "test-framework.fs"
@ -25,6 +25,7 @@ let FSI_BASIC = FSI_CORECLR
let FSC_BASIC = FSC_OPT_PLUS_DEBUG let FSC_BASIC = FSC_OPT_PLUS_DEBUG
let FSI_BASIC = FSI_FILE let FSI_BASIC = FSI_FILE
#endif #endif
// ^^^^^^^^^^^^ To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test ^^^^^^^^^^^^
module CoreTests = module CoreTests =
// These tests are enabled for .NET Framework and .NET Core // These tests are enabled for .NET Framework and .NET Core
@ -176,17 +177,61 @@ module CoreTests =
let cfg = testConfig "core/byrefs" let cfg = testConfig "core/byrefs"
use testOkFile = fileguard cfg "test.ok" begin
use testOkFile = fileguard cfg "test.ok"
fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"] fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
exec cfg ("." ++ "test.exe") "" exec cfg ("." ++ "test.exe") ""
testOkFile.CheckExists() testOkFile.CheckExists()
end
fsi cfg "" ["test.fsx"] begin
use testOkFile = fileguard cfg "test.ok"
fsi cfg "" ["test.fsx"]
testOkFile.CheckExists() testOkFile.CheckExists()
end
begin
use testOkFile = fileguard cfg "test.ok"
fsiAnyCpu cfg "" ["test.fsx"]
testOkFile.CheckExists()
end
[<Test>]
let span () =
let cfg = testConfig "core/span"
begin
use testOkFile = fileguard cfg "test.ok"
fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
// Execution is disabled until we can be sure .NET 4.7.2 is on the machine
//exec cfg ("." ++ "test.exe") ""
//testOkFile.CheckExists()
end
// Execution is disabled until we can be sure .NET 4.7.2 is on the machine
//begin
// use testOkFile = fileguard cfg "test.ok"
// fsi cfg "" ["test.fsx"]
// testOkFile.CheckExists()
//end
// Execution is disabled until we can be sure .NET 4.7.2 is on the machine
//begin
// use testOkFile = fileguard cfg "test.ok"
// fsiAnyCpu cfg "" ["test.fsx"]
// testOkFile.CheckExists()
//end
[<Test>] [<Test>]
let asyncStackTraces () = let asyncStackTraces () =
@ -381,19 +426,22 @@ module CoreTests =
peverify cfg "lib.dll" peverify cfg "lib.dll"
csc cfg """/nologo /target:library /r:"%s" /r:lib.dll /out:lib2.dll""" cfg.FSCOREDLLPATH ["lib2.cs"] csc cfg """/nologo /target:library /r:"%s" /r:lib.dll /out:lib2.dll /langversion:7.2""" cfg.FSCOREDLLPATH ["lib2.cs"]
csc cfg """/nologo /target:library /r:"%s" /out:lib3.dll""" cfg.FSCOREDLLPATH ["lib3.cs"] csc cfg """/nologo /target:library /r:"%s" /out:lib3.dll /langversion:7.2""" cfg.FSCOREDLLPATH ["lib3.cs"]
fsc cfg "%s -r:lib.dll -r:lib2.dll -r:lib3.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"] fsc cfg "%s -r:lib.dll -r:lib2.dll -r:lib3.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
peverify cfg "test.exe" peverify cfg "test.exe"
exec cfg ("." ++ "test.exe") ""
// Same with library references the other way around // Same with library references the other way around
fsc cfg "%s -r:lib.dll -r:lib3.dll -r:lib2.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"] fsc cfg "%s -r:lib.dll -r:lib3.dll -r:lib2.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
peverify cfg "test.exe" peverify cfg "test.exe"
exec cfg ("." ++ "test.exe") ""
// Same without the reference to lib.dll - testing an incomplete reference set, but only compiling a subset of the code // Same without the reference to lib.dll - testing an incomplete reference set, but only compiling a subset of the code
fsc cfg "%s -r:System.Runtime.dll --noframework --define:NO_LIB_REFERENCE -r:lib3.dll -r:lib2.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"] fsc cfg "%s -r:System.Runtime.dll --noframework --define:NO_LIB_REFERENCE -r:lib3.dll -r:lib2.dll -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
@ -2299,6 +2347,12 @@ module TypecheckTests =
[<Test>] [<Test>]
let ``type check neg102`` () = singleNegTest (testConfig "typecheck/sigs") "neg102" let ``type check neg102`` () = singleNegTest (testConfig "typecheck/sigs") "neg102"
[<Test>]
let ``type check neg106`` () = singleNegTest (testConfig "typecheck/sigs") "neg106"
[<Test>]
let ``type check neg107`` () = singleNegTest (testConfig "typecheck/sigs") "neg107"
[<Test>] [<Test>]
let ``type check neg103`` () = singleNegTest (testConfig "typecheck/sigs") "neg103" let ``type check neg103`` () = singleNegTest (testConfig "typecheck/sigs") "neg103"

Просмотреть файл

@ -1,5 +1,8 @@
namespace global namespace global
[<assembly: System.Reflection.AssemblyCopyrightAttribute("hey!")>]
do ()
type TheGeneratedType1() = type TheGeneratedType1() =
member x.Prop1 = 1 member x.Prop1 = 1
static member (+) (x1:TheGeneratedType1,x2:TheGeneratedType1) = x1 static member (+) (x1:TheGeneratedType1,x2:TheGeneratedType1) = x1

124
tests/fsharp/typecheck/sigs/neg106.bsl поставляемый Normal file
Просмотреть файл

@ -0,0 +1,124 @@
neg106.fs(8,59,8,61): typecheck error FS3231: A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'
neg106.fs(13,18,13,72): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<int>, value: int, comparand: int) : int'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<int64>, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int64>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<float32>, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<float32>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<float>, value: float, comparand: float) : float'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<float>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<obj>, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<obj>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<nativeint>, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<nativeint>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange<'T when 'T : not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<'a>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<int>, value: int, comparand: int) : int'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<int64>, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int64>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<float32>, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<float32>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<float>, value: float, comparand: float) : float'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<float>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<obj>, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<obj>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<nativeint>, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<nativeint>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange<'T when 'T : not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<'a>'
.
neg106.fs(23,35,23,39): typecheck error FS0001: Type mismatch. Expecting a
'byref<int>'
but given a
'inref<int>'
The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'
neg106.fs(31,22,31,26): typecheck error FS0001: Type mismatch. Expecting a
'byref<int>'
but given a
'inref<int>'
The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'
neg106.fs(40,18,40,32): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below.
neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref<int> -> unit'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int>'
.
neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref<int> -> unit'. Type constraint mismatch. The type
'string'
is not compatible with type
'int'
.
neg106.fs(41,19,41,31): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below.
neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref<int> -> unit'. Type constraint mismatch. The type
'int'
is not compatible with type
'string'
.
neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref<int> -> unit'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int>'
.
neg106.fs(49,22,49,26): typecheck error FS0001: Type mismatch. Expecting a
'byref<int>'
but given a
'inref<int>'
The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'
neg106.fs(60,9,60,25): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted.
neg106.fs(65,42,65,48): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted.
neg106.fs(74,9,74,17): typecheck error FS0257: Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.

Просмотреть файл

@ -0,0 +1,74 @@
module M
//#r @"..\..\..\..\packages\System.Memory.4.5.0-rc1\lib\netstandard2.0\System.Memory.dll"
//#r @"..\..\..\..\packages\NETStandard.Library.NETFramework\2.0.0-preview2-25405-01\build\net461\ref\netstandard.dll"
module CompareExchangeTests_Negative1 =
let x = 3
let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) // No overloads match for method 'CompareExchange'. 'inref<int>' is not compatible with type 'byref<int>'
module CompareExchangeTests_Negative1b =
let Test() =
let x = 3
let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) // No overloads match for method 'CompareExchange'. 'inref<int>' is not compatible with type 'byref<int>'
()
module CompareExchangeTests_Negative2 =
let v = System.Threading.Interlocked.CompareExchange(&3, 3, 4) // 'inref<int>' is not compatible with type 'byref<int>'
module TryGetValueTests_Negative1 =
let Test() =
let d = dict [ (3,4) ]
let res = 9
let v = d.TryGetValue(3, &res) // 'inref<int,>' is not compatible with type 'byref<int>'
()
module FSharpDeclaredOutParamTest_Negaative1 =
type C() =
static member M([<System.Runtime.InteropServices.Out>] x: byref<int>) = ()
let Test() =
let res = 9
let v = C.M(&res) //'inref<int>' is not compatible with type 'byref<int>'
()
module FSharpDeclaredOverloadedOutParamTest_Negative1 =
type C() =
static member M(a: int, [<System.Runtime.InteropServices.Out>] x: byref<int>) = x <- 7
static member M(a: string, [<System.Runtime.InteropServices.Out>] x: byref<int>) = x <- 8
let Test() =
let res = 9
let v = C.M("a", &res) //'inref<int>' is not compatible with type 'byref<int>'
let v2 = C.M(3, &res) //'inref<int>' is not compatible with type 'byref<int>'
()
module FSharpDeclaredOutParamTest_Negative1 =
type C() =
static member M([<System.Runtime.InteropServices.Out>] x: byref<int>) = ()
let Test() =
let res = 9
let v = C.M(&res) // 'inref<int>' is not compatible with type 'byref<int>'
()
module TestOneArgumentInRefThenMutate_Negative1 =
type C() =
static member M (x:inref<int>) = &x
let test() =
let mutable r1 = 1
let addr = &C.M (&r1) // Expecting a 'byref<int,ByRefKinds.Out>' but given a 'inref<int>'. The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In'
addr <- addr + 1 // "The byref pointer is readonly, so this write is not permitted"
module EvilStruct_Negative1 =
[<Struct>]
type EvilStruct(s: int) =
member x.Replace(y:EvilStruct) = x <- y
module MutateInRef1 =
[<Struct>]
type TestMut =
val mutable x : int
let testIn (m: inref<TestMut>) =
m.x <- 1

Просмотреть файл

@ -0,0 +1,124 @@
neg106.fs(8,59,8,61): typecheck error FS3231: A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...'
neg106.fs(13,18,13,72): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<int>, value: int, comparand: int) : int'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<int64>, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int64>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<float32>, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<float32>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<float>, value: float, comparand: float) : float'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<float>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<obj>, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<obj>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<nativeint>, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<nativeint>'
.
neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange<'T when 'T : not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<'a>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<int>, value: int, comparand: int) : int'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<int64>, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int64>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<float32>, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<float32>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<float>, value: float, comparand: float) : float'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<float>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<obj>, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<obj>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref<nativeint>, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<nativeint>'
.
neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange<'T when 'T : not struct>(location1: byref<'T>, value: 'T, comparand: 'T) : 'T'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<'a>'
.
neg106.fs(23,35,23,39): typecheck error FS0001: Type mismatch. Expecting a
'byref<int>'
but given a
'inref<int>'
The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'
neg106.fs(31,22,31,26): typecheck error FS0001: Type mismatch. Expecting a
'byref<int>'
but given a
'inref<int>'
The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'
neg106.fs(40,18,40,32): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below.
neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref<int> -> unit'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int>'
.
neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref<int> -> unit'. Type constraint mismatch. The type
'string'
is not compatible with type
'int'
.
neg106.fs(41,19,41,31): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below.
neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref<int> -> unit'. Type constraint mismatch. The type
'int'
is not compatible with type
'string'
.
neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref<int> -> unit'. Type constraint mismatch. The type
'inref<int>'
is not compatible with type
'byref<int>'
.
neg106.fs(49,22,49,26): typecheck error FS0001: Type mismatch. Expecting a
'byref<int>'
but given a
'inref<int>'
The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In'
neg106.fs(60,9,60,25): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted.
neg106.fs(65,42,65,48): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted.
neg106.fs(74,9,74,17): typecheck error FS0257: Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'.

66
tests/fsharp/typecheck/sigs/neg107.bsl поставляемый Normal file
Просмотреть файл

@ -0,0 +1,66 @@
neg107.fsx(26,48,26,59): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(27,69,27,80): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(28,43,28,59): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(28,47,28,58): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(28,57,28,58): typecheck error FS0418: The byref typed value 'a' cannot be used at this point
neg107.fsx(28,47,28,58): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(29,51,29,67): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(29,55,29,66): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(29,65,29,66): typecheck error FS0418: The byref typed value 'a' cannot be used at this point
neg107.fsx(29,55,29,66): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(31,49,31,54): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(31,57,31,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(32,70,32,75): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(32,78,32,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(33,48,33,53): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(33,48,33,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(33,56,33,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(33,56,33,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(33,56,33,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(33,48,33,53): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(34,56,34,61): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(34,56,34,61): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(34,64,34,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(34,64,34,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(34,64,34,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(34,56,34,61): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(37,33,37,34): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(37,33,37,34): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(45,34,45,40): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference
neg107.fsx(45,34,45,38): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference
neg107.fsx(53,34,53,38): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference
neg107.fsx(67,34,67,40): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference
neg107.fsx(67,34,67,38): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference

Просмотреть файл

@ -0,0 +1,67 @@
#r @"..\..\..\..\packages\System.Memory.4.5.0-rc1\lib\netstandard2.0\System.Memory.dll"
#r @"..\..\..\..\packages\NETStandard.Library.NETFramework.2.0.0-preview2-25405-01\build\net461\ref\netstandard.dll"
namespace System.Runtime.CompilerServices
open System
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
[<AttributeUsage(AttributeTargets.All,AllowMultiple=false)>]
[<Sealed>]
type IsReadOnlyAttribute() =
inherit System.Attribute()
[<AttributeUsage(AttributeTargets.All,AllowMultiple=false)>]
[<Sealed>]
type IsByRefLikeAttribute() =
inherit System.Attribute()
namespace Test
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
open System
module Span_Negative1 =
let TestClosure1 (a: inref<int>) = id (fun () -> a)
let TestClosure1b ([<In; IsReadOnly>] a: byref<int>) = id (fun () -> a)
let TestClosure2 (a: Span<int>) = id (fun () -> a)
let TestClosure3 (a: ReadOnlySpan<int>) = id (fun () -> a)
let TestAsyncClosure1 (a: inref<int>) = async { return a }
let TestAsyncClosure1b ([<In; IsReadOnly>] a: byref<int>) = async { return a }
let TestAsyncClosure2 (a: Span<int>) = async { return a }
let TestAsyncClosure3 (a: ReadOnlySpan<int>) = async { return a }
module Span_Negative2 =
let TestLocal1 () = let x = Span() in x
module MutateInRef2 =
[<Struct>]
type TestMut =
val mutable x : int
member this.XAddr = &this.x // not allowed, Struct members cannot return the address of fields of the struct by reference", not entirely clear why C# disallowed this
module MutateInRef3 =
[<Struct>]
type TestMut =
val mutable x : int
member this.XAddr = &this // not allowed, Struct members cannot return the address of fields of the struct by reference", not entirely clear why C# disallowed this
module MutateInRef4 =
[<Struct>]
type TestMut1 =
val mutable x : int
[<Struct>]
type TestMut2 =
val mutable x : TestMut1
member this.XAddr = &this.x.x // not allowed, Struct members cannot return the address of fields of the struct by reference", not entirely clear why C# disallowed this

Просмотреть файл

@ -0,0 +1,66 @@
neg107.fsx(26,48,26,59): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(27,69,27,80): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(28,43,28,59): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(28,47,28,58): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(28,57,28,58): typecheck error FS0418: The byref typed value 'a' cannot be used at this point
neg107.fsx(28,47,28,58): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(29,51,29,67): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(29,55,29,66): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(29,65,29,66): typecheck error FS0418: The byref typed value 'a' cannot be used at this point
neg107.fsx(29,55,29,66): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(31,49,31,54): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(31,57,31,65): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(32,70,32,75): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(32,78,32,86): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(33,48,33,53): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(33,48,33,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(33,56,33,64): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(33,56,33,64): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(33,56,33,64): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(33,48,33,53): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(34,56,34,61): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(34,56,34,61): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(34,64,34,72): typecheck error FS0406: The byref-typed variable 'a' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions.
neg107.fsx(34,64,34,72): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg107.fsx(34,64,34,72): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(34,56,34,61): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(37,33,37,34): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(37,33,37,34): typecheck error FS0425: The type of a first-class function cannot contain byrefs
neg107.fsx(45,34,45,40): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference
neg107.fsx(45,34,45,38): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference
neg107.fsx(53,34,53,38): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference
neg107.fsx(67,34,67,40): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference
neg107.fsx(67,34,67,38): typecheck error FS3234: Struct members cannot return the address of fields of the struct by reference

4
tests/fsharp/typecheck/sigs/neg63.bsl поставляемый
Просмотреть файл

@ -9,6 +9,6 @@ neg63.fs(11,5,11,13): typecheck error FS0412: A type instantiation involves a by
neg63.fs(14,8,14,9): typecheck error FS3155: A quotation may not involve an assignment to or taking the address of a captured local variable neg63.fs(14,8,14,9): typecheck error FS3155: A quotation may not involve an assignment to or taking the address of a captured local variable
neg63.fs(18,6,18,7): typecheck error FS3209: The address of the variable 'x' cannot be used at this point. A method or function may not return the address of this local value. neg63.fs(18,6,18,7): typecheck error FS3209: The address of the variable 'x' or a related expression cannot be used at this point. This is to ensure the address of the local value does not escape its scope.
neg63.fs(26,6,26,10): typecheck error FS3209: The address of the variable 'addr' cannot be used at this point. A method or function may not return the address of this local value. neg63.fs(26,6,26,10): typecheck error FS3228: The address of the variable 'addr' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.

2
tests/fsharp/typecheck/sigs/neg97.bsl поставляемый
Просмотреть файл

@ -1,5 +1,5 @@
neg97.fs(13,1,13,2): typecheck error FS0256: A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' neg97.fs(13,1,13,10): typecheck error FS0256: A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'
neg97.fs(16,9,16,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. neg97.fs(16,9,16,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.

Просмотреть файл

@ -0,0 +1,28 @@
neg97.fs(13,1,13,10): typecheck error FS0256: A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'
neg97.fs(16,9,16,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.
neg97.fs(16,9,16,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'
neg97.fs(20,9,20,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.
neg97.fs(20,9,20,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'
neg97.fs(25,9,25,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.
neg97.fs(25,9,25,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'
neg97.fs(30,9,30,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'.
neg97.fs(30,9,30,10): typecheck error FS3207: Invalid use of 'fixed'. 'fixed' may only be used in a declaration of the form 'use x = fixed expr' where the expression is an array, the address of a field, the address of an array element or a string'
neg97.fs(36,20,36,32): typecheck error FS0698: Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution
neg97.fs(36,20,36,32): typecheck error FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'T has been constrained to be type 'string'.
neg97.fs(36,12,36,14): typecheck error FS0663: This type parameter has been used in a way that constrains it to always be 'string'
neg97.fs(42,20,42,22): typecheck error FS0039: The type parameter 'T is not defined. Maybe you want one of the following:
'U

Просмотреть файл

@ -1,2 +1,4 @@
neg_byref_16.fs(3,33,3,42): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. neg_byref_16.fs(3,33,3,42): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg_byref_16.fs(3,40,3,41): typecheck error FS0421: The address of the variable 'a' cannot be used at this point

12
tests/fsharp/typecheck/sigs/neg_byref_17.bsl поставляемый
Просмотреть файл

@ -1,6 +1,10 @@
neg_byref_17.fs(2,5,2,8): typecheck error FS0431: A byref typed value would be stored here. Top-level let-bound byref values are not permitted. neg_byref_17.fs(2,17,2,27): typecheck error FS0001: This expression was expected to have type
'byref<int>'
but here has type
'int'
neg_byref_17.fs(2,17,2,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. neg_byref_17.fs(3,17,3,24): typecheck error FS0001: This expression was expected to have type
'byref<int>'
neg_byref_17.fs(3,17,3,22): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. but here has type
'int'

12
tests/fsharp/typecheck/sigs/neg_byref_22.bsl поставляемый
Просмотреть файл

@ -1,4 +1,16 @@
neg_byref_22.fs(3,16,3,20): typecheck error FS3226: A byref pointer returned by a function or method is implicitly dereferenced as of F# 4.5. To acquire the return value as a pointer, use the address-of operator, e.g. '&f(x)' or '&obj.Method(arg1, arg2)'.
neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected to have type
'byref<int>'
but here has type
'int'
neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected to have type
'byref<int>'
but here has type
'int'
neg_byref_22.fs(5,16,5,17): typecheck error FS0001: This expression was expected to have type neg_byref_22.fs(5,16,5,17): typecheck error FS0001: This expression was expected to have type
'float' 'float'
but here has type but here has type

2
tests/fsharp/typecheck/sigs/neg_byref_7.bsl поставляемый
Просмотреть файл

@ -19,4 +19,4 @@ neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves
neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL.
neg_byref_7.fs(4,41,4,42): typecheck error FS3209: The address of the variable 'y' cannot be used at this point. A method or function may not return the address of this local value. neg_byref_7.fs(4,41,4,42): typecheck error FS3228: The address of the variable 'y' or a related expression cannot be used at this point. The address may not be passed to a call that returns an address. This is to ensure the address of the local value does not escape its scope.

Просмотреть файл

@ -2,7 +2,7 @@
// Verify appropriate error if attempting to assign a ByRef value to an // Verify appropriate error if attempting to assign a ByRef value to an
// object field. (Disallowed by the CLR.) // object field. (Disallowed by the CLR.)
//<Expects id="FS0412" span="(14,28-14,37)" status="error">A type instantiation involves a byref type\. This is not permitted by the rules of Common IL\.$</Expects>
//<Expects id="FS0421" span="(14,29-14,30)" status="error">The address of the variable 'x' cannot be used at this point$</Expects> //<Expects id="FS0421" span="(14,29-14,30)" status="error">The address of the variable 'x' cannot be used at this point$</Expects>
//<Expects id="FS0412" span="(19,20-19,53)" status="error">A type instantiation involves a byref type\. This is not permitted by the rules of Common IL\.$</Expects> //<Expects id="FS0412" span="(19,20-19,53)" status="error">A type instantiation involves a byref type\. This is not permitted by the rules of Common IL\.$</Expects>
let mutable mutableObjectField : obj = null let mutable mutableObjectField : obj = null

Просмотреть файл

@ -1,7 +1,7 @@
 
#if INTERACTIVE #if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive #r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../Debug/net40/bin/FSharp.Compiler.Service.ProjectCracker.dll" #r "../../debug/fcs/net45/FSharp.Compiler.Service.ProjectCracker.dll"
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll" #r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#load "FsUnit.fs" #load "FsUnit.fs"
#load "Common.fs" #load "Common.fs"
@ -673,7 +673,6 @@ let ``Test Unoptimized Declarations Project1`` () =
"member M2(__) (unitVar1) = __.compiledAsInstanceMethod(()) @ (56,21--56,47)"; "member M2(__) (unitVar1) = __.compiledAsInstanceMethod(()) @ (56,21--56,47)";
"member SM1(unitVar0) = Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (compiledAsStaticField,let x: Microsoft.FSharp.Core.int = compiledAsStaticField in ClassWithImplicitConstructor.compiledAsGenericStaticMethod<Microsoft.FSharp.Core.int> (x)) @ (57,26--57,101)"; "member SM1(unitVar0) = Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (compiledAsStaticField,let x: Microsoft.FSharp.Core.int = compiledAsStaticField in ClassWithImplicitConstructor.compiledAsGenericStaticMethod<Microsoft.FSharp.Core.int> (x)) @ (57,26--57,101)";
"member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)"; "member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)";
//"member ToString(__) (unitVar1) = Operators.op_Addition<Microsoft.FSharp.Core.string,Microsoft.FSharp.Core.string,Microsoft.FSharp.Core.string> (base.ToString(),Operators.ToString<Microsoft.FSharp.Core.int> (999)) @ (59,29--59,57)";
"member TestCallinToString(this) (unitVar1) = this.ToString() @ (60,39--60,54)"; "member TestCallinToString(this) (unitVar1) = this.ToString() @ (60,39--60,54)";
"type Error"; "let err = {Data0 = 3; Data1 = 4} @ (64,10--64,20)"; "type Error"; "let err = {Data0 = 3; Data1 = 4} @ (64,10--64,20)";
"let matchOnException(err) = match (if err :? M.Error then $0 else $1) targets ... @ (66,33--66,36)"; "let matchOnException(err) = match (if err :? M.Error then $0 else $1) targets ... @ (66,33--66,36)";
@ -693,16 +692,13 @@ let ``Test Unoptimized Declarations Project1`` () =
"let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)"; "let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)";
"do Console.WriteLine (\"777\")"; "do Console.WriteLine (\"777\")";
"let functionWithSubmsumption(x) = IntrinsicFunctions.UnboxGeneric<Microsoft.FSharp.Core.string> (x) @ (102,40--102,52)"; "let functionWithSubmsumption(x) = IntrinsicFunctions.UnboxGeneric<Microsoft.FSharp.Core.string> (x) @ (102,40--102,52)";
//"let functionWithCoercion(x) = Operators.op_PipeRight<Microsoft.FSharp.Core.string,Microsoft.FSharp.Core.string> (Operators.op_PipeRight<Microsoft.FSharp.Core.string,Microsoft.FSharp.Core.string> (IntrinsicFunctions.UnboxGeneric<Microsoft.FSharp.Core.string> (x :> Microsoft.FSharp.Core.obj),fun x -> M.functionWithSubmsumption (x :> Microsoft.FSharp.Core.obj)),fun x -> M.functionWithSubmsumption (x :> Microsoft.FSharp.Core.obj)) @ (103,39--103,116)";
"type MultiArgMethods"; "type MultiArgMethods";
"member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)"; "member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)";
"member Method(x) (a,b) = 1 @ (106,37--106,38)"; "member Method(x) (a,b) = 1 @ (106,37--106,38)";
"member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)";
"let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (m.Method(7,8),fun tupledArg -> let arg00: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg01: Microsoft.FSharp.Core.int = tupledArg.Item1 in fun tupledArg -> let arg10: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg11: Microsoft.FSharp.Core.int = tupledArg.Item1 in m.CurriedMethod(arg00,arg01,arg10,arg11) (9,10) (11,12)) @ (110,8--110,9)"; "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (m.Method(7,8),fun tupledArg -> let arg00: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg01: Microsoft.FSharp.Core.int = tupledArg.Item1 in fun tupledArg -> let arg10: Microsoft.FSharp.Core.int = tupledArg.Item0 in let arg11: Microsoft.FSharp.Core.int = tupledArg.Item1 in m.CurriedMethod(arg00,arg01,arg10,arg11) (9,10) (11,12)) @ (110,8--110,9)";
//"let functionThatUsesObjectExpression(unitVar0) = { new Object() with member x.ToString(unitVar1) = Operators.ToString<Microsoft.FSharp.Core.int> (888) } @ (114,3--114,55)";
//"let functionThatUsesObjectExpressionWithInterfaceImpl(unitVar0) = { new Object() with member x.ToString(unitVar1) = Operators.ToString<Microsoft.FSharp.Core.int> (888) interface System.IComparable with member x.CompareTo(y) = 0 } :> System.IComparable @ (117,3--120,38)";
"let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition<Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)"; "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition<Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)";
"let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = x in let y2: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref<Microsoft.FSharp.Core.int> (3) in let y3: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = [I_ldelema (NormalAddress,false,ILArrayShape [(Some 0, None)],TypeVar 0us)](arr,0) in let y4: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray<Microsoft.FSharp.Core.int> (arr,0)),r.contents))))) @ (125,16--125,17)"; "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = x in let y2: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref<Microsoft.FSharp.Core.int> (3) in let y3: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = [I_ldelema (NormalAddress,false,ILArrayShapeFIX,!0)](arr,0) in let y4: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray<Microsoft.FSharp.Core.int> (arr,0)),r.contents))))) @ (125,16--125,17)";
"let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)";
"let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = Operators.op_Subtraction<System.DateTime,System.DateTime,System.TimeSpan> (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref<System.DateTime> = &dt2 in let dt7: System.TimeSpan = Operators.op_Subtraction<System.DateTime,System.DateTime,System.TimeSpan> (dt6,dt4) in dt7 @ (142,7--142,10)"; "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = Operators.op_Subtraction<System.DateTime,System.DateTime,System.TimeSpan> (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref<System.DateTime> = &dt2 in let dt7: System.TimeSpan = Operators.op_Subtraction<System.DateTime,System.DateTime,System.TimeSpan> (dt6,dt4) in dt7 @ (142,7--142,10)";
"let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan<Microsoft.FSharp.Core.int> (x,100) do x <- Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (x,1) done; x) @ (152,15--152,16)"; "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan<Microsoft.FSharp.Core.int> (x,100) do x <- Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (x,1) done; x) @ (152,15--152,16)";
@ -815,11 +811,6 @@ let ``Test Optimized Declarations Project1`` () =
"member M2(__) (unitVar1) = __.compiledAsInstanceMethod(()) @ (56,21--56,47)"; "member M2(__) (unitVar1) = __.compiledAsInstanceMethod(()) @ (56,21--56,47)";
"member SM1(unitVar0) = Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (compiledAsStaticField,ClassWithImplicitConstructor.compiledAsGenericStaticMethod<Microsoft.FSharp.Core.int> (compiledAsStaticField)) @ (57,26--57,101)"; "member SM1(unitVar0) = Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (compiledAsStaticField,ClassWithImplicitConstructor.compiledAsGenericStaticMethod<Microsoft.FSharp.Core.int> (compiledAsStaticField)) @ (57,26--57,101)";
"member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)"; "member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)";
//#if NO_PROJECTCRACKER // proxy for COMPILER
// "member ToString(__) (unitVar1) = String.Concat (base.ToString(),let value: Microsoft.FSharp.Core.int = 999 in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box<Microsoft.FSharp.Core.int> (value) in match (if Operators.op_Equality<Microsoft.FSharp.Core.obj> (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ...) @ (59,29--59,57)";
//#else
// //"member ToString(__) (unitVar1) = String.Concat (base.ToString(),let x: Microsoft.FSharp.Core.int = 999 in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box<Microsoft.FSharp.Core.int> (x) in match (if Operators.op_Equality<Microsoft.FSharp.Core.obj> (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ...) @ (59,29--59,57)";
//#endif
"member TestCallinToString(this) (unitVar1) = this.ToString() @ (60,39--60,54)"; "member TestCallinToString(this) (unitVar1) = this.ToString() @ (60,39--60,54)";
"type Error"; "let err = {Data0 = 3; Data1 = 4} @ (64,10--64,20)"; "type Error"; "let err = {Data0 = 3; Data1 = 4} @ (64,10--64,20)";
"let matchOnException(err) = match (if err :? M.Error then $0 else $1) targets ... @ (66,33--66,36)"; "let matchOnException(err) = match (if err :? M.Error then $0 else $1) targets ... @ (66,33--66,36)";
@ -839,25 +830,13 @@ let ``Test Optimized Declarations Project1`` () =
"let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)"; "let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)";
"do Console.WriteLine (\"777\")"; "do Console.WriteLine (\"777\")";
"let functionWithSubmsumption(x) = IntrinsicFunctions.UnboxGeneric<Microsoft.FSharp.Core.string> (x) @ (102,40--102,52)"; "let functionWithSubmsumption(x) = IntrinsicFunctions.UnboxGeneric<Microsoft.FSharp.Core.string> (x) @ (102,40--102,52)";
//#if NO_PROJECTCRACKER // proxy for COMPILER
// "let functionWithCoercion(x) = let arg: Microsoft.FSharp.Core.string = let arg: Microsoft.FSharp.Core.string = IntrinsicFunctions.UnboxGeneric<Microsoft.FSharp.Core.string> (x :> Microsoft.FSharp.Core.obj) in M.functionWithSubmsumption (arg :> Microsoft.FSharp.Core.obj) in M.functionWithSubmsumption (arg :> Microsoft.FSharp.Core.obj) @ (103,39--103,116)";
//#else
// "let functionWithCoercion(x) = let x: Microsoft.FSharp.Core.string = let x: Microsoft.FSharp.Core.string = IntrinsicFunctions.UnboxGeneric<Microsoft.FSharp.Core.string> (x :> Microsoft.FSharp.Core.obj) in M.functionWithSubmsumption (x :> Microsoft.FSharp.Core.obj) in M.functionWithSubmsumption (x :> Microsoft.FSharp.Core.obj) @ (103,39--103,116)";
//#endif
"type MultiArgMethods"; "type MultiArgMethods";
"member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)"; "member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)";
"member Method(x) (a,b) = 1 @ (106,37--106,38)"; "member Method(x) (a,b) = 1 @ (106,37--106,38)";
"member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)"; "member CurriedMethod(x) (a1,b1) (a2,b2) = 1 @ (107,63--107,64)";
"let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (m.Method(7,8),let arg00: Microsoft.FSharp.Core.int = 9 in let arg01: Microsoft.FSharp.Core.int = 10 in let arg10: Microsoft.FSharp.Core.int = 11 in let arg11: Microsoft.FSharp.Core.int = 12 in m.CurriedMethod(arg00,arg01,arg10,arg11)) @ (110,8--110,9)"; "let testFunctionThatCallsMultiArgMethods(unitVar0) = let m: M.MultiArgMethods = new MultiArgMethods(3,4) in Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (m.Method(7,8),let arg00: Microsoft.FSharp.Core.int = 9 in let arg01: Microsoft.FSharp.Core.int = 10 in let arg10: Microsoft.FSharp.Core.int = 11 in let arg11: Microsoft.FSharp.Core.int = 12 in m.CurriedMethod(arg00,arg01,arg10,arg11)) @ (110,8--110,9)";
//#if NO_PROJECTCRACKER // proxy for COMPILER
// "let functionThatUsesObjectExpression(unitVar0) = { new Object() with member x.ToString(unitVar1) = let value: Microsoft.FSharp.Core.int = 888 in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box<Microsoft.FSharp.Core.int> (value) in match (if Operators.op_Equality<Microsoft.FSharp.Core.obj> (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... } @ (114,3--114,55)";
// "let functionThatUsesObjectExpressionWithInterfaceImpl(unitVar0) = { new Object() with member x.ToString(unitVar1) = let value: Microsoft.FSharp.Core.int = 888 in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box<Microsoft.FSharp.Core.int> (value) in match (if Operators.op_Equality<Microsoft.FSharp.Core.obj> (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... interface System.IComparable with member x.CompareTo(y) = 0 } :> System.IComparable @ (117,3--120,38)";
//#else
// "let functionThatUsesObjectExpression(unitVar0) = { new Object() with member x.ToString(unitVar1) = let x: Microsoft.FSharp.Core.int = 888 in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box<Microsoft.FSharp.Core.int> (x) in match (if Operators.op_Equality<Microsoft.FSharp.Core.obj> (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... } @ (114,3--114,55)";
// "let functionThatUsesObjectExpressionWithInterfaceImpl(unitVar0) = { new Object() with member x.ToString(unitVar1) = let x: Microsoft.FSharp.Core.int = 888 in let matchValue: Microsoft.FSharp.Core.obj = Operators.Box<Microsoft.FSharp.Core.int> (x) in match (if Operators.op_Equality<Microsoft.FSharp.Core.obj> (matchValue,dflt) then $0 else (if matchValue :? System.IFormattable then $1 else $2)) targets ... interface System.IComparable with member x.CompareTo(y) = 0 } :> System.IComparable @ (117,3--120,38)";
//#endif
"let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition<Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)"; "let testFunctionThatUsesUnitsOfMeasure(x) (y) = Operators.op_Addition<Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>,Microsoft.FSharp.Core.float<'u>> (x,y) @ (122,70--122,75)";
"let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = x in let y2: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref<Microsoft.FSharp.Core.int> (3) in let y3: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = [I_ldelema (NormalAddress,false,ILArrayShapeFIX,TypeVar 0us)](arr,0) in let y4: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray<Microsoft.FSharp.Core.int> (arr,0)),r.contents))))) @ (125,16--125,17)"; "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = x in let y2: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &w in let arr: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.[] = [|3; 4|] in let r: Microsoft.FSharp.Core.int Microsoft.FSharp.Core.ref = Operators.Ref<Microsoft.FSharp.Core.int> (3) in let y3: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = [I_ldelema (NormalAddress,false,ILArrayShapeFIX,!0)](arr,0) in let y4: Microsoft.FSharp.Core.byref<Microsoft.FSharp.Core.int> = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32,Microsoft.FSharp.Core.int32> (Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray<Microsoft.FSharp.Core.int> (arr,0)),r.contents))))) @ (125,16--125,17)";
"let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)"; "let testFunctionThatUsesStructs1(dt) = dt.AddDays(3) @ (139,57--139,72)";
"let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = DateTime.op_Subtraction (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref<System.DateTime> = &dt2 in let dt7: System.TimeSpan = DateTime.op_Subtraction (dt6,dt4) in dt7 @ (142,7--142,10)"; "let testFunctionThatUsesStructs2(unitVar0) = let dt1: System.DateTime = DateTime.get_Now () in let mutable dt2: System.DateTime = DateTime.get_Now () in let dt3: System.TimeSpan = DateTime.op_Subtraction (dt1,dt2) in let dt4: System.DateTime = dt1.AddDays(3) in let dt5: Microsoft.FSharp.Core.int = dt1.get_Millisecond() in let dt6: Microsoft.FSharp.Core.byref<System.DateTime> = &dt2 in let dt7: System.TimeSpan = DateTime.op_Subtraction (dt6,dt4) in dt7 @ (142,7--142,10)";
"let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan<Microsoft.FSharp.Core.int> (x,100) do x <- Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (x,1) done; x) @ (152,15--152,16)"; "let testFunctionThatUsesWhileLoop(unitVar0) = let mutable x: Microsoft.FSharp.Core.int = 1 in (while Operators.op_LessThan<Microsoft.FSharp.Core.int> (x,100) do x <- Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (x,1) done; x) @ (152,15--152,16)";

Просмотреть файл

@ -1,6 +1,6 @@
#if INTERACTIVE #if INTERACTIVE
#r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive #r "../../debug/fcs/net45/FSharp.Compiler.Service.dll" // note, run 'build fcs debug' to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../Debug/net40/bin/FSharp.Compiler.Service.ProjectCracker.dll" #r "../../debug/fcs/net45/FSharp.Compiler.Service.ProjectCracker.dll"
#r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll" #r "../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
#load "FsUnit.fs" #load "FsUnit.fs"
#load "Common.fs" #load "Common.fs"