[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:
Родитель
e21c296355
Коммит
5bfd9fcd38
|
@ -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. '&f(x)' or '&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 [<Struct>] 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 [<Struct>] 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<'T, ByRefKinds.InOut></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<'T, ByRefKinds.InOut></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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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. '&f(x)' or '&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. '&f(x)' or '&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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] 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 [<Struct>] attribute to the type.</source>
|
||||||
|
<target state="new">A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] 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 ¶m1 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(¶m1) <- stackReferringBecauseMutable2
|
||||||
|
|
||||||
|
// this is NOT allowed
|
||||||
|
param1 <- stackReferring3
|
||||||
|
|
||||||
|
// this is NOT allowed
|
||||||
|
&stackReferring3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// this is allowed
|
||||||
|
//¶m1 - uncomment to test return
|
||||||
|
|
||||||
|
module SpanSafetyTests4 =
|
||||||
|
let test2 (param1: byref<Span<int>>) (param2: Span<byte>) =
|
||||||
|
// this is allowed
|
||||||
|
¶m1 // 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
|
||||||
|
|
|
@ -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 = ...'.
|
|
@ -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
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Загрузка…
Ссылка в новой задаче