[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
|
@ -224,7 +224,6 @@ To do this, build the non-buildfromsource version of FSharp.Compiler.Private (sr
|
|||
.\build net40
|
||||
copy /y src\fsharp\FSharp.Compiler.Private\obj\release\net40\FSComp.* src\buildfromsource\FSharp.Compiler.Private\
|
||||
|
||||
|
||||
#### Configuring proxy server
|
||||
|
||||
If you are behind a proxy server, NuGet client tool must be configured to use it:
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
<package id="Microsoft.FSharp.TupleSample" version="1.0.0-alpha-161121"/>
|
||||
<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 -->
|
||||
<!-- 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" />
|
||||
|
|
|
@ -8,6 +8,7 @@ module Microsoft.FSharp.Compiler.AbstractIL.IL
|
|||
|
||||
|
||||
open System
|
||||
open System.Diagnostics
|
||||
open System.IO
|
||||
open System.Collections
|
||||
open System.Collections.Generic
|
||||
|
@ -568,7 +569,7 @@ type ILBoxity =
|
|||
| AsValue
|
||||
|
||||
// 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 =
|
||||
{ trefScope: ILScopeRef
|
||||
trefEnclosing: string list
|
||||
|
@ -637,11 +638,15 @@ type ILTypeRef =
|
|||
member tref.QualifiedName =
|
||||
tref.AddQualifiedNameExtension(tref.BasicQualifiedName)
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
/// For debugging
|
||||
override x.ToString() = x.FullName
|
||||
|
||||
|
||||
and
|
||||
[<StructuralEquality; StructuralComparison>]
|
||||
and [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
ILTypeSpec =
|
||||
{ tspecTypeRef: ILTypeRef
|
||||
/// The type instantiation if the type is generic.
|
||||
|
@ -671,9 +676,13 @@ and
|
|||
|
||||
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 "<...>"
|
||||
|
||||
and [<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]
|
||||
and [<RequireQualifiedAccess; StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
ILType =
|
||||
| Void
|
||||
| Array of ILArrayShape * ILType
|
||||
|
@ -740,6 +749,10 @@ and [<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]
|
|||
match x with
|
||||
| ILType.TypeVar _ -> true | _ -> false
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
override x.ToString() = x.QualifiedName
|
||||
|
||||
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
|
||||
|
||||
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
type ILMethodRef =
|
||||
{ mrefParent: ILTypeRef
|
||||
mrefCallconv: ILCallingConv
|
||||
|
@ -783,18 +797,26 @@ type ILMethodRef =
|
|||
static member Create(a, b, c, d, e, 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 + "(...)"
|
||||
|
||||
|
||||
[<StructuralEquality; StructuralComparison>]
|
||||
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
type ILFieldRef =
|
||||
{ DeclaringTypeRef: ILTypeRef
|
||||
Name: string
|
||||
Type: ILType }
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
override x.ToString() = x.DeclaringTypeRef.ToString() + "::" + x.Name
|
||||
|
||||
[<StructuralEquality; StructuralComparison>]
|
||||
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
type ILMethodSpec =
|
||||
{ mspecMethodRef: ILMethodRef
|
||||
|
||||
|
@ -820,8 +842,13 @@ type ILMethodSpec =
|
|||
|
||||
member x.FormalReturnType = x.MethodRef.ReturnType
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
override x.ToString() = x.MethodRef.ToString() + "(...)"
|
||||
|
||||
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
type ILFieldSpec =
|
||||
{ FieldRef: ILFieldRef
|
||||
DeclaringType: ILType }
|
||||
|
@ -832,6 +859,10 @@ type ILFieldSpec =
|
|||
|
||||
member x.DeclaringTypeRef = x.FieldRef.DeclaringTypeRef
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
override x.ToString() = x.FieldRef.ToString()
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
@ -865,6 +896,7 @@ type ILSourceDocument =
|
|||
|
||||
member x.File=x.sourceFile
|
||||
|
||||
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
type ILSourceMarker =
|
||||
{ sourceDocument: ILSourceDocument
|
||||
sourceLine: int
|
||||
|
@ -889,6 +921,10 @@ type ILSourceMarker =
|
|||
|
||||
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
|
||||
|
||||
type ILAttribElem =
|
||||
|
@ -912,11 +948,16 @@ type ILAttribElem =
|
|||
|
||||
type ILAttributeNamedArg = (string * ILType * bool * ILAttribElem)
|
||||
|
||||
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
type ILAttribute =
|
||||
{ Method: ILMethodSpec
|
||||
Data: byte[]
|
||||
Elements: ILAttribElem list }
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
override x.ToString() = x.Method.ToString() + "(...)"
|
||||
|
||||
[<NoEquality; NoComparison; Struct>]
|
||||
|
@ -1424,6 +1465,8 @@ type ILReturn =
|
|||
|
||||
member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
|
||||
|
||||
member x.WithCustomAttrs(customAttrs) = { x with CustomAttrsStored = storeILCustomAttrs customAttrs }
|
||||
|
||||
type ILOverridesSpec =
|
||||
| OverridesSpec of ILMethodRef * ILType
|
||||
|
||||
|
@ -1475,6 +1518,7 @@ type ILGenericVariance =
|
|||
| CoVariant
|
||||
| ContraVariant
|
||||
|
||||
[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
type ILGenericParameterDef =
|
||||
{ Name: string
|
||||
Constraints: ILTypes
|
||||
|
@ -1487,6 +1531,10 @@ type ILGenericParameterDef =
|
|||
|
||||
member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
override x.ToString() = x.Name
|
||||
|
||||
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)
|
||||
|
||||
[<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) =
|
||||
|
||||
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.IsRTSpecialName = (x.Attributes &&& EventAttributes.RTSpecialName) <> enum<_>(0)
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
override x.ToString() = "event " + x.Name
|
||||
|
||||
[<NoEquality; NoComparison>]
|
||||
|
@ -1705,7 +1757,7 @@ type ILEventDefs =
|
|||
|
||||
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) =
|
||||
|
||||
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.IsRTSpecialName = (x.Attributes &&& PropertyAttributes.RTSpecialName) <> enum<_>(0)
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
override x.ToString() = "property " + x.Name
|
||||
|
||||
// Index table by name.
|
||||
|
@ -2469,7 +2526,7 @@ let tname_IntPtr = "System.IntPtr"
|
|||
[<Literal>]
|
||||
let tname_UIntPtr = "System.UIntPtr"
|
||||
|
||||
[<NoEquality; NoComparison>]
|
||||
[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
// This data structure needs an entirely delayed implementation
|
||||
type ILGlobals(primaryScopeRef) =
|
||||
|
||||
|
@ -2514,6 +2571,11 @@ type ILGlobals(primaryScopeRef) =
|
|||
member x.typ_Double = m_typ_Double
|
||||
member x.typ_Bool = m_typ_Bool
|
||||
member x.typ_Char = m_typ_Char
|
||||
|
||||
/// For debugging
|
||||
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
|
||||
member x.DebugText = x.ToString()
|
||||
|
||||
override x.ToString() = "<ILGlobals>"
|
||||
|
||||
let mkILGlobals primaryScopeRef = ILGlobals primaryScopeRef
|
||||
|
|
|
@ -796,6 +796,8 @@ type ILReturn =
|
|||
|
||||
member CustomAttrs: ILAttributes
|
||||
|
||||
member WithCustomAttrs: customAttrs: ILAttributes -> ILReturn
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
type ILSecurityAction =
|
||||
| Request
|
||||
|
|
|
@ -135,6 +135,9 @@ module Array =
|
|||
|
||||
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 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
|
||||
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 =
|
||||
List.length l1 = List.length l2 &&
|
||||
List.forall2 p l1 l2
|
||||
|
|
|
@ -7,27 +7,22 @@
|
|||
|
||||
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.Internal
|
||||
open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
|
||||
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.ErrorLogger
|
||||
open Microsoft.FSharp.Compiler.Range
|
||||
|
||||
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
|
||||
open Microsoft.FSharp.Core.ReflectionAdapters
|
||||
#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)
|
||||
methB.SetImplementationFlags(attrs)
|
||||
|
||||
member methB.SetReturnTypeAndLog(rt:System.Type) =
|
||||
if logRefEmitCalls then printfn "methodBuilder%d.SetReturnType(typeof<%s>)" (abs <| hash methB) rt.FullName
|
||||
methB.SetReturnType(rt)
|
||||
|
||||
member methB.SetParametersAndLog(ps) =
|
||||
if logRefEmitCalls then printfn "methodBuilder%d.SetParameters(%A)" (abs <| hash methB) ps
|
||||
methB.SetParameters(ps)
|
||||
member methB.SetSignatureAndLog(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers) =
|
||||
if logRefEmitCalls then printfn "methodBuilder%d.SetSignature(...)" (abs <| hash methB)
|
||||
methB.SetSignature(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers,parameterTypeOptionalCustomModifiers)
|
||||
|
||||
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
|
||||
|
@ -558,11 +549,11 @@ and convTypeAux cenv emEnv preferCreated typ =
|
|||
baseT.MakeByRefType()
|
||||
| ILType.TypeVar tv -> envGetTyvar emEnv tv
|
||||
// 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
|
||||
| ILType.Modified (true, _, _) -> failwith "convType: modreq"
|
||||
| ILType.FunctionPointer _callsig -> failwith "convType: fptr"
|
||||
|
||||
| ILType.FunctionPointer _callsig -> failwith "convType: fptr"
|
||||
|
||||
// [Bug 4063].
|
||||
// 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 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
|
||||
|
@ -1537,11 +1547,22 @@ let rec buildMethodPass2 cenv tref (typB:TypeBuilder) emEnv (mdef : ILMethodDef)
|
|||
let genArgs = getGenericArgumentsOfMethod methB
|
||||
let emEnv = envPushTyvars emEnv (Array.append (getGenericArgumentsOfType (typB.AsType())) genArgs)
|
||||
buildGenParamsPass1b cenv emEnv genArgs mdef.GenericParams;
|
||||
|
||||
// Set parameter and return types (may depend on generic args)
|
||||
methB.SetParametersAndLog(convTypesToArray cenv emEnv mdef.ParameterTypes);
|
||||
methB.SetReturnTypeAndLog(convType cenv emEnv mdef.Return.Type);
|
||||
let parameterTypes = convTypesToArray cenv emEnv mdef.ParameterTypes
|
||||
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
|
||||
methB.SetImplementationFlagsAndLog(implflags);
|
||||
methB.SetImplementationFlagsAndLog(implflags)
|
||||
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>
|
||||
</data>
|
||||
<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 name="patternMatchGuardIsNotBool" xml:space="preserve">
|
||||
<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">
|
||||
<value>Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression.</value>
|
||||
</data>
|
||||
<data name="chkNoByrefReturnOfLocal" 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>
|
||||
<data name="chkNoByrefAddressOfLocal" xml:space="preserve">
|
||||
<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 name="tcNamedActivePattern" xml:space="preserve">
|
||||
<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">
|
||||
<value>The file '{0}' changed on disk unexpectedly, please reload.</value>
|
||||
</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>
|
|
@ -248,21 +248,21 @@ let MethInfoHasAttribute g m attribSpec minfo =
|
|||
|
||||
|
||||
/// 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
|
||||
match TryDecodeILAttribute g tref cattrs with
|
||||
| Some ([ILAttribElem.String (Some msg) ], _) ->
|
||||
| Some ([ILAttribElem.String (Some msg) ], _) when not isByrefLikeTyconRef ->
|
||||
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
|
||||
ErrorD (ObsoleteError(msg, m))
|
||||
else
|
||||
WarnD (ObsoleteWarning(msg, m))
|
||||
| Some ([ILAttribElem.String None ], _) ->
|
||||
| Some ([ILAttribElem.String None ], _) when not isByrefLikeTyconRef ->
|
||||
WarnD(ObsoleteWarning("", m))
|
||||
| Some _ ->
|
||||
| Some _ when not isByrefLikeTyconRef ->
|
||||
WarnD(ObsoleteWarning("", m))
|
||||
| None ->
|
||||
| _ ->
|
||||
CompleteD
|
||||
|
||||
/// 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.
|
||||
let CheckPropInfoAttributes pinfo m =
|
||||
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) -> CheckFSharpAttributes g vref.Attribs m
|
||||
| FSProp _ -> failwith "CheckPropInfoAttributes: unreachable"
|
||||
|
@ -389,7 +389,7 @@ let CheckPropInfoAttributes pinfo m =
|
|||
let CheckILFieldAttributes g (finfo:ILFieldInfo) m =
|
||||
match finfo with
|
||||
| ILFieldInfo(_, pd) ->
|
||||
CheckILAttributes g pd.CustomAttrs m |> CommitOperationResult
|
||||
CheckILAttributes g false pd.CustomAttrs m |> CommitOperationResult
|
||||
#if !NO_EXTENSIONTYPING
|
||||
| ProvidedField (amap, fi, m) ->
|
||||
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 search =
|
||||
BindMethInfoAttributes m minfo
|
||||
(fun ilAttribs -> Some(CheckILAttributes g ilAttribs m))
|
||||
(fun ilAttribs -> Some(CheckILAttributes g false ilAttribs m))
|
||||
(fun fsAttribs ->
|
||||
let res =
|
||||
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.
|
||||
let CheckEntityAttributes g (x:TyconRef) m =
|
||||
if x.IsILTycon then
|
||||
CheckILAttributes g x.ILTyconRawMetadata.CustomAttrs m
|
||||
CheckILAttributes g (isByrefLikeTyconRef g m x) x.ILTyconRawMetadata.CustomAttrs m
|
||||
else
|
||||
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 mkCompareObjTy g ty = (mkThisTy g ty) --> (g.obj_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 mkEqualsObjTy g ty = (mkThisTy g ty) --> (g.obj_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 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)
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -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 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
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -84,7 +91,9 @@ let mkILCallGetEqualityComparer (g: TcGlobals) m =
|
|||
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 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 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 mkThatAddrLocalIfNeeded g m tcve ty =
|
||||
if isStructTy g ty then
|
||||
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 =
|
||||
if isStructTy g ty then
|
||||
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
|
||||
|
||||
let mkBindThatAddr g m ty thataddrv thatv thate expr =
|
||||
if isStructTy g ty then
|
||||
// let thataddrv = &thatv
|
||||
mkCompGenLet m thataddrv (mkValAddr m (mkLocalValRef thatv)) expr
|
||||
mkCompGenLet m thataddrv (mkValAddr m false (mkLocalValRef thatv)) expr
|
||||
else
|
||||
// let thataddrv = that
|
||||
mkCompGenLet m thataddrv thate expr
|
||||
|
@ -131,7 +141,7 @@ let mkBindThatAddrIfNeeded m thataddrvOpt thatv expr =
|
|||
| None -> expr
|
||||
| Some thataddrv ->
|
||||
// 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 =
|
||||
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
|
||||
thisv,thatv,expr
|
||||
|
||||
|
||||
/// 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 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
|
||||
let isUnit = g.compilingFslib && tycon.DisplayName = "Unit"
|
||||
not isUnit &&
|
||||
|
||||
not (TyconRefHasAttribute g tycon.Range g.attrib_IsByRefLikeAttribute (mkLocalTyconRef tycon)) &&
|
||||
match getAugmentationAttribs g tycon with
|
||||
// [< >]
|
||||
| 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
|
||||
let isUnit = g.compilingFslib && tycon.DisplayName = "Unit"
|
||||
not isUnit &&
|
||||
not (TyconRefHasAttribute g tycon.Range g.attrib_IsByRefLikeAttribute (mkLocalTyconRef tycon)) &&
|
||||
|
||||
match getAugmentationAttribs g tycon with
|
||||
// [< >]
|
||||
|
|
|
@ -80,6 +80,12 @@ let NewInferenceType () = mkTyparTy (NewTypar (TyparKind.Type, TyparRigidity.Fle
|
|||
let NewErrorType () = mkTyparTy (NewErrorTypar ())
|
||||
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 ())
|
||||
|
||||
// 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]))
|
||||
-> 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 ->
|
||||
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
|
||||
|
||||
|
||||
let calledObjArgTys = minfo.GetObjArgTypes(amap, m, minst)
|
||||
let calledObjArgTys = calledMeth.CalledObjArgTys(m)
|
||||
|
||||
// Check all the argument types.
|
||||
|
||||
|
@ -1919,7 +1937,7 @@ and CanMemberSigsMatchUpToCheck
|
|||
if isArray1DTy g calledArg.CalledArgumentType then
|
||||
let paramArrayElemTy = destArrayTy g calledArg.CalledArgumentType
|
||||
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
|
||||
CompleteD)
|
||||
|
||||
|
@ -1942,7 +1960,7 @@ and CanMemberSigsMatchUpToCheck
|
|||
let calledArgTy = rfinfo.FieldType
|
||||
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
|
||||
// -- op_Explicit, op_Implicit
|
||||
|
@ -1953,11 +1971,17 @@ and CanMemberSigsMatchUpToCheck
|
|||
| Some _ when minfo.IsConstructor -> CompleteD
|
||||
| Some _ when not alwaysCheckReturn && isNil unnamedCalledOutArgs -> CompleteD
|
||||
| Some reqdRetTy ->
|
||||
let methodRetTy = calledMeth.ReturnTypeAfterOutArgTupling
|
||||
let methodRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling
|
||||
unifyTypes reqdRetTy methodRetTy )))))
|
||||
|
||||
// Assert a subtype constraint, and wrap an ErrorsFromAddingSubsumptionConstraint error around any failure
|
||||
// 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 =
|
||||
TryD (fun () -> SolveTypSubsumesTypKeepAbbrevs csenv ndeep m trace cxsln ty1 ty2)
|
||||
(function
|
||||
|
@ -1973,11 +1997,11 @@ and private SolveTypSubsumesTypWithReport (csenv:ConstraintSolverEnv) ndeep m tr
|
|||
|
||||
// ty1: actual
|
||||
// ty2: expected
|
||||
and private SolveTypEqualsTypWithReport (csenv:ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 =
|
||||
TryD (fun () -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv 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 actual expected)
|
||||
(function
|
||||
| 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
|
||||
(csenv:ConstraintSolverEnv)
|
||||
|
@ -2276,15 +2300,21 @@ and ResolveOverloading
|
|||
let c = compareTypes calledArg1.CalledArgumentType calledArg2.CalledArgumentType
|
||||
if c <> 0 then c else
|
||||
|
||||
// Func<_> is always considered better than any other delegate type
|
||||
let c =
|
||||
(calledArg1.CalledArgumentType, calledArg2.CalledArgumentType) ||> compareCond (fun ty1 ty2 ->
|
||||
|
||||
// Func<_> is always considered better than any other delegate type
|
||||
match tryDestAppTy csenv.g ty1 with
|
||||
| Some tcref1 ->
|
||||
| Some tcref1 when
|
||||
tcref1.DisplayName = "Func" &&
|
||||
(match tcref1.PublicPath with Some p -> p.EnclosingPath = [| "System" |] | _ -> false) &&
|
||||
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)
|
||||
|
||||
if c <> 0 then c else
|
||||
|
@ -2438,7 +2468,10 @@ and ResolveOverloading
|
|||
| None -> CompleteD
|
||||
| Some _ when calledMeth.Method.IsConstructor -> CompleteD
|
||||
| Some reqdRetTy ->
|
||||
let actualRetTy = calledMeth.ReturnTypeAfterOutArgTupling
|
||||
let actualRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling
|
||||
if isByrefTy g reqdRetTy then
|
||||
ErrorD(Error(FSComp.SR.tcByrefReturnImplicitlyDereferenced(), m))
|
||||
else
|
||||
MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy)
|
||||
|
||||
| None ->
|
||||
|
@ -2649,7 +2682,7 @@ let CodegenWitnessThatTypSupportsTraitConstraint tcVal g amap m (traitInfo:Trait
|
|||
// 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
|
||||
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))))
|
||||
else
|
||||
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
|
||||
if rfref.Tycon.IsStructOrEnumTycon && not (isByrefTy g (tyOfExpr g argExprs.[0])) then
|
||||
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)))
|
||||
else
|
||||
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
|
||||
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
|
||||
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.
|
||||
// For now, suppressing any transforms on these.
|
||||
// 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 mutableVal = v.IsMutable
|
||||
let byrefVal = isByrefLikeTy g v.Type
|
||||
let byrefVal = isByrefLikeTy g m v.Type
|
||||
not dllImportStubOrOtherNeverInline &&
|
||||
not byrefVal &&
|
||||
not mutableVal &&
|
||||
|
@ -595,8 +595,8 @@ let eligibleVal g (v:Val) =
|
|||
not v.IsCompiledAsTopLevel
|
||||
|
||||
let determineTransforms g (z : GlobalUsageAnalysis.Results) =
|
||||
let selectTransform f sites =
|
||||
if not (eligibleVal g f) then None else
|
||||
let selectTransform (f: Val) sites =
|
||||
if not (eligibleVal g f.Range f) then None else
|
||||
// Consider f, if it has top-level lambda (meaning has term args)
|
||||
match Zmap.tryFind f z.Defns with
|
||||
| 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."
|
||||
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."
|
||||
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."
|
||||
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"
|
||||
|
@ -1426,3 +1426,13 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl
|
|||
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!'."
|
||||
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")>]
|
||||
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>]
|
||||
[<CompiledName("AddPointerInlined")>]
|
||||
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>
|
||||
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>]
|
||||
[<NoDynamicInvocation>]
|
||||
[<CompiledName("ToNativeIntInlined")>]
|
||||
|
|
|
@ -64,8 +64,14 @@ namespace Microsoft.FSharp.Core
|
|||
|
||||
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 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>
|
||||
type 'T array = '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&" #)
|
||||
|
||||
/// <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>
|
||||
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>
|
||||
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)
|
||||
|
||||
|
||||
/// 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
|
||||
|
||||
open System
|
||||
|
|
|
@ -1659,6 +1659,24 @@ namespace Microsoft.FSharp.Core
|
|||
/// <returns>The optimized function.</returns>
|
||||
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
|
||||
/// set values of this type.</summary>
|
||||
[<StructuralEquality; StructuralComparison>]
|
||||
|
@ -3195,6 +3213,7 @@ namespace Microsoft.FSharp.Core
|
|||
[<CompiledName("ToChar")>]
|
||||
val inline char : value:^T -> char when ^T : (static member op_Explicit : ^T -> char) and default ^T : int
|
||||
|
||||
|
||||
namespace Microsoft.FSharp.Control
|
||||
|
||||
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))
|
||||
#endif
|
||||
|
||||
// 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
|
||||
// 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).
|
||||
/// 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
|
||||
/// 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).
|
||||
type PtrsOK =
|
||||
| PtrTypesOK
|
||||
| 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 =
|
||||
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 =
|
||||
let g = amap.g
|
||||
let tinst = DropErasedTyargs tinst
|
||||
|
||||
// See above note on ptrsOK
|
||||
if ptrsOK = PtrTypesOK && tyconRefEq g tcref g.nativeptr_tcr && (freeInTypes CollectTypars tinst).FreeTypars.IsEmpty then
|
||||
GenNamedTyAppAux amap m tyenv ptrsOK g.ilsigptr_tcr tinst
|
||||
|
@ -417,7 +434,10 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty =
|
|||
#endif
|
||||
match stripTyEqnsAndMeasureEqns g ty with
|
||||
| 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_fun (dty, returnTy) -> EraseClosures.mkILFuncTy g.ilxPubCloEnv (GenTypeArgAux amap m tyenv dty) (GenTypeArgAux amap m tyenv returnTy)
|
||||
|
||||
| TType_ucase (ucref, args) ->
|
||||
|
@ -428,7 +448,9 @@ and GenTypeAux amap m (tyenv: TypeReprEnv) voidOK ptrsOK ty =
|
|||
let tps = DropErasedTypars tps
|
||||
if tps.IsEmpty then GenTypeAux amap m tyenv VoidNotOK ptrsOK tau
|
||||
else EraseClosures.mkILTyFuncTy g.ilxPubCloEnv
|
||||
|
||||
| TType_var tp -> mkILTyvarTy tyenv.[tp,m]
|
||||
|
||||
| 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 =
|
||||
match returnTyOpt with
|
||||
| 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 =
|
||||
ty |> GenTypeAux amap m tyenv VoidNotOK PtrTypesOK
|
||||
and GenParamType amap m tyenv isSlotSig ty =
|
||||
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 =
|
||||
tys |> List.map (GenTypeAux amap m tyenv VoidNotOK PtrTypesOK)
|
||||
and GenParamTypes amap m tyenv isSlotSig tys =
|
||||
tys |> List.map (GenParamType amap m tyenv isSlotSig)
|
||||
|
||||
and GenTypeArgs amap m tyenv tyargs = GenTypeArgsAux amap m tyenv tyargs
|
||||
|
||||
|
@ -607,7 +635,7 @@ type ValStorage =
|
|||
| StaticProperty of ILMethodSpec * OptionalShadowLocal
|
||||
/// 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.
|
||||
| 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"
|
||||
| Env of ILType * int * ILFieldSpec * NamedLocalIlxClosureInfo ref option
|
||||
/// 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 ilRetTy = GenReturnType amap m tyenvUnderTypars returnTy
|
||||
if isCtor || cctor then ILType.Void else ilRetTy
|
||||
|
||||
let ilTy = GenType amap m tyenvUnderTypars (mkAppTy parentTcref (List.map mkTyparTy ctps))
|
||||
|
||||
if isCompiledAsInstance || isCtor then
|
||||
// Find the 'this' argument type if any
|
||||
let thisTy,flatArgInfos =
|
||||
|
@ -797,18 +827,19 @@ let GetMethodSpecForMemberVal amap g (memberInfo:ValMemberInfo) (vref:ValRef) =
|
|||
ctps
|
||||
thisArgTys
|
||||
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 mspec = mkILInstanceMethSpecInTy (ilTy,vref.CompiledName,ilMethodArgTys,ilActualRetTy,ilMethodInst)
|
||||
|
||||
mspec,ctps,mtps,paramInfos,retInfo
|
||||
mspec,ctps,mtps,paramInfos,retInfo,methodArgTys
|
||||
else
|
||||
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 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
|
||||
|
||||
|
@ -894,18 +925,18 @@ let ComputeStorageForTopVal (amap, g, optIntraAssemblyInfo:IlxGenIntraAssemblyIn
|
|||
| _ ->
|
||||
match vref.MemberInfo with
|
||||
| Some memberInfo when not vref.IsExtensionMember ->
|
||||
let mspec,_,_,paramInfos,retInfo = GetMethodSpecForMemberVal amap g memberInfo vref
|
||||
Method (topValInfo, vref, mspec, m, paramInfos, retInfo)
|
||||
let mspec,_,_,paramInfos,retInfo,methodArgTys = GetMethodSpecForMemberVal amap g memberInfo vref
|
||||
Method (topValInfo, vref, mspec, m, paramInfos, methodArgTys, retInfo)
|
||||
| _ ->
|
||||
let (tps, curriedArgInfos, returnTy, retInfo) = GetTopValTypeInCompiledForm g topValInfo vref.Type m
|
||||
let tyenvUnderTypars = TypeReprEnv.ForTypars tps
|
||||
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 ilLocTy = mkILTyForCompLoc cloc
|
||||
let ilMethodInst = GenTypeArgs amap m tyenvUnderTypars (List.map mkTyparTy tps)
|
||||
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 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
|
||||
| TOp.UnionCaseFieldGet(ucref,n),[e],_ ->
|
||||
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
|
||||
| TOp.UnionCaseTagGet ucref,[e],_ ->
|
||||
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
|
||||
| TOp.ValFieldGet f,[],_ ->
|
||||
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
|
||||
| TOp.ValFieldGetAddr f,[],_ ->
|
||||
| TOp.ValFieldGetAddr (f, _readonly),[],_ ->
|
||||
GenGetStaticFieldAddr cenv cgbuf eenv (f,tyargs,m) sequel
|
||||
| TOp.ValFieldSet f,[e1;e2],_ ->
|
||||
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
|
||||
| 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
|
||||
| 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.Reraise,[],[rtnty] -> GenReraise cenv cgbuf eenv (rtnty,m) 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(LByrefGet,v),[],[] -> GenGetByref cenv cgbuf eenv (v,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.Bytes bytes,[],[] ->
|
||||
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
|
||||
match storage with
|
||||
| Method (_,_,mspec,_,_,_) ->
|
||||
| Method (_,_,mspec,_,_,_,_) ->
|
||||
CG.EmitInstr cgbuf (pop 0) (Push [cenv.g.iltyp_RuntimeMethodHandle]) (I_ldtoken (ILToken.ILMethod mspec))
|
||||
| _ ->
|
||||
errorR(Error(FSComp.SR.ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen(), m))
|
||||
|
@ -2573,7 +2604,7 @@ and GenApp cenv cgbuf eenv (f,fty,tyargs,args,m) sequel =
|
|||
when
|
||||
(let storage = StorageForValRef m vref eenv
|
||||
match storage with
|
||||
| Method (topValInfo,vref,_,_,_,_) ->
|
||||
| Method (topValInfo,vref,_,_,_,_,_) ->
|
||||
(let tps,argtys,_,_ = GetTopValTypeInFSharpForm cenv.g topValInfo vref.Type m
|
||||
tps.Length = tyargs.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
|
||||
match storage with
|
||||
| Method (topValInfo,vref,mspec,_,_,_) ->
|
||||
| Method (topValInfo,vref,mspec,_,_,_,_) ->
|
||||
let nowArgs,laterArgs =
|
||||
let _,curriedArgInfos,_,_ = GetTopValTypeInFSharpForm cenv.g topValInfo vref.Type m
|
||||
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 =
|
||||
let vspec = v.Deref
|
||||
let ilTy = GenTypeOfVal cenv eenv vspec
|
||||
match StorageForValRef m v eenv with
|
||||
let storage = StorageForValRef m v eenv
|
||||
match storage with
|
||||
| Local (idx,None) ->
|
||||
CG.EmitInstrs cgbuf (pop 0) (Push [ILType.Byref ilTy]) [ I_ldloca (uint16 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.
|
||||
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
|
||||
Type= GenParamType cenv.amap m eenv.tyenv ty
|
||||
Type= ilTy
|
||||
Default=defaultParamValue
|
||||
Marshal=paramMarshal2
|
||||
IsIn=inFlag || inFlag2
|
||||
IsOut=outFlag || outFlag2
|
||||
IsOptional=optionalFlag || optionalFlag2
|
||||
CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs (GenAttrs cenv eenv attribs))
|
||||
CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs ilAttribs)
|
||||
MetadataIndex = NoMetadataIdx }
|
||||
|
||||
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 ilRetTy = GenReturnType cenv.amap m eenvForSlotSig.tyenv returnTy
|
||||
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
|
||||
|
||||
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
|
||||
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 methodVars = List.concat vsl
|
||||
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) ->
|
||||
|
||||
|
@ -4948,9 +4995,9 @@ and GenMarshal cenv attribs =
|
|||
// No MarshalAs detected
|
||||
None, attribs
|
||||
|
||||
and GenParamAttribs cenv attribs =
|
||||
let inFlag = HasFSharpAttributeOpt cenv.g cenv.g.attrib_InAttribute attribs
|
||||
let outFlag = HasFSharpAttribute cenv.g cenv.g.attrib_OutAttribute attribs
|
||||
and GenParamAttribs cenv paramTy 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 || isOutByrefTy cenv.g paramTy
|
||||
let optionalFlag = HasFSharpAttributeOpt cenv.g cenv.g.attrib_OptionalAttribute 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
|
||||
let 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 (IsMatchingFSharpAttributeOpt cenv.g cenv.g.attrib_OptionalAttribute >> 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
|
||||
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 argInfosAndTypes =
|
||||
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
|
||||
|
||||
(Set.empty,argInfosAndTypes)
|
||||
||> List.mapFold (fun takenNames ((ilArgTy,topArgInfo),implValOpt) ->
|
||||
let inFlag,outFlag,optionalFlag,defaultParamValue,Marshal,attribs = GenParamAttribs cenv topArgInfo.Attribs
|
||||
(Set.empty,List.zip methodArgTys argInfosAndTypes)
|
||||
||> List.mapFold (fun takenNames (methodArgTy, ((ilArgTy,topArgInfo),implValOpt)) ->
|
||||
let inFlag,outFlag,optionalFlag,defaultParamValue,Marshal,attribs = GenParamAttribs cenv methodArgTy topArgInfo.Attribs
|
||||
|
||||
let idOpt = (match topArgInfo.Name with
|
||||
| Some v -> Some v
|
||||
|
@ -4998,6 +5045,14 @@ and GenParams cenv eenv (mspec:ILMethodSpec) (attribs:ArgReprInfo list) (implVal
|
|||
| None ->
|
||||
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 =
|
||||
{ Name=nmOpt
|
||||
Type= ilArgTy
|
||||
|
@ -5006,17 +5061,17 @@ and GenParams cenv eenv (mspec:ILMethodSpec) (attribs:ArgReprInfo list) (implVal
|
|||
IsIn=inFlag
|
||||
IsOut=outFlag
|
||||
IsOptional=optionalFlag
|
||||
CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs (GenAttrs cenv eenv attribs))
|
||||
CustomAttrsStored = storeILCustomAttrs (mkILCustomAttrs ilAttribs)
|
||||
MetadataIndex = NoMetadataIdx }
|
||||
|
||||
param, takenNames)
|
||||
|> fst
|
||||
|
||||
and GenReturnInfo cenv eenv ilRetTy (retInfo : ArgReprInfo) : ILReturn =
|
||||
let marshal,attrs = GenMarshal cenv retInfo.Attribs
|
||||
let marshal,attribs = GenMarshal cenv retInfo.Attribs
|
||||
{ Type=ilRetTy
|
||||
Marshal=marshal
|
||||
CustomAttrsStored= storeILCustomAttrs (mkILCustomAttrs (GenAttrs cenv eenv attrs))
|
||||
CustomAttrsStored= storeILCustomAttrs (mkILCustomAttrs (GenAttrs cenv eenv attribs))
|
||||
MetadataIndex = NoMetadataIdx }
|
||||
|
||||
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
|
||||
cenv cgbuf eenv
|
||||
(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 selfMethodVars,nonSelfMethodVars,compileAsInstance =
|
||||
|
@ -5122,6 +5177,7 @@ and GenMethodForBinding
|
|||
let nonUnitNonSelfMethodVars,body = BindUnitVars cenv.g (nonSelfMethodVars,paramInfos,body)
|
||||
let nonUnitMethodVars = selfMethodVars@nonUnitNonSelfMethodVars
|
||||
let cmtps,curriedArgInfos,_,_ = GetTopValTypeInCompiledForm cenv.g topValInfo v.Type v.Range
|
||||
|
||||
let eenv = bindBaseOrThisVarOpt cenv eenv ctorThisValOpt
|
||||
let eenv = bindBaseOrThisVarOpt cenv eenv baseValOpt
|
||||
|
||||
|
@ -5204,7 +5260,7 @@ and GenMethodForBinding
|
|||
yield! GenCompilationArgumentCountsAttr cenv v ]
|
||||
|
||||
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 methName = mspec.Name
|
||||
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))
|
||||
| StaticProperty (ilGetterMethSpec,_) ->
|
||||
error(Error(FSComp.SR.ilStaticMethodIsNotLambda(ilGetterMethSpec.Name),m))
|
||||
| Method (_,_,mspec,m,_,_) ->
|
||||
| Method (_,_,mspec,m,_,_,_) ->
|
||||
error(Error(FSComp.SR.ilStaticMethodIsNotLambda(mspec.Name),m))
|
||||
| Null -> CG.EmitInstr cgbuf (pop 1) Push0 AI_pop
|
||||
| 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))
|
||||
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.
|
||||
// We generate a lambda expression and that simply calls
|
||||
// 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,[],[])
|
||||
| FSAttrib(vref) ->
|
||||
assert(vref.IsMember)
|
||||
let mspec,_,_,_,_ = GetMethodSpecForMemberVal amap g (Option.get vref.MemberInfo) vref
|
||||
let mspec,_,_,_,_,_ = GetMethodSpecForMemberVal amap g (Option.get vref.MemberInfo) vref
|
||||
mspec
|
||||
let ilArgs = List.map2 (fun (AttribExpr(_,vexpr)) ty -> GenAttribArg amap g eenv vexpr ty) args mspec.FormalArgTypes
|
||||
mkILCustomAttribMethRef g.ilg (mspec,ilArgs, props)
|
||||
|
@ -6053,11 +6109,11 @@ and GenAbstractBinding cenv eenv tref (vref:ValRef) =
|
|||
[ yield! GenAttrs cenv eenv attribs
|
||||
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 ilMethTypars = GenGenericParams cenv eenvForMeth mtps
|
||||
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 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,
|
||||
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
|
||||
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>
|
||||
|
@ -6428,7 +6484,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) =
|
|||
let (|Lazy|) (x:Lazy<_>) = x.Force()
|
||||
match (eenv.valsInScope.TryFind cenv.g.sprintf_vref.Deref,
|
||||
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
|
||||
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>
|
||||
|
@ -6968,7 +7024,7 @@ let defaultOf =
|
|||
let LookupGeneratedValue (amap:ImportMap) (ctxt: ExecutionContext) eenv (v:Val) =
|
||||
try
|
||||
// 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 *)
|
||||
ctxt.LookupType ilTy
|
||||
// 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.
|
||||
let methInfo = staticTyp.GetMethod(ilGetterMethRef.Name, BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic)
|
||||
methInfo.Invoke((null:obj),(null:obj[]))
|
||||
Some (obj,objTyp)
|
||||
Some (obj,objTyp())
|
||||
|
||||
| StaticProperty (ilGetterMethSpec, _) ->
|
||||
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.
|
||||
let methInfo = staticTyp.GetMethod(ilGetterMethSpec.Name, BindingFlags.Static ||| BindingFlags.Public ||| BindingFlags.NonPublic)
|
||||
methInfo.Invoke((null:obj),(null:obj[]))
|
||||
Some (obj,objTyp)
|
||||
Some (obj,objTyp())
|
||||
|
||||
| Null ->
|
||||
Some (null,objTyp)
|
||||
Some (null,objTyp())
|
||||
| Local _ -> None
|
||||
| Method _ -> None
|
||||
| Arg _ -> None
|
||||
|
|
|
@ -149,7 +149,7 @@ let IsRefusedTLR g (f:Val) =
|
|||
// things marked ValInline.Never are special
|
||||
let dllImportStubOrOtherNeverInline = (f.InlineInfo = ValInline.Never)
|
||||
// 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
|
||||
let specialVal = f.MemberInfo.IsSome
|
||||
let alreadyChosen = f.ValReprInfo.IsSome
|
||||
|
@ -162,10 +162,9 @@ let IsMandatoryTopLevel (f:Val) =
|
|||
specialVal || isModulBinding
|
||||
|
||||
let IsMandatoryNonTopLevel g (f:Val) =
|
||||
let byrefVal = isByrefLikeTy g f.Type
|
||||
let byrefVal = isByrefLikeTy g f.Range f.Type
|
||||
byrefVal
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
|
||||
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
|
||||
let vals = vals |> List.filter (Zset.memberOf topValS >> not)
|
||||
|
||||
|
|
|
@ -56,16 +56,18 @@ type CalledArg =
|
|||
IsParamArray : bool
|
||||
OptArgInfo : OptionalArgInfo
|
||||
CallerInfoInfo : CallerInfoInfo
|
||||
IsInArg: bool
|
||||
IsOutArg: bool
|
||||
ReflArgInfo: ReflectedArgInfo
|
||||
NameOpt: Ident option
|
||||
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
|
||||
IsParamArray=isParamArray
|
||||
OptArgInfo =optArgInfo
|
||||
CallerInfoInfo = callerInfoInfo
|
||||
IsInArg=isInArg
|
||||
IsOutArg=isOutArg
|
||||
ReflArgInfo=reflArgInfo
|
||||
NameOpt=nameOpt
|
||||
|
@ -126,13 +128,24 @@ let AdjustCalledArgType (infoReader:InfoReader) isConstraint (calledArg: CalledA
|
|||
let calledArgTy = calledArg.CalledArgumentType
|
||||
let callerArgTy = callerArg.Type
|
||||
let m = callerArg.Range
|
||||
if isConstraint then calledArgTy else
|
||||
// If the called method argument is a byref type, then the caller may provide a byref or ref
|
||||
if isByrefTy g calledArgTy then
|
||||
if isConstraint then
|
||||
calledArgTy
|
||||
else
|
||||
|
||||
// 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
|
||||
// If the called method argument is a delegate type, then the caller may provide a function
|
||||
let calledArgTy =
|
||||
|
@ -193,11 +206,12 @@ type CalledMethArgSet<'T> =
|
|||
let MakeCalledArgs amap m (minfo:MethInfo) minst =
|
||||
// Mark up the arguments with their position, so we can sort them back into order later
|
||||
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)
|
||||
IsParamArray=isParamArrayArg
|
||||
OptArgInfo=optArgInfo
|
||||
CallerInfoInfo = callerInfoFlags
|
||||
IsInArg=isInArg
|
||||
IsOutArg=isOutArg
|
||||
ReflArgInfo=reflArgInfo
|
||||
NameOpt=nmOpt
|
||||
|
@ -350,6 +364,7 @@ type CalledMeth<'T>
|
|||
let unnamedCalledOutArgs = argSetInfos |> List.collect (fun (_, _, _, _, _, x) -> x)
|
||||
|
||||
member x.infoReader = infoReader
|
||||
|
||||
member x.amap = infoReader.amap
|
||||
|
||||
/// the method we're attempting to call
|
||||
|
@ -372,12 +387,14 @@ type CalledMeth<'T>
|
|||
/// The argument analysis for each set of curried arguments
|
||||
member x.ArgSets = argSets
|
||||
|
||||
/// return type
|
||||
member x.ReturnType = methodRetTy
|
||||
/// return type after implicit deference of byref returns is taken into account
|
||||
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
|
||||
member x.ReturnTypeAfterOutArgTupling =
|
||||
let retTy = x.ReturnType
|
||||
member x.CalledReturnTypeAfterOutArgTupling =
|
||||
let retTy = x.CalledReturnTypeAfterByrefDeref
|
||||
if isNil unnamedCalledOutArgs then
|
||||
retTy
|
||||
else
|
||||
|
@ -408,16 +425,28 @@ type CalledMeth<'T>
|
|||
member x.NumArgSets = x.ArgSets.Length
|
||||
|
||||
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.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.ParamArrayElementType =
|
||||
assert (x.UsesParamArrayConversion)
|
||||
x.ParamArrayCalledArgOpt.Value.CalledArgumentType |> destArrayTy x.amap.g
|
||||
|
||||
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.NumCallerTyArgs = x.CallerTyArgs.Length
|
||||
|
||||
member x.AssignsAllNamedArgs = isNil x.UnassignedNamedArgs
|
||||
|
@ -451,8 +480,11 @@ type CalledMeth<'T>
|
|||
x.ArgSets |> List.map (fun argSet -> argSet.AssignedNamedArgs)
|
||||
|
||||
member x.AllUnnamedCalledArgs = x.ArgSets |> List.collect (fun x -> x.UnnamedCalledArgs)
|
||||
|
||||
member x.TotalNumUnnamedCalledArgs = x.ArgSets |> List.sumBy (fun x -> x.NumUnnamedCalledArgs)
|
||||
|
||||
member x.TotalNumUnnamedCallerArgs = x.ArgSets |> List.sumBy (fun x -> x.NumUnnamedCallerArgs)
|
||||
|
||||
member x.TotalNumAssignedNamedArgs = x.ArgSets |> List.sumBy (fun x -> x.NumAssignedNamedArgs)
|
||||
|
||||
let NamesOfCalledArgs (calledArgs: CalledArg list) =
|
||||
|
@ -547,15 +579,13 @@ let TakeObjAddrForMethodCall g amap (minfo:MethInfo) isMutable m objArgs f =
|
|||
match objArgs with
|
||||
| [objArgExpr] ->
|
||||
let hasCallInfo = ccallInfo.IsSome
|
||||
let mustTakeAddress =
|
||||
(minfo.IsStruct && not minfo.IsExtensionMember) // don't take the address of a struct when passing to an extension member
|
||||
|| hasCallInfo
|
||||
let mustTakeAddress = hasCallInfo || minfo.ObjArgNeedsAddress(amap, m)
|
||||
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
|
||||
let objArgExpr' =
|
||||
if not hasCallInfo && // minfo.IsExtensionMember && minfo.IsStruct &&
|
||||
if not hasCallInfo &&
|
||||
not (TypeDefinitelySubsumesTypeNoCoercion 0 g amap m minfo.ApparentEnclosingType objArgTy) then
|
||||
mkCoerceExpr(objArgExpr', minfo.ApparentEnclosingType, m, objArgTy)
|
||||
else
|
||||
|
@ -1074,7 +1104,7 @@ module ProvidedMethodCalls =
|
|||
match ea.PApplyOption((function ProvidedAddressOfExpr x -> Some x | _ -> None), m) with
|
||||
| Some 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
|
||||
None, (ce, tyOfExpr g ce)
|
||||
| None ->
|
||||
|
|
|
@ -467,7 +467,7 @@ let private GetCSharpStyleIndexedExtensionMembersForTyconRef (amap:Import.Import
|
|||
// So we need to go and crack the type of the 'this' argument.
|
||||
let thisTy = minfo.GetParamTypes(amap,m,generalizeTypars minfo.FormalMethodTypars).Head.Head
|
||||
match thisTy with
|
||||
| AppTy amap.g (tcrefOfTypeExtended, _) -> Some tcrefOfTypeExtended
|
||||
| AppTy g (tcrefOfTypeExtended, _) when not (isByrefTy g thisTy) -> Some tcrefOfTypeExtended
|
||||
| _ -> None
|
||||
|
||||
Some rs
|
||||
|
|
|
@ -906,15 +906,28 @@ module private PrintTypes =
|
|||
| [arg] -> layoutTypeWithInfoAndPrec denv env 2 arg ^^ 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 =
|
||||
|
||||
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 ->
|
||||
layoutTypeWithInfoAndPrec denv env prec (reduceTyconRefMeasureableOrProvided denv.g tc args)
|
||||
|
||||
// Layout a type application
|
||||
| TType_app (tc,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.
|
||||
///
|
||||
/// 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
|
||||
match isParamArray, nmOpt, isOptArg, tryDestOptionTy denv.g pty with
|
||||
// Layout an optional argument
|
||||
|
|
|
@ -1248,7 +1248,7 @@ let rec ExprHasEffect g expr =
|
|||
| Expr.Const _ -> false
|
||||
/// type applications do not have effects, with the exception of type functions
|
||||
| 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.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
|
||||
|
@ -1256,35 +1256,35 @@ let rec ExprHasEffect g expr =
|
|||
and ExprsHaveEffect g exprs = List.exists (ExprHasEffect g) exprs
|
||||
and BindingsHaveEffect g binds = List.exists (BindingHasEffect g) binds
|
||||
and BindingHasEffect g bind = bind.Expr |> ExprHasEffect g
|
||||
and OpHasEffect g op =
|
||||
and OpHasEffect g m op =
|
||||
match op with
|
||||
| TOp.Tuple _ -> false
|
||||
| TOp.Recd (ctor, tcref) ->
|
||||
match ctor with
|
||||
| RecdExprIsObjInit -> true
|
||||
| RecdExpr -> isRecdOrUnionOrStructTyconRefDefinitelyMutable g tcref
|
||||
| TOp.UnionCase ucref -> isRecdOrUnionOrStructTyconRefDefinitelyMutable g ucref.TyconRef
|
||||
| RecdExpr -> not (isRecdOrStructTyconRefReadOnly g m tcref)
|
||||
| TOp.UnionCase ucref -> isRecdOrUnionOrStructTyconRefDefinitelyMutable ucref.TyconRef
|
||||
| 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.UnionCaseProof _ -> false
|
||||
| TOp.UnionCaseFieldGet (ucref, n) -> isUnionCaseFieldMutable g ucref n
|
||||
| TOp.ILAsm(instrs, _) -> IlAssemblyCodeHasEffect instrs
|
||||
| TOp.TupleFieldGet(_) -> false
|
||||
| TOp.ExnFieldGet(ecref, n) -> isExnFieldMutable ecref n
|
||||
| TOp.RefAddrGet -> false
|
||||
| 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.UnionCaseFieldGetAddr _ -> false (* data is immutable, so taking address is ok *)
|
||||
| TOp.LValueOp (LGetAddr, lv) -> lv.IsMutable
|
||||
| TOp.RefAddrGet _ -> false
|
||||
| TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some true)
|
||||
| TOp.ValFieldGetAddr (rfref, _readonly) -> rfref.RecdField.IsMutable
|
||||
| TOp.UnionCaseFieldGetAddr _ -> false // union case fields are immutable
|
||||
| TOp.LValueOp (LAddrOf _, lv) -> lv.IsMutable
|
||||
| TOp.UnionCaseFieldSet _
|
||||
| TOp.ExnFieldSet _
|
||||
| TOp.Coerce
|
||||
| TOp.Reraise
|
||||
| TOp.For _
|
||||
| TOp.While _
|
||||
| TOp.TryCatch _
|
||||
| TOp.TryFinally _ (* note: these really go through a different path anyway *)
|
||||
| TOp.TryCatch _ (* conservative *)
|
||||
| TOp.TryFinally _ (* conservative *)
|
||||
| TOp.TraitCall _
|
||||
| TOp.Goto _
|
||||
| TOp.Label _
|
||||
|
@ -1791,17 +1791,17 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) =
|
|||
MightMakeCriticalTailcall=false
|
||||
Info=UnknownValue }
|
||||
(* Handle addresses *)
|
||||
| TOp.LValueOp (LGetAddr, lv), _, _ ->
|
||||
| TOp.LValueOp ((LAddrOf _ as lop), lv), _, _ ->
|
||||
let e, _ = OptimizeExpr cenv env (exprForValRef m lv)
|
||||
let op' =
|
||||
match e with
|
||||
// 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
|
||||
Expr.Op (op', tyargs, args, m),
|
||||
{ TotalSize = 1
|
||||
FunctionSize = 1
|
||||
HasEffect = OpHasEffect cenv.g op'
|
||||
HasEffect = OpHasEffect cenv.g m op'
|
||||
MightMakeCriticalTailcall = false
|
||||
Info = UnknownValue }
|
||||
(* 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 argEffects = OrEffects 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 =
|
||||
match op with
|
||||
| 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.Array | TOp.For _ | TOp.While _ | TOp.TryCatch _ | TOp.TryFinally _
|
||||
| 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.ExnFieldSet _ -> 1, valu
|
||||
| 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.
|
||||
// If we ever reuse DevirtualizeApplication to transform an arbitrary virtual call into a
|
||||
// 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)
|
||||
| _ ->
|
||||
// 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
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
and ComputeSplitToMethodCondition flag threshold cenv env (e, einfo) =
|
||||
and ComputeSplitToMethodCondition flag threshold cenv env (e:Expr, einfo) =
|
||||
flag &&
|
||||
// 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).
|
||||
|
@ -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.
|
||||
// It can't use any protected or base calls, rethrow(), byrefs etc.
|
||||
let m = e.Range
|
||||
(let fvs = freeInExpr CollectLocals e
|
||||
not fvs.UsesUnboundRethrow &&
|
||||
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.
|
||||
(v.BaseOrThisInfo = NormalVal &&
|
||||
// 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
|
||||
not (IsGenericValWithGenericContraints cenv.g v) &&
|
||||
// None of them should be mutable
|
||||
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) =
|
||||
if ComputeSplitToMethodCondition flag threshold cenv env (e, einfo) then
|
||||
|
|
|
@ -904,7 +904,7 @@ let CompilePatternBasic
|
|||
when isNil topgtvs && ucref.Tycon.IsStructRecordOrUnionTycon ->
|
||||
|
||||
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
|
||||
| None -> Some addrexp, None
|
||||
| Some (v,e) ->
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -426,7 +426,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.
|
|||
| TOp.UnionCaseFieldGet (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))
|
||||
|
||||
| TOp.UnionCaseFieldGetAddr _,_tyargs,_ ->
|
||||
|
@ -518,7 +518,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP.
|
|||
// rebuild reraise<T>() and Convert
|
||||
mkReraiseLibCall cenv.g toTy m |> ConvExpr cenv env
|
||||
|
||||
| TOp.LValueOp(LGetAddr,vref),[],[] ->
|
||||
| TOp.LValueOp(LAddrOf _,vref),[],[] ->
|
||||
QP.mkAddressOf(ConvValRef false cenv env m vref [])
|
||||
|
||||
| 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.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.RefAddrGet,_,_ -> wfail(Error(FSComp.SR.crefQuotationsCantRequireByref(), m))
|
||||
| TOp.RefAddrGet _,_,_ -> wfail(Error(FSComp.SR.crefQuotationsCantRequireByref(), m))
|
||||
| TOp.TraitCall (_ss),_,_ -> wfail(Error(FSComp.SR.crefQuotationsCantCallTraitMembers(), m))
|
||||
| _ ->
|
||||
wfail(InternalError( "Unexpected expression shape",m))
|
||||
|
@ -665,9 +665,9 @@ and ConvLValueExprCore cenv env expr =
|
|||
match expr with
|
||||
| Expr.Op(op,tyargs,args,m) ->
|
||||
match op, args, tyargs with
|
||||
| TOp.LValueOp(LGetAddr,vref),_,_ -> ConvValRef false cenv env m vref []
|
||||
| TOp.ValFieldGetAddr(rfref),_,_ -> ConvClassOrRecdFieldGet cenv env m rfref tyargs args
|
||||
| TOp.UnionCaseFieldGetAddr(ucref,n),[e],_ -> ConvUnionFieldGet cenv env m ucref n tyargs e
|
||||
| TOp.LValueOp(LAddrOf _,vref),_,_ -> ConvValRef false cenv env m vref []
|
||||
| TOp.ValFieldGetAddr(rfref, _),_,_ -> ConvClassOrRecdFieldGet cenv env m rfref tyargs args
|
||||
| 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_ldsflda(fspec) ],_rtys),_,_ -> ConvLdfld cenv env m fspec tyargs args
|
||||
| TOp.ILAsm(([ I_ldelema(_ro,_isNativePtr,shape,_tyarg) ] ),_), (arr::idxs), [elemty] ->
|
||||
|
|
|
@ -560,8 +560,45 @@ let tryNormalizeMeasureInType g ty =
|
|||
// Some basic type builders
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
let mkNativePtrTy (g:TcGlobals) ty = TType_app (g.nativeptr_tcr, [ty])
|
||||
let mkByrefTy (g:TcGlobals) ty = TType_app (g.byref_tcr, [ty])
|
||||
let mkNativePtrTy (g:TcGlobals) 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 =
|
||||
if rank < 1 || rank > 32 then
|
||||
|
@ -675,7 +712,16 @@ let rec stripTyEqnsA g canShortcut ty =
|
|||
| Some abbrevTy ->
|
||||
stripTyEqnsA g canShortcut (applyTyconAbbrev abbrevTy tycon tinst)
|
||||
| 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)
|
||||
else
|
||||
ty
|
||||
|
@ -782,11 +828,6 @@ let (|StripNullableTy|) g ty =
|
|||
| AppTy g (tcr, [tyarg]) when tyconRefEq g tcr g.system_Nullable_tcref -> tyarg
|
||||
| _ -> 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 =
|
||||
match typ with
|
||||
| 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 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 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)
|
||||
|
||||
|
@ -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,
|
||||
/// 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.
|
||||
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
|
||||
/// 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 mkAddrSet m v e = Expr.Op (TOp.LValueOp (LByrefSet, v), [], [e], 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
|
||||
|
@ -1315,14 +1357,21 @@ type ValHash<'T> =
|
|||
|
||||
[<Struct; NoEquality; NoComparison>]
|
||||
type ValMultiMap<'T>(contents: StampMap<'T list>) =
|
||||
|
||||
member m.ContainsKey (v: Val) =
|
||||
contents.ContainsKey v.Stamp
|
||||
|
||||
member m.Find (v: Val) =
|
||||
match contents |> Map.tryFind v.Stamp with
|
||||
| Some vals -> vals
|
||||
| _ -> []
|
||||
|
||||
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.Contents = contents
|
||||
|
||||
static member Empty = ValMultiMap<'T>(Map.empty)
|
||||
|
||||
[<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
|
||||
| _ -> failwith "destListTy"
|
||||
|
||||
let isTypeConstructorEqualToOptional g tcOpt tc =
|
||||
let tyconRefEqOpt g tcOpt tc =
|
||||
match tcOpt with
|
||||
| None -> false
|
||||
| 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 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)
|
||||
|
@ -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 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 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
|
||||
let extensionInfoOfTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.TypeReprInfo | _ -> TNoRepr)
|
||||
#endif
|
||||
|
@ -2754,7 +2814,7 @@ let isILAttribByName (tencl:string list, tname: string) (attr: ILAttribute) =
|
|||
(attr.Method.DeclaringType.TypeSpec.Name = tname) &&
|
||||
(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) =
|
||||
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
|
||||
// on imported types. However this is fairly rare and can also be solved by caching the
|
||||
// results of attribute lookups in the TAST
|
||||
let HasILAttribute tref (attrs: ILAttributes) = Array.exists (isILAttrib tref) attrs.AsArray
|
||||
|
||||
let HasILAttributeByName tname (attrs: ILAttributes) = Array.exists (isILAttribByName ([], tname)) attrs.AsArray
|
||||
let HasILAttribute tref (attrs: ILAttributes) =
|
||||
attrs.AsArray |> Array.exists (isILAttrib tref)
|
||||
|
||||
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)
|
||||
|
||||
// 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)
|
||||
let IsMatchingFSharpAttribute g (AttribInfo(_, tcref)) (Attrib(tcref2, _, _, _, _, _, _)) = tyconRefEq g tcref tcref2
|
||||
let HasFSharpAttribute g tref attrs = List.exists (IsMatchingFSharpAttribute g tref) attrs
|
||||
|
@ -2881,15 +2935,44 @@ let TyconRefHasAttribute g m attribSpec tcref =
|
|||
(fun _ -> Some ())
|
||||
|> 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...
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
let destByrefTy g ty =
|
||||
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"
|
||||
|
||||
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 =
|
||||
match ty |> stripTyEqns g with
|
||||
| TType_app(tcref, [x]) when tyconRefEq g g.nativeptr_tcr tcref -> x
|
||||
|
@ -3062,7 +3145,7 @@ module DebugPrint = begin
|
|||
|
||||
let lvalopL x =
|
||||
match x with
|
||||
| LGetAddr -> wordL (tagText "LGetAddr")
|
||||
| LAddrOf readonly -> wordL (tagText (sprintf "LAddrOf(%b)" readonly))
|
||||
| LByrefGet -> wordL (tagText "LByrefGet")
|
||||
| LSet -> wordL (tagText "LSet")
|
||||
| LByrefSet -> wordL (tagText "LByrefSet")
|
||||
|
@ -3539,9 +3622,9 @@ module DebugPrint = begin
|
|||
(atomL rx ^^ rightL(tagText ".#") ^^ recdFieldRefL rf)
|
||||
| Expr.Op (TOp.ValFieldGet rf, _, [], _) ->
|
||||
recdFieldRefL rf
|
||||
| Expr.Op (TOp.ValFieldGetAddr rf, _, [rx], _) ->
|
||||
| Expr.Op (TOp.ValFieldGetAddr (rf, _), _, [rx], _) ->
|
||||
leftL(tagText "&") ^^ bracketL (atomL rx ^^ rightL(tagText ".!") ^^ recdFieldRefL rf)
|
||||
| Expr.Op (TOp.ValFieldGetAddr rf, _, [], _) ->
|
||||
| Expr.Op (TOp.ValFieldGetAddr (rf, _), _, [], _) ->
|
||||
leftL(tagText "&") ^^ (recdFieldRefL rf)
|
||||
| Expr.Op (TOp.UnionCaseTagGet tycr, _, [x], _) ->
|
||||
wordL (tagText ("#" + tycr.LogicalName + ".tag")) ^^ atomL x
|
||||
|
@ -3584,7 +3667,7 @@ module DebugPrint = begin
|
|||
| Expr.Op (TOp.Bytes _, _ , _ , _) ->
|
||||
wordL(tagText "bytes++")
|
||||
| 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.ExnFieldGet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldGet...")
|
||||
| Expr.Op (TOp.ExnFieldSet _, _tyargs, _args, _) -> wordL(tagText "TOp.ExnFieldSet...")
|
||||
|
@ -4307,7 +4390,7 @@ and accFreeInOp opts op acc =
|
|||
| TOp.TryFinally _
|
||||
| TOp.For _
|
||||
| TOp.Coerce
|
||||
| TOp.RefAddrGet
|
||||
| TOp.RefAddrGet _
|
||||
| TOp.Array
|
||||
| TOp.While _
|
||||
| TOp.Goto _ | TOp.Label _ | TOp.Return
|
||||
|
@ -4320,7 +4403,7 @@ and accFreeInOp opts op acc =
|
|||
// Things containing just a union case reference
|
||||
| TOp.UnionCaseProof cr
|
||||
| TOp.UnionCase cr
|
||||
| TOp.UnionCaseFieldGetAddr (cr, _)
|
||||
| TOp.UnionCaseFieldGetAddr (cr, _, _)
|
||||
| TOp.UnionCaseFieldGet (cr, _)
|
||||
| TOp.UnionCaseFieldSet (cr, _) -> accFreeUnionCaseRef opts cr acc
|
||||
|
||||
|
@ -4330,7 +4413,7 @@ and accFreeInOp opts op acc =
|
|||
| TOp.ExnFieldSet (ecr, _) -> accFreeExnRef ecr acc
|
||||
|
||||
| TOp.ValFieldGet fr
|
||||
| TOp.ValFieldGetAddr fr
|
||||
| TOp.ValFieldGetAddr (fr, _)
|
||||
| TOp.ValFieldSet fr -> accFreeRecdFieldRef opts fr acc
|
||||
|
||||
| TOp.Recd (kind, tcr) ->
|
||||
|
@ -4756,23 +4839,23 @@ and remapExpr (g: TcGlobals) (compgen:ValCopyFlag) (tmenv:Remap) x =
|
|||
// of a temporary local, e.g.
|
||||
// &(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 (entityRefInThisAssembly g.compilingFslib rfref.TyconRef) ->
|
||||
|
||||
let tinst = remapTypes tmenv tinst
|
||||
let arg = remapExpr g compgen tmenv arg
|
||||
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 (entityRefInThisAssembly g.compilingFslib uref.TyconRef) ->
|
||||
|
||||
let tinst = remapTypes tmenv tinst
|
||||
let arg = remapExpr g compgen tmenv arg
|
||||
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) ->
|
||||
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.ValFieldSet rfref -> TOp.ValFieldSet(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.UnionCaseFieldGetAddr(ucref, n, readonly) -> TOp.UnionCaseFieldGetAddr(remapUnionCaseRef tmenv.tyconRefRemap ucref, n, readonly)
|
||||
| TOp.UnionCaseFieldSet(ucref, n) -> TOp.UnionCaseFieldSet(remapUnionCaseRef tmenv.tyconRefRemap ucref, n)
|
||||
| TOp.ILAsm (instrs, tys) ->
|
||||
let tys2 = remapTypes tmenv tys
|
||||
|
@ -5236,16 +5320,17 @@ let isUnionCaseDefinitelyMutable (uc:UnionCase) = uc.FieldTable.FieldsByIndex |>
|
|||
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.
|
||||
let isRecdOrUnionOrStructTyconDefinitelyMutable (_g:TcGlobals) (tycon:Tycon) =
|
||||
let isRecdOrUnionOrStructTyconRefDefinitelyMutable (tcref: TyconRef) =
|
||||
let tycon = tcref.Deref
|
||||
if tycon.IsUnionTycon then
|
||||
tycon.UnionCasesArray |> Array.exists isUnionCaseDefinitelyMutable
|
||||
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
|
||||
else
|
||||
false
|
||||
|
||||
let isRecdOrUnionOrStructTyconRefDefinitelyMutable g (tcr : TyconRef) = isRecdOrUnionOrStructTyconDefinitelyMutable g tcr.Deref
|
||||
|
||||
// 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
|
||||
// each raised object. Hence we treat exception objects as if they have identity
|
||||
|
@ -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
|
||||
// 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
|
||||
// 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.
|
||||
let isUnionCaseFieldMutable (g: TcGlobals) (ucref:UnionCaseRef) n =
|
||||
(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.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.ValFieldGetAddr(fref) -> mkByrefTy g (actualTyOfRecdFieldRef fref tinst)
|
||||
| TOp.ValFieldGetAddr(fref, readonly) -> mkByrefTyWithFlag g readonly (actualTyOfRecdFieldRef fref tinst)
|
||||
| TOp.ValFieldGet(fref) -> actualTyOfRecdFieldRef fref tinst
|
||||
| (TOp.ValFieldSet _ | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ | TOp.LValueOp ((LSet | LByrefSet), _)) ->g.unit_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.ExnFieldGet(ecref, j) -> recdFieldTyOfExnDefRefByIdx ecref j
|
||||
| TOp.LValueOp (LByrefGet, v) -> destByrefTy g v.Type
|
||||
| TOp.LValueOp (LGetAddr, v) -> mkByrefTy g v.Type
|
||||
| TOp.RefAddrGet -> (match tinst with [ty] -> mkByrefTy g ty | _ -> failwith "bad TOp.RefAddrGet node")
|
||||
| TOp.LValueOp (LAddrOf readonly, v) -> mkByrefTyWithFlag g readonly v.Type
|
||||
| TOp.RefAddrGet readonly -> (match tinst with [ty] -> mkByrefTyWithFlag g readonly ty | _ -> failwith "bad TOp.RefAddrGet node")
|
||||
| TOp.TraitCall (TTrait(_, _, _, _, ty, _)) -> GetFSharpViewOfReturnType g ty
|
||||
| TOp.Reraise -> (match tinst with [rtn_ty] -> rtn_ty | _ -> failwith "bad TOp.Reraise node")
|
||||
| TOp.Goto _ | TOp.Label _ | TOp.Return ->
|
||||
|
@ -5565,17 +5650,39 @@ let mkAndSimplifyMatch spBind exprm matchm ty tree targets =
|
|||
// mkExprAddrOfExprAux
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
type Mutates = DefinitelyMutates | PossiblyMutates | NeverMutates
|
||||
type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates
|
||||
exception DefensiveCopyWarning of string * range
|
||||
|
||||
let isRecdOrStructTyReadOnly g ty =
|
||||
match tryDestAppTy g ty with
|
||||
| None -> false
|
||||
| Some tcref ->
|
||||
not (isRecdOrUnionOrStructTyconRefDefinitelyMutable g tcref) ||
|
||||
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
|
||||
| None -> false
|
||||
| Some tcref -> isRecdOrStructTyconRefReadOnly g m tcref
|
||||
|
||||
|
||||
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
|
||||
// under certain conditions
|
||||
// - all instances of the type are known to be immutable; OR
|
||||
|
@ -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
|
||||
// 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
|
||||
// and the value is a true local or closure field.
|
||||
not v.IsMutable &&
|
||||
not v.IsMemberOrModuleBinding &&
|
||||
(match mut with
|
||||
| NeverMutates -> true
|
||||
| PossiblyMutates -> isRecdOrStructTyReadOnly g v.Type
|
||||
| DefinitelyMutates -> false)
|
||||
not vref.IsMutable &&
|
||||
not vref.IsMemberOrModuleBinding &&
|
||||
// Note: We can't add this:
|
||||
// || valRefInThisAssembly g.compilingFslib vref
|
||||
// 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".
|
||||
// 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) =
|
||||
v.IsMutable &&
|
||||
let MustTakeAddressOfVal (g:TcGlobals) (vref:ValRef) =
|
||||
vref.IsMutable &&
|
||||
// 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
|
||||
not rf.IsStatic &&
|
||||
rf.IsMutable
|
||||
not rfref.IsStatic &&
|
||||
rfref.IsMutable
|
||||
|
||||
let MustTakeAddressOfRecdFieldRef (rfref: RecdFieldRef) = MustTakeAddressOfRecdField rfref.RecdField
|
||||
|
||||
let CanTakeAddressOfRecdFieldRef (g:TcGlobals) (rfref: RecdFieldRef) mut tinst =
|
||||
mut <> DefinitelyMutates &&
|
||||
let CanTakeAddressOfRecdFieldRef (g:TcGlobals) m (rfref: RecdFieldRef) tinst mut =
|
||||
// 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 &&
|
||||
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 =
|
||||
mut <> DefinitelyMutates &&
|
||||
let CanTakeAddressOfUnionFieldRef (g:TcGlobals) m (uref: UnionCaseRef) cidx tinst mut =
|
||||
// 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 &&
|
||||
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 =
|
||||
if not mustTakeAddress then None, e else
|
||||
match e with
|
||||
// LVALUE: "x" where "x" is byref
|
||||
| Expr.Op (TOp.LValueOp (LByrefGet, v), _, [], m) ->
|
||||
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 of "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 intra-assembly values
|
||||
| Expr.Val(vref, _, m) when MustTakeAddressOfVal g vref || CanTakeAddressOfImmutableVal g m vref mut ->
|
||||
let readonly = not (MustTakeAddressOfVal g vref)
|
||||
None, mkValAddr m readonly vref, readonly
|
||||
|
||||
// LVALUE: "x" where "e.x" is a .NET static field.
|
||||
// LVALUE of "e.f" where "f" is record field.
|
||||
| Expr.Op (TOp.ValFieldGet rfref, tinst, [obje], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref tinst mut ->
|
||||
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 of "e.f" where "f" is union field.
|
||||
| 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 wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut obje None m
|
||||
let readonly = readonly || not (MustTakeAddressOfRecdField (uref.FieldByIndex(cidx)))
|
||||
wrap, mkUnionCaseFieldGetAddrProvenViaExprAddr(readonly, expra, uref, tinst, cidx, m), readonly
|
||||
|
||||
// LVALUE of "f" where "f" is a .NET static field.
|
||||
| Expr.Op (TOp.ILAsm ([IL.I_ldsfld(_vol, fspec)], [ty2]), tinst, [], m) ->
|
||||
None, Expr.Op (TOp.ILAsm ([IL.I_ldsflda(fspec)], [mkByrefTy g ty2]), 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: "x" where "e.x" is a .NET instance field. "e" may be an lvalue
|
||||
| Expr.Op (TOp.ILAsm ([IL.I_ldfld(_align, _vol, fspec)], [ty2]), tinst, [e], m)
|
||||
->
|
||||
let exprty = tyOfExpr g e
|
||||
let wrap, expra = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m
|
||||
wrap, Expr.Op (TOp.ILAsm ([IL.I_ldflda(fspec)], [mkByrefTy g ty2]), tinst, [expra], m)
|
||||
// LVALUE of "e.f" where "f" is a .NET instance field.
|
||||
| Expr.Op (TOp.ILAsm ([IL.I_ldfld(_align, _vol, fspec)], [ty2]), tinst, [obje], m) ->
|
||||
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: "x" where "x" is mutable static field.
|
||||
| Expr.Op (TOp.ValFieldGet rfref, tinst, [], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g rfref mut tinst ->
|
||||
None, mkStaticRecdFieldGetAddr(rfref, tinst, m)
|
||||
// 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: "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) ->
|
||||
// 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 readonly = false // array address is never forced to be readonly
|
||||
let shape = ILArrayShape.SingleDimensional
|
||||
let readonly = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress
|
||||
let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress
|
||||
let isNativePtr =
|
||||
match addrExprVal with
|
||||
| Some(vf) -> valRefEq g vf g.addrof2_vref
|
||||
| _ -> false
|
||||
None, mkArrayElemAddress g (readonly, isNativePtr, shape, elemTy, aexpr, nexpr, m)
|
||||
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
|
||||
| Expr.App(Expr.Val(vf, _, _), _, [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) ->
|
||||
// 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(vref, _, _), _, [elemTy], (aexpr::args), _)
|
||||
when (valRefEq g vref g.array2D_get_vref || valRefEq g vref g.array3D_get_vref || valRefEq g vref g.array4D_get_vref) ->
|
||||
|
||||
let readonly = false // array address is never forced to be readonly
|
||||
let shape = ILArrayShape.FromRank args.Length
|
||||
let readonly = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress
|
||||
let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress
|
||||
let isNativePtr =
|
||||
match addrExprVal with
|
||||
| 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
|
||||
| Expr.Val(v, _, m) when mut = DefinitelyMutates
|
||||
->
|
||||
if isByrefTy g v.Type then error(Error(FSComp.SR.tastUnexpectedByRef(), m));
|
||||
if v.IsMutable then
|
||||
error(Error(FSComp.SR.tastInvalidAddressOfMutableAcrossAssemblyBoundary(), m));
|
||||
else
|
||||
error(Error(FSComp.SR.tastValueMustBeMutable(), m));
|
||||
// LVALUE: "&meth(args)" where meth has a byref or inref return. Includes "&span.[idx]".
|
||||
| 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)
|
||||
None, e, readonly
|
||||
|
||||
// Give a nice error message for address-of-byref
|
||||
| Expr.Val(vref, _, m) when isByrefTy g vref.Type ->
|
||||
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
|
||||
| Expr.Val _ when mut = DefinitelyMutates ->
|
||||
error(Error(FSComp.SR.tastValueMustBeMutable(), m))
|
||||
|
||||
| _ ->
|
||||
let ty = tyOfExpr g e
|
||||
let ty = tyOfExpr g expr
|
||||
if isStructTy g ty then
|
||||
match mut with
|
||||
| NeverMutates -> ()
|
||||
| AddressOfOp -> () // we get an inref
|
||||
| DefinitelyMutates ->
|
||||
errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(), m));
|
||||
// Give a nice error message for mutating something we can't take the address of
|
||||
errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(), m))
|
||||
| PossiblyMutates ->
|
||||
warning(DefensiveCopyWarning(FSComp.SR.tastValueHasBeenCopied(), m));
|
||||
// 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
|
||||
Some (tmp, e), (mkValAddr m (mkLocalValRef tmp))
|
||||
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 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
|
||||
| None -> (fun x -> x), addre
|
||||
| Some (tmp, rval) -> (fun x -> mkCompGenLet m tmp rval x), addre
|
||||
| None -> (fun x -> x), addre, readonly
|
||||
| Some (tmp, rval) -> (fun x -> mkCompGenLet m tmp rval x), addre, readonly
|
||||
|
||||
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))
|
||||
|
||||
let mkRecdFieldGet g (e, fref:RecdFieldRef, tinst, m) =
|
||||
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))
|
||||
|
||||
let mkUnionCaseFieldGetUnproven g (e, cref:UnionCaseRef, tinst, j, m) =
|
||||
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))
|
||||
|
||||
|
||||
|
|
|
@ -164,6 +164,9 @@ val isBeingGeneralized : Typar -> TypeScheme -> bool
|
|||
val mkLazyAnd : TcGlobals -> range -> Expr -> Expr -> Expr
|
||||
val mkLazyOr : TcGlobals -> range -> Expr -> Expr -> Expr
|
||||
val mkByrefTy : TcGlobals -> TType -> TType
|
||||
val mkByrefTyWithInference : TcGlobals -> TType -> TType -> TType
|
||||
val mkInByrefTy : TcGlobals -> TType -> TType
|
||||
val mkOutByrefTy : TcGlobals -> TType -> TType
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Make construction operations
|
||||
|
@ -183,10 +186,10 @@ val mkReraiseLibCall : TcGlobals -> TType -> range -> Expr
|
|||
|
||||
val mkTupleFieldGet : TcGlobals -> TupInfo * Expr * TypeInst * int * 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 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 mkUnionCaseTagGetViaExprAddr : Expr * TyconRef * TypeInst * range -> Expr
|
||||
|
||||
|
@ -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,
|
||||
/// 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.
|
||||
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,
|
||||
/// 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 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
|
||||
|
@ -263,9 +266,9 @@ val convertToTypeWithMetadataIfPossible : TcGlobals -> TType -> TType
|
|||
//-------------------------------------------------------------------------
|
||||
|
||||
exception DefensiveCopyWarning of string * range
|
||||
type Mutates = DefinitelyMutates | PossiblyMutates | NeverMutates
|
||||
val mkExprAddrOfExprAux : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Val * Expr) option * Expr
|
||||
val mkExprAddrOfExpr : TcGlobals -> bool -> bool -> Mutates -> Expr -> ValRef option -> range -> (Expr -> Expr) * Expr
|
||||
type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates
|
||||
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 * bool
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// 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
|
||||
[<Struct; NoEquality; NoComparison>]
|
||||
type ValMultiMap<'T> =
|
||||
|
||||
member ContainsKey : Val -> bool
|
||||
|
||||
member Find : Val -> 'T list
|
||||
|
||||
member Add : Val * 'T -> ValMultiMap<'T>
|
||||
|
||||
member Remove : Val -> ValMultiMap<'T>
|
||||
|
||||
member Contents : StampMap<'T list>
|
||||
|
||||
static member Empty : ValMultiMap<'T>
|
||||
|
||||
[<Sealed>]
|
||||
/// Maps Typar to T based on stamp keys
|
||||
type TyparMap<'T> =
|
||||
|
||||
member Item : Typar -> 'T with get
|
||||
|
||||
member ContainsKey : Typar -> bool
|
||||
|
||||
member TryFind : Typar -> 'T option
|
||||
|
||||
member Add : Typar * 'T -> TyparMap<'T>
|
||||
|
||||
static member Empty : TyparMap<'T>
|
||||
|
||||
[<NoEquality; NoComparison;Sealed>]
|
||||
/// Maps TyconRef to T based on stamp keys
|
||||
type TyconRefMap<'T> =
|
||||
|
||||
member Item : TyconRef -> 'T with get
|
||||
|
||||
member TryFind : TyconRef -> 'T option
|
||||
|
||||
member ContainsKey : TyconRef -> bool
|
||||
|
||||
member Add : TyconRef -> 'T -> TyconRefMap<'T>
|
||||
|
||||
member Remove : TyconRef -> TyconRefMap<'T>
|
||||
|
||||
member IsEmpty : bool
|
||||
|
||||
static member Empty : TyconRefMap<'T>
|
||||
|
||||
static member OfList : (TyconRef * 'T) list -> TyconRefMap<'T>
|
||||
|
||||
/// Maps TyconRef to list of T based on stamp keys
|
||||
[<Struct; NoEquality; NoComparison>]
|
||||
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
|
||||
|
@ -874,7 +900,7 @@ val mkAddrSet : range -> ValRef -> Expr -> Expr
|
|||
/// *localv_ptr
|
||||
val mkAddrGet : range -> ValRef -> Expr
|
||||
/// &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
|
||||
|
@ -978,6 +1004,7 @@ val ExprStats : Expr -> string
|
|||
//-------------------------------------------------------------------------
|
||||
|
||||
val mkNativePtrTy : TcGlobals -> TType -> TType
|
||||
val mkVoidPtrTy : TcGlobals -> TType
|
||||
val mkArrayType : TcGlobals -> TType -> TType
|
||||
val isOptionTy : TcGlobals -> TType -> bool
|
||||
val destOptionTy : TcGlobals -> TType -> TType
|
||||
|
@ -1095,10 +1122,13 @@ val TypeHasDefaultValue : TcGlobals -> range -> TType -> bool
|
|||
val isAbstractTycon : Tycon -> bool
|
||||
|
||||
val isUnionCaseRefDefinitelyMutable : UnionCaseRef -> bool
|
||||
val isRecdOrUnionOrStructTyconRefDefinitelyMutable : TcGlobals -> TyconRef -> bool
|
||||
val isRecdOrUnionOrStructTyconRefDefinitelyMutable : TyconRef -> bool
|
||||
val isExnDefinitelyMutable : TyconRef -> bool
|
||||
val isUnionCaseFieldMutable : TcGlobals -> UnionCaseRef -> 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 ComputeFieldName : Tycon -> RecdField -> string
|
||||
|
@ -1377,7 +1407,6 @@ val TryFindAttributeUsageAttribute : TcGlobals -> range -> TyconRef -> bool opti
|
|||
val TryDecodeTypeProviderAssemblyAttr : ILGlobals -> ILAttribute -> string option
|
||||
#endif
|
||||
val IsSignatureDataVersionAttr : ILAttribute -> bool
|
||||
val ILThingHasExtensionAttribute : ILAttributes -> bool
|
||||
val TryFindAutoOpenAttr : IL.ILGlobals -> ILAttribute -> string option
|
||||
val TryFindInternalsVisibleToAttr : IL.ILGlobals -> ILAttribute -> string option
|
||||
val IsMatchingSignatureDataVersionAttr : IL.ILGlobals -> ILVersionInfo -> ILAttribute -> bool
|
||||
|
@ -1396,13 +1425,17 @@ val mkCompilerGeneratedAttr : TcGlobals -> int -> ILAtt
|
|||
// More common type construction
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
val isInByrefTy : TcGlobals -> TType -> bool
|
||||
val isOutByrefTy : TcGlobals -> TType -> bool
|
||||
val isByrefTy : TcGlobals -> TType -> bool
|
||||
|
||||
val isNativePtrTy : TcGlobals -> TType -> bool
|
||||
val destByrefTy : TcGlobals -> TType -> TType
|
||||
val destNativePtrTy : TcGlobals -> TType -> TType
|
||||
|
||||
val isByrefLikeTyconRef : TcGlobals -> TyconRef -> bool
|
||||
val isByrefLikeTy : TcGlobals -> TType -> bool
|
||||
val isByrefTyconRef : TcGlobals -> TyconRef -> bool
|
||||
val isByrefLikeTyconRef : TcGlobals -> range -> TyconRef -> bool
|
||||
val isByrefLikeTy : TcGlobals -> range -> TType -> bool
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// 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_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 =
|
||||
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 =
|
||||
match u_byte st with
|
||||
| 0 -> LGetAddr
|
||||
| 0 -> LAddrOf false
|
||||
| 1 -> LByrefGet
|
||||
| 2 -> LSet
|
||||
| 3 -> LByrefSet
|
||||
|
@ -2284,7 +2284,7 @@ and p_op x st =
|
|||
else
|
||||
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.RefAddrGet -> p_byte 13 st
|
||||
| TOp.RefAddrGet _ -> p_byte 13 st
|
||||
| TOp.UnionCaseProof (a) -> p_byte 14 st; p_ucref a st
|
||||
| TOp.Coerce -> p_byte 15 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.TryCatch _ -> p_byte 23 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.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 30 is taken for struct tuples, see above
|
||||
| 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
|
||||
let b = u_typs st
|
||||
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
|
||||
TOp.UnionCaseProof a
|
||||
| 15 -> TOp.Coerce
|
||||
|
@ -2360,12 +2360,12 @@ and u_op st =
|
|||
| 23 -> TOp.TryCatch(NoSequencePointAtTry,NoSequencePointAtWith)
|
||||
| 24 -> TOp.TryFinally(NoSequencePointAtTry,NoSequencePointAtFinally)
|
||||
| 25 -> let a = u_rfref st
|
||||
TOp.ValFieldGetAddr a
|
||||
TOp.ValFieldGetAddr (a, false)
|
||||
| 26 -> TOp.UInt16s (u_array u_uint16 st)
|
||||
| 27 -> TOp.Reraise
|
||||
| 28 -> let a = u_ucref st
|
||||
let b = u_int st
|
||||
TOp.UnionCaseFieldGetAddr (a,b)
|
||||
TOp.UnionCaseFieldGetAddr (a,b, false)
|
||||
| 29 -> TOp.Tuple tupInfoStruct
|
||||
| 30 -> let a = u_int st
|
||||
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 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
|
||||
|
||||
let unpickleModuleOrNamespace st = u_tycon_spec st
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
/// comparison and hashing functions.
|
||||
module internal Microsoft.FSharp.Compiler.TcGlobals
|
||||
|
||||
open Internal.Utilities
|
||||
open System.Collections.Generic
|
||||
open System.Diagnostics
|
||||
|
||||
open Microsoft.FSharp.Compiler
|
||||
open Microsoft.FSharp.Compiler.AbstractIL
|
||||
open Microsoft.FSharp.Compiler.AbstractIL.IL
|
||||
|
@ -21,12 +23,24 @@ open Microsoft.FSharp.Compiler.Ast
|
|||
open Microsoft.FSharp.Compiler.Lib
|
||||
open Microsoft.FSharp.Compiler.PrettyNaming
|
||||
|
||||
open System.Collections.Generic
|
||||
open Internal.Utilities
|
||||
|
||||
let internal DummyFileNameForRangesWithoutASpecificLocation = "startup"
|
||||
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
|
||||
|
||||
|
@ -37,7 +51,6 @@ let ValRefForIntrinsic (IntrinsicValRef(mvr, _, _, _, key)) = mkNonLocalValRef
|
|||
[<AutoOpen>]
|
||||
module FSharpLib =
|
||||
|
||||
let CoreOperatorsName = FSharpLib.Root + ".Core.Operators"
|
||||
let CoreOperatorsCheckedName = FSharpLib.Root + ".Core.Operators.Checked"
|
||||
let ControlName = FSharpLib.Root + ".Control"
|
||||
let LinqName = FSharpLib.Root + ".Linq"
|
||||
|
@ -47,22 +60,18 @@ module FSharpLib =
|
|||
let LinqRuntimeHelpersName = FSharpLib.Root + ".Linq.RuntimeHelpers"
|
||||
let RuntimeHelpersName = FSharpLib.Root + ".Core.CompilerServices.RuntimeHelpers"
|
||||
let ExtraTopLevelOperatorsName = FSharpLib.Root + ".Core.ExtraTopLevelOperators"
|
||||
let HashCompareName = FSharpLib.Root + ".Core.LanguagePrimitives.HashCompare"
|
||||
let NativeInteropName = FSharpLib.Root + ".NativeInterop"
|
||||
|
||||
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 LinqPath = IL.splitNamespace LinqName
|
||||
let CollectionsPath = IL.splitNamespace CollectionsName
|
||||
let LanguagePrimitivesPath = IL.splitNamespace LanguagePrimitivesName |> Array.ofList
|
||||
let HashComparePath = IL.splitNamespace HashCompareName |> Array.ofList
|
||||
let NativeInteropPath = IL.splitNamespace NativeInteropName |> Array.ofList
|
||||
let CompilerServicesPath = IL.splitNamespace CompilerServicesName |> Array.ofList
|
||||
let LinqRuntimeHelpersPath = IL.splitNamespace LinqRuntimeHelpersName |> Array.ofList
|
||||
let RuntimeHelpersPath = IL.splitNamespace RuntimeHelpersName |> Array.ofList
|
||||
let QuotationsPath = IL.splitNamespace QuotationsName |> Array.ofList
|
||||
let ExtraTopLevelOperatorsPath = IL.splitNamespace ExtraTopLevelOperatorsName |> Array.ofList
|
||||
|
||||
let RootPathArray = FSharpLib.RootPath |> 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
|
||||
|
||||
|
||||
type public BuiltinAttribInfo =
|
||||
type
|
||||
[<NoEquality; NoComparison; StructuredFormatDisplay("{DebugText}")>]
|
||||
BuiltinAttribInfo =
|
||||
| AttribInfo of ILTypeRef * TyconRef
|
||||
|
||||
member this.TyconRef = let (AttribInfo(_, tcref)) = this in tcref
|
||||
|
||||
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>]
|
||||
let tname_DebuggerNonUserCodeAttribute = "System.Diagnostics.DebuggerNonUserCodeAttribute"
|
||||
[<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_pint64_tcr = mk_MFCore_tcref fslibCcu "int64`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_voidptr_tcr = mk_MFCore_tcref fslibCcu "voidptr"
|
||||
let v_ilsigptr_tcr = mk_MFCore_tcref fslibCcu "ilsigptr`1"
|
||||
let v_fastFunc_tcr = mk_MFCore_tcref fslibCcu "FSharpFunc`2"
|
||||
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_MFLinqRuntimeHelpers_nleref = mkNonLocalEntityRef fslibCcu FSharpLib.LinqRuntimeHelpersPath
|
||||
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_MFIntrinsicOperators_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicOperators"
|
||||
let fslib_MFIntrinsicFunctions_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "IntrinsicFunctions"
|
||||
let fslib_MFHashCompare_nleref = mkNestedNonLocalEntityRef fslib_MFLanguagePrimitives_nleref "HashCompare"
|
||||
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_MFOperatorsUnchecked_nleref = mkNestedNonLocalEntityRef fslib_MFOperators_nleref "Unchecked"
|
||||
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_MFMapModule_nleref = mkNestedNonLocalEntityRef fslib_MFCollections_nleref "MapModule"
|
||||
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_MFRuntimeHelpers_nleref = mkNestedNonLocalEntityRef fslib_MFCompilerServices_nleref "RuntimeHelpers"
|
||||
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_MFMapModule_nleref
|
||||
fslib_MFStringModule_nleref
|
||||
fslib_MFNativePtrModule_nleref
|
||||
fslib_MFOptionModule_nleref
|
||||
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_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_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))
|
||||
|
@ -915,7 +946,11 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
|
|||
member __.pint16_tcr = v_pint16_tcr
|
||||
member __.pint64_tcr = v_pint64_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 __.voidptr_tcr = v_voidptr_tcr
|
||||
member __.ilsigptr_tcr = v_ilsigptr_tcr
|
||||
member __.fastFunc_tcr = v_fastFunc_tcr
|
||||
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 __.seq_tcr = v_seq_tcr
|
||||
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 measureinverse_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureInverse`1"
|
||||
member val measureone_tcr = mk_MFCompilerServices_tcref fslibCcu "MeasureOne"
|
||||
|
@ -1074,6 +1112,11 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d
|
|||
member val attrib_IDispatchConstantAttribute = tryFindSysAttrib "System.Runtime.CompilerServices.IDispatchConstantAttribute"
|
||||
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_DllImportAttribute = tryFindSysAttrib "System.Runtime.InteropServices.DllImportAttribute"
|
||||
member val attrib_StructLayoutAttribute = findSysAttrib "System.Runtime.InteropServices.StructLayoutAttribute"
|
||||
|
@ -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_FieldOffsetAttribute = findSysAttrib "System.Runtime.InteropServices.FieldOffsetAttribute"
|
||||
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_OptionalAttribute = tryFindSysAttrib "System.Runtime.InteropServices.OptionalAttribute"
|
||||
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 seq_singleton_vref = ValRefForIntrinsic v_seq_singleton_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_delay_vref = ValRefForIntrinsic v_seq_delay_info
|
||||
member val seq_append_vref = ValRefForIntrinsic v_seq_append_info
|
||||
|
|
|
@ -537,8 +537,8 @@ type cenv =
|
|||
let CopyAndFixupTypars m rigid tpsorig =
|
||||
ConstraintSolver.FreshenAndFixupTypars m rigid [] [] tpsorig
|
||||
|
||||
let UnifyTypes cenv (env: TcEnv) m expectedTy actualTy =
|
||||
ConstraintSolver.AddCxTypeEqualsType env.eContextInfo env.DisplayEnv cenv.css m (tryNormalizeMeasureInType cenv.g expectedTy) (tryNormalizeMeasureInType cenv.g actualTy)
|
||||
let UnifyTypes cenv (env: TcEnv) m actualTy expectedTy =
|
||||
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
|
||||
let MakeInitialEnv env =
|
||||
|
@ -864,7 +864,7 @@ let TcConst cenv ty m env c =
|
|||
| SynMeasure.Anon _ -> error(Error(FSComp.SR.tcUnexpectedMeasureAnon(), 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 measureTy =
|
||||
|
@ -2100,32 +2100,37 @@ module GeneralizationHelpers =
|
|||
|
||||
let rec IsGeneralizableValue g t =
|
||||
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
|
||||
| Expr.Op(TOp.Coerce, [inputTy;actualTy], [e1], _) when isFunTy g actualTy && isFunTy g inputTy ->
|
||||
IsGeneralizableValue g e1
|
||||
|
||||
| Expr.Op(op, _, args, _) ->
|
||||
|
||||
let canGeneralizeOp =
|
||||
match op with
|
||||
| TOp.Tuple _ -> true
|
||||
| TOp.UnionCase uc -> not (isUnionCaseRefDefinitelyMutable uc)
|
||||
| TOp.Recd(ctorInfo, tcref) ->
|
||||
match ctorInfo with
|
||||
| RecdExpr -> not (isRecdOrUnionOrStructTyconRefDefinitelyMutable g tcref)
|
||||
| RecdExpr -> not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref)
|
||||
| RecdExprIsObjInit -> false
|
||||
| TOp.Array -> isNil args
|
||||
| TOp.ExnConstr ec -> not (isExnDefinitelyMutable ec)
|
||||
|
||||
| TOp.ILAsm([], _) -> true
|
||||
|
||||
| _ -> false
|
||||
&& List.forall (IsGeneralizableValue g) args
|
||||
|
||||
canGeneralizeOp && List.forall (IsGeneralizableValue g) args
|
||||
|
||||
| Expr.LetRec(binds, body, _, _) ->
|
||||
binds |> List.forall (fun b -> not b.Var.IsMutable) &&
|
||||
binds |> List.forall (fun b -> IsGeneralizableValue g b.Expr) &&
|
||||
IsGeneralizableValue g body
|
||||
|
||||
| Expr.Let(bind, body, _, _) ->
|
||||
not bind.Var.IsMutable &&
|
||||
IsGeneralizableValue g bind.Expr &&
|
||||
|
@ -2639,6 +2644,9 @@ let FreshenObjectArgType cenv m rigid tcref isExtrinsic declaredTyconTypars =
|
|||
// Struct members have a byref 'this' type (unless they are extrinsic extension members)
|
||||
let thisTy =
|
||||
if not isExtrinsic && tcref.IsStructOrEnumTycon then
|
||||
if isRecdOrStructTyReadOnly cenv.g m objTy then
|
||||
mkInByrefTy cenv.g objTy
|
||||
else
|
||||
mkByrefTy cenv.g objTy
|
||||
else
|
||||
objTy
|
||||
|
@ -3058,7 +3066,7 @@ let BuildILFieldGet g amap m objExpr (finfo:ILFieldInfo) =
|
|||
Expr.Const(TcFieldInit m lit, m, fieldType)
|
||||
| _ ->
|
||||
#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
|
||||
// This ensures we always get the type instantiation right when doing this from
|
||||
// polymorphic code, after inlining etc. *
|
||||
|
@ -3076,7 +3084,7 @@ let BuildILFieldSet g m objExpr (finfo:ILFieldInfo) argExpr =
|
|||
// polymorphic code, after inlining etc. *
|
||||
let fspec = mkILFieldSpec(fref, mkILNamedTy valu fref.DeclaringTypeRef [])
|
||||
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))
|
||||
|
||||
let BuildILStaticFieldSet m (finfo:ILFieldInfo) argExpr =
|
||||
|
@ -3095,7 +3103,7 @@ let BuildRecdFieldSet g m objExpr (rfinfo:RecdFieldInfo) argExpr =
|
|||
let tgty = rfinfo.DeclaringType
|
||||
let valu = isStructTy g tgty
|
||||
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) )
|
||||
|
||||
|
||||
|
@ -3952,30 +3960,75 @@ let CheckAndRewriteObjectCtor g env (ctorLambaExpr:Expr) =
|
|||
|
||||
/// Post-typechecking normalizations to enforce semantic constraints
|
||||
/// 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
|
||||
match expr, arg with
|
||||
|
||||
// Special rule for building applications of the 'x && y' operator
|
||||
| ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [x0], _), _) , _
|
||||
when valRefEq g vf g.and_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], _), _), _
|
||||
when valRefEq g vf g.or_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, _, _), _, _, [], _), _), _
|
||||
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.
|
||||
let _unit_ty, rtn_ty = destFunTy g exprty
|
||||
MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m rtn_ty))
|
||||
MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m resultTy)), resultTy
|
||||
|
||||
// Special rules for NativePtr.ofByRef to generalize result.
|
||||
// See RFC FS-1053.md
|
||||
| ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _
|
||||
when (valRefEq g vf g.addrof_vref ||
|
||||
valRefEq g vf g.addrof2_vref) ->
|
||||
if valRefEq g vf g.addrof2_vref then warning(UseOfAddressOfOperator(m))
|
||||
let wrap, e1a' = mkExprAddrOfExpr g true false DefinitelyMutates arg (Some(vf)) m
|
||||
MakeApplicableExprNoFlex cenv (wrap(e1a'))
|
||||
when (valRefEq g vf g.nativeptr_tobyref_vref) ->
|
||||
|
||||
let argty = NewInferenceType()
|
||||
let resultTy = mkByrefTyWithInference g argty (NewByRefKindInferenceType g m)
|
||||
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
|
||||
|
@ -5959,6 +6012,10 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) =
|
|||
let mExprAndDotLookup = unionRanges e1.Range (rangeOfLid longId)
|
||||
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
|
||||
| SynExpr.DotNamedIndexedPropertySet (e1, (LongIdentWithDots(longId, _) as lidwd), e2, e3, mStmt) ->
|
||||
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 domainTy, resultTy = UnifyFunctionType (Some mWholeExpr) cenv env.DisplayEnv mWholeExpr fty
|
||||
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
|
||||
Some (PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr f' resultTy ExprAtomicFlag.Atomic delayed )
|
||||
else None
|
||||
|
@ -6292,7 +6349,7 @@ and TcRecordConstruction cenv overallTy env tpenv optOrigExpr objTy fldsList m =
|
|||
match optOrigExpr with
|
||||
| None -> [], id
|
||||
| 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 flds =
|
||||
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.
|
||||
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
|
||||
| [] ->
|
||||
// Avoid unifying twice: we're about to unify in TcDelayed
|
||||
|
||||
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
|
||||
|
||||
| DelayedDot :: _
|
||||
| DelayedSet _ :: _
|
||||
| DelayedDotLookup _ :: _ -> ()
|
||||
| DelayedTypeApp (_, _mTypeArgs, mExprAndTypeArgs) :: delayedList' ->
|
||||
// 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' ->
|
||||
let denv = env.DisplayEnv
|
||||
match UnifyFunctionTypeUndoIfFailed cenv denv mExpr exprty with
|
||||
| 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 ->
|
||||
let mArg = arg.Range
|
||||
match arg with
|
||||
|
@ -8302,7 +8385,7 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed =
|
|||
RecordNameAndTypeResolutions_IdeallyWithoutHavingOtherEffects_Delayed cenv env tpenv delayed
|
||||
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 =
|
||||
Propagate cenv overallTy env tpenv expr exprty delayed
|
||||
|
@ -8334,8 +8417,16 @@ and TcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag:ExprAtomicF
|
|||
// f<tyargs>
|
||||
| DelayedTypeApp (_, mTypeArgs, _mExprAndTypeArgs) :: _ ->
|
||||
error(Error(FSComp.SR.tcUnexpectedTypeArguments(), mTypeArgs))
|
||||
| DelayedSet _ :: _ ->
|
||||
error(Error(FSComp.SR.tcInvalidAssignment(), mExpr))
|
||||
| DelayedSet (synExpr2, mStmt) :: otherDelayed ->
|
||||
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.
|
||||
|
@ -8377,7 +8468,7 @@ and TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty (
|
|||
| _ -> ()
|
||||
|
||||
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
|
||||
| None ->
|
||||
// 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.DotIndexedSet _
|
||||
| SynExpr.LongIdentSet _
|
||||
| SynExpr.Set _
|
||||
| SynExpr.JoinIn _
|
||||
| SynExpr.NamedIndexedPropertySet _
|
||||
| SynExpr.DotNamedIndexedPropertySet _
|
||||
|
@ -8839,7 +8931,10 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del
|
|||
// Always allow subsumption on assignment to fields
|
||||
let e2', tpenv = TcExprFlex cenv true vty2 env tpenv e2
|
||||
let vexp =
|
||||
if isByrefTy cenv.g vty then
|
||||
if isInByrefTy cenv.g vty then
|
||||
errorR(Error(FSComp.SR.writeToReadOnlyByref(), mStmt))
|
||||
mkAddrSet mStmt vref e2'
|
||||
elif isByrefTy cenv.g vty then
|
||||
mkAddrSet mStmt vref e2'
|
||||
else
|
||||
mkValSet mStmt vref e2'
|
||||
|
@ -8877,11 +8972,21 @@ and TcItemThen cenv overallTy env tpenv (item, mItem, rest, afterResolution) del
|
|||
if not pinfo.IsStatic then error (Error (FSComp.SR.tcPropertyIsNotStatic(nm), mItem))
|
||||
match delayed with
|
||||
| DelayedSet(e2, mStmt) :: otherDelayed ->
|
||||
let args = if pinfo.IsIndexer then args else []
|
||||
if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt))
|
||||
// Static Property Set (possibly indexer)
|
||||
UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty
|
||||
let meths = pinfos |> SettersOfPropInfos
|
||||
if meths.IsEmpty then
|
||||
let meths = pinfos |> GettersOfPropInfos
|
||||
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
|
||||
|
@ -9052,12 +9157,21 @@ and TcLookupThen cenv overallTy env tpenv mObjExpr objExpr objExprTy longId dela
|
|||
|
||||
match delayed with
|
||||
| DelayedSet(e2, mStmt) :: otherDelayed ->
|
||||
let args = if pinfo.IsIndexer then args else []
|
||||
if not (isNil otherDelayed) then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt))
|
||||
// Instance property setter
|
||||
UnifyTypes cenv env mStmt overallTy cenv.g.unit_ty
|
||||
let meths = SettersOfPropInfos pinfos
|
||||
if isNil meths then error (Error (FSComp.SR.tcPropertyCannotBeSet1 nm, mItem))
|
||||
if meths.IsEmpty then
|
||||
let meths = pinfos |> GettersOfPropInfos
|
||||
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 []
|
||||
| _ ->
|
||||
|
@ -9213,7 +9327,7 @@ and TcMethodApplicationThen
|
|||
and GetNewInferenceTypeForMethodArg cenv env tpenv x =
|
||||
match x with
|
||||
| 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.Quote(_, raw, a, _, _) ->
|
||||
if raw then mkRawQuotedExprTy cenv.g
|
||||
|
@ -9245,7 +9359,7 @@ and TcMethodApplication
|
|||
|
||||
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
|
||||
|
||||
let callerObjArgTys = objArgs |> List.map (tyOfExpr cenv.g)
|
||||
|
@ -9624,7 +9738,7 @@ and TcMethodApplication
|
|||
if HasHeadType cenv.g cenv.g.tcref_System_Collections_Generic_Dictionary finalCalledMethInfo.ApparentEnclosingType &&
|
||||
finalCalledMethInfo.IsConstructor &&
|
||||
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
|
||||
|
||||
match argsOfAppTy cenv.g finalCalledMethInfo.ApparentEnclosingType with
|
||||
|
@ -9659,53 +9773,65 @@ and TcMethodApplication
|
|||
|
||||
// Handle adhoc argument conversions
|
||||
let coerceExpr isOutArg calledArgTy (reflArgInfo: ReflectedArgInfo) callerArgTy m callerArgExpr =
|
||||
let g = cenv.g
|
||||
|
||||
if isByrefTy cenv.g calledArgTy && isRefCellTy cenv.g callerArgTy then
|
||||
Expr.Op(TOp.RefAddrGet, [destRefCellTy cenv.g callerArgTy], [callerArgExpr], m)
|
||||
if isByrefTy g calledArgTy && isRefCellTy g callerArgTy then
|
||||
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
|
||||
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
|
||||
let delegateTy = destLinqExpressionTy cenv.g calledArgTy
|
||||
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)
|
||||
elif reflArgInfo.AutoQuote && isQuotedExprTy cenv.g calledArgTy && not (isQuotedExprTy cenv.g callerArgTy) then
|
||||
match reflArgInfo with
|
||||
| ReflectedArgInfo.Quote true ->
|
||||
mkCallLiftValueWithDefn cenv.g m calledArgTy callerArgExpr
|
||||
None, mkCallLiftValueWithDefn cenv.g m calledArgTy callerArgExpr
|
||||
| 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
|
||||
|
||||
// Note: out args do not need to be coerced
|
||||
elif isOutArg then
|
||||
callerArgExpr
|
||||
None, callerArgExpr
|
||||
|
||||
// Note: not all these casts are reported in quotations
|
||||
else
|
||||
mkCoerceIfNeeded cenv.g calledArgTy callerArgTy callerArgExpr
|
||||
None, mkCoerceIfNeeded cenv.g calledArgTy callerArgTy callerArgExpr
|
||||
|
||||
// Handle optional arguments
|
||||
let optArgPreBinder, allArgs, outArgExprs, outArgTmpBinds =
|
||||
// Handle param array and optional arguments
|
||||
let optArgPreBinder, paramArrayPreBinders, allArgs, outArgExprs, outArgTmpBinds =
|
||||
|
||||
let normalUnnamedArgs =
|
||||
(finalUnnamedCalledArgs, finalUnnamedCallerArgs) ||> List.map2 (fun called caller -> { NamedArgIdOpt = None; CalledArg=called; CallerArg=caller })
|
||||
|
||||
let paramArrayArgs =
|
||||
let paramArrayPreBinders, paramArrayArgs =
|
||||
match finalCalledMeth.ParamArrayCalledArgOpt with
|
||||
| None -> []
|
||||
| None ->
|
||||
[], []
|
||||
| Some paramArrayCalledArg ->
|
||||
let paramArrayCalledArgElementType = destArrayTy cenv.g paramArrayCalledArg.CalledArgumentType
|
||||
|
||||
let es =
|
||||
finalParamArrayCallerArgs |> List.map (fun callerArg ->
|
||||
let paramArrayPreBinders, es =
|
||||
finalParamArrayCallerArgs
|
||||
|> List.map (fun callerArg ->
|
||||
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"
|
||||
//
|
||||
|
@ -9782,7 +9908,7 @@ and TcMethodApplication
|
|||
| PassByRef (ty, dfltVal2) ->
|
||||
let v, _ = mkCompGenLocal mMethExpr "defaultByrefArg" ty
|
||||
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
|
||||
| CalleeSide ->
|
||||
let calledNonOptTy =
|
||||
|
@ -9849,7 +9975,7 @@ and TcMethodApplication
|
|||
let outArgTy = destByrefTy cenv.g calledArgTy
|
||||
let outv, outArgExpr = mkMutableCompGenLocal mMethExpr "outArg" outArgTy // mutable!
|
||||
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 }
|
||||
(outArg, outArgExpr), mkCompGenBind outv expr)
|
||||
|> List.unzip
|
||||
|
@ -9866,7 +9992,7 @@ and TcMethodApplication
|
|||
let allArgs =
|
||||
allArgs |> List.sortBy (fun x -> x.Position)
|
||||
|
||||
optArgPreBinder, allArgs, outArgExprs, outArgTmpBinds
|
||||
optArgPreBinder, paramArrayPreBinders, allArgs, outArgExprs, outArgTmpBinds
|
||||
|
||||
let coerce (assignedArg: AssignedCalledArg<_>) =
|
||||
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)))
|
||||
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
|
||||
let expr, exprty =
|
||||
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
|
||||
let expr, exprty =
|
||||
|
@ -9903,51 +10037,54 @@ and TcMethodApplication
|
|||
expr, tyOfExpr cenv.g expr
|
||||
|
||||
// Handle post-hoc property assignments
|
||||
let expr =
|
||||
if isCheckingAttributeCall then expr else
|
||||
if isNil finalAssignedItemSetters then expr else
|
||||
let setterExprPrebinders, expr =
|
||||
if isCheckingAttributeCall then
|
||||
[], expr
|
||||
elif isNil finalAssignedItemSetters then
|
||||
[], expr
|
||||
else
|
||||
// This holds the result of the call
|
||||
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
|
||||
let propSetExpr =
|
||||
(mkUnit cenv.g mMethExpr, finalAssignedItemSetters) ||> List.fold (fun acc (AssignedItemSetter(id, setter, CallerArg(callerArgTy, m, isOptCallerArg, argExpr))) ->
|
||||
let setterExprPrebinders, propSetExpr =
|
||||
(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))
|
||||
|
||||
let action, defnItem =
|
||||
let argExprPrebinder, action, defnItem =
|
||||
match setter with
|
||||
| AssignedPropSetter (pinfo, pminfo, pminst) ->
|
||||
MethInfoChecks cenv.g cenv.amap true None [objExpr] ad m pminfo
|
||||
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 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 ->
|
||||
// Get or set instance IL field
|
||||
ILFieldInstanceChecks cenv.g cenv.amap ad m finfo
|
||||
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
|
||||
action, Item.ILField finfo
|
||||
argExprPrebinder, action, Item.ILField finfo
|
||||
|
||||
| AssignedRecdFieldSetter rfinfo ->
|
||||
RecdFieldInstanceChecks cenv.g cenv.amap ad m rfinfo
|
||||
let calledArgTy = rfinfo.FieldType
|
||||
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
|
||||
action, Item.RecdField rfinfo
|
||||
argExprPrebinder, action, Item.RecdField rfinfo
|
||||
|
||||
// Record the resolution for the Language Service
|
||||
let item = Item.SetterArg (id, defnItem)
|
||||
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
|
||||
let expr = mkCompGenLet mMethExpr objv expr (mkCompGenSequential mMethExpr propSetExpr objExpr)
|
||||
expr
|
||||
setterExprPrebinders, expr
|
||||
|
||||
// Build the lambda expression if any
|
||||
let expr =
|
||||
|
@ -9973,6 +10110,10 @@ and TcMethodApplication
|
|||
expr, tpenv
|
||||
|
||||
// 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 = objArgPreBinder expr
|
||||
|
||||
|
@ -10181,7 +10322,7 @@ and TcAndBuildFixedExpr cenv env (overallPatTy, fixedExpr, overallExprTy, mBindi
|
|||
match stripExpr fixedExpr with
|
||||
| Expr.Op (op, tyargs, args, _) ->
|
||||
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_ldelema _], _), _, _ -> true
|
||||
| TOp.RefAddrGet _, _, _ -> true
|
||||
|
@ -10230,7 +10371,7 @@ and TcAndBuildFixedExpr cenv env (overallPatTy, fixedExpr, overallExprTy, mBindi
|
|||
//
|
||||
mkCompGenLetIn mBinding "tmpArray" overallExprTy fixedExpr (fun (_, ve) ->
|
||||
// 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
|
||||
let zero = mkConvToNativeInt cenv.g (mkInt32 cenv.g mBinding 0) mBinding
|
||||
// This is arr.Length
|
||||
|
@ -12418,6 +12559,12 @@ module IncrClassChecking =
|
|||
| InVar false -> true
|
||||
| _ -> 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
|
||||
/// a "let v = ..." class binding
|
||||
member localRep.MakeValueLookup thisValOpt tinst safeStaticInitInfo v tyargs m =
|
||||
|
@ -12463,19 +12610,19 @@ module IncrClassChecking =
|
|||
| InMethod _, _ ->
|
||||
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
|
||||
match localRep.LookupRepr v, thisValOpt with
|
||||
| InField(false, _, rfref), Some(thisVal) ->
|
||||
let thise = exprForVal m thisVal
|
||||
mkRecdFieldGetAddrViaExprAddr(thise, rfref, tinst, m)
|
||||
mkRecdFieldGetAddrViaExprAddr(readonly, thise, rfref, tinst, m)
|
||||
| InField(false, _, _rfref), None ->
|
||||
error(InternalError("Unexpected missing 'this' variable in MakeValueGetAddress", m))
|
||||
| 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
|
||||
| InVar _, _ ->
|
||||
mkValAddr m (mkLocalValRef v)
|
||||
mkValAddr m readonly (mkLocalValRef v)
|
||||
| InMethod _, _ ->
|
||||
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.
|
||||
/// v -> this.fieldv
|
||||
/// 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
|
||||
let FixupExprNode rw e =
|
||||
//dprintfn "Fixup %s" (showL (exprL e))
|
||||
let g = localRep.RepInfoTcGlobals
|
||||
let e = NormalizeAndAdjustPossibleSubsumptionExprs g e
|
||||
match e with
|
||||
// Rewrite references to applied let-bound-functions-compiled-as-methods
|
||||
| Expr.App(Expr.Val (ValDeref(v), _, _), _, tyargs, args, m)
|
||||
when (localRep.IsValWithRepresentation(v) &&
|
||||
(match localRep.LookupRepr(v) with
|
||||
| InMethod _ -> true //(methodVal.Typars.Length > thisTyInst.Length)
|
||||
| _ -> false )) ->
|
||||
// Rewrite references to applied recursive let-bound-functions-compiled-as-methods
|
||||
// Rewrite references to applied recursive generic let-bound-functions-compiled-as-methods
|
||||
| Expr.App(Expr.Val (ValDeref v, _, _), _, tyargs, args, m)
|
||||
| Expr.App(Expr.Link {contents = Expr.Val (ValDeref v, _, _) }, _, tyargs, args, m)
|
||||
| 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 args = args |> List.map rw
|
||||
Some (MakeApplicationAndBetaReduce g (expr, (tyOfExpr g expr), [], args, m))
|
||||
|
||||
|
||||
// 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) ->
|
||||
|
||||
//dprintfn "Found use of %s" v.LogicalName
|
||||
Some (localRep.MakeValueLookup thisValOpt thisTyInst safeStaticInitInfo v [] m)
|
||||
|
||||
// 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) ->
|
||||
let arg = rw arg
|
||||
Some (localRep.MakeValueAssign thisValOpt thisTyInst safeStaticInitInfo v arg m)
|
||||
|
||||
// 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) ->
|
||||
Some (localRep.MakeValueGetAddress thisValOpt thisTyInst safeStaticInitInfo v m)
|
||||
Some (localRep.MakeValueGetAddress readonly thisValOpt thisTyInst safeStaticInitInfo v m)
|
||||
|
||||
| _ -> None
|
||||
Tastops.RewriteExpr { PreIntercept = Some FixupExprNode
|
||||
|
@ -12657,7 +12804,7 @@ module IncrClassChecking =
|
|||
let TransBind (reps:IncrClassReprInfo) (TBind(v, rhsExpr, spBind)) =
|
||||
if v.MustInline then
|
||||
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
|
||||
let isPriorToSuperInit =
|
||||
|
@ -12709,7 +12856,7 @@ module IncrClassChecking =
|
|||
match safeStaticInitInfo with
|
||||
| SafeInitField (rfref, _) ->
|
||||
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
|
||||
| NoSafeInitInfo ->
|
||||
None
|
||||
|
@ -12745,7 +12892,7 @@ module IncrClassChecking =
|
|||
([], actions, methodBinds), reps
|
||||
|
||||
| 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 isPriorToSuperInit = false
|
||||
if isStatic then
|
||||
|
@ -12765,7 +12912,7 @@ module IncrClassChecking =
|
|||
| None -> ()
|
||||
| Some v ->
|
||||
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 isPriorToSuperInit = false
|
||||
yield (isPriorToSuperInit, binder) ]
|
||||
|
@ -12779,7 +12926,7 @@ module IncrClassChecking =
|
|||
[ match ctorInfo.InstanceCtorSafeInitInfo with
|
||||
| SafeInitField (rfref, _) ->
|
||||
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 isPriorToSuperInit = false
|
||||
yield (isPriorToSuperInit, binder)
|
||||
|
@ -12862,7 +13009,7 @@ module IncrClassChecking =
|
|||
// 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
|
||||
// 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
|
||||
| _ ->
|
||||
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.
|
||||
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) } )
|
||||
|
||||
|
@ -14197,7 +14344,7 @@ module TyconConstraintInference =
|
|||
// If the type was excluded, say why
|
||||
if not res then
|
||||
match TryFindFSharpBoolAttribute g g.attrib_StructuralEqualityAttribute tycon.Attribs with
|
||||
| Some(true) ->
|
||||
| Some true ->
|
||||
if AugmentWithHashCompare.TyconIsCandidateForAugmentationWithEquals cenv.g tycon then
|
||||
match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsEquality tycon >> not) with
|
||||
| None ->
|
||||
|
|
|
@ -629,6 +629,9 @@ and
|
|||
/// F# syntax: expr.ident...ident <- expr
|
||||
| DotSet of SynExpr * longDotId:LongIdentWithDots * SynExpr * range:range
|
||||
|
||||
/// F# syntax: expr <- expr
|
||||
| Set of SynExpr * SynExpr * range:range
|
||||
|
||||
/// F# syntax: expr.[expr,...,expr]
|
||||
| DotIndexedGet of SynExpr * SynIndexerArg list * range * range:range
|
||||
|
||||
|
@ -763,6 +766,7 @@ and
|
|||
| SynExpr.DotIndexedSet (range=m)
|
||||
| SynExpr.DotGet (range=m)
|
||||
| SynExpr.DotSet (range=m)
|
||||
| SynExpr.Set (range=m)
|
||||
| SynExpr.DotNamedIndexedPropertySet (range=m)
|
||||
| SynExpr.LibraryOnlyUnionCaseFieldGet (range=m)
|
||||
| SynExpr.LibraryOnlyUnionCaseFieldSet (range=m)
|
||||
|
@ -824,6 +828,7 @@ and
|
|||
| SynExpr.DotIndexedGet (range=m)
|
||||
| SynExpr.DotIndexedSet (range=m)
|
||||
| SynExpr.DotSet (range=m)
|
||||
| SynExpr.Set (range=m)
|
||||
| SynExpr.DotNamedIndexedPropertySet (range=m)
|
||||
| SynExpr.LibraryOnlyUnionCaseFieldGet (range=m)
|
||||
| SynExpr.LibraryOnlyUnionCaseFieldSet (range=m)
|
||||
|
@ -887,6 +892,7 @@ and
|
|||
| SynExpr.DotIndexedSet (range=m)
|
||||
| SynExpr.DotGet (range=m)
|
||||
| SynExpr.DotSet (range=m)
|
||||
| SynExpr.Set (range=m)
|
||||
| SynExpr.DotNamedIndexedPropertySet (range=m)
|
||||
| SynExpr.LibraryOnlyUnionCaseFieldGet (range=m)
|
||||
| SynExpr.LibraryOnlyUnionCaseFieldSet (range=m)
|
||||
|
@ -1857,7 +1863,8 @@ let mkSynAssign (l: SynExpr) (r: SynExpr) =
|
|||
mkSynDotParenSet m a b r
|
||||
| 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)
|
||||
| _ -> 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 =
|
||||
match l with
|
||||
|
@ -2356,6 +2363,7 @@ let rec synExprContainsError inpExpr =
|
|||
|
||||
| SynExpr.NamedIndexedPropertySet (_,e1,e2,_)
|
||||
| SynExpr.DotSet (e1,_,e2,_)
|
||||
| SynExpr.Set (e1,e2,_)
|
||||
| SynExpr.LibraryOnlyUnionCaseFieldSet (e1,_,_,e2,_)
|
||||
| SynExpr.JoinIn (e1,_,e2,_)
|
||||
| SynExpr.App (_,_,e1,e2,_) ->
|
||||
|
|
|
@ -147,9 +147,9 @@ let TransformExpr g (nvs: ValMap<_>) exprF expr =
|
|||
Some (mkRefCellSet g m v.Type nve arg)
|
||||
|
||||
// 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]
|
||||
Some (mkRecdFieldGetAddrViaExprAddr (nve, mkRefCellContentsRef g, [v.Type], m))
|
||||
Some (mkRecdFieldGetAddrViaExprAddr (readonly, nve, mkRefCellContentsRef g, [v.Type], m))
|
||||
|
||||
| _ -> None
|
||||
|
||||
|
@ -183,7 +183,8 @@ let TransformImplFile g amap implFile =
|
|||
|> ValMap.OfList
|
||||
|
||||
implFile |>
|
||||
RewriteImplFile { PreIntercept = Some(TransformExpr g nvs)
|
||||
RewriteImplFile
|
||||
{ PreIntercept = Some(TransformExpr g nvs)
|
||||
PreInterceptBinding = Some(TransformBinding g nvs)
|
||||
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)
|
||||
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.Ptr ILType.Void when env.g.voidptr_tcr.CanDeref -> mkVoidPtrTy env.g
|
||||
| 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.Modified(_,_,ty) ->
|
||||
|
@ -260,6 +262,9 @@ let rec ImportProvidedType (env:ImportMap) (m:range) (* (tinst:TypeInst) *) (st:
|
|||
mkByrefTy g elemTy
|
||||
elif st.PUntaint((fun st -> st.IsPointer),m) then
|
||||
let elemTy = (ImportProvidedType env m (* tinst *) (st.PApply((fun st -> st.GetElementType()),m)))
|
||||
if isUnitTy g elemTy || isVoidTy g elemTy && g.voidptr_tcr.CanDeref then
|
||||
mkVoidPtrTy g
|
||||
else
|
||||
mkNativePtrTy g elemTy
|
||||
else
|
||||
|
||||
|
|
|
@ -573,7 +573,7 @@ type ParamNameAndType =
|
|||
/// Full information about a parameter returned for use by the type checker and language service.
|
||||
type ParamData =
|
||||
/// 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
|
||||
| _ -> 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.
|
||||
member x.IsFSharpStyleExtensionMember =
|
||||
match x with FSMeth (_,_,vref,_) -> vref.IsExtensionMember | _ -> false
|
||||
|
@ -1350,6 +1357,7 @@ type MethInfo =
|
|||
| Some _ -> ReflectedArgInfo.Quote false
|
||||
| _ -> ReflectedArgInfo.None
|
||||
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
|
||||
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
|
||||
else CallerLineNumber
|
||||
|
||||
yield (isParamArrayArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo) ] ]
|
||||
yield (isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo) ] ]
|
||||
|
||||
| FSMeth(g,_,vref,_) ->
|
||||
GetArgInfosOfMember x.IsCSharpStyleExtensionMember g vref
|
||||
|
@ -1379,7 +1387,8 @@ type MethInfo =
|
|||
match TryFindFSharpBoolAttributeAssumeFalse g g.attrib_ReflectedDefinitionAttribute argInfo.Attribs with
|
||||
| Some b -> ReflectedArgInfo.Quote b
|
||||
| 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 isCallerSideOptArg = HasFSharpAttributeOpt g g.attrib_OptionalAttribute argInfo.Attribs
|
||||
let optArgInfo =
|
||||
|
@ -1430,7 +1439,7 @@ type MethInfo =
|
|||
| Some optTy when typeEquiv g g.int32_ty optTy -> CallerFilePath
|
||||
| _ -> CallerLineNumber
|
||||
|
||||
(isParamArrayArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo))
|
||||
(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo))
|
||||
|
||||
| DefaultStructCtor _ ->
|
||||
[[]]
|
||||
|
@ -1446,7 +1455,9 @@ type MethInfo =
|
|||
| Some ([ Some (:? bool as b) ], _) -> ReflectedArgInfo.Quote b
|
||||
| Some _ -> ReflectedArgInfo.Quote false
|
||||
| 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
|
||||
|
||||
|
||||
|
@ -1546,12 +1557,12 @@ type MethInfo =
|
|||
#endif
|
||||
|
||||
let paramAttribs = x.GetParamAttribs(amap, m)
|
||||
(paramAttribs,paramNamesAndTypes) ||> List.map2 (List.map2 (fun (isParamArrayArg,isOutArg,optArgInfo,callerInfoInfo,reflArgInfo) (ParamNameAndType(nmOpt,pty)) ->
|
||||
ParamData(isParamArrayArg,isOutArg,optArgInfo,callerInfoInfo,nmOpt,reflArgInfo,pty)))
|
||||
(paramAttribs,paramNamesAndTypes) ||> List.map2 (List.map2 (fun (isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo) (ParamNameAndType(nmOpt,pty)) ->
|
||||
ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, nmOpt, reflArgInfo, pty)))
|
||||
|
||||
/// Get the ParamData objects for the parameters of a MethInfo
|
||||
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.
|
||||
|
@ -2134,7 +2145,7 @@ type PropInfo =
|
|||
/// Get the details of the indexer parameters associated with the property
|
||||
member x.GetParamDatas(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
|
||||
member x.GetParamTypes(amap,m) =
|
||||
|
|
|
@ -663,6 +663,9 @@ module ParsedInput =
|
|||
walkExpr e1
|
||||
addLongIdentWithDots idents
|
||||
walkExpr e2
|
||||
| SynExpr.Set (e1, e2, _) ->
|
||||
walkExpr e1
|
||||
walkExpr e2
|
||||
| SynExpr.DotIndexedGet (e, args, _, _) ->
|
||||
walkExpr e
|
||||
List.iter walkIndexerArg args
|
||||
|
|
|
@ -85,14 +85,14 @@ module internal DescriptionListsImpl =
|
|||
else
|
||||
// TODO: in this case ucinst is ignored - it gives the instantiation of the type parameters of
|
||||
// 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(
|
||||
name=initial.ParameterName,
|
||||
canonicalTypeTextForSorting=initial.CanonicalTypeTextForSorting,
|
||||
display=display,
|
||||
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(
|
||||
name = (match nmOpt with None -> "" | Some pn -> pn.idText),
|
||||
canonicalTypeTextForSorting = printCanonicalizedTypeName g denv pty,
|
||||
|
@ -103,7 +103,7 @@ module internal DescriptionListsImpl =
|
|||
let PrettyParamsOfParamDatas g denv typarInst (paramDatas:ParamData list) rty =
|
||||
let paramInfo,paramTypes =
|
||||
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
|
||||
match nmOpt, isOptArg, tryDestOptionTy denv.g pty with
|
||||
// Layout an optional argument
|
||||
|
@ -237,7 +237,7 @@ module internal DescriptionListsImpl =
|
|||
let firstCurriedParamDatas =
|
||||
firstCurriedArgInfo
|
||||
|> 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
|
||||
let curriedRetTy =
|
||||
|
@ -321,7 +321,7 @@ module internal DescriptionListsImpl =
|
|||
| None ->
|
||||
let argNamesAndTys = SymbolHelpers.ParamNameAndTypesOfUnaryCustomOperation g minfo
|
||||
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 _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
|
||||
|
||||
// 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
|
||||
// for display as part of the method group
|
||||
|
|
|
@ -840,17 +840,22 @@ module internal InterfaceStubGenerator =
|
|||
|
||||
| SynExpr.Ident(_ident) ->
|
||||
None
|
||||
|
||||
| SynExpr.LongIdent(_, _longIdent, _altNameRefCell, _range) ->
|
||||
None
|
||||
|
||||
| SynExpr.LongIdentSet(_longIdent, synExpr, _range) ->
|
||||
walkExpr synExpr
|
||||
|
||||
| SynExpr.DotGet(synExpr, _dotm, _longIdent, _range) ->
|
||||
walkExpr synExpr
|
||||
|
||||
| SynExpr.DotSet(synExpr1, _longIdent, synExpr2, _range) ->
|
||||
List.tryPick walkExpr [synExpr1; synExpr2]
|
||||
|
||||
| SynExpr.Set(synExpr1, synExpr2, _range) ->
|
||||
List.tryPick walkExpr [synExpr1; synExpr2]
|
||||
|
||||
| SynExpr.DotIndexedGet(synExpr, IndexerArgList synExprList, _range, _range2) ->
|
||||
Option.orElse (walkExpr synExpr) (List.tryPick walkExpr synExprList)
|
||||
|
||||
|
|
|
@ -394,7 +394,8 @@ module public AstTraversal =
|
|||
| SynExpr.LongIdent(_, _longIdent, _altNameRefCell, _range) -> None
|
||||
| SynExpr.LongIdentSet(_longIdent, synExpr, _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 synExpr2 synExpr2.Range traverseSynExpr]
|
||||
|> pick expr
|
||||
|
|
|
@ -223,10 +223,14 @@ module Structure =
|
|||
| SynExpr.InferredUpcast (e,_)
|
||||
| SynExpr.DotGet (e,_,_,_)
|
||||
| SynExpr.Do (e,_)
|
||||
| SynExpr.DotSet (e,_,_,_)
|
||||
| SynExpr.Typed (e,_,_)
|
||||
| SynExpr.DotIndexedGet (e,_,_,_)
|
||||
| SynExpr.DotIndexedSet (e,_,_,_,_,_) -> parseExpr e
|
||||
| SynExpr.DotIndexedGet (e,_,_,_) ->
|
||||
parseExpr e
|
||||
| SynExpr.Set (e1,e2,_)
|
||||
| SynExpr.DotSet (e1,_,e2,_)
|
||||
| SynExpr.DotIndexedSet (e1,_,e2,_,_,_) ->
|
||||
parseExpr e1
|
||||
parseExpr e2
|
||||
| SynExpr.New (_,_,expr,r) ->
|
||||
rcheck Scope.New Collapse.Below r expr.Range
|
||||
parseExpr expr
|
||||
|
|
|
@ -212,6 +212,7 @@ type FSharpParseFileResults(errors: FSharpErrorInfo[], input: Ast.ParsedInput op
|
|||
|
||||
| SynExpr.NamedIndexedPropertySet (_,e1,e2,_)
|
||||
| SynExpr.DotSet (e1,_,e2,_)
|
||||
| SynExpr.Set (e1,e2,_)
|
||||
| SynExpr.LibraryOnlyUnionCaseFieldSet (e1,_,_,e2,_)
|
||||
| SynExpr.App (_,_,e1,e2,_) ->
|
||||
yield! walkExpr false e1
|
||||
|
@ -480,6 +481,13 @@ module UntypedParseImpl =
|
|||
else
|
||||
// see comment below for SynExpr.DotSet
|
||||
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) ->
|
||||
if AstTraversal.rangeContainsPosLeftEdgeInclusive synExpr.Range pos then
|
||||
traverseSynExpr synExpr
|
||||
|
@ -642,6 +650,10 @@ module UntypedParseImpl =
|
|||
dive lidwd lidwd.Range (traverseLidOrElse(Some exprLeft))
|
||||
dive exprRhs exprRhs.Range traverseSynExpr
|
||||
] |> 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) ->
|
||||
[ dive lidwd lidwd.Range (traverseLidOrElse None)
|
||||
dive exprIndexer exprIndexer.Range traverseSynExpr
|
||||
|
@ -843,6 +855,7 @@ module UntypedParseImpl =
|
|||
| SynExpr.LongIdentSet(_, e, _) -> walkExprWithKind parentKind e
|
||||
| SynExpr.DotGet(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.DotIndexedSet(e, args, _, _, _, _) -> walkExprWithKind parentKind e |> Option.orElse (List.tryPick walkIndexerArg args)
|
||||
| SynExpr.NamedIndexedPropertySet(_, e1, e2, _) -> List.tryPick (walkExprWithKind parentKind) [e1; e2]
|
||||
|
|
|
@ -353,7 +353,7 @@ type TypeCheckInfo
|
|||
methods
|
||||
|> List.collect (fun meth ->
|
||||
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
|
||||
| Some n -> Some (Item.ArgName(n, ty, Some (ArgumentContainer.Method meth)))
|
||||
| None -> None
|
||||
|
|
|
@ -302,10 +302,10 @@ module FSharpExprConvert =
|
|||
match expr with
|
||||
| Expr.Op(op, tyargs, args, m) ->
|
||||
match op, args, tyargs with
|
||||
| TOp.LValueOp(LGetAddr, vref), _, _ -> exprForValRef m vref
|
||||
| TOp.ValFieldGetAddr(rfref), [], _ -> mkStaticRecdFieldGet(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.LValueOp(LAddrOf _, vref), _, _ -> exprForValRef m vref
|
||||
| TOp.ValFieldGetAddr(rfref, _), [], _ -> mkStaticRecdFieldGet(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.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_ldelema(_ro, _isNativePtr, shape, _tyarg) ] ), _), (arr::idxs), [elemty] ->
|
||||
|
@ -581,10 +581,10 @@ module FSharpExprConvert =
|
|||
let projR = FSharpField(cenv, ucref, n)
|
||||
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)
|
||||
|
||||
| TOp.ValFieldGetAddr(_rfref), _tyargs, _ ->
|
||||
| TOp.ValFieldGetAddr _, _tyargs, _ ->
|
||||
E.AddressOf(ConvLValueExpr cenv env expr)
|
||||
|
||||
| TOp.ValFieldGet(rfref), tyargs, [] ->
|
||||
|
@ -755,7 +755,7 @@ module FSharpExprConvert =
|
|||
// rebuild reraise<T>() and Convert
|
||||
mkReraiseLibCall cenv.g toTy m |> ConvExprPrim cenv env
|
||||
|
||||
| TOp.LValueOp(LGetAddr, vref), [], [] ->
|
||||
| TOp.LValueOp(LAddrOf _, vref), [], [] ->
|
||||
E.AddressOf(ConvExpr cenv env (exprForValRef m vref))
|
||||
|
||||
| TOp.LValueOp(LByrefSet, vref), [], [e] ->
|
||||
|
@ -815,8 +815,8 @@ module FSharpExprConvert =
|
|||
let argsR = ConvExprs cenv env args
|
||||
E.TraitCall(tysR, nm, memFlags, argtysR, tyargsR, argsR)
|
||||
|
||||
| TOp.RefAddrGet, [ty], [e] ->
|
||||
let replExpr = mkRecdFieldGetAddrViaExprAddr(e, mkRefCellContentsRef cenv.g, [ty], m)
|
||||
| TOp.RefAddrGet readonly, [ty], [e] ->
|
||||
let replExpr = mkRecdFieldGetAddrViaExprAddr(readonly, e, mkRefCellContentsRef cenv.g, [ty], m)
|
||||
ConvExprPrim cenv env replExpr
|
||||
|
||||
| _ -> 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) :> _
|
||||
|
||||
| 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
|
||||
| Item.ImplicitOp _
|
||||
|
@ -1747,11 +1747,11 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
|
|||
match d with
|
||||
| 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
|
||||
// either .NET or F# parameters
|
||||
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
|
||||
|
||||
|
@ -1759,11 +1759,11 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
|
|||
| M m | C m ->
|
||||
[ for argtys in m.GetParamDatas(cenv.amap, range0, m.FormalMethodInst) do
|
||||
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
|
||||
// either .NET or F# parameters
|
||||
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
|
||||
|
||||
|
@ -1780,7 +1780,7 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
|
|||
else [typ]
|
||||
yield
|
||||
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
|
||||
else makeReadOnlyCollection []
|
||||
|
@ -1792,9 +1792,10 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
|
|||
yield
|
||||
[ for argty, argInfo in argtys do
|
||||
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 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
|
||||
|
||||
|
@ -1810,29 +1811,29 @@ and FSharpMemberOrFunctionOrValue(cenv, d:FSharpMemberOrValData, item) =
|
|||
// For non-standard events, just use the delegate type as the ReturnParameter type
|
||||
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 ->
|
||||
// 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 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 ->
|
||||
// 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 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 ->
|
||||
match v.ValReprInfo with
|
||||
| None ->
|
||||
let _, tau = v.TypeScheme
|
||||
let _argtysl, rty = stripFunTy cenv.g tau
|
||||
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)) ->
|
||||
let tau = v.TauType
|
||||
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 =
|
||||
|
@ -2228,7 +2229,7 @@ and FSharpStaticParameter(cenv, sp: Tainted< ExtensionTyping.ProvidedParameterIn
|
|||
override x.ToString() =
|
||||
"static parameter " + x.Name
|
||||
#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,
|
||||
(fun () ->
|
||||
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 __.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)
|
||||
|
||||
|
@ -2255,6 +2256,8 @@ and FSharpParameter(cenv, typ:TType, topArgInfo:ArgReprInfo, mOpt, isParamArrayA
|
|||
|
||||
member __.IsParamArrayArg = isParamArrayArg
|
||||
|
||||
member __.IsInArg = isInArg
|
||||
|
||||
member __.IsOutArg = isOutArg
|
||||
|
||||
member __.IsOptionalArg = isOptionalArg
|
||||
|
|
|
@ -850,6 +850,9 @@ and [<Class>] public FSharpParameter =
|
|||
/// Indicate this is an out argument
|
||||
member IsOutArg: bool
|
||||
|
||||
/// Indicate this is an in argument
|
||||
member IsInArg: bool
|
||||
|
||||
/// Indicate this is an optional argument
|
||||
member IsOptionalArg: bool
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">Neočekávané použití proměnné typu ByRef.</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="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">
|
||||
<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>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<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>
|
||||
<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="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 />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">Unerwartete Verwendung einer Variablen vom Typ "byref".</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="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">
|
||||
<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>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<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>
|
||||
<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="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 />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="new">Unexpected use of a byref-typed variable</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="tastInvalidMutationOfConstant">
|
||||
<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>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<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>
|
||||
<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}' 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 />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="new">The file '{0}' changed on disk unexpectedly, please reload.</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">Uso inesperado de una variable de tipo byref.</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="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">
|
||||
<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>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<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>
|
||||
<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="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 />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">Utilisation inattendue d'une variable typée byref</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="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">
|
||||
<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>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<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>
|
||||
<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="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 />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="translated">Changement inattendu du fichier '{0}' sur le disque. Rechargez le fichier.</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">Utilizzo non previsto di una variabile di tipo byref</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="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">
|
||||
<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>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<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>
|
||||
<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="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 />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="translated">Il file '{0}' è stato modificato su disco in modo imprevisto. Ricaricare.</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">byref 型変数の予期しない使用方法です:</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="translated">値の型の内容を変更するか、値の型のアドレスを使用するために、値は変更可能にする必要があります (たとえば、'let mutable x = ...')</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">定数式の変更は無効です。変更可能なローカルに式をコピーしてください (たとえば、'let mutable x = ...')。</target>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">変数 '{0}' のアドレスはこのポイントでは使用できません。メソッドまたは関数がこのローカル値のアドレスを返さない可能性があります。</target>
|
||||
<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="needs-review-translation">変数 '{0}' のアドレスはこのポイントでは使用できません。メソッドまたは関数がこのローカル値のアドレスを返さない可能性があります。</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="translated">ファイル '{0}' がディスク上で予期せず変更されました。再度読み込んでください。</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">예기치 않은 byref 형식 변수의 사용입니다.</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="translated">내용을 변경하거나 값 형식의 주소를 사용하려면 값을 변경할 수 있어야 합니다(예: 'let mutable x = ...').</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">상수 식을 잘못 변경했습니다. 식을 변경할 수 있는 로컬로 복사하십시오(예: 'let mutable x = ...').</target>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">지금은 '{0}' 변수의 주소를 사용할 수 없습니다. 메서드 또는 함수가 이 로컬 값의 주소를 반환할 수 없습니다.</target>
|
||||
<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="needs-review-translation">지금은 '{0}' 변수의 주소를 사용할 수 없습니다. 메서드 또는 함수가 이 로컬 값의 주소를 반환할 수 없습니다.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="translated">'{0}' 파일이 디스크에서 예기치 않게 변경되었습니다. 다시 로드하세요.</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">Nieoczekiwane użycie zmiennej typu byref</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="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">
|
||||
<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>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<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>
|
||||
<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="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 />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="translated">Plik „{0}” nieoczekiwanie uległ zmianie na dysku. Załaduj go ponownie.</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">Uso inesperado de uma variável do tipo byref</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="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">
|
||||
<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>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<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>
|
||||
<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="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 />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="translated">O arquivo '{0}' foi alterado no disco inesperadamente. Recarregue-o.</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">Недопустимое использование переменной типа byref</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="translated">Чтобы изменить содержимое или получить адрес типа значения, значение должно быть изменяемым, например, "let mutable x = ..."</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">Недопустимое изменение константного выражения. Рекомендуется скопировать выражение в изменяемую локальную переменную, например, "let mutable x = ...".</target>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">Адрес переменной "{0}" сейчас невозможно использовать. Метод или функция могут не возвратить адрес этого локального значения.</target>
|
||||
<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="needs-review-translation">Адрес переменной "{0}" сейчас невозможно использовать. Метод или функция могут не возвратить адрес этого локального значения.</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="translated">Файл "{0}" был неожиданно изменен на диске, повторите загрузку.</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">Beklenmeyen byref olarak belirtilmiş değişken kullanımı</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="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">
|
||||
<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>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<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>
|
||||
<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="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 />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">对 byref 类型化变量的意外使用</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="translated">值必须是可变的,以便更改内容或采用值类型的地址,例如“let mutable x = ...”</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">常数表达式的变化无效。请考虑将该表达式复制一个可变的本地变量,例如“let mutable x = ...”。</target>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">当前无法使用变量 {0} 的地址。方法或函数可能没有返回该本地值的地址。</target>
|
||||
<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="needs-review-translation">当前无法使用变量 {0} 的地址。方法或函数可能没有返回该本地值的地址。</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="translated">文件“{0}”在磁盘上意外更改,请重新加载。</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -412,11 +412,6 @@
|
|||
<target state="translated">未預期的 ByRef 類型變數用法</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="translated">值必須是可變動的,才能變動內容或接受實值類型的位址,例如 'let mutable x = ...'</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">常數運算式無效的變動。請考慮將運算式複製到可變動的區域變數,例如 'let mutable x = ...'。</target>
|
||||
|
@ -6523,8 +6518,8 @@
|
|||
<note />
|
||||
</trans-unit>
|
||||
<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>
|
||||
<target state="translated">目前無法使用變數 '{0}' 的位址。方法或函式無法傳回此本機值的位址。</target>
|
||||
<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="needs-review-translation">目前無法使用變數 '{0}' 的位址。方法或函式無法傳回此本機值的位址。</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="tcNamedActivePattern">
|
||||
|
@ -6992,6 +6987,61 @@
|
|||
<target state="translated">檔案 '{0}' 在磁碟上意外變更,請重新載入。</target>
|
||||
<note />
|
||||
</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>
|
||||
</file>
|
||||
</xliff>
|
|
@ -7,6 +7,7 @@ namespace global
|
|||
|
||||
open System
|
||||
open System.IO
|
||||
open System.Text
|
||||
open System.Diagnostics
|
||||
|
||||
[<AutoOpen>]
|
||||
|
@ -117,15 +118,23 @@ module Scripting =
|
|||
let p = new Process()
|
||||
p.EnableRaisingEvents <- true
|
||||
p.StartInfo <- processInfo
|
||||
let out = StringBuilder()
|
||||
let err = StringBuilder()
|
||||
|
||||
cmdArgs.RedirectOutput|> Option.iter (fun f ->
|
||||
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 ->
|
||||
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
|
||||
|
@ -151,7 +160,7 @@ module Scripting =
|
|||
match p.ExitCode with
|
||||
| 0 -> Success
|
||||
| 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)
|
||||
|
||||
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.Type GetType()
|
||||
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 Match(System.Object)
|
||||
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: Void SetPointerInlined[T](IntPtr, Int32, 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: 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)
|
||||
|
|
|
@ -800,6 +800,20 @@ Microsoft.FSharp.Core.AutoSerializableAttribute: System.Object get_TypeId()
|
|||
Microsoft.FSharp.Core.AutoSerializableAttribute: System.String ToString()
|
||||
Microsoft.FSharp.Core.AutoSerializableAttribute: System.Type GetType()
|
||||
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 IsDefaultAttribute()
|
||||
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: Void SetPointerInlined[T](IntPtr, Int32, 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: 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)
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -50,11 +50,26 @@ namespace CustomExtensions
|
|||
{
|
||||
|
||||
/// 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 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
|
||||
{
|
||||
internal class SomeClass
|
||||
|
|
|
@ -16,6 +16,11 @@ let test (s : string) b =
|
|||
if b then stderr.WriteLine " OK"
|
||||
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
|
||||
module TestExtensions =
|
||||
open CustomExtensions
|
||||
|
@ -154,8 +159,19 @@ let TestAccessibility() =
|
|||
|
||||
module TestExtensions =
|
||||
open CustomExtensions
|
||||
test "dfeweeon" (r1.ExtendFSharpType() = 5)
|
||||
test "dfeweeon" (Lib2().ExtendCSharpType() = 4)
|
||||
check "dfeweeon" (r1.ExtendFSharpType()) 5
|
||||
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
|
||||
|
||||
|
|
|
@ -31,4 +31,6 @@ try
|
|||
|
||||
asmBuilder.Save(filename)
|
||||
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
|
||||
//#r @"../../release/net40/bin/FSharp.Compiler.dll"
|
||||
// vvvvvvvvvvvvv To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test vvvvvvvvvvvvvvvv
|
||||
#if INTERACTIVE
|
||||
#r @"../../packages/NUnit.3.5.0/lib/net45/nunit.framework.dll"
|
||||
#load "../../src/scripts/scriptlib.fsx"
|
||||
#load "test-framework.fs"
|
||||
|
@ -25,6 +25,7 @@ let FSI_BASIC = FSI_CORECLR
|
|||
let FSC_BASIC = FSC_OPT_PLUS_DEBUG
|
||||
let FSI_BASIC = FSI_FILE
|
||||
#endif
|
||||
// ^^^^^^^^^^^^ To run these tests in F# Interactive , 'build net40', then send this chunk, then evaluate body of a test ^^^^^^^^^^^^
|
||||
|
||||
module CoreTests =
|
||||
// These tests are enabled for .NET Framework and .NET Core
|
||||
|
@ -176,6 +177,7 @@ module CoreTests =
|
|||
|
||||
let cfg = testConfig "core/byrefs"
|
||||
|
||||
begin
|
||||
use testOkFile = fileguard cfg "test.ok"
|
||||
|
||||
fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
|
||||
|
@ -183,10 +185,53 @@ module CoreTests =
|
|||
exec cfg ("." ++ "test.exe") ""
|
||||
|
||||
testOkFile.CheckExists()
|
||||
end
|
||||
|
||||
begin
|
||||
use testOkFile = fileguard cfg "test.ok"
|
||||
fsi cfg "" ["test.fsx"]
|
||||
|
||||
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>]
|
||||
let asyncStackTraces () =
|
||||
|
@ -381,19 +426,22 @@ module CoreTests =
|
|||
|
||||
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"]
|
||||
|
||||
peverify cfg "test.exe"
|
||||
|
||||
exec cfg ("." ++ "test.exe") ""
|
||||
|
||||
// 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"]
|
||||
|
||||
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
|
||||
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>]
|
||||
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>]
|
||||
let ``type check neg103`` () = singleNegTest (testConfig "typecheck/sigs") "neg103"
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
namespace global
|
||||
|
||||
[<assembly: System.Reflection.AssemblyCopyrightAttribute("hey!")>]
|
||||
do ()
|
||||
|
||||
type TheGeneratedType1() =
|
||||
member x.Prop1 = 1
|
||||
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(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"'.
|
||||
|
||||
|
|
|
@ -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,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,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>'
|
||||
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
|
||||
'float'
|
||||
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(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
|
||||
// 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="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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#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/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"
|
||||
#load "FsUnit.fs"
|
||||
#load "Common.fs"
|
||||
|
@ -673,7 +673,6 @@ let ``Test Unoptimized Declarations Project1`` () =
|
|||
"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 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)";
|
||||
"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)";
|
||||
|
@ -693,16 +692,13 @@ let ``Test Unoptimized Declarations Project1`` () =
|
|||
"let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)";
|
||||
"do Console.WriteLine (\"777\")";
|
||||
"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";
|
||||
"member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)";
|
||||
"member Method(x) (a,b) = 1 @ (106,37--106,38)";
|
||||
"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 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 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 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)";
|
||||
|
@ -815,11 +811,6 @@ let ``Test Optimized Declarations Project1`` () =
|
|||
"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 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)";
|
||||
"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)";
|
||||
|
@ -839,25 +830,13 @@ let ``Test Optimized Declarations Project1`` () =
|
|||
"let v = M.c ().get_InstanceProperty(()) @ (98,8--98,26)";
|
||||
"do Console.WriteLine (\"777\")";
|
||||
"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";
|
||||
"member .ctor(c,d) = (new Object(); ()) @ (105,5--105,20)";
|
||||
"member Method(x) (a,b) = 1 @ (106,37--106,38)";
|
||||
"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)";
|
||||
//#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 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 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)";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#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/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"
|
||||
#load "FsUnit.fs"
|
||||
#load "Common.fs"
|
||||
|
|
Загрузка…
Ссылка в новой задаче