From f0512c1150bb0cd60cbe254f069b1815dc2adb2b Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 01:15:30 +0100 Subject: [PATCH 01/61] initial support for span, readonly refs, byref-like structs --- packages.config | 1 + src/absil/il.fs | 44 +++--- src/absil/illib.fs | 6 + src/fsharp/AttributeChecking.fs | 20 +-- src/fsharp/CompileOps.fs | 2 +- src/fsharp/CompileOptions.fs | 24 ++-- src/fsharp/DetupleArgs.fs | 6 +- src/fsharp/FSharp.Core/nativeptr.fs | 8 ++ src/fsharp/FSharp.Core/nativeptr.fsi | 16 +++ src/fsharp/FSharp.Core/prim-types-prelude.fs | 2 +- src/fsharp/FSharp.Core/prim-types-prelude.fsi | 9 ++ src/fsharp/IlxGen.fs | 6 +- src/fsharp/InnerLambdasToTopLevelFuncs.fs | 6 +- src/fsharp/NameResolution.fs | 2 +- src/fsharp/Optimizer.fs | 33 ++--- src/fsharp/PostInferenceChecks.fs | 51 +++---- src/fsharp/TastOps.fs | 127 ++++++++++-------- src/fsharp/TastOps.fsi | 13 +- src/fsharp/TcGlobals.fs | 7 + src/fsharp/TypeChecker.fs | 22 +-- src/fsharp/import.fs | 6 +- src/fsharp/symbols/Symbols.fs | 4 +- src/fsharp/tast.fs | 110 +++++++++++---- 23 files changed, 330 insertions(+), 195 deletions(-) diff --git a/packages.config b/packages.config index a137d8a900..e61ca96e38 100644 --- a/packages.config +++ b/packages.config @@ -36,6 +36,7 @@ + diff --git a/src/absil/il.fs b/src/absil/il.fs index cfe88edba0..af43db3b60 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -633,8 +633,6 @@ and static member Create(tref,inst) = { tspecTypeRef =tref; tspecInst=inst } - override x.ToString() = x.TypeRef.ToString() + if isNil x.GenericArgs then "" else "<...>" - member x.BasicQualifiedName = let tc = x.TypeRef.BasicQualifiedName if isNil x.GenericArgs then @@ -647,6 +645,8 @@ and member x.FullName=x.TypeRef.FullName + override x.ToString() = x.TypeRef.ToString() + if isNil x.GenericArgs then "" else "<...>" + and [] ILType = | Void @@ -685,34 +685,36 @@ and [] x.AddQualifiedNameExtension(x.BasicQualifiedName) member x.TypeSpec = - match x with - | ILType.Boxed tr | ILType.Value tr -> tr - | _ -> invalidOp "not a nominal type" + match x with + | ILType.Boxed tr | ILType.Value tr -> tr + | _ -> invalidOp "not a nominal type" member x.Boxity = - match x with - | ILType.Boxed _ -> AsObject - | ILType.Value _ -> AsValue - | _ -> invalidOp "not a nominal type" + match x with + | ILType.Boxed _ -> AsObject + | ILType.Value _ -> AsValue + | _ -> invalidOp "not a nominal type" member x.TypeRef = - match x with - | ILType.Boxed tspec | ILType.Value tspec -> tspec.TypeRef - | _ -> invalidOp "not a nominal type" + match x with + | ILType.Boxed tspec | ILType.Value tspec -> tspec.TypeRef + | _ -> invalidOp "not a nominal type" member x.IsNominal = - match x with - | ILType.Boxed _ | ILType.Value _ -> true - | _ -> false + match x with + | ILType.Boxed _ | ILType.Value _ -> true + | _ -> false member x.GenericArgs = - match x with - | ILType.Boxed tspec | ILType.Value tspec -> tspec.GenericArgs - | _ -> [] + match x with + | ILType.Boxed tspec | ILType.Value tspec -> tspec.GenericArgs + | _ -> [] member x.IsTyvar = - match x with - | ILType.TypeVar _ -> true | _ -> false + match x with + | ILType.TypeVar _ -> true | _ -> false + + override x.ToString() = x.QualifiedName and [] ILCallingSignature = @@ -855,6 +857,8 @@ type ILAttribute = Data: byte[] Elements: ILAttribElem list} + override x.ToString() = x.Method.ToString() + "(...)" + [] type ILAttributes(array : ILAttribute[]) = member x.AsArray = array diff --git a/src/absil/illib.fs b/src/absil/illib.fs index a1adb372e9..e938097e31 100644 --- a/src/absil/illib.fs +++ b/src/absil/illib.fs @@ -43,6 +43,12 @@ let inline isNonNull x = not (isNull x) let inline nonNull msg x = if isNull x then failwith ("null: " + msg) else x let inline (===) x y = LanguagePrimitives.PhysicalEquality x y +// Singletons +let someTrue = Some true +let someFalse = Some false +let someBool b = if b then someTrue else someFalse +let someUnit = Some () + //--------------------------------------------------------------------- // Library: ReportTime //--------------------------------------------------------------------- diff --git a/src/fsharp/AttributeChecking.fs b/src/fsharp/AttributeChecking.fs index 50f0bb1518..700836f381 100644 --- a/src/fsharp/AttributeChecking.fs +++ b/src/fsharp/AttributeChecking.fs @@ -247,21 +247,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', @@ -373,7 +373,7 @@ let CheckProvidedAttributesForUnseen (provAttribs: Tainted 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" @@ -388,7 +388,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 @@ -398,7 +398,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 () -> @@ -480,7 +480,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 diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index c9010003ba..8ab5c36d08 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -3032,7 +3032,7 @@ type TcConfig private (data : TcConfigBuilder, validate:bool) = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter let lower = String.lowercase filename let lightOnByDefault = List.exists (Filename.checkSuffix lower) FSharpLightSyntaxFileSuffixes - if lightOnByDefault then (tcConfig.light <> Some(false)) else (tcConfig.light = Some(true) ) + if lightOnByDefault then (tcConfig.light <> Some(false)) else (tcConfig.light = someTrue ) member tcConfig.GetAvailableLoadedSources() = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index 5969e38fc8..f24659fddb 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -396,18 +396,18 @@ let setFlag r n = | _ -> raise (Failure "expected 0/1") let SetOptimizeOff(tcConfigB : TcConfigBuilder) = - tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some false } - tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false } - tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some false } + tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = someFalse } + tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = someFalse } + tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = someFalse } tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 0 } tcConfigB.doDetuple <- false; tcConfigB.doTLR <- false; tcConfigB.doFinalSimplify <- false; let SetOptimizeOn(tcConfigB : TcConfigBuilder) = - tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some true } - tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true } - tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some true } + tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = someTrue } + tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = someTrue } + tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = someTrue } tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 6 } tcConfigB.doDetuple <- true; tcConfigB.doTLR <- true; @@ -943,8 +943,8 @@ let deprecatedFlagsFsc tcConfigB = deprecatedFlagsBoth tcConfigB @ [ cliRootFlag tcConfigB - CompilerOption("jit-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some true }), Some(DeprecatedCommandLineOptionNoDescription("--jit-optimize", rangeCmdArgs)), None) - CompilerOption("no-jit-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some false }), Some(DeprecatedCommandLineOptionNoDescription("--no-jit-optimize", rangeCmdArgs)), None) + CompilerOption("jit-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = someTrue }), Some(DeprecatedCommandLineOptionNoDescription("--jit-optimize", rangeCmdArgs)), None) + CompilerOption("no-jit-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = someFalse }), Some(DeprecatedCommandLineOptionNoDescription("--no-jit-optimize", rangeCmdArgs)), None) CompilerOption("jit-tracking", tagNone, OptionUnit (fun _ -> (tcConfigB.jitTracking <- true) ), Some(DeprecatedCommandLineOptionNoDescription("--jit-tracking", rangeCmdArgs)), None) CompilerOption("no-jit-tracking", tagNone, OptionUnit (fun _ -> (tcConfigB.jitTracking <- false) ), Some(DeprecatedCommandLineOptionNoDescription("--no-jit-tracking", rangeCmdArgs)), None) CompilerOption("progress", tagNone, OptionUnit (fun () -> progress := true), Some(DeprecatedCommandLineOptionNoDescription("--progress", rangeCmdArgs)), None) @@ -954,10 +954,10 @@ let deprecatedFlagsFsc tcConfigB = (compilingFsLibNoBigIntFlag tcConfigB) CompilerOption("version", tagString, OptionString (fun s -> tcConfigB.version <- VersionString s), Some(DeprecatedCommandLineOptionNoDescription("--version", rangeCmdArgs)), None) // "--clr-mscorlib", OptionString (fun s -> warning(Some(DeprecatedCommandLineOptionNoDescription("--clr-mscorlib", rangeCmdArgs))) tcConfigB.Build.mscorlib_assembly_name <- s), "\n\tThe name of mscorlib on the target CLR" - CompilerOption("local-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true }), Some(DeprecatedCommandLineOptionNoDescription("--local-optimize", rangeCmdArgs)), None) - CompilerOption("no-local-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false }), Some(DeprecatedCommandLineOptionNoDescription("--no-local-optimize", rangeCmdArgs)), None) - CompilerOption("cross-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some true }), Some(DeprecatedCommandLineOptionNoDescription("--cross-optimize", rangeCmdArgs)), None) - CompilerOption("no-cross-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some false }), Some(DeprecatedCommandLineOptionNoDescription("--no-cross-optimize", rangeCmdArgs)), None) + CompilerOption("local-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = someTrue }), Some(DeprecatedCommandLineOptionNoDescription("--local-optimize", rangeCmdArgs)), None) + CompilerOption("no-local-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = someFalse }), Some(DeprecatedCommandLineOptionNoDescription("--no-local-optimize", rangeCmdArgs)), None) + CompilerOption("cross-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = someTrue }), Some(DeprecatedCommandLineOptionNoDescription("--cross-optimize", rangeCmdArgs)), None) + CompilerOption("no-cross-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = someFalse }), Some(DeprecatedCommandLineOptionNoDescription("--no-cross-optimize", rangeCmdArgs)), None) CompilerOption("no-string-interning", tagNone, OptionUnit (fun () -> tcConfigB.internConstantStrings <- false), Some(DeprecatedCommandLineOptionNoDescription("--no-string-interning", rangeCmdArgs)), None) CompilerOption("statistics", tagNone, OptionUnit (fun () -> tcConfigB.stats <- true), Some(DeprecatedCommandLineOptionNoDescription("--statistics", rangeCmdArgs)), None) CompilerOption("generate-filter-blocks", tagNone, OptionUnit (fun () -> tcConfigB.generateFilterBlocks <- true), Some(DeprecatedCommandLineOptionNoDescription("--generate-filter-blocks", rangeCmdArgs)), None) diff --git a/src/fsharp/DetupleArgs.fs b/src/fsharp/DetupleArgs.fs index 8b2a85bddf..e9b3ceeff3 100644 --- a/src/fsharp/DetupleArgs.fs +++ b/src/fsharp/DetupleArgs.fs @@ -583,10 +583,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,7 +595,7 @@ let eligibleVal g (v:Val) = let determineTransforms g (z : GlobalUsageAnalysis.Results) = let selectTransform f sites = - if not (eligibleVal g f) then None else + if not (eligibleVal g Range.rangeStartup 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 diff --git a/src/fsharp/FSharp.Core/nativeptr.fs b/src/fsharp/FSharp.Core/nativeptr.fs index 29e2ecb67a..db9f81bf8a 100644 --- a/src/fsharp/FSharp.Core/nativeptr.fs +++ b/src/fsharp/FSharp.Core/nativeptr.fs @@ -25,6 +25,14 @@ module NativePtr = [] let inline toNativeInt (address: nativeptr<'T>) = (# "" address : nativeint #) + [] + [] + let inline toVoidPtr (address: nativeptr<'T>) = (# "" address : voidptr #) + + [] + [] + let inline ofVoidPtr (address: voidptr) = (# "" address : nativeptr<'T> #) + [] [] let inline add (address : nativeptr<'T>) (index:int) : nativeptr<'T> = toNativeInt address + nativeint index * (# "sizeof !0" type('T) : nativeint #) |> ofNativeInt diff --git a/src/fsharp/FSharp.Core/nativeptr.fsi b/src/fsharp/FSharp.Core/nativeptr.fsi index 47a0509e71..98f8d2fd9c 100644 --- a/src/fsharp/FSharp.Core/nativeptr.fsi +++ b/src/fsharp/FSharp.Core/nativeptr.fsi @@ -19,6 +19,22 @@ namespace Microsoft.FSharp.NativeInterop /// A typed pointer. val inline ofNativeInt : address:nativeint -> nativeptr<'T> + [] + [] + [] + /// Returns a typed native pointer for a given machine address. + /// The pointer address. + /// A typed pointer. + val inline toVoidPtr : address:nativeptr<'T> -> voidptr + + [] + [] + [] + /// Returns a typed native pointer for a untyped native pointer. + /// The untyped pointer. + /// A typed pointer. + val inline ofVoidPtr : voidptr -> nativeptr<'T> + [] [] [] diff --git a/src/fsharp/FSharp.Core/prim-types-prelude.fs b/src/fsharp/FSharp.Core/prim-types-prelude.fs index f06eb19b96..705efcc24b 100644 --- a/src/fsharp/FSharp.Core/prim-types-prelude.fs +++ b/src/fsharp/FSharp.Core/prim-types-prelude.fs @@ -67,5 +67,5 @@ namespace Microsoft.FSharp.Core type byref<'T> = (# "!0&" #) type nativeptr<'T when 'T : unmanaged> = (# "native int" #) + type voidptr = (# "void*" #) type ilsigptr<'T> = (# "!0*" #) - diff --git a/src/fsharp/FSharp.Core/prim-types-prelude.fsi b/src/fsharp/FSharp.Core/prim-types-prelude.fsi index 9267ab531a..74eb0cd5e9 100644 --- a/src/fsharp/FSharp.Core/prim-types-prelude.fsi +++ b/src/fsharp/FSharp.Core/prim-types-prelude.fsi @@ -229,6 +229,15 @@ namespace Microsoft.FSharp.Core /// by the functions in the NativeInterop.NativePtr module. type nativeptr<'T when 'T : unmanaged> = (# "native int" #) + /// Represents an untyped unmanaged pointer in F# code. + /// + /// 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 + /// nativeint type may be required. Values of this type can be generated + /// by the functions in the NativeInterop.NativePtr module. + type voidptr = (# "void*" #) + /// This type is for internal use by the F# code generator. type ilsigptr<'T> = (# "!0*" #) diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index c424eb3124..91bf963379 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -397,6 +397,8 @@ and GenNamedTyAppAux (amap:ImportMap) m tyenv ptrsOK tcref 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 + elif ptrsOK = PtrTypesOK && tyconRefEq g tcref g.voidptr_tcr then + GenNamedTyAppAux amap m tyenv ptrsOK g.voidptr_tcr tinst else #if !NO_EXTENSIONTYPING match tcref.TypeReprInfo with @@ -6287,7 +6289,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = isEmptyStruct && cenv.opts.workAroundReflectionEmitBugs && not tycon.TyparsNoRange.IsEmpty // Compute a bunch of useful things for each field - let isCLIMutable = (TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_CLIMutableAttribute tycon.Attribs = Some true) + let isCLIMutable = (TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_CLIMutableAttribute tycon.Attribs = someTrue) let fieldSummaries = [ for fspec in tycon.AllFieldsAsList do @@ -6493,7 +6495,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = // FSharp 1.0 bug 1988: Explicitly setting the ComVisible(true) attribute on an F# type causes an F# record to be emitted in a way that enables mutation for COM interop scenarios // FSharp 3.0 feature: adding CLIMutable to a record type causes emit of default constructor, and all fields get property setters // Records that are value types do not create a default constructor with CLIMutable or ComVisible - if not isStructRecord && (isCLIMutable || (TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_ComVisibleAttribute tycon.Attribs = Some true)) then + if not isStructRecord && (isCLIMutable || (TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_ComVisibleAttribute tycon.Attribs = someTrue)) then yield mkILSimpleStorageCtor(None, Some cenv.g.ilg.typ_Object.TypeSpec, ilThisTy, [], [], reprAccess) if not (tycon.HasMember cenv.g "ToString" []) then diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fs b/src/fsharp/InnerLambdasToTopLevelFuncs.fs index f955982350..3cb33c39a0 100644 --- a/src/fsharp/InnerLambdasToTopLevelFuncs.fs +++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fs @@ -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 Range.rangeStartup 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,7 +162,7 @@ let IsMandatoryTopLevel (f:Val) = specialVal || isModulBinding let IsMandatoryNonTopLevel g (f:Val) = - let byrefVal = isByrefLikeTy g f.Type + let byrefVal = isByrefLikeTy g Range.rangeStartup f.Type byrefVal @@ -727,7 +727,7 @@ let FlatEnvPacks g fclassM topValS declist (reqdItemsMap: Zmap List.filter (fun v -> not (isByrefLikeTy g v.Type)) + let vals = vals |> List.filter (fun v -> not (isByrefLikeTy g Range.rangeStartup v.Type)) // Remove values which have been labelled TLR, no need to close over these let vals = vals |> List.filter (Zset.memberOf topValS >> not) diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index ce0d34a1c2..66abfbcc56 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -771,7 +771,7 @@ let rec AddModuleOrNamespaceRefsToNameEnv g amap m root ad nenv (modrefs: Module nenv.eFullyQualifiedModulesAndNamespaces } let nenv = (nenv,modrefs) ||> List.fold (fun nenv modref -> - if modref.IsModule && TryFindFSharpBoolAttribute g g.attrib_AutoOpenAttribute modref.Attribs = Some true then + if modref.IsModule && TryFindFSharpBoolAttribute g g.attrib_AutoOpenAttribute modref.Attribs = someTrue then AddModuleOrNamespaceContentsToNameEnv g amap ad m false nenv modref else nenv) diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 308736ddbd..2d53df370e 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -1247,7 +1247,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 @@ -1255,16 +1255,16 @@ 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 -> isRecdOrUnionOrStructTyconRefAllocObservable g tcref - | TOp.UnionCase ucref -> isRecdOrUnionOrStructTyconRefAllocObservable g ucref.TyconRef - | TOp.ExnConstr ecref -> isExnAllocObservable ecref - | TOp.Bytes _ | TOp.UInt16s _ | TOp.Array -> true (* alloc observable *) + | RecdExpr -> not (isRecdOrStructTyconRefReadOnly g m tcref) + | TOp.UnionCase ucref -> isRecdOrUnionOrStructTyconRefDefinitelyMutable ucref.TyconRef + | TOp.ExnConstr ecref -> isExnDefinitelyMutable ecref + | TOp.Bytes _ | TOp.UInt16s _ | TOp.Array -> true // mutable | TOp.UnionCaseTagGet _ -> false | TOp.UnionCaseProof _ -> false | TOp.UnionCaseFieldGet (ucref, n) -> isUnionCaseFieldMutable g ucref n @@ -1272,9 +1272,9 @@ and OpHasEffect g op = | 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.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = someTrue) + | TOp.ValFieldGetAddr rfref -> rfref.RecdField.IsMutable + | TOp.UnionCaseFieldGetAddr _ -> false // union case fields are immutable | TOp.LValueOp (LGetAddr, lv) -> lv.IsMutable | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ @@ -1282,8 +1282,8 @@ and OpHasEffect g op = | 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 _ @@ -1800,7 +1800,7 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = 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 *) @@ -1849,7 +1849,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) @@ -2759,7 +2759,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). @@ -2770,6 +2770,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 && @@ -2780,12 +2781,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 diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 938661e039..40e4c799be 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -277,8 +277,8 @@ and CheckTraitInfoDeep ((_,_,_,visitTraitSolutionOpt,_) as f) g env (TTrait(typs // check for byref types //-------------------------------------------------------------------------- -let CheckForByrefLikeType cenv env typ check = - CheckTypeDeep (ignore, Some (fun tcref -> if isByrefLikeTyconRef cenv.g tcref then check()), None, None, None) cenv.g env typ +let CheckForByrefLikeType cenv env m typ check = + CheckTypeDeep (ignore, Some (fun tcref -> if isByrefLikeTyconRef cenv.g m tcref then check()), None, None, None) cenv.g env typ //-------------------------------------------------------------------------- @@ -303,7 +303,7 @@ let CheckEscapes cenv allowProtected m syntacticArgs body = (* m is a range suit false else (v.BaseOrThisInfo = BaseVal) || - (isByrefLikeTy cenv.g v.Type) + (isByrefLikeTy cenv.g m v.Type) let frees = freeInExpr CollectLocals body let fvs = frees.FreeLocals @@ -312,7 +312,7 @@ let CheckEscapes cenv allowProtected m syntacticArgs body = (* m is a range suit elif Zset.exists cantBeFree fvs then let v = List.find cantBeFree (Zset.elements fvs) (* byref error before mutable error (byrefs are mutable...). *) - if (isByrefLikeTy cenv.g v.Type) then + if (isByrefLikeTy cenv.g m v.Type) then // Inner functions are not guaranteed to compile to method with a predictable arity (number of arguments). // As such, partial applications involving byref arguments could lead to closures containing byrefs. // For safety, such functions are assumed to have no known arity, and so can not accept byrefs. @@ -388,19 +388,19 @@ let CheckType permitByrefs (cenv:cenv) env m ty = errorR (Error(FSComp.SR.checkNotSufficientlyGenericBecauseOfScope(tp.DisplayName),m)) let visitTyconRef tcref = - if not permitByrefs && isByrefLikeTyconRef cenv.g tcref then + if not permitByrefs && isByrefLikeTyconRef cenv.g m tcref then errorR(Error(FSComp.SR.chkErrorUseOfByref(), m)) if tyconRefEq cenv.g cenv.g.system_Void_tcref tcref then errorR(Error(FSComp.SR.chkSystemVoidOnlyInTypeof(), m)) // check if T contains byref types in case of byref let visitAppTy (tcref,tinst) = - if isByrefLikeTyconRef cenv.g tcref then + if isByrefLikeTyconRef cenv.g m tcref then let visitType ty0 = match tryDestAppTy cenv.g ty0 with | None -> () | Some tcref -> - if isByrefLikeTyconRef cenv.g tcref then + if isByrefLikeTyconRef cenv.g m tcref then errorR(Error(FSComp.SR.chkNoByrefsOfByrefs(NicePrint.minimalStringOfType cenv.denv ty), m)) CheckTypesDeep (visitType, None, None, None, None) cenv.g env tinst @@ -510,7 +510,7 @@ and CheckVal (cenv:cenv) (env:env) v m context = if isSpliceOperator cenv.g v then errorR(Error(FSComp.SR.chkNoFirstClassSplicing(), m)) if valRefEq cenv.g v cenv.g.addrof_vref then errorR(Error(FSComp.SR.chkNoFirstClassAddressOf(), m)) if valRefEq cenv.g v cenv.g.reraise_vref then errorR(Error(FSComp.SR.chkNoFirstClassRethrow(), m)) - if noByrefs context && isByrefLikeTy cenv.g v.Type then + if noByrefs context && isByrefLikeTy cenv.g m v.Type then // byref typed val can only occur in permitting contexts errorR(Error(FSComp.SR.chkNoByrefAtThisPoint(v.DisplayName), m)) CheckTypePermitByrefs cenv env m v.Type @@ -827,13 +827,13 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckTypeInstNoByrefs cenv env m tyargs | TOp.ValFieldGetAddr rfref,tyargs,[] -> - if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then + if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressStaticFieldAtThisPoint(rfref.FieldName), m)) CheckTypeInstNoByrefs cenv env m tyargs // NOTE: there are no arg exprs to check in this case | TOp.ValFieldGetAddr rfref,tyargs,[rx] -> - if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then + if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(rfref.FieldName), m)) // This construct is used for &(rx.rfield) and &(rx->rfield). Relax to permit byref types for rx. [See Bug 1263]. CheckTypeInstNoByrefs cenv env m tyargs @@ -848,7 +848,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprPermitByref cenv env arg1 // allow byref - it may be address-of-struct | TOp.UnionCaseFieldGetAddr (uref, _idx),tyargs,[rx] -> - if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then + if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(uref.CaseName), m)) CheckTypeInstNoByrefs cenv env m tyargs // allow rx to be byref here, for struct unions @@ -869,12 +869,12 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // permit byref for lhs lvalue of readonly value CheckExprPermitByref cenv env lhs | [ I_ldflda (fspec) | I_ldsflda (fspec) ],[lhs] -> - if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then + if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(fspec.Name), m)) // permit byref for lhs lvalue CheckExprPermitByref cenv env lhs | [ I_ldelema (_,isNativePtr,_,_) ],lhsArray::indices -> - if noByrefs context && cenv.reportErrors && not isNativePtr && isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) then + if noByrefs context && cenv.reportErrors && not isNativePtr && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressOfArrayElementAtThisPoint(), m)) // permit byref for lhs lvalue CheckExprPermitByref cenv env lhsArray @@ -965,12 +965,12 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // Check byref return types if cenv.reportErrors then if (not inlined && (isNil tps && isNil vsl)) || not isTop then - CheckForByrefLikeType cenv env bodyty (fun () -> + CheckForByrefLikeType cenv env m bodyty (fun () -> errorR(Error(FSComp.SR.chkFirstClassFuncNoByref(), m))) elif not cenv.g.compilingFslib && isByrefTy cenv.g bodyty then // check no byrefs-in-the-byref - CheckForByrefLikeType cenv env (destByrefTy cenv.g bodyty) (fun () -> + CheckForByrefLikeType cenv env m (destByrefTy cenv.g bodyty) (fun () -> errorR(Error(FSComp.SR.chkReturnTypeNoByref(), m))) for tp in tps do @@ -981,7 +981,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn | _ -> // Permit byrefs for let x = ... CheckTypePermitByrefs cenv env m ety - if not inlined && (isByrefLikeTy cenv.g ety || isNativePtrTy cenv.g ety) then + if not inlined && (isByrefLikeTy cenv.g m ety || isNativePtrTy cenv.g ety) then // allow byref to occur as RHS of byref binding. CheckExprPermitByref cenv env e else @@ -1102,7 +1102,7 @@ and CheckAttribs cenv env (attribs: Attribs) = |> Seq.map fst |> Seq.toList // Filter for allowMultiple = false - |> List.filter (fun (tcref,m) -> TryFindAttributeUsageAttribute cenv.g m tcref <> Some(true)) + |> List.filter (fun (tcref,m) -> TryFindAttributeUsageAttribute cenv.g m tcref <> someTrue) if cenv.reportErrors then for (tcref,m) in duplicates do @@ -1150,6 +1150,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = let nm = v.DisplayName errorR(Error(FSComp.SR.chkMemberUsedInInvalidWay(nm, nm, stringOfRange m), v.Range)) + let m = v.Range // Byrefs allowed for x in 'let x = ...' v.Type |> CheckTypePermitByrefs cenv env v.Range v.Attribs |> CheckAttribs cenv env @@ -1158,7 +1159,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = // Check accessibility if (v.IsMemberOrModuleBinding || v.IsMember) && not v.IsIncrClassGeneratedMember then let access = AdjustAccess (IsHiddenVal env.sigToImplRemapInfo v) (fun () -> v.TopValDeclaringEntity.CompilationPath) v.Accessibility - CheckTypeForAccess cenv env (fun () -> NicePrint.stringOfQualifiedValOrMember cenv.denv v) access v.Range v.Type + CheckTypeForAccess cenv env (fun () -> NicePrint.stringOfQualifiedValOrMember cenv.denv v) access m v.Type let env = if v.IsConstructor && not v.IsIncrClassConstructor then { env with limited=true } else env @@ -1167,7 +1168,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = // Check top-level let-bound values match bind.Var.ValReprInfo with | Some info when info.HasNoArgs -> - CheckForByrefLikeType cenv env v.Type (fun () -> errorR(Error(FSComp.SR.chkNoByrefAsTopValue(),v.Range))) + CheckForByrefLikeType cenv env m v.Type (fun () -> errorR(Error(FSComp.SR.chkNoByrefAsTopValue(),m))) | _ -> () if Option.isSome v.PublicPath then @@ -1186,7 +1187,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = HasFSharpAttribute cenv.g cenv.g.attrib_ReflectedDefinitionAttribute v.TopValDeclaringEntity.Attribs) then if v.IsInstanceMember && v.MemberApparentEntity.IsStructOrEnumTycon then - errorR(Error(FSComp.SR.chkNoReflectedDefinitionOnStructMember(),v.Range)) + errorR(Error(FSComp.SR.chkNoReflectedDefinitionOnStructMember(),m)) cenv.usesQuotations <- true // If we've already recorded a definition then skip this @@ -1208,7 +1209,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = QuotationTranslator.ConvExprPublic qscope env taue |> ignore let _,_,argExprs = qscope.Close() if not (isNil argExprs) then - errorR(Error(FSComp.SR.chkReflectedDefCantSplice(), v.Range)) + errorR(Error(FSComp.SR.chkReflectedDefCantSplice(), m)) QuotationTranslator.ConvMethodBase qscope env (v.CompiledName, v) |> ignore with | QuotationTranslator.InvalidQuotedTerm e -> @@ -1228,7 +1229,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = let topValInfo = match bind.Var.ValReprInfo with Some info -> info | _ -> ValReprInfo.emptyValData - CheckLambdas isTop v.MemberInfo cenv env v.MustInline topValInfo alwaysCheckNoReraise bindRhs v.Range v.Type + CheckLambdas isTop v.MemberInfo cenv env v.MustInline topValInfo alwaysCheckNoReraise bindRhs m v.Type and CheckBindings cenv env xs = List.iter (CheckBinding cenv env false) xs @@ -1376,7 +1377,7 @@ let CheckRecdField isUnion cenv env (tycon:Tycon) (rfield:RecdField) = CheckAttribs cenv env rfield.PropertyAttribs CheckAttribs cenv env rfield.FieldAttribs if cenv.reportErrors then - CheckForByrefLikeType cenv env rfield.FormalType (fun () -> errorR(Error(FSComp.SR.chkCantStoreByrefValue(), tycon.Range))) + CheckForByrefLikeType cenv env rfield.Range rfield.FormalType (fun () -> errorR(Error(FSComp.SR.chkCantStoreByrefValue(), tycon.Range))) let CheckEntityDefn cenv env (tycon:Entity) = #if !NO_EXTENSIONTYPING @@ -1640,7 +1641,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = for f in tycon.AllInstanceFieldsAsList do // Check if it's marked unsafe let zeroInitUnsafe = TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_DefaultValueAttribute f.FieldAttribs - if zeroInitUnsafe = Some(true) then + if zeroInitUnsafe = someTrue then let ty' = generalizedTyconRef (mkLocalTyconRef tycon) if not (TypeHasDefaultValue cenv.g m ty') then errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m)) @@ -1649,7 +1650,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = match tycon.TypeAbbrev with | None -> () | Some typ -> - CheckForByrefLikeType cenv env typ (fun () -> errorR(Error(FSComp.SR.chkNoByrefInTypeAbbrev(), tycon.Range))) + CheckForByrefLikeType cenv env m typ (fun () -> errorR(Error(FSComp.SR.chkNoByrefInTypeAbbrev(), tycon.Range))) let CheckEntityDefns cenv env tycons = tycons |> List.iter (CheckEntityDefn cenv env) diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 55dd3af045..dec33df4c7 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -560,6 +560,7 @@ let tryNormalizeMeasureInType g ty = // Some basic type builders //--------------------------------------------------------------------------- +let mkVoidPtrTy (g:TcGlobals) = TType_app (g.voidptr_tcr, []) let mkNativePtrTy (g:TcGlobals) ty = TType_app (g.nativeptr_tcr, [ty]) let mkByrefTy (g:TcGlobals) ty = TType_app (g.byref_tcr, [ty]) @@ -1534,12 +1535,6 @@ let isTypeConstructorEqualToOptional g tcOpt tc = | 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) @@ -1550,7 +1545,7 @@ let isVoidTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> 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) + #if !NO_EXTENSIONTYPING let extensionInfoOfTy g ty = ty |> stripTyEqns g |> (function TType_app(tcref, _) -> tcref.TypeReprInfo | _ -> TNoRepr) #endif @@ -2744,7 +2739,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 @@ -2752,18 +2747,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 @@ -2835,16 +2824,16 @@ let TryBindTyconRefAttribute g (m:range) (AttribInfo (atref, _) as args) (tcref: let TryFindTyconRefBoolAttribute g m attribSpec tcref = TryBindTyconRefAttribute g m attribSpec tcref (function - | ([ ], _) -> Some true - | ([ILAttribElem.Bool (v) ], _) -> Some v + | ([ ], _) -> someTrue + | ([ILAttribElem.Bool (v) ], _) -> someBool v | _ -> None) (function - | (Attrib(_, _, [ ], _, _, _, _)) -> Some true - | (Attrib(_, _, [ AttribBoolArg v ], _, _, _, _)) -> Some v + | (Attrib(_, _, [ ], _, _, _, _)) -> someTrue + | (Attrib(_, _, [ AttribBoolArg v ], _, _, _, _)) -> someBool v | _ -> None) (function - | ([ ], _) -> Some true - | ([ Some ((:? bool as v) : obj) ], _) -> Some v + | ([ ], _) -> someTrue + | ([ Some ((:? bool as v) : obj) ], _) -> someBool v | _ -> None) let TryFindAttributeUsageAttribute g m tcref = @@ -2866,11 +2855,27 @@ let TryFindTyconRefStringAttribute g m attribSpec tcref = /// Check if a type definition has a specific attribute let TyconRefHasAttribute g m attribSpec tcref = TryBindTyconRefAttribute g m attribSpec tcref - (fun _ -> Some ()) - (fun _ -> Some ()) - (fun _ -> Some ()) + (fun _ -> someUnit) + (fun _ -> someUnit) + (fun _ -> someUnit) |> Option.isSome +let isByrefLikeTyconRef g m (tcref: TyconRef) = + match tcref.TryIsByRefLike with + | Some res -> res + | None -> + let res = + 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 || + 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... //------------------------------------------------------------------------- @@ -5220,30 +5225,32 @@ and remarkBind m (TBind(v, repr, _)) = // Reference semantics? //-------------------------------------------------------------------------- -let isRecdOrStructFieldAllocObservable (f:RecdField) = not f.IsStatic && f.IsMutable -let isUnionCaseAllocObservable (uc:UnionCase) = uc.FieldTable.FieldsByIndex |> Array.exists isRecdOrStructFieldAllocObservable -let isUnionCaseRefAllocObservable (uc:UnionCaseRef) = uc.UnionCase |> isUnionCaseAllocObservable +let isRecdOrStructFieldDefinitelyMutable (f:RecdField) = not f.IsStatic && f.IsMutable +let isUnionCaseDefinitelyMutable (uc:UnionCase) = uc.FieldTable.FieldsByIndex |> Array.exists isRecdOrStructFieldDefinitelyMutable +let isUnionCaseRefDefinitelyMutable (uc:UnionCaseRef) = uc.UnionCase |> isUnionCaseDefinitelyMutable -let isRecdOrUnionOrStructTyconAllocObservable (_g:TcGlobals) (tycon:Tycon) = +/// This is an incomplete check for .NET struct types. Returning 'false' doesn't mean the thing is immutable. +let isRecdOrUnionOrStructTyconRefDefinitelyMutable (tcref: TyconRef) = + let tycon = tcref.Deref if tycon.IsUnionTycon then - tycon.UnionCasesArray |> Array.exists isUnionCaseAllocObservable + tycon.UnionCasesArray |> Array.exists isUnionCaseDefinitelyMutable elif tycon.IsRecordTycon || tycon.IsStructOrEnumTycon then - tycon.AllFieldsArray |> Array.exists isRecdOrStructFieldAllocObservable + // 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 isRecdOrUnionOrStructTyconRefAllocObservable g (tcr : TyconRef) = isRecdOrUnionOrStructTyconAllocObservable 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 -let isExnAllocObservable (_ecref:TyconRef) = true +let isExnDefinitelyMutable (_ecref:TyconRef) = true // Some of the implementations of library functions on lists use mutation on the tail // 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) || @@ -5556,13 +5563,23 @@ let mkAndSimplifyMatch spBind exprm matchm ty tree targets = type Mutates = DefinitelyMutates | PossiblyMutates | NeverMutates exception DefensiveCopyWarning of string * range -let isRecdOrStructTyImmutable g ty = +let isRecdOrStructTyconRefReadOnly (g: TcGlobals) m (tcref: TyconRef) = + match tcref.TryIsReadOnly with + | Some res -> res + | None -> + let res = + not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) || + tyconRefEq g tcref g.decimal_tcr || + tyconRefEq g tcref g.date_tcr || + TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref + tcref.SetIsReadOnly res + res + +let isRecdOrStructTyReadOnly (g: TcGlobals) m ty = match tryDestAppTy g ty with | None -> false - | Some tcref -> - not (isRecdOrUnionOrStructTyconRefAllocObservable g tcref) || - tyconRefEq g tcref g.decimal_tcr || - tyconRefEq g tcref g.date_tcr + | Some tcref -> isRecdOrStructTyconRefReadOnly g m tcref + // We can take the address of values of struct type even if the value is immutable // under certain conditions @@ -5575,18 +5592,18 @@ let isRecdOrStructTyImmutable g ty = // let g1 = A.G(1) // (fun () -> g1.x1) // -// Note: isRecdOrStructTyImmutable implies PossiblyMutates or NeverMutates +// Note: isRecdOrStructTyReadOnly implies PossiblyMutates or NeverMutates // // 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 m (v: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 -> isRecdOrStructTyImmutable g v.Type + | PossiblyMutates -> isRecdOrStructTyReadOnly g m v.Type | DefinitelyMutates -> false) let MustTakeAddressOfVal (g:TcGlobals) (v:ValRef) = @@ -5601,19 +5618,19 @@ let MustTakeAddressOfRecdField (rf: RecdField) = let MustTakeAddressOfRecdFieldRef (rfref: RecdFieldRef) = MustTakeAddressOfRecdField rfref.RecdField -let CanTakeAddressOfRecdFieldRef (g:TcGlobals) (rfref: RecdFieldRef) mut tinst = +let CanTakeAddressOfRecdFieldRef (g:TcGlobals) m (rfref: RecdFieldRef) mut = mut <> DefinitelyMutates && // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields entityRefInThisAssembly g.compilingFslib rfref.TyconRef && - isRecdOrStructTyImmutable g (actualTyOfRecdFieldRef rfref tinst) + isRecdOrStructTyconRefReadOnly g m rfref.TyconRef -let CanTakeAddressOfUnionFieldRef (g:TcGlobals) (uref: UnionCaseRef) mut tinst cidx = +let CanTakeAddressOfUnionFieldRef (g:TcGlobals) m (uref: UnionCaseRef) mut = mut <> DefinitelyMutates && // We only do this if the field is defined in this assembly because we can't take addresses across assemblies for immutable fields entityRefInThisAssembly g.compilingFslib uref.TyconRef && - isRecdOrStructTyImmutable g (actualTyOfUnionFieldRef uref cidx tinst) - + isRecdOrStructTyconRefReadOnly g m uref.TyconRef +/// Make the address-of expression and return a wrapper that adds any allocated locals at an appropriate scope let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m = if not mustTakeAddress then None, e else match e with @@ -5622,15 +5639,15 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress 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 -> + | Expr.Val(v, _, m) when MustTakeAddressOfVal g v || CanTakeAddressOfImmutableVal g m 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 -> + | Expr.Op (TOp.ValFieldGet rfref, tinst, [e], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref mut -> 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 -> + | Expr.Op (TOp.UnionCaseFieldGet (uref, cidx), tinst, [e], m) when MustTakeAddressOfRecdField (uref.FieldByIndex(cidx)) || CanTakeAddressOfUnionFieldRef g m uref mut -> 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) @@ -5647,7 +5664,7 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress wrap, Expr.Op (TOp.ILAsm ([IL.I_ldflda(fspec)], [mkByrefTy g ty2]), tinst, [expra], m) // LVALUE: "x" where "x" is mutable static field. - | Expr.Op (TOp.ValFieldGet rfref, tinst, [], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g rfref mut tinst -> + | Expr.Op (TOp.ValFieldGet rfref, tinst, [], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref mut -> None, mkStaticRecdFieldGetAddr(rfref, tinst, m) // LVALUE: "e.[n]" where e is an array of structs @@ -7281,7 +7298,7 @@ let TypeNullIsExtraValue g m ty = false else // Putting AllowNullLiteralAttribute(true) on an F# type means 'null' can be used with that type - isAppTy g ty && TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute (tcrefOfAppTy g ty) = Some(true) + isAppTy g ty && TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute (tcrefOfAppTy g ty) = someTrue let TypeNullIsTrueValue g ty = (match tryDestAppTy g ty with @@ -7439,7 +7456,7 @@ let isSealedTy g ty = if (isFSharpInterfaceTy g ty || isFSharpClassTy g ty) then let tcref, _ = destAppTy g ty - (TryFindFSharpBoolAttribute g g.attrib_SealedAttribute tcref.Attribs = Some(true)) + (TryFindFSharpBoolAttribute g g.attrib_SealedAttribute tcref.Attribs = someTrue) else // All other F# types, array, byref, tuple types are sealed true @@ -7448,7 +7465,7 @@ let isComInteropTy g ty = let tcr, _ = destAppTy g ty match g.attrib_ComImportAttribute with | None -> false - | Some attr -> TryFindFSharpBoolAttribute g attr tcr.Attribs = Some(true) + | Some attr -> TryFindFSharpBoolAttribute g attr tcr.Attribs = someTrue let ValSpecIsCompiledAsInstance g (v:Val) = match v.MemberInfo with diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index 63ee7ee670..443e2875e3 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -975,6 +975,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 @@ -1091,11 +1092,12 @@ val TypeHasDefaultValue : TcGlobals -> range -> TType -> bool val isAbstractTycon : Tycon -> bool -val isUnionCaseRefAllocObservable : UnionCaseRef -> bool -val isRecdOrUnionOrStructTyconRefAllocObservable : TcGlobals -> TyconRef -> bool -val isExnAllocObservable : TyconRef -> bool +val isUnionCaseRefDefinitelyMutable : UnionCaseRef -> 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 useGenuineField : Tycon -> RecdField -> bool val ComputeFieldName : Tycon -> RecdField -> string @@ -1374,7 +1376,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 @@ -1398,8 +1399,8 @@ 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 isByrefLikeTyconRef : TcGlobals -> range -> TyconRef -> bool +val isByrefLikeTy : TcGlobals -> range -> TType -> bool //------------------------------------------------------------------------- // Tuple constructors/destructors diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index 64ea4e96d6..40c574e365 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -202,6 +202,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d let v_pint64_tcr = mk_MFCore_tcref fslibCcu "int64`1" let v_byref_tcr = mk_MFCore_tcref fslibCcu "byref`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" @@ -916,6 +917,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member __.pint64_tcr = v_pint64_tcr member __.byref_tcr = v_byref_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 @@ -1073,6 +1075,11 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d member val attrib_ParamArrayAttribute = findSysAttrib "System.ParamArrayAttribute" 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" diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index b2afcc0b0b..2cbc6b5eca 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -2169,13 +2169,13 @@ module GeneralizationHelpers = | Expr.Op(op, _, args, _) -> match op with | TOp.Tuple _ -> true - | TOp.UnionCase uc -> not (isUnionCaseRefAllocObservable uc) + | TOp.UnionCase uc -> not (isUnionCaseRefDefinitelyMutable uc) | TOp.Recd(ctorInfo, tcref) -> match ctorInfo with - | RecdExpr -> not (isRecdOrUnionOrStructTyconRefAllocObservable g tcref) + | RecdExpr -> not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) | RecdExprIsObjInit -> false | TOp.Array -> isNil args - | TOp.ExnConstr ec -> not (isExnAllocObservable ec) + | TOp.ExnConstr ec -> not (isExnDefinitelyMutable ec) | TOp.ILAsm([], _) -> true @@ -14111,7 +14111,7 @@ module TyconConstraintInference = // If the type was excluded, say why if not res then match TryFindFSharpBoolAttribute g g.attrib_StructuralComparisonAttribute tycon.Attribs with - | Some(true) -> + | Some true -> match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsComparison tycon >> not) with | None -> assert false @@ -14235,7 +14235,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 -> @@ -15121,7 +15121,7 @@ module EstablishTypeDefinitionCores = let hasSealedAttr = // The special case is needed for 'unit' because the 'Sealed' attribute is not yet available when this type is defined. if cenv.g.compilingFslib && id.idText = "Unit" then - Some true + someTrue else TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_SealedAttribute attrs let hasMeasureAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute attrs @@ -15132,7 +15132,7 @@ module EstablishTypeDefinitionCores = let hasCLIMutable = HasFSharpAttribute cenv.g cenv.g.attrib_CLIMutableAttribute attrs let structLayoutAttr = TryFindFSharpInt32Attribute cenv.g cenv.g.attrib_StructLayoutAttribute attrs - let hasAllowNullLiteralAttr = TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_AllowNullLiteralAttribute attrs = Some(true) + let hasAllowNullLiteralAttr = TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_AllowNullLiteralAttribute attrs = Some true if hasAbstractAttr then tycon.TypeContents.tcaug_abstract <- true @@ -15166,7 +15166,7 @@ module EstablishTypeDefinitionCores = let hiddenReprChecks(hasRepr) = structLayoutAttributeCheck(false) - if hasSealedAttr = Some(false) || (hasRepr && hasSealedAttr <> Some(true) && not (id.idText = "Unit" && cenv.g.compilingFslib) ) then + if hasSealedAttr = Some(false) || (hasRepr && hasSealedAttr <> Some true && not (id.idText = "Unit" && cenv.g.compilingFslib) ) then errorR(Error(FSComp.SR.tcRepresentationOfTypeHiddenBySignature(), m)) if hasAbstractAttr then errorR (Error(FSComp.SR.tcOnlyClassesCanHaveAbstract(), m)) @@ -15178,7 +15178,7 @@ module EstablishTypeDefinitionCores = if hasCLIMutable then errorR (Error(FSComp.SR.tcThisTypeMayNotHaveACLIMutableAttribute(), m)) let noSealedAttributeCheck(k) = - if hasSealedAttr = Some(true) then errorR (Error(k(), m)) + if hasSealedAttr = Some true then errorR (Error(k(), m)) let noFieldsCheck(fields':RecdField list) = match fields' with @@ -15253,7 +15253,7 @@ module EstablishTypeDefinitionCores = TNoRepr, None, NoSafeInitInfo | SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, rhsType, _) -> - if hasSealedAttr = Some(true) then + if hasSealedAttr = Some true then errorR (Error(FSComp.SR.tcAbbreviatedTypesCannotBeSealed(), m)) noAbstractClassAttributeCheck() noAllowNullLiteralAttributeCheck() @@ -15356,7 +15356,7 @@ module EstablishTypeDefinitionCores = TTyconStruct | TyconInterface -> - if hasSealedAttr = Some(true) then errorR (Error(FSComp.SR.tcInterfaceTypesCannotBeSealed(), m)) + if hasSealedAttr = Some true then errorR (Error(FSComp.SR.tcInterfaceTypesCannotBeSealed(), m)) noCLIMutableAttributeCheck() structLayoutAttributeCheck(false) noAbstractClassAttributeCheck() diff --git a/src/fsharp/import.fs b/src/fsharp/import.fs index 571c20b6d9..b814d3fd69 100644 --- a/src/fsharp/import.fs +++ b/src/fsharp/import.fs @@ -169,6 +169,7 @@ let rec ImportILType (env:ImportMap) m tinst typ = ImportTyconRefApp env tcref inst | ILType.Byref ty -> mkByrefTy env.g (ImportILType env m tinst ty) + | ILType.Ptr ILType.Void -> 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,7 +261,10 @@ 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))) - mkNativePtrTy g elemTy + if isUnitTy g elemTy || isVoidTy g elemTy then + mkVoidPtrTy g + else + mkNativePtrTy g elemTy else // REVIEW: Extension type could try to be its own generic arg (or there could be a type loop) diff --git a/src/fsharp/symbols/Symbols.fs b/src/fsharp/symbols/Symbols.fs index 555f216409..46ca9ef7ad 100644 --- a/src/fsharp/symbols/Symbols.fs +++ b/src/fsharp/symbols/Symbols.fs @@ -201,9 +201,9 @@ type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol - member x.DeclarationLocation = SymbolHelpers.rangeOfItem cenv.g None x.Item - member x.ImplementationLocation = SymbolHelpers.rangeOfItem cenv.g (Some(false)) x.Item + member x.ImplementationLocation = SymbolHelpers.rangeOfItem cenv.g someFalse x.Item - member x.SignatureLocation = SymbolHelpers.rangeOfItem cenv.g (Some(true)) x.Item + member x.SignatureLocation = SymbolHelpers.rangeOfItem cenv.g someTrue x.Item member x.IsEffectivelySameAs(y:FSharpSymbol) = x.Equals(y) || ItemsAreEffectivelyEqual cenv.g x.Item y.Item diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index 460da78922..d25e13450c 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -198,7 +198,7 @@ type ValFlags(flags:int64) = | _ -> failwith "unreachable" - member x.SetIsMemberOrModuleBinding = ValFlags(flags ||| 0b0000000000010000000L) + member x.WithIsMemberOrModuleBinding = ValFlags(flags ||| 0b0000000000010000000L) member x.IsExtensionMember = (flags &&& 0b0000000000100000000L) <> 0L @@ -211,7 +211,7 @@ type ValFlags(flags:int64) = | 0b0000001000000000000L -> ValInRecScope(false) | _ -> failwith "unreachable" - member x.SetRecursiveValInfo(recValInfo) = + member x.WithRecursiveValInfo(recValInfo) = let flags = (flags &&& ~~~0b0000001100000000000L) ||| (match recValInfo with @@ -222,23 +222,23 @@ type ValFlags(flags:int64) = member x.MakesNoCriticalTailcalls = (flags &&& 0b0000010000000000000L) <> 0L - member x.SetMakesNoCriticalTailcalls = ValFlags(flags ||| 0b0000010000000000000L) + member x.WithTakesNoCriticalTailcalls = ValFlags(flags ||| 0b0000010000000000000L) member x.PermitsExplicitTypeInstantiation = (flags &&& 0b0000100000000000000L) <> 0L member x.HasBeenReferenced = (flags &&& 0b0001000000000000000L) <> 0L - member x.SetHasBeenReferenced = ValFlags(flags ||| 0b0001000000000000000L) + member x.WithHasBeenReferenced = ValFlags(flags ||| 0b0001000000000000000L) member x.IsCompiledAsStaticPropertyWithoutField = (flags &&& 0b0010000000000000000L) <> 0L - member x.SetIsCompiledAsStaticPropertyWithoutField = ValFlags(flags ||| 0b0010000000000000000L) + member x.WithIsCompiledAsStaticPropertyWithoutField = ValFlags(flags ||| 0b0010000000000000000L) member x.IsGeneratedEventVal = (flags &&& 0b0100000000000000000L) <> 0L member x.IsFixed = (flags &&& 0b1000000000000000000L) <> 0L - member x.SetIsFixed = ValFlags(flags ||| 0b1000000000000000000L) + member x.WithIsFixed = ValFlags(flags ||| 0b1000000000000000000L) /// Get the flags as included in the F# binary metadata @@ -314,8 +314,10 @@ type TyparFlags(flags:int32) = /// Indicates if the type inference variable was generated after an error when type checking expressions or patterns member x.IsFromError = (flags &&& 0b0000000000010) <> 0x0 + /// Indicates if the type variable is compiler generated, i.e. is an implicit type inference variable member x.IsCompilerGenerated = (flags &&& 0b0000000000100) <> 0x0 + /// Indicates if the type variable has a static "head type" requirement, i.e. ^a variables used in FSharp.Core and member constraints. member x.StaticReq = match (flags &&& 0b0000000001000) with @@ -364,32 +366,64 @@ type TyparFlags(flags:int32) = type EntityFlags(flags:int64) = new (usesPrefixDisplay, isModuleOrNamespace, preEstablishedHasDefaultCtor, hasSelfReferentialCtor, isStructRecordOrUnionType) = - EntityFlags((if isModuleOrNamespace then 0b00000000001L else 0L) ||| - (if usesPrefixDisplay then 0b00000000010L else 0L) ||| - (if preEstablishedHasDefaultCtor then 0b00000000100L else 0L) ||| - (if hasSelfReferentialCtor then 0b00000001000L else 0L) ||| - (if isStructRecordOrUnionType then 0b00000100000L else 0L)) - - member x.IsModuleOrNamespace = (flags &&& 0b00000000001L) <> 0x0L - member x.IsPrefixDisplay = (flags &&& 0b00000000010L) <> 0x0L + EntityFlags((if isModuleOrNamespace then 0b000000000000001L else 0L) ||| + (if usesPrefixDisplay then 0b000000000000010L else 0L) ||| + (if preEstablishedHasDefaultCtor then 0b000000000000100L else 0L) ||| + (if hasSelfReferentialCtor then 0b000000000001000L else 0L) ||| + (if isStructRecordOrUnionType then 0b000000000100000L else 0L)) + + member x.IsModuleOrNamespace = (flags &&& 0b000000000000001L) <> 0x0L + member x.IsPrefixDisplay = (flags &&& 0b000000000000010L) <> 0x0L // This bit is not pickled, only used while establishing a type constructor. It is needed because the type constructor // is known to satisfy the default constructor constraint even before any of its members have been established. - member x.PreEstablishedHasDefaultConstructor = (flags &&& 0b00000000100L) <> 0x0L + member x.PreEstablishedHasDefaultConstructor = (flags &&& 0b000000000000100L) <> 0x0L // This bit represents an F# specific condition where a type has at least one constructor that may access // the 'this' pointer prior to successful initialization of the partial contents of the object. In this // case sub-classes must protect themselves against early access to their contents. - member x.HasSelfReferentialConstructor = (flags &&& 0b00000001000L) <> 0x0L + member x.HasSelfReferentialConstructor = (flags &&& 0b000000000001000L) <> 0x0L + + /// This bit is reserved for us in the pickle format, see pickle.fs, it's being listed here to stop it ever being used for anything else + static member ReservedBitForPickleFormatTyconReprFlag = 0b000000000010000L /// This bit represents a F# record that is a value type, or a struct record. - member x.IsStructRecordOrUnionType = (flags &&& 0b00000100000L) <> 0x0L + member x.IsStructRecordOrUnionType = (flags &&& 0b000000000100000L) <> 0x0L - /// This bit is reserved for us in the pickle format, see pickle.fs, it's being listed here to stop it ever being used for anything else - static member ReservedBitForPickleFormatTyconReprFlag = 0b00000010000L + /// These two bits represents the on-demand analysis about whether the entity has the IsByRefLike attribute + member x.TryIsByRefLike = (flags &&& 0b000000011000000L) + |> function + | 0b000000011000000L -> someTrue + | 0b000000010000000L -> someFalse + | _ -> None + + /// Adjust the on-demand analysis about whether the entity has the IsByRefLike attribute + member x.WithIsByRefLike(flag) = + let flags = + (flags &&& ~~~0b000000011000000L) ||| + (match flag with + | true -> 0b000000011000000L + | false -> 0b000000010000000L) + EntityFlags(flags) + + /// These two bits represents the on-demand analysis about whether the entity has the IsReadOnly attribute or is otherwise determined to be a readonly struct + member x.TryIsReadOnly = (flags &&& 0b000001100000000L) + |> function + | 0b000001100000000L -> someTrue + | 0b000001000000000L -> someFalse + | _ -> None + + /// Adjust the on-demand analysis about whether the entity has the IsReadOnly attribute or is otherwise determined to be a readonly struct + member x.WithIsReadOnly(flag) = + let flags = + (flags &&& ~~~0b000001100000000L) ||| + (match flag with + | true -> 0b000001100000000L + | false -> 0b000001000000000L) + EntityFlags(flags) /// Get the flags as included in the F# binary metadata - member x.PickledBits = (flags &&& ~~~0b00000000100L) + member x.PickledBits = (flags &&& ~~~0b000001111000100L) #if DEBUG @@ -972,6 +1006,18 @@ and /// Represents a type definition, exception definition, module definition or /// Indicates if this is an F# type definition whose r.h.s. is known to be a record type definition that is a value type. member x.IsStructRecordOrUnionTycon = match x.TypeReprInfo with TRecdRepr _ | TUnionRepr _ -> x.entity_flags.IsStructRecordOrUnionType | _ -> false + /// The on-demand analysis about whether the entity has the IsByRefLike attribute + member x.TryIsByRefLike = x.entity_flags.TryIsByRefLike + + /// Set the on-demand analysis about whether the entity has the IsByRefLike attribute + member x.SetIsByRefLike b = x.entity_flags <- x.entity_flags.WithIsByRefLike b + + /// These two bits represents the on-demand analysis about whether the entity has the IsReadOnly attribute or is otherwise determined to be a readonly struct + member x.TryIsReadOnly = x.entity_flags.TryIsReadOnly + + /// Set the on-demand analysis about whether the entity has the IsReadOnly attribute or is otherwise determined to be a readonly struct + member x.SetIsReadOnly b = x.entity_flags <- x.entity_flags.WithIsReadOnly b + /// Indicates if this is an F# type definition whose r.h.s. is known to be some kind of F# object model definition member x.IsFSharpObjectModelTycon = match x.TypeReprInfo with | TFSharpObjectRepr _ -> true | _ -> false @@ -2723,17 +2769,17 @@ and [] member x.DisplayName = DemangleOperatorName x.CoreDisplayName - member x.SetValRec b = x.val_flags <- x.val_flags.SetRecursiveValInfo b + member x.SetValRec b = x.val_flags <- x.val_flags.WithRecursiveValInfo b - member x.SetIsMemberOrModuleBinding() = x.val_flags <- x.val_flags.SetIsMemberOrModuleBinding + member x.SetIsMemberOrModuleBinding() = x.val_flags <- x.val_flags.WithIsMemberOrModuleBinding - member x.SetMakesNoCriticalTailcalls() = x.val_flags <- x.val_flags.SetMakesNoCriticalTailcalls + member x.SetMakesNoCriticalTailcalls() = x.val_flags <- x.val_flags.WithTakesNoCriticalTailcalls - member x.SetHasBeenReferenced() = x.val_flags <- x.val_flags.SetHasBeenReferenced + member x.SetHasBeenReferenced() = x.val_flags <- x.val_flags.WithHasBeenReferenced - member x.SetIsCompiledAsStaticPropertyWithoutField() = x.val_flags <- x.val_flags.SetIsCompiledAsStaticPropertyWithoutField + member x.SetIsCompiledAsStaticPropertyWithoutField() = x.val_flags <- x.val_flags.WithIsCompiledAsStaticPropertyWithoutField - member x.SetIsFixed() = x.val_flags <- x.val_flags.SetIsFixed + member x.SetIsFixed() = x.val_flags <- x.val_flags.WithIsFixed member x.SetValReprInfo info = match x.val_opt_data with @@ -3309,6 +3355,18 @@ and /// Indicates if this is an F# type definition whose r.h.s. is known to be some kind of F# object model definition member x.IsFSharpObjectModelTycon = x.Deref.IsFSharpObjectModelTycon + /// The on-demand analysis about whether the entity has the IsByRefLike attribute + member x.TryIsByRefLike = x.Deref.TryIsByRefLike + + /// Set the on-demand analysis about whether the entity has the IsByRefLike attribute + member x.SetIsByRefLike b = x.Deref.SetIsByRefLike b + + /// The on-demand analysis about whether the entity has the IsByRefLike attribute + member x.TryIsReadOnly = x.Deref.TryIsReadOnly + + /// Set the on-demand analysis about whether the entity has the IsReadOnly attribute or is otherwise determined to be a readonly struct + member x.SetIsReadOnly b = x.Deref.SetIsReadOnly b + /// Indicates if this is an F# type definition whose r.h.s. definition is unknown (i.e. a traditional ML 'abstract' type in a signature, /// which in F# is called a 'unknown representation' type). member x.IsHiddenReprTycon = x.Deref.IsHiddenReprTycon From 9a4fdae44d81fca2372dcec4f94a106ee5286e06 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 01:49:00 +0100 Subject: [PATCH 02/61] fix proto build --- packages.config | 1 + src/fsharp/TastOps.fs | 2 ++ src/fsharp/tast.fs | 53 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/packages.config b/packages.config index e61ca96e38..f922611d5c 100644 --- a/packages.config +++ b/packages.config @@ -37,6 +37,7 @@ + diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index dec33df4c7..43ff8e361a 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -2861,6 +2861,7 @@ let TyconRefHasAttribute g m attribSpec tcref = |> Option.isSome let isByrefLikeTyconRef g m (tcref: TyconRef) = + tcref.CanDeref && match tcref.TryIsByRefLike with | Some res -> res | None -> @@ -5564,6 +5565,7 @@ type Mutates = DefinitelyMutates | PossiblyMutates | NeverMutates exception DefensiveCopyWarning of string * range let isRecdOrStructTyconRefReadOnly (g: TcGlobals) m (tcref: TyconRef) = + tcref.CanDeref && match tcref.TryIsReadOnly with | Some res -> res | None -> diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index d25e13450c..353d7225d4 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -4040,13 +4040,18 @@ and Attribs = Attrib list and AttribKind = /// Indicates an attribute refers to a type defined in an imported .NET assembly | ILAttrib of ILMethodRef + /// Indicates an attribute refers to a type defined in an imported F# assembly | FSAttrib of ValRef + override x.ToString() = sprintf "AttribKind(...)" + /// Attrib(kind,unnamedArgs,propVal,appliedToAGetterOrSetter,targetsOpt,range) and Attrib = | Attrib of TyconRef * AttribKind * AttribExpr list * AttribNamedArg list * bool * AttributeTargets option * range + override x.ToString() = sprintf "Attrib(...)" + /// We keep both source expression and evaluated expression around to help intellisense and signature printing and AttribExpr = /// AttribExpr(source, evaluated) @@ -4113,6 +4118,8 @@ and /// body -- the rest of the decision tree | TDBind of Binding * DecisionTree + override x.ToString() = sprintf "DecisionTree(...)" + /// Represents a test and a subsequent decision tree and DecisionTreeCase = | TCase of DecisionTreeTest * DecisionTree @@ -4123,6 +4130,8 @@ and DecisionTreeCase = /// Get the decision tree or a successful test member x.CaseTree = let (TCase(_,d)) = x in d + override x.ToString() = sprintf "DecisionTreeCase(...)" + and [] DecisionTreeTest = @@ -4154,6 +4163,7 @@ and /// activePatternInfo -- The extracted info for the active pattern. | ActivePatternCase of Expr * TTypes * (ValRef * TypeInst) option * int * ActivePatternInfo + override x.ToString() = sprintf "DecisionTreeTest(...)" /// A target of a decision tree. Can be thought of as a little function, though is compiled as a local block. and DecisionTreeTarget = @@ -4174,6 +4184,8 @@ and Binding = /// The information about whether to emit a sequence point for the binding member x.SequencePointInfo = (let (TBind(_,_,sp)) = x in sp) + + override x.ToString() = sprintf "Binding for %s" x.Var.CompiledName /// Represents a reference to an active pattern element. The /// integer indicates which choice in the target set is being selected by this item. @@ -4226,6 +4238,8 @@ and ValReprInfo = | (_::_::h)::t -> loop t (acc + h.Length + 2) loop args 0 + override __.ToString() = "ValReprInfo(...)" + /// Records the "extra information" for an argument compiled as a real /// method argument, specifically the argument name and attributes. and @@ -4238,6 +4252,8 @@ and // MUTABILITY: used when propagating names of parameters from signature into the implementation. mutable Name : Ident option } + override __.ToString() = "ArgReprInfo(...)" + /// Records the extra metadata stored about typars for type parameters /// compiled as "real" IL type parameters, specifically for values with /// ValReprInfo. Any information here is propagated from signature through @@ -4332,6 +4348,8 @@ and /// appropriate type instantiation. These are immediately eliminated on subsequent rewrites. | Link of Expr ref + override __.ToString() = "Expr(...)" + and [] TOp = @@ -4444,6 +4462,7 @@ and /// retTy -- the types of pushed values, if any | ILCall of bool * bool * bool * bool * ValUseFlag * bool * bool * ILMethodRef * TypeInst * TypeInst * TTypes + override __.ToString() = "TOp(...)" /// Indicates the kind of record construction operation. and RecordConstructionInfo = @@ -4530,18 +4549,27 @@ and StaticOptimization = /// TObjExprMethod(slotsig,attribs,methTyparsOfOverridingMethod,methodParams,methodBodyExpr,m) and ObjExprMethod = | TObjExprMethod of SlotSig * Attribs * Typars * Val list list * Expr * range + member x.Id = let (TObjExprMethod(slotsig,_,_,_,_,m)) = x in mkSynId m slotsig.Name + override __.ToString() = "TObjExprMethod(...)" + /// Represents an abstract method slot, or delegate signature. /// /// TSlotSig(methodName,declaringType,declaringTypeParameters,methodTypeParameters,slotParameters,returnTy) and SlotSig = | TSlotSig of string * TType * Typars * Typars * SlotParam list list * TType option + member ss.Name = let (TSlotSig(nm,_,_,_,_,_)) = ss in nm + member ss.ImplementedType = let (TSlotSig(_,ty,_,_,_,_)) = ss in ty + member ss.ClassTypars = let (TSlotSig(_,_,ctps,_,_,_)) = ss in ctps + member ss.MethodTypars = let (TSlotSig(_,_,_,mtps,_,_)) = ss in mtps + member ss.FormalParams = let (TSlotSig(_,_,_,_,ps,_)) = ss in ps + member ss.FormalReturnType = let (TSlotSig(_,_,_,_,_,rt)) = ss in rt /// Represents a parameter to an abstract method slot. @@ -4549,8 +4577,11 @@ and SlotSig = /// TSlotParam(nm,ty,inFlag,outFlag,optionalFlag,attribs) and SlotParam = | TSlotParam of string option * TType * bool (* in *) * bool (* out *) * bool (* optional *) * Attribs + member x.Type = let (TSlotParam(_,ty,_,_,_,_)) = x in ty + override __.ToString() = "TSlotParam(...)" + /// A type for a module-or-namespace-fragment and the actual definition of the module-or-namespace-fragment /// The first ModuleOrNamespaceType is the signature and is a binder. However the bindings are not used in the ModuleOrNamespaceExpr: it is only referenced from the 'outside' /// is for use by FCS only to report the "hidden" contents of the assembly prior to applying the signature. @@ -4559,8 +4590,11 @@ and ModuleOrNamespaceExprWithSig = ModuleOrNamespaceType * ModuleOrNamespaceExpr * range + member x.Type = let (ModuleOrNamespaceExprWithSig(mtyp,_,_)) = x in mtyp + override __.ToString() = "ModuleOrNamespaceExprWithSig(...)" + /// The contents of a module-or-namespace-fragment definition and ModuleOrNamespaceExpr = /// Indicates the module is a module with a signature @@ -4578,6 +4612,8 @@ and ModuleOrNamespaceExpr = /// Indicates the module fragment is a 'rec' or 'non-rec' definition of types and modules | TMDefRec of isRec:bool * Tycon list * ModuleOrNamespaceBinding list * range + override __.ToString() = "ModuleOrNamespaceExpr(...)" + /// A named module-or-namespace-fragment definition and [] ModuleOrNamespaceBinding = @@ -4591,15 +4627,22 @@ and [] /// This is the body of the module/namespace ModuleOrNamespaceExpr + override __.ToString() = "ModuleOrNamespaceBinding(...)" /// Represents a complete typechecked implementation file, including its typechecked signature if any. /// /// TImplFile(qualifiedNameOfFile,pragmas,implementationExpressionWithSignature,hasExplicitEntryPoint,isScript) -and TypedImplFile = TImplFile of QualifiedNameOfFile * ScopedPragma list * ModuleOrNamespaceExprWithSig * bool * bool +and TypedImplFile = + | TImplFile of QualifiedNameOfFile * ScopedPragma list * ModuleOrNamespaceExprWithSig * bool * bool + + override __.ToString() = "TImplFile(...)" /// Represents a complete typechecked assembly, made up of multiple implementation files. /// -and TypedAssemblyAfterOptimization = TypedAssemblyAfterOptimization of (TypedImplFile * (* optimizeDuringCodeGen: *) (Expr -> Expr)) list +and TypedAssemblyAfterOptimization = + | TypedAssemblyAfterOptimization of (TypedImplFile * (* optimizeDuringCodeGen: *) (Expr -> Expr)) list + + override __.ToString() = "TypedAssemblyAfterOptimization(...)" //--------------------------------------------------------------------------- // Freevars. Computed and cached by later phases (never computed type checking). Cached in terms. Not pickled. @@ -4636,6 +4679,8 @@ and FreeTyvars = /// and we have to check various conditions associated with that. FreeTypars: FreeTypars } + override x.ToString() = sprintf "FreeTyvars(...)" + /// Represents an amortized computation of the free variables in an expression and FreeVarsCache = FreeVars cache @@ -4669,6 +4714,8 @@ and FreeVars = /// See FreeTyvars above. FreeTyvars: FreeTyvars } + override x.ToString() = sprintf "FreeVars(...)" + /// Specifies the compiled representations of type and exception definitions. Basically /// just an ILTypeRef. Computed and cached by later phases. Stored in /// type and exception definitions. Not pickled. Store an optional ILType object for @@ -4697,6 +4744,8 @@ and [] // type ilsigptr<'T> = (# "!0*" #) | ILAsmOpen of ILType + override x.ToString() = sprintf "CompiledTypeRepr(...)" + //--------------------------------------------------------------------------- // Basic properties on type definitions //--------------------------------------------------------------------------- From e4744e92c918fee099e3feaf93d9e7b91ece3ca6 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 02:51:39 +0100 Subject: [PATCH 03/61] make proto work with previous FSharp.Core --- src/fsharp/IlxGen.fs | 2 -- src/fsharp/TastOps.fs | 4 +++- src/fsharp/import.fs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 91bf963379..fe4f7edf82 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -397,8 +397,6 @@ and GenNamedTyAppAux (amap:ImportMap) m tyenv ptrsOK tcref 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 - elif ptrsOK = PtrTypesOK && tyconRefEq g tcref g.voidptr_tcr then - GenNamedTyAppAux amap m tyenv ptrsOK g.voidptr_tcr tinst else #if !NO_EXTENSIONTYPING match tcref.TypeReprInfo with diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 43ff8e361a..e48a29fbae 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -560,7 +560,9 @@ let tryNormalizeMeasureInType g ty = // Some basic type builders //--------------------------------------------------------------------------- -let mkVoidPtrTy (g:TcGlobals) = TType_app (g.voidptr_tcr, []) +let mkVoidPtrTy (g:TcGlobals) = + assert env.g.voidptr_tcr.CanDeref + TType_app (g.voidptr_tcr, []) let mkNativePtrTy (g:TcGlobals) ty = TType_app (g.nativeptr_tcr, [ty]) let mkByrefTy (g:TcGlobals) ty = TType_app (g.byref_tcr, [ty]) diff --git a/src/fsharp/import.fs b/src/fsharp/import.fs index b814d3fd69..6c8e1271ba 100644 --- a/src/fsharp/import.fs +++ b/src/fsharp/import.fs @@ -169,7 +169,7 @@ let rec ImportILType (env:ImportMap) m tinst typ = ImportTyconRefApp env tcref inst | ILType.Byref ty -> mkByrefTy env.g (ImportILType env m tinst ty) - | ILType.Ptr ILType.Void -> mkVoidPtrTy env.g + | 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) -> @@ -261,7 +261,7 @@ 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 then + if isUnitTy g elemTy || isVoidTy g elemTy && g.voidptr_tcr.CanDeref then mkVoidPtrTy g else mkNativePtrTy g elemTy From 70df8f2ecdefd506d3c4e534f992e423a2a64f63 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 02:52:07 +0100 Subject: [PATCH 04/61] make proto work with previous FSharp.Core --- src/fsharp/TastOps.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index e48a29fbae..c3d1a5f2a3 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -561,7 +561,7 @@ let tryNormalizeMeasureInType g ty = //--------------------------------------------------------------------------- let mkVoidPtrTy (g:TcGlobals) = - assert env.g.voidptr_tcr.CanDeref + assert g.voidptr_tcr.CanDeref TType_app (g.voidptr_tcr, []) let mkNativePtrTy (g:TcGlobals) ty = TType_app (g.nativeptr_tcr, [ty]) let mkByrefTy (g:TcGlobals) ty = TType_app (g.byref_tcr, [ty]) From 016b8ddbd9326e8432989555ec5ca6e98221991f Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 12:15:06 +0100 Subject: [PATCH 05/61] update baselines --- tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs | 2 ++ tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs index c9738c1b8b..8e03c2b6de 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs @@ -3141,6 +3141,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) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs index 27527ff429..5ef8782123 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs @@ -3288,6 +3288,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) From 35c2517257eee70ab5f78b140e4090719102e8ab Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 13:48:13 +0100 Subject: [PATCH 06/61] integrate code cleanup --- src/absil/il.fs | 3 --- src/fsharp/Optimizer.fs | 7 ------- 2 files changed, 10 deletions(-) diff --git a/src/absil/il.fs b/src/absil/il.fs index eedbdb36c3..af43db3b60 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -713,11 +713,8 @@ and [] member x.IsTyvar = match x with | ILType.TypeVar _ -> true | _ -> false -<<<<<<< HEAD override x.ToString() = x.QualifiedName -======= ->>>>>>> 0fd7cdf6f6df77d7d4dbb81a1943ab90f11bd16f and [] ILCallingSignature = diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 6a4cfcac7c..2d53df370e 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -1261,17 +1261,10 @@ and OpHasEffect g m op = | TOp.Recd (ctor, tcref) -> match ctor with | RecdExprIsObjInit -> true -<<<<<<< HEAD | RecdExpr -> not (isRecdOrStructTyconRefReadOnly g m tcref) | TOp.UnionCase ucref -> isRecdOrUnionOrStructTyconRefDefinitelyMutable ucref.TyconRef | TOp.ExnConstr ecref -> isExnDefinitelyMutable ecref | TOp.Bytes _ | TOp.UInt16s _ | TOp.Array -> true // mutable -======= - | RecdExpr -> isRecdOrUnionOrStructTyconRefDefinitelyMutable g tcref - | TOp.UnionCase ucref -> isRecdOrUnionOrStructTyconRefDefinitelyMutable g ucref.TyconRef - | TOp.ExnConstr ecref -> isExnDefinitelyMutable ecref - | TOp.Bytes _ | TOp.UInt16s _ | TOp.Array -> true (* alloc observable *) ->>>>>>> 0fd7cdf6f6df77d7d4dbb81a1943ab90f11bd16f | TOp.UnionCaseTagGet _ -> false | TOp.UnionCaseProof _ -> false | TOp.UnionCaseFieldGet (ucref, n) -> isUnionCaseFieldMutable g ucref n From e9cba694850e1f12beb7c4db266f84410a4bb3ea Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 13:49:42 +0100 Subject: [PATCH 07/61] integrate code cleanup --- src/fsharp/tast.fs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index 877566ad57..bb8fe0636a 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -448,9 +448,6 @@ type EntityFlags(flags:int64) = /// Get the flags as included in the F# binary metadata member x.PickledBits = (flags &&& ~~~0b000001111000100L) - /// Get the flags as included in the F# binary metadata - member x.PickledBits = (flags &&& ~~~0b000000000000100L) - #if DEBUG assert (sizeof = 8) @@ -4699,8 +4696,6 @@ and [] override __.ToString() = "ModuleOrNamespaceBinding(...)" ->>>>>>> 0fd7cdf6f6df77d7d4dbb81a1943ab90f11bd16f - /// Represents a complete typechecked implementation file, including its typechecked signature if any. /// /// TImplFile(qualifiedNameOfFile,pragmas,implementationExpressionWithSignature,hasExplicitEntryPoint,isScript) From ead3008e62aaccbc4b847a7e872b73d339318c97 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 13:56:34 +0100 Subject: [PATCH 08/61] integrate code cleanup --- src/absil/illib.fs | 6 ------ src/fsharp/CompileOps.fs | 2 +- src/fsharp/CompileOptions.fs | 24 ++++++++++++------------ src/fsharp/IlxGen.fs | 4 ++-- src/fsharp/NameResolution.fs | 2 +- src/fsharp/PostInferenceChecks.fs | 2 +- src/fsharp/TastOps.fs | 24 ++++++++++++------------ src/fsharp/symbols/Symbols.fs | 4 ++-- src/fsharp/tast.fs | 14 +++++++------- 9 files changed, 38 insertions(+), 44 deletions(-) diff --git a/src/absil/illib.fs b/src/absil/illib.fs index e938097e31..a1adb372e9 100644 --- a/src/absil/illib.fs +++ b/src/absil/illib.fs @@ -43,12 +43,6 @@ let inline isNonNull x = not (isNull x) let inline nonNull msg x = if isNull x then failwith ("null: " + msg) else x let inline (===) x y = LanguagePrimitives.PhysicalEquality x y -// Singletons -let someTrue = Some true -let someFalse = Some false -let someBool b = if b then someTrue else someFalse -let someUnit = Some () - //--------------------------------------------------------------------- // Library: ReportTime //--------------------------------------------------------------------- diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index 8ab5c36d08..c9010003ba 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -3032,7 +3032,7 @@ type TcConfig private (data : TcConfigBuilder, validate:bool) = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter let lower = String.lowercase filename let lightOnByDefault = List.exists (Filename.checkSuffix lower) FSharpLightSyntaxFileSuffixes - if lightOnByDefault then (tcConfig.light <> Some(false)) else (tcConfig.light = someTrue ) + if lightOnByDefault then (tcConfig.light <> Some(false)) else (tcConfig.light = Some(true) ) member tcConfig.GetAvailableLoadedSources() = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter diff --git a/src/fsharp/CompileOptions.fs b/src/fsharp/CompileOptions.fs index f24659fddb..5969e38fc8 100644 --- a/src/fsharp/CompileOptions.fs +++ b/src/fsharp/CompileOptions.fs @@ -396,18 +396,18 @@ let setFlag r n = | _ -> raise (Failure "expected 0/1") let SetOptimizeOff(tcConfigB : TcConfigBuilder) = - tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = someFalse } - tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = someFalse } - tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = someFalse } + tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some false } + tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false } + tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some false } tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 0 } tcConfigB.doDetuple <- false; tcConfigB.doTLR <- false; tcConfigB.doFinalSimplify <- false; let SetOptimizeOn(tcConfigB : TcConfigBuilder) = - tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = someTrue } - tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = someTrue } - tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = someTrue } + tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some true } + tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true } + tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some true } tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 6 } tcConfigB.doDetuple <- true; tcConfigB.doTLR <- true; @@ -943,8 +943,8 @@ let deprecatedFlagsFsc tcConfigB = deprecatedFlagsBoth tcConfigB @ [ cliRootFlag tcConfigB - CompilerOption("jit-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = someTrue }), Some(DeprecatedCommandLineOptionNoDescription("--jit-optimize", rangeCmdArgs)), None) - CompilerOption("no-jit-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = someFalse }), Some(DeprecatedCommandLineOptionNoDescription("--no-jit-optimize", rangeCmdArgs)), None) + CompilerOption("jit-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some true }), Some(DeprecatedCommandLineOptionNoDescription("--jit-optimize", rangeCmdArgs)), None) + CompilerOption("no-jit-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some false }), Some(DeprecatedCommandLineOptionNoDescription("--no-jit-optimize", rangeCmdArgs)), None) CompilerOption("jit-tracking", tagNone, OptionUnit (fun _ -> (tcConfigB.jitTracking <- true) ), Some(DeprecatedCommandLineOptionNoDescription("--jit-tracking", rangeCmdArgs)), None) CompilerOption("no-jit-tracking", tagNone, OptionUnit (fun _ -> (tcConfigB.jitTracking <- false) ), Some(DeprecatedCommandLineOptionNoDescription("--no-jit-tracking", rangeCmdArgs)), None) CompilerOption("progress", tagNone, OptionUnit (fun () -> progress := true), Some(DeprecatedCommandLineOptionNoDescription("--progress", rangeCmdArgs)), None) @@ -954,10 +954,10 @@ let deprecatedFlagsFsc tcConfigB = (compilingFsLibNoBigIntFlag tcConfigB) CompilerOption("version", tagString, OptionString (fun s -> tcConfigB.version <- VersionString s), Some(DeprecatedCommandLineOptionNoDescription("--version", rangeCmdArgs)), None) // "--clr-mscorlib", OptionString (fun s -> warning(Some(DeprecatedCommandLineOptionNoDescription("--clr-mscorlib", rangeCmdArgs))) tcConfigB.Build.mscorlib_assembly_name <- s), "\n\tThe name of mscorlib on the target CLR" - CompilerOption("local-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = someTrue }), Some(DeprecatedCommandLineOptionNoDescription("--local-optimize", rangeCmdArgs)), None) - CompilerOption("no-local-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = someFalse }), Some(DeprecatedCommandLineOptionNoDescription("--no-local-optimize", rangeCmdArgs)), None) - CompilerOption("cross-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = someTrue }), Some(DeprecatedCommandLineOptionNoDescription("--cross-optimize", rangeCmdArgs)), None) - CompilerOption("no-cross-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = someFalse }), Some(DeprecatedCommandLineOptionNoDescription("--no-cross-optimize", rangeCmdArgs)), None) + CompilerOption("local-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true }), Some(DeprecatedCommandLineOptionNoDescription("--local-optimize", rangeCmdArgs)), None) + CompilerOption("no-local-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false }), Some(DeprecatedCommandLineOptionNoDescription("--no-local-optimize", rangeCmdArgs)), None) + CompilerOption("cross-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some true }), Some(DeprecatedCommandLineOptionNoDescription("--cross-optimize", rangeCmdArgs)), None) + CompilerOption("no-cross-optimize", tagNone, OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some false }), Some(DeprecatedCommandLineOptionNoDescription("--no-cross-optimize", rangeCmdArgs)), None) CompilerOption("no-string-interning", tagNone, OptionUnit (fun () -> tcConfigB.internConstantStrings <- false), Some(DeprecatedCommandLineOptionNoDescription("--no-string-interning", rangeCmdArgs)), None) CompilerOption("statistics", tagNone, OptionUnit (fun () -> tcConfigB.stats <- true), Some(DeprecatedCommandLineOptionNoDescription("--statistics", rangeCmdArgs)), None) CompilerOption("generate-filter-blocks", tagNone, OptionUnit (fun () -> tcConfigB.generateFilterBlocks <- true), Some(DeprecatedCommandLineOptionNoDescription("--generate-filter-blocks", rangeCmdArgs)), None) diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index fe4f7edf82..c424eb3124 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -6287,7 +6287,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = isEmptyStruct && cenv.opts.workAroundReflectionEmitBugs && not tycon.TyparsNoRange.IsEmpty // Compute a bunch of useful things for each field - let isCLIMutable = (TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_CLIMutableAttribute tycon.Attribs = someTrue) + let isCLIMutable = (TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_CLIMutableAttribute tycon.Attribs = Some true) let fieldSummaries = [ for fspec in tycon.AllFieldsAsList do @@ -6493,7 +6493,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon:Tycon) = // FSharp 1.0 bug 1988: Explicitly setting the ComVisible(true) attribute on an F# type causes an F# record to be emitted in a way that enables mutation for COM interop scenarios // FSharp 3.0 feature: adding CLIMutable to a record type causes emit of default constructor, and all fields get property setters // Records that are value types do not create a default constructor with CLIMutable or ComVisible - if not isStructRecord && (isCLIMutable || (TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_ComVisibleAttribute tycon.Attribs = someTrue)) then + if not isStructRecord && (isCLIMutable || (TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_ComVisibleAttribute tycon.Attribs = Some true)) then yield mkILSimpleStorageCtor(None, Some cenv.g.ilg.typ_Object.TypeSpec, ilThisTy, [], [], reprAccess) if not (tycon.HasMember cenv.g "ToString" []) then diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index 66abfbcc56..ce0d34a1c2 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -771,7 +771,7 @@ let rec AddModuleOrNamespaceRefsToNameEnv g amap m root ad nenv (modrefs: Module nenv.eFullyQualifiedModulesAndNamespaces } let nenv = (nenv,modrefs) ||> List.fold (fun nenv modref -> - if modref.IsModule && TryFindFSharpBoolAttribute g g.attrib_AutoOpenAttribute modref.Attribs = someTrue then + if modref.IsModule && TryFindFSharpBoolAttribute g g.attrib_AutoOpenAttribute modref.Attribs = Some true then AddModuleOrNamespaceContentsToNameEnv g amap ad m false nenv modref else nenv) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 40e4c799be..8b5defac60 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -1641,7 +1641,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = for f in tycon.AllInstanceFieldsAsList do // Check if it's marked unsafe let zeroInitUnsafe = TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_DefaultValueAttribute f.FieldAttribs - if zeroInitUnsafe = someTrue then + if zeroInitUnsafe = Some(true) then let ty' = generalizedTyconRef (mkLocalTyconRef tycon) if not (TypeHasDefaultValue cenv.g m ty') then errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m)) diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index d46ac3d7f8..b74f529e80 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -2826,16 +2826,16 @@ let TryBindTyconRefAttribute g (m:range) (AttribInfo (atref, _) as args) (tcref: let TryFindTyconRefBoolAttribute g m attribSpec tcref = TryBindTyconRefAttribute g m attribSpec tcref (function - | ([ ], _) -> someTrue - | ([ILAttribElem.Bool (v) ], _) -> someBool v + | ([ ], _) -> Some true + | ([ILAttribElem.Bool (v) ], _) -> Some v | _ -> None) (function - | (Attrib(_, _, [ ], _, _, _, _)) -> someTrue - | (Attrib(_, _, [ AttribBoolArg v ], _, _, _, _)) -> someBool v + | (Attrib(_, _, [ ], _, _, _, _)) -> Some true + | (Attrib(_, _, [ AttribBoolArg v ], _, _, _, _)) -> Some v | _ -> None) (function - | ([ ], _) -> someTrue - | ([ Some ((:? bool as v) : obj) ], _) -> someBool v + | ([ ], _) -> Some true + | ([ Some ((:? bool as v) : obj) ], _) -> Some v | _ -> None) let TryFindAttributeUsageAttribute g m tcref = @@ -2857,9 +2857,9 @@ let TryFindTyconRefStringAttribute g m attribSpec tcref = /// Check if a type definition has a specific attribute let TyconRefHasAttribute g m attribSpec tcref = TryBindTyconRefAttribute g m attribSpec tcref - (fun _ -> someUnit) - (fun _ -> someUnit) - (fun _ -> someUnit) + (fun _ -> Some ()) + (fun _ -> Some ()) + (fun _ -> Some ()) |> Option.isSome let isByrefLikeTyconRef g m (tcref: TyconRef) = @@ -7302,7 +7302,7 @@ let TypeNullIsExtraValue g m ty = false else // Putting AllowNullLiteralAttribute(true) on an F# type means 'null' can be used with that type - isAppTy g ty && TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute (tcrefOfAppTy g ty) = someTrue + isAppTy g ty && TryFindTyconRefBoolAttribute g m g.attrib_AllowNullLiteralAttribute (tcrefOfAppTy g ty) = Some(true) let TypeNullIsTrueValue g ty = (match tryDestAppTy g ty with @@ -7460,7 +7460,7 @@ let isSealedTy g ty = if (isFSharpInterfaceTy g ty || isFSharpClassTy g ty) then let tcref, _ = destAppTy g ty - (TryFindFSharpBoolAttribute g g.attrib_SealedAttribute tcref.Attribs = someTrue) + (TryFindFSharpBoolAttribute g g.attrib_SealedAttribute tcref.Attribs = Some(true)) else // All other F# types, array, byref, tuple types are sealed true @@ -7469,7 +7469,7 @@ let isComInteropTy g ty = let tcr, _ = destAppTy g ty match g.attrib_ComImportAttribute with | None -> false - | Some attr -> TryFindFSharpBoolAttribute g attr tcr.Attribs = someTrue + | Some attr -> TryFindFSharpBoolAttribute g attr tcr.Attribs = Some(true) let ValSpecIsCompiledAsInstance g (v:Val) = match v.MemberInfo with diff --git a/src/fsharp/symbols/Symbols.fs b/src/fsharp/symbols/Symbols.fs index 46ca9ef7ad..555f216409 100644 --- a/src/fsharp/symbols/Symbols.fs +++ b/src/fsharp/symbols/Symbols.fs @@ -201,9 +201,9 @@ type FSharpSymbol(cenv: SymbolEnv, item: (unit -> Item), access: (FSharpSymbol - member x.DeclarationLocation = SymbolHelpers.rangeOfItem cenv.g None x.Item - member x.ImplementationLocation = SymbolHelpers.rangeOfItem cenv.g someFalse x.Item + member x.ImplementationLocation = SymbolHelpers.rangeOfItem cenv.g (Some(false)) x.Item - member x.SignatureLocation = SymbolHelpers.rangeOfItem cenv.g someTrue x.Item + member x.SignatureLocation = SymbolHelpers.rangeOfItem cenv.g (Some(true)) x.Item member x.IsEffectivelySameAs(y:FSharpSymbol) = x.Equals(y) || ItemsAreEffectivelyEqual cenv.g x.Item y.Item diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index bb8fe0636a..52395e5178 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -233,7 +233,7 @@ type ValFlags(flags:int64) = member x.MakesNoCriticalTailcalls = (flags &&& 0b0000010000000000000L) <> 0L - member x.WithTakesNoCriticalTailcalls = ValFlags(flags ||| 0b0000010000000000000L) + member x.WithMakesNoCriticalTailcalls = ValFlags(flags ||| 0b0000010000000000000L) member x.PermitsExplicitTypeInstantiation = (flags &&& 0b0000100000000000000L) <> 0L @@ -2804,7 +2804,7 @@ and [] member x.SetIsMemberOrModuleBinding() = x.val_flags <- x.val_flags.WithIsMemberOrModuleBinding - member x.SetMakesNoCriticalTailcalls() = x.val_flags <- x.val_flags.WithTakesNoCriticalTailcalls + member x.SetMakesNoCriticalTailcalls() = x.val_flags <- x.val_flags.WithMakesNoCriticalTailcalls member x.SetHasBeenReferenced() = x.val_flags <- x.val_flags.WithHasBeenReferenced @@ -4679,7 +4679,7 @@ and ModuleOrNamespaceExpr = /// Indicates the module fragment is a 'rec' or 'non-rec' definition of types and modules | TMDefRec of isRec:bool * Tycon list * ModuleOrNamespaceBinding list * range - override __.ToString() = "ModuleOrNamespaceExpr(...)" + override x.ToString() = "ModuleOrNamespaceExpr(...)" /// A named module-or-namespace-fragment definition and [] @@ -4702,14 +4702,14 @@ and [] and TypedImplFile = | TImplFile of QualifiedNameOfFile * ScopedPragma list * ModuleOrNamespaceExprWithSig * bool * bool - override __.ToString() = "TImplFile(...)" + override x.ToString() = "TImplFile(...)" /// Represents a complete typechecked assembly, made up of multiple implementation files. /// and TypedAssemblyAfterOptimization = | TypedAssemblyAfterOptimization of (TypedImplFile * (* optimizeDuringCodeGen: *) (Expr -> Expr)) list - override __.ToString() = "TypedAssemblyAfterOptimization(...)" + override x.ToString() = "TypedAssemblyAfterOptimization(...)" //--------------------------------------------------------------------------- // Freevars. Computed and cached by later phases (never computed type checking). Cached in terms. Not pickled. @@ -4746,7 +4746,7 @@ and FreeTyvars = /// and we have to check various conditions associated with that. FreeTypars: FreeTypars } - override x.ToString() = sprintf "FreeTyvars(...)" + override x.ToString() = "FreeTyvars(...)" /// Represents an amortized computation of the free variables in an expression and FreeVarsCache = FreeVars cache @@ -4780,7 +4780,7 @@ and FreeVars = /// See FreeTyvars above. FreeTyvars: FreeTyvars } - override x.ToString() = "FreeVars(...)" + override x.ToString() = "FreeVars(...)" /// Specifies the compiled representations of type and exception definitions. Basically /// just an ILTypeRef. Computed and cached by later phases. Stored in From b812351cd6831dcb7fbfa9e7428ee96bf27b6999 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 14:00:26 +0100 Subject: [PATCH 09/61] integrate code cleanup --- src/fsharp/DetupleArgs.fs | 4 ++-- src/fsharp/InnerLambdasToTopLevelFuncs.fs | 7 +++---- src/fsharp/PostInferenceChecks.fs | 2 +- src/fsharp/tast.fs | 8 ++++---- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/fsharp/DetupleArgs.fs b/src/fsharp/DetupleArgs.fs index e9b3ceeff3..4223a98098 100644 --- a/src/fsharp/DetupleArgs.fs +++ b/src/fsharp/DetupleArgs.fs @@ -594,8 +594,8 @@ let eligibleVal g m (v:Val) = not v.IsCompiledAsTopLevel let determineTransforms g (z : GlobalUsageAnalysis.Results) = - let selectTransform f sites = - if not (eligibleVal g Range.rangeStartup 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 diff --git a/src/fsharp/InnerLambdasToTopLevelFuncs.fs b/src/fsharp/InnerLambdasToTopLevelFuncs.fs index 3cb33c39a0..54e304526a 100644 --- a/src/fsharp/InnerLambdasToTopLevelFuncs.fs +++ b/src/fsharp/InnerLambdasToTopLevelFuncs.fs @@ -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 Range.rangeStartup 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 Range.rangeStartup 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 List.filter (fun v -> not (isByrefLikeTy g Range.rangeStartup 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) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 8b5defac60..1f9f05cdb4 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -1102,7 +1102,7 @@ and CheckAttribs cenv env (attribs: Attribs) = |> Seq.map fst |> Seq.toList // Filter for allowMultiple = false - |> List.filter (fun (tcref,m) -> TryFindAttributeUsageAttribute cenv.g m tcref <> someTrue) + |> List.filter (fun (tcref,m) -> TryFindAttributeUsageAttribute cenv.g m tcref <> Some(true)) if cenv.reportErrors then for (tcref,m) in duplicates do diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index 52395e5178..c3be9912da 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -416,8 +416,8 @@ type EntityFlags(flags:int64) = /// These two bits represents the on-demand analysis about whether the entity has the IsByRefLike attribute member x.TryIsByRefLike = (flags &&& 0b000000011000000L) |> function - | 0b000000011000000L -> someTrue - | 0b000000010000000L -> someFalse + | 0b000000011000000L -> Some true + | 0b000000010000000L -> Some false | _ -> None /// Adjust the on-demand analysis about whether the entity has the IsByRefLike attribute @@ -432,8 +432,8 @@ type EntityFlags(flags:int64) = /// These two bits represents the on-demand analysis about whether the entity has the IsReadOnly attribute or is otherwise determined to be a readonly struct member x.TryIsReadOnly = (flags &&& 0b000001100000000L) |> function - | 0b000001100000000L -> someTrue - | 0b000001000000000L -> someFalse + | 0b000001100000000L -> Some true + | 0b000001000000000L -> Some false | _ -> None /// Adjust the on-demand analysis about whether the entity has the IsReadOnly attribute or is otherwise determined to be a readonly struct From 87e48e9818b9e27aaff3927e2e971a37c884e359 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 14:57:58 +0100 Subject: [PATCH 10/61] fix build --- src/fsharp/Optimizer.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 2d53df370e..10e3684a3b 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -1272,7 +1272,7 @@ and OpHasEffect g m op = | 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 = someTrue) + | TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some true) | TOp.ValFieldGetAddr rfref -> rfref.RecdField.IsMutable | TOp.UnionCaseFieldGetAddr _ -> false // union case fields are immutable | TOp.LValueOp (LGetAddr, lv) -> lv.IsMutable From 7e1782b8fff9d272340b1550a0a6cde5e8b3ffcb Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 16:34:10 +0100 Subject: [PATCH 11/61] fix build --- src/fsharp/TypeChecker.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 2cbc6b5eca..c2e1f9f2bd 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -15121,7 +15121,7 @@ module EstablishTypeDefinitionCores = let hasSealedAttr = // The special case is needed for 'unit' because the 'Sealed' attribute is not yet available when this type is defined. if cenv.g.compilingFslib && id.idText = "Unit" then - someTrue + Some true else TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_SealedAttribute attrs let hasMeasureAttr = HasFSharpAttribute cenv.g cenv.g.attrib_MeasureAttribute attrs From 5d19184bfecb40ea4731b83d7c5d017e8b88d71f Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 17:06:12 +0100 Subject: [PATCH 12/61] implicit deref of byref returns --- src/fsharp/ConstraintSolver.fs | 19 +++---------------- src/fsharp/MethodCalls.fs | 19 +++++++++++++++++-- src/fsharp/TastOps.fs | 4 ++++ src/fsharp/TypeChecker.fs | 10 +++++++++- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 01ccd1168c..90ef7984e7 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -1884,7 +1884,6 @@ and CanMemberSigsMatchUpToCheck let minst = calledMeth.CalledTyArgs let uminst = calledMeth.CallerTyArgs let callerObjArgTys = calledMeth.CallerObjArgTys - let methodRetTy = calledMeth.ReturnType let assignedItemSetters = calledMeth.AssignedItemSetters let unnamedCalledOptArgs = calledMeth.UnnamedCalledOptArgs let unnamedCalledOutArgs = calledMeth.UnnamedCalledOutArgs @@ -1949,13 +1948,7 @@ and CanMemberSigsMatchUpToCheck | Some _ when minfo.IsConstructor -> CompleteD | Some _ when not alwaysCheckReturn && isNil unnamedCalledOutArgs -> CompleteD | Some reqdRetTy -> - let methodRetTy = - if isNil unnamedCalledOutArgs then - methodRetTy - else - let outArgTys = unnamedCalledOutArgs |> List.map (fun calledArg -> destByrefTy g calledArg.CalledArgumentType) - if isUnitTy g methodRetTy then mkRefTupledTy g outArgTys - else mkRefTupledTy g (methodRetTy :: outArgTys) + let methodRetTy = calledMeth.ReturnTypeAfterOutArgTupling unifyTypes reqdRetTy methodRetTy ))))) //------------------------------------------------------------------------- @@ -2445,14 +2438,8 @@ and ResolveOverloading | None -> CompleteD | Some _ when calledMeth.Method.IsConstructor -> CompleteD | Some reqdRetTy -> - let methodRetTy = - if isNil calledMeth.UnnamedCalledOutArgs then - calledMeth.ReturnType - else - let outArgTys = calledMeth.UnnamedCalledOutArgs |> List.map (fun calledArg -> destByrefTy g calledArg.CalledArgumentType) - if isUnitTy g calledMeth.ReturnType then mkRefTupledTy g outArgTys - else mkRefTupledTy g (calledMeth.ReturnType :: outArgTys) - MustUnify csenv ndeep trace cxsln reqdRetTy methodRetTy) + let actualRetTy = calledMeth.ReturnTypeAfterOutArgTupling + MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy) | None -> None, errors diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index 7457763b00..94b3c3a082 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -371,8 +371,23 @@ type CalledMeth<'T> /// The argument analysis for each set of curried arguments member x.ArgSets = argSets - /// return type - member x.ReturnType = methodRetTy + /// raw return type + member x.ReturnTypeBeforeByrefDeref = methodRetTy + + /// return type after implicit deference of byref returns is taken into account + member x.ReturnTypeAfterByrefDeref = + let retTy = x.ReturnTypeBeforeByrefDeref + 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.ReturnTypeAfterByrefDeref + if isNil unnamedCalledOutArgs then + retTy + else + let outArgTys = unnamedCalledOutArgs |> List.map (fun calledArg -> destByrefTy g calledArg.CalledArgumentType) + if isUnitTy g retTy then mkRefTupledTy g outArgTys + else mkRefTupledTy g (retTy :: outArgTys) /// named setters member x.AssignedItemSetters = assignedNamedProps diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index b74f529e80..e35e789a89 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -5705,6 +5705,10 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress else error(Error(FSComp.SR.tastValueMustBeLocalAndMutable(), m)); + // LVALUE: "&meth(args)" where meth has a byref return. Includes "&span.[idx]". + | Expr.Let(TBind(v, e, _), Expr.Op(TOp.LValueOp (LByrefGet, v2), _, _, _), _, _) when isByrefTy g v.Type && (valRefEq g (mkLocalValRef v) v2) -> + None, e + | _ -> let ty = tyOfExpr g e if isStructTy g ty then diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index c2e1f9f2bd..678f10e8d9 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -9931,11 +9931,19 @@ and TcMethodApplication let allArgsCoerced = List.map coerce allArgs - // 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 = From fbebe24661c7ded5a756e588f9295f9da8882b35 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 17:18:31 +0100 Subject: [PATCH 13/61] add tests for Memory, ReadOnlySpan and ReadOnlyMemory --- tests/fsharp/core/span/test.fsx | 136 ++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 tests/fsharp/core/span/test.fsx diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx new file mode 100644 index 0000000000..ef9639c852 --- /dev/null +++ b/tests/fsharp/core/span/test.fsx @@ -0,0 +1,136 @@ +#r @"..\..\..\..\packages\System.Memory.4.5.0-rc1\lib\netstandard2.0\System.Memory.dll" +#r @"C:\Users\dsyme\.nuget\packages\NETStandard.Library.NETFramework\2.0.0-preview2-25405-01\build\net461\ref\netstandard.dll" + + +namespace System.Runtime.CompilerServices +open System + +[] +[] +type IsReadOnlyAttribute() = + inherit System.Attribute() + +[] +[] +type IsByRefLikeAttribute() = + inherit System.Attribute() + +namespace Test + +open System +open System.Runtime.CompilerServices + +[] +type ReadOnlyStruct(count1: int, count2: int) = + member x.Count1 = count1 + member x.Count2 = count2 + +[] +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) = () + let f5 (x: Memory) = () + let f6 (x: ReadOnlySpan) = () + let f7 (x: ReadOnlyMemory) = () + +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) = + let mutable sum = 0 + for i in 0 .. bytes.Length - 1 do + sum <- sum + int bytes.[i] + sum + + let SafeSum2(bytes: Span) = + 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) = + 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) = + 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) = + let mutable sum = 0 + for i in 0 .. bytes.Length - 1 do + sum <- sum + int bytes.[i] + sum + + let SafeSum6(bytes: ReadOnlySpan) = + 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) = + 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) = + 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(100) + let arraySpan = new Span(arrayMemory); + SafeSum(arraySpan)|> printfn "res = %d" + + // native memory + let nativeMemory = Marshal.AllocHGlobal(100); + let nativeSpan = new Span(nativeMemory.ToPointer(), 100); + SafeSum(nativeSpan)|> printfn "res = %d" + Marshal.FreeHGlobal(nativeMemory); + + // stack memory + let mem = NativePtr.stackalloc(100) + let mem2 = mem |> NativePtr.toVoidPtr + let stackSpan = Span(mem2, 100) + SafeSum(stackSpan) |> printfn "res = %d" + f6() +#if NOT_YET +// Allow this: +[] +type ByRefLikeStructWithByrefField(count1: byref, count2: int) = + member x.Count1 = count1 + member x.Count2 = count2 + + +// Disallow this: +[] +type ReadOnlyStruct = + [] + val mutable X : int +#endif + From 48114101b36cffe63e0a0b44517d2aad7e9249b1 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 21:09:17 +0100 Subject: [PATCH 14/61] fix tests --- src/fsharp/TypeChecker.fs | 55 ++++++++++++-------- tests/fsharp/core/byrefs/test.fsx | 86 +++++++++++++++++++++---------- 2 files changed, 93 insertions(+), 48 deletions(-) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 678f10e8d9..f220903596 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -2898,12 +2898,15 @@ type ApplicableExpr = Expr * // is this the first in an application series bool + member x.Range = match x with | ApplicableExpr (_, e, _) -> e.Range + member x.Type = match x with | ApplicableExpr (cenv, e, _) -> tyOfExpr cenv.g e + member x.SupplyArgument(e2, m) = let (ApplicableExpr (cenv, fe, first)) = x let combinedExpr = @@ -2915,6 +2918,7 @@ type ApplicableExpr = | _ -> Expr.App(fe, tyOfExpr cenv.g fe, [], [e2], m) ApplicableExpr(cenv, combinedExpr, false) + member x.Expr = match x with | ApplicableExpr(_, e, _) -> e @@ -4006,29 +4010,35 @@ 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 = match expr, arg with | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [x0], _), _) , _ when valRefEq cenv.g vf cenv.g.and_vref || valRefEq cenv.g vf cenv.g.and2_vref -> - MakeApplicableExprNoFlex cenv (mkLazyAnd cenv.g m x0 arg) + MakeApplicableExprNoFlex cenv (mkLazyAnd cenv.g m x0 arg), resultTy | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [x0], _), _), _ when valRefEq cenv.g vf cenv.g.or_vref || valRefEq cenv.g vf cenv.g.or2_vref -> - MakeApplicableExprNoFlex cenv (mkLazyOr cenv.g m x0 arg ) + MakeApplicableExprNoFlex cenv (mkLazyOr cenv.g m x0 arg ), resultTy | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ when valRefEq cenv.g vf cenv.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 cenv.g exprty - MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m rtn_ty)) + MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m resultTy)), resultTy | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ when (valRefEq cenv.g vf cenv.g.addrof_vref || valRefEq cenv.g vf cenv.g.addrof2_vref) -> if valRefEq cenv.g vf cenv.g.addrof2_vref then warning(UseOfAddressOfOperator(m)) let wrap, e1a' = mkExprAddrOfExpr cenv.g true false DefinitelyMutates arg (Some(vf)) m - MakeApplicableExprNoFlex cenv (wrap(e1a')) + MakeApplicableExprNoFlex cenv (wrap(e1a')), resultTy + | _ when isByrefTy cenv.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 cenv.g resultTy + MakeApplicableExprNoFlex cenv expr, resultTy | _ -> - expr.SupplyArgument(arg, m) + expr.SupplyArgument(arg, m), resultTy //------------------------------------------------------------------------- // Additional data structures used by type checking @@ -6210,9 +6220,9 @@ 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 fAndArg, 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 ) + Some (PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr fAndArg resultTy ExprAtomicFlag.Atomic delayed ) else None match attemptArrayString with @@ -8296,25 +8306,26 @@ and TcSequenceExpression cenv env tpenv comp overallTy m = delayedExpr, tpenv //------------------------------------------------------------------------- -// Typecheck "expr ... " constructs where "..." is a sequence of applications, -// type applications and dot-notation projections. First extract known -// type information from the "..." part to use during type checking. -// -// 'overallTy' is the type expected for the entire chain of expr + lookups. -// 'exprty' is the type of the expression on the left of the lookup chain. -// -// Unsophisticated applications can propagate information from the expected overall type 'overallTy' -// through to the leading function type 'exprty'. This is because the application -// unambiguously implies a function type //------------------------------------------------------------------------- +/// When checking sequence of function applications, +/// type applications and dot-notation projections, first extract known +/// type information from the applications. +/// +/// 'overallTy' is the type expected for the entire chain of expr + lookups. +/// 'exprty' is the type of the expression on the left of the lookup chain. +/// +/// We propagate information from the expected overall type 'overallTy'. The use +/// 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 = match delayedList with | [] -> // Avoid unifying twice: we're about to unify in TcDelayed - if not (isNil delayed) then + if not (isNil delayed) && not (isByrefTy cenv.g exprty) then + let exprty = if isByrefTy cenv.g exprty then destByrefTy cenv.g exprty else exprty + UnifyTypesAndRecover cenv env mExpr overallTy exprty UnifyTypesAndRecover cenv env mExpr overallTy exprty | DelayedDot :: _ | DelayedSet _ :: _ @@ -8373,7 +8384,7 @@ and TcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag:ExprAtomicF // expr.M(args) where x.M is a .NET method or index property // expr.M where x.M is a .NET method or index property | DelayedDotLookup (longId, mDotLookup) :: otherDelayed -> - TcLookupThen cenv overallTy env tpenv mExpr expr.Expr exprty longId otherDelayed mDotLookup + TcLookupThen cenv overallTy env tpenv mExpr expr.Expr exprty longId otherDelayed mDotLookup // f x | DelayedApp (hpa, arg, mExprAndArg) :: otherDelayed -> TcFunctionApplicationThen cenv overallTy env tpenv mExprAndArg expr exprty arg hpa otherDelayed @@ -8423,7 +8434,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 '{ ... }' diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 6c4f3d960b..b0c8980c05 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -27,11 +27,17 @@ module ByrefReturnTests = let f () = &x let test() = - let addr = f () + let addr : byref = &f() addr <- addr + 1 check2 "cepojcwem1" 2 x + + let test2() = + let res = f() + 1 + check2 "cepojcwem1b" 3 res + test() + test2() module TestMatchReturn = let mutable x = 1 @@ -40,16 +46,23 @@ module ByrefReturnTests = let f inp = match inp with 3 -> &x | _ -> &y let test() = - let addr = f 3 + let addr = &f 3 addr <- addr + 1 check2 "cepojcwem2" 2 x check2 "cepojcwem3" 1 y - let addr = f 4 + let addr = &f 4 addr <- addr + 1 check2 "cepojcwem4" 2 x check2 "cepojcwem5" 2 y + let test2() = + let res = f 3 + let res2 = f 3 + 1 + check2 "cepojcwem2b" 3 res2 + check2 "cepojcwem3b" 2 res + test() + test2() module TestConditionalReturn = let mutable x = 1 @@ -58,16 +71,23 @@ module ByrefReturnTests = let f inp = if inp = 3 then &x else &y let test() = - let addr = f 3 + let addr = &f 3 addr <- addr + 1 check2 "cepojcwem6" 2 x check2 "cepojcwem7" 1 y - let addr = f 4 + let addr = &f 4 addr <- addr + 1 check2 "cepojcwem8" 2 x check2 "cepojcwem9" 2 y + let test2() = + let res = f 3 + let res2 = f 3 + 1 + check2 "cepojcwem8b" 3 res2 + check2 "cepojcwem9b" 2 res + test() + test2() module TestTryCatchReturn = let mutable x = 1 @@ -76,16 +96,23 @@ module ByrefReturnTests = let f inp = try &x with _ -> &y let test() = - let addr = f 3 + let addr = &f 3 addr <- addr + 1 check2 "cepojcwem6b" 2 x check2 "cepojcwem7b" 1 y - let addr = f 4 + let addr = &f 4 addr <- addr + 1 check2 "cepojcwem8b" 3 x check2 "cepojcwem9b" 1 y + let test2() = + let res = f 3 + let res2 = f 3 + 1 + check2 "cepojcwem2ff" 4 res2 + check2 "cepojcwem3gg" 3 res + test() + test2() module TestTryFinallyReturn = let mutable x = 1 @@ -94,16 +121,23 @@ module ByrefReturnTests = let f inp = try &x with _ -> &y let test() = - let addr = f 3 + let addr = &f 3 addr <- addr + 1 check2 "cepojcwem6b" 2 x check2 "cepojcwem7b" 1 y - let addr = f 4 + let addr = &f 4 addr <- addr + 1 check2 "cepojcwem8b" 3 x check2 "cepojcwem9b" 1 y + let test2() = + let res = f 3 + let res2 = f 3 + 1 + check2 "cepojcwem2tf" 4 res2 + check2 "cepojcwem3qw" 3 res + test() + test2() module TestOneArgument = @@ -111,7 +145,7 @@ module ByrefReturnTests = let test() = let mutable r1 = 1 - let addr = f &r1 + let addr = &f &r1 addr <- addr + 1 check2 "cepojcwem10" 2 r1 @@ -124,7 +158,7 @@ module ByrefReturnTests = let test() = let mutable r1 = 1 let mutable r2 = 0 - let addr = f (&r1, &r2) + let addr = &f (&r1, &r2) addr <- addr + 1 check2 "cepojcwem11" 2 r1 @@ -137,7 +171,7 @@ module ByrefReturnTests = let test() = let r = { z = 1 } - let addr = f r + let addr = &f r addr <- addr + 1 check2 "cepojcwem12" 2 r.z @@ -150,7 +184,7 @@ module ByrefReturnTests = let test() = let mutable r = { z = 1 } - let addr = f &r + let addr = &f &r addr <- addr + 1 check2 "cepojcwem13a" 2 r.z @@ -164,7 +198,7 @@ module ByrefReturnTests = let test() = let c = C() - let addr = f c + let addr = &f c addr <- addr + 1 check2 "cepojcwem13b" 1 c.z @@ -176,7 +210,7 @@ module ByrefReturnTests = let test() = let r = [| 1 |] - let addr = f r + let addr = &f r addr <- addr + 1 check2 "cepojcwem14" 2 r.[0] @@ -191,7 +225,7 @@ module ByrefReturnTests = let test() = let mutable r = { z = 1 } - let addr = f &r + let addr = &f &r addr <- addr + 1 check2 "cepojcwem15" 2 r.z @@ -211,12 +245,12 @@ module ByrefReturnTests = { new I with member this.M() = &x } - let f (i:I) = i.M() + let f (i:I) = &i.M() let test() = - let addr = f (C()) + let addr = &f (C()) addr <- addr + 1 - let addr = f (ObjExpr()) + let addr = &f (ObjExpr()) addr <- addr + 1 check2 "cepojcwem16" 3 x @@ -236,12 +270,12 @@ module ByrefReturnTests = { new I with member this.P = &x } - let f (i:I) = i.P + let f (i:I) = &i.P let test() = - let addr = f (C()) + let addr = &f (C()) addr <- addr + 1 - let addr = f (ObjExpr()) + let addr = &f (ObjExpr()) addr <- addr + 1 check2 "cepojcwem17" 3 x @@ -254,10 +288,10 @@ module ByrefReturnTests = let d() = D(fun () -> &x) - let f (d:D) = d.Invoke() + let f (d:D) = &d.Invoke() let test() = - let addr = f (d()) + let addr = &f (d()) check2 "cepojcwem18a" 1 x addr <- addr + 1 check2 "cepojcwem18b" 2 x @@ -284,10 +318,10 @@ module ByrefReturnTests = let d() = D(fun xb -> &xb) - let f (d:D) = d.Invoke(&x) + let f (d:D) = &d.Invoke(&x) let test() = - let addr = f (d()) + let addr = &f (d()) check2 "cepojcwem18a2" 1 x addr <- addr + 1 check2 "cepojcwem18b3" 2 x From bf6638516947199f874491f1145b3f4b36852b5a Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 22:50:19 +0100 Subject: [PATCH 15/61] simplify diff --- src/fsharp/TypeChecker.fs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index f220903596..5915119444 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -8323,7 +8323,7 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = match delayedList with | [] -> // Avoid unifying twice: we're about to unify in TcDelayed - if not (isNil delayed) && not (isByrefTy cenv.g exprty) then + if not (isNil delayed) then let exprty = if isByrefTy cenv.g exprty then destByrefTy cenv.g exprty else exprty UnifyTypesAndRecover cenv env mExpr overallTy exprty UnifyTypesAndRecover cenv env mExpr overallTy exprty @@ -14130,7 +14130,7 @@ module TyconConstraintInference = // If the type was excluded, say why if not res then match TryFindFSharpBoolAttribute g g.attrib_StructuralComparisonAttribute tycon.Attribs with - | Some true -> + | Some(true) -> match structuralTypes |> List.tryFind (fst >> checkIfFieldTypeSupportsComparison tycon >> not) with | None -> assert false @@ -15151,7 +15151,7 @@ module EstablishTypeDefinitionCores = let hasCLIMutable = HasFSharpAttribute cenv.g cenv.g.attrib_CLIMutableAttribute attrs let structLayoutAttr = TryFindFSharpInt32Attribute cenv.g cenv.g.attrib_StructLayoutAttribute attrs - let hasAllowNullLiteralAttr = TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_AllowNullLiteralAttribute attrs = Some true + let hasAllowNullLiteralAttr = TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_AllowNullLiteralAttribute attrs = Some(true) if hasAbstractAttr then tycon.TypeContents.tcaug_abstract <- true @@ -15185,7 +15185,7 @@ module EstablishTypeDefinitionCores = let hiddenReprChecks(hasRepr) = structLayoutAttributeCheck(false) - if hasSealedAttr = Some(false) || (hasRepr && hasSealedAttr <> Some true && not (id.idText = "Unit" && cenv.g.compilingFslib) ) then + if hasSealedAttr = Some false || (hasRepr && hasSealedAttr <> Some(true) && not (id.idText = "Unit" && cenv.g.compilingFslib) ) then errorR(Error(FSComp.SR.tcRepresentationOfTypeHiddenBySignature(), m)) if hasAbstractAttr then errorR (Error(FSComp.SR.tcOnlyClassesCanHaveAbstract(), m)) @@ -15375,7 +15375,7 @@ module EstablishTypeDefinitionCores = TTyconStruct | TyconInterface -> - if hasSealedAttr = Some true then errorR (Error(FSComp.SR.tcInterfaceTypesCannotBeSealed(), m)) + if hasSealedAttr = Some(true) then errorR (Error(FSComp.SR.tcInterfaceTypesCannotBeSealed(), m)) noCLIMutableAttributeCheck() structLayoutAttributeCheck(false) noAbstractClassAttributeCheck() From 05c3ba0418a28c1d251554571b24dbe2a141abe1 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 23:11:07 +0100 Subject: [PATCH 16/61] simplify diff --- src/fsharp/PostInferenceChecks.fs | 11 +++++------ src/fsharp/TypeChecker.fs | 6 +++--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 1f9f05cdb4..1e73a6abc3 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -1150,7 +1150,6 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = let nm = v.DisplayName errorR(Error(FSComp.SR.chkMemberUsedInInvalidWay(nm, nm, stringOfRange m), v.Range)) - let m = v.Range // Byrefs allowed for x in 'let x = ...' v.Type |> CheckTypePermitByrefs cenv env v.Range v.Attribs |> CheckAttribs cenv env @@ -1159,7 +1158,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = // Check accessibility if (v.IsMemberOrModuleBinding || v.IsMember) && not v.IsIncrClassGeneratedMember then let access = AdjustAccess (IsHiddenVal env.sigToImplRemapInfo v) (fun () -> v.TopValDeclaringEntity.CompilationPath) v.Accessibility - CheckTypeForAccess cenv env (fun () -> NicePrint.stringOfQualifiedValOrMember cenv.denv v) access m v.Type + CheckTypeForAccess cenv env (fun () -> NicePrint.stringOfQualifiedValOrMember cenv.denv v) access v.Range v.Type let env = if v.IsConstructor && not v.IsIncrClassConstructor then { env with limited=true } else env @@ -1168,7 +1167,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = // Check top-level let-bound values match bind.Var.ValReprInfo with | Some info when info.HasNoArgs -> - CheckForByrefLikeType cenv env m v.Type (fun () -> errorR(Error(FSComp.SR.chkNoByrefAsTopValue(),m))) + CheckForByrefLikeType cenv env v.Range v.Type (fun () -> errorR(Error(FSComp.SR.chkNoByrefAsTopValue(),v.Range))) | _ -> () if Option.isSome v.PublicPath then @@ -1187,7 +1186,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = HasFSharpAttribute cenv.g cenv.g.attrib_ReflectedDefinitionAttribute v.TopValDeclaringEntity.Attribs) then if v.IsInstanceMember && v.MemberApparentEntity.IsStructOrEnumTycon then - errorR(Error(FSComp.SR.chkNoReflectedDefinitionOnStructMember(),m)) + errorR(Error(FSComp.SR.chkNoReflectedDefinitionOnStructMember(),v.Range)) cenv.usesQuotations <- true // If we've already recorded a definition then skip this @@ -1209,7 +1208,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = QuotationTranslator.ConvExprPublic qscope env taue |> ignore let _,_,argExprs = qscope.Close() if not (isNil argExprs) then - errorR(Error(FSComp.SR.chkReflectedDefCantSplice(), m)) + errorR(Error(FSComp.SR.chkReflectedDefCantSplice(), v.Range)) QuotationTranslator.ConvMethodBase qscope env (v.CompiledName, v) |> ignore with | QuotationTranslator.InvalidQuotedTerm e -> @@ -1229,7 +1228,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = let topValInfo = match bind.Var.ValReprInfo with Some info -> info | _ -> ValReprInfo.emptyValData - CheckLambdas isTop v.MemberInfo cenv env v.MustInline topValInfo alwaysCheckNoReraise bindRhs m v.Type + CheckLambdas isTop v.MemberInfo cenv env v.MustInline topValInfo alwaysCheckNoReraise bindRhs v.Range v.Type and CheckBindings cenv env xs = List.iter (CheckBinding cenv env false) xs diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 5915119444..556732d623 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -15185,7 +15185,7 @@ module EstablishTypeDefinitionCores = let hiddenReprChecks(hasRepr) = structLayoutAttributeCheck(false) - if hasSealedAttr = Some false || (hasRepr && hasSealedAttr <> Some(true) && not (id.idText = "Unit" && cenv.g.compilingFslib) ) then + if hasSealedAttr = Some(false) || (hasRepr && hasSealedAttr <> Some(true) && not (id.idText = "Unit" && cenv.g.compilingFslib) ) then errorR(Error(FSComp.SR.tcRepresentationOfTypeHiddenBySignature(), m)) if hasAbstractAttr then errorR (Error(FSComp.SR.tcOnlyClassesCanHaveAbstract(), m)) @@ -15197,7 +15197,7 @@ module EstablishTypeDefinitionCores = if hasCLIMutable then errorR (Error(FSComp.SR.tcThisTypeMayNotHaveACLIMutableAttribute(), m)) let noSealedAttributeCheck(k) = - if hasSealedAttr = Some true then errorR (Error(k(), m)) + if hasSealedAttr = Some(true) then errorR (Error(k(), m)) let noFieldsCheck(fields':RecdField list) = match fields' with @@ -15272,7 +15272,7 @@ module EstablishTypeDefinitionCores = TNoRepr, None, NoSafeInitInfo | SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, rhsType, _) -> - if hasSealedAttr = Some true then + if hasSealedAttr = Some(true) then errorR (Error(FSComp.SR.tcAbbreviatedTypesCannotBeSealed(), m)) noAbstractClassAttributeCheck() noAllowNullLiteralAttributeCheck() From 7dee3e74a39f7ea1e7ec357f880fcda0043256f7 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 12 May 2018 23:18:43 +0100 Subject: [PATCH 17/61] remove duplicate error messages --- src/fsharp/TypeChecker.fs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index c80ea7d364..f150883bf1 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -6156,9 +6156,9 @@ 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 fAndArg, resultTy = buildApp cenv (MakeApplicableExprNoFlex cenv f) resultTy 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 fAndArg resultTy ExprAtomicFlag.Atomic delayed ) + Some (PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr f' resultTy ExprAtomicFlag.Atomic delayed ) else None match attemptArrayString with @@ -8262,7 +8262,6 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = if not (isNil delayed) then let exprty = if isByrefTy cenv.g exprty then destByrefTy cenv.g exprty else exprty UnifyTypesAndRecover cenv env mExpr overallTy exprty - UnifyTypesAndRecover cenv env mExpr overallTy exprty | DelayedDot :: _ | DelayedSet _ :: _ | DelayedDotLookup _ :: _ -> () From bfcb9c81ce979f02b718c1cfb31aedfd204f659b Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sun, 13 May 2018 00:13:30 +0100 Subject: [PATCH 18/61] fix build --- src/fsharp/TypeChecker.fs | 57 ++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index f150883bf1..b4945e4973 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -3947,32 +3947,45 @@ let CheckAndRewriteObjectCtor g env (ctorLambaExpr:Expr) = /// Post-typechecking normalizations to enforce semantic constraints /// lazy and, lazy or, rethrow, address-of 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 cenv.g vf cenv.g.and_vref - || valRefEq cenv.g vf cenv.g.and2_vref -> - MakeApplicableExprNoFlex cenv (mkLazyAnd cenv.g m x0 arg), resultTy + when valRefEq g vf g.and_vref + || valRefEq g vf g.and2_vref -> + 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 cenv.g vf cenv.g.or_vref - || valRefEq cenv.g vf cenv.g.or2_vref -> - MakeApplicableExprNoFlex cenv (mkLazyOr cenv.g m x0 arg ), resultTy + when valRefEq g vf g.or_vref + || valRefEq g vf g.or2_vref -> + 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 cenv.g vf cenv.g.reraise_vref -> + when valRefEq g vf g.reraise_vref -> // exprty is of type: "unit -> 'a". Break it and store the 'a type here, used later as return type. MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m resultTy)), resultTy + + // Special rules for building applications of the '&expr' or '&&expr' operators, both of which get the + // address of an expression. | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ - when (valRefEq cenv.g vf cenv.g.addrof_vref || - valRefEq cenv.g vf cenv.g.addrof2_vref) -> - if valRefEq cenv.g vf cenv.g.addrof2_vref then warning(UseOfAddressOfOperator(m)) - let wrap, e1a' = mkExprAddrOfExpr cenv.g true false DefinitelyMutates arg (Some(vf)) m + 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')), resultTy - | _ when isByrefTy cenv.g resultTy -> + + // Special rule for implicitly dereferencing byref return values on dereference + | _ 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 cenv.g resultTy + let resultTy = destByrefTy g resultTy MakeApplicableExprNoFlex cenv expr, resultTy + | _ -> expr.SupplyArgument(arg, m), resultTy @@ -8255,25 +8268,33 @@ 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 stripByrefsOnReturn delayedList mExpr exprty = match delayedList with | [] -> // Avoid unifying twice: we're about to unify in TcDelayed if not (isNil delayed) then - let exprty = if isByrefTy cenv.g exprty then destByrefTy cenv.g exprty else exprty + let exprty = if stripByrefsOnReturn && isByrefTy cenv.g exprty then 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 stripByrefsOnReturn 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 don't strip byrefs off the return type for "&x" and "&&x" + let stripByrefsOnReturn = + match expr with + | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _) when valRefEq cenv.g vf cenv.g.addrof_vref -> false + | _ -> stripByrefsOnReturn + + propagate stripByrefsOnReturn delayedList' mExprAndArg resultTy + | None -> let mArg = arg.Range match arg with @@ -8294,7 +8315,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 true delayed expr.Range exprty and PropagateThenTcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag:ExprAtomicFlag) delayed = Propagate cenv overallTy env tpenv expr exprty delayed From a5218ef22629849d4ac704b5620bb904509b2e81 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sun, 13 May 2018 01:50:06 +0100 Subject: [PATCH 19/61] test updates --- src/fsharp/PostInferenceChecks.fs | 12 +- tests/fsharp/core/span/test.fsx | 288 +++++++++++++++++------------- 2 files changed, 169 insertions(+), 131 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 4bab0ae495..276e9a9727 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -541,7 +541,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = (match v.DeclaringEntity with Parent tcref -> isAbstractTycon tcref.Deref | _ -> false) then errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(),m)) - if isByrefTy cenv.g v.Type && + if isByrefLikeTy cenv.g v.Type && // A byref return location... (match context with PermitByref isReturn -> isReturn | _ -> false) && // The value is a local.... @@ -672,7 +672,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = let isByrefReturnCall = // if return is a byref, and being used as a return, then all arguments must be usable as byref returns match context with - | PermitByref true when isByrefTy cenv.g (tyOfExpr cenv.g expr) -> true + | PermitByref true when isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) -> true | _ -> false CheckExprs cenv env argsl (mkArgsForAppliedExpr isByrefReturnCall f) @@ -767,7 +767,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // if return is a byref, and being used as a return, then all arguments must be usable as byref returns match context,tys with - | PermitByref true, [ty] when isByrefTy cenv.g ty -> CheckExprsPermitByrefReturns cenv env args + | PermitByref true, [ty] when isByrefLikeTy cenv.g ty -> CheckExprsPermitByrefReturns cenv env args | _ -> CheckExprsPermitByrefs cenv env args @@ -937,7 +937,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn | true, firstArg::_ -> firstArg.SetHasBeenReferenced() | _ -> () // any byRef arguments are considered used, as they may be 'out's - restArgs |> List.iter (fun arg -> if isByrefTy cenv.g arg.Type then arg.SetHasBeenReferenced()) + restArgs |> List.iter (fun arg -> if isByrefLikeTy cenv.g arg.Type then arg.SetHasBeenReferenced()) syntacticArgs |> List.iter (CheckValSpec cenv env) syntacticArgs |> List.iter (BindVal cenv env) @@ -954,7 +954,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn CheckNoReraise cenv freesOpt body // Check the body of the lambda - if (not (isNil tps) || not (isNil vsl)) && isTop && not cenv.g.compilingFslib && isByrefTy cenv.g bodyty then + if (not (isNil tps) || not (isNil vsl)) && isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g bodyty then // allow byref to occur as return position for byref-typed top level function or method CheckExprPermitByrefReturn cenv env body else @@ -1465,7 +1465,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = if numCurriedArgSets > 1 && (minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) |> List.existsSquared (fun (ParamData(isParamArrayArg, isOutArg, optArgInfo, callerInfoInfo, _, reflArgInfo, ty)) -> - isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefTy cenv.g ty)) then + isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefLikeTy cenv.g ty)) then errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m)) if numCurriedArgSets = 1 then diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index ef9639c852..d983522137 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -1,136 +1,174 @@ #r @"..\..\..\..\packages\System.Memory.4.5.0-rc1\lib\netstandard2.0\System.Memory.dll" #r @"C:\Users\dsyme\.nuget\packages\NETStandard.Library.NETFramework\2.0.0-preview2-25405-01\build\net461\ref\netstandard.dll" - namespace System.Runtime.CompilerServices -open System -[] -[] -type IsReadOnlyAttribute() = - inherit System.Attribute() + open System + open System.Runtime.CompilerServices + open System.Runtime.InteropServices + [] + [] + type IsReadOnlyAttribute() = + inherit System.Attribute() -[] -[] -type IsByRefLikeAttribute() = - inherit System.Attribute() + [] + [] + type IsByRefLikeAttribute() = + inherit System.Attribute() namespace Test -open System -open System.Runtime.CompilerServices - -[] -type ReadOnlyStruct(count1: int, count2: int) = - member x.Count1 = count1 - member x.Count2 = count2 - -[] -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) = () - let f5 (x: Memory) = () - let f6 (x: ReadOnlySpan) = () - let f7 (x: ReadOnlyMemory) = () - -module Sample1 = - open FSharp.NativeInterop + open System + open System.Runtime.CompilerServices open System.Runtime.InteropServices -// this method does not care what kind of memory it works on - let SafeSum(bytes: Span) = - let mutable sum = 0 - for i in 0 .. bytes.Length - 1 do - sum <- sum + int bytes.[i] - sum - - let SafeSum2(bytes: Span) = - 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) = - 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) = - 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) = - let mutable sum = 0 - for i in 0 .. bytes.Length - 1 do - sum <- sum + int bytes.[i] - sum - - let SafeSum6(bytes: ReadOnlySpan) = - 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) = - 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) = - 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(100) - let arraySpan = new Span(arrayMemory); - SafeSum(arraySpan)|> printfn "res = %d" - - // native memory - let nativeMemory = Marshal.AllocHGlobal(100); - let nativeSpan = new Span(nativeMemory.ToPointer(), 100); - SafeSum(nativeSpan)|> printfn "res = %d" - Marshal.FreeHGlobal(nativeMemory); - - // stack memory - let mem = NativePtr.stackalloc(100) - let mem2 = mem |> NativePtr.toVoidPtr - let stackSpan = Span(mem2, 100) - SafeSum(stackSpan) |> printfn "res = %d" - f6() -#if NOT_YET -// Allow this: -[] -type ByRefLikeStructWithByrefField(count1: byref, count2: int) = - member x.Count1 = count1 - member x.Count2 = count2 - - -// Disallow this: -[] -type ReadOnlyStruct = - [] - val mutable X : int -#endif + + + [] + type ReadOnlyStruct(count1: int, count2: int) = + member x.Count1 = count1 + member x.Count2 = count2 + + [] + 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) = () + let f5 (x: Memory) = () + let f6 (x: ReadOnlySpan) = () + let f7 (x: ReadOnlyMemory) = () + + 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) = + let mutable sum = 0 + for i in 0 .. bytes.Length - 1 do + sum <- sum + int bytes.[i] + sum + + let SafeSum2(bytes: Span) = + 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) = + 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) = + 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) = + let mutable sum = 0 + for i in 0 .. bytes.Length - 1 do + sum <- sum + int bytes.[i] + sum + + let SafeSum6(bytes: ReadOnlySpan) = + 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) = + 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) = + 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(100) + let arraySpan = new Span(arrayMemory); + SafeSum(arraySpan)|> printfn "res = %d" + + // native memory + let nativeMemory = Marshal.AllocHGlobal(100); + let nativeSpan = new Span(nativeMemory.ToPointer(), 100); + SafeSum(nativeSpan)|> printfn "res = %d" + Marshal.FreeHGlobal(nativeMemory); + + // stack memory + let mem = NativePtr.stackalloc(100) + let mem2 = mem |> NativePtr.toVoidPtr + let stackSpan = Span(mem2, 100) + SafeSum(stackSpan) |> printfn "res = %d" + f6() + + module ReadOnlyIn = + + let TestInAttribute1 ([] a: byref) = a + + [] + type Ext = + [] + static member ExtDateTime(dt: DateTime, x:int) = dt.AddDays(double x) + + [] + static member ExtDateTime2([] dt: byref, x:int) = dt.AddDays(double x) + + module UseExt = + let dt = DateTime.Now.ExtDateTime(3) + //let dt2 = DateTime.Now.ExtDateTime2(3) + + +(* + module Negative = + let TestClosure1 ([] a: byref) = id (fun () -> a) + let TestClosure2 ([] a: Span) = id (fun () -> a) + let TestClosure3 ([] a: ReadOnlySpan) = id (fun () -> a) + + let TestAsyncClosure1 ([] a: byref) = async { return a } + let TestAsyncClosure2 ([] a: Span) = async { return a } + let TestAsyncClosure3 ([] a: ReadOnlySpan) = async { return a } +*) + +//Since in parameters are read-only ref parameters, all ref parameter limitations apply. +// +//Cannot apply with an iterator method (I.e. method that has yield statements.) +//Cannot apply with an async method + + + #if NOT_YET + // Allow this: + [] + type ByRefLikeStructWithByrefField(count1: byref, count2: int) = + member x.Count1 = count1 + member x.Count2 = count2 + + + // Disallow this: + [] + type ReadOnlyStruct = + [] + val mutable X : int + #endif From 091a103b65e4079585048bcc01132c612ee5f8b0 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sun, 13 May 2018 04:06:27 +0100 Subject: [PATCH 20/61] fix build --- src/fsharp/PostInferenceChecks.fs | 10 +++++----- tests/fsharp/typeProviders/helloWorld/provided.fs | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 276e9a9727..ac75d84ce9 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -541,7 +541,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = (match v.DeclaringEntity with Parent tcref -> isAbstractTycon tcref.Deref | _ -> false) then errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(),m)) - if isByrefLikeTy cenv.g v.Type && + if isByrefLikeTy cenv.g m v.Type && // A byref return location... (match context with PermitByref isReturn -> isReturn | _ -> false) && // The value is a local.... @@ -672,7 +672,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = let isByrefReturnCall = // if return is a byref, and being used as a return, then all arguments must be usable as byref returns match context with - | PermitByref true when isByrefLikeTy cenv.g (tyOfExpr cenv.g expr) -> true + | PermitByref true when isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) -> true | _ -> false CheckExprs cenv env argsl (mkArgsForAppliedExpr isByrefReturnCall f) @@ -767,7 +767,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // if return is a byref, and being used as a return, then all arguments must be usable as byref returns match context,tys with - | PermitByref true, [ty] when isByrefLikeTy cenv.g ty -> CheckExprsPermitByrefReturns cenv env args + | PermitByref true, [ty] when isByrefLikeTy cenv.g m ty -> CheckExprsPermitByrefReturns cenv env args | _ -> CheckExprsPermitByrefs cenv env args @@ -937,7 +937,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn | true, firstArg::_ -> firstArg.SetHasBeenReferenced() | _ -> () // any byRef arguments are considered used, as they may be 'out's - restArgs |> List.iter (fun arg -> if isByrefLikeTy cenv.g arg.Type then arg.SetHasBeenReferenced()) + restArgs |> List.iter (fun arg -> if isByrefLikeTy cenv.g m arg.Type then arg.SetHasBeenReferenced()) syntacticArgs |> List.iter (CheckValSpec cenv env) syntacticArgs |> List.iter (BindVal cenv env) @@ -954,7 +954,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn CheckNoReraise cenv freesOpt body // Check the body of the lambda - if (not (isNil tps) || not (isNil vsl)) && isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g bodyty then + if (not (isNil tps) || not (isNil vsl)) && isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g m bodyty then // allow byref to occur as return position for byref-typed top level function or method CheckExprPermitByrefReturn cenv env body else diff --git a/tests/fsharp/typeProviders/helloWorld/provided.fs b/tests/fsharp/typeProviders/helloWorld/provided.fs index f3ce98f61d..bcdc86452e 100644 --- a/tests/fsharp/typeProviders/helloWorld/provided.fs +++ b/tests/fsharp/typeProviders/helloWorld/provided.fs @@ -1,5 +1,8 @@ namespace global +[] +do () + type TheGeneratedType1() = member x.Prop1 = 1 static member (+) (x1:TheGeneratedType1,x2:TheGeneratedType1) = x1 From 88654e408748dee4ca571c580a4aa48c3cea655f Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sun, 13 May 2018 04:07:00 +0100 Subject: [PATCH 21/61] fix build --- src/fsharp/PostInferenceChecks.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index ac75d84ce9..d7dab07277 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -1465,7 +1465,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = if numCurriedArgSets > 1 && (minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) |> List.existsSquared (fun (ParamData(isParamArrayArg, isOutArg, optArgInfo, callerInfoInfo, _, reflArgInfo, ty)) -> - isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefLikeTy cenv.g ty)) then + isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefLikeTy cenv.g m ty)) then errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m)) if numCurriedArgSets = 1 then From f29282f8008f5c1e09fc73cce0ce8e674e03f023 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Mon, 14 May 2018 00:05:56 +0100 Subject: [PATCH 22/61] update baselines --- tests/fsharp/typecheck/sigs/neg_byref_17.bsl | 12 ++++++++---- tests/fsharp/typecheck/sigs/neg_byref_22.bsl | 10 ++++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg_byref_17.bsl b/tests/fsharp/typecheck/sigs/neg_byref_17.bsl index 3d857907b8..270d06fbfc 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_17.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_17.bsl @@ -1,6 +1,10 @@ -neg_byref_17.fs(2,5,2,8): typecheck error FS0431: A byref typed value would be stored here. Top-level let-bound byref values are not permitted. +neg_byref_17.fs(2,17,2,27): typecheck error FS0001: This expression was expected to have type + 'byref' +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' +but here has type + 'int' diff --git a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl index 675eefac32..da7df92104 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl @@ -1,4 +1,14 @@ +neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected to have type + 'byref' +but here has type + 'int' + +neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected to have type + 'byref' +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 From fb593457ba6bef06ee696cd3416d3a62e066d7e9 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Mon, 14 May 2018 13:34:50 +0100 Subject: [PATCH 23/61] fix uses of NativePtr.toByRef --- src/fsharp/FSharp.Core/nativeptr.fsi | 2 +- src/fsharp/TcGlobals.fs | 15 ++++++++------- src/fsharp/TypeChecker.fs | 16 +++++++++++----- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/fsharp/FSharp.Core/nativeptr.fsi b/src/fsharp/FSharp.Core/nativeptr.fsi index 98f8d2fd9c..db6a6d9e2f 100644 --- a/src/fsharp/FSharp.Core/nativeptr.fsi +++ b/src/fsharp/FSharp.Core/nativeptr.fsi @@ -22,7 +22,7 @@ namespace Microsoft.FSharp.NativeInterop [] [] [] - /// Returns a typed native pointer for a given machine address. + /// Returns an untyped native pointer for a given typed pointer. /// The pointer address. /// A typed pointer. val inline toVoidPtr : address:nativeptr<'T> -> voidptr diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index 40c574e365..3bfd2a1fcb 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -37,7 +37,6 @@ let ValRefForIntrinsic (IntrinsicValRef(mvr, _, _, _, key)) = mkNonLocalValRef [] 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 +46,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 @@ -385,6 +380,7 @@ 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" @@ -409,6 +405,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" @@ -472,6 +469,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 @@ -651,6 +649,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)) @@ -1306,6 +1306,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 diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index b4945e4973..79f5a9ad56 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -3971,13 +3971,17 @@ let buildApp cenv expr resultTy arg m = // Special rules for building applications of the '&expr' or '&&expr' operators, both of which get the // address of an expression. | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ - when (valRefEq g vf g.addrof_vref || - valRefEq g vf g.addrof2_vref) -> + 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')), resultTy - // Special rule for implicitly dereferencing byref return values on dereference + // Special rules for building applications of the 'NativePtr.toByRef' whose return value doesn't get implicitly dereferenced. + | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ + when (valRefEq g vf g.nativeptr_tobyref_vref) -> + expr.SupplyArgument(arg, m), resultTy + + // Special rule for implicitly dereferencing byref return values | _ when isByrefTy g resultTy -> // Handle byref returns, byref-typed returns get implicitly dereferenced let v, _ = mkCompGenLocal m "byrefReturn" resultTy @@ -8287,10 +8291,12 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = match UnifyFunctionTypeUndoIfFailed cenv denv mExpr exprty with | Some (_, resultTy) -> - // We don't strip byrefs off the return type for "&x" and "&&x" + // We don't strip byrefs off the return type for "&x" or 'NativePtr.toByRef' let stripByrefsOnReturn = match expr with - | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _) when valRefEq cenv.g vf cenv.g.addrof_vref -> false + | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _) + when (valRefEq cenv.g vf cenv.g.addrof_vref || + valRefEq cenv.g vf cenv.g.nativeptr_tobyref_vref) -> false | _ -> stripByrefsOnReturn propagate stripByrefsOnReturn delayedList' mExprAndArg resultTy From c49bdc300ae28107c74dabc3d3ee6a5590ac6e41 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 15 May 2018 02:11:33 +0100 Subject: [PATCH 24/61] switch to inference using byref pointer capabilities --- src/FSharpSource.Settings.targets | 14 +- src/fsharp/AugmentWithHashCompare.fs | 6 +- src/fsharp/ConstraintSolver.fs | 106 ++-- src/fsharp/FSComp.txt | 5 +- src/fsharp/FSharp.Core/prim-types-prelude.fs | 6 + src/fsharp/FSharp.Core/prim-types-prelude.fsi | 15 +- src/fsharp/FSharp.Core/prim-types.fs | 19 +- src/fsharp/FSharp.Core/prim-types.fsi | 18 + src/fsharp/IlxGen.fs | 17 +- src/fsharp/MethodCalls.fs | 16 +- src/fsharp/NicePrint.fs | 2 +- src/fsharp/Optimizer.fs | 14 +- src/fsharp/PatternMatchCompilation.fs | 2 +- src/fsharp/PostInferenceChecks.fs | 39 +- src/fsharp/QuotationTranslator.fs | 12 +- src/fsharp/TastOps.fs | 196 ++++--- src/fsharp/TastOps.fsi | 31 +- src/fsharp/TastPickle.fs | 16 +- src/fsharp/TcGlobals.fs | 12 +- src/fsharp/TypeChecker.fs | 117 ++-- src/fsharp/autobox.fs | 4 +- src/fsharp/import.fs | 1 + src/fsharp/infos.fs | 28 +- src/fsharp/service/ServiceDeclarationLists.fs | 12 +- src/fsharp/service/service.fs | 2 +- src/fsharp/symbols/Exprs.fs | 18 +- src/fsharp/symbols/Symbols.fs | 31 +- src/fsharp/symbols/Symbols.fsi | 3 + src/fsharp/tast.fs | 8 +- src/fsharp/xlf/FSComp.txt.cs.xlf | 15 +- src/fsharp/xlf/FSComp.txt.de.xlf | 15 +- src/fsharp/xlf/FSComp.txt.en.xlf | 17 +- src/fsharp/xlf/FSComp.txt.es.xlf | 15 +- src/fsharp/xlf/FSComp.txt.fr.xlf | 15 +- src/fsharp/xlf/FSComp.txt.it.xlf | 15 +- src/fsharp/xlf/FSComp.txt.ja.xlf | 15 +- src/fsharp/xlf/FSComp.txt.ko.xlf | 15 +- src/fsharp/xlf/FSComp.txt.pl.xlf | 15 +- src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 15 +- src/fsharp/xlf/FSComp.txt.ru.xlf | 15 +- src/fsharp/xlf/FSComp.txt.tr.xlf | 15 +- src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 15 +- src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 15 +- tests/fsharp/core/byrefs/test.fsx | 535 +++++++++++++++++- tests/fsharp/core/span/test.fsx | 12 + .../src/FSharp.VS.FSI/fsiSessionToolWindow.fs | 16 - 46 files changed, 1124 insertions(+), 421 deletions(-) diff --git a/src/FSharpSource.Settings.targets b/src/FSharpSource.Settings.targets index 6ecd5f0612..d0ebb1cf03 100644 --- a/src/FSharpSource.Settings.targets +++ b/src/FSharpSource.Settings.targets @@ -190,7 +190,7 @@ full portable true - DEBUG;NO_STRONG_NAMES;$(DefineConstants) + PROTO;DEBUG;NO_STRONG_NAMES;$(DefineConstants) @@ -199,18 +199,6 @@ 3 - - $(DefineConstants),VS_VERSION_DEV12=True - $(DefineConstants);VS_VERSION_DEV12 - $(DefineConstants),VS_VERSION_DEV14=True - $(DefineConstants);VS_VERSION_DEV14 - $(DefineConstants),VS_VERSION_DEV15=True - $(DefineConstants);VS_VERSION_DEV15 - - $(DefineConstants),VS_VERSION_DEV14=True - $(DefineConstants);VS_VERSION_DEV14 - - $([System.DateTime]::Now.ToString(`yyMMdd`)) diff --git a/src/fsharp/AugmentWithHashCompare.fs b/src/fsharp/AugmentWithHashCompare.fs index 7e914267bd..3c11de5df5 100644 --- a/src/fsharp/AugmentWithHashCompare.fs +++ b/src/fsharp/AugmentWithHashCompare.fs @@ -115,13 +115,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 +131,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) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 90ef7984e7..025110390e 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -116,34 +116,34 @@ let FreshenMethInfo m (minfo:MethInfo) = [] /// Information about the context of a type equation. type ContextInfo = -/// No context was given. -| NoContext -/// The type equation comes from an IF expression. -| IfExpression of range -/// The type equation comes from an omitted else branch. -| OmittedElseBranch of range -/// The type equation comes from a type check of the result of an else branch. -| ElseBranchResult of range -/// The type equation comes from the verification of record fields. -| RecordFields -/// The type equation comes from the verification of a tuple in record fields. -| TupleInRecordFields -/// The type equation comes from a list or array constructor -| CollectionElement of bool * range -/// The type equation comes from a return in a computation expression. -| ReturnInComputationExpression -/// The type equation comes from a yield in a computation expression. -| YieldInComputationExpression -/// The type equation comes from a runtime type test. -| RuntimeTypeTest of bool -/// The type equation comes from an downcast where a upcast could be used. -| DowncastUsedInsteadOfUpcast of bool -/// The type equation comes from a return type of a pattern match clause (not the first clause). -| FollowingPatternMatchClause of range -/// The type equation comes from a pattern match guard. -| PatternMatchGuard of range -/// The type equation comes from a sequence expression. -| SequenceExpression of TType + /// No context was given. + | NoContext + /// The type equation comes from an IF expression. + | IfExpression of range + /// The type equation comes from an omitted else branch. + | OmittedElseBranch of range + /// The type equation comes from a type check of the result of an else branch. + | ElseBranchResult of range + /// The type equation comes from the verification of record fields. + | RecordFields + /// The type equation comes from the verification of a tuple in record fields. + | TupleInRecordFields + /// The type equation comes from a list or array constructor + | CollectionElement of bool * range + /// The type equation comes from a return in a computation expression. + | ReturnInComputationExpression + /// The type equation comes from a yield in a computation expression. + | YieldInComputationExpression + /// The type equation comes from a runtime type test. + | RuntimeTypeTest of bool + /// The type equation comes from an downcast where a upcast could be used. + | DowncastUsedInsteadOfUpcast of bool + /// The type equation comes from a return type of a pattern match clause (not the first clause). + | FollowingPatternMatchClause of range + /// The type equation comes from a pattern match guard. + | PatternMatchGuard of range + /// The type equation comes from a sequence expression. + | SequenceExpression of TType exception ConstraintSolverTupleDiffLengths of DisplayEnv * TType list * TType list * range * range exception ConstraintSolverInfiniteTypes of ContextInfo * DisplayEnv * TType * TType * range * range @@ -837,6 +837,11 @@ and SolveFunTypEqn csenv ndeep m2 trace cxsln d1 d2 r1 r2 = SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln d1 d2 ++ (fun () -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln r1 r2) +// 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 SolveTypSubsumesTyp (csenv:ConstraintSolverEnv) ndeep m2 (trace: OptionalTrace) cxsln ty1 ty2 = // 'a :> obj ---> let ndeep = ndeep + 1 @@ -873,6 +878,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 @@ -1914,7 +1931,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) @@ -1937,7 +1954,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 @@ -1951,15 +1968,14 @@ and CanMemberSigsMatchUpToCheck let methodRetTy = calledMeth.ReturnTypeAfterOutArgTupling unifyTypes reqdRetTy methodRetTy ))))) -//------------------------------------------------------------------------- -// Resolve IL overloading. -// -// This utilizes the type inference constraint solving engine in undo mode. -//------------------------------------------------------------------------- - - // 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 +1989,13 @@ and private SolveTypSubsumesTypWithReport (csenv:ConstraintSolverEnv) ndeep m tr | _ -> ErrorD (ErrorsFromAddingSubsumptionConstraint(csenv.g, csenv.DisplayEnv, ty1, ty2, res, ContextInfo.NoContext, m)) | _ -> ErrorD (ErrorsFromAddingSubsumptionConstraint(csenv.g, csenv.DisplayEnv, ty1, ty2, res, csenv.eContextInfo, m))) -and private SolveTypEqualsTypWithReport (csenv:ConstraintSolverEnv) ndeep m trace cxsln ty1 ty2 = - TryD (fun () -> SolveTypEqualsTypKeepAbbrevsWithCxsln csenv ndeep m trace cxsln ty1 ty2) +// ty1: actual +// ty2: expected +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) @@ -2498,8 +2516,8 @@ let EliminateConstraintsForGeneralizedTypars csenv (trace:OptionalTrace) (genera // No error recovery here: we do that on a per-expression basis. //------------------------------------------------------------------------- -let AddCxTypeEqualsType contextInfo denv css m ty1 ty2 = - SolveTypEqualsTypWithReport (MakeConstraintSolverEnv contextInfo css m denv) 0 m NoTrace None ty1 ty2 +let AddCxTypeEqualsType contextInfo denv css m actual expected = + SolveTypEqualsTypWithReport (MakeConstraintSolverEnv contextInfo css m denv) 0 m NoTrace None actual expected |> RaiseOperationResult let UndoIfFailed f = @@ -2649,7 +2667,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 +2682,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)) diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 441507eaf7..0ad88684f9 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -83,7 +83,7 @@ tastTypeHasAssemblyCodeRepresentation,"The type '%s' has an inline assembly code 253,tastInvalidFormForPropertyGetter,"Invalid form for a property getter. At least one '()' argument is required when using the explicit syntax." 254,tastInvalidFormForPropertySetter,"Invalid form for a property setter. At least one argument is required." 255,tastUnexpectedByRef,"Unexpected use of a byref-typed variable" -256,tastValueMustBeLocalAndMutable,"A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'" +256,tastValueMustBeMutable,"A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...'" 257,tastInvalidMutationOfConstant,"Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'." tastValueHasBeenCopied,"The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed" 259,tastRecursiveValuesMayNotBeInConstructionOfTuple,"Recursively defined values cannot appear directly as part of the construction of a tuple value within a recursive binding" @@ -1424,4 +1424,5 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 3220,tcTupleMemberNotNormallyUsed,"This method or property is not normally used from F# code, use an explicit tuple pattern for deconstruction instead." 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." \ No newline at end of file +3223,ilreadFileChanged,"The file '%s' changed on disk unexpectedly, please reload." +3224,writeToReadOnlyByref,"The byref pointer is readonly, so this write is not permitted." diff --git a/src/fsharp/FSharp.Core/prim-types-prelude.fs b/src/fsharp/FSharp.Core/prim-types-prelude.fs index 705efcc24b..4a04797d3d 100644 --- a/src/fsharp/FSharp.Core/prim-types-prelude.fs +++ b/src/fsharp/FSharp.Core/prim-types-prelude.fs @@ -64,8 +64,14 @@ namespace Microsoft.FSharp.Core type array<'T> = 'T[] + /// Represents a managed pointer in F# code. + type byref<'T, 'Kind> = (# "!0&" #) + + /// Represents a managed pointer in F# code. For F# 4.5+ this is considered equivalent to byref<'T, ByRefKinds.InOut> type byref<'T> = (# "!0&" #) type nativeptr<'T when 'T : unmanaged> = (# "native int" #) + type voidptr = (# "void*" #) + type ilsigptr<'T> = (# "!0*" #) diff --git a/src/fsharp/FSharp.Core/prim-types-prelude.fsi b/src/fsharp/FSharp.Core/prim-types-prelude.fsi index 74eb0cd5e9..7b05b5c9ce 100644 --- a/src/fsharp/FSharp.Core/prim-types-prelude.fsi +++ b/src/fsharp/FSharp.Core/prim-types-prelude.fsi @@ -25,41 +25,52 @@ namespace Microsoft.FSharp.Core /// An abbreviation for the CLI type System.Single. type float32 = System.Single + /// An abbreviation for the CLI type System.Double. type float = System.Double + /// An abbreviation for the CLI type System.Single. type single = System.Single + /// An abbreviation for the CLI type System.Double. type double = System.Double /// An abbreviation for the CLI type System.SByte. type sbyte = System.SByte + /// An abbreviation for the CLI type System.Byte. type byte = System.Byte + /// An abbreviation for the CLI type System.SByte. type int8 = System.SByte + /// An abbreviation for the CLI type System.Byte. type uint8 = System.Byte /// An abbreviation for the CLI type System.Int16. type int16 = System.Int16 + /// An abbreviation for the CLI type System.UInt16. type uint16 = System.UInt16 /// An abbreviation for the CLI type System.Int32. type int32 = System.Int32 + /// An abbreviation for the CLI type System.UInt32. type uint32 = System.UInt32 /// An abbreviation for the CLI type System.Int64. type int64 = System.Int64 + /// An abbreviation for the CLI type System.UInt64. type uint64 = System.UInt64 /// An abbreviation for the CLI type System.Char. type char = System.Char + /// An abbreviation for the CLI type System.Boolean. type bool = System.Boolean + /// An abbreviation for the CLI type System.Decimal. type decimal = System.Decimal @@ -216,8 +227,10 @@ namespace Microsoft.FSharp.Core /// values. type 'T array = 'T[] - /// Represents a managed pointer in F# code. + type byref<'T, 'Kind> = (# "!0&" #) + + /// Represents a managed pointer in F# code. For F# 4.5+ this is considered equivalent to byref<'T, ByRefKinds.InOut> type byref<'T> = (# "!0&" #) /// Represents an unmanaged pointer in F# code. diff --git a/src/fsharp/FSharp.Core/prim-types.fs b/src/fsharp/FSharp.Core/prim-types.fs index bb79e0f84d..abb346be9e 100644 --- a/src/fsharp/FSharp.Core/prim-types.fs +++ b/src/fsharp/FSharp.Core/prim-types.fs @@ -5639,6 +5639,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 + + /// Represents a in-argument or readonly managed pointer in F# code. This type should only be used with F# 4.5+. + type inref<'T> = byref<'T, ByRefKinds.In> + + /// Represents a out-argument managed pointer in F# code. This type should only be used with F# 4.5+. + type outref<'T> = byref<'T, ByRefKinds.Out> + namespace Microsoft.FSharp.Control open System @@ -5681,7 +5699,6 @@ namespace Microsoft.FSharp.Control namespace Microsoft.FSharp.Control open System - open System.Diagnostics open Microsoft.FSharp.Core type IDelegateEvent<'Delegate when 'Delegate :> System.Delegate > = diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index 9e9bb34c2b..025c3a431c 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -3161,6 +3161,24 @@ namespace Microsoft.FSharp.Core [] val inline char : value:^T -> char when ^T : (static member op_Explicit : ^T -> char) and default ^T : int + /// 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 + + /// Represents a in-argument or readonly managed pointer in F# code. This type should only be used with F# 4.5+. + type inref<'T> = byref<'T, ByRefKinds.In> + + /// Represents a out-argument managed pointer in F# code. This type should only be used with F# 4.5+. + type outref<'T> = byref<'T, ByRefKinds.Out> + namespace Microsoft.FSharp.Control open Microsoft.FSharp.Core diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index e93708737d..60d5b2889a 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -1881,7 +1881,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 +1895,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 +1917,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(LGetAddr _,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 @@ -3465,10 +3465,11 @@ 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 ilTy = GenParamType cenv.amap m eenv.tyenv ty let inFlag2,outFlag2,optionalFlag2,defaultParamValue,paramMarshal2,attribs = GenParamAttribs cenv attribs { Name=nm - Type= GenParamType cenv.amap m eenv.tyenv ty + Type= ilTy Default=defaultParamValue Marshal=paramMarshal2 IsIn=inFlag || inFlag2 @@ -4949,7 +4950,7 @@ and GenMarshal cenv attribs = None, attribs and GenParamAttribs cenv attribs = - let inFlag = HasFSharpAttributeOpt cenv.g cenv.g.attrib_InAttribute attribs + let inFlag = HasFSharpAttribute cenv.g cenv.g.attrib_InAttribute attribs let outFlag = HasFSharpAttribute cenv.g cenv.g.attrib_OutAttribute attribs let optionalFlag = HasFSharpAttributeOpt cenv.g cenv.g.attrib_OptionalAttribute attribs @@ -4959,7 +4960,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) diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index 76b708bd96..64ef3bf5a0 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -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 @@ -193,11 +195,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 @@ -372,12 +375,9 @@ type CalledMeth<'T> /// The argument analysis for each set of curried arguments member x.ArgSets = argSets - /// raw return type - member x.ReturnTypeBeforeByrefDeref = methodRetTy - /// return type after implicit deference of byref returns is taken into account member x.ReturnTypeAfterByrefDeref = - let retTy = x.ReturnTypeBeforeByrefDeref + let retTy = methodRetTy if isByrefTy g retTy then destByrefTy g retTy else retTy /// return type after tupling of out args is taken into account @@ -556,7 +556,7 @@ let TakeObjAddrForMethodCall g amap (minfo:MethInfo) isMutable m objArgs f = (minfo.IsStruct && not minfo.IsExtensionMember) // don't take the address of a struct when passing to an extension member || hasCallInfo let objArgTy = tyOfExpr g objArgExpr - let 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' = @@ -1079,7 +1079,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 -> diff --git a/src/fsharp/NicePrint.fs b/src/fsharp/NicePrint.fs index 657e61d023..a8001e2833 100755 --- a/src/fsharp/NicePrint.fs +++ b/src/fsharp/NicePrint.fs @@ -1228,7 +1228,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 diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index c7300d3a9d..271ba7a477 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -1271,11 +1271,11 @@ and OpHasEffect g m op = | TOp.ILAsm(instrs, _) -> IlAssemblyCodeHasEffect instrs | TOp.TupleFieldGet(_) -> false | TOp.ExnFieldGet(ecref, n) -> isExnFieldMutable ecref n - | TOp.RefAddrGet -> false + | TOp.RefAddrGet _ -> false | TOp.ValFieldGet rfref -> rfref.RecdField.IsMutable || (TryFindTyconRefBoolAttribute g Range.range0 g.attrib_AllowNullLiteralAttribute rfref.TyconRef = Some true) - | TOp.ValFieldGetAddr rfref -> rfref.RecdField.IsMutable + | TOp.ValFieldGetAddr (rfref, _readonly) -> rfref.RecdField.IsMutable | TOp.UnionCaseFieldGetAddr _ -> false // union case fields are immutable - | TOp.LValueOp (LGetAddr, lv) -> lv.IsMutable + | TOp.LValueOp (LGetAddr _, lv) -> lv.IsMutable | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ | TOp.Coerce @@ -1790,12 +1790,12 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = MightMakeCriticalTailcall=false Info=UnknownValue } (* Handle addresses *) - | TOp.LValueOp (LGetAddr, lv), _, _ -> + | TOp.LValueOp ((LGetAddr _ 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 @@ -1881,7 +1881,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) -> @@ -2276,7 +2276,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 diff --git a/src/fsharp/PatternMatchCompilation.fs b/src/fsharp/PatternMatchCompilation.fs index 4537c8549d..12d399da0b 100644 --- a/src/fsharp/PatternMatchCompilation.fs +++ b/src/fsharp/PatternMatchCompilation.fs @@ -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) -> diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index d7dab07277..ac47ec9df8 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -784,7 +784,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckTypeInstNoByrefs cenv env m tyargs CheckExprsNoByrefs cenv env args - | TOp.LValueOp(LGetAddr,v),_,_ -> + | TOp.LValueOp(LGetAddr _,v),_,_ -> if cenv.reportErrors then if noByrefs context && cenv.reportErrors then errorR(Error(FSComp.SR.chkNoAddressOfAtThisPoint(v.DisplayName), m)) @@ -824,13 +824,13 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = | TOp.Reraise,[_ty1],[] -> CheckTypeInstNoByrefs cenv env m tyargs - | TOp.ValFieldGetAddr rfref,tyargs,[] -> + | TOp.ValFieldGetAddr (rfref, _readonly),tyargs,[] -> if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressStaticFieldAtThisPoint(rfref.FieldName), m)) CheckTypeInstNoByrefs cenv env m tyargs // NOTE: there are no arg exprs to check in this case - | TOp.ValFieldGetAddr rfref,tyargs,[rx] -> + | TOp.ValFieldGetAddr (rfref, _readonly),tyargs,[rx] -> if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(rfref.FieldName), m)) // This construct is used for &(rx.rfield) and &(rx->rfield). Relax to permit byref types for rx. [See Bug 1263]. @@ -845,7 +845,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckTypeInstNoByrefs cenv env m tyargs CheckExprPermitByref cenv env arg1 // allow byref - it may be address-of-struct - | TOp.UnionCaseFieldGetAddr (uref, _idx),tyargs,[rx] -> + | TOp.UnionCaseFieldGetAddr (uref, _idx, _readonly),tyargs,[rx] -> if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(uref.CaseName), m)) CheckTypeInstNoByrefs cenv env m tyargs @@ -888,24 +888,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // allow args to be byref here CheckExprsPermitByrefs cenv env args - | ( TOp.Tuple _ - | TOp.UnionCase _ - | TOp.ExnConstr _ - | TOp.Array - | TOp.Bytes _ - | TOp.UInt16s _ - | TOp.Recd _ - | TOp.ValFieldSet _ - | TOp.UnionCaseTagGet _ - | TOp.UnionCaseProof _ - | TOp.UnionCaseFieldGet _ - | TOp.UnionCaseFieldSet _ - | TOp.ExnFieldGet _ - | TOp.ExnFieldSet _ - | TOp.TupleFieldGet _ - | TOp.RefAddrGet - | _ (* catch all! *) - ),_,_ -> + | _ -> CheckTypeInstNoByrefs cenv env m tyargs CheckExprsNoByrefs cenv env args @@ -1464,13 +1447,15 @@ let CheckEntityDefn cenv env (tycon:Entity) = if numCurriedArgSets > 1 && (minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) - |> List.existsSquared (fun (ParamData(isParamArrayArg, isOutArg, optArgInfo, callerInfoInfo, _, reflArgInfo, ty)) -> - isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefLikeTy cenv.g m ty)) then + |> List.existsSquared (fun (ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, _, reflArgInfo, ty)) -> + isParamArrayArg || isInArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefLikeTy cenv.g m ty)) then errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m)) if numCurriedArgSets = 1 then minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) - |> List.iterSquared (fun (ParamData(_, _, optArgInfo, callerInfoInfo, _, _, ty)) -> + |> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfoInfo, _, _, ty)) -> + // TODO: default values and in args + ignore isInArg match (optArgInfo, callerInfoInfo) with | _, NoCallerInfo -> () | NotOptional, _ -> errorR(Error(FSComp.SR.tcCallerInfoNotOptional(callerInfoInfo.ToString()),m)) @@ -1647,7 +1632,9 @@ let CheckEntityDefn cenv env (tycon:Entity) = match tycon.TypeAbbrev with | None -> () | Some typ -> - CheckForByrefLikeType cenv env m typ (fun () -> errorR(Error(FSComp.SR.chkNoByrefInTypeAbbrev(), tycon.Range))) + // Library-defined outref<'T> and inref<'T> contain byrefs on the r.h.s. + if not cenv.g.compilingFslib then + CheckForByrefLikeType cenv env m typ (fun () -> errorR(Error(FSComp.SR.chkNoByrefInTypeAbbrev(), tycon.Range))) let CheckEntityDefns cenv env tycons = tycons |> List.iter (CheckEntityDefn cenv env) diff --git a/src/fsharp/QuotationTranslator.fs b/src/fsharp/QuotationTranslator.fs index eacd5ca599..d383138b9e 100644 --- a/src/fsharp/QuotationTranslator.fs +++ b/src/fsharp/QuotationTranslator.fs @@ -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() and Convert mkReraiseLibCall cenv.g toTy m |> ConvExpr cenv env - | TOp.LValueOp(LGetAddr,vref),[],[] -> + | TOp.LValueOp(LGetAddr _,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(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.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] -> diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 9740d1624d..9346ccda25 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -560,12 +560,27 @@ let tryNormalizeMeasureInType g ty = // Some basic type builders //--------------------------------------------------------------------------- -let mkVoidPtrTy (g:TcGlobals) = - assert g.voidptr_tcr.CanDeref - TType_app (g.voidptr_tcr, []) let mkNativePtrTy (g:TcGlobals) ty = TType_app (g.nativeptr_tcr, [ty]) let mkByrefTy (g:TcGlobals) ty = TType_app (g.byref_tcr, [ty]) +let mkInrefTy (g:TcGlobals) ty = TType_app (g.inref_tcr, [ty]) +let mkOutrefTy (g:TcGlobals) ty = TType_app (g.outref_tcr, [ty]) +let mkByrefTyWithFlag g readonly ty = (if readonly then mkInrefTy g ty else mkByrefTy g ty) + +let mkByref2Ty (g:TcGlobals) ty1 ty2 = + assert g.byref2_tcr.CanDeref // check we are using FSharp.Core 4.5.0.0+ + TType_app (g.byref2_tcr, [ty1; ty2]) + +let mkVoidPtrTy (g:TcGlobals) = + assert g.voidptr_tcr.CanDeref // check we are using FSharp.Core 4.5.0.0+ + TType_app (g.voidptr_tcr, []) + +let mkByrefTyWithInference (g:TcGlobals) ty1 ty2 = + if g.byref2_tcr.CanDeref then + 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 errorR(Error(FSComp.SR.tastopsMaxArrayThirtyTwo(rank), m)) @@ -678,7 +693,10 @@ 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 + // Add the equation `byref<'T> = byref<'T, ByRefKinds.InOut> for F# 4.5+ when using FSharp.Core 4.5.0.0+ + if tyconRefEq g tcref g.byref_tcr && g.byref2_tcr.CanDeref then + mkByref2Ty g tinst.[0] (TType_app(g.byrefkind_InOut_tcr, [])) + elif tycon.IsMeasureableReprTycon && List.forall (isDimensionless g) tinst then stripTyEqnsA g canShortcut (reduceTyconMeasureableOrProvided g tycon tinst) else ty @@ -1234,13 +1252,13 @@ 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, aexpr, nexpr, m) = Expr.Op (TOp.ILAsm ([IL.I_ldelema(ilInstrReadOnlyAnnotation, isNativePtr, shape, mkILTyvarTy 0us)], [mkByrefTyWithFlag g readonly elemTy]), [elemTy], [aexpr;nexpr], m) let mkRecdFieldSetViaExprAddr (e1, fref, tinst, e2, m) = Expr.Op (TOp.ValFieldSet(fref), tinst, [e1;e2], m) @@ -1257,7 +1275,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 @@ -1290,7 +1308,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 (LGetAddr readonly, v), [], [], m) //-------------------------------------------------------------------------- // Maps tracking extra information for values @@ -1546,7 +1564,24 @@ 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 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) @@ -2879,6 +2914,9 @@ let isByrefLikeTyconRef g m (tcref: TyconRef) = | None -> let res = tyconRefEq g g.byref_tcr tcref || + (g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref) || + tyconRefEq g g.inref_tcr tcref || + tyconRefEq g g.outref_tcr tcref || isTypeConstructorEqualToOptional g g.system_TypedReference_tcref tcref || isTypeConstructorEqualToOptional g g.system_ArgIterator_tcref tcref || isTypeConstructorEqualToOptional g g.system_RuntimeArgumentHandle_tcref tcref || @@ -2895,7 +2933,8 @@ let isByrefLikeTy g m ty = 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 // F# 4.5 with FSharp.Core 4.5.0.0+ + | TType_app(tcref, [x]) when tyconRefEq g g.byref_tcr tcref -> x // all others | _ -> failwith "destByrefTy: not a byref type" let destNativePtrTy g ty = @@ -3070,7 +3109,7 @@ module DebugPrint = begin let lvalopL x = match x with - | LGetAddr -> wordL (tagText "LGetAddr") + | LGetAddr readonly -> wordL (tagText (sprintf "LGetAddr(%b)" readonly)) | LByrefGet -> wordL (tagText "LByrefGet") | LSet -> wordL (tagText "LSet") | LByrefSet -> wordL (tagText "LByrefSet") @@ -3547,9 +3586,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 @@ -3592,7 +3631,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...") @@ -4314,7 +4353,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 @@ -4327,7 +4366,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 @@ -4337,7 +4376,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) -> @@ -4763,23 +4802,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 @@ -4849,8 +4888,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 @@ -5339,16 +5379,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 (LGetAddr 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 -> @@ -5573,7 +5613,7 @@ 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 isRecdOrStructTyconRefReadOnly (g: TcGlobals) m (tcref: TyconRef) = @@ -5615,10 +5655,11 @@ let CanTakeAddressOfImmutableVal g m (v:ValRef) mut = // and the value is a true local or closure field. not v.IsMutable && not v.IsMemberOrModuleBinding && - (match mut with - | NeverMutates -> true - | PossiblyMutates -> isRecdOrStructTyReadOnly g m v.Type - | DefinitelyMutates -> false) + match mut with + | NeverMutates -> true + | PossiblyMutates -> isRecdOrStructTyReadOnly g m v.Type + | DefinitelyMutates -> false + | AddressOfOp -> true // you can take the address but you might get a (readonly) inref as a result let MustTakeAddressOfVal (g:TcGlobals) (v:ValRef) = v.IsMutable && @@ -5644,86 +5685,102 @@ let CanTakeAddressOfUnionFieldRef (g:TcGlobals) m (uref: UnionCaseRef) mut = entityRefInThisAssembly g.compilingFslib uref.TyconRef && isRecdOrStructTyconRefReadOnly g m uref.TyconRef -/// Make the address-of expression and return a wrapper that adds any allocated locals at an appropriate scope +/// 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 readonly pointer (e.g. the address of +/// let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m = - if not mustTakeAddress then None, e else + if not mustTakeAddress then + None, e, false + else match e with // LVALUE: "x" where "x" is byref | Expr.Op (TOp.LValueOp (LByrefGet, v), _, [], m) -> - None, exprForValRef m v + let readonly = isInByrefTy g v.Type + None, exprForValRef m v, readonly // 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 m v mut -> - None, mkValAddr m v + let readonly = not (MustTakeAddressOfVal g v) + None, mkValAddr m readonly v, readonly // LVALUE: "x" where "e.x" is record field. | Expr.Op (TOp.ValFieldGet rfref, tinst, [e], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref mut -> let exprty = tyOfExpr g e - let wrap, expra = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m - wrap, mkRecdFieldGetAddrViaExprAddr(expra, rfref, tinst, m) + let wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m + let readonly = readonly || not (MustTakeAddressOfRecdFieldRef rfref) + wrap, mkRecdFieldGetAddrViaExprAddr(readonly, expra, rfref, tinst, m), readonly // LVALUE: "x" where "e.x" is union field | Expr.Op (TOp.UnionCaseFieldGet (uref, cidx), tinst, [e], m) when MustTakeAddressOfRecdField (uref.FieldByIndex(cidx)) || CanTakeAddressOfUnionFieldRef g m uref mut -> 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) + let wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m + let readonly = readonly || not (MustTakeAddressOfRecdField (uref.FieldByIndex(cidx))) + wrap, mkUnionCaseFieldGetAddrProvenViaExprAddr(readonly, expra, uref, tinst, cidx, m), readonly // LVALUE: "x" where "e.x" 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 + //let readonly = not (MustTakeAddressOfILStaticField (uref.FieldByIndex(cidx))) + 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) - -> + | 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) + let wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m + //let readonly = not (MustTakeAddressOfILField fspec) + wrap, Expr.Op (TOp.ILAsm ([IL.I_ldflda(fspec)], [mkByrefTy g 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 m rfref mut -> - None, mkStaticRecdFieldGetAddr(rfref, tinst, m) + let readonly = false + 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) -> + | Expr.App(Expr.Val(vf, _, _), _, [elemTy], [aexpr;nexpr], _) when (valRefEq g vf g.array_get_vref) -> + let readonly = false 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) -> + let readonly = false 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) - - // 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.tastValueMustBeLocalAndMutable(), m)); + None, Expr.Op (TOp.ILAsm ([IL.I_ldelema(ilInstrReadOnlyAnnotation, isNativePtr, shape, mkILTyvarTy 0us)], [mkByrefTy g elemTy]), [elemTy], (aexpr::args), m), readonly + + | Expr.Val(v, _, m) when isByrefTy g v.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(v, _, m) when (mut = DefinitelyMutates || mut = AddressOfOp) && v.IsMutable -> + error(Error(FSComp.SR.tastInvalidAddressOfMutableAcrossAssemblyBoundary(), m)) + + // Give a nice error message for DefinitelyMutates on immutable values + | Expr.Val _ when mut = DefinitelyMutates -> + error(Error(FSComp.SR.tastValueMustBeMutable(), m)) // LVALUE: "&meth(args)" where meth has a byref return. Includes "&span.[idx]". | Expr.Let(TBind(v, e, _), Expr.Op(TOp.LValueOp (LByrefGet, v2), _, _, _), _, _) when isByrefTy g v.Type && (valRefEq g (mkLocalValRef v) v2) -> - None, e + let readonly = isInByrefTy g (tyOfExpr g e) + None, e, readonly | _ -> let ty = tyOfExpr g e if isStructTy g ty then match mut with | NeverMutates -> () + | AddressOfOp -> () // we get an inref | DefinitelyMutates -> errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(), m)); | PossiblyMutates -> @@ -5732,26 +5789,27 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress match mut with | NeverMutates -> mkCompGenLocal m "copyOfStruct" ty | _ -> mkMutableCompGenLocal m "copyOfStruct" ty - Some (tmp, e), (mkValAddr m (mkLocalValRef tmp)) + let readonly = true + Some (tmp, e), (mkValAddr m readonly (mkLocalValRef tmp)), readonly 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)) diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index 9b69e4a9a7..c1846a2d98 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -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 mkInrefTy : TcGlobals -> TType -> TType +val mkOutrefTy : TcGlobals -> TType -> TType //------------------------------------------------------------------------- // Make construction operations @@ -182,12 +185,12 @@ 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 mkStaticRecdFieldGet : RecdFieldRef * TypeInst * range -> Expr -val mkStaticRecdFieldSet : RecdFieldRef * TypeInst * Expr * range -> Expr -val mkStaticRecdFieldGetAddr : RecdFieldRef * TypeInst * range -> Expr -val mkRecdFieldSetViaExprAddr : Expr * RecdFieldRef * TypeInst * Expr * range -> Expr +val mkRecdFieldGetViaExprAddr : 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 : readonly: bool * RecdFieldRef * TypeInst * range -> Expr +val mkRecdFieldSetViaExprAddr : Expr * RecdFieldRef * TypeInst * Expr * range -> Expr val mkUnionCaseTagGetViaExprAddr : Expr * TyconRef * TypeInst * range -> Expr /// Make a 'TOp.UnionCaseProof' expression, which proves a union value is over a particular case (used only for ref-unions, not struct-unions) @@ -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 * Expr * range -> Expr //------------------------------------------------------------------------- // Compiled view of tuples @@ -263,9 +266,9 @@ val helpEnsureTypeHasMetadata : 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 @@ -874,7 +877,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 @@ -1101,6 +1104,7 @@ val isExnDefinitelyMutable : TyconRef -> bool val isUnionCaseFieldMutable : TcGlobals -> UnionCaseRef -> int -> bool val isExnFieldMutable : TyconRef -> int -> bool val isRecdOrStructTyconRefReadOnly: TcGlobals -> range -> TyconRef -> bool +val isRecdOrStructTyReadOnly: TcGlobals -> range -> TType -> bool val useGenuineField : Tycon -> RecdField -> bool val ComputeFieldName : Tycon -> RecdField -> string @@ -1397,7 +1401,10 @@ 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 diff --git a/src/fsharp/TastPickle.fs b/src/fsharp/TastPickle.fs index 81a2dd85aa..2756b6470d 100755 --- a/src/fsharp/TastPickle.fs +++ b/src/fsharp/TastPickle.fs @@ -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 LGetAddr _ -> 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 -> LGetAddr 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 | 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) diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index 3bfd2a1fcb..7f745ef04e 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -196,6 +196,9 @@ 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" @@ -387,6 +390,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d 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" @@ -916,6 +920,9 @@ 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 @@ -927,6 +934,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 "In" + 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" @@ -1089,7 +1099,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" diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 79f5a9ad56..6eeba499f5 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -533,8 +533,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 = @@ -860,7 +860,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 = @@ -2635,7 +2635,10 @@ 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 - mkByrefTy cenv.g objTy + if isRecdOrStructTyReadOnly cenv.g m objTy then + mkInrefTy cenv.g objTy + else + mkByrefTy cenv.g objTy else objTy tcrefObjTy, enclosingDeclaredTypars, renaming, objTy, thisTy @@ -3054,7 +3057,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. * @@ -3072,7 +3075,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 = @@ -3091,7 +3094,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) ) @@ -3973,22 +3976,18 @@ let buildApp cenv expr resultTy arg m = | 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')), resultTy - - // Special rules for building applications of the 'NativePtr.toByRef' whose return value doesn't get implicitly dereferenced. - | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ - when (valRefEq g vf g.nativeptr_tobyref_vref) -> - expr.SupplyArgument(arg, m), resultTy + let wrap, e1a', readonly = mkExprAddrOfExpr g true false AddressOfOp arg (Some(vf)) m + // Assert the result type to be readonly if argument is readonly struct + let resultTy = + let argTy = tyOfExpr g arg + if readonly then + let expected = mkInrefTy g argTy +// UnifyTypes cenv env m resultTy expected + expected + else + mkByrefTyWithInference g argTy (NewInferenceType()) // resultTy - // Special rule for implicitly dereferencing byref return values - | _ 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 + MakeApplicableExprNoFlex cenv (wrap(e1a')), resultTy | _ -> expr.SupplyArgument(arg, m), resultTy @@ -6306,7 +6305,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 -> @@ -8272,34 +8271,42 @@ 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 stripByrefsOnReturn 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 - let exprty = if stripByrefsOnReturn && isByrefTy cenv.g exprty then destByrefTy cenv.g exprty else exprty + + // We generate a tag inference parameter to the return type for "&x" and 'NativePtr.toByRef' + let exprty = + if isAddrOf && isByrefTy cenv.g exprty then + mkByrefTyWithInference cenv.g (destByrefTy cenv.g exprty) (NewInferenceType()) + 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 stripByrefsOnReturn 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) -> - // We don't strip byrefs off the return type for "&x" or 'NativePtr.toByRef' - let stripByrefsOnReturn = + // We add tag parameter to the return type for "&x" and 'NativePtr.toByRef' + 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) -> false - | _ -> stripByrefsOnReturn + valRefEq cenv.g vf cenv.g.nativeptr_tobyref_vref) -> true + | _ -> false - propagate stripByrefsOnReturn delayedList' mExprAndArg resultTy + propagate isAddrOf delayedList' mExprAndArg resultTy | None -> let mArg = arg.Range @@ -8321,7 +8328,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 true 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 @@ -8857,10 +8864,13 @@ 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 - mkAddrSet mStmt vref e2' + 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' + mkValSet mStmt vref e2' PropagateThenTcDelayed cenv overallTy env tpenv mStmt (MakeApplicableExprNoFlex cenv vexp) (tyOfExpr cenv.g vexp) ExprAtomicFlag.NonAtomic otherDelayed @@ -9231,7 +9241,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, _, _) -> mkByrefTyWithInference cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) (NewInferenceType()) | SynExpr.Lambda(_, _, _, a, _) -> mkFunTy (NewInferenceType ()) (GetNewInferenceTypeForMethodArg cenv env tpenv a) | SynExpr.Quote(_, raw, a, _, _) -> if raw then mkRawQuotedExprTy cenv.g @@ -9263,8 +9273,8 @@ and TcMethodApplication let denv = env.DisplayEnv - let isSimpleFormalArg (isParamArrayArg, isOutArg, optArgInfo: OptionalArgInfo, callerInfoInfo: CallerInfoInfo, _reflArgInfo: ReflectedArgInfo) = - not isParamArrayArg && not isOutArg && not optArgInfo.IsOptional && callerInfoInfo = NoCallerInfo + let isSimpleFormalArg (isParamArrayArg, isInArg, isOutArg, optArgInfo: OptionalArgInfo, callerInfoInfo: CallerInfoInfo, _reflArgInfo: ReflectedArgInfo) = + not isParamArrayArg && not isInArg && not isOutArg && not optArgInfo.IsOptional && callerInfoInfo = NoCallerInfo let callerObjArgTys = objArgs |> List.map (tyOfExpr cenv.g) @@ -9642,7 +9652,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 @@ -9679,7 +9689,12 @@ and TcMethodApplication let coerceExpr isOutArg calledArgTy (reflArgInfo: ReflectedArgInfo) callerArgTy m callerArgExpr = if isByrefTy cenv.g calledArgTy && isRefCellTy cenv.g callerArgTy then - Expr.Op(TOp.RefAddrGet, [destRefCellTy cenv.g callerArgTy], [callerArgExpr], m) + Expr.Op(TOp.RefAddrGet false, [destRefCellTy cenv.g callerArgTy], [callerArgExpr], m) + + elif isInByrefTy cenv.g calledArgTy && not (isByrefTy cenv.g callerArgTy) then + let tmp, _ = mkCompGenLocal m "copyOfStruct" callerArgTy + failwith "no auto conv yet - scope of tmp not right" + mkCompGenLet m tmp callerArgExpr (mkValAddr m true (mkLocalValRef tmp)) elif isDelegateTy cenv.g calledArgTy && isFunTy cenv.g callerArgTy then CoerceFromFSharpFuncToDelegate cenv.g cenv.amap cenv.infoReader ad callerArgTy m callerArgExpr calledArgTy @@ -9800,7 +9815,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 = @@ -9867,7 +9882,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 @@ -10205,7 +10220,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 @@ -10254,7 +10269,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 @@ -12482,19 +12497,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)) @@ -12567,9 +12582,9 @@ module IncrClassChecking = 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 (LGetAddr 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 diff --git a/src/fsharp/autobox.fs b/src/fsharp/autobox.fs index b972799c86..2ead1d41a4 100644 --- a/src/fsharp/autobox.fs +++ b/src/fsharp/autobox.fs @@ -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 (LGetAddr 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 diff --git a/src/fsharp/import.fs b/src/fsharp/import.fs index 6c8e1271ba..5635c0b45b 100644 --- a/src/fsharp/import.fs +++ b/src/fsharp/import.fs @@ -168,6 +168,7 @@ 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" -> mkInrefTy 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) diff --git a/src/fsharp/infos.fs b/src/fsharp/infos.fs index 192254a9d6..9de3aabf3a 100755 --- a/src/fsharp/infos.fs +++ b/src/fsharp/infos.fs @@ -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 //------------------------------------------------------------------------- @@ -1349,6 +1349,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 @@ -1368,7 +1369,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 @@ -1378,7 +1379,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 = @@ -1429,7 +1431,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 _ -> [[]] @@ -1445,7 +1447,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 @@ -1544,12 +1548,18 @@ 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)) -> + let g = x.TcGlobals + let pty = + // add the "annotation" about whether this is an inref, outref or plain byref + if isByrefTy g pty && isInArg then mkInrefTy g (destByrefTy g pty) + elif isByrefTy g pty && isOutArg then mkOutrefTy g (destByrefTy g pty) + else 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. @@ -2130,7 +2140,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) = diff --git a/src/fsharp/service/ServiceDeclarationLists.fs b/src/fsharp/service/ServiceDeclarationLists.fs index 83f1bccba0..420be3fab7 100644 --- a/src/fsharp/service/ServiceDeclarationLists.fs +++ b/src/fsharp/service/ServiceDeclarationLists.fs @@ -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 diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs index b63a612da0..2c56bb57e7 100644 --- a/src/fsharp/service/service.fs +++ b/src/fsharp/service/service.fs @@ -352,7 +352,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 diff --git a/src/fsharp/symbols/Exprs.fs b/src/fsharp/symbols/Exprs.fs index ecbcea1019..d393a66612 100644 --- a/src/fsharp/symbols/Exprs.fs +++ b/src/fsharp/symbols/Exprs.fs @@ -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(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.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() and Convert mkReraiseLibCall cenv.g toTy m |> ConvExprPrim cenv env - | TOp.LValueOp(LGetAddr, vref), [], [] -> + | TOp.LValueOp(LGetAddr _, 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) diff --git a/src/fsharp/symbols/Symbols.fs b/src/fsharp/symbols/Symbols.fs index 555f216409..d18140c5fb 100644 --- a/src/fsharp/symbols/Symbols.fs +++ b/src/fsharp/symbols/Symbols.fs @@ -281,7 +281,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 _ @@ -1743,11 +1743,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 @@ -1755,11 +1755,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 @@ -1776,7 +1776,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 [] @@ -1788,9 +1788,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 @@ -1806,29 +1807,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 = @@ -2224,7 +2225,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 @@ -2238,7 +2239,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) @@ -2251,6 +2252,8 @@ and FSharpParameter(cenv, typ:TType, topArgInfo:ArgReprInfo, mOpt, isParamArrayA member __.IsParamArrayArg = isParamArrayArg + member __.IsInArg = isInArg + member __.IsOutArg = isOutArg member __.IsOptionalArg = isOptionalArg diff --git a/src/fsharp/symbols/Symbols.fsi b/src/fsharp/symbols/Symbols.fsi index a6cf492c4d..6c6da7f522 100644 --- a/src/fsharp/symbols/Symbols.fsi +++ b/src/fsharp/symbols/Symbols.fsi @@ -847,6 +847,9 @@ and [] 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 diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index c3be9912da..2a9d67835b 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -4459,7 +4459,7 @@ and | ValFieldGet of RecdFieldRef /// An operation representing getting the address of a record field - | ValFieldGetAddr of RecdFieldRef + | ValFieldGetAddr of RecdFieldRef * readonly: bool /// An operation representing getting an integer tag for a union value representing the union case number | UnionCaseTagGet of TyconRef @@ -4472,7 +4472,7 @@ and | UnionCaseFieldGet of UnionCaseRef * int /// An operation representing a field-get from a union value, where that value has been proven to be of the corresponding union case. - | UnionCaseFieldGetAddr of UnionCaseRef * int + | UnionCaseFieldGetAddr of UnionCaseRef * int * readonly: bool /// An operation representing a field-get from a union value. The value is not assumed to have been proven to be of the corresponding union case. | UnionCaseFieldSet of UnionCaseRef * int @@ -4490,7 +4490,7 @@ and | ILAsm of ILInstr list * TTypes /// Generate a ldflda on an 'a ref. - | RefAddrGet + | RefAddrGet of bool /// Conversion node, compiled via type-directed translation or to box/unbox | Coerce @@ -4561,7 +4561,7 @@ and ForLoopStyle = /// Indicates what kind of pointer operation this is. and LValueOperation = /// In C syntax this is: &localv - | LGetAddr + | LGetAddr of readonly: bool /// In C syntax this is: *localv_ptr | LByrefGet diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 8747689952..b730b82975 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -412,11 +412,6 @@ Neočekávané použití proměnné typu ByRef. - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - 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 = ... - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Neplatná mutace konstantního výrazu. Zvažte možnost zkopírovat výraz do lokální proměnné, třeba let mutable x = ... @@ -6987,6 +6982,16 @@ Soubor {0} se na disku neočekávaně změnil, opakujte prosím načtení. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index f6884a84cd..a16b0898dc 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -412,11 +412,6 @@ Unerwartete Verwendung einer Variablen vom Typ "byref". - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - Ein Wert muss änderbar sein, um die Inhalte eines Werttyps zu mutieren oder seine Adresse zu übernehmen, z.B. "let mutable x = ...". - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Ungültige Mutation eines konstanten Ausdrucks. Kopieren Sie den Ausdruck in eine änderbare lokale Variable, z.B. "let mutable x = ...". @@ -6987,6 +6982,16 @@ Die Datei "{0}" wurde auf dem Datenträger unerwartet geändert. Laden Sie sie erneut. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.en.xlf b/src/fsharp/xlf/FSComp.txt.en.xlf index c633c17802..94af2c7966 100644 --- a/src/fsharp/xlf/FSComp.txt.en.xlf +++ b/src/fsharp/xlf/FSComp.txt.en.xlf @@ -412,11 +412,6 @@ Unexpected use of a byref-typed variable - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. @@ -6987,6 +6982,16 @@ The file '{0}' changed on disk unexpectedly, please reload. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + - + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 454a9c8f11..b8ae645806 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -412,11 +412,6 @@ Uso inesperado de una variable de tipo byref. - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - 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 = ...' - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Mutación no válida de una expresión constante. Considere copiar la expresión en un local mutable; por ejemplo, 'let mutable x = ...'. @@ -6987,6 +6982,16 @@ El archivo "{0}" cambió en el disco de manera inesperada; cárguelo de nuevo. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index 479fb4d089..065f919c91 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -412,11 +412,6 @@ Utilisation inattendue d'une variable typée byref - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - Une valeur doit être mutable pour pouvoir muter le contenu ou accepter l'adresse d'un type valeur, par exemple 'let mutable x = ...' - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Mutation non valide d'une expression constante. Copiez l'expression dans une variable locale mutable, par exemple 'let mutable x = ...'. @@ -6987,6 +6982,16 @@ Changement inattendu du fichier '{0}' sur le disque. Rechargez le fichier. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index df26d0b3af..624b1c9d3a 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -412,11 +412,6 @@ Utilizzo non previsto di una variabile di tipo byref - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - Un valore deve essere modificabile per poter modificare i contenuti oppure utilizzare l'indirizzo di un tipo di valore, ad esempio 'let mutable x = ...' - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Modifica non valida di un'espressione costante. Provare a copiare l'espressione in un locale modificabile, ad esempio 'let mutable x = ...'. @@ -6987,6 +6982,16 @@ Il file '{0}' è stato modificato su disco in modo imprevisto. Ricaricare. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 2c8a8ad6fe..8479835881 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -412,11 +412,6 @@ byref 型変数の予期しない使用方法です: - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - 値の型の内容を変更するか、値の型のアドレスを使用するために、値は変更可能にする必要があります (たとえば、'let mutable x = ...') - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. 定数式の変更は無効です。変更可能なローカルに式をコピーしてください (たとえば、'let mutable x = ...')。 @@ -6987,6 +6982,16 @@ ファイル '{0}' がディスク上で予期せず変更されました。再度読み込んでください。 + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index a47473ed55..49e7782d1f 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -412,11 +412,6 @@ 예기치 않은 byref 형식 변수의 사용입니다. - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - 내용을 변경하거나 값 형식의 주소를 사용하려면 값을 변경할 수 있어야 합니다(예: 'let mutable x = ...'). - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. 상수 식을 잘못 변경했습니다. 식을 변경할 수 있는 로컬로 복사하십시오(예: 'let mutable x = ...'). @@ -6987,6 +6982,16 @@ '{0}' 파일이 디스크에서 예기치 않게 변경되었습니다. 다시 로드하세요. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index 2db955549e..c2e0e1e566 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -412,11 +412,6 @@ Nieoczekiwane użycie zmiennej typu byref - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - Aby można było zmodyfikować zawartość lub pobrać adres typu wartości, wartość musi być modyfikowalna, na przykład „let mutable x = ...” - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Nieprawidłowa mutacja wyrażenia stałej. Rozważ skopiowanie wyrażenia do modyfikowalnej wartości lokalnej, na przykład „let mutable x = ...”. @@ -6987,6 +6982,16 @@ Plik „{0}” nieoczekiwanie uległ zmianie na dysku. Załaduj go ponownie. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index c067bdd77e..aa0c9df006 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -412,11 +412,6 @@ Uso inesperado de uma variável do tipo byref - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - 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 = ...' - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Mutação inválida de uma expressão constante. Considere copiar a expressão para um local mutável, por exemplo: 'let mutable x = ...'. @@ -6987,6 +6982,16 @@ O arquivo '{0}' foi alterado no disco inesperadamente. Recarregue-o. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 03aef1b881..c75ded78a0 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -412,11 +412,6 @@ Недопустимое использование переменной типа byref - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - Чтобы изменить содержимое или получить адрес типа значения, значение должно быть изменяемым, например, "let mutable x = ..." - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Недопустимое изменение константного выражения. Рекомендуется скопировать выражение в изменяемую локальную переменную, например, "let mutable x = ...". @@ -6987,6 +6982,16 @@ Файл "{0}" был неожиданно изменен на диске, повторите загрузку. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index e09c9914db..0680ce1f90 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -412,11 +412,6 @@ Beklenmeyen byref olarak belirtilmiş değişken kullanımı - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - İç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 = ...' - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. Sabit ifadesinin geçersiz olarak değiştirilmesi. İfadeyi değiştirilebilir bir yerel değere kopyalamayı düşünün, örn. 'let mutable x = ...'. @@ -6987,6 +6982,16 @@ Diskte '{0}' dosyası beklenmedik şekilde değiştirildi. Lütfen yeniden yükleyin. + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 3f87c23463..f1903ea501 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -412,11 +412,6 @@ 对 byref 类型化变量的意外使用 - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - 值必须是可变的,以便更改内容或采用值类型的地址,例如“let mutable x = ...” - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. 常数表达式的变化无效。请考虑将该表达式复制一个可变的本地变量,例如“let mutable x = ...”。 @@ -6987,6 +6982,16 @@ 文件“{0}”在磁盘上意外更改,请重新加载。 + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 56d15fc848..fe73e6d6f9 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -412,11 +412,6 @@ 未預期的 ByRef 類型變數用法 - - A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' - 值必須是可變動的,才能變動內容或接受實值類型的位址,例如 'let mutable x = ...' - - Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. 常數運算式無效的變動。請考慮將運算式複製到可變動的區域變數,例如 'let mutable x = ...'。 @@ -6987,6 +6982,16 @@ 檔案 '{0}' 在磁碟上意外變更,請重新載入。 + + The byref pointer is readonly, so this write is not permitted. + The byref pointer is readonly, so this write is not permitted. + + + + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + \ No newline at end of file diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index b0c8980c05..e85ca276f8 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -19,6 +19,131 @@ let check s actual expected = let check2 s expected actual = check s actual expected +// Test a simple ref argument +module CompareExchangeTests = + let mutable x = 3 + let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) + +#if NEG +module CompareExchangeTests_Negative1 = + let x = 3 + let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) + +module CompareExchangeTests_Negative2 = + let v = System.Threading.Interlocked.CompareExchange(&3, 3, 4) +#endif + +// Test a simple out argument +module TryGetValueTests = + let d = dict [ (3,4) ] + let mutable res = 9 + let v = d.TryGetValue(3, &res) + +#if NEG +module TryGetValueTests_Negative1 = + let d = dict [ (3,4) ] + let res = 9 + let v = d.TryGetValue(3, &res) +#endif + + +module FSharpDeclaredOutParamTest = + type C() = + static member M([] x: byref) = () + let mutable res = 9 + let v = C.M(&res) + + +module FSharpDeclaredOutParamTest2 = + type C() = + static member M([] x: outref) = () + let mutable res = 9 + let v = C.M(&res) + +module FSharpDeclaredOutParamTest3 = + type C() = + static member M(x: outref) = () + let mutable res = 9 + let v = C.M(&res) + +#if NEG +module FSharpDeclaredOutParamTest_Neagative1 = + type C() = + static member M([] x: byref) = () + let res = 9 + let v = C.M(&res) +#endif + +module FSharpDeclaredOverloadedOutParamTest = + type C() = + static member M(a: int, [] x: byref) = () + static member M(a: string, [] x: byref) = () + let mutable res = 9 + let v = C.M("a", &res) + let v2 = C.M(3, &res) + +module FSharpDeclaredOverloadedOutParamTest2 = + type C() = + static member M(a: int, [] x: outref) = () + static member M(a: string, [] x: outref) = () + let mutable res = 9 + let v = C.M("a", &res) + let v2 = C.M(3, &res) + +module FSharpDeclaredOverloadedOutParamTest3 = + type C() = + static member M(a: int, x: outref) = () + static member M(a: string, x: outref) = () + let mutable res = 9 + let v = C.M("a", &res) + let v2 = C.M(3, &res) + +#if NEG +module FSharpDeclaredOverloadedOutParamTest_Negative1 = + type C() = + static member M(a: int, [] x: byref) = () + static member M(a: string, [] x: byref) = () + let res = 9 + let v = C.M("a", &res) + let v2 = C.M(3, &res) + +module FSharpDeclaredOutParamTest_Negative1 = + type C() = + static member M([] x: byref) = () + let res = 9 + let v = C.M(&res) +#endif + +module FSharpDeclaredInParamTest = + type C() = + static member M([] x: inref) = () + let mutable res = 9 + let v = C.M(&res) + +module FSharpDeclaredInParamTest2 = + type C() = + static member M([] x: inref) = () + let res = System.DateTime.Now + let v = C.M(&res) + +module FSharpDeclaredInParamTest3 = + type C() = + static member M(x: inref) = () + let res = System.DateTime.Now + let v = C.M(&res) + +module FSharpDeclaredInParamTest4 = + type C() = + static member M(x: inref<'T>) = () + let res = "abc" + let v = C.M(&res) + +module FSharpDeclaredInParamTest5 = + type C() = + static member M(x: inref<'T>) = () + let res = "abc" + let v = C.M(&res) + module ByrefReturnTests = module TestImmediateReturn = @@ -27,13 +152,14 @@ module ByrefReturnTests = let f () = &x let test() = - let addr : byref = &f() + let addr : byref = f() addr <- addr + 1 check2 "cepojcwem1" 2 x let test2() = - let res = f() + 1 + let v = f() + let res = v + 1 check2 "cepojcwem1b" 3 res test() @@ -46,18 +172,18 @@ module ByrefReturnTests = let f inp = match inp with 3 -> &x | _ -> &y let test() = - let addr = &f 3 + let addr = f 3 addr <- addr + 1 check2 "cepojcwem2" 2 x check2 "cepojcwem3" 1 y - let addr = &f 4 + let addr = f 4 addr <- addr + 1 check2 "cepojcwem4" 2 x check2 "cepojcwem5" 2 y let test2() = let res = f 3 - let res2 = f 3 + 1 + let res2 = res + 1 check2 "cepojcwem2b" 3 res2 check2 "cepojcwem3b" 2 res @@ -71,18 +197,18 @@ module ByrefReturnTests = let f inp = if inp = 3 then &x else &y let test() = - let addr = &f 3 + let addr = f 3 addr <- addr + 1 check2 "cepojcwem6" 2 x check2 "cepojcwem7" 1 y - let addr = &f 4 + let addr = f 4 addr <- addr + 1 check2 "cepojcwem8" 2 x check2 "cepojcwem9" 2 y let test2() = let res = f 3 - let res2 = f 3 + 1 + let res2 = res + 1 check2 "cepojcwem8b" 3 res2 check2 "cepojcwem9b" 2 res @@ -96,18 +222,18 @@ module ByrefReturnTests = let f inp = try &x with _ -> &y let test() = - let addr = &f 3 + let addr = f 3 addr <- addr + 1 check2 "cepojcwem6b" 2 x check2 "cepojcwem7b" 1 y - let addr = &f 4 + let addr = f 4 addr <- addr + 1 check2 "cepojcwem8b" 3 x check2 "cepojcwem9b" 1 y let test2() = let res = f 3 - let res2 = f 3 + 1 + let res2 = res + 1 check2 "cepojcwem2ff" 4 res2 check2 "cepojcwem3gg" 3 res @@ -121,18 +247,18 @@ module ByrefReturnTests = let f inp = try &x with _ -> &y let test() = - let addr = &f 3 + let addr = f 3 addr <- addr + 1 check2 "cepojcwem6b" 2 x check2 "cepojcwem7b" 1 y - let addr = &f 4 + let addr = f 4 addr <- addr + 1 check2 "cepojcwem8b" 3 x check2 "cepojcwem9b" 1 y let test2() = let res = f 3 - let res2 = f 3 + 1 + let res2 = res + 1 check2 "cepojcwem2tf" 4 res2 check2 "cepojcwem3qw" 3 res @@ -145,7 +271,7 @@ module ByrefReturnTests = let test() = let mutable r1 = 1 - let addr = &f &r1 + let addr = f &r1 addr <- addr + 1 check2 "cepojcwem10" 2 r1 @@ -158,7 +284,7 @@ module ByrefReturnTests = let test() = let mutable r1 = 1 let mutable r2 = 0 - let addr = &f (&r1, &r2) + let addr = f (&r1, &r2) addr <- addr + 1 check2 "cepojcwem11" 2 r1 @@ -171,7 +297,7 @@ module ByrefReturnTests = let test() = let r = { z = 1 } - let addr = &f r + let addr = f r addr <- addr + 1 check2 "cepojcwem12" 2 r.z @@ -184,7 +310,7 @@ module ByrefReturnTests = let test() = let mutable r = { z = 1 } - let addr = &f &r + let addr = f &r addr <- addr + 1 check2 "cepojcwem13a" 2 r.z @@ -198,7 +324,7 @@ module ByrefReturnTests = let test() = let c = C() - let addr = &f c + let addr = f c addr <- addr + 1 check2 "cepojcwem13b" 1 c.z @@ -210,7 +336,7 @@ module ByrefReturnTests = let test() = let r = [| 1 |] - let addr = &f r + let addr = f r addr <- addr + 1 check2 "cepojcwem14" 2 r.[0] @@ -225,7 +351,7 @@ module ByrefReturnTests = let test() = let mutable r = { z = 1 } - let addr = &f &r + let addr = f &r addr <- addr + 1 check2 "cepojcwem15" 2 r.z @@ -248,9 +374,9 @@ module ByrefReturnTests = let f (i:I) = &i.M() let test() = - let addr = &f (C()) + let addr = f (C()) addr <- addr + 1 - let addr = &f (ObjExpr()) + let addr = f (ObjExpr()) addr <- addr + 1 check2 "cepojcwem16" 3 x @@ -273,9 +399,9 @@ module ByrefReturnTests = let f (i:I) = &i.P let test() = - let addr = &f (C()) + let addr = f (C()) addr <- addr + 1 - let addr = &f (ObjExpr()) + let addr = f (ObjExpr()) addr <- addr + 1 check2 "cepojcwem17" 3 x @@ -291,7 +417,7 @@ module ByrefReturnTests = let f (d:D) = &d.Invoke() let test() = - let addr = &f (d()) + let addr = f (d()) check2 "cepojcwem18a" 1 x addr <- addr + 1 check2 "cepojcwem18b" 2 x @@ -321,13 +447,368 @@ module ByrefReturnTests = let f (d:D) = &d.Invoke(&x) let test() = - let addr = &f (d()) + let addr = f (d()) check2 "cepojcwem18a2" 1 x addr <- addr + 1 check2 "cepojcwem18b3" 2 x test() +module ByrefReturnMemberTests = + + module TestImmediateReturn = + let mutable x = 1 + + type C() = + static member M () = &x + + let test() = + let addr : byref = &C.M() + addr <- addr + 1 + check2 "mepojcwem1" 2 x + + + let test2() = + let v = &C.M() + let res = v + 1 + check2 "mepojcwem1b" 3 res + + test() + test2() + + module TestMatchReturn = + let mutable x = 1 + let mutable y = 1 + + type C() = + static member M inp = match inp with 3 -> &x | _ -> &y + + let test() = + let addr = &C.M 3 + addr <- addr + 1 + check2 "mepojcwem2" 2 x + check2 "mepojcwem3" 1 y + let addr = &C.M 4 + addr <- addr + 1 + check2 "mepojcwem4" 2 x + check2 "mepojcwem5" 2 y + + let test2() = + let res = &C.M 3 + let res2 = res + 1 + check2 "mepojcwem2b" 3 res2 + check2 "mepojcwem3b" 2 res + + test() + test2() + + module TestConditionalReturn = + let mutable x = 1 + let mutable y = 1 + + type C() = + static member M inp = if inp = 3 then &x else &y + + let test() = + let addr = &C.M 3 + addr <- addr + 1 + check2 "mepojcwem6" 2 x + check2 "mepojcwem7" 1 y + let addr = &C.M 4 + addr <- addr + 1 + check2 "mepojcwem8" 2 x + check2 "mepojcwem9" 2 y + + let test2() = + let res = &C.M 3 + let res2 = res + 1 + check2 "mepojcwem8b" 3 res2 + check2 "mepojcwem9b" 2 res + + test() + test2() + + module TestTryCatchReturn = + let mutable x = 1 + let mutable y = 1 + + type C() = + static member M inp = try &x with _ -> &y + + let test() = + let addr = &C.M 3 + addr <- addr + 1 + check2 "mepojcwem6b" 2 x + check2 "mepojcwem7b" 1 y + let addr = &C.M 4 + addr <- addr + 1 + check2 "mepojcwem8b" 3 x + check2 "mepojcwem9b" 1 y + + let test2() = + let res = &C.M 3 + let res2 = res + 1 + check2 "mepojcwem2ff" 4 res2 + check2 "mepojcwem3gg" 3 res + + test() + test2() + + module TestTryFinallyReturn = + let mutable x = 1 + let mutable y = 1 + + type C() = + static member M inp = try &x with _ -> &y + + let test() = + let addr = &C.M 3 + addr <- addr + 1 + check2 "mepojcwem6b" 2 x + check2 "mepojcwem7b" 1 y + let addr = &C.M 4 + addr <- addr + 1 + check2 "mepojcwem8b" 3 x + check2 "mepojcwem9b" 1 y + + let test2() = + let res = &C.M 3 + let res2 = res + 1 + check2 "mepojcwem2tf" 4 res2 + check2 "mepojcwem3qw" 3 res + + test() + test2() + + module TestOneArgument = + + type C() = + static member M (x:byref) = &x + + let test() = + let mutable r1 = 1 + let addr = &C.M (&r1) + addr <- addr + 1 + check2 "mepojcwem10" 2 r1 + + test() + +#if NEG + module TestOneArgumentInRefThenMutate_Negative1 = + + type C() = + static member M (x:inref) = &x + + let test() = + let mutable r1 = 1 + let addr = &C.M (&r1) + addr <- addr + 1 // "The byref pointer is readonly, so this write is not permitted" + check2 "mepojcwem10" 2 r1 + + test() +#endif + + module TestOneArgumentInRefReturned = + + type C() = + static member M (x:inref) = &x + + let test() = + let mutable r1 = 1 + let addr = &C.M (&r1) + let x = addr + 1 + check2 "mepojcwem10" 1 r1 + check2 "mepojcwem10vr" 2 x + + test() + + module TestOneArgumentOutRef = + + type C() = + static member M (x:outref) = &x + + let test() = + let mutable r1 = 1 + let addr = &C.M (&r1) + addr <- addr + 1 + check2 "mepojcwem10" 2 r1 + + test() + + module TestTwoArguments = + + type C() = + static member M (x:byref, y:byref) = &x + + let test() = + let mutable r1 = 1 + let mutable r2 = 0 + let addr = &C.M (&r1, &r2) + addr <- addr + 1 + check2 "mepojcwem11" 2 r1 + + test() + + module TestRecordParam = + + type R = { mutable z : int } + type C() = + static member M (x:R) = &x.z + + let test() = + let r = { z = 1 } + let addr = &C.M r + addr <- addr + 1 + check2 "mepojcwem12" 2 r.z + + test() + + module TestRecordParam2 = + + type R = { mutable z : int } + type C() = + static member M (x:byref) = &x.z + + let test() = + let mutable r = { z = 1 } + let addr = &C.M(&r) + addr <- addr + 1 + check2 "mepojcwem13a" 2 r.z + + test() + + module TestClassParamMutableField = + + type C() = [] val mutable z : int + + type C2() = + static member M (x:C) = &x.z + + let test() = + let c = C() + let addr = &C2.M c + addr <- addr + 1 + check2 "mepojcwem13b" 1 c.z + + test() + + module TestArrayParam = + + type C() = + static member M (x:int[]) = &x.[0] + + let test() = + let r = [| 1 |] + let addr = &C.M r + addr <- addr + 1 + check2 "mepojcwem14" 2 r.[0] + + test() + + module TestStructParam = + + [] + type R = { mutable z : int } + + type C() = + static member M (x:byref) = &x.z + + let test() = + let mutable r = { z = 1 } + let addr = &C.M(&r) + addr <- addr + 1 + check2 "mepojcwem15" 2 r.z + + test() + + module TestInterfaceMethod = + let mutable x = 1 + + type I = + abstract M : unit -> byref + + type C() = + interface I with + member this.M() = &x + + let ObjExpr() = + { new I with + member this.M() = &x } + + let test() = + let addr = &(C() :> I).M() + addr <- addr + 1 + let addr = &(ObjExpr()).M() + addr <- addr + 1 + check2 "mepojcwem16" 3 x + + test() + + module TestInterfaceProperty = + let mutable x = 1 + + type I = + abstract P : byref + + type C() = + interface I with + member this.P = &x + + let ObjExpr() = + { new I with + member this.P = &x } + + let test() = + let addr = &(C() :> I).P + addr <- addr + 1 + let addr = &(ObjExpr()).P + addr <- addr + 1 + check2 "mepojcwem17" 3 x + + test() + + module TestDelegateMethod = + let mutable x = 1 + + type D = delegate of unit -> byref + + let test() = + let d = D(fun () -> &x) + let addr = &d.Invoke() + check2 "mepojcwem18a" 1 x + addr <- addr + 1 + check2 "mepojcwem18b" 2 x + + test() + + module TestBaseCall = + type Incrementor(z) = + abstract member Increment : int byref * int byref -> unit + default this.Increment(i : int byref,j : int byref) = + i <- i + z + + type Decrementor(z) = + inherit Incrementor(z) + override this.Increment(i, j) = + base.Increment(&i, &j) + + i <- i - z + + module TestDelegateMethod2 = + let mutable x = 1 + + type D = delegate of byref -> byref + + let d = D(fun xb -> &xb) + + let test() = + let addr = &d.Invoke(&x) + check2 "mepojcwem18a2" 1 x + addr <- addr + 1 + check2 "mepojcwem18b3" 2 x + + test() + let aa = if !failures then (stdout.WriteLine "Test Failed"; exit 1) diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index d983522137..04d8878eb9 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -140,7 +140,19 @@ namespace Test //let dt2 = DateTime.Now.ExtDateTime2(3) + + [] + type AllowedEvilStruct = + [] + val mutable v : int + member x.Replace(y:AllowedEvilStruct) = x <- y + + (* + [] + type EvilStruct(s: int) = + member x.Replace(y:EvilStruct) = x <- y + module Negative = let TestClosure1 ([] a: byref) = id (fun () -> a) let TestClosure2 ([] a: Span) = id (fun () -> a) diff --git a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs index 331453ae38..eae479ef9e 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs @@ -490,21 +490,6 @@ type internal FsiToolWindow() as this = match RegistryHelpers.tryReadHKCU (defaultVSRegistryRoot + "\\" + settingsRegistrySubKey) debugPromptRegistryValue with | Some(1) -> true // warning dialog suppressed | _ -> -#if VS_VERSION_DEV12 - let result = - VsShellUtilities.ShowMessageBox( - serviceProvider = provider, - message = VFSIstrings.SR.sessionIsNotDebugFriendly(), - title = VFSIstrings.SR.fsharpInteractive(), - icon = OLEMSGICON.OLEMSGICON_WARNING, - msgButton = OLEMSGBUTTON.OLEMSGBUTTON_YESNO, - defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST - ) - - // if user picks YES, allow debugging anyways - result = 6 - -#else let mutable suppressDiag = false let result = Microsoft.VisualStudio.PlatformUI.MessageDialog.Show( @@ -520,7 +505,6 @@ type internal FsiToolWindow() as this = // if user picks YES, allow debugging anyways result = Microsoft.VisualStudio.PlatformUI.MessageDialogCommand.Yes -#endif let onAttachDebugger (sender:obj) (args:EventArgs) = if checkDebuggability() then From 47b83d95edebdadca36e1ba6c515b89701b7adea Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 15 May 2018 13:25:53 +0100 Subject: [PATCH 25/61] fix proto build --- src/fsharp/TastOps.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 9346ccda25..d1d24b8ac4 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -694,7 +694,7 @@ let rec stripTyEqnsA g canShortcut ty = stripTyEqnsA g canShortcut (applyTyconAbbrev abbrevTy tycon tinst) | None -> // Add the equation `byref<'T> = byref<'T, ByRefKinds.InOut> for F# 4.5+ when using FSharp.Core 4.5.0.0+ - if tyconRefEq g tcref g.byref_tcr && g.byref2_tcr.CanDeref then + 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, [])) elif tycon.IsMeasureableReprTycon && List.forall (isDimensionless g) tinst then stripTyEqnsA g canShortcut (reduceTyconMeasureableOrProvided g tycon tinst) From fe4abce867eacb891ca0b94831e6e7d4af67c0c0 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Tue, 15 May 2018 20:00:48 +0100 Subject: [PATCH 26/61] update baselines, byref extension methods --- packages.config | 3 + src/fsharp/ConstraintSolver.fs | 6 +- src/fsharp/MethodCalls.fs | 127 ++++++++------ src/fsharp/NameResolution.fs | 2 +- src/fsharp/PostInferenceChecks.fs | 4 +- src/fsharp/TastOps.fs | 4 +- src/fsharp/TastOps.fsi | 2 +- src/fsharp/TypeChecker.fs | 106 ++++++------ src/fsharp/import.fs | 2 +- src/fsharp/infos.fs | 9 +- tests/fsharp/core/byrefs/test.fsx | 166 +++++++++++-------- tests/fsharp/core/span/test.fsx | 33 +--- tests/fsharp/tests.fs | 64 ++++++- tests/fsharp/typecheck/sigs/neg106.bsl | 4 + tests/fsharp/typecheck/sigs/neg106.fs | 60 +++++++ tests/fsharp/typecheck/sigs/neg106.vsbsl | 84 ++++++++++ tests/fsharp/typecheck/sigs/neg107.bsl | 60 +++++++ tests/fsharp/typecheck/sigs/neg107.fsx | 37 +++++ tests/fsharp/typecheck/sigs/neg107.vsbsl | 60 +++++++ tests/fsharp/typecheck/sigs/neg97.bsl | 2 +- tests/fsharp/typecheck/sigs/neg97.vsbsl | 28 ++++ tests/fsharp/typecheck/sigs/neg_byref_17.bsl | 12 +- tests/fsharp/typecheck/sigs/neg_byref_22.bsl | 10 -- 23 files changed, 649 insertions(+), 236 deletions(-) create mode 100644 tests/fsharp/typecheck/sigs/neg106.bsl create mode 100644 tests/fsharp/typecheck/sigs/neg106.fs create mode 100644 tests/fsharp/typecheck/sigs/neg106.vsbsl create mode 100644 tests/fsharp/typecheck/sigs/neg107.bsl create mode 100644 tests/fsharp/typecheck/sigs/neg107.fsx create mode 100644 tests/fsharp/typecheck/sigs/neg107.vsbsl create mode 100644 tests/fsharp/typecheck/sigs/neg97.vsbsl diff --git a/packages.config b/packages.config index f922611d5c..2d4353c743 100644 --- a/packages.config +++ b/packages.config @@ -36,8 +36,11 @@ + + + diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 37492725a2..f184a2ddea 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -1913,7 +1913,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. @@ -1965,7 +1965,7 @@ 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 @@ -2456,7 +2456,7 @@ and ResolveOverloading | None -> CompleteD | Some _ when calledMeth.Method.IsConstructor -> CompleteD | Some reqdRetTy -> - let actualRetTy = calledMeth.ReturnTypeAfterOutArgTupling + let actualRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy) | None -> diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index 3b5dc37f80..81d7942b9e 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -128,48 +128,59 @@ 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 isByrefTy g callerArgTy then - calledArgTy + 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 - mkRefCellTy g (destByrefTy g calledArgTy) - else - // If the called method argument is a delegate type, then the caller may provide a function - let calledArgTy = - let adjustDelegateTy calledTy = - let (SigOfFunctionForDelegate(_, delArgTys, _, fty)) = GetSigOfFunctionForDelegate infoReader calledTy m AccessibleFromSomewhere - let delArgTys = if isNil delArgTys then [g.unit_ty] else delArgTys - if (fst (stripFunTy g callerArgTy)).Length = delArgTys.Length - then fty - else calledArgTy - - if isDelegateTy g calledArgTy && isFunTy g callerArgTy then - adjustDelegateTy calledArgTy - - elif isLinqExpressionTy g calledArgTy && isFunTy g callerArgTy then - let origArgTy = calledArgTy - let calledArgTy = destLinqExpressionTy g calledArgTy - if isDelegateTy g calledArgTy then + // If the called method argument is a delegate type, then the caller may provide a function + let calledArgTy = + let adjustDelegateTy calledTy = + let (SigOfFunctionForDelegate(_, delArgTys, _, fty)) = GetSigOfFunctionForDelegate infoReader calledTy m AccessibleFromSomewhere + let delArgTys = if isNil delArgTys then [g.unit_ty] else delArgTys + if (fst (stripFunTy g callerArgTy)).Length = delArgTys.Length + then fty + else calledArgTy + + if isDelegateTy g calledArgTy && isFunTy g callerArgTy then adjustDelegateTy calledArgTy - else - // BUG 435170: called arg is Expr<'t> where 't is not delegate - such conversion is not legal -> return original type - origArgTy - - elif calledArg.ReflArgInfo.AutoQuote && isQuotedExprTy g calledArgTy && not (isQuotedExprTy g callerArgTy) then - destQuotedExprTy g calledArgTy - - else calledArgTy - - // Adjust the called argument type to take into account whether the caller's argument is M(?arg=Some(3)) or M(arg=1) - // If the called method argument is optional with type Option, then the caller may provide a T, unless their argument is propagating-optional (i.e. isOptCallerArg) - let calledArgTy = - match calledArg.OptArgInfo with - | NotOptional -> calledArgTy - | CalleeSide when not callerArg.IsOptional && isOptionTy g calledArgTy -> destOptionTy g calledArgTy - | CalleeSide | CallerSide _ -> calledArgTy - calledArgTy + + elif isLinqExpressionTy g calledArgTy && isFunTy g callerArgTy then + let origArgTy = calledArgTy + let calledArgTy = destLinqExpressionTy g calledArgTy + if isDelegateTy g calledArgTy then + adjustDelegateTy calledArgTy + else + // BUG 435170: called arg is Expr<'t> where 't is not delegate - such conversion is not legal -> return original type + origArgTy + + elif calledArg.ReflArgInfo.AutoQuote && isQuotedExprTy g calledArgTy && not (isQuotedExprTy g callerArgTy) then + destQuotedExprTy g calledArgTy + + else calledArgTy + + // Adjust the called argument type to take into account whether the caller's argument is M(?arg=Some(3)) or M(arg=1) + // If the called method argument is optional with type Option, then the caller may provide a T, unless their argument is propagating-optional (i.e. isOptCallerArg) + let calledArgTy = + match calledArg.OptArgInfo with + | NotOptional -> calledArgTy + | CalleeSide when not callerArg.IsOptional && isOptionTy g calledArgTy -> destOptionTy g calledArgTy + | CalleeSide | CallerSide _ -> calledArgTy + calledArgTy //------------------------------------------------------------------------- @@ -353,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 @@ -376,13 +388,13 @@ type CalledMeth<'T> member x.ArgSets = argSets /// return type after implicit deference of byref returns is taken into account - member x.ReturnTypeAfterByrefDeref = + 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.ReturnTypeAfterByrefDeref + member x.CalledReturnTypeAfterOutArgTupling = + let retTy = x.CalledReturnTypeAfterByrefDeref if isNil unnamedCalledOutArgs then retTy else @@ -410,19 +422,31 @@ type CalledMeth<'T> static member GetMethod (x:CalledMeth<'T>) = x.Method - member x.NumArgSets = x.ArgSets.Length + member x.NumArgSets = x.ArgSets.Length + + member x.HasOptArgs = not (isNil x.UnnamedCalledOptArgs) + + member x.HasOutArgs = not (isNil x.UnnamedCalledOutArgs) - member x.HasOptArgs = not (isNil x.UnnamedCalledOptArgs) - member x.HasOutArgs = not (isNil x.UnnamedCalledOutArgs) member x.UsesParamArrayConversion = x.ArgSets |> List.exists (fun argSet -> argSet.ParamArrayCalledArgOpt.IsSome) + member x.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 @@ -456,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) = @@ -552,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', _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 diff --git a/src/fsharp/NameResolution.fs b/src/fsharp/NameResolution.fs index ce0d34a1c2..ee6527f90d 100644 --- a/src/fsharp/NameResolution.fs +++ b/src/fsharp/NameResolution.fs @@ -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 diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index b3e08d77ea..78cf083b2e 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -937,7 +937,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn CheckNoReraise cenv freesOpt body // Check the body of the lambda - if (not (isNil tps) || not (isNil vsl)) && isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g m bodyty then + if (* (not (isNil tps) || not (isNil vsl)) && *) isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g m bodyty then // allow byref to occur as return position for byref-typed top level function or method CheckExprPermitByrefReturn cenv env body else @@ -945,7 +945,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // Check byref return types if cenv.reportErrors then - if (not inlined && (isNil tps && isNil vsl)) || not isTop then + if (* (not inlined && (isNil tps && isNil vsl)) || *) not isTop then CheckForByrefLikeType cenv env m bodyty (fun () -> errorR(Error(FSComp.SR.chkFirstClassFuncNoByref(), m))) diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index d1d24b8ac4..1c0845321b 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -563,9 +563,9 @@ let tryNormalizeMeasureInType g ty = let mkNativePtrTy (g:TcGlobals) ty = TType_app (g.nativeptr_tcr, [ty]) let mkByrefTy (g:TcGlobals) ty = TType_app (g.byref_tcr, [ty]) -let mkInrefTy (g:TcGlobals) ty = TType_app (g.inref_tcr, [ty]) +let mkInByrefTy (g:TcGlobals) ty = TType_app (g.inref_tcr, [ty]) let mkOutrefTy (g:TcGlobals) ty = TType_app (g.outref_tcr, [ty]) -let mkByrefTyWithFlag g readonly ty = (if readonly then mkInrefTy g 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 FSharp.Core 4.5.0.0+ diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index c1846a2d98..5125de4b4f 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -165,7 +165,7 @@ 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 mkInrefTy : TcGlobals -> TType -> TType +val mkInByrefTy : TcGlobals -> TType -> TType val mkOutrefTy : TcGlobals -> TType -> TType //------------------------------------------------------------------------- diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index ae8b3b0d1f..a697c2c771 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -2640,7 +2640,7 @@ let FreshenObjectArgType cenv m rigid tcref isExtrinsic declaredTyconTypars = let thisTy = if not isExtrinsic && tcref.IsStructOrEnumTycon then if isRecdOrStructTyReadOnly cenv.g m objTy then - mkInrefTy cenv.g objTy + mkInByrefTy cenv.g objTy else mkByrefTy cenv.g objTy else @@ -3981,13 +3981,11 @@ let buildApp cenv expr resultTy arg m = 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', readonly = mkExprAddrOfExpr g true false AddressOfOp arg (Some(vf)) m - // Assert the result type to be readonly if argument is readonly struct + // Assert the result type to be readonly if we couldn't take the address let resultTy = let argTy = tyOfExpr g arg if readonly then - let expected = mkInrefTy g argTy -// UnifyTypes cenv env m resultTy expected - expected + mkInByrefTy g argTy else mkByrefTyWithInference g argTy (NewInferenceType()) // resultTy @@ -9688,58 +9686,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 false, [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 cenv.g calledArgTy && not (isByrefTy cenv.g callerArgTy) then - let tmp, _ = mkCompGenLocal m "copyOfStruct" callerArgTy - failwith "no auto conv yet - scope of tmp not right" - mkCompGenLet m tmp callerArgExpr (mkValAddr m true (mkLocalValRef tmp)) + 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 = - match finalCalledMeth.ParamArrayCalledArgOpt with - | None -> [] - | Some paramArrayCalledArg -> - let paramArrayCalledArgElementType = destArrayTy cenv.g paramArrayCalledArg.CalledArgumentType - - let es = - finalParamArrayCallerArgs |> List.map (fun callerArg -> - let (CallerArg(callerArgTy, m, isOutArg, callerArgExpr)) = callerArg - coerceExpr isOutArg paramArrayCalledArgElementType paramArrayCalledArg.ReflArgInfo callerArgTy m callerArgExpr) - - [ { NamedArgIdOpt = None; CalledArg=paramArrayCalledArg; CallerArg=CallerArg(paramArrayCalledArg.CalledArgumentType, mMethExpr, false, Expr.Op(TOp.Array, [paramArrayCalledArgElementType], es , mMethExpr)) } ] + let paramArrayPreBinders, paramArrayArgs = + match finalCalledMeth.ParamArrayCalledArgOpt with + | None -> + [], [] + | Some paramArrayCalledArg -> + let paramArrayCalledArgElementType = destArrayTy cenv.g paramArrayCalledArg.CalledArgumentType + + 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 + + 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" // @@ -9900,7 +9905,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 @@ -9918,7 +9923,7 @@ 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 = @@ -9945,51 +9950,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 = @@ -10015,6 +10023,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 diff --git a/src/fsharp/import.fs b/src/fsharp/import.fs index 5635c0b45b..8d862e98c6 100644 --- a/src/fsharp/import.fs +++ b/src/fsharp/import.fs @@ -168,7 +168,7 @@ 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" -> mkInrefTy env.g (ImportILType env m tinst ty) + | 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) diff --git a/src/fsharp/infos.fs b/src/fsharp/infos.fs index 9de3aabf3a..3e03de4930 100755 --- a/src/fsharp/infos.fs +++ b/src/fsharp/infos.fs @@ -1183,6 +1183,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 @@ -1552,7 +1559,7 @@ type MethInfo = let g = x.TcGlobals let pty = // add the "annotation" about whether this is an inref, outref or plain byref - if isByrefTy g pty && isInArg then mkInrefTy g (destByrefTy g pty) + if isByrefTy g pty && isInArg then mkInByrefTy g (destByrefTy g pty) elif isByrefTy g pty && isOutArg then mkOutrefTy g (destByrefTy g pty) else pty ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, nmOpt, reflArgInfo, pty))) diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index e85ca276f8..c94fda4a5e 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -22,97 +22,73 @@ let check2 s expected actual = check s actual expected // Test a simple ref argument module CompareExchangeTests = let mutable x = 3 - let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) - -#if NEG -module CompareExchangeTests_Negative1 = - let x = 3 - let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) - -module CompareExchangeTests_Negative2 = - let v = System.Threading.Interlocked.CompareExchange(&3, 3, 4) -#endif + let v = System.Threading.Interlocked.CompareExchange(&x, 4, 3) + check "cweweoiwekla" v 3 + let v2 = System.Threading.Interlocked.CompareExchange(&x, 5, 3) + check "cweweoiweklb" v2 4 // Test a simple out argument module TryGetValueTests = let d = dict [ (3,4) ] let mutable res = 9 let v = d.TryGetValue(3, &res) - -#if NEG -module TryGetValueTests_Negative1 = - let d = dict [ (3,4) ] - let res = 9 - let v = d.TryGetValue(3, &res) -#endif - + check "cweweoiwekl1" v true + check "cweweoiwekl2" res 4 + let v2 = d.TryGetValue(5, &res) + check "cweweoiwekl3" v2 false + check "cweweoiwekl4" res 4 module FSharpDeclaredOutParamTest = type C() = - static member M([] x: byref) = () + static member M([] x: byref) = x <- 5 let mutable res = 9 let v = C.M(&res) + check "cwvereweoiwekl4" res 5 module FSharpDeclaredOutParamTest2 = type C() = - static member M([] x: outref) = () + static member M([] x: outref) = x <- 5 let mutable res = 9 let v = C.M(&res) + check "cweweoiweklceew4" res 5 module FSharpDeclaredOutParamTest3 = type C() = - static member M(x: outref) = () + static member M(x: outref) = x <- 5 let mutable res = 9 let v = C.M(&res) - -#if NEG -module FSharpDeclaredOutParamTest_Neagative1 = - type C() = - static member M([] x: byref) = () - let res = 9 - let v = C.M(&res) -#endif + check "cweweoiwek28989" res 5 module FSharpDeclaredOverloadedOutParamTest = type C() = - static member M(a: int, [] x: byref) = () - static member M(a: string, [] x: byref) = () + static member M(a: int, [] x: byref) = x <- 7 + static member M(a: string, [] x: byref) = x <- 8 let mutable res = 9 let v = C.M("a", &res) + check "cweweoiwek2cbe9" res 8 let v2 = C.M(3, &res) + check "cweweoiwek28498" res 7 module FSharpDeclaredOverloadedOutParamTest2 = type C() = - static member M(a: int, [] x: outref) = () - static member M(a: string, [] x: outref) = () + static member M(a: int, [] x: outref) = x <- 7 + static member M(a: string, [] x: outref) = x <- 8 let mutable res = 9 let v = C.M("a", &res) + check "cweweoiwek2v90" res 8 let v2 = C.M(3, &res) + check "cweweoiwek2c98" res 7 module FSharpDeclaredOverloadedOutParamTest3 = type C() = - static member M(a: int, x: outref) = () - static member M(a: string, x: outref) = () + static member M(a: int, x: outref) = x <- 7 + static member M(a: string, x: outref) = x <- 8 let mutable res = 9 let v = C.M("a", &res) + check "cweweoiwek2v99323" res 8 let v2 = C.M(3, &res) - -#if NEG -module FSharpDeclaredOverloadedOutParamTest_Negative1 = - type C() = - static member M(a: int, [] x: byref) = () - static member M(a: string, [] x: byref) = () - let res = 9 - let v = C.M("a", &res) - let v2 = C.M(3, &res) - -module FSharpDeclaredOutParamTest_Negative1 = - type C() = - static member M([] x: byref) = () - let res = 9 - let v = C.M(&res) -#endif + check "cweweoiwe519" res 7 module FSharpDeclaredInParamTest = type C() = @@ -132,17 +108,50 @@ module FSharpDeclaredInParamTest3 = let res = System.DateTime.Now let v = C.M(&res) +module FSharpDeclaredInParamTest3a = + type C() = + static member M(x: inref) = () + let w = System.DateTime.Now + let v = C.M(w) + +module FSharpDeclaredInParamTest3b = + type C() = + static member M(x: inref) = () + let v = C.M(System.DateTime.Now) + +module FSharpDeclaredInParamTest3c = + type C() = + static member M(x: inref) = () + let v = C.M(System.DateTime.Now.AddDays(1.0)) + +module FSharpDeclaredInParamTest3d = + type C() = + static member M(x: inref) = () + let mutable w = System.DateTime.Now + let v = C.M(w) + +module FSharpDeclaredInParamTest3e = + type C() = + static member M(x: inref) = x + let date = System.DateTime.Now.Date + let w = [| date |] + let v = C.M(w.[0]) + check "lmvjvwo1" v date + module FSharpDeclaredInParamTest4 = type C() = - static member M(x: inref<'T>) = () + static member M(x: inref<'T>) = x let res = "abc" let v = C.M(&res) + check "lmvjvwo2" res "abc" + check "lmvjvwo3" v "abc" module FSharpDeclaredInParamTest5 = type C() = - static member M(x: inref<'T>) = () + static member M(x: inref<'T>) = x let res = "abc" let v = C.M(&res) + check "lmvjvwo4" v "abc" module ByrefReturnTests = @@ -593,21 +602,6 @@ module ByrefReturnMemberTests = test() -#if NEG - module TestOneArgumentInRefThenMutate_Negative1 = - - type C() = - static member M (x:inref) = &x - - let test() = - let mutable r1 = 1 - let addr = &C.M (&r1) - addr <- addr + 1 // "The byref pointer is readonly, so this write is not permitted" - check2 "mepojcwem10" 2 r1 - - test() -#endif - module TestOneArgumentInRefReturned = type C() = @@ -810,6 +804,42 @@ module ByrefReturnMemberTests = test() + module ByRefExtensionMethods1 = + + open System + open System.Runtime.CompilerServices + + [] + type Ext = + + [] + static member ExtDateTime2(dt: inref, x:int) = dt.AddDays(double x) + + module UseExt = + let now = DateTime.Now + let dt2 = now.ExtDateTime2(3) + check "£f3mllkm2" dt2 (now.AddDays(3.0)) + + +(* + module ByRefExtensionMethodsOverloading = + + open System + open System.Runtime.CompilerServices + + [] + type Ext = + [] + static member ExtDateTime(dt: DateTime, x:int) = dt.AddDays(double x) + + [] + static member ExtDateTime(dt: inref, x:int) = dt.AddDays(2.0 * double x) + + module UseExt = + let dt = DateTime.Now.ExtDateTime(3) + let dt2 = DateTime.Now.ExtDateTime(3) +*) + let aa = if !failures then (stdout.WriteLine "Test Failed"; exit 1) else (stdout.WriteLine "Test Passed"; diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index 04d8878eb9..fff5fc65ac 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -1,5 +1,5 @@ #r @"..\..\..\..\packages\System.Memory.4.5.0-rc1\lib\netstandard2.0\System.Memory.dll" -#r @"C:\Users\dsyme\.nuget\packages\NETStandard.Library.NETFramework\2.0.0-preview2-25405-01\build\net461\ref\netstandard.dll" +#r @"..\..\..\..\packages\NETStandard.Library.NETFramework.2.0.0-preview2-25405-01\build\net461\ref\netstandard.dll" namespace System.Runtime.CompilerServices @@ -123,22 +123,6 @@ namespace Test SafeSum(stackSpan) |> printfn "res = %d" f6() - module ReadOnlyIn = - - let TestInAttribute1 ([] a: byref) = a - - [] - type Ext = - [] - static member ExtDateTime(dt: DateTime, x:int) = dt.AddDays(double x) - - [] - static member ExtDateTime2([] dt: byref, x:int) = dt.AddDays(double x) - - module UseExt = - let dt = DateTime.Now.ExtDateTime(3) - //let dt2 = DateTime.Now.ExtDateTime2(3) - [] @@ -148,21 +132,6 @@ namespace Test member x.Replace(y:AllowedEvilStruct) = x <- y -(* - [] - type EvilStruct(s: int) = - member x.Replace(y:EvilStruct) = x <- y - - module Negative = - let TestClosure1 ([] a: byref) = id (fun () -> a) - let TestClosure2 ([] a: Span) = id (fun () -> a) - let TestClosure3 ([] a: ReadOnlySpan) = id (fun () -> a) - - let TestAsyncClosure1 ([] a: byref) = async { return a } - let TestAsyncClosure2 ([] a: Span) = async { return a } - let TestAsyncClosure3 ([] a: ReadOnlySpan) = async { return a } -*) - //Since in parameters are read-only ref parameters, all ref parameter limitations apply. // //Cannot apply with an iterator method (I.e. method that has yield statements.) diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 15fcd5b8e6..063a4bcdc0 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -170,25 +170,67 @@ module CoreTests = [] let ``attributes-FSI_BASIC`` () = singleTestBuildAndRun "core/attributes" FSI_BASIC -#endif -#if !FSHARP_SUITE_DRIVES_CORECLR_TESTS [] let byrefs () = let cfg = testConfig "core/byrefs" - use testOkFile = fileguard cfg "test.ok" + begin + use testOkFile = fileguard cfg "test.ok" - fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"] + fsc cfg "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"] - exec cfg ("." ++ "test.exe") "" + exec cfg ("." ++ "test.exe") "" - testOkFile.CheckExists() + testOkFile.CheckExists() + end - fsi cfg "" ["test.fsx"] + begin + use testOkFile = fileguard cfg "test.ok" + fsi cfg "" ["test.fsx"] - testOkFile.CheckExists() + testOkFile.CheckExists() + end + + begin + + use testOkFile = fileguard cfg "test.ok" + + fsiAnyCpu cfg "" ["test.fsx"] + + testOkFile.CheckExists() + end + + [] + 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 #endif [] @@ -2237,6 +2279,12 @@ module TypecheckTests = [] let ``type check neg102`` () = singleNegTest (testConfig "typecheck/sigs") "neg102" + [] + let ``type check neg106`` () = singleNegTest (testConfig "typecheck/sigs") "neg106" + + [] + let ``type check neg107`` () = singleNegTest (testConfig "typecheck/sigs") "neg107" + [] let ``type check neg_issue_3752`` () = singleNegTest (testConfig "typecheck/sigs") "neg_issue_3752" diff --git a/tests/fsharp/typecheck/sigs/neg106.bsl b/tests/fsharp/typecheck/sigs/neg106.bsl new file mode 100644 index 0000000000..c3dfc5415c --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg106.bsl @@ -0,0 +1,4 @@ + +neg106.fs(22,24,22,25): parse error FS0010: Unexpected quote symbol in binding. Expected incomplete structured construct at or before this point or other token. + +neg106.fs(24,1,24,7): parse error FS0010: Incomplete structured construct at or before this point in definition. Expected incomplete structured construct at or before this point or other token. diff --git a/tests/fsharp/typecheck/sigs/neg106.fs b/tests/fsharp/typecheck/sigs/neg106.fs new file mode 100644 index 0000000000..efec084135 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg106.fs @@ -0,0 +1,60 @@ +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'. 'byref' is not compatible with type 'byref' + +module CompareExchangeTests_Negative2 = + let v = System.Threading.Interlocked.CompareExchange(&3, 3, 4) // 'byref' is not compatible with type 'byref' + +module TryGetValueTests_Negative1 = + let d = dict [ (3,4) ] + let res = 9 + let v = d.TryGetValue(3, &res) // 'byref' is not compatible with type 'byref' + +module FSharpDeclaredOutParamTest_Neagative1 = + type C() = + static member M([] x: byref) = () + let res = 9 + let v = C.M(&res) 'byref' is not compatible with type 'byref' + +module FSharpDeclaredOverloadedOutParamTest_Negative1 = + type C() = + static member M(a: int, [] x: byref) = x <- 7 + static member M(a: string, [] x: byref) = x <- 8 + let res = 9 + let v = C.M("a", &res) 'byref' is not compatible with type 'byref' + let v2 = C.M(3, &res) 'byref' is not compatible with type 'byref' + +module FSharpDeclaredOutParamTest_Negative1 = + type C() = + static member M([] x: byref) = () + let res = 9 + let v = C.M(&res) // 'byref' is not compatible with type 'byref' + +module TestOneArgumentInRefThenMutate_Negative1 = + + type C() = + static member M (x:inref) = &x + + let test() = + let mutable r1 = 1 + let addr = &C.M (&r1) // Expecting a 'byref' but given a 'inref'. 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 = + [] + type EvilStruct(s: int) = + member x.Replace(y:EvilStruct) = x <- y + +module Span_Negative2 = + let TestClosure1 ([] a: byref) = id (fun () -> a) + let TestClosure2 ([] a: Span) = id (fun () -> a) + let TestClosure3 ([] a: ReadOnlySpan) = id (fun () -> a) + + let TestAsyncClosure1 ([] a: byref) = async { return a } + let TestAsyncClosure2 ([] a: Span) = async { return a } + let TestAsyncClosure3 ([] a: ReadOnlySpan) = async { return a } diff --git a/tests/fsharp/typecheck/sigs/neg106.vsbsl b/tests/fsharp/typecheck/sigs/neg106.vsbsl new file mode 100644 index 0000000000..b854b8ae53 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg106.vsbsl @@ -0,0 +1,84 @@ + +neg106.fs(22,24,22,25): parse error FS0010: Unexpected quote symbol in binding. Expected incomplete structured construct at or before this point or other token. + +neg106.fs(24,1,24,7): parse error FS0010: Incomplete structured construct at or before this point in definition. Expected incomplete structured construct at or before this point or other token. + +neg106.fs(8,14,8,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,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 + 'byref' +is not compatible with type + 'byref<'a>' +. + +neg106.fs(11,14,11,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,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 + 'byref' +is not compatible with type + 'byref<'a>' +. + +neg106.fs(16,31,16,35): typecheck error FS0001: Type mismatch. Expecting a + 'byref' +but given a + 'inref' +The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In' diff --git a/tests/fsharp/typecheck/sigs/neg107.bsl b/tests/fsharp/typecheck/sigs/neg107.bsl new file mode 100644 index 0000000000..4b7c2da4b9 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg107.bsl @@ -0,0 +1,60 @@ + +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,13,27,25): typecheck error FS0037: Duplicate definition of value 'TestClosure1' + +neg107.fsx(27,68,27,79): 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,13,32,30): typecheck error FS0037: Duplicate definition of value 'TestAsyncClosure1' + +neg107.fsx(32,69,32,74): 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,77,32,85): 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 diff --git a/tests/fsharp/typecheck/sigs/neg107.fsx b/tests/fsharp/typecheck/sigs/neg107.fsx new file mode 100644 index 0000000000..c9c5f8080f --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg107.fsx @@ -0,0 +1,37 @@ +#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 + [] + [] + type IsReadOnlyAttribute() = + inherit System.Attribute() + + [] + [] + type IsByRefLikeAttribute() = + inherit System.Attribute() + +namespace Test + + open System.Runtime.CompilerServices + open System.Runtime.InteropServices + open System + + module Span_Negative1 = + let TestClosure1 (a: inref) = id (fun () -> a) + let TestClosure1 ([] a: byref) = id (fun () -> a) + let TestClosure2 (a: Span) = id (fun () -> a) + let TestClosure3 (a: ReadOnlySpan) = id (fun () -> a) + + let TestAsyncClosure1 (a: inref) = async { return a } + let TestAsyncClosure1 ([] a: byref) = async { return a } + let TestAsyncClosure2 (a: Span) = async { return a } + let TestAsyncClosure3 (a: ReadOnlySpan) = async { return a } + + module Span_Negative2 = + let TestLocal1 () = let x = Span() in x diff --git a/tests/fsharp/typecheck/sigs/neg107.vsbsl b/tests/fsharp/typecheck/sigs/neg107.vsbsl new file mode 100644 index 0000000000..4b7c2da4b9 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg107.vsbsl @@ -0,0 +1,60 @@ + +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,13,27,25): typecheck error FS0037: Duplicate definition of value 'TestClosure1' + +neg107.fsx(27,68,27,79): 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,13,32,30): typecheck error FS0037: Duplicate definition of value 'TestAsyncClosure1' + +neg107.fsx(32,69,32,74): 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,77,32,85): 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 diff --git a/tests/fsharp/typecheck/sigs/neg97.bsl b/tests/fsharp/typecheck/sigs/neg97.bsl index db02521eaf..1e882f98b6 100644 --- a/tests/fsharp/typecheck/sigs/neg97.bsl +++ b/tests/fsharp/typecheck/sigs/neg97.bsl @@ -1,5 +1,5 @@ -neg97.fs(13,1,13,2): typecheck error FS0256: A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' +neg97.fs(13,1,13,10): typecheck error FS0256: A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' neg97.fs(16,9,16,10): typecheck error FS0009: Uses of this construct may result in the generation of unverifiable .NET IL code. This warning can be disabled using '--nowarn:9' or '#nowarn "9"'. diff --git a/tests/fsharp/typecheck/sigs/neg97.vsbsl b/tests/fsharp/typecheck/sigs/neg97.vsbsl new file mode 100644 index 0000000000..1e882f98b6 --- /dev/null +++ b/tests/fsharp/typecheck/sigs/neg97.vsbsl @@ -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 diff --git a/tests/fsharp/typecheck/sigs/neg_byref_17.bsl b/tests/fsharp/typecheck/sigs/neg_byref_17.bsl index 270d06fbfc..3d857907b8 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_17.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_17.bsl @@ -1,10 +1,6 @@ -neg_byref_17.fs(2,17,2,27): typecheck error FS0001: This expression was expected to have type - 'byref' -but here has type - 'int' +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(3,17,3,24): typecheck error FS0001: This expression was expected to have type - 'byref' -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. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl index da7df92104..675eefac32 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl @@ -1,14 +1,4 @@ -neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected to have type - 'byref' -but here has type - 'int' - -neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected to have type - 'byref' -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 From 35e18004d0fe2799b40753123f18f8b498ac8284 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Wed, 16 May 2018 12:43:44 +0100 Subject: [PATCH 27/61] fix test errors --- DEVGUIDE.md | 2 + .../FSharp.Compiler.Private/FSComp.fs | 6 +- .../FSharp.Compiler.Private/FSComp.resx | 3 + src/fsharp/PostInferenceChecks.fs | 20 +++--- src/fsharp/TastOps.fs | 62 +++++++++++++------ src/fsharp/TypeChecker.fs | 50 ++++++++++----- 6 files changed, 98 insertions(+), 45 deletions(-) diff --git a/DEVGUIDE.md b/DEVGUIDE.md index 9fd9345265..1fc0d8ec85 100644 --- a/DEVGUIDE.md +++ b/DEVGUIDE.md @@ -221,6 +221,8 @@ If you change error messages you may need to update FSComp.fs in `src\buildfroms To do this, build the non-buildfromsource version of FSharp.Compiler.Private (src\fsharp\FSharp.Compiler.Private) then check its obj\ directory for `FSComp.fs` and manually copy that into the buildfromsource directory. + .\build net40 + copy /y src\fsharp\FSharp.Compiler.Private\obj\release\net40\FSComp.* src\buildfromsource\FSharp.Compiler.Private\ #### Configuring proxy server diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index 17261e4db7..a7359b0c48 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -3376,7 +3376,7 @@ type internal SR private() = /// No implementation files specified /// (Originally from ..\FSComp.txt:1115) static member fscNoImplementationFiles() = (2002, GetStringFunc("fscNoImplementationFiles",",,,") ) - /// An %s specified version '%s', but this value is invalid and has been ignored + /// The attribute %s specified version '%s', but this value is invalid and has been ignored /// (Originally from ..\FSComp.txt:1116) static member fscBadAssemblyVersion(a0 : System.String, a1 : System.String) = (2003, GetStringFunc("fscBadAssemblyVersion",",,,%s,,,%s,,,") a0 a1) /// Conflicting options specified: 'win32manifest' and 'win32res'. Only one of these can be used. @@ -4309,6 +4309,9 @@ type internal SR private() = /// The file '%s' changed on disk unexpectedly, please reload. /// (Originally from ..\FSComp.txt:1427) static member ilreadFileChanged(a0 : System.String) = (3223, GetStringFunc("ilreadFileChanged",",,,%s,,,") a0) + /// The byref pointer is readonly, so this write is not permitted. + /// (Originally from ..\FSComp.txt:1428) + static member writeToReadOnlyByref() = (3224, GetStringFunc("writeToReadOnlyByref",",,,") ) /// Call this method once to validate that all known resources are valid; throws if not static member RunStartupValidation() = @@ -5710,4 +5713,5 @@ type internal SR private() = ignore(GetString("implicitlyDiscardedInSequenceExpression")) ignore(GetString("implicitlyDiscardedSequenceInSequenceExpression")) ignore(GetString("ilreadFileChanged")) + ignore(GetString("writeToReadOnlyByref")) () diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index 79581353b4..dc45c4bf3f 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -4312,4 +4312,7 @@ The file '{0}' changed on disk unexpectedly, please reload. + + The byref pointer is readonly, so this write is not permitted. + \ No newline at end of file diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 78cf083b2e..3f6bcdcb95 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -288,35 +288,35 @@ let CheckForByrefLikeType cenv env m typ check = /// For TObjExprMethod(v,e) nodes we always know the legitimate syntactic arguments. let CheckEscapes cenv allowProtected m syntacticArgs body = (* m is a range suited to error reporting *) if cenv.reportErrors then - let cantBeFree v = - // First, if v is a syntactic argument, then it can be free since it was passed in. + let cantBeFree (v: Val) = + // If v is a syntactic argument, then it can be free since it was passed in. // The following can not be free: // a) BaseVal can never escape. // b) Byref typed values can never escape. // Note that: Local mutables can be free, as they will be boxed later. // These checks must correspond to the tests governing the error messages below. - let passedIn = ListSet.contains valEq v syntacticArgs - if passedIn then - false - else - (v.BaseOrThisInfo = BaseVal) || - (isByrefLikeTy cenv.g m v.Type) + ((v.BaseOrThisInfo = BaseVal) || (isByrefLikeTy cenv.g m v.Type)) && + not (ListSet.contains valEq v syntacticArgs) let frees = freeInExpr CollectLocals body let fvs = frees.FreeLocals + if not allowProtected && frees.UsesMethodLocalConstructs then errorR(Error(FSComp.SR.chkProtectedOrBaseCalled(), m)) elif Zset.exists cantBeFree fvs then let v = List.find cantBeFree (Zset.elements fvs) - (* byref error before mutable error (byrefs are mutable...). *) + + // byref error before mutable error (byrefs are mutable...). if (isByrefLikeTy cenv.g m v.Type) then // Inner functions are not guaranteed to compile to method with a predictable arity (number of arguments). // As such, partial applications involving byref arguments could lead to closures containing byrefs. // For safety, such functions are assumed to have no known arity, and so can not accept byrefs. errorR(Error(FSComp.SR.chkByrefUsedInInvalidWay(v.DisplayName), m)) + elif v.BaseOrThisInfo = BaseVal then errorR(Error(FSComp.SR.chkBaseUsedInInvalidWay(), m)) + else (* Should be dead code, unless governing tests change *) errorR(InternalError(FSComp.SR.chkVariableUsedInInvalidWay(v.DisplayName), m)) @@ -931,7 +931,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn | Some membInfo -> testHookMemberBody membInfo body // Check escapes in the body. Allow access to protected things within members. - let freesOpt = CheckEscapes cenv (Option.isSome memInfo) m syntacticArgs body + let freesOpt = CheckEscapes cenv memInfo.IsSome m syntacticArgs body // no reraise under lambda expression CheckNoReraise cenv freesOpt body diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 1c0845321b..bc93ec0c64 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -560,23 +560,42 @@ 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 mkInByrefTy (g:TcGlobals) ty = TType_app (g.inref_tcr, [ty]) -let mkOutrefTy (g:TcGlobals) ty = TType_app (g.outref_tcr, [ty]) -let mkByrefTyWithFlag g readonly ty = (if readonly then mkInByrefTy g ty else mkByrefTy g 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 = byref, see RFC FS-1053.md + TType_app (g.inref_tcr, [ty]) + else + mkByrefTy g ty + +let mkOutrefTy (g:TcGlobals) ty = + if g.outref_tcr.CanDeref then // If not using sufficient FSharp.Core, then outref = byref, 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 FSharp.Core 4.5.0.0+ + 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 FSharp.Core 4.5.0.0+ + 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 g.byref2_tcr.CanDeref then // If not using sufficient FSharp.Core, then inref = byref, see RFC FS-1053.md TType_app (g.byref2_tcr, [ty1; ty2]) else TType_app (g.byref_tcr, [ty1]) @@ -693,9 +712,15 @@ let rec stripTyEqnsA g canShortcut ty = | Some abbrevTy -> stripTyEqnsA g canShortcut (applyTyconAbbrev abbrevTy tycon tinst) | None -> - // Add the equation `byref<'T> = byref<'T, ByRefKinds.InOut> for F# 4.5+ when using FSharp.Core 4.5.0.0+ + // 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 @@ -1550,7 +1575,7 @@ 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 @@ -2907,19 +2932,20 @@ let TyconRefHasAttribute g m attribSpec tcref = (fun _ -> Some ()) |> Option.isSome -let isByrefLikeTyconRef g m (tcref: TyconRef) = +// See RFC FS-1053.md +let isByrefLikeTyconRef (g: TcGlobals) m (tcref: TyconRef) = tcref.CanDeref && match tcref.TryIsByRefLike with | Some res -> res | None -> let res = - tyconRefEq g g.byref_tcr tcref || + (g.byref_tcr.CanDeref && tyconRefEq g g.byref_tcr tcref) || (g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref) || - tyconRefEq g g.inref_tcr tcref || - tyconRefEq g g.outref_tcr tcref || - isTypeConstructorEqualToOptional g g.system_TypedReference_tcref tcref || - isTypeConstructorEqualToOptional g g.system_ArgIterator_tcref tcref || - isTypeConstructorEqualToOptional g g.system_RuntimeArgumentHandle_tcref 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 || TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref tcref.SetIsByRefLike res res @@ -2933,7 +2959,7 @@ let isByrefLikeTy g m ty = let destByrefTy g ty = match ty |> stripTyEqns g with - | TType_app(tcref, [x; _]) when g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tcref -> x // F# 4.5 with FSharp.Core 4.5.0.0+ + | 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" diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index a697c2c771..82a5c0ec45 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -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) = 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, _) -> - match op with - | TOp.Tuple _ -> true - | TOp.UnionCase uc -> not (isUnionCaseRefDefinitelyMutable uc) - | TOp.Recd(ctorInfo, tcref) -> - match ctorInfo with - | RecdExpr -> not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) - | RecdExprIsObjInit -> false - | TOp.Array -> isNil args - | TOp.ExnConstr ec -> not (isExnDefinitelyMutable ec) - | TOp.ILAsm([], _) -> true - - | _ -> false - && List.forall (IsGeneralizableValue g) 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 tcref) + | RecdExprIsObjInit -> false + | TOp.Array -> isNil args + | TOp.ExnConstr ec -> not (isExnDefinitelyMutable ec) + | TOp.ILAsm([], _) -> true + | _ -> false + + 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 && @@ -3975,16 +3980,27 @@ let buildApp cenv expr resultTy arg m = // exprty is of type: "unit -> 'a". Break it and store the 'a type here, used later as return type. 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.nativeptr_tobyref_vref) -> + + let argTy = tyOfExpr g arg + let resultTy = mkByrefTyWithInference g argTy (NewInferenceType()) // resultTy + expr.SupplyArgument(arg, m), resultTy + // Special rules for building applications of the '&expr' or '&&expr' operators, both of which get the // address of an expression. + // + // See also RFC FS-1053.md | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ - when (valRefEq g vf g.addrof_vref || valRefEq g vf g.addrof2_vref) -> + when (valRefEq g vf g.addrof_vref || valRefEq g vf g.addrof2_vref || valRefEq g vf g.nativeptr_tobyref_vref) -> if valRefEq g vf g.addrof2_vref then warning(UseOfAddressOfOperator(m)) 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 + if readonly && valRefEq g vf g.addrof_vref then mkInByrefTy g argTy else mkByrefTyWithInference g argTy (NewInferenceType()) // resultTy @@ -8277,6 +8293,7 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = 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) (NewInferenceType()) @@ -8298,6 +8315,7 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = | Some (_, 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, _, _), _, _, [], _), _) From 7b125d163c7b40446aa9c60b15c4bf0f4318d4a4 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Wed, 16 May 2018 16:38:15 +0100 Subject: [PATCH 28/61] emit in,out,modreq attributes correctly --- src/absil/il.fs | 2 + src/absil/il.fsi | 2 + src/absil/ilreflect.fs | 69 ++++++---- src/fsharp/ConstraintSolver.fs | 6 + src/fsharp/ConstraintSolver.fsi | 3 + src/fsharp/FSComp.txt | 1 + src/fsharp/IlxGen.fs | 154 ++++++++++++++------- src/fsharp/PostInferenceChecks.fs | 6 +- src/fsharp/TastOps.fs | 12 +- src/fsharp/TastOps.fsi | 3 +- src/fsharp/TcGlobals.fs | 2 +- src/fsharp/TypeChecker.fs | 6 +- src/fsharp/infos.fs | 2 +- src/fsharp/xlf/FSComp.txt.cs.xlf | 5 + src/fsharp/xlf/FSComp.txt.de.xlf | 5 + src/fsharp/xlf/FSComp.txt.en.xlf | 5 + src/fsharp/xlf/FSComp.txt.es.xlf | 5 + src/fsharp/xlf/FSComp.txt.fr.xlf | 5 + src/fsharp/xlf/FSComp.txt.it.xlf | 5 + src/fsharp/xlf/FSComp.txt.ja.xlf | 5 + src/fsharp/xlf/FSComp.txt.ko.xlf | 5 + src/fsharp/xlf/FSComp.txt.pl.xlf | 5 + src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 5 + src/fsharp/xlf/FSComp.txt.ru.xlf | 5 + src/fsharp/xlf/FSComp.txt.tr.xlf | 5 + src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 5 + src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 5 + tests/fsharp/core/byrefs/test.fsx | 185 +++++++++++++++++++++----- 28 files changed, 405 insertions(+), 118 deletions(-) diff --git a/src/absil/il.fs b/src/absil/il.fs index 9631e876ef..2501805cc9 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -1449,6 +1449,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 diff --git a/src/absil/il.fsi b/src/absil/il.fsi index 621bfb1eff..fe0bd1bdac 100644 --- a/src/absil/il.fsi +++ b/src/absil/il.fsi @@ -796,6 +796,8 @@ type ILReturn = member CustomAttrs: ILAttributes + member WithCustomAttrs: customAttrs: ILAttributes -> ILReturn + [] type ILSecurityAction = | Request diff --git a/src/absil/ilreflect.fs b/src/absil/ilreflect.fs index c84a1bd36f..c62ed5a846 100644 --- a/src/absil/ilreflect.fs +++ b/src/absil/ilreflect.fs @@ -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 diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index f184a2ddea..65036f06f7 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -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 diff --git a/src/fsharp/ConstraintSolver.fsi b/src/fsharp/ConstraintSolver.fsi index b483c00fb0..a6054be1bd 100644 --- a/src/fsharp/ConstraintSolver.fsi +++ b/src/fsharp/ConstraintSolver.fsi @@ -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 diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 0ad88684f9..8caa78d73d 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1426,3 +1426,4 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 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." diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 60d5b2889a..44b9d8cdfc 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -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 *) - -and GenParamType amap m tyenv ty = - ty |> GenTypeAux amap m tyenv VoidNotOK PtrTypesOK + | 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 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) @@ -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 @@ -3465,8 +3496,15 @@ 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 ilTy = GenParamType cenv.amap m eenv.tyenv ty - 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= ilTy @@ -3475,7 +3513,7 @@ and GenSlotParam m cenv eenv (TSlotParam(nm,ty,inFlag,outFlag,optionalFlag,attri 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)) = @@ -3485,6 +3523,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) @@ -4698,11 +4743,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) -> @@ -4949,9 +4994,9 @@ and GenMarshal cenv attribs = // No MarshalAs detected None, attribs -and GenParamAttribs cenv attribs = - let inFlag = HasFSharpAttribute 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 @@ -4968,7 +5013,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 @@ -4981,9 +5026,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 @@ -4999,6 +5044,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 @@ -5007,17 +5060,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 = @@ -5109,7 +5162,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 = @@ -5123,6 +5176,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 @@ -5205,7 +5259,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 @@ -5433,7 +5487,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)) @@ -5472,7 +5526,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 @@ -5725,7 +5779,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) @@ -6054,11 +6108,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) @@ -6100,7 +6154,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 @@ -6427,7 +6481,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 @@ -6967,7 +7021,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). @@ -6985,7 +7039,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 = @@ -6995,10 +7049,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 diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 3f6bcdcb95..3f13e59470 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -1601,12 +1601,16 @@ let CheckEntityDefn cenv env (tycon:Entity) = | _ -> () + let tcref = mkLocalTyconRef tycon let interfaces = - AllSuperTypesOfType cenv.g cenv.amap tycon.Range AllowMultiIntfInstantiations.Yes (generalizedTyconRef (mkLocalTyconRef tycon)) + AllSuperTypesOfType cenv.g cenv.amap tycon.Range AllowMultiIntfInstantiations.Yes (generalizedTyconRef tcref) |> List.filter (isInterfaceTy cenv.g) if tycon.IsFSharpInterfaceTycon then List.iter visitType interfaces // Check inherited interface is as accessible + + if not (isRecdOrStructTyconRefLogicallyReadOnly cenv.g tcref) && isRecdOrStructTyconRefReadOnly cenv.g m tcref then + errorR(Error(FSComp.SR.readOnlyAttributeOnStructWithMutableField(),m)) if cenv.reportErrors then if not tycon.IsTypeAbbrev then diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index bc93ec0c64..048d407fa5 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -574,7 +574,7 @@ let mkInByrefTy (g:TcGlobals) ty = else mkByrefTy g ty -let mkOutrefTy (g:TcGlobals) ty = +let mkOutByrefTy (g:TcGlobals) ty = if g.outref_tcr.CanDeref then // If not using sufficient FSharp.Core, then outref = byref, see RFC FS-1053.md TType_app (g.outref_tcr, [ty]) else @@ -5642,15 +5642,19 @@ let mkAndSimplifyMatch spBind exprm matchm ty tree targets = type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates exception DefensiveCopyWarning of string * range +let isRecdOrStructTyconRefLogicallyReadOnly (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 res = - not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) || - tyconRefEq g tcref g.decimal_tcr || - tyconRefEq g tcref g.date_tcr || + isRecdOrStructTyconRefLogicallyReadOnly g tcref || TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref tcref.SetIsReadOnly res res diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index 5125de4b4f..06b4dee2d2 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -166,7 +166,7 @@ val mkLazyOr : TcGlobals -> range -> Expr -> Expr -> Expr val mkByrefTy : TcGlobals -> TType -> TType val mkByrefTyWithInference : TcGlobals -> TType -> TType -> TType val mkInByrefTy : TcGlobals -> TType -> TType -val mkOutrefTy : TcGlobals -> TType -> TType +val mkOutByrefTy : TcGlobals -> TType -> TType //------------------------------------------------------------------------- // Make construction operations @@ -1104,6 +1104,7 @@ val isExnDefinitelyMutable : TyconRef -> bool val isUnionCaseFieldMutable : TcGlobals -> UnionCaseRef -> int -> bool val isExnFieldMutable : TyconRef -> int -> bool val isRecdOrStructTyconRefReadOnly: TcGlobals -> range -> TyconRef -> bool +val isRecdOrStructTyconRefLogicallyReadOnly: TcGlobals -> TyconRef -> bool val isRecdOrStructTyReadOnly: TcGlobals -> range -> TType -> bool val useGenuineField : Tycon -> RecdField -> bool diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index 7f745ef04e..0378331226 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -935,7 +935,7 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d 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 "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" diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 82a5c0ec45..b88878a1a5 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -3986,7 +3986,7 @@ let buildApp cenv expr resultTy arg m = when (valRefEq g vf g.nativeptr_tobyref_vref) -> let argTy = tyOfExpr g arg - let resultTy = mkByrefTyWithInference g argTy (NewInferenceType()) // resultTy + let resultTy = mkByrefTyWithInference g argTy (NewByRefKindInferenceType g m) // resultTy expr.SupplyArgument(arg, m), resultTy // Special rules for building applications of the '&expr' or '&&expr' operators, both of which get the @@ -4003,7 +4003,7 @@ let buildApp cenv expr resultTy arg m = if readonly && valRefEq g vf g.addrof_vref then mkInByrefTy g argTy else - mkByrefTyWithInference g argTy (NewInferenceType()) // resultTy + mkByrefTyWithInference g argTy (NewByRefKindInferenceType g m) // resultTy MakeApplicableExprNoFlex cenv (wrap(e1a')), resultTy @@ -8296,7 +8296,7 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = // See RFC FS-1053.md let exprty = if isAddrOf && isByrefTy cenv.g exprty then - mkByrefTyWithInference cenv.g (destByrefTy cenv.g exprty) (NewInferenceType()) + mkByrefTyWithInference cenv.g (destByrefTy cenv.g exprty) (NewByRefKindInferenceType cenv.g mExpr) else exprty diff --git a/src/fsharp/infos.fs b/src/fsharp/infos.fs index 3e03de4930..7edd799aad 100755 --- a/src/fsharp/infos.fs +++ b/src/fsharp/infos.fs @@ -1560,7 +1560,7 @@ type MethInfo = let pty = // add the "annotation" about whether this is an inref, outref or plain byref if isByrefTy g pty && isInArg then mkInByrefTy g (destByrefTy g pty) - elif isByrefTy g pty && isOutArg then mkOutrefTy g (destByrefTy g pty) + elif isByrefTy g pty && isOutArg then mkOutByrefTy g (destByrefTy g pty) else pty ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, nmOpt, reflArgInfo, pty))) diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index b730b82975..d53cff5ad5 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index a16b0898dc..e07bad57eb 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.en.xlf b/src/fsharp/xlf/FSComp.txt.en.xlf index 94af2c7966..ea624fd341 100644 --- a/src/fsharp/xlf/FSComp.txt.en.xlf +++ b/src/fsharp/xlf/FSComp.txt.en.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index b8ae645806..1a180ebbb4 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index 065f919c91..2a38eef1d5 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 624b1c9d3a..29c2272007 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 8479835881..c84cb363c6 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index 49e7782d1f..02eeb561c7 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index c2e0e1e566..538881e817 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index aa0c9df006..4df092e720 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index c75ded78a0..ff08cb1b40 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 0680ce1f90..896f276f8a 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index f1903ea501..f579adcf88 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index fe73e6d6f9..d772a2399c 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -6992,6 +6992,11 @@ A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' + + A ReadOnly attribute has been applied to a struct type with a mutable field. + A ReadOnly attribute has been applied to a struct type with a mutable field. + + \ No newline at end of file diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index c94fda4a5e..82ff2cd0e1 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -1,8 +1,9 @@ // #Conformance #Constants #Recursion #LetBindings #MemberDefinitions #Mutable #if TESTS_AS_APP -module Core_apporder +module Core_byrefs #endif + #light let failures = ref false let report_failure (s) = @@ -38,99 +39,217 @@ module TryGetValueTests = check "cweweoiwekl3" v2 false check "cweweoiwekl4" res 4 -module FSharpDeclaredOutParamTest = + +module ByRefParam = + type C() = + static member M(x: byref) = x <- 5 + let mutable res = 9 + let v = C.M(&res) + check "cwvereweoiwekl4" res 5 + + let minfo = typeof.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 + +module ByRefParam_ExplicitOutAttribute = type C() = static member M([] x: byref) = x <- 5 let mutable res = 9 let v = C.M(&res) check "cwvereweoiwekl4" res 5 + let minfo = typeof.GetMethod("M") + check "cwnoreeker5" (minfo.GetParameters().[0].IsIn) false + check "cwnoreeker6" (minfo.GetParameters().[0].IsOut) true + check "cwnoreekers1" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 + check "cwnoreeker7" (minfo.ReturnParameter.IsIn) false + check "cwnoreeker8" (minfo.ReturnParameter.IsOut) false -module FSharpDeclaredOutParamTest2 = +module ByRefParam_ExplicitInAttribute = type C() = - static member M([] x: outref) = x <- 5 + static member M([] x: byref) = x <- 5 + let mutable res = 9 + let v = C.M(&res) + check "cwvereweoiwekl4" res 5 + + let minfo = typeof.GetMethod("M") + check "cwnoreeker9" (minfo.GetParameters().[0].IsIn) true + check "cwnoreekerq" (minfo.GetParameters().[0].IsOut) false + check "cwnoreekers2" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 + check "cwnoreekerw" (minfo.ReturnParameter.IsIn) false + check "cwnoreekere" (minfo.ReturnParameter.IsOut) false + +module ByRefReturn = + type C() = + static member M(x: byref) = x <- x + 1; &x let mutable res = 9 let v = C.M(&res) + check "cwvereweoiwvw4" v 10 + + let minfo = typeof.GetMethod("M") + check "cwnoreekerr" (minfo.ReturnParameter.IsIn) false + check "cwnoreekert" (minfo.ReturnParameter.IsOut) false + + +module Slot_ByRefReturn = + type I = + abstract M : x: byref -> byref + type C() = + interface I with + member __.M(x: byref) = x <- 5; &x + let mutable res = 9 + let v = (C() :> I).M(&res) + check "cweweoiwek28989" res 5 + check "cweweoiwek28989" v 5 + + let minfo = typeof.GetMethod("M") + check "cwnoreekery" (minfo.GetParameters().[0].IsIn) false + check "cwnoreekeru" (minfo.GetParameters().[0].IsOut) false + check "cwnoreekeri" (minfo.ReturnParameter.IsIn) false + check "cwnoreekers" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 + check "cwnoreekero" (minfo.ReturnParameter.IsOut) false + +module InRefReturn = + type C() = + static member M(x: inref) = &x + let mutable res = 9 + let v = C.M(&res) + check "cwvereweoiwvw4" v 9 + + let minfo = typeof.GetMethod("M") + check "cwnoreekerp" (minfo.GetParameters().[0].IsIn) true + check "cwnoreekera" (minfo.GetParameters().[0].IsOut) false + check "cwnoreekers3" (minfo.ReturnParameter.IsIn) false // has modreq 'In' but reflection never returns true for ReturnParameter.IsIn + check "cwnoreekers4" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 1 + check "cwnoreekerd" (minfo.ReturnParameter.IsOut) false + +module Slot_InRefReturn = + type I = + abstract M : x: inref -> inref + type C() = + interface I with + member __.M(x: inref) = &x + let mutable res = 9 + let v = (C() :> I).M(&res) + check "cweweoiwek28989" res 9 + check "cweweoiwek28989" v 9 + + let minfo = typeof.GetMethod("M") + check "cwnoreekerp" (minfo.GetParameters().[0].IsIn) true + check "cwnoreekera" (minfo.GetParameters().[0].IsOut) false + check "cwnoreekers5" (minfo.ReturnParameter.IsIn) false // has modreq 'In' but reflection never returns true for ReturnParameter.IsIn + check "cwnoreekers6" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 1 + check "cwnoreekerd" (minfo.ReturnParameter.IsOut) false + + +module OutRefParam_ExplicitOutAttribute = + type C() = + static member M([] x: outref) = x <- 5 + let mutable res = 9 + C.M(&res) check "cweweoiweklceew4" res 5 -module FSharpDeclaredOutParamTest3 = +module OutRefParam = type C() = static member M(x: outref) = x <- 5 let mutable res = 9 - let v = C.M(&res) + C.M(&res) check "cweweoiwek28989" res 5 -module FSharpDeclaredOverloadedOutParamTest = +module Slot_OutRefParam = + type I = + abstract M : x: outref -> unit + type C() = + interface I with + member __.M(x: outref) = x <- 5 + let mutable res = 9 + (C() :> I).M(&res) + check "cweweoiwek28989" res 5 + +module ByRefParam_OverloadedTest_ExplicitOutAttribute = type C() = static member M(a: int, [] x: byref) = x <- 7 static member M(a: string, [] x: byref) = x <- 8 let mutable res = 9 - let v = C.M("a", &res) + C.M("a", &res) check "cweweoiwek2cbe9" res 8 - let v2 = C.M(3, &res) + C.M(3, &res) check "cweweoiwek28498" res 7 -module FSharpDeclaredOverloadedOutParamTest2 = +module OutRefParam_Overloaded_ExplicitOutAttribute = type C() = static member M(a: int, [] x: outref) = x <- 7 static member M(a: string, [] x: outref) = x <- 8 let mutable res = 9 - let v = C.M("a", &res) + C.M("a", &res) check "cweweoiwek2v90" res 8 - let v2 = C.M(3, &res) + C.M(3, &res) check "cweweoiwek2c98" res 7 -module FSharpDeclaredOverloadedOutParamTest3 = +module OutRefParam_Overloaded = type C() = static member M(a: int, x: outref) = x <- 7 static member M(a: string, x: outref) = x <- 8 let mutable res = 9 - let v = C.M("a", &res) + C.M("a", &res) check "cweweoiwek2v99323" res 8 - let v2 = C.M(3, &res) + C.M(3, &res) check "cweweoiwe519" res 7 -module FSharpDeclaredInParamTest = +module InRefParam_ExplicitInAttribute = type C() = static member M([] x: inref) = () let mutable res = 9 - let v = C.M(&res) + C.M(&res) + check "cweweoiwe519btr" res 9 -module FSharpDeclaredInParamTest2 = +module InRefParam_ExplicitInAttributeDateTime = type C() = - static member M([] x: inref) = () + static member M([] x: inref) = x let res = System.DateTime.Now - let v = C.M(&res) + let v = C.M(&res) + check "cweweoiwe519cw" v res -module FSharpDeclaredInParamTest3 = +module InRefParam = type C() = - static member M(x: inref) = () + static member M(x: inref) = x let res = System.DateTime.Now let v = C.M(&res) + check "cweweoiwe51btw" v res -module FSharpDeclaredInParamTest3a = + let minfo = typeof.GetMethod("M") + check "cwnoreekerf" (minfo.GetParameters().[0].IsIn) true + check "cwnoreekerg" (minfo.GetParameters().[0].IsOut) false + +module InRefParam_DateTime = type C() = - static member M(x: inref) = () + static member M(x: inref) = x let w = System.DateTime.Now let v = C.M(w) + check "cweweoiwe51btw" v w -module FSharpDeclaredInParamTest3b = +module InRefParam_DateTime_ImplicitAddressOfAtCallSite = type C() = - static member M(x: inref) = () + static member M(x: inref) = x let v = C.M(System.DateTime.Now) + check "cweweoiwe51btw" v.Date System.DateTime.Now.Date -module FSharpDeclaredInParamTest3c = +module InRefParam_DateTime_ImplicitAddressOfAtCallSite2 = type C() = - static member M(x: inref) = () + static member M(x: inref) = x let v = C.M(System.DateTime.Now.AddDays(1.0)) + check "cweweoiwe51btw" v.Date (System.DateTime.Now.AddDays(1.0).Date) -module FSharpDeclaredInParamTest3d = +module InRefParam_DateTime_ImplicitAddressOfAtCallSite3 = type C() = - static member M(x: inref) = () + static member M(x: inref) = x let mutable w = System.DateTime.Now let v = C.M(w) + check "cweweoiwe51btw" v w -module FSharpDeclaredInParamTest3e = +module InRefParam_DateTime_ImplicitAddressOfAtCallSite4 = type C() = static member M(x: inref) = x let date = System.DateTime.Now.Date @@ -138,7 +257,7 @@ module FSharpDeclaredInParamTest3e = let v = C.M(w.[0]) check "lmvjvwo1" v date -module FSharpDeclaredInParamTest4 = +module InRefParam_Generic_ExplicitAddressOfAttCallSite1 = type C() = static member M(x: inref<'T>) = x let res = "abc" @@ -146,7 +265,7 @@ module FSharpDeclaredInParamTest4 = check "lmvjvwo2" res "abc" check "lmvjvwo3" v "abc" -module FSharpDeclaredInParamTest5 = +module InRefParam_Generic_ExplicitAddressOfAttCallSite2 = type C() = static member M(x: inref<'T>) = x let res = "abc" From 6ea92d6c9856764bc89125bea0e9cd557b9f4245 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Wed, 16 May 2018 17:40:38 +0100 Subject: [PATCH 29/61] update tests --- src/fsharp/PostInferenceChecks.fs | 2 +- src/fsharp/TastOps.fs | 8 +++--- src/fsharp/TastOps.fsi | 2 +- tests/fsharp/core/span/test.fsx | 47 +++++++++++++++---------------- tests/fsharp/core/span/testlib.fs | 15 ++++++++++ 5 files changed, 44 insertions(+), 30 deletions(-) create mode 100644 tests/fsharp/core/span/testlib.fs diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 3f13e59470..ea25c83b80 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -1609,7 +1609,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = if tycon.IsFSharpInterfaceTycon then List.iter visitType interfaces // Check inherited interface is as accessible - if not (isRecdOrStructTyconRefLogicallyReadOnly cenv.g tcref) && isRecdOrStructTyconRefReadOnly cenv.g m tcref then + if not (isRecdOrStructTyconRefAssumedImmutable cenv.g tcref) && isRecdOrStructTyconRefReadOnly cenv.g m tcref then errorR(Error(FSComp.SR.readOnlyAttributeOnStructWithMutableField(),m)) if cenv.reportErrors then diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 048d407fa5..5d3d76bfda 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -5642,7 +5642,7 @@ let mkAndSimplifyMatch spBind exprm matchm ty tree targets = type Mutates = AddressOfOp | DefinitelyMutates | PossiblyMutates | NeverMutates exception DefensiveCopyWarning of string * range -let isRecdOrStructTyconRefLogicallyReadOnly (g: TcGlobals) (tcref: TyconRef) = +let isRecdOrStructTyconRefAssumedImmutable (g: TcGlobals) (tcref: TyconRef) = tcref.CanDeref && not (isRecdOrUnionOrStructTyconRefDefinitelyMutable tcref) || tyconRefEq g tcref g.decimal_tcr || @@ -5653,9 +5653,9 @@ let isRecdOrStructTyconRefReadOnly (g: TcGlobals) m (tcref: TyconRef) = match tcref.TryIsReadOnly with | Some res -> res | None -> - let res = - isRecdOrStructTyconRefLogicallyReadOnly g tcref || - TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref + let isImmutable = isRecdOrStructTyconRefAssumedImmutable g tcref + let hasAttrib = TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref + let res = isImmutable || hasAttrib tcref.SetIsReadOnly res res diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index 06b4dee2d2..baf40259d2 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -1104,7 +1104,7 @@ val isExnDefinitelyMutable : TyconRef -> bool val isUnionCaseFieldMutable : TcGlobals -> UnionCaseRef -> int -> bool val isExnFieldMutable : TyconRef -> int -> bool val isRecdOrStructTyconRefReadOnly: TcGlobals -> range -> TyconRef -> bool -val isRecdOrStructTyconRefLogicallyReadOnly: TcGlobals -> TyconRef -> bool +val isRecdOrStructTyconRefAssumedImmutable: TcGlobals -> TyconRef -> bool val isRecdOrStructTyReadOnly: TcGlobals -> range -> TType -> bool val useGenuineField : Tycon -> RecdField -> bool diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index fff5fc65ac..f3989953a6 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -16,8 +16,7 @@ namespace System.Runtime.CompilerServices type IsByRefLikeAttribute() = inherit System.Attribute() -namespace Test - +namespace Tests open System open System.Runtime.CompilerServices open System.Runtime.InteropServices @@ -34,7 +33,7 @@ namespace Test member x.Count2 = count2 module TypeRefTests = - + let f1 (x: ByRefLikeStruct) = () let f2 (x: ReadOnlyStruct) = x.Count1 let f3 (x: ReadOnlyStruct) = x @@ -131,25 +130,25 @@ namespace Test val mutable v : int member x.Replace(y:AllowedEvilStruct) = x <- y - -//Since in parameters are read-only ref parameters, all ref parameter limitations apply. -// -//Cannot apply with an iterator method (I.e. method that has yield statements.) -//Cannot apply with an async method - - - #if NOT_YET - // Allow this: - [] - type ByRefLikeStructWithByrefField(count1: byref, count2: int) = - member x.Count1 = count1 - member x.Count2 = count2 - - - // Disallow this: - [] - type ReadOnlyStruct = - [] - val mutable X : int - #endif +#if NEGATIVE + +// Disallow this: +[] +type DisallowedIsReadOnlyStruct = + [] + val mutable X : int +#endif + +#if NOT_YET +// Allow this: +[] +type ByRefLikeStructWithSpanField(count1: Span, count2: int) = + member x.Count1 = count1 + member x.Count2 = count2 + +[] +type ByRefLikeStructWithByrefField(count1: byref, count2: int) = + member x.Count1 = count1 + member x.Count2 = count2 +#endif diff --git a/tests/fsharp/core/span/testlib.fs b/tests/fsharp/core/span/testlib.fs new file mode 100644 index 0000000000..9f8ee20650 --- /dev/null +++ b/tests/fsharp/core/span/testlib.fs @@ -0,0 +1,15 @@ +namespace System.Runtime.CompilerServices + + open System + open System.Runtime.CompilerServices + open System.Runtime.InteropServices + [] + [] + type IsReadOnlyAttribute() = + inherit System.Attribute() + + [] + [] + type IsByRefLikeAttribute() = + inherit System.Attribute() + From c3fe07150de6ff623584686aeee6bcd9424839fd Mon Sep 17 00:00:00 2001 From: Don Syme Date: Wed, 16 May 2018 18:25:14 +0100 Subject: [PATCH 30/61] fix build --- src/fsharp/MethodCalls.fs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index 81d7942b9e..17d40d27db 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -132,10 +132,12 @@ let AdjustCalledArgType (infoReader:InfoReader) isConstraint (calledArg: CalledA calledArgTy else - // If the called method argument is an inref type, then the caller may provide a byref or value + // If the called method argument is an inref type, then the caller may provide a byref or ref or value if isInByrefTy g calledArgTy then if isByrefTy g callerArgTy then calledArgTy + elif isRefCellTy g callerArgTy (* || isTyparTy g callerArgTy -- for compat *) then + mkRefCellTy g (destByrefTy g calledArgTy) else destByrefTy g calledArgTy From c321ccb57acc87cf3159c582d5c8cd61746426b1 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Thu, 17 May 2018 10:21:48 +0100 Subject: [PATCH 31/61] fix build --- src/fsharp/MethodCalls.fs | 4 ++-- src/fsharp/TypeChecker.fs | 12 ++++++++++-- src/fsharp/infos.fs | 19 +++++++++++++------ 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index 17d40d27db..8def316cef 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -136,8 +136,8 @@ let AdjustCalledArgType (infoReader:InfoReader) isConstraint (calledArg: CalledA if isInByrefTy g calledArgTy then if isByrefTy g callerArgTy then calledArgTy - elif isRefCellTy g callerArgTy (* || isTyparTy g callerArgTy -- for compat *) then - mkRefCellTy g (destByrefTy g calledArgTy) + // elif isRefCellTy g callerArgTy (* || isTyparTy g callerArgTy -- for compat *) then + // mkRefCellTy g (destByrefTy g calledArgTy) else destByrefTy g calledArgTy diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index b88878a1a5..ad1b5632b1 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -9258,6 +9258,14 @@ and TcMethodApplicationThen and GetNewInferenceTypeForMethodArg cenv env tpenv x = match x with | SynExprParen(a, _, _, _) -> GetNewInferenceTypeForMethodArg cenv env tpenv a + + // // For code compat reasons we allow passing a "ref" arg where an `inref<_>` is required though taking the address is + //// now implicit. In order to infer this we check the callsite syntax. + //| SynExpr.App(_, _, SingleIdent opId, _, _) + // when opId.idText = "ref" && + // (match env.eNameResEnv.eUnqualifiedItems.TryFind(opId.idText) with Some(Item.Value vref) -> valRefEq cenv.g vref cenv.g.fsharpref_vref | _ -> false) -> + // mkRefCellTy cenv.g (NewInferenceType()) + | SynExpr.AddressOf(true, a, _, _) -> mkByrefTyWithInference cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) (NewInferenceType()) | SynExpr.Lambda(_, _, _, a, _) -> mkFunTy (NewInferenceType ()) (GetNewInferenceTypeForMethodArg cenv env tpenv a) | SynExpr.Quote(_, raw, a, _, _) -> @@ -9290,8 +9298,8 @@ and TcMethodApplication let denv = env.DisplayEnv - let isSimpleFormalArg (isParamArrayArg, isInArg, isOutArg, optArgInfo: OptionalArgInfo, callerInfoInfo: CallerInfoInfo, _reflArgInfo: ReflectedArgInfo) = - not isParamArrayArg && not isInArg && not isOutArg && not optArgInfo.IsOptional && callerInfoInfo = NoCallerInfo + 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) diff --git a/src/fsharp/infos.fs b/src/fsharp/infos.fs index 7edd799aad..3459d949b5 100755 --- a/src/fsharp/infos.fs +++ b/src/fsharp/infos.fs @@ -1556,12 +1556,19 @@ type MethInfo = let paramAttribs = x.GetParamAttribs(amap, m) (paramAttribs,paramNamesAndTypes) ||> List.map2 (List.map2 (fun (isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo) (ParamNameAndType(nmOpt,pty)) -> - let g = x.TcGlobals - let pty = - // add the "annotation" about whether this is an inref, outref or plain byref - if isByrefTy g pty && isInArg then mkInByrefTy g (destByrefTy g pty) - elif isByrefTy g pty && isOutArg then mkOutByrefTy g (destByrefTy g pty) - else pty + // This was an attempt to add the "annotation" about whether this is an inref, outref or plain byref + // + // However we can't do this for "[in]" based on the attribute alone - the modreq is also needed. + // There is existing .NET Com Interop code that has the "[in]" attribute that doesn't have the modreq attribute + // and we can't retofit the "inref" type onto that code (it would probably legitimate to do so but requires very careful + // extra type inference rules in order to maintain compat). + // + //let pty = + // let g = x.TcGlobals + // // We don't do this for "[in]" based on the attribute alone - the modreq is also needed. + // //if isByrefTy g pty && isInArg then mkInByrefTy g (destByrefTy g pty) + // if isByrefTy g pty && isOutArg then mkOutByrefTy g (destByrefTy g pty) + // else pty ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, nmOpt, reflArgInfo, pty))) /// Get the ParamData objects for the parameters of a MethInfo From 057b5211f208afe282ea2cb750ac52146ca32f9b Mon Sep 17 00:00:00 2001 From: Don Syme Date: Thu, 17 May 2018 13:57:08 +0100 Subject: [PATCH 32/61] fix tests --- .../FSharp.Compiler.Private/FSComp.fs | 4 ++++ .../FSharp.Compiler.Private/FSComp.resx | 3 +++ src/fsharp/TypeChecker.fs | 20 ++++++++++++++----- src/scripts/scriptlib.fsx | 15 +++++++++++--- tests/fsharp/core/fsiAndModifiers/prepare.fsx | 4 +++- tests/fsharp/typecheck/sigs/neg106.vsbsl | 4 ++-- 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index a7359b0c48..bba878b891 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -4312,6 +4312,9 @@ type internal SR private() = /// The byref pointer is readonly, so this write is not permitted. /// (Originally from ..\FSComp.txt:1428) static member writeToReadOnlyByref() = (3224, GetStringFunc("writeToReadOnlyByref",",,,") ) + /// A ReadOnly attribute has been applied to a struct type with a mutable field. + /// (Originally from ..\FSComp.txt:1429) + static member readOnlyAttributeOnStructWithMutableField() = (3225, GetStringFunc("readOnlyAttributeOnStructWithMutableField",",,,") ) /// Call this method once to validate that all known resources are valid; throws if not static member RunStartupValidation() = @@ -5714,4 +5717,5 @@ type internal SR private() = ignore(GetString("implicitlyDiscardedSequenceInSequenceExpression")) ignore(GetString("ilreadFileChanged")) ignore(GetString("writeToReadOnlyByref")) + ignore(GetString("readOnlyAttributeOnStructWithMutableField")) () diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index dc45c4bf3f..6facfc93b6 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -4315,4 +4315,7 @@ The byref pointer is readonly, so this write is not permitted. + + A ReadOnly attribute has been applied to a struct type with a mutable field. + \ No newline at end of file diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index ad1b5632b1..5481d79a38 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -3977,6 +3977,7 @@ let buildApp cenv expr resultTy arg m = // 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. MakeApplicableExprNoFlex cenv (mkCompGenSequential m arg (mkReraise m resultTy)), resultTy @@ -3989,22 +3990,31 @@ let buildApp cenv expr resultTy arg m = let resultTy = mkByrefTyWithInference g argTy (NewByRefKindInferenceType g m) // resultTy expr.SupplyArgument(arg, m), resultTy - // Special rules for building applications of the '&expr' or '&&expr' operators, both of which get the + // 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 || valRefEq g vf g.addrof2_vref || valRefEq g vf g.nativeptr_tobyref_vref) -> - if valRefEq g vf g.addrof2_vref then warning(UseOfAddressOfOperator(m)) + 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 && valRefEq g vf g.addrof_vref then + if readonly then mkInByrefTy g argTy else - mkByrefTyWithInference g argTy (NewByRefKindInferenceType g m) // resultTy + 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 | _ -> diff --git a/src/scripts/scriptlib.fsx b/src/scripts/scriptlib.fsx index 79481efb7c..6835b9418f 100644 --- a/src/scripts/scriptlib.fsx +++ b/src/scripts/scriptlib.fsx @@ -7,6 +7,7 @@ namespace global open System open System.IO +open System.Text open System.Diagnostics [] @@ -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) = diff --git a/tests/fsharp/core/fsiAndModifiers/prepare.fsx b/tests/fsharp/core/fsiAndModifiers/prepare.fsx index 6a5b171467..1179c8623a 100644 --- a/tests/fsharp/core/fsiAndModifiers/prepare.fsx +++ b/tests/fsharp/core/fsiAndModifiers/prepare.fsx @@ -31,4 +31,6 @@ try asmBuilder.Save(filename) exit 0 -with _ -> exit 1 \ No newline at end of file +with err -> + printfn "Error: %A" err + exit 1 \ No newline at end of file diff --git a/tests/fsharp/typecheck/sigs/neg106.vsbsl b/tests/fsharp/typecheck/sigs/neg106.vsbsl index b854b8ae53..1994596521 100644 --- a/tests/fsharp/typecheck/sigs/neg106.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg106.vsbsl @@ -78,7 +78,7 @@ is not compatible with type . neg106.fs(16,31,16,35): typecheck error FS0001: Type mismatch. Expecting a - 'byref' + 'byref' but given a 'inref' -The type 'ByRefKinds.Out' does not match the type 'ByRefKinds.In' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' From 45050eb3e5060f826e5e4231565040acaf01422f Mon Sep 17 00:00:00 2001 From: Don Syme Date: Thu, 17 May 2018 14:42:33 +0100 Subject: [PATCH 33/61] fix tests --- tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs | 14 ++++++++++++++ tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs index 8e03c2b6de..8f9b94faf9 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.coreclr.fs @@ -773,6 +773,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() diff --git a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs index 5ef8782123..62459c9b18 100644 --- a/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs +++ b/tests/FSharp.Core.UnitTests/SurfaceArea.net40.fs @@ -777,6 +777,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) From 9f95be8223688f89af359520e17cc9273d2fe546 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Thu, 17 May 2018 16:00:13 +0100 Subject: [PATCH 34/61] get it right silly boy --- src/fsharp/TypeChecker.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 5481d79a38..6d80416b07 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -3986,8 +3986,8 @@ let buildApp cenv expr resultTy arg m = | ApplicableExpr(_, Expr.App(Expr.Val(vf, _, _), _, _, [], _), _), _ when (valRefEq g vf g.nativeptr_tobyref_vref) -> - let argTy = tyOfExpr g arg - let resultTy = mkByrefTyWithInference g argTy (NewByRefKindInferenceType g m) // resultTy + 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 From e747a8425598330fe524b1c867a6296c2608b071 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 18 May 2018 13:48:49 +0100 Subject: [PATCH 35/61] fix test --- src/fsharp/TastOps.fs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 5d3d76bfda..c8aeabd4c8 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -828,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 @@ -2963,6 +2958,10 @@ let destByrefTy g ty = | 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 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 From 9a1efdb079b0d881dc95c8b1b87f4b26385c7283 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 19 May 2018 00:04:00 +0100 Subject: [PATCH 36/61] minor cleanup --- src/FSharpSource.Settings.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FSharpSource.Settings.targets b/src/FSharpSource.Settings.targets index e0e13a59de..ef284990aa 100644 --- a/src/FSharpSource.Settings.targets +++ b/src/FSharpSource.Settings.targets @@ -189,7 +189,7 @@ full portable true - PROTO;DEBUG;NO_STRONG_NAMES;$(DefineConstants) + DEBUG;NO_STRONG_NAMES;$(DefineConstants) From 33aa5aa62caa286ab5f37d14789e840901041665 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 19 May 2018 01:28:26 +0100 Subject: [PATCH 37/61] add more tests --- src/fsharp/PostInferenceChecks.fs | 11 +++++------ src/fsharp/TastOps.fs | 23 +++++++++++++---------- src/fsharp/TastOps.fsi | 2 +- src/fsharp/TastPickle.fs | 4 ++-- src/fsharp/TypeChecker.fs | 10 +--------- src/fsharp/infos.fs | 13 ------------- tests/fsharp/core/byrefs/test.fsx | 10 ++++++++++ tests/fsharp/core/fsfromfsviacs/lib2.cs | 15 +++++++++++++++ tests/fsharp/core/fsfromfsviacs/test.fsx | 20 ++++++++++++++++++-- tests/fsharp/tests.fs | 7 +++++-- 10 files changed, 70 insertions(+), 45 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index ea25c83b80..59212355c2 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -920,7 +920,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn | true, firstArg::_ -> firstArg.SetHasBeenReferenced() | _ -> () // any byRef arguments are considered used, as they may be 'out's - restArgs |> List.iter (fun arg -> if isByrefLikeTy cenv.g m arg.Type then arg.SetHasBeenReferenced()) + restArgs |> List.iter (fun arg -> if isByrefTy cenv.g arg.Type then arg.SetHasBeenReferenced()) syntacticArgs |> List.iter (CheckValSpec cenv env) syntacticArgs |> List.iter (BindVal cenv env) @@ -937,7 +937,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn CheckNoReraise cenv freesOpt body // Check the body of the lambda - if (* (not (isNil tps) || not (isNil vsl)) && *) isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g m bodyty then + if (not (isNil tps) || not (isNil vsl)) && isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g m bodyty then // allow byref to occur as return position for byref-typed top level function or method CheckExprPermitByrefReturn cenv env body else @@ -945,7 +945,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // Check byref return types if cenv.reportErrors then - if (* (not inlined && (isNil tps && isNil vsl)) || *) not isTop then + if (not inlined && (isNil tps && isNil vsl)) || not isTop then CheckForByrefLikeType cenv env m bodyty (fun () -> errorR(Error(FSComp.SR.chkFirstClassFuncNoByref(), m))) @@ -1447,14 +1447,13 @@ let CheckEntityDefn cenv env (tycon:Entity) = if numCurriedArgSets > 1 && (minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) - |> List.existsSquared (fun (ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, _, reflArgInfo, ty)) -> - isParamArrayArg || isInArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefLikeTy cenv.g m ty)) then + |> List.existsSquared (fun (ParamData(isParamArrayArg, _isInArg, isOutArg, optArgInfo, callerInfoInfo, _, reflArgInfo, ty)) -> + isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefLikeTy cenv.g m ty)) then errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m)) if numCurriedArgSets = 1 then minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) |> List.iterSquared (fun (ParamData(_, isInArg, _, optArgInfo, callerInfoInfo, _, _, ty)) -> - // TODO: default values and in args ignore isInArg match (optArgInfo, callerInfoInfo) with | _, NoCallerInfo -> () diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index c8aeabd4c8..891d1a64d2 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -1278,7 +1278,8 @@ let mkStaticRecdFieldGetAddr(readonly, fref, tinst, m) = Expr.Op (TOp.ValFieldGe 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, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, aexpr, nexpr, m) = Expr.Op (TOp.ILAsm ([IL.I_ldelema(ilInstrReadOnlyAnnotation, isNativePtr, shape, mkILTyvarTy 0us)], [mkByrefTyWithFlag g readonly 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) @@ -5726,17 +5727,20 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress | Expr.Op (TOp.LValueOp (LByrefGet, v), _, [], m) -> let readonly = isInByrefTy g v.Type None, exprForValRef m v, readonly + // 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 m v mut -> let readonly = not (MustTakeAddressOfVal g v) None, mkValAddr m readonly v, readonly + // LVALUE: "x" where "e.x" is record field. | Expr.Op (TOp.ValFieldGet rfref, tinst, [e], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref mut -> let exprty = tyOfExpr g e let wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m let readonly = readonly || not (MustTakeAddressOfRecdFieldRef rfref) wrap, mkRecdFieldGetAddrViaExprAddr(readonly, expra, rfref, tinst, m), readonly + // LVALUE: "x" where "e.x" is union field | Expr.Op (TOp.UnionCaseFieldGet (uref, cidx), tinst, [e], m) when MustTakeAddressOfRecdField (uref.FieldByIndex(cidx)) || CanTakeAddressOfUnionFieldRef g m uref mut -> let exprty = tyOfExpr g e @@ -5746,39 +5750,38 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress // LVALUE: "x" where "e.x" is a .NET static field. | Expr.Op (TOp.ILAsm ([IL.I_ldsfld(_vol, fspec)], [ty2]), tinst, [], m) -> - let readonly = false - //let readonly = not (MustTakeAddressOfILStaticField (uref.FieldByIndex(cidx))) + 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 + // 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 e None m - //let readonly = not (MustTakeAddressOfILField fspec) - wrap, Expr.Op (TOp.ILAsm ([IL.I_ldflda(fspec)], [mkByrefTy g ty2]), tinst, [expra], m), readonly + 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 m rfref mut -> - let readonly = false + 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) -> - let readonly = false + let readonly = false // array address is never forced to be readonly let shape = ILArrayShape.SingleDimensional 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, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, aexpr, nexpr, m), readonly + 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) -> - let readonly = false + let readonly = false // array address is never forced to be readonly let shape = ILArrayShape.FromRank args.Length let ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress let isNativePtr = @@ -5786,7 +5789,7 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress | Some(vf) -> valRefEq g vf g.addrof2_vref | _ -> false - None, Expr.Op (TOp.ILAsm ([IL.I_ldelema(ilInstrReadOnlyAnnotation, isNativePtr, shape, mkILTyvarTy 0us)], [mkByrefTy g elemTy]), [elemTy], (aexpr::args), m), readonly + None, mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, (aexpr::args), m), readonly | Expr.Val(v, _, m) when isByrefTy g v.Type -> error(Error(FSComp.SR.tastUnexpectedByRef(), m)) diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index baf40259d2..38d2c07df2 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -222,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 -> readonly: bool * 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 diff --git a/src/fsharp/TastPickle.fs b/src/fsharp/TastPickle.fs index 2756b6470d..c09cd1277d 100755 --- a/src/fsharp/TastPickle.fs +++ b/src/fsharp/TastPickle.fs @@ -2283,7 +2283,7 @@ and p_op x st = p_byte 30 st; p_int a 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.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.UnionCaseProof (a) -> p_byte 14 st; p_ucref a st | TOp.Coerce -> p_byte 15 st @@ -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 false + | 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 diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 6d80416b07..4e803106ed 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -9268,14 +9268,6 @@ and TcMethodApplicationThen and GetNewInferenceTypeForMethodArg cenv env tpenv x = match x with | SynExprParen(a, _, _, _) -> GetNewInferenceTypeForMethodArg cenv env tpenv a - - // // For code compat reasons we allow passing a "ref" arg where an `inref<_>` is required though taking the address is - //// now implicit. In order to infer this we check the callsite syntax. - //| SynExpr.App(_, _, SingleIdent opId, _, _) - // when opId.idText = "ref" && - // (match env.eNameResEnv.eUnqualifiedItems.TryFind(opId.idText) with Some(Item.Value vref) -> valRefEq cenv.g vref cenv.g.fsharpref_vref | _ -> false) -> - // mkRefCellTy cenv.g (NewInferenceType()) - | SynExpr.AddressOf(true, a, _, _) -> mkByrefTyWithInference cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) (NewInferenceType()) | SynExpr.Lambda(_, _, _, a, _) -> mkFunTy (NewInferenceType ()) (GetNewInferenceTypeForMethodArg cenv env tpenv a) | SynExpr.Quote(_, raw, a, _, _) -> @@ -10318,7 +10310,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 (false, 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 diff --git a/src/fsharp/infos.fs b/src/fsharp/infos.fs index 3459d949b5..8faabb81e8 100755 --- a/src/fsharp/infos.fs +++ b/src/fsharp/infos.fs @@ -1556,19 +1556,6 @@ type MethInfo = let paramAttribs = x.GetParamAttribs(amap, m) (paramAttribs,paramNamesAndTypes) ||> List.map2 (List.map2 (fun (isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, reflArgInfo) (ParamNameAndType(nmOpt,pty)) -> - // This was an attempt to add the "annotation" about whether this is an inref, outref or plain byref - // - // However we can't do this for "[in]" based on the attribute alone - the modreq is also needed. - // There is existing .NET Com Interop code that has the "[in]" attribute that doesn't have the modreq attribute - // and we can't retofit the "inref" type onto that code (it would probably legitimate to do so but requires very careful - // extra type inference rules in order to maintain compat). - // - //let pty = - // let g = x.TcGlobals - // // We don't do this for "[in]" based on the attribute alone - the modreq is also needed. - // //if isByrefTy g pty && isInArg then mkInByrefTy g (destByrefTy g pty) - // if isByrefTy g pty && isOutArg then mkOutByrefTy g (destByrefTy g pty) - // else pty ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfoInfo, nmOpt, reflArgInfo, pty))) /// Get the ParamData objects for the parameters of a MethInfo diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 82ff2cd0e1..be75d9bd60 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -958,6 +958,16 @@ module ByrefReturnMemberTests = let dt = DateTime.Now.ExtDateTime(3) let dt2 = DateTime.Now.ExtDateTime(3) *) + module TestReadOnlyAddressOfStaticField = + type C() = + static let x = 1 + static member F() = &x + + let test() = + let addr = &C.F() + check2 "mepojcwem18a2dw" 1 addr + + test() let aa = if !failures then (stdout.WriteLine "Test Failed"; exit 1) diff --git a/tests/fsharp/core/fsfromfsviacs/lib2.cs b/tests/fsharp/core/fsfromfsviacs/lib2.cs index 95671b926f..677e462f51 100644 --- a/tests/fsharp/core/fsfromfsviacs/lib2.cs +++ b/tests/fsharp/core/fsfromfsviacs/lib2.cs @@ -50,11 +50,26 @@ public static class Extensions { /// 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 diff --git a/tests/fsharp/core/fsfromfsviacs/test.fsx b/tests/fsharp/core/fsfromfsviacs/test.fsx index 1fba263ef4..a73be17813 100644 --- a/tests/fsharp/core/fsfromfsviacs/test.fsx +++ b/tests/fsharp/core/fsfromfsviacs/test.fsx @@ -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 diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 2ac5299a49..e5ab82cf25 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -404,19 +404,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"] From 4e4921b131478c318331d5c0d17af9d1102cc62a Mon Sep 17 00:00:00 2001 From: Don Syme Date: Mon, 21 May 2018 15:42:14 +0100 Subject: [PATCH 38/61] clarify overloading behaviour + test case --- src/fsharp/ConstraintSolver.fs | 12 +++++++++--- tests/fsharp/core/byrefs/test.fsx | 26 ++++++++++++++++++++++++++ tests/fsharp/core/span/test.fsx | 11 +++++++---- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index 65036f06f7..f20fe0d501 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -2300,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 + | _ when isInByrefTy csenv.g ty2 && typeEquiv csenv.g ty1 (destByrefTy csenv.g ty2) -> + true + | _ -> false) if c <> 0 then c else diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index be75d9bd60..096f702de2 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -223,6 +223,32 @@ module InRefParam = check "cwnoreekerf" (minfo.GetParameters().[0].IsIn) true check "cwnoreekerg" (minfo.GetParameters().[0].IsOut) false +module InRefParamOverload_ExplicitAddressOfAtCallSite = + type C() = + static member M(x: System.DateTime) = x.AddDays(1.0) + static member M(x: inref) = x.AddDays(2.0) + static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) + static member M2(x: inref, y: int) = x.AddDays(2.0) + let res = System.DateTime.Now + let v = C.M(&res) + check "cweweoiwe51btw8" v (res.AddDays(2.0)) + let v2 = C.M2(&res, 0) + check "cweweoiwe51btw6" v2 (res.AddDays(2.0)) + + +module InRefParamOverload_ImplicitAddressOfAtCallSite = + type C() = + static member M(x: System.DateTime) = x.AddDays(1.0) + static member M(x: inref) = x.AddDays(2.0) + static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) + static member M2(x: inref, y: int) = x.AddDays(2.0) + let res = System.DateTime.Now + let v = C.M(res) + check "cweweoiwe51btw1" v (res.AddDays(1.0)) + let v2 = C.M2(res, 4) + check "cweweoiwe51btw2" v2 (res.AddDays(1.0)) + + module InRefParam_DateTime = type C() = static member M(x: inref) = x diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index f3989953a6..ca240329d7 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -106,18 +106,21 @@ namespace Tests let f6() = // managed memory let arrayMemory = Array.zeroCreate(100) - let arraySpan = new Span(arrayMemory); + let arraySpan = new Span(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(nativeMemory.ToPointer(), 100); + let nativeMemory = Marshal.AllocHGlobal(100) + let nativeSpan = new Span(nativeMemory.ToPointer(), 100) + for i in 0 .. 99 do Marshal.WriteByte(nativeMemory, i, byte i) SafeSum(nativeSpan)|> printfn "res = %d" - Marshal.FreeHGlobal(nativeMemory); + Marshal.FreeHGlobal(nativeMemory) // stack memory let mem = NativePtr.stackalloc(100) let mem2 = mem |> NativePtr.toVoidPtr + for i in 0 .. 99 do NativePtr.set mem i (byte i) let stackSpan = Span(mem2, 100) SafeSum(stackSpan) |> printfn "res = %d" f6() From 19463a9fc0ef8056aaa3e8981b69b92b4875e174 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 25 May 2018 12:26:46 +0200 Subject: [PATCH 39/61] fix build break --- src/fsharp/FSharp.Core/prim-types.fsi | 35 ++++++++++++++------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/fsharp/FSharp.Core/prim-types.fsi b/src/fsharp/FSharp.Core/prim-types.fsi index 5a1cefef7d..5600db0552 100644 --- a/src/fsharp/FSharp.Core/prim-types.fsi +++ b/src/fsharp/FSharp.Core/prim-types.fsi @@ -1659,6 +1659,24 @@ namespace Microsoft.FSharp.Core /// The optimized function. 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 + + /// Represents a in-argument or readonly managed pointer in F# code. This type should only be used with F# 4.5+. + type inref<'T> = byref<'T, ByRefKinds.In> + + /// Represents a out-argument managed pointer in F# code. This type should only be used with F# 4.5+. + type outref<'T> = byref<'T, ByRefKinds.Out> + /// The type of mutable references. Use the functions [!] and [:=] to get and /// set values of this type. [] @@ -3195,23 +3213,6 @@ namespace Microsoft.FSharp.Core [] val inline char : value:^T -> char when ^T : (static member op_Explicit : ^T -> char) and default ^T : int - /// 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 - - /// Represents a in-argument or readonly managed pointer in F# code. This type should only be used with F# 4.5+. - type inref<'T> = byref<'T, ByRefKinds.In> - - /// Represents a out-argument managed pointer in F# code. This type should only be used with F# 4.5+. - type outref<'T> = byref<'T, ByRefKinds.Out> namespace Microsoft.FSharp.Control From 75709d34d3fef6d1b6ffec71c8be5d817413c146 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 25 May 2018 14:45:14 +0200 Subject: [PATCH 40/61] fix build of tests --- tests/fsharp/tests.fs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 755b20d6fc..e23b4a8f8a 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -231,7 +231,6 @@ module CoreTests = // fsiAnyCpu cfg "" ["test.fsx"] // testOkFile.CheckExists() //end - testOkFile.CheckExists() [] let asyncStackTraces () = From 520a9191f6e867d0fffd0a54d4b97f8a34c471a6 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 25 May 2018 15:10:21 +0200 Subject: [PATCH 41/61] update tests --- tests/fsharp/typecheck/sigs/neg106.bsl | 120 ++++++++++++++++++++++- tests/fsharp/typecheck/sigs/neg106.fs | 16 +-- tests/fsharp/typecheck/sigs/neg106.vsbsl | 44 ++++++++- tests/fsharp/typecheck/sigs/neg107.bsl | 10 +- tests/fsharp/typecheck/sigs/neg107.fsx | 4 +- tests/fsharp/typecheck/sigs/neg107.vsbsl | 10 +- 6 files changed, 170 insertions(+), 34 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg106.bsl b/tests/fsharp/typecheck/sigs/neg106.bsl index c3dfc5415c..25196d19b4 100644 --- a/tests/fsharp/typecheck/sigs/neg106.bsl +++ b/tests/fsharp/typecheck/sigs/neg106.bsl @@ -1,4 +1,120 @@ -neg106.fs(22,24,22,25): parse error FS0010: Unexpected quote symbol in binding. Expected incomplete structured construct at or before this point or other token. +neg106.fs(8,14,8,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(8,14,8,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 + 'byref' +is not compatible with type + 'byref<'a>' +. -neg106.fs(24,1,24,7): parse error FS0010: Incomplete structured construct at or before this point in definition. Expected incomplete structured construct at or before this point or other token. +neg106.fs(11,14,11,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(11,14,11,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 + 'byref' +is not compatible with type + 'byref<'a>' +. + +neg106.fs(16,31,16,35): typecheck error FS0001: Type mismatch. Expecting a + 'byref' +but given a + 'inref' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' + +neg106.fs(22,18,22,22): typecheck error FS0001: Type mismatch. Expecting a + 'byref' +but given a + 'inref' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' + +neg106.fs(29,14,29,28): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. +neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type + 'string' +is not compatible with type + 'int' +. + +neg106.fs(30,15,30,27): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. +neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type + 'int' +is not compatible with type + 'string' +. +neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. + +neg106.fs(36,18,36,22): typecheck error FS0001: Type mismatch. Expecting a + 'byref' +but given a + 'inref' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' + +neg106.fs(46,9,46,25): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted. + +neg106.fs(51,42,51,48): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted. diff --git a/tests/fsharp/typecheck/sigs/neg106.fs b/tests/fsharp/typecheck/sigs/neg106.fs index efec084135..b08941b026 100644 --- a/tests/fsharp/typecheck/sigs/neg106.fs +++ b/tests/fsharp/typecheck/sigs/neg106.fs @@ -15,19 +15,19 @@ module TryGetValueTests_Negative1 = let res = 9 let v = d.TryGetValue(3, &res) // 'byref' is not compatible with type 'byref' -module FSharpDeclaredOutParamTest_Neagative1 = +module FSharpDeclaredOutParamTest_Negaative1 = type C() = static member M([] x: byref) = () let res = 9 - let v = C.M(&res) 'byref' is not compatible with type 'byref' + let v = C.M(&res) //'byref' is not compatible with type 'byref' module FSharpDeclaredOverloadedOutParamTest_Negative1 = type C() = static member M(a: int, [] x: byref) = x <- 7 static member M(a: string, [] x: byref) = x <- 8 let res = 9 - let v = C.M("a", &res) 'byref' is not compatible with type 'byref' - let v2 = C.M(3, &res) 'byref' is not compatible with type 'byref' + let v = C.M("a", &res) //'byref' is not compatible with type 'byref' + let v2 = C.M(3, &res) //'byref' is not compatible with type 'byref' module FSharpDeclaredOutParamTest_Negative1 = type C() = @@ -50,11 +50,3 @@ module EvilStruct_Negative1 = type EvilStruct(s: int) = member x.Replace(y:EvilStruct) = x <- y -module Span_Negative2 = - let TestClosure1 ([] a: byref) = id (fun () -> a) - let TestClosure2 ([] a: Span) = id (fun () -> a) - let TestClosure3 ([] a: ReadOnlySpan) = id (fun () -> a) - - let TestAsyncClosure1 ([] a: byref) = async { return a } - let TestAsyncClosure2 ([] a: Span) = async { return a } - let TestAsyncClosure3 ([] a: ReadOnlySpan) = async { return a } diff --git a/tests/fsharp/typecheck/sigs/neg106.vsbsl b/tests/fsharp/typecheck/sigs/neg106.vsbsl index 1994596521..25196d19b4 100644 --- a/tests/fsharp/typecheck/sigs/neg106.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg106.vsbsl @@ -1,8 +1,4 @@ -neg106.fs(22,24,22,25): parse error FS0010: Unexpected quote symbol in binding. Expected incomplete structured construct at or before this point or other token. - -neg106.fs(24,1,24,7): parse error FS0010: Incomplete structured construct at or before this point in definition. Expected incomplete structured construct at or before this point or other token. - neg106.fs(8,14,8,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type 'byref' @@ -82,3 +78,43 @@ neg106.fs(16,31,16,35): typecheck error FS0001: Type mismatch. Expecting a but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' + +neg106.fs(22,18,22,22): typecheck error FS0001: Type mismatch. Expecting a + 'byref' +but given a + 'inref' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' + +neg106.fs(29,14,29,28): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. +neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. +neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type + 'string' +is not compatible with type + 'int' +. + +neg106.fs(30,15,30,27): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. +neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type + 'int' +is not compatible with type + 'string' +. +neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type + 'byref' +is not compatible with type + 'byref' +. + +neg106.fs(36,18,36,22): typecheck error FS0001: Type mismatch. Expecting a + 'byref' +but given a + 'inref' +The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' + +neg106.fs(46,9,46,25): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted. + +neg106.fs(51,42,51,48): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted. diff --git a/tests/fsharp/typecheck/sigs/neg107.bsl b/tests/fsharp/typecheck/sigs/neg107.bsl index 4b7c2da4b9..401484eb33 100644 --- a/tests/fsharp/typecheck/sigs/neg107.bsl +++ b/tests/fsharp/typecheck/sigs/neg107.bsl @@ -1,9 +1,7 @@ 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,13,27,25): typecheck error FS0037: Duplicate definition of value 'TestClosure1' - -neg107.fsx(27,68,27,79): 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. @@ -25,11 +23,9 @@ neg107.fsx(31,49,31,54): typecheck error FS0406: The byref-typed variable 'a' is 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,13,32,30): typecheck error FS0037: Duplicate definition of value 'TestAsyncClosure1' - -neg107.fsx(32,69,32,74): 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,77,32,85): 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. diff --git a/tests/fsharp/typecheck/sigs/neg107.fsx b/tests/fsharp/typecheck/sigs/neg107.fsx index c9c5f8080f..3bca46d42c 100644 --- a/tests/fsharp/typecheck/sigs/neg107.fsx +++ b/tests/fsharp/typecheck/sigs/neg107.fsx @@ -24,12 +24,12 @@ namespace Test module Span_Negative1 = let TestClosure1 (a: inref) = id (fun () -> a) - let TestClosure1 ([] a: byref) = id (fun () -> a) + let TestClosure1b ([] a: byref) = id (fun () -> a) let TestClosure2 (a: Span) = id (fun () -> a) let TestClosure3 (a: ReadOnlySpan) = id (fun () -> a) let TestAsyncClosure1 (a: inref) = async { return a } - let TestAsyncClosure1 ([] a: byref) = async { return a } + let TestAsyncClosure1b ([] a: byref) = async { return a } let TestAsyncClosure2 (a: Span) = async { return a } let TestAsyncClosure3 (a: ReadOnlySpan) = async { return a } diff --git a/tests/fsharp/typecheck/sigs/neg107.vsbsl b/tests/fsharp/typecheck/sigs/neg107.vsbsl index 4b7c2da4b9..401484eb33 100644 --- a/tests/fsharp/typecheck/sigs/neg107.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg107.vsbsl @@ -1,9 +1,7 @@ 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,13,27,25): typecheck error FS0037: Duplicate definition of value 'TestClosure1' - -neg107.fsx(27,68,27,79): 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. @@ -25,11 +23,9 @@ neg107.fsx(31,49,31,54): typecheck error FS0406: The byref-typed variable 'a' is 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,13,32,30): typecheck error FS0037: Duplicate definition of value 'TestAsyncClosure1' - -neg107.fsx(32,69,32,74): 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,77,32,85): 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. From 37ccc1c8d26aa3b4448a988ad539824472a5f530 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 25 May 2018 15:20:47 +0200 Subject: [PATCH 42/61] add more tests --- tests/fsharp/core/byrefs/test.fsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 096f702de2..0dd236d8f6 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -62,7 +62,8 @@ module ByRefParam_ExplicitOutAttribute = let minfo = typeof.GetMethod("M") check "cwnoreeker5" (minfo.GetParameters().[0].IsIn) false - check "cwnoreeker6" (minfo.GetParameters().[0].IsOut) true + check "cwnoreeker6a" (minfo.GetParameters().[0].IsOut) true + check "cwnoreeker6b" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 check "cwnoreekers1" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 check "cwnoreeker7" (minfo.ReturnParameter.IsIn) false check "cwnoreeker8" (minfo.ReturnParameter.IsOut) false @@ -77,6 +78,7 @@ module ByRefParam_ExplicitInAttribute = let minfo = typeof.GetMethod("M") check "cwnoreeker9" (minfo.GetParameters().[0].IsIn) true check "cwnoreekerq" (minfo.GetParameters().[0].IsOut) false + check "cwnoreeker6c" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 check "cwnoreekers2" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 0 check "cwnoreekerw" (minfo.ReturnParameter.IsIn) false check "cwnoreekere" (minfo.ReturnParameter.IsOut) false @@ -89,6 +91,7 @@ module ByRefReturn = check "cwvereweoiwvw4" v 10 let minfo = typeof.GetMethod("M") + check "cwnoreeker6d" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 check "cwnoreekerr" (minfo.ReturnParameter.IsIn) false check "cwnoreekert" (minfo.ReturnParameter.IsOut) false @@ -105,6 +108,7 @@ module Slot_ByRefReturn = check "cweweoiwek28989" v 5 let minfo = typeof.GetMethod("M") + check "cwnoreeker6e" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 check "cwnoreekery" (minfo.GetParameters().[0].IsIn) false check "cwnoreekeru" (minfo.GetParameters().[0].IsOut) false check "cwnoreekeri" (minfo.ReturnParameter.IsIn) false @@ -121,6 +125,7 @@ module InRefReturn = let minfo = typeof.GetMethod("M") check "cwnoreekerp" (minfo.GetParameters().[0].IsIn) true check "cwnoreekera" (minfo.GetParameters().[0].IsOut) false + check "cwnoreeker6f" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 // modreq only placed on abstract/virtual check "cwnoreekers3" (minfo.ReturnParameter.IsIn) false // has modreq 'In' but reflection never returns true for ReturnParameter.IsIn check "cwnoreekers4" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 1 check "cwnoreekerd" (minfo.ReturnParameter.IsOut) false @@ -139,6 +144,7 @@ module Slot_InRefReturn = let minfo = typeof.GetMethod("M") check "cwnoreekerp" (minfo.GetParameters().[0].IsIn) true check "cwnoreekera" (minfo.GetParameters().[0].IsOut) false + check "cwnoreeker6g" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 1 check "cwnoreekers5" (minfo.ReturnParameter.IsIn) false // has modreq 'In' but reflection never returns true for ReturnParameter.IsIn check "cwnoreekers6" (minfo.ReturnParameter.GetRequiredCustomModifiers().Length) 1 check "cwnoreekerd" (minfo.ReturnParameter.IsOut) false From bf940d19d5c80674f8c90897d8126803430fbdaa Mon Sep 17 00:00:00 2001 From: Don Syme Date: Thu, 31 May 2018 18:20:27 +0100 Subject: [PATCH 43/61] byref fixes --- src/fsharp/PostInferenceChecks.fs | 134 ++++++++++++++++++------------ 1 file changed, 79 insertions(+), 55 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index bf1141a73b..a551f658e6 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -198,7 +198,7 @@ let BindVals cenv env vs = List.iter (BindVal cenv env) vs // approx walk of type //-------------------------------------------------------------------------- -let rec CheckTypeDeep ((visitTyp,visitTyconRefOpt,visitAppTyOpt,visitTraitSolutionOpt, visitTyparOpt) as f) g env typ = +let rec CheckTypeDeep ((visitTyp,visitTyconRefOpt,visitAppTyOpt,visitTraitSolutionOpt, visitTyparOpt) as f) g env isInner typ = // We iterate the _solved_ constraints as well, to pick up any record of trait constraint solutions // This means we walk _all_ the constraints _everywhere_ in a type, including // those attached to _solved_ type variables. This is used by PostTypeCheckSemanticChecks to detect uses of @@ -223,13 +223,13 @@ let rec CheckTypeDeep ((visitTyp,visitTyconRefOpt,visitAppTyOpt,visitTraitSoluti match typ with | TType_forall (tps,body) -> let env = BindTypars g env tps - CheckTypeDeep f g env body + CheckTypeDeep f g env isInner body tps |> List.iter (fun tp -> tp.Constraints |> List.iter (CheckTypeConstraintDeep f g env)) | TType_measure _ -> () | TType_app (tcref,tinst) -> match visitTyconRefOpt with - | Some visitTyconRef -> visitTyconRef tcref + | Some visitTyconRef -> visitTyconRef isInner tcref | None -> () CheckTypesDeep f g env tinst match visitAppTyOpt with @@ -238,7 +238,7 @@ let rec CheckTypeDeep ((visitTyp,visitTyconRefOpt,visitAppTyOpt,visitTraitSoluti | TType_ucase (_,tinst) -> CheckTypesDeep f g env tinst | TType_tuple (_,typs) -> CheckTypesDeep f g env typs - | TType_fun (s,t) -> CheckTypeDeep f g env s; CheckTypeDeep f g env t + | TType_fun (s,t) -> CheckTypeDeep f g env true s; CheckTypeDeep f g env true t | TType_var tp -> if not tp.IsSolved then match visitTyparOpt with @@ -246,16 +246,16 @@ let rec CheckTypeDeep ((visitTyp,visitTyconRefOpt,visitAppTyOpt,visitTraitSoluti | Some visitTypar -> visitTypar (env,tp) -and CheckTypesDeep f g env tys = List.iter (CheckTypeDeep f g env) tys +and CheckTypesDeep f g env tys = List.iter (CheckTypeDeep f g env true) tys and CheckTypeConstraintDeep f g env x = match x with - | TyparConstraint.CoercesTo(ty,_) -> CheckTypeDeep f g env ty + | TyparConstraint.CoercesTo(ty,_) -> CheckTypeDeep f g env true ty | TyparConstraint.MayResolveMember(traitInfo,_) -> CheckTraitInfoDeep f g env traitInfo - | TyparConstraint.DefaultsTo(_,ty,_) -> CheckTypeDeep f g env ty + | TyparConstraint.DefaultsTo(_,ty,_) -> CheckTypeDeep f g env true ty | TyparConstraint.SimpleChoice(tys,_) -> CheckTypesDeep f g env tys - | TyparConstraint.IsEnum(uty,_) -> CheckTypeDeep f g env uty - | TyparConstraint.IsDelegate(aty,bty,_) -> CheckTypeDeep f g env aty; CheckTypeDeep f g env bty + | TyparConstraint.IsEnum(uty,_) -> CheckTypeDeep f g env true uty + | TyparConstraint.IsDelegate(aty,bty,_) -> CheckTypeDeep f g env true aty; CheckTypeDeep f g env true bty | TyparConstraint.SupportsComparison _ | TyparConstraint.SupportsEquality _ | TyparConstraint.SupportsNull _ @@ -266,7 +266,7 @@ and CheckTypeConstraintDeep f g env x = and CheckTraitInfoDeep ((_,_,_,visitTraitSolutionOpt,_) as f) g env (TTrait(typs,_,_,argtys,rty,soln)) = CheckTypesDeep f g env typs CheckTypesDeep f g env argtys - Option.iter (CheckTypeDeep f g env) rty + Option.iter (CheckTypeDeep f g env true ) rty match visitTraitSolutionOpt, !soln with | Some visitTraitSolution, Some sln -> visitTraitSolution sln | _ -> () @@ -276,7 +276,7 @@ and CheckTraitInfoDeep ((_,_,_,visitTraitSolutionOpt,_) as f) g env (TTrait(typs //-------------------------------------------------------------------------- let CheckForByrefLikeType cenv env typ check = - CheckTypeDeep (ignore, Some (fun tcref -> if isByrefLikeTyconRef cenv.g tcref then check()), None, None, None) cenv.g env typ + CheckTypeDeep (ignore, Some (fun _deep tcref -> if isByrefLikeTyconRef cenv.g tcref then check()), None, None, None) cenv.g env false typ //-------------------------------------------------------------------------- @@ -351,7 +351,7 @@ let CheckTypeForAccess (cenv:cenv) env objName valAcc m ty = if isLessAccessible tyconAcc valAcc then errorR(Error(FSComp.SR.chkTypeLessAccessibleThanType(tcref.DisplayName, (objName())), m)) - CheckTypeDeep (visitType, None, None, None, None) cenv.g env ty + CheckTypeDeep (visitType, None, None, None, None) cenv.g env false ty let WarnOnWrongTypeForAccess (cenv:cenv) env objName valAcc m ty = if cenv.reportErrors then @@ -369,12 +369,15 @@ let WarnOnWrongTypeForAccess (cenv:cenv) env objName valAcc m ty = let warningText = errorText + System.Environment.NewLine + FSComp.SR.tcTypeAbbreviationsCheckedAtCompileTime() warning(AttributeChecking.ObsoleteWarning(warningText, m)) - CheckTypeDeep (visitType, None, None, None, None) cenv.g env ty + CheckTypeDeep (visitType, None, None, None, None) cenv.g env false ty //-------------------------------------------------------------------------- // check type instantiations //-------------------------------------------------------------------------- +[] +type PermitByrefs = None | Outer | All + /// Check types occurring in the TAST. let CheckType permitByrefs (cenv:cenv) env m ty = if cenv.reportErrors then @@ -385,8 +388,8 @@ let CheckType permitByrefs (cenv:cenv) env m ty = else errorR (Error(FSComp.SR.checkNotSufficientlyGenericBecauseOfScope(tp.DisplayName),m)) - let visitTyconRef tcref = - if not permitByrefs && isByrefLikeTyconRef cenv.g tcref then + let visitTyconRef isInner tcref = + if (permitByrefs = PermitByrefs.None || permitByrefs = PermitByrefs.Outer && isInner) && isByrefLikeTyconRef cenv.g tcref then errorR(Error(FSComp.SR.chkErrorUseOfByref(), m)) if tyconRefEq cenv.g cenv.g.system_Void_tcref tcref then errorR(Error(FSComp.SR.chkSystemVoidOnlyInTypeof(), m)) @@ -411,19 +414,24 @@ let CheckType permitByrefs (cenv:cenv) env m ty = cenv.potentialUnboundUsesOfVals <- cenv.potentialUnboundUsesOfVals.Add(vref.Stamp,m) | _ -> () - CheckTypeDeep (ignore, Some visitTyconRef, Some visitAppTy, Some visitTraitSolution, Some visitTypar) cenv.g env ty + CheckTypeDeep (ignore, Some visitTyconRef, Some visitAppTy, Some visitTraitSolution, Some visitTypar) cenv.g env false ty /// Check types occurring in TAST (like CheckType) and additionally reject any byrefs. /// The additional byref checks are to catch "byref instantiations" - one place were byref are not permitted. -let CheckTypeNoByrefs (cenv:cenv) env m ty = CheckType false cenv env m ty -let CheckTypePermitByrefs (cenv:cenv) env m ty = CheckType true cenv env m ty +let CheckTypeNoByrefs (cenv:cenv) env m ty = CheckType PermitByrefs.None cenv env m ty + +/// Check types occurring in TAST but allow an outer byref. +let CheckTypePermitOuterByref (cenv:cenv) env m ty = CheckType PermitByrefs.Outer cenv env m ty + +/// Check types occurring in TAST but allow all byrefs. Only used on internally-generated types +let CheckTypePermitAllByrefs (cenv:cenv) env m ty = CheckType PermitByrefs.All cenv env m ty let CheckTypeInstNoByrefs cenv env m tyargs = tyargs |> List.iter (CheckTypeNoByrefs cenv env m) -let CheckTypeInstPermitByrefs cenv env m tyargs = - tyargs |> List.iter (CheckType true cenv env m) +let CheckTypeInstPermitAllByrefs cenv env m tyargs = + tyargs |> List.iter (CheckTypePermitAllByrefs cenv env m) //-------------------------------------------------------------------------- @@ -445,22 +453,29 @@ let mkArgsPermitByrefs isByrefReturnCall n = else TupleOfArgsPermitByrefs n /// Work out what byref-values are allowed at input positions to named F# functions or members -let mkArgsForAppliedVal isByrefReturnCall (vref:ValRef) = +let mkArgsForAppliedVal isBaseCall isByrefReturnCall (vref:ValRef) argsl = match vref.ValReprInfo with - | Some topValInfo -> List.map (mkArgsPermitByrefs isByrefReturnCall) topValInfo.AritiesOfArgs + | Some topValInfo -> + let argArities = topValInfo.AritiesOfArgs + let argArities = if isBaseCall && argArities.Length >= 1 then List.tail argArities else argArities + // Check for partial applications: arguments to partial applciations don't get to use byrefs + if List.length argsl >= argArities.Length then + List.map (mkArgsPermitByrefs isByrefReturnCall) argArities + else + [] | None -> [] /// Work out what byref-values are allowed at input positions to functions -let rec mkArgsForAppliedExpr isByrefReturnCall x = +let rec mkArgsForAppliedExpr isBaseCall isByrefReturnCall argsl x = match x with // recognise val - | Expr.Val (vref,_,_) -> mkArgsForAppliedVal isByrefReturnCall vref + | Expr.Val (vref,_,_) -> mkArgsForAppliedVal isBaseCall isByrefReturnCall vref argsl // step through reclink - | Expr.Link eref -> mkArgsForAppliedExpr isByrefReturnCall !eref + | Expr.Link eref -> mkArgsForAppliedExpr isBaseCall isByrefReturnCall argsl !eref // step through instantiations - | Expr.App(f,_fty,_tyargs,[],_) -> mkArgsForAppliedExpr isByrefReturnCall f + | Expr.App(f,_fty,_tyargs,[],_) -> mkArgsForAppliedExpr isBaseCall isByrefReturnCall argsl f // step through subsumption coercions - | Expr.Op(TOp.Coerce,_,[f],_) -> mkArgsForAppliedExpr isByrefReturnCall f + | Expr.Op(TOp.Coerce,_,[f],_) -> mkArgsForAppliedExpr isBaseCall isByrefReturnCall argsl f | _ -> [] /// Applied functions get wrapped in coerce nodes for subsumption coercions @@ -511,7 +526,7 @@ and CheckVal (cenv:cenv) (env:env) v m context = if noByrefs context && isByrefLikeTy cenv.g v.Type then // byref typed val can only occur in permitting contexts errorR(Error(FSComp.SR.chkNoByrefAtThisPoint(v.DisplayName), m)) - CheckTypePermitByrefs cenv env m v.Type + CheckTypePermitAllByrefs cenv env m v.Type // the byref checks are done at the actual binding of the value /// Check an expression, given information about the position of the expression and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = @@ -530,7 +545,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = CheckExpr cenv env body context | Expr.Const (_,m,ty) -> - CheckTypePermitByrefs cenv env m ty + CheckTypePermitOuterByref cenv env m ty | Expr.Val (v,vFlags,m) -> if cenv.reportErrors then @@ -572,7 +587,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = CheckExprNoByrefs cenv env superInitCall CheckMethods cenv env basev overrides CheckInterfaceImpls cenv env basev iimpls - CheckTypePermitByrefs cenv env m typ + CheckTypeNoByrefs cenv env m typ let interfaces = [ if isInterfaceTy cenv.g typ then yield! AllSuperTypesOfType cenv.g cenv.amap m AllowMultiIntfInstantiations.Yes typ @@ -582,7 +597,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = CheckMultipleInterfaceInstantiations cenv interfaces m // Allow base calls to F# methods - | Expr.App((InnerExprPat(ExprValWithPossibleTypeInst(v,vFlags,_,_) as f)),fty,tyargs,(Expr.Val(baseVal,_,_) :: rest),m) + | Expr.App((InnerExprPat(ExprValWithPossibleTypeInst(v,vFlags,_,_) as f)),_fty,tyargs,(Expr.Val(baseVal,_,_) :: rest),m) when ((match vFlags with VSlotDirectCall -> true | _ -> false) && baseVal.BaseOrThisInfo = BaseVal) -> // dprintfn "GOT BASE VAL USE" @@ -592,9 +607,8 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = else CheckVal cenv env v m NoByrefs CheckVal cenv env baseVal m NoByrefs - CheckTypePermitByrefs cenv env m fty - CheckTypeInstPermitByrefs cenv env m tyargs - CheckExprs cenv env rest (List.tail (mkArgsForAppliedExpr false f)) + CheckTypeInstNoByrefs cenv env m tyargs + CheckExprs cenv env rest (mkArgsForAppliedExpr true false rest f) // Allow base calls to IL methods | Expr.Op (TOp.ILCall (virt,_,_,_,_,_,_,mref,enclTypeArgs,methTypeArgs,tys),tyargs,(Expr.Val(baseVal,_,_)::rest),m) @@ -632,10 +646,10 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = // Allow '%expr' in quotations | Expr.App(Expr.Val(vref,_,_),_,tinst,[arg],m) when isSpliceOperator cenv.g vref && env.quote -> - CheckTypeInstPermitByrefs cenv env m tinst + CheckTypeInstPermitAllByrefs cenv env m tinst // it's the splice operator, a byref instantiation is allowed CheckExprNoByrefs cenv env arg - | Expr.App(f,fty,tyargs,argsl,m) -> + | Expr.App(f,_fty,tyargs,argsl,m) -> if cenv.reportErrors then let g = cenv.g match f with @@ -666,15 +680,13 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = () CheckTypeInstNoByrefs cenv env m tyargs - CheckTypePermitByrefs cenv env m fty - CheckTypeInstPermitByrefs cenv env m tyargs CheckExprNoByrefs cenv env f let isByrefReturnCall = // if return is a byref, and being used as a return, then all arguments must be usable as byref returns match context with | PermitByref true when isByrefTy cenv.g (tyOfExpr cenv.g expr) -> true | _ -> false - CheckExprs cenv env argsl (mkArgsForAppliedExpr isByrefReturnCall f) + CheckExprs cenv env argsl (mkArgsForAppliedExpr false isByrefReturnCall argsl f) // REVIEW: fold the next two cases together | Expr.Lambda(_,_ctorThisValOpt,_baseValOpt,argvs,_,m,rty) -> @@ -692,7 +704,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = CheckExprNoByrefs cenv env e1 | Expr.Match(_,_,dtree,targets,m,ty) -> - CheckTypePermitByrefs cenv env m ty // computed byrefs allowed at each branch + CheckTypePermitAllByrefs cenv env m ty // computed byrefs allowed at each branch CheckDecisionTree cenv env dtree CheckDecisionTreeTargets cenv env targets context @@ -734,7 +746,7 @@ and CheckInterfaceImpl cenv env baseValOpt (_ty,overrides) = and CheckExprOp cenv env (op,tyargs,args,m) context expr = let limitedCheck() = if env.limited then errorR(Error(FSComp.SR.chkObjCtorsCantUseExceptionHandling(), m)) - List.iter (CheckTypePermitByrefs cenv env m) tyargs + (* Special cases *) match op,tyargs,args with // Handle these as special cases since mutables are allowed inside their bodies @@ -743,7 +755,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprsNoByrefs cenv env [e1;e2] | TOp.TryFinally _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],e2,_,_)] -> - CheckTypeInstPermitByrefs cenv env m tyargs // result of a try/finally can be a byref + CheckTypeInstPermitAllByrefs cenv env m tyargs // result of a try/finally can be a byref limitedCheck() CheckExpr cenv env e1 context // result of a try/finally can be a byref if in a position where the overall expression is can be a byref CheckExprNoByrefs cenv env e2 @@ -753,7 +765,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprsNoByrefs cenv env [e1;e2;e3] | TOp.TryCatch _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],_e2,_,_); Expr.Lambda(_,_,_,[_],e3,_,_)] -> - CheckTypeInstPermitByrefs cenv env m tyargs // result of a try/catch can be a byref + CheckTypeInstPermitAllByrefs cenv env m tyargs // result of a try/catch can be a byref limitedCheck() CheckExpr cenv env e1 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref // [(* e2; -- don't check filter body - duplicates logic in 'catch' body *) e3] @@ -763,7 +775,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckTypeInstNoByrefs cenv env m tyargs CheckTypeInstNoByrefs cenv env m enclTypeArgs CheckTypeInstNoByrefs cenv env m methTypeArgs - CheckTypeInstPermitByrefs cenv env m tys // permit byref returns + CheckTypeInstPermitAllByrefs cenv env m tys // permit byref returns // if return is a byref, and being used as a return, then all arguments must be usable as byref returns match context,tys with @@ -818,7 +830,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = | TOp.Coerce,[_ty1;_ty2],[x] -> // Subsumption coercions of functions may involve byrefs in other argument positions - CheckTypeInstPermitByrefs cenv env m tyargs + CheckTypeInstPermitAllByrefs cenv env m tyargs CheckExpr cenv env x context | TOp.Reraise,[_ty1],[] -> @@ -853,7 +865,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprPermitByref cenv env rx | TOp.ILAsm (instrs,tys),_,_ -> - CheckTypeInstPermitByrefs cenv env m tys + CheckTypeInstPermitAllByrefs cenv env m tys CheckTypeInstNoByrefs cenv env m tyargs match instrs,args with | [ I_stfld (_alignment,_vol,_fspec) ],[lhs;rhs] -> @@ -961,7 +973,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // This path is for expression bindings that are not actually lambdas | _ -> // Permit byrefs for let x = ... - CheckTypePermitByrefs cenv env m ety + CheckTypePermitAllByrefs cenv env m ety if not inlined && (isByrefLikeTy cenv.g ety || isNativePtrTy cenv.g ety) then // allow byref to occur as RHS of byref binding. CheckExprPermitByref cenv env e @@ -1011,11 +1023,11 @@ and CheckDecisionTreeSwitch cenv env (e,cases,dflt,m) = and CheckDecisionTreeTest cenv env m discrim = match discrim with - | DecisionTreeTest.UnionCase (_,tinst) -> CheckTypeInstPermitByrefs cenv env m tinst - | DecisionTreeTest.ArrayLength (_,typ) -> CheckTypePermitByrefs cenv env m typ + | DecisionTreeTest.UnionCase (_,tinst) -> CheckTypeInstPermitAllByrefs cenv env m tinst + | DecisionTreeTest.ArrayLength (_,typ) -> CheckTypePermitAllByrefs cenv env m typ | DecisionTreeTest.Const _ -> () | DecisionTreeTest.IsNull -> () - | DecisionTreeTest.IsInst (srcTyp,dstTyp) -> CheckTypePermitByrefs cenv env m srcTyp; CheckTypePermitByrefs cenv env m dstTyp + | DecisionTreeTest.IsInst (srcTyp,dstTyp) -> CheckTypePermitAllByrefs cenv env m srcTyp; CheckTypePermitAllByrefs cenv env m dstTyp | DecisionTreeTest.ActivePatternCase (exp,_,_,_,_) -> CheckExprNoByrefs cenv env exp and CheckAttrib cenv env (Attrib(_,_,args,props,_,_,_)) = @@ -1101,7 +1113,7 @@ and CheckArgInfo cenv env (argInfo : ArgReprInfo) = and CheckValSpec cenv env (v:Val) = v.Attribs |> CheckAttribs cenv env v.ValReprInfo |> Option.iter (CheckValInfo cenv env) - v.Type |> CheckTypePermitByrefs cenv env v.Range + v.Type |> CheckTypePermitAllByrefs cenv env v.Range and AdjustAccess isHidden (cpath: unit -> CompilationPath) access = if isHidden then @@ -1132,7 +1144,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = errorR(Error(FSComp.SR.chkMemberUsedInInvalidWay(nm, nm, stringOfRange m), v.Range)) // Byrefs allowed for x in 'let x = ...' - v.Type |> CheckTypePermitByrefs cenv env v.Range + v.Type |> CheckTypePermitAllByrefs cenv env v.Range v.Attribs |> CheckAttribs cenv env v.ValReprInfo |> Option.iter (CheckValInfo cenv env) @@ -1566,10 +1578,20 @@ let CheckEntityDefn cenv env (tycon:Entity) = tycon.AllFieldsArray |> Array.iter (CheckRecdField false cenv env tycon) // Abstract slots can have byref arguments and returns - abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> CheckTypePermitByrefs cenv env m) + for vref in abstractSlotValsOfTycons [tycon] do + match vref.ValReprInfo with + | Some topValInfo -> + let tps, argtysl, rty, _ = GetTopValTypeInFSharpForm cenv.g topValInfo vref.Type m + let env = BindTypars cenv.g env tps + for argtys in argtysl do + for (argty, _) in argtys do + CheckTypePermitOuterByref cenv env m argty + CheckTypePermitOuterByref cenv env m rty + + | None -> () - // Interface slots can have byref arguments and returns - tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (CheckTypePermitByrefs cenv env m) + // Supported interface may not have byrefs + tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (CheckTypeNoByrefs cenv env m) superOfTycon cenv.g tycon |> CheckTypeNoByrefs cenv env m @@ -1581,7 +1603,9 @@ let CheckEntityDefn cenv env (tycon:Entity) = // Access checks let access = AdjustAccess (IsHiddenTycon env.sigToImplRemapInfo tycon) (fun () -> tycon.CompilationPath) tycon.Accessibility let visitType ty = CheckTypeForAccess cenv env (fun () -> tycon.DisplayNameWithStaticParametersAndUnderscoreTypars) access tycon.Range ty + abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> visitType) + superOfTycon cenv.g tycon |> visitType // We do not have to check access of interface implementations. See FSharp 1.0 5042 From 50f2085c6cd864a08046ab422728001af45fafaa Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 1 Jun 2018 01:11:05 +0100 Subject: [PATCH 44/61] updates for subsumption calls, error message, assign-to-return-byref --- .../FSharp.Compiler.Private/FSComp.fs | 2 +- .../FSharp.Compiler.Private/FSComp.resx | 2 +- src/fsharp/FSComp.txt | 2 +- src/fsharp/TypeChecker.fs | 53 ++++++++++++++----- src/fsharp/xlf/FSComp.txt.cs.xlf | 2 +- src/fsharp/xlf/FSComp.txt.de.xlf | 2 +- src/fsharp/xlf/FSComp.txt.en.xlf | 4 +- src/fsharp/xlf/FSComp.txt.es.xlf | 2 +- src/fsharp/xlf/FSComp.txt.fr.xlf | 2 +- src/fsharp/xlf/FSComp.txt.it.xlf | 2 +- src/fsharp/xlf/FSComp.txt.ja.xlf | 2 +- src/fsharp/xlf/FSComp.txt.ko.xlf | 2 +- src/fsharp/xlf/FSComp.txt.pl.xlf | 2 +- src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 2 +- src/fsharp/xlf/FSComp.txt.ru.xlf | 2 +- src/fsharp/xlf/FSComp.txt.tr.xlf | 2 +- src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 2 +- src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 2 +- tests/fsharp/core/byrefs/test.fsx | 24 +++++++++ tests/fsharp/core/span/test.fsx | 31 +++++++++++ tests/fsharp/typecheck/sigs/neg63.bsl | 4 +- tests/fsharp/typecheck/sigs/neg_byref_7.bsl | 2 +- 22 files changed, 117 insertions(+), 33 deletions(-) diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index 31ef03f13b..c233e02e15 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -4027,7 +4027,7 @@ type internal SR private() = /// Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression. /// (Originally from ../FSComp.txt:1333) static member tcCouldNotFindOffsetToStringData() = (3208, GetStringFunc("tcCouldNotFindOffsetToStringData",",,,") ) - /// 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. + /// The address of the variable '%s' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . /// (Originally from ../FSComp.txt:1334) static member chkNoByrefReturnOfLocal(a0 : System.String) = (3209, GetStringFunc("chkNoByrefReturnOfLocal",",,,%s,,,") a0) /// %s is an active pattern and cannot be treated as a discriminated union case with named fields. diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index 96bcf3fa22..257f135fdb 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -4030,7 +4030,7 @@ Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression. - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . {0} is an active pattern and cannot be treated as a discriminated union case with named fields. diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index e4a4001eb6..9c7e2516e5 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -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,chkNoByrefReturnOfLocal,"The address of the variable '%s' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape 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" diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 058614ab50..f6f56fc49c 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -8400,8 +8400,17 @@ and TcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag:ExprAtomicF // f | 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 + if readonly then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) + 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. @@ -8946,14 +8955,24 @@ 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 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 + 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 | _ -> // Static Property Get (possibly indexer) let meths = pinfos |> GettersOfPropInfos @@ -9121,14 +9140,23 @@ 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)) - 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 [] + 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 [] | _ -> // Instance property getter let meths = GettersOfPropInfos pinfos @@ -9436,7 +9464,7 @@ and TcMethodApplication resultTy) curriedArgTys, returnTy - if isProp && Option.isNone curriedCallerArgsOpt then + if isProp && Option.isNone curriedCallerArgsOpt then error(Error(FSComp.SR.parsIndexerPropertyRequiresAtLeastOneArgument(), mItem)) // STEP 1. UnifyUniqueOverloading. This happens BEFORE we type check the arguments. @@ -12615,6 +12643,8 @@ module IncrClassChecking = // 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) @@ -12624,7 +12654,6 @@ module IncrClassChecking = | _ -> false )) -> //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)) diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 9973bab53f..d9f63b83e6 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 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. diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index fc9bf61430..1c1f64ca16 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 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. diff --git a/src/fsharp/xlf/FSComp.txt.en.xlf b/src/fsharp/xlf/FSComp.txt.en.xlf index a9b2295902..840cffb403 100644 --- a/src/fsharp/xlf/FSComp.txt.en.xlf +++ b/src/fsharp/xlf/FSComp.txt.en.xlf @@ -6518,8 +6518,8 @@ - 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. - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 88c8a62db0..b331d74d5b 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 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. diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index f6c2e68de6..41f135d8bf 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 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. diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 526d8390b9..7725909224 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 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. diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 1bd9fb58c9..259120e659 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 変数 '{0}' のアドレスはこのポイントでは使用できません。メソッドまたは関数がこのローカル値のアドレスを返さない可能性があります。 diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index cff320b0c0..22ddafc452 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 지금은 '{0}' 변수의 주소를 사용할 수 없습니다. 메서드 또는 함수가 이 로컬 값의 주소를 반환할 수 없습니다. diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index a43fb6bb9a..d06eec8dad 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 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. diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index 2027154ca7..765d301026 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 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. diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 894d1c91b6..258f0c625e 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . Адрес переменной "{0}" сейчас невозможно использовать. Метод или функция могут не возвратить адрес этого локального значения. diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 474cdfa10c..9ec4b15054 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . '{0}' değişkeninin adresi bu noktada kullanılamaz. Bir metot veya işlev, bu yerel değerin adresini döndüremez. diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 12cddb3b56..b12cedf774 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 当前无法使用变量 {0} 的地址。方法或函数可能没有返回该本地值的地址。 diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 559539f116..bf02055daf 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -6518,7 +6518,7 @@ - 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. + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . 目前無法使用變數 '{0}' 的位址。方法或函式無法傳回此本機值的位址。 diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 0dd236d8f6..1650fc6d85 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -1001,6 +1001,30 @@ module ByrefReturnMemberTests = test() + module TestAssignToReturnByref = + type C() = + static let mutable v = System.DateTime.Now + static member M() = &v + static member P = &v + member __.InstanceM() = &v + member __.InstanceP with get() = &v + static member Value = v + + let F1() = + let today = System.DateTime.Now.Date + C.M() <- today + check "cwecjc" C.Value today + C.P <- C.M().AddDays(1.0) + check "cwecjc1" C.Value (today.AddDays(1.0)) + let c = C() + c.InstanceM() <- today.AddDays(2.0) + check "cwecjc2" C.Value (today.AddDays(2.0)) + c.InstanceP <- today.AddDays(3.0) + check "cwecjc1" C.Value (today.AddDays(3.0)) + + F1() + + let aa = if !failures then (stdout.WriteLine "Test Failed"; exit 1) else (stdout.WriteLine "Test Passed"; diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index ca240329d7..07aa2eafea 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -133,6 +133,37 @@ namespace Tests val mutable v : int member x.Replace(y:AllowedEvilStruct) = x <- y + module SubsumptionOnMember = + type Doot() = class end + + [] + type GiantDad() = + + let test (data: Span) (doot: Doot) = + () + + member __.Test(data: Span) = + test data Unchecked.defaultof + + 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.Empty + data.[0] <- 1uy + + module AssignToSpanItemGeneric = + let F2<'T>() = + let data = Span<'T>.Empty + data.[0] <- Unchecked.defaultof<'T> + + #if NEGATIVE // Disallow this: diff --git a/tests/fsharp/typecheck/sigs/neg63.bsl b/tests/fsharp/typecheck/sigs/neg63.bsl index 63f7da210c..3d1df0e77a 100644 --- a/tests/fsharp/typecheck/sigs/neg63.bsl +++ b/tests/fsharp/typecheck/sigs/neg63.bsl @@ -9,6 +9,6 @@ neg63.fs(11,5,11,13): typecheck error FS0412: A type instantiation involves a by neg63.fs(14,8,14,9): typecheck error FS3155: A quotation may not involve an assignment to or taking the address of a captured local variable -neg63.fs(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' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape 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 FS3209: The address of the variable 'addr' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . diff --git a/tests/fsharp/typecheck/sigs/neg_byref_7.bsl b/tests/fsharp/typecheck/sigs/neg_byref_7.bsl index 8b085ebcf5..b3a58fdb75 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_7.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_7.bsl @@ -19,4 +19,4 @@ neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg_byref_7.fs(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 FS3209: The address of the variable 'y' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . From e0de866a582f393c64fdfbe4c6026fae9ea9f095 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 1 Jun 2018 01:27:53 +0100 Subject: [PATCH 45/61] test updates, implicit deref on byref return for normal functions --- src/fsharp/TypeChecker.fs | 12 +++++- tests/fsharp/core/byrefs/test.fsx | 72 +++++++++++++++++++++---------- 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index f6f56fc49c..59937bbf53 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -4013,12 +4013,20 @@ let buildApp cenv expr resultTy arg m = // 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-> + 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), resultTy @@ -8320,6 +8328,8 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = 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 + destByrefTy cenv.g exprty else exprty diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 1650fc6d85..dc89186d0b 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -312,7 +312,7 @@ module ByrefReturnTests = let f () = &x let test() = - let addr : byref = f() + let addr : byref = &f() addr <- addr + 1 check2 "cepojcwem1" 2 x @@ -332,11 +332,11 @@ module ByrefReturnTests = let f inp = match inp with 3 -> &x | _ -> &y let test() = - let addr = f 3 + let addr = &f 3 addr <- addr + 1 check2 "cepojcwem2" 2 x check2 "cepojcwem3" 1 y - let addr = f 4 + let addr = &f 4 addr <- addr + 1 check2 "cepojcwem4" 2 x check2 "cepojcwem5" 2 y @@ -357,11 +357,11 @@ module ByrefReturnTests = let f inp = if inp = 3 then &x else &y let test() = - let addr = f 3 + let addr = &f 3 addr <- addr + 1 check2 "cepojcwem6" 2 x check2 "cepojcwem7" 1 y - let addr = f 4 + let addr = &f 4 addr <- addr + 1 check2 "cepojcwem8" 2 x check2 "cepojcwem9" 2 y @@ -382,11 +382,11 @@ module ByrefReturnTests = let f inp = try &x with _ -> &y let test() = - let addr = f 3 + let addr = &f 3 addr <- addr + 1 check2 "cepojcwem6b" 2 x check2 "cepojcwem7b" 1 y - let addr = f 4 + let addr = &f 4 addr <- addr + 1 check2 "cepojcwem8b" 3 x check2 "cepojcwem9b" 1 y @@ -407,11 +407,11 @@ module ByrefReturnTests = let f inp = try &x with _ -> &y let test() = - let addr = f 3 + let addr = &f 3 addr <- addr + 1 check2 "cepojcwem6b" 2 x check2 "cepojcwem7b" 1 y - let addr = f 4 + let addr = &f 4 addr <- addr + 1 check2 "cepojcwem8b" 3 x check2 "cepojcwem9b" 1 y @@ -431,7 +431,7 @@ module ByrefReturnTests = let test() = let mutable r1 = 1 - let addr = f &r1 + let addr = &f &r1 addr <- addr + 1 check2 "cepojcwem10" 2 r1 @@ -444,7 +444,7 @@ module ByrefReturnTests = let test() = let mutable r1 = 1 let mutable r2 = 0 - let addr = f (&r1, &r2) + let addr = &f (&r1, &r2) addr <- addr + 1 check2 "cepojcwem11" 2 r1 @@ -457,7 +457,7 @@ module ByrefReturnTests = let test() = let r = { z = 1 } - let addr = f r + let addr = &f r addr <- addr + 1 check2 "cepojcwem12" 2 r.z @@ -470,7 +470,7 @@ module ByrefReturnTests = let test() = let mutable r = { z = 1 } - let addr = f &r + let addr = &f &r addr <- addr + 1 check2 "cepojcwem13a" 2 r.z @@ -484,7 +484,7 @@ module ByrefReturnTests = let test() = let c = C() - let addr = f c + let addr = &f c addr <- addr + 1 check2 "cepojcwem13b" 1 c.z @@ -496,7 +496,7 @@ module ByrefReturnTests = let test() = let r = [| 1 |] - let addr = f r + let addr = &f r addr <- addr + 1 check2 "cepojcwem14" 2 r.[0] @@ -511,7 +511,7 @@ module ByrefReturnTests = let test() = let mutable r = { z = 1 } - let addr = f &r + let addr = &f &r addr <- addr + 1 check2 "cepojcwem15" 2 r.z @@ -534,9 +534,9 @@ module ByrefReturnTests = let f (i:I) = &i.M() let test() = - let addr = f (C()) + let addr = &f (C()) addr <- addr + 1 - let addr = f (ObjExpr()) + let addr = &f (ObjExpr()) addr <- addr + 1 check2 "cepojcwem16" 3 x @@ -559,9 +559,9 @@ module ByrefReturnTests = let f (i:I) = &i.P let test() = - let addr = f (C()) + let addr = &f (C()) addr <- addr + 1 - let addr = f (ObjExpr()) + let addr = &f (ObjExpr()) addr <- addr + 1 check2 "cepojcwem17" 3 x @@ -577,7 +577,7 @@ module ByrefReturnTests = let f (d:D) = &d.Invoke() let test() = - let addr = f (d()) + let addr = &f (d()) check2 "cepojcwem18a" 1 x addr <- addr + 1 check2 "cepojcwem18b" 2 x @@ -607,7 +607,7 @@ module ByrefReturnTests = let f (d:D) = &d.Invoke(&x) let test() = - let addr = f (d()) + let addr = &f (d()) check2 "cepojcwem18a2" 1 x addr <- addr + 1 check2 "cepojcwem18b3" 2 x @@ -1024,6 +1024,34 @@ module ByrefReturnMemberTests = F1() + module BaseCallByref = + + type Incrementor(z) = + abstract member Increment : int byref * int byref -> unit + default this.Increment(i : int byref,j : int byref) = + i <- i + z + + type Decrementor(z) = + inherit Incrementor(z) + override this.Increment(i, j) = + base.Increment(&i, &j) + + i <- i - z + + + module Bug820 = + + let inline f (x, r:byref<_>) = r <- x + let mutable x = Unchecked.defaultof<_> + f (0, &x) + + module Bug820b = + + type Bug820x() = + let f (x, r:byref<_>) = r <- x + let mutable x = Unchecked.defaultof<_> + member __.P = f (0, &x) + let aa = if !failures then (stdout.WriteLine "Test Failed"; exit 1) From 49b2280490a29efa17e43dd6d20e1e32cac98616 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 1 Jun 2018 02:26:29 +0100 Subject: [PATCH 46/61] update baseline --- tests/fsharp/typecheck/sigs/neg_byref_16.bsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/fsharp/typecheck/sigs/neg_byref_16.bsl b/tests/fsharp/typecheck/sigs/neg_byref_16.bsl index 91e5f4fe78..529156816d 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_16.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_16.bsl @@ -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 From a6e2b443c0994fa6122625fe7797a5a056b24a8a Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 1 Jun 2018 11:46:14 +0100 Subject: [PATCH 47/61] improve debug formatting, better error message on implicit deref, improve error messages --- src/fsharp/ConstraintSolver.fs | 5 +- src/fsharp/FSComp.txt | 1 + src/fsharp/MethodCalls.fs | 4 +- src/fsharp/NicePrint.fs | 17 +- src/fsharp/TastPickle.fs | 2 +- src/fsharp/TypeChecker.fs | 5 +- src/fsharp/tast.fs | 438 +++++++++++++++---- src/fsharp/xlf/FSComp.txt.cs.xlf | 5 + src/fsharp/xlf/FSComp.txt.de.xlf | 5 + src/fsharp/xlf/FSComp.txt.en.xlf | 5 + src/fsharp/xlf/FSComp.txt.es.xlf | 5 + src/fsharp/xlf/FSComp.txt.fr.xlf | 5 + src/fsharp/xlf/FSComp.txt.it.xlf | 5 + src/fsharp/xlf/FSComp.txt.ja.xlf | 5 + src/fsharp/xlf/FSComp.txt.ko.xlf | 5 + src/fsharp/xlf/FSComp.txt.pl.xlf | 5 + src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 5 + src/fsharp/xlf/FSComp.txt.ru.xlf | 5 + src/fsharp/xlf/FSComp.txt.tr.xlf | 5 + src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 5 + src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 5 + tests/fsharp/tests.fs | 5 +- tests/fsharp/typecheck/sigs/neg106.bsl | 38 +- tests/fsharp/typecheck/sigs/neg106.fs | 14 +- tests/fsharp/typecheck/sigs/neg106.vsbsl | 38 +- tests/fsharp/typecheck/sigs/neg_byref_17.bsl | 12 +- tests/fsharp/typecheck/sigs/neg_byref_22.bsl | 10 + 27 files changed, 510 insertions(+), 149 deletions(-) diff --git a/src/fsharp/ConstraintSolver.fs b/src/fsharp/ConstraintSolver.fs index fb69d04ed0..6bee3d6a8c 100644 --- a/src/fsharp/ConstraintSolver.fs +++ b/src/fsharp/ConstraintSolver.fs @@ -2469,7 +2469,10 @@ and ResolveOverloading | Some _ when calledMeth.Method.IsConstructor -> CompleteD | Some reqdRetTy -> let actualRetTy = calledMeth.CalledReturnTypeAfterOutArgTupling - MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy) + if isByrefTy g reqdRetTy then + ErrorD(Error(FSComp.SR.tcByrefReturnImplicitlyDereferenced(), m)) + else + MustUnify csenv ndeep trace cxsln reqdRetTy actualRetTy) | None -> None, errors diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 9c7e2516e5..1675c1702c 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1428,3 +1428,4 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 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)'." diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index 8def316cef..81d7942b9e 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -132,12 +132,10 @@ let AdjustCalledArgType (infoReader:InfoReader) isConstraint (calledArg: CalledA calledArgTy else - // If the called method argument is an inref type, then the caller may provide a byref or ref or value + // 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 - // elif isRefCellTy g callerArgTy (* || isTyparTy g callerArgTy -- for compat *) then - // mkRefCellTy g (destByrefTy g calledArgTy) else destByrefTy g calledArgTy diff --git a/src/fsharp/NicePrint.fs b/src/fsharp/NicePrint.fs index a8001e2833..a57a0178c1 100755 --- a/src/fsharp/NicePrint.fs +++ b/src/fsharp/NicePrint.fs @@ -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' as 'inref' + | 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' as 'outref' + | 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' as 'byref' + | 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 diff --git a/src/fsharp/TastPickle.fs b/src/fsharp/TastPickle.fs index c09cd1277d..77b8883a28 100755 --- a/src/fsharp/TastPickle.fs +++ b/src/fsharp/TastPickle.fs @@ -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 diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 59937bbf53..90ad09a120 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -8329,6 +8329,9 @@ and Propagate cenv overallTy env tpenv (expr: ApplicableExpr) exprty delayed = 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 @@ -9320,7 +9323,7 @@ and TcMethodApplicationThen and GetNewInferenceTypeForMethodArg cenv env tpenv x = match x with | SynExprParen(a, _, _, _) -> GetNewInferenceTypeForMethodArg cenv env tpenv a - | SynExpr.AddressOf(true, a, _, _) -> mkByrefTyWithInference cenv.g (GetNewInferenceTypeForMethodArg cenv env tpenv a) (NewInferenceType()) + | 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 diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index 7e29a3bc8c..6e5805ec03 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -8,6 +8,7 @@ module internal Microsoft.FSharp.Compiler.Tast open System open System.Collections.Generic +open System.Diagnostics open System.Reflection open Internal.Utilities open Microsoft.FSharp.Compiler.AbstractIL @@ -260,7 +261,7 @@ type ValFlags(flags:int64) = (flags &&& ~~~0b0011001100000000000L) /// Represents the kind of a type parameter -[] +[] type TyparKind = | Type @@ -272,6 +273,9 @@ type TyparKind = | TyparKind.Type -> None | TyparKind.Measure -> Some "Measure" + [] + member x.DebugText = x.ToString() + override x.ToString() = match x with | TyparKind.Type -> "type" @@ -540,6 +544,7 @@ type CompilationPath = +[] type EntityOptionalData = { /// The name of the type, possibly with `n mangling @@ -579,10 +584,13 @@ type EntityOptionalData = mutable entity_exn_info: ExceptionInfo } + [] + member x.DebugText = x.ToString() + override x.ToString() = "EntityOptionalData(...)" and /// Represents a type definition, exception definition, module definition or namespace definition. - [] + [] Entity = { /// The declared type parameters of the type // MUTABILITY; used only during creation and remapping of tycons @@ -1228,6 +1236,9 @@ and /// Represents a type definition, exception definition, module definition or /// Sets the structness of a record or union type definition member x.SetIsStructRecordOrUnion b = let flags = x.entity_flags in x.entity_flags <- EntityFlags(flags.IsPrefixDisplay, flags.IsModuleOrNamespace, flags.PreEstablishedHasDefaultConstructor, flags.HasSelfReferentialConstructor, b) + [] + member x.DebugText = x.ToString() + override x.ToString() = x.LogicalName and [] MaybeLazy<'T> = @@ -1251,7 +1262,7 @@ and ParentRef = | ParentNone and - [] + [] TyconAugmentation = { /// This is the value implementing the auto-generated comparison /// semantics if any. It is not present if the type defines its own implementation @@ -1321,10 +1332,13 @@ and tcaug_closed=false tcaug_abstract=false } + [] + member x.DebugText = x.ToString() + override x.ToString() = "TyconAugmentation(...)" and - [] + [] /// The information for the contents of a type. Also used for a provided namespace. TyconRepresentation = @@ -1368,20 +1382,26 @@ and /// The information for exception definitions should be folded into here. | TNoRepr + [] + member x.DebugText = x.ToString() + override x.ToString() = "TyconRepresentation(...)" and - [] + [] /// TILObjectReprData(scope, nesting, definition) TILObjectReprData = | TILObjectReprData of ILScopeRef * ILTypeDef list * ILTypeDef + [] + member x.DebugText = x.ToString() + override x.ToString() = "TILObjectReprData(...)" #if !NO_EXTENSIONTYPING and - [] + [] /// The information kept about a provided type TProvidedTypeInfo = @@ -1432,6 +1452,9 @@ and if info.IsErased then info.LazyBaseType.Force (m,objTy) else failwith "expect erased type" + [] + member x.DebugText = x.ToString() + override x.ToString() = "TProvidedTypeInfo(...)" #endif @@ -1459,7 +1482,7 @@ and | TTyconStruct | TTyconEnum -> true and - [] + [] TyconObjModelData = { /// Indicates whether the type declaration is a class, interface, enum, delegate or struct fsobjmodel_kind: TyconObjModelKind @@ -1470,10 +1493,13 @@ and /// The fields of the class, struct or enum fsobjmodel_rfields: TyconRecdFields } + [] + member x.DebugText = x.ToString() + override x.ToString() = "TyconObjModelData(...)" and - [] + [] TyconRecdFields = { /// The fields of the record, in declaration order. FieldsByIndex: RecdField[] @@ -1493,10 +1519,13 @@ and member x.TrueInstanceFieldsAsList = x.AllFieldsAsList |> List.filter (fun f -> not f.IsStatic && not f.IsCompilerGenerated) + [] + member x.DebugText = x.ToString() + override x.ToString() = "TyconRecdFields(...)" and - [] + [] TyconUnionCases = { /// The cases of the discriminated union, in declaration order. CasesByIndex: UnionCase[] @@ -1509,10 +1538,13 @@ and member x.UnionCasesAsList = x.CasesByIndex |> Array.toList + [] + member x.DebugText = x.ToString() + override x.ToString() = "TyconUnionCases(...)" and - [] + [] TyconUnionData = { /// The cases contained in the discriminated union. CasesTable: TyconUnionCases @@ -1522,11 +1554,13 @@ and member x.UnionCasesAsList = x.CasesTable.CasesByIndex |> Array.toList + [] + member x.DebugText = x.ToString() + override x.ToString() = "TyconUnionData(...)" and - [] - [] + [] UnionCase = { /// Data carried by the case. FieldTable: TyconRecdFields @@ -1580,12 +1614,15 @@ and member uc.IsNullary = (uc.FieldTable.FieldsByIndex.Length = 0) + [] + member x.DebugText = x.ToString() + override x.ToString() = "UnionCase(" + x.DisplayName + ")" and /// This may represent a "field" in either a struct, class, record or union /// It is normally compiled to a property. - [] + [] RecdField = { /// Is the field declared mutable in F#? rfield_mutable: bool @@ -1697,9 +1734,14 @@ and | Some Const.Zero -> true | _ -> false - override x.ToString() = "RecdField(" + x.Name + ")" + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.Name -and ExceptionInfo = +and + [] + ExceptionInfo = /// Indicates that an exception is an abbreviation for the given exception | TExnAbbrevRepr of TyconRef @@ -1712,9 +1754,13 @@ and ExceptionInfo = /// Indicates that an exception is abstract, i.e. is in a signature file, and we do not know the representation | TExnNone + [] + member x.DebugText = x.ToString() + override x.ToString() = "ExceptionInfo(...)" -and [] ModuleOrNamespaceType(kind: ModuleOrNamespaceKind, vals: QueueList, entities: QueueList) = +and [] + ModuleOrNamespaceType(kind: ModuleOrNamespaceKind, vals: QueueList, entities: QueueList) = /// Mutation used during compilation of FSharp.Core.dll let mutable entities = entities @@ -1880,6 +1926,9 @@ and [] ModuleOrNamespaceType(kind: ModuleOrNamespaceKind, vals: QueueLis cacheOptRef modulesByDemangledNameCache (fun () -> QueueList.foldBack add entities Map.empty) + [] + member x.DebugText = x.ToString() + override x.ToString() = "ModuleOrNamespaceType(...)" and ModuleOrNamespace = Entity @@ -2007,13 +2056,19 @@ and Construct = | XmlDoc [||], TAccess [] -> None | _ -> Some { Entity.EmptyEntityOptData with entity_xmldoc = xml; entity_tycon_repr_accessibility = access; entity_accessiblity = access } } -and Accessibility = +and + [] + Accessibility = /// Indicates the construct can only be accessed from any code in the given type constructor, module or assembly. [] indicates global scope. | TAccess of CompilationPath list + [] + member x.DebugText = x.ToString() + override x.ToString() = "Accessibility(...)" -and [] +and + [] TyparOptionalData = { /// MUTABILITY: we set the names of generalized inference type parameters to make the look nice for IL code generation @@ -2030,13 +2085,15 @@ and [] mutable typar_attribs: Attribs } + [] + member x.DebugText = x.ToString() + override __.ToString() = sprintf "TyparOptionalData(...)" and TyparData = Typar and - [] - [] + [] /// A declared generic type/measure parameter, or a type/measure inference variable. Typar = // Backing data for type parameters and type inference variables @@ -2217,10 +2274,13 @@ and /// Sets whether the comparison constraint of a type definition depends on this type variable member x.SetComparisonDependsOn b = let flags = x.typar_flags in x.typar_flags <- TyparFlags(flags.Kind, flags.Rigidity, flags.IsFromError, flags.IsCompilerGenerated, flags.StaticReq, flags.DynamicReq, flags.EqualityConditionalOn, b) + [] + member x.DebugText = x.ToString() + override x.ToString() = x.Name and - [] + [] TyparConstraint = /// Indicates a constraint that a type is a subtype of the given type | CoercesTo of TType * range @@ -2263,11 +2323,15 @@ and /// Indicates a constraint that a type is .NET unmanaged type | IsUnmanaged of range - override x.ToString() = "TyparConstraint(...)" + // Prefer the default formatting of this union type + //[] + //member x.DebugText = x.ToString() + // + //override x.ToString() = "TyparConstraint(...)" /// The specification of a member constraint that must be solved and - [] + [] TraitConstraintInfo = /// TTrait(tys,nm,memFlags,argtys,rty,colution) @@ -2287,10 +2351,13 @@ and with get() = (let (TTrait(_,_,_,_,_,sln)) = x in sln.Value) and set v = (let (TTrait(_,_,_,_,_,sln)) = x in sln.Value <- v) + [] + member x.DebugText = x.ToString() + override x.ToString() = "TTrait(" + x.MemberName + ")" and - [] + [] /// Indicates the solution of a member constraint during inference. TraitConstraintSln = @@ -2327,10 +2394,13 @@ and /// Indicates a trait is solved by a 'fake' instance of an operator, like '+' on integers | BuiltInSln + [] + member x.DebugText = x.ToString() + override x.ToString() = "TraitConstraintSln(...)" /// The partial information used to index the methods of all those in a ModuleOrNamespace. -and [] +and [] ValLinkagePartialKey = { /// The name of the type with which the member is associated. None for non-member values. MemberParentMangledName : string option @@ -2344,11 +2414,16 @@ and [] /// Indicates the total argument count of the member. TotalArgCount: int } + [] + member x.DebugText = x.ToString() + override x.ToString() = "ValLinkagePartialKey(" + x.LogicalName + ")" /// The full information used to identify a specific overloaded method /// amongst all those in a ModuleOrNamespace. -and ValLinkageFullKey(partialKey: ValLinkagePartialKey, typeForLinkage:TType option) = +and + [< (* NoEquality; NoComparison; *) StructuredFormatDisplay("{DebugText}")>] + ValLinkageFullKey(partialKey: ValLinkagePartialKey, typeForLinkage:TType option) = /// The partial information used to index the value in a ModuleOrNamespace. member x.PartialKey = partialKey @@ -2356,9 +2431,14 @@ and ValLinkageFullKey(partialKey: ValLinkagePartialKey, typeForLinkage:TType op /// The full type of the value for the purposes of linking. May be None for non-members, since they can't be overloaded. member x.TypeForLinkage = typeForLinkage + [] + member x.DebugText = x.ToString() + override x.ToString() = "ValLinkageFullKey(" + partialKey.LogicalName + ")" -and ValOptionalData = +and + [] + ValOptionalData = { /// MUTABILITY: for unpickle linkage mutable val_compiled_name: string option @@ -2409,10 +2489,13 @@ and ValOptionalData = mutable val_attribs: Attribs } + [] + member x.DebugText = x.ToString() + override x.ToString() = "ValOptionalData(...)" and ValData = Val -and [] +and [] Val = { /// Mutable for unpickle linkage @@ -2688,7 +2771,7 @@ and [] // We use it here: // - in opt.fs : when compiling fslib, we bind an entry for the value in a global table (see bind_escaping_local_vspec) // - in ilxgen.fs: when compiling fslib, we bind an entry for the value in a global table (see bind_escaping_local_vspec) - // - in opt.fs : (fullDisplayTextOfValRef) for error reporting of non-inlinable values + // - in opt.fs : (fullDebugTextOfValRef) for error reporting of non-inlinable values // - in service.fs (boutput_item_description): to display the full text of a value's binding location // - in check.fs: as a boolean to detect public values for saving quotations // - in ilxgen.fs: as a boolean to detect public values for saving quotations @@ -2875,12 +2958,15 @@ and [] /// Indicates if a value is linked to backing data yet. Only used during unpickling of F# metadata. member x.IsLinked = match box x.val_logical_name with null -> false | _ -> true + [] + member x.DebugText = x.ToString() + override x.ToString() = x.LogicalName and /// Represents the extra information stored for a member - [] + [] ValMemberInfo = { /// The parent type. For an extension member this is the type being extended ApparentEnclosingEntity: TyconRef @@ -2893,10 +2979,13 @@ and MemberFlags: MemberFlags } + [] + member x.DebugText = x.ToString() + override x.ToString() = "ValMemberInfo(...)" and - [] + [] NonLocalValOrMemberRef = { /// A reference to the entity containing the value or member. This will always be a non-local reference EnclosingEntity : EntityRef @@ -2911,18 +3000,26 @@ and member x.AssemblyName = x.EnclosingEntity.nlr.AssemblyName /// For debugging - member x.Display = x.ToString() + [] + member x.DebugText = x.ToString() /// For debugging override x.ToString() = x.EnclosingEntity.nlr.ToString() + "::" + x.ItemKey.PartialKey.LogicalName -and ValPublicPath = +and + [] + ValPublicPath = | ValPubPath of PublicPath * ValLinkageFullKey + [] + member x.DebugText = x.ToString() + override __.ToString() = sprintf "ValPubPath(...)" /// Index into the namespace/module structure of a particular CCU -and NonLocalEntityRef = +and + [] + NonLocalEntityRef = | NonLocalEntityRef of CcuThunk * string[] /// Try to find the entity corresponding to the given path in the given CCU @@ -3090,11 +3187,13 @@ and NonLocalEntityRef = member nleref.ModuleOrNamespaceType = nleref.Deref.ModuleOrNamespaceType + [] + member x.DebugText = x.ToString() + override x.ToString() = x.DisplayName and - [] - [] + [] EntityRef = { /// Indicates a reference to something bound in this CCU mutable binding: NonNullSlot @@ -3144,12 +3243,6 @@ and /// Is the destination assembly available? member tcr.CanDeref = tcr.TryDeref.IsSome - override x.ToString() = - if x.IsLocalRef then - x.ResolvedTarget.DisplayName - else - x.nlr.DisplayName - /// Gets the data indicating the compiled representation of a type or module in terms of Abstract IL data structures. member x.CompiledRepresentation = x.Deref.CompiledRepresentation @@ -3442,6 +3535,15 @@ and member x.MakeNestedUnionCaseRef (uc: UnionCase) = UCRef (x, uc.Id.idText) + [] + member x.DebugText = x.ToString() + + override x.ToString() = + if x.IsLocalRef then + x.ResolvedTarget.DisplayName + else + x.nlr.DisplayName + /// note: ModuleOrNamespaceRef and TyconRef are type equivalent and ModuleOrNamespaceRef = EntityRef @@ -3450,8 +3552,7 @@ and TyconRef = EntityRef /// References are either local or nonlocal and - [] - [] + [] ValRef = { /// Indicates a reference to something bound in this CCU mutable binding: NonNullSlot @@ -3662,12 +3763,17 @@ and /// Get the number of 'this'/'self' object arguments for the member. Instance extension members return '1'. member x.NumObjArgs = x.Deref.NumObjArgs + [] + member x.DebugText = x.ToString() + override x.ToString() = if x.IsLocalRef then x.ResolvedTarget.DisplayName else x.nlr.ToString() /// Represents a reference to a case of a union type -and UnionCaseRef = +and + [] + UnionCaseRef = | UCRef of TyconRef * string /// Get a reference to the type containing this union case @@ -3717,10 +3823,15 @@ and UnionCaseRef = /// Get a field of the union case by index member x.FieldByIndex n = x.UnionCase.FieldTable.FieldByIndex n - override x.ToString() = sprintf "UnionCase(%s)" x.CaseName + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.CaseName /// Represents a reference to a field in a record, class or struct -and RecdFieldRef = +and + [] + RecdFieldRef = | RFRef of TyconRef * string /// Get a reference to the type containing this union case @@ -3762,11 +3873,14 @@ and RecdFieldRef = with :? KeyNotFoundException -> error(InternalError(sprintf "field %s not found in type %s" id tcref.LogicalName, tcref.Range)) - override x.ToString() = sprintf "RecdField(%s)" x.FieldName + [] + member x.DebugText = x.ToString() + + override x.ToString() = x.FieldName and /// The algebra of types - [] + [] TType = /// TType_forall(typars, bodyTy). @@ -3816,9 +3930,12 @@ and let (TILObjectReprData(scope,_nesting,_definition)) = _uc.Tycon.ILTyconInfo scope.QualifiedName + [] + member x.DebugText = x.ToString() + override x.ToString() = match x with - | TType_forall (_tps,ty) -> "forall _. " + ty.ToString() + | TType_forall (_tps,ty) -> "forall ... " + ty.ToString() | TType_app (tcref, tinst) -> tcref.DisplayName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") | TType_tuple (tupInfo, tinst) -> (match tupInfo with @@ -3826,12 +3943,12 @@ and | TupInfo.Const true -> "struct ") + String.concat "," (List.map string tinst) + ")" | TType_fun (d,r) -> "(" + string d + " -> " + string r + ")" - | TType_ucase (uc,tinst) -> "union case type " + uc.CaseName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") + | TType_ucase (uc,tinst) -> "ucase " + uc.CaseName + (match tinst with [] -> "" | tys -> "<" + String.concat "," (List.map string tys) + ">") | TType_var tp -> match tp.Solution with | None -> tp.DisplayName | Some _ -> tp.DisplayName + " (solved, see Solution property)" - | TType_measure ms -> sprintf "%A" ms + | TType_measure ms -> ms.ToString() and TypeInst = TType list @@ -3841,7 +3958,9 @@ and [] TupInfo = /// Some constant, e.g. true or false for tupInfo | Const of bool -and [] Measure = +and + [] + Measure = /// A variable unit-of-measure | Var of Typar @@ -3860,10 +3979,14 @@ and [] Measure = /// Raising a measure to a rational power | RationalPower of Measure * Rational - override x.ToString() = "Measure(...)" + // Prefer the default formatting of this union type + //[] + //member x.DebugText = x.ToString() + // + //override x.ToString() = "Measure(...)" and - [] + [] CcuData = { /// Holds the filename for the DLL, if any FileName: string option @@ -3913,6 +4036,9 @@ and /// The table of .NET CLI type forwarders for this assembly TypeForwarders : CcuTypeForwarderTable } + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "CcuData(%A)" x.FileName /// Represents a table of .NET CLI type forwarders for an assembly @@ -3939,7 +4065,9 @@ and CcuReference = string // ILAssemblyRef /// by ccu-thunks. Ultimately, a ccu-thunk is either a (named) element of /// the data structure, or it is a delayed fixup, i.e. an invalid dangling /// reference that has not had an appropriate fixup applied. -and CcuThunk = +and + [] + CcuThunk = { mutable target: CcuData /// ccu.orphanfixup is true when a reference is missing in the transitive closure of static references that @@ -4060,25 +4188,38 @@ and CcuThunk = member ccu.MemberSignatureEquality(ty1:TType, ty2:TType) = ccu.Deref.MemberSignatureEquality ty1 ty2 + [] + member x.DebugText = x.ToString() + override ccu.ToString() = ccu.AssemblyName /// The result of attempting to resolve an assembly name to a full ccu. /// UnresolvedCcu will contain the name of the assembly that could not be resolved. -and CcuResolutionResult = +and + [] + CcuResolutionResult = | ResolvedCcu of CcuThunk | UnresolvedCcu of string - override __.ToString() = "CcuResolutionResult(...)" + [] + member x.DebugText = x.ToString() + + override x.ToString() = match x with ResolvedCcu ccu -> ccu.ToString() | UnresolvedCcu s -> "unresolved " + s /// Represents the information saved in the assembly signature data resource for an F# assembly -and PickledCcuInfo = - { mspec: ModuleOrNamespace +and + [] + PickledCcuInfo = + { mspec: ModuleOrNamespace + + compileTimeWorkingDir: string - compileTimeWorkingDir: string + usesQuotations : bool } - usesQuotations : bool } + [] + member x.DebugText = x.ToString() override __.ToString() = "PickledCcuInfo(...)" @@ -4090,7 +4231,9 @@ and PickledCcuInfo = and Attribs = Attrib list -and AttribKind = +and + [] + AttribKind = /// Indicates an attribute refers to a type defined in an imported .NET assembly | ILAttrib of ILMethodRef @@ -4098,27 +4241,47 @@ and AttribKind = /// Indicates an attribute refers to a type defined in an imported F# assembly | FSAttrib of ValRef + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "AttribKind(...)" /// Attrib(kind,unnamedArgs,propVal,appliedToAGetterOrSetter,targetsOpt,range) -and Attrib = +and + [] + Attrib = | Attrib of TyconRef * AttribKind * AttribExpr list * AttribNamedArg list * bool * AttributeTargets option * range - override x.ToString() = sprintf "Attrib(...)" + [] + member x.DebugText = x.ToString() + + member x.TyconRef = (let (Attrib(tcref, _, _, _, _, _, _)) = x in tcref) + + override x.ToString() = "attrib" + x.TyconRef.ToString() /// We keep both source expression and evaluated expression around to help intellisense and signature printing -and AttribExpr = +and + [] + AttribExpr = /// AttribExpr(source, evaluated) | AttribExpr of Expr * Expr + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "AttribExpr(...)" /// AttribNamedArg(name,type,isField,value) -and AttribNamedArg = +and + [] + AttribNamedArg = | AttribNamedArg of (string*TType*bool*AttribExpr) + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "AttribNamedArg(...)" /// Constants in expressions @@ -4148,7 +4311,7 @@ and [] /// the decision tree are labelled by integers that are unique for that /// particular tree. and - [] + [] DecisionTree = /// TDSwitch(input, cases, default, range) @@ -4177,10 +4340,15 @@ and /// body -- the rest of the decision tree | TDBind of Binding * DecisionTree + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "DecisionTree(...)" /// Represents a test and a subsequent decision tree -and DecisionTreeCase = +and + [] + DecisionTreeCase = | TCase of DecisionTreeTest * DecisionTree /// Get the discriminator associated with the case @@ -4189,10 +4357,13 @@ and DecisionTreeCase = /// Get the decision tree or a successful test member x.CaseTree = let (TCase(_,d)) = x in d + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "DecisionTreeCase(...)" and - [] + [] DecisionTreeTest = /// Test if the input to a decision tree matches the given union case | UnionCase of UnionCaseRef * TypeInst @@ -4222,19 +4393,29 @@ and /// activePatternInfo -- The extracted info for the active pattern. | ActivePatternCase of Expr * TTypes * (ValRef * TypeInst) option * int * ActivePatternInfo + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "DecisionTreeTest(...)" /// A target of a decision tree. Can be thought of as a little function, though is compiled as a local block. -and DecisionTreeTarget = +and + [] + DecisionTreeTarget = | TTarget of Vals * Expr * SequencePointInfoForTarget + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "DecisionTreeTarget(...)" /// A collection of simultaneous bindings and Bindings = Binding list /// A binding of a variable to an expression, as in a `let` binding or similar -and Binding = +and + [] + Binding = | TBind of Val * Expr * SequencePointInfoForBinding /// The value being bound @@ -4246,11 +4427,16 @@ and Binding = /// The information about whether to emit a sequence point for the binding member x.SequencePointInfo = (let (TBind(_,_,sp)) = x in sp) + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "TBind(%s, ...)" x.Var.CompiledName /// Represents a reference to an active pattern element. The /// integer indicates which choice in the target set is being selected by this item. -and ActivePatternElemRef = +and + [] + ActivePatternElemRef = | APElemRef of ActivePatternInfo * ValRef * int /// Get the full information about the active pattern being referred to @@ -4262,11 +4448,16 @@ and ActivePatternElemRef = /// Get the index of the active pattern element within the overall active pattern member x.CaseIndex = (let (APElemRef(_,_,n)) = x in n) + [] + member x.DebugText = x.ToString() + override __.ToString() = "ActivePatternElemRef(...)" /// Records the "extra information" for a value compiled as a method (rather /// than a closure or a local), including argument names, attributes etc. -and ValReprInfo = +and + [] + ValReprInfo = /// ValReprInfo (numTypars, args, result) | ValReprInfo of TyparReprInfo list * ArgReprInfo list list * ArgReprInfo @@ -4301,12 +4492,15 @@ and ValReprInfo = | (_::_::h)::t -> loop t (acc + h.Length + 2) loop args 0 + [] + member x.DebugText = x.ToString() + override __.ToString() = "ValReprInfo(...)" /// Records the "extra information" for an argument compiled as a real /// method argument, specifically the argument name and attributes. and - [] + [] ArgReprInfo = { // MUTABILITY: used when propagating signature attributes into the implementation. @@ -4315,6 +4509,9 @@ and // MUTABILITY: used when propagating names of parameters from signature into the implementation. mutable Name : Ident option } + [] + member x.DebugText = x.ToString() + override __.ToString() = "ArgReprInfo(...)" /// Records the extra metadata stored about typars for type parameters @@ -4331,7 +4528,7 @@ and Vals = Val list /// The big type of expressions. and - [] + [] Expr = /// A constant expression. | Const of Const * range * TType @@ -4411,10 +4608,14 @@ and /// appropriate type instantiation. These are immediately eliminated on subsequent rewrites. | Link of Expr ref - override __.ToString() = "Expr(...)" + // Prefer to use the default formatting of this union type + //[] + //member x.DebugText = x.ToString() + // + //override __.ToString() = "Expr(...)" and - [] + [] TOp = /// An operation representing the creation of a union value of the particular union case @@ -4525,7 +4726,11 @@ and /// retTy -- the types of pushed values, if any | ILCall of bool * bool * bool * bool * ValUseFlag * bool * bool * ILMethodRef * TypeInst * TypeInst * TTypes - override __.ToString() = "TOp(...)" + // Prefer to use the default formatting of this union type + //[] + //member x.DebugText = x.ToString() + // + //override __.ToString() = "TOp(...)" /// Indicates the kind of record construction operation. and RecordConstructionInfo = @@ -4611,18 +4816,25 @@ and StaticOptimization = /// A representation of a method in an object expression. /// /// TObjExprMethod(slotsig,attribs,methTyparsOfOverridingMethod,methodParams,methodBodyExpr,m) -and ObjExprMethod = +and + [] + ObjExprMethod = | TObjExprMethod of SlotSig * Attribs * Typars * Val list list * Expr * range member x.Id = let (TObjExprMethod(slotsig,_,_,_,_,m)) = x in mkSynId m slotsig.Name + [] + member x.DebugText = x.ToString() + override x.ToString() = sprintf "TObjExprMethod(%s, ...)" x.Id.idText /// Represents an abstract method slot, or delegate signature. /// /// TSlotSig(methodName,declaringType,declaringTypeParameters,methodTypeParameters,slotParameters,returnTy) -and SlotSig = +and + [] + SlotSig = | TSlotSig of string * TType * Typars * Typars * SlotParam list list * TType option @@ -4638,22 +4850,32 @@ and SlotSig = member ss.FormalReturnType = let (TSlotSig(_,_,_,_,_,rt)) = ss in rt + [] + member x.DebugText = x.ToString() + override ss.ToString() = sprintf "TSlotSig(%s, ...)" ss.Name /// Represents a parameter to an abstract method slot. /// /// TSlotParam(nm,ty,inFlag,outFlag,optionalFlag,attribs) -and SlotParam = +and + [] + SlotParam = | TSlotParam of string option * TType * bool (* in *) * bool (* out *) * bool (* optional *) * Attribs member x.Type = let (TSlotParam(_,ty,_,_,_,_)) = x in ty + [] + member x.DebugText = x.ToString() + override x.ToString() = "TSlotParam(...)" /// A type for a module-or-namespace-fragment and the actual definition of the module-or-namespace-fragment /// The first ModuleOrNamespaceType is the signature and is a binder. However the bindings are not used in the ModuleOrNamespaceExpr: it is only referenced from the 'outside' /// is for use by FCS only to report the "hidden" contents of the assembly prior to applying the signature. -and ModuleOrNamespaceExprWithSig = +and + [] + ModuleOrNamespaceExprWithSig = | ModuleOrNamespaceExprWithSig of ModuleOrNamespaceType * ModuleOrNamespaceExpr @@ -4661,10 +4883,15 @@ and ModuleOrNamespaceExprWithSig = member x.Type = let (ModuleOrNamespaceExprWithSig(mtyp,_,_)) = x in mtyp + [] + member x.DebugText = x.ToString() + override x.ToString() = "ModuleOrNamespaceExprWithSig(...)" /// The contents of a module-or-namespace-fragment definition -and ModuleOrNamespaceExpr = +and + [] + ModuleOrNamespaceExpr = /// Indicates the module is a module with a signature | TMAbstract of ModuleOrNamespaceExprWithSig @@ -4680,10 +4907,14 @@ and ModuleOrNamespaceExpr = /// Indicates the module fragment is a 'rec' or 'non-rec' definition of types and modules | TMDefRec of isRec:bool * Tycon list * ModuleOrNamespaceBinding list * range + [] + member x.DebugText = x.ToString() + override x.ToString() = "ModuleOrNamespaceExpr(...)" /// A named module-or-namespace-fragment definition -and [] +and + [] ModuleOrNamespaceBinding = | Binding of Binding @@ -4695,21 +4926,34 @@ and [] /// This is the body of the module/namespace ModuleOrNamespaceExpr + [] + member x.DebugText = x.ToString() + override __.ToString() = "ModuleOrNamespaceBinding(...)" /// Represents a complete typechecked implementation file, including its typechecked signature if any. /// /// TImplFile(qualifiedNameOfFile,pragmas,implementationExpressionWithSignature,hasExplicitEntryPoint,isScript) -and TypedImplFile = +and + [] + TypedImplFile = | TImplFile of QualifiedNameOfFile * ScopedPragma list * ModuleOrNamespaceExprWithSig * bool * bool + [] + member x.DebugText = x.ToString() + override x.ToString() = "TImplFile(...)" /// Represents a complete typechecked assembly, made up of multiple implementation files. /// -and TypedAssemblyAfterOptimization = +and + [] + TypedAssemblyAfterOptimization = | TypedAssemblyAfterOptimization of (TypedImplFile * (* optimizeDuringCodeGen: *) (Expr -> Expr)) list + [] + member x.DebugText = x.ToString() + override x.ToString() = "TypedAssemblyAfterOptimization(...)" //--------------------------------------------------------------------------- @@ -4735,7 +4979,9 @@ and FreeUnionCases = Zset /// Represents a set of 'free' type-related elements, including named types, trait solutions, union cases and /// record fields. -and FreeTyvars = +and + [] + FreeTyvars = { /// The summary of locally defined type definitions used in the expression. These may be made private by a signature /// and we have to check various conditions associated with that. FreeTycons: FreeTycons @@ -4747,13 +4993,18 @@ and FreeTyvars = /// and we have to check various conditions associated with that. FreeTypars: FreeTypars } + [] + member x.DebugText = x.ToString() + override x.ToString() = "FreeTyvars(...)" /// Represents an amortized computation of the free variables in an expression and FreeVarsCache = FreeVars cache /// Represents the set of free variables in an expression -and FreeVars = +and + [] + FreeVars = { /// The summary of locally defined variables used in the expression. These may be hidden at let bindings etc. /// or made private by a signature or marked 'internal' or 'private', and we have to check various conditions associated with that. FreeLocals: FreeLocals @@ -4781,13 +5032,17 @@ and FreeVars = /// See FreeTyvars above. FreeTyvars: FreeTyvars } + [] + member x.DebugText = x.ToString() + override x.ToString() = "FreeVars(...)" /// Specifies the compiled representations of type and exception definitions. Basically /// just an ILTypeRef. Computed and cached by later phases. Stored in /// type and exception definitions. Not pickled. Store an optional ILType object for /// non-generic types. -and [] +and + [] CompiledTypeRepr = /// An AbstractIL type representation that is just the name of a type. @@ -4811,6 +5066,9 @@ and [] // type ilsigptr<'T> = (# "!0*" #) | ILAsmOpen of ILType + [] + member x.DebugText = x.ToString() + override x.ToString() = "CompiledTypeRepr(...)" //--------------------------------------------------------------------------- diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index d9f63b83e6..27c5da3682 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index 1c1f64ca16..6ce373f9e9 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.en.xlf b/src/fsharp/xlf/FSComp.txt.en.xlf index 840cffb403..24290de3d6 100644 --- a/src/fsharp/xlf/FSComp.txt.en.xlf +++ b/src/fsharp/xlf/FSComp.txt.en.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index b331d74d5b..8941c33f9a 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index 41f135d8bf..f90da76524 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 7725909224..f2069bf118 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 259120e659..190f2e6a72 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index 22ddafc452..92d0de171d 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index d06eec8dad..aef65bae42 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index 765d301026..b357f6e988 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 258f0c625e..22cdcaf9e2 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 9ec4b15054..d47ab9dad6 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index b12cedf774..f01b5cd0d2 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index bf02055daf..04929cd133 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -7002,6 +7002,11 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + 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)'. + + \ No newline at end of file diff --git a/tests/fsharp/tests.fs b/tests/fsharp/tests.fs index 088979c432..c475280e2e 100644 --- a/tests/fsharp/tests.fs +++ b/tests/fsharp/tests.fs @@ -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 diff --git a/tests/fsharp/typecheck/sigs/neg106.bsl b/tests/fsharp/typecheck/sigs/neg106.bsl index 25196d19b4..3eba5fcba5 100644 --- a/tests/fsharp/typecheck/sigs/neg106.bsl +++ b/tests/fsharp/typecheck/sigs/neg106.bsl @@ -1,93 +1,93 @@ neg106.fs(8,14,8,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,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 - 'byref' + 'inref' is not compatible with type 'byref<'a>' . neg106.fs(11,14,11,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,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 - 'byref' + 'inref' is not compatible with type 'byref<'a>' . neg106.fs(16,31,16,35): typecheck error FS0001: Type mismatch. Expecting a - 'byref' + 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' neg106.fs(22,18,22,22): typecheck error FS0001: Type mismatch. Expecting a - 'byref' + 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' neg106.fs(29,14,29,28): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . @@ -104,13 +104,13 @@ is not compatible with type 'string' . neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(36,18,36,22): typecheck error FS0001: Type mismatch. Expecting a - 'byref' + 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' diff --git a/tests/fsharp/typecheck/sigs/neg106.fs b/tests/fsharp/typecheck/sigs/neg106.fs index b08941b026..cf1357ca2d 100644 --- a/tests/fsharp/typecheck/sigs/neg106.fs +++ b/tests/fsharp/typecheck/sigs/neg106.fs @@ -5,35 +5,35 @@ module M module CompareExchangeTests_Negative1 = let x = 3 - let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) // No overloads match for method 'CompareExchange'. 'byref' is not compatible with type 'byref' + let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) // No overloads match for method 'CompareExchange'. 'inref' is not compatible with type 'byref' module CompareExchangeTests_Negative2 = - let v = System.Threading.Interlocked.CompareExchange(&3, 3, 4) // 'byref' is not compatible with type 'byref' + let v = System.Threading.Interlocked.CompareExchange(&3, 3, 4) // 'inref' is not compatible with type 'byref' module TryGetValueTests_Negative1 = let d = dict [ (3,4) ] let res = 9 - let v = d.TryGetValue(3, &res) // 'byref' is not compatible with type 'byref' + let v = d.TryGetValue(3, &res) // 'inref' is not compatible with type 'byref' module FSharpDeclaredOutParamTest_Negaative1 = type C() = static member M([] x: byref) = () let res = 9 - let v = C.M(&res) //'byref' is not compatible with type 'byref' + let v = C.M(&res) //'inref' is not compatible with type 'byref' module FSharpDeclaredOverloadedOutParamTest_Negative1 = type C() = static member M(a: int, [] x: byref) = x <- 7 static member M(a: string, [] x: byref) = x <- 8 let res = 9 - let v = C.M("a", &res) //'byref' is not compatible with type 'byref' - let v2 = C.M(3, &res) //'byref' is not compatible with type 'byref' + let v = C.M("a", &res) //'inref' is not compatible with type 'byref' + let v2 = C.M(3, &res) //'inref' is not compatible with type 'byref' module FSharpDeclaredOutParamTest_Negative1 = type C() = static member M([] x: byref) = () let res = 9 - let v = C.M(&res) // 'byref' is not compatible with type 'byref' + let v = C.M(&res) // 'inref' is not compatible with type 'byref' module TestOneArgumentInRefThenMutate_Negative1 = diff --git a/tests/fsharp/typecheck/sigs/neg106.vsbsl b/tests/fsharp/typecheck/sigs/neg106.vsbsl index 25196d19b4..3eba5fcba5 100644 --- a/tests/fsharp/typecheck/sigs/neg106.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg106.vsbsl @@ -1,93 +1,93 @@ neg106.fs(8,14,8,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(8,14,8,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 - 'byref' + 'inref' is not compatible with type 'byref<'a>' . neg106.fs(11,14,11,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(11,14,11,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 - 'byref' + 'inref' is not compatible with type 'byref<'a>' . neg106.fs(16,31,16,35): typecheck error FS0001: Type mismatch. Expecting a - 'byref' + 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' neg106.fs(22,18,22,22): typecheck error FS0001: Type mismatch. Expecting a - 'byref' + 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' neg106.fs(29,14,29,28): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . @@ -104,13 +104,13 @@ is not compatible with type 'string' . neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type - 'byref' + 'inref' is not compatible with type 'byref' . neg106.fs(36,18,36,22): typecheck error FS0001: Type mismatch. Expecting a - 'byref' + 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' diff --git a/tests/fsharp/typecheck/sigs/neg_byref_17.bsl b/tests/fsharp/typecheck/sigs/neg_byref_17.bsl index 3d857907b8..270d06fbfc 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_17.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_17.bsl @@ -1,6 +1,10 @@ -neg_byref_17.fs(2,5,2,8): typecheck error FS0431: A byref typed value would be stored here. Top-level let-bound byref values are not permitted. +neg_byref_17.fs(2,17,2,27): typecheck error FS0001: This expression was expected to have type + 'byref' +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' +but here has type + 'int' diff --git a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl index 675eefac32..da7df92104 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl @@ -1,4 +1,14 @@ +neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected to have type + 'byref' +but here has type + 'int' + +neg_byref_22.fs(3,16,3,20): typecheck error FS0001: This expression was expected to have type + 'byref' +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 From 74809bb5b33680ab1a1d64b724754ad2fbfd0032 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 1 Jun 2018 13:15:35 +0100 Subject: [PATCH 48/61] add more tests for recursive functions --- src/absil/il.fs | 80 ++++++++++++++++++--- src/fsharp/TastOps.fs | 7 ++ src/fsharp/TastOps.fsi | 25 ++++++- src/fsharp/TcGlobals.fs | 34 +++++++-- src/fsharp/TypeChecker.fs | 41 ++++++----- src/fsharp/tast.fs | 2 +- tests/fsharp/core/byrefs/test.fsx | 116 ++++++++++++++++++++++++++++++ 7 files changed, 271 insertions(+), 34 deletions(-) diff --git a/src/absil/il.fs b/src/absil/il.fs index 2d8dbc23d5..4e047481aa 100644 --- a/src/absil/il.fs +++ b/src/absil/il.fs @@ -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. -[] +[] type ILTypeRef = { trefScope: ILScopeRef trefEnclosing: string list @@ -637,11 +638,15 @@ type ILTypeRef = member tref.QualifiedName = tref.AddQualifiedNameExtension(tref.BasicQualifiedName) + /// For debugging + [] + member x.DebugText = x.ToString() + + /// For debugging override x.ToString() = x.FullName -and - [] +and [] ILTypeSpec = { tspecTypeRef: ILTypeRef /// The type instantiation if the type is generic. @@ -671,9 +676,13 @@ and member x.FullName=x.TypeRef.FullName + /// For debugging + [] + member x.DebugText = x.ToString() + override x.ToString() = x.TypeRef.ToString() + if isNil x.GenericArgs then "" else "<...>" -and [] +and [] ILType = | Void | Array of ILArrayShape * ILType @@ -740,6 +749,10 @@ and [] match x with | ILType.TypeVar _ -> true | _ -> false + /// For debugging + [] + member x.DebugText = x.ToString() + override x.ToString() = x.QualifiedName and [] @@ -756,6 +769,7 @@ let mkILCallSig (cc, args, ret) = { ArgTypes=args; CallingConv=cc; ReturnType=re let mkILBoxedType (tspec:ILTypeSpec) = tspec.TypeRef.AsBoxedType tspec +[] 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 + [] + member x.DebugText = x.ToString() + override x.ToString() = x.DeclaringTypeRef.ToString() + "::" + x.Name + "(...)" -[] +[] type ILFieldRef = { DeclaringTypeRef: ILTypeRef Name: string Type: ILType } + /// For debugging + [] + member x.DebugText = x.ToString() + override x.ToString() = x.DeclaringTypeRef.ToString() + "::" + x.Name -[] +[] type ILMethodSpec = { mspecMethodRef: ILMethodRef @@ -802,7 +824,7 @@ type ILMethodSpec = mspecMethodInst: ILGenericArgs } - static member Create(a, b, c) = { mspecDeclaringType=a; mspecMethodRef =b; mspecMethodInst=c } + static member Create(a, b, c) = { mspecDeclaringType=a; mspecMethodRef=b; mspecMethodInst=c } member x.MethodRef = x.mspecMethodRef @@ -820,8 +842,13 @@ type ILMethodSpec = member x.FormalReturnType = x.MethodRef.ReturnType + /// For debugging + [] + member x.DebugText = x.ToString() + override x.ToString() = x.MethodRef.ToString() + "(...)" +[] type ILFieldSpec = { FieldRef: ILFieldRef DeclaringType: ILType } @@ -832,6 +859,10 @@ type ILFieldSpec = member x.DeclaringTypeRef = x.FieldRef.DeclaringTypeRef + /// For debugging + [] + member x.DebugText = x.ToString() + override x.ToString() = x.FieldRef.ToString() // -------------------------------------------------------------------- @@ -865,6 +896,7 @@ type ILSourceDocument = member x.File=x.sourceFile +[] type ILSourceMarker = { sourceDocument: ILSourceDocument sourceLine: int @@ -889,6 +921,10 @@ type ILSourceMarker = member x.EndColumn=x.sourceEndColumn + /// For debugging + [] + 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) +[] type ILAttribute = { Method: ILMethodSpec Data: byte[] Elements: ILAttribElem list } + /// For debugging + [] + member x.DebugText = x.ToString() + override x.ToString() = x.Method.ToString() + "(...)" [] @@ -1477,6 +1518,7 @@ type ILGenericVariance = | CoVariant | ContraVariant +[] type ILGenericParameterDef = { Name: string Constraints: ILTypes @@ -1489,6 +1531,10 @@ type ILGenericParameterDef = member x.CustomAttrs = x.CustomAttrsStored.GetCustomAttrs x.MetadataIndex + /// For debugging + [] + member x.DebugText = x.ToString() + override x.ToString() = x.Name type ILGenericParameterDefs = ILGenericParameterDef list @@ -1667,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) -[] +[] 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) = @@ -1697,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 + [] + member x.DebugText = x.ToString() + override x.ToString() = "event " + x.Name [] @@ -1707,7 +1757,7 @@ type ILEventDefs = member x.LookupByName s = let (ILEvents t) = x in t.[s] -[] +[] 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) = @@ -1739,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 + [] + member x.DebugText = x.ToString() + override x.ToString() = "property " + x.Name // Index table by name. @@ -2471,7 +2526,7 @@ let tname_IntPtr = "System.IntPtr" [] let tname_UIntPtr = "System.UIntPtr" -[] +[] // This data structure needs an entirely delayed implementation type ILGlobals(primaryScopeRef) = @@ -2516,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 + [] + member x.DebugText = x.ToString() + override x.ToString() = "" let mkILGlobals primaryScopeRef = ILGlobals primaryScopeRef diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 8cadda0df1..ca39c68230 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -1357,14 +1357,21 @@ type ValHash<'T> = [] 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) [] diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index 7c521bbc8a..6c213690b3 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -299,41 +299,64 @@ type ValHash<'T> = /// Maps Val's to list of T based on stamp keys [] 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> [] /// 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> [] /// 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 [] 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> + static member OfList : (TyconRef * 'T) list -> TyconRefMultiMap<'T> //------------------------------------------------------------------------- // Orderings on Tycon, Val, RecdFieldRef, Typar diff --git a/src/fsharp/TcGlobals.fs b/src/fsharp/TcGlobals.fs index 0378331226..c4235f6fe4 100755 --- a/src/fsharp/TcGlobals.fs +++ b/src/fsharp/TcGlobals.fs @@ -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,13 +23,25 @@ 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 +[] +type IntrinsicValRef = + | IntrinsicValRef of NonLocalEntityRef * string * bool * TType * ValLinkageFullKey + + member x.Name = (let (IntrinsicValRef(_, nm, _, _, _)) = x in nm) + + /// For debugging + [] + member x.DebugText = x.ToString() + /// For debugging + override x.ToString() = x.Name + let ValRefForIntrinsic (IntrinsicValRef(mvr, _, _, _, key)) = mkNonLocalValRef mvr key //------------------------------------------------------------------------- @@ -82,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 + [] + 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 + [] + member x.DebugText = x.ToString() + + /// For debugging + override x.ToString() = x.TyconRef.ToString() + + [] let tname_DebuggerNonUserCodeAttribute = "System.Diagnostics.DebuggerNonUserCodeAttribute" [] diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 90ad09a120..02dde793b4 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -12555,6 +12555,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 = @@ -12652,7 +12658,7 @@ 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)) @@ -12660,33 +12666,32 @@ module IncrClassChecking = 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 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 readonly, ValDeref(v)), [], [] , m) + | Expr.Op(TOp.LValueOp (LGetAddr readonly, ValDeref v), [], [] , m) when localRep.IsValWithRepresentation(v) -> Some (localRep.MakeValueGetAddress readonly thisValOpt thisTyInst safeStaticInitInfo v m) @@ -12795,7 +12800,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 = @@ -12847,7 +12852,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 @@ -12883,7 +12888,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 @@ -12903,7 +12908,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) ] @@ -12917,7 +12922,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) @@ -13000,7 +13005,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 @@ -13674,7 +13679,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) } ) diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index 6e5805ec03..78be995b91 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -3947,7 +3947,7 @@ and | TType_var tp -> match tp.Solution with | None -> tp.DisplayName - | Some _ -> tp.DisplayName + " (solved, see Solution property)" + | Some _ -> tp.DisplayName + " (solved)" | TType_measure ms -> ms.ToString() and TypeInst = TType list diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index dc89186d0b..323f9e365f 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -1052,7 +1052,123 @@ module ByrefReturnMemberTests = let mutable x = Unchecked.defaultof<_> member __.P = f (0, &x) + // check recursive functions + module BeefModuleGeneric = + let rec beef (unused: 'T) id (data: byref) : unit = + if id = 10 then + data <- 3uy + else + beef unused (id + 1) &data + let Test() = + let mutable x = 0uy + beef "unused" 0 &x + check "vruoer" x 3uy + Test() + + module BeefModuleNonGeneric = + + let rec beef id (data: byref) : unit = + if id = 10 then + data <- 3uy + else + beef (id + 1) &data + + let Test() = + let mutable x = 0uy + beef 0 &x + check "vruoer3r" x 3uy + Test() + + module BeefModuleNonGenericSubsume = + + let rec beef id (data: byref) (y: System.IComparable) : unit = + if id = 10 then + data <- 3uy + else + beef (id + 1) &data y + + let Test() = + let mutable x = 0uy + beef 0 &x Unchecked.defaultof + check "vruoer3r" x 3uy + + Test() + + type GenericBeefRecursive() = + + let rec beef unused id (data: byref) : unit = + if id = 10 then data <- 3uy else beef unused (id + 1) &data + + static do GenericBeefRecursive().Test() + + member __.Test() = + let mutable x = 0uy + beef "unused" 0 &x + check "vruoer3rv" x 3uy + let mutable z = 0uy + beef 6L 0 &z + check "vruoer3rvwqf" z 3uy + + type NonGenericBeefRecursiveInClass() = + + let rec beef id (data: byref) : unit = + if id = 10 then + data <- 3uy + else + beef (id + 1) &data + + static do NonGenericBeefRecursiveInClass().Test() + + member __.Test() = + let mutable x = 0uy + beef 0 &x + check "vruoer3rvvremtys" x 3uy + + + type NonGenericBeefRecursiveInClassSubsume() = + + let rec beef id (data: byref) (y:System.IComparable) : unit = + if id = 10 then + data <- 3uy + else + beef (id + 1) &data y + + static do NonGenericBeefRecursiveInClassSubsume().Test() + + member __.Test() = + let mutable x = 0uy + beef 0 &x Unchecked.defaultof + check "vruoer3rvvremtys" x 3uy + + type StaticGenericBeefRecursiveInClass() = + + static let rec beef unused id (data: byref) : unit = + if id = 10 then data <- 3uy else beef unused (id + 1) &data + + static do StaticGenericBeefRecursiveInClass.Test() + + static member Test() = + let mutable x = 0uy + beef "unused" 0 &x + check "vruoer3rv" x 3uy + let mutable z = 0uy + beef 6L 0 &z + check "vruoer3rvwqfgw" z 3uy + + type StaticNonGenericBeefRecursiveInClass() = + + static let rec beef id (data: byref) : unit = + if id = 10 then data <- 3uy else beef (id + 1) &data + + static do StaticNonGenericBeefRecursiveInClass.Test() + + static member Test() = + let mutable x = 0uy + beef 0 &x + check "vruoer3rvvrebae" x 3uy + + let aa = if !failures then (stdout.WriteLine "Test Failed"; exit 1) else (stdout.WriteLine "Test Passed"; From 4a614531dfac7aad6bd52a14bea6aa081db2ab57 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 1 Jun 2018 13:19:28 +0100 Subject: [PATCH 49/61] update baselines --- .../FSharp.Compiler.Private/FSComp.fs | 2804 +++++++++-------- .../FSharp.Compiler.Private/FSComp.resx | 5 +- tests/fsharp/typecheck/sigs/neg_byref_22.bsl | 2 + 3 files changed, 1410 insertions(+), 1401 deletions(-) diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index c233e02e15..ab6e1ba319 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -1,4 +1,4 @@ -// This is a generated file; the original input is '../FSComp.txt' +// This is a generated file; the original input is '..\FSComp.txt' namespace FSComp open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators @@ -116,4208 +116,4211 @@ type internal SR private() = // END BOILERPLATE /// The namespace '%s' is not defined. - /// (Originally from ../FSComp.txt:4) + /// (Originally from ..\FSComp.txt:4) static member undefinedNameNamespace(a0 : System.String) = (GetStringFunc("undefinedNameNamespace",",,,%s,,,") a0) /// The namespace or module '%s' is not defined. - /// (Originally from ../FSComp.txt:5) + /// (Originally from ..\FSComp.txt:5) static member undefinedNameNamespaceOrModule(a0 : System.String) = (GetStringFunc("undefinedNameNamespaceOrModule",",,,%s,,,") a0) /// The field, constructor or member '%s' is not defined. - /// (Originally from ../FSComp.txt:6) + /// (Originally from ..\FSComp.txt:6) static member undefinedNameFieldConstructorOrMember(a0 : System.String) = (GetStringFunc("undefinedNameFieldConstructorOrMember",",,,%s,,,") a0) /// The value, constructor, namespace or type '%s' is not defined. - /// (Originally from ../FSComp.txt:7) + /// (Originally from ..\FSComp.txt:7) static member undefinedNameValueConstructorNamespaceOrType(a0 : System.String) = (GetStringFunc("undefinedNameValueConstructorNamespaceOrType",",,,%s,,,") a0) /// The value or constructor '%s' is not defined. - /// (Originally from ../FSComp.txt:8) + /// (Originally from ..\FSComp.txt:8) static member undefinedNameValueOfConstructor(a0 : System.String) = (GetStringFunc("undefinedNameValueOfConstructor",",,,%s,,,") a0) /// The value, namespace, type or module '%s' is not defined. - /// (Originally from ../FSComp.txt:9) + /// (Originally from ..\FSComp.txt:9) static member undefinedNameValueNamespaceTypeOrModule(a0 : System.String) = (GetStringFunc("undefinedNameValueNamespaceTypeOrModule",",,,%s,,,") a0) /// The constructor, module or namespace '%s' is not defined. - /// (Originally from ../FSComp.txt:10) + /// (Originally from ..\FSComp.txt:10) static member undefinedNameConstructorModuleOrNamespace(a0 : System.String) = (GetStringFunc("undefinedNameConstructorModuleOrNamespace",",,,%s,,,") a0) /// The type '%s' is not defined. - /// (Originally from ../FSComp.txt:11) + /// (Originally from ..\FSComp.txt:11) static member undefinedNameType(a0 : System.String) = (GetStringFunc("undefinedNameType",",,,%s,,,") a0) /// The type '%s' is not defined in '%s'. - /// (Originally from ../FSComp.txt:12) + /// (Originally from ..\FSComp.txt:12) static member undefinedNameTypeIn(a0 : System.String, a1 : System.String) = (GetStringFunc("undefinedNameTypeIn",",,,%s,,,%s,,,") a0 a1) /// The record label or namespace '%s' is not defined. - /// (Originally from ../FSComp.txt:13) + /// (Originally from ..\FSComp.txt:13) static member undefinedNameRecordLabelOrNamespace(a0 : System.String) = (GetStringFunc("undefinedNameRecordLabelOrNamespace",",,,%s,,,") a0) /// The record label '%s' is not defined. - /// (Originally from ../FSComp.txt:14) + /// (Originally from ..\FSComp.txt:14) static member undefinedNameRecordLabel(a0 : System.String) = (GetStringFunc("undefinedNameRecordLabel",",,,%s,,,") a0) /// Maybe you want one of the following: - /// (Originally from ../FSComp.txt:15) + /// (Originally from ..\FSComp.txt:15) static member undefinedNameSuggestionsIntro() = (GetStringFunc("undefinedNameSuggestionsIntro",",,,") ) /// The type parameter %s is not defined. - /// (Originally from ../FSComp.txt:16) + /// (Originally from ..\FSComp.txt:16) static member undefinedNameTypeParameter(a0 : System.String) = (GetStringFunc("undefinedNameTypeParameter",",,,%s,,,") a0) /// The pattern discriminator '%s' is not defined. - /// (Originally from ../FSComp.txt:17) + /// (Originally from ..\FSComp.txt:17) static member undefinedNamePatternDiscriminator(a0 : System.String) = (GetStringFunc("undefinedNamePatternDiscriminator",",,,%s,,,") a0) /// Replace with '%s' - /// (Originally from ../FSComp.txt:18) + /// (Originally from ..\FSComp.txt:18) static member replaceWithSuggestion(a0 : System.String) = (GetStringFunc("replaceWithSuggestion",",,,%s,,,") a0) /// Add . for indexer access. - /// (Originally from ../FSComp.txt:19) + /// (Originally from ..\FSComp.txt:19) static member addIndexerDot() = (GetStringFunc("addIndexerDot",",,,") ) /// All elements of a list constructor expression must have the same type. This expression was expected to have type '%s', but here has type '%s'. - /// (Originally from ../FSComp.txt:20) + /// (Originally from ..\FSComp.txt:20) static member listElementHasWrongType(a0 : System.String, a1 : System.String) = (GetStringFunc("listElementHasWrongType",",,,%s,,,%s,,,") a0 a1) /// All elements of an array constructor expression must have the same type. This expression was expected to have type '%s', but here has type '%s'. - /// (Originally from ../FSComp.txt:21) + /// (Originally from ..\FSComp.txt:21) static member arrayElementHasWrongType(a0 : System.String, a1 : System.String) = (GetStringFunc("arrayElementHasWrongType",",,,%s,,,%s,,,") a0 a1) /// The 'if' expression is missing an 'else' branch. The 'then' branch has type '%s'. Because 'if' is an expression, and not a statement, add an 'else' branch which returns a value of the same type. - /// (Originally from ../FSComp.txt:22) + /// (Originally from ..\FSComp.txt:22) static member missingElseBranch(a0 : System.String) = (GetStringFunc("missingElseBranch",",,,%s,,,") a0) /// The 'if' expression needs to have type '%s' to satisfy context type requirements. It currently has type '%s'. - /// (Originally from ../FSComp.txt:23) + /// (Originally from ..\FSComp.txt:23) static member ifExpression(a0 : System.String, a1 : System.String) = (GetStringFunc("ifExpression",",,,%s,,,%s,,,") a0 a1) /// All branches of an 'if' expression must have the same type. This expression was expected to have type '%s', but here has type '%s'. - /// (Originally from ../FSComp.txt:24) + /// (Originally from ..\FSComp.txt:24) static member elseBranchHasWrongType(a0 : System.String, a1 : System.String) = (GetStringFunc("elseBranchHasWrongType",",,,%s,,,%s,,,") a0 a1) /// All branches of a pattern match expression must return values of the same type. The first branch returned a value of type '%s', but this branch returned a value of type '%s'. - /// (Originally from ../FSComp.txt:25) + /// (Originally from ..\FSComp.txt:25) static member followingPatternMatchClauseHasWrongType(a0 : System.String, a1 : System.String) = (GetStringFunc("followingPatternMatchClauseHasWrongType",",,,%s,,,%s,,,") a0 a1) /// A pattern match guard must be of type 'bool', but this 'when' expression is of type '%s'. - /// (Originally from ../FSComp.txt:26) + /// (Originally from ..\FSComp.txt:26) static member patternMatchGuardIsNotBool(a0 : System.String) = (GetStringFunc("patternMatchGuardIsNotBool",",,,%s,,,") a0) /// A ';' is used to separate field values in records. Consider replacing ',' with ';'. - /// (Originally from ../FSComp.txt:27) + /// (Originally from ..\FSComp.txt:27) static member commaInsteadOfSemicolonInRecord() = (GetStringFunc("commaInsteadOfSemicolonInRecord",",,,") ) /// The '!' operator is used to dereference a ref cell. Consider using 'not expr' here. - /// (Originally from ../FSComp.txt:28) + /// (Originally from ..\FSComp.txt:28) static member derefInsteadOfNot() = (GetStringFunc("derefInsteadOfNot",",,,") ) /// The non-generic type '%s' does not expect any type arguments, but here is given %d type argument(s) - /// (Originally from ../FSComp.txt:29) + /// (Originally from ..\FSComp.txt:29) static member buildUnexpectedTypeArgs(a0 : System.String, a1 : System.Int32) = (GetStringFunc("buildUnexpectedTypeArgs",",,,%s,,,%d,,,") a0 a1) /// Consider using 'return!' instead of 'return'. - /// (Originally from ../FSComp.txt:30) + /// (Originally from ..\FSComp.txt:30) static member returnUsedInsteadOfReturnBang() = (GetStringFunc("returnUsedInsteadOfReturnBang",",,,") ) /// Consider using 'yield!' instead of 'yield'. - /// (Originally from ../FSComp.txt:31) + /// (Originally from ..\FSComp.txt:31) static member yieldUsedInsteadOfYieldBang() = (GetStringFunc("yieldUsedInsteadOfYieldBang",",,,") ) /// \nA tuple type is required for one or more arguments. Consider wrapping the given arguments in additional parentheses or review the definition of the interface. - /// (Originally from ../FSComp.txt:32) + /// (Originally from ..\FSComp.txt:32) static member tupleRequiredInAbstractMethod() = (GetStringFunc("tupleRequiredInAbstractMethod",",,,") ) /// Invalid warning number '%s' - /// (Originally from ../FSComp.txt:33) + /// (Originally from ..\FSComp.txt:33) static member buildInvalidWarningNumber(a0 : System.String) = (203, GetStringFunc("buildInvalidWarningNumber",",,,%s,,,") a0) /// Invalid version string '%s' - /// (Originally from ../FSComp.txt:34) + /// (Originally from ..\FSComp.txt:34) static member buildInvalidVersionString(a0 : System.String) = (204, GetStringFunc("buildInvalidVersionString",",,,%s,,,") a0) /// Invalid version file '%s' - /// (Originally from ../FSComp.txt:35) + /// (Originally from ..\FSComp.txt:35) static member buildInvalidVersionFile(a0 : System.String) = (205, GetStringFunc("buildInvalidVersionFile",",,,%s,,,") a0) /// Microsoft (R) F# Compiler version %s - /// (Originally from ../FSComp.txt:36) + /// (Originally from ..\FSComp.txt:36) static member buildProductName(a0 : System.String) = (GetStringFunc("buildProductName",",,,%s,,,") a0) /// F# Compiler for F# %s - /// (Originally from ../FSComp.txt:37) + /// (Originally from ..\FSComp.txt:37) static member buildProductNameCommunity(a0 : System.String) = (GetStringFunc("buildProductNameCommunity",",,,%s,,,") a0) /// Problem with filename '%s': %s - /// (Originally from ../FSComp.txt:38) + /// (Originally from ..\FSComp.txt:38) static member buildProblemWithFilename(a0 : System.String, a1 : System.String) = (206, GetStringFunc("buildProblemWithFilename",",,,%s,,,%s,,,") a0 a1) /// No inputs specified - /// (Originally from ../FSComp.txt:39) + /// (Originally from ..\FSComp.txt:39) static member buildNoInputsSpecified() = (207, GetStringFunc("buildNoInputsSpecified",",,,") ) /// The '--pdb' option requires the '--debug' option to be used - /// (Originally from ../FSComp.txt:40) + /// (Originally from ..\FSComp.txt:40) static member buildPdbRequiresDebug() = (209, GetStringFunc("buildPdbRequiresDebug",",,,") ) /// The search directory '%s' is invalid - /// (Originally from ../FSComp.txt:41) + /// (Originally from ..\FSComp.txt:41) static member buildInvalidSearchDirectory(a0 : System.String) = (210, GetStringFunc("buildInvalidSearchDirectory",",,,%s,,,") a0) /// The search directory '%s' could not be found - /// (Originally from ../FSComp.txt:42) + /// (Originally from ..\FSComp.txt:42) static member buildSearchDirectoryNotFound(a0 : System.String) = (211, GetStringFunc("buildSearchDirectoryNotFound",",,,%s,,,") a0) /// '%s' is not a valid filename - /// (Originally from ../FSComp.txt:43) + /// (Originally from ..\FSComp.txt:43) static member buildInvalidFilename(a0 : System.String) = (212, GetStringFunc("buildInvalidFilename",",,,%s,,,") a0) /// '%s' is not a valid assembly name - /// (Originally from ../FSComp.txt:44) + /// (Originally from ..\FSComp.txt:44) static member buildInvalidAssemblyName(a0 : System.String) = (213, GetStringFunc("buildInvalidAssemblyName",",,,%s,,,") a0) /// Unrecognized privacy setting '%s' for managed resource, valid options are 'public' and 'private' - /// (Originally from ../FSComp.txt:45) + /// (Originally from ..\FSComp.txt:45) static member buildInvalidPrivacy(a0 : System.String) = (214, GetStringFunc("buildInvalidPrivacy",",,,%s,,,") a0) /// Multiple references to '%s.dll' are not permitted - /// (Originally from ../FSComp.txt:46) + /// (Originally from ..\FSComp.txt:46) static member buildMultipleReferencesNotAllowed(a0 : System.String) = (215, GetStringFunc("buildMultipleReferencesNotAllowed",",,,%s,,,") a0) /// Could not read version from mscorlib.dll - /// (Originally from ../FSComp.txt:47) + /// (Originally from ..\FSComp.txt:47) static member buildCouldNotReadVersionInfoFromMscorlib() = (GetStringFunc("buildCouldNotReadVersionInfoFromMscorlib",",,,") ) /// Unable to read assembly '%s' - /// (Originally from ../FSComp.txt:48) + /// (Originally from ..\FSComp.txt:48) static member buildCannotReadAssembly(a0 : System.String) = (218, GetStringFunc("buildCannotReadAssembly",",,,%s,,,") a0) /// Assembly resolution failure at or near this location - /// (Originally from ../FSComp.txt:49) + /// (Originally from ..\FSComp.txt:49) static member buildAssemblyResolutionFailed() = (220, GetStringFunc("buildAssemblyResolutionFailed",",,,") ) /// The declarations in this file will be placed in an implicit module '%s' based on the file name '%s'. However this is not a valid F# identifier, so the contents will not be accessible from other files. Consider renaming the file or adding a 'module' or 'namespace' declaration at the top of the file. - /// (Originally from ../FSComp.txt:50) + /// (Originally from ..\FSComp.txt:50) static member buildImplicitModuleIsNotLegalIdentifier(a0 : System.String, a1 : System.String) = (221, GetStringFunc("buildImplicitModuleIsNotLegalIdentifier",",,,%s,,,%s,,,") a0 a1) /// Files in libraries or multiple-file applications must begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. Only the last source file of an application may omit such a declaration. - /// (Originally from ../FSComp.txt:51) + /// (Originally from ..\FSComp.txt:51) static member buildMultiFileRequiresNamespaceOrModule() = (222, GetStringFunc("buildMultiFileRequiresNamespaceOrModule",",,,") ) /// Files in libraries or multiple-file applications must begin with a namespace or module declaration. When using a module declaration at the start of a file the '=' sign is not allowed. If this is a top-level module, consider removing the = to resolve this error. - /// (Originally from ../FSComp.txt:52) + /// (Originally from ..\FSComp.txt:52) static member noEqualSignAfterModule() = (222, GetStringFunc("noEqualSignAfterModule",",,,") ) /// This file contains multiple declarations of the form 'module SomeNamespace.SomeModule'. Only one declaration of this form is permitted in a file. Change your file to use an initial namespace declaration and/or use 'module ModuleName = ...' to define your modules. - /// (Originally from ../FSComp.txt:53) + /// (Originally from ..\FSComp.txt:53) static member buildMultipleToplevelModules() = (223, GetStringFunc("buildMultipleToplevelModules",",,,") ) /// Option requires parameter: %s - /// (Originally from ../FSComp.txt:54) + /// (Originally from ..\FSComp.txt:54) static member buildOptionRequiresParameter(a0 : System.String) = (224, GetStringFunc("buildOptionRequiresParameter",",,,%s,,,") a0) /// Source file '%s' could not be found - /// (Originally from ../FSComp.txt:55) + /// (Originally from ..\FSComp.txt:55) static member buildCouldNotFindSourceFile(a0 : System.String) = (225, GetStringFunc("buildCouldNotFindSourceFile",",,,%s,,,") a0) /// The file extension of '%s' is not recognized. Source files must have extension .fs, .fsi, .fsx, .fsscript, .ml or .mli. - /// (Originally from ../FSComp.txt:56) + /// (Originally from ..\FSComp.txt:56) static member buildInvalidSourceFileExtension(a0 : System.String) = (226, GetStringFunc("buildInvalidSourceFileExtension",",,,%s,,,") a0) /// Could not resolve assembly '%s' - /// (Originally from ../FSComp.txt:57) + /// (Originally from ..\FSComp.txt:57) static member buildCouldNotResolveAssembly(a0 : System.String) = (227, GetStringFunc("buildCouldNotResolveAssembly",",,,%s,,,") a0) /// Could not resolve assembly '%s' required by '%s' - /// (Originally from ../FSComp.txt:58) + /// (Originally from ..\FSComp.txt:58) static member buildCouldNotResolveAssemblyRequiredByFile(a0 : System.String, a1 : System.String) = (228, GetStringFunc("buildCouldNotResolveAssemblyRequiredByFile",",,,%s,,,%s,,,") a0 a1) /// Error opening binary file '%s': %s - /// (Originally from ../FSComp.txt:59) + /// (Originally from ..\FSComp.txt:59) static member buildErrorOpeningBinaryFile(a0 : System.String, a1 : System.String) = (229, GetStringFunc("buildErrorOpeningBinaryFile",",,,%s,,,%s,,,") a0 a1) /// The F#-compiled DLL '%s' needs to be recompiled to be used with this version of F# - /// (Originally from ../FSComp.txt:60) + /// (Originally from ..\FSComp.txt:60) static member buildDifferentVersionMustRecompile(a0 : System.String) = (231, GetStringFunc("buildDifferentVersionMustRecompile",",,,%s,,,") a0) /// Invalid directive. Expected '#I \"\"'. - /// (Originally from ../FSComp.txt:61) + /// (Originally from ..\FSComp.txt:61) static member buildInvalidHashIDirective() = (232, GetStringFunc("buildInvalidHashIDirective",",,,") ) /// Invalid directive. Expected '#r \"\"'. - /// (Originally from ../FSComp.txt:62) + /// (Originally from ..\FSComp.txt:62) static member buildInvalidHashrDirective() = (233, GetStringFunc("buildInvalidHashrDirective",",,,") ) /// Invalid directive. Expected '#load \"\" ... \"\"'. - /// (Originally from ../FSComp.txt:63) + /// (Originally from ..\FSComp.txt:63) static member buildInvalidHashloadDirective() = (234, GetStringFunc("buildInvalidHashloadDirective",",,,") ) /// Invalid directive. Expected '#time', '#time \"on\"' or '#time \"off\"'. - /// (Originally from ../FSComp.txt:64) + /// (Originally from ..\FSComp.txt:64) static member buildInvalidHashtimeDirective() = (235, GetStringFunc("buildInvalidHashtimeDirective",",,,") ) /// Directives inside modules are ignored - /// (Originally from ../FSComp.txt:65) + /// (Originally from ..\FSComp.txt:65) static member buildDirectivesInModulesAreIgnored() = (236, GetStringFunc("buildDirectivesInModulesAreIgnored",",,,") ) /// A signature for the file or module '%s' has already been specified - /// (Originally from ../FSComp.txt:66) + /// (Originally from ..\FSComp.txt:66) static member buildSignatureAlreadySpecified(a0 : System.String) = (237, GetStringFunc("buildSignatureAlreadySpecified",",,,%s,,,") a0) /// An implementation of file or module '%s' has already been given. Compilation order is significant in F# because of type inference. You may need to adjust the order of your files to place the signature file before the implementation. In Visual Studio files are type-checked in the order they appear in the project file, which can be edited manually or adjusted using the solution explorer. - /// (Originally from ../FSComp.txt:67) + /// (Originally from ..\FSComp.txt:67) static member buildImplementationAlreadyGivenDetail(a0 : System.String) = (238, GetStringFunc("buildImplementationAlreadyGivenDetail",",,,%s,,,") a0) /// An implementation of the file or module '%s' has already been given - /// (Originally from ../FSComp.txt:68) + /// (Originally from ..\FSComp.txt:68) static member buildImplementationAlreadyGiven(a0 : System.String) = (239, GetStringFunc("buildImplementationAlreadyGiven",",,,%s,,,") a0) /// The signature file '%s' does not have a corresponding implementation file. If an implementation file exists then check the 'module' and 'namespace' declarations in the signature and implementation files match. - /// (Originally from ../FSComp.txt:69) + /// (Originally from ..\FSComp.txt:69) static member buildSignatureWithoutImplementation(a0 : System.String) = (240, GetStringFunc("buildSignatureWithoutImplementation",",,,%s,,,") a0) /// '%s' is not a valid integer argument - /// (Originally from ../FSComp.txt:70) + /// (Originally from ..\FSComp.txt:70) static member buildArgInvalidInt(a0 : System.String) = (241, GetStringFunc("buildArgInvalidInt",",,,%s,,,") a0) /// '%s' is not a valid floating point argument - /// (Originally from ../FSComp.txt:71) + /// (Originally from ..\FSComp.txt:71) static member buildArgInvalidFloat(a0 : System.String) = (242, GetStringFunc("buildArgInvalidFloat",",,,%s,,,") a0) /// Unrecognized option: '%s' - /// (Originally from ../FSComp.txt:72) + /// (Originally from ..\FSComp.txt:72) static member buildUnrecognizedOption(a0 : System.String) = (243, GetStringFunc("buildUnrecognizedOption",",,,%s,,,") a0) /// Invalid module or namespace name - /// (Originally from ../FSComp.txt:73) + /// (Originally from ..\FSComp.txt:73) static member buildInvalidModuleOrNamespaceName() = (244, GetStringFunc("buildInvalidModuleOrNamespaceName",",,,") ) /// Error reading/writing metadata for the F# compiled DLL '%s'. Was the DLL compiled with an earlier version of the F# compiler? (error: '%s'). - /// (Originally from ../FSComp.txt:74) + /// (Originally from ..\FSComp.txt:74) static member pickleErrorReadingWritingMetadata(a0 : System.String, a1 : System.String) = (GetStringFunc("pickleErrorReadingWritingMetadata",",,,%s,,,%s,,,") a0 a1) /// The type/module '%s' is not a concrete module or type - /// (Originally from ../FSComp.txt:75) + /// (Originally from ..\FSComp.txt:75) static member tastTypeOrModuleNotConcrete(a0 : System.String) = (245, GetStringFunc("tastTypeOrModuleNotConcrete",",,,%s,,,") a0) /// The type '%s' has an inline assembly code representation - /// (Originally from ../FSComp.txt:76) + /// (Originally from ..\FSComp.txt:76) static member tastTypeHasAssemblyCodeRepresentation(a0 : System.String) = (GetStringFunc("tastTypeHasAssemblyCodeRepresentation",",,,%s,,,") a0) /// A namespace and a module named '%s' both occur in two parts of this assembly - /// (Originally from ../FSComp.txt:77) + /// (Originally from ..\FSComp.txt:77) static member tastNamespaceAndModuleWithSameNameInAssembly(a0 : System.String) = (247, GetStringFunc("tastNamespaceAndModuleWithSameNameInAssembly",",,,%s,,,") a0) /// Two modules named '%s' occur in two parts of this assembly - /// (Originally from ../FSComp.txt:78) + /// (Originally from ..\FSComp.txt:78) static member tastTwoModulesWithSameNameInAssembly(a0 : System.String) = (248, GetStringFunc("tastTwoModulesWithSameNameInAssembly",",,,%s,,,") a0) /// Two type definitions named '%s' occur in namespace '%s' in two parts of this assembly - /// (Originally from ../FSComp.txt:79) + /// (Originally from ..\FSComp.txt:79) static member tastDuplicateTypeDefinitionInAssembly(a0 : System.String, a1 : System.String) = (249, GetStringFunc("tastDuplicateTypeDefinitionInAssembly",",,,%s,,,%s,,,") a0 a1) /// A module and a type definition named '%s' occur in namespace '%s' in two parts of this assembly - /// (Originally from ../FSComp.txt:80) + /// (Originally from ..\FSComp.txt:80) static member tastConflictingModuleAndTypeDefinitionInAssembly(a0 : System.String, a1 : System.String) = (250, GetStringFunc("tastConflictingModuleAndTypeDefinitionInAssembly",",,,%s,,,%s,,,") a0 a1) /// Invalid member signature encountered because of an earlier error - /// (Originally from ../FSComp.txt:81) + /// (Originally from ..\FSComp.txt:81) static member tastInvalidMemberSignature() = (251, GetStringFunc("tastInvalidMemberSignature",",,,") ) /// This value does not have a valid property setter type - /// (Originally from ../FSComp.txt:82) + /// (Originally from ..\FSComp.txt:82) static member tastValueDoesNotHaveSetterType() = (252, GetStringFunc("tastValueDoesNotHaveSetterType",",,,") ) /// Invalid form for a property getter. At least one '()' argument is required when using the explicit syntax. - /// (Originally from ../FSComp.txt:83) + /// (Originally from ..\FSComp.txt:83) static member tastInvalidFormForPropertyGetter() = (253, GetStringFunc("tastInvalidFormForPropertyGetter",",,,") ) /// Invalid form for a property setter. At least one argument is required. - /// (Originally from ../FSComp.txt:84) + /// (Originally from ..\FSComp.txt:84) static member tastInvalidFormForPropertySetter() = (254, GetStringFunc("tastInvalidFormForPropertySetter",",,,") ) /// Unexpected use of a byref-typed variable - /// (Originally from ../FSComp.txt:85) + /// (Originally from ..\FSComp.txt:85) static member tastUnexpectedByRef() = (255, GetStringFunc("tastUnexpectedByRef",",,,") ) /// A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...' /// (Originally from ..\FSComp.txt:86) static member tastValueMustBeMutable() = (256, GetStringFunc("tastValueMustBeMutable",",,,") ) /// Invalid mutation of a constant expression. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...'. - /// (Originally from ../FSComp.txt:87) + /// (Originally from ..\FSComp.txt:87) static member tastInvalidMutationOfConstant() = (257, GetStringFunc("tastInvalidMutationOfConstant",",,,") ) /// The value has been copied to ensure the original is not mutated by this operation or because the copy is implicit when returning a struct from a member and another member is then accessed - /// (Originally from ../FSComp.txt:88) + /// (Originally from ..\FSComp.txt:88) static member tastValueHasBeenCopied() = (GetStringFunc("tastValueHasBeenCopied",",,,") ) /// Recursively defined values cannot appear directly as part of the construction of a tuple value within a recursive binding - /// (Originally from ../FSComp.txt:89) + /// (Originally from ..\FSComp.txt:89) static member tastRecursiveValuesMayNotBeInConstructionOfTuple() = (259, GetStringFunc("tastRecursiveValuesMayNotBeInConstructionOfTuple",",,,") ) /// Recursive values cannot appear directly as a construction of the type '%s' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead. - /// (Originally from ../FSComp.txt:90) + /// (Originally from ..\FSComp.txt:90) static member tastRecursiveValuesMayNotAppearInConstructionOfType(a0 : System.String) = (260, GetStringFunc("tastRecursiveValuesMayNotAppearInConstructionOfType",",,,%s,,,") a0) /// Recursive values cannot be directly assigned to the non-mutable field '%s' of the type '%s' within a recursive binding. Consider using a mutable field instead. - /// (Originally from ../FSComp.txt:91) + /// (Originally from ..\FSComp.txt:91) static member tastRecursiveValuesMayNotBeAssignedToNonMutableField(a0 : System.String, a1 : System.String) = (261, GetStringFunc("tastRecursiveValuesMayNotBeAssignedToNonMutableField",",,,%s,,,%s,,,") a0 a1) /// Unexpected decode of AutoOpenAttribute - /// (Originally from ../FSComp.txt:92) + /// (Originally from ..\FSComp.txt:92) static member tastUnexpectedDecodeOfAutoOpenAttribute() = (GetStringFunc("tastUnexpectedDecodeOfAutoOpenAttribute",",,,") ) /// Unexpected decode of InternalsVisibleToAttribute - /// (Originally from ../FSComp.txt:93) + /// (Originally from ..\FSComp.txt:93) static member tastUnexpectedDecodeOfInternalsVisibleToAttribute() = (GetStringFunc("tastUnexpectedDecodeOfInternalsVisibleToAttribute",",,,") ) /// Unexpected decode of InterfaceDataVersionAttribute - /// (Originally from ../FSComp.txt:94) + /// (Originally from ..\FSComp.txt:94) static member tastUnexpectedDecodeOfInterfaceDataVersionAttribute() = (GetStringFunc("tastUnexpectedDecodeOfInterfaceDataVersionAttribute",",,,") ) /// Active patterns cannot return more than 7 possibilities - /// (Originally from ../FSComp.txt:95) + /// (Originally from ..\FSComp.txt:95) static member tastActivePatternsLimitedToSeven() = (265, GetStringFunc("tastActivePatternsLimitedToSeven",",,,") ) /// This is not a valid constant expression or custom attribute value - /// (Originally from ../FSComp.txt:96) + /// (Originally from ..\FSComp.txt:96) static member tastNotAConstantExpression() = (267, GetStringFunc("tastNotAConstantExpression",",,,") ) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe mutability attributes differ - /// (Originally from ../FSComp.txt:97) + /// (Originally from ..\FSComp.txt:97) static member ValueNotContainedMutabilityAttributesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityAttributesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe names differ - /// (Originally from ../FSComp.txt:98) + /// (Originally from ..\FSComp.txt:98) static member ValueNotContainedMutabilityNamesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityNamesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe compiled names differ - /// (Originally from ../FSComp.txt:99) + /// (Originally from ..\FSComp.txt:99) static member ValueNotContainedMutabilityCompiledNamesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityCompiledNamesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe display names differ - /// (Originally from ../FSComp.txt:100) + /// (Originally from ..\FSComp.txt:100) static member ValueNotContainedMutabilityDisplayNamesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityDisplayNamesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe accessibility specified in the signature is more than that specified in the implementation - /// (Originally from ../FSComp.txt:101) + /// (Originally from ..\FSComp.txt:101) static member ValueNotContainedMutabilityAccessibilityMore(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityAccessibilityMore",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe inline flags differ - /// (Originally from ../FSComp.txt:102) + /// (Originally from ..\FSComp.txt:102) static member ValueNotContainedMutabilityInlineFlagsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityInlineFlagsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe literal constant values and/or attributes differ - /// (Originally from ../FSComp.txt:103) + /// (Originally from ..\FSComp.txt:103) static member ValueNotContainedMutabilityLiteralConstantValuesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityLiteralConstantValuesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is a type function and the other is not. The signature requires explicit type parameters if they are present in the implementation. - /// (Originally from ../FSComp.txt:104) + /// (Originally from ..\FSComp.txt:104) static member ValueNotContainedMutabilityOneIsTypeFunction(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityOneIsTypeFunction",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe respective type parameter counts differ - /// (Originally from ../FSComp.txt:105) + /// (Originally from ..\FSComp.txt:105) static member ValueNotContainedMutabilityParameterCountsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityParameterCountsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe types differ - /// (Originally from ../FSComp.txt:106) + /// (Originally from ..\FSComp.txt:106) static member ValueNotContainedMutabilityTypesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityTypesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is an extension member and the other is not - /// (Originally from ../FSComp.txt:107) + /// (Originally from ..\FSComp.txt:107) static member ValueNotContainedMutabilityExtensionsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityExtensionsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nAn arity was not inferred for this value - /// (Originally from ../FSComp.txt:108) + /// (Originally from ..\FSComp.txt:108) static member ValueNotContainedMutabilityArityNotInferred(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityArityNotInferred",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe number of generic parameters in the signature and implementation differ (the signature declares %s but the implementation declares %s - /// (Originally from ../FSComp.txt:109) + /// (Originally from ..\FSComp.txt:109) static member ValueNotContainedMutabilityGenericParametersDiffer(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String, a4 : System.String) = (GetStringFunc("ValueNotContainedMutabilityGenericParametersDiffer",",,,%s,,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3 a4) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe generic parameters in the signature and implementation have different kinds. Perhaps there is a missing [] attribute. - /// (Originally from ../FSComp.txt:110) + /// (Originally from ..\FSComp.txt:110) static member ValueNotContainedMutabilityGenericParametersAreDifferentKinds(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityGenericParametersAreDifferentKinds",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe arities in the signature and implementation differ. The signature specifies that '%s' is function definition or lambda expression accepting at least %s argument(s), but the implementation is a computed function value. To declare that a computed function value is a permitted implementation simply parenthesize its type in the signature, e.g.\n\tval %s: int -> (int -> int)\ninstead of\n\tval %s: int -> int -> int. - /// (Originally from ../FSComp.txt:111) + /// (Originally from ..\FSComp.txt:111) static member ValueNotContainedMutabilityAritiesDiffer(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String, a4 : System.String, a5 : System.String, a6 : System.String) = (GetStringFunc("ValueNotContainedMutabilityAritiesDiffer",",,,%s,,,%s,,,%s,,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3 a4 a5 a6) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe CLI member names differ - /// (Originally from ../FSComp.txt:112) + /// (Originally from ..\FSComp.txt:112) static member ValueNotContainedMutabilityDotNetNamesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityDotNetNamesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is static and the other isn't - /// (Originally from ../FSComp.txt:113) + /// (Originally from ..\FSComp.txt:113) static member ValueNotContainedMutabilityStaticsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityStaticsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is virtual and the other isn't - /// (Originally from ../FSComp.txt:114) + /// (Originally from ..\FSComp.txt:114) static member ValueNotContainedMutabilityVirtualsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityVirtualsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is abstract and the other isn't - /// (Originally from ../FSComp.txt:115) + /// (Originally from ..\FSComp.txt:115) static member ValueNotContainedMutabilityAbstractsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityAbstractsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is final and the other isn't - /// (Originally from ../FSComp.txt:116) + /// (Originally from ..\FSComp.txt:116) static member ValueNotContainedMutabilityFinalsDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityFinalsDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is marked as an override and the other isn't - /// (Originally from ../FSComp.txt:117) + /// (Originally from ..\FSComp.txt:117) static member ValueNotContainedMutabilityOverridesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityOverridesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nOne is a constructor/property and the other is not - /// (Originally from ../FSComp.txt:118) + /// (Originally from ..\FSComp.txt:118) static member ValueNotContainedMutabilityOneIsConstructor(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityOneIsConstructor",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe compiled representation of this method is as a static member but the signature indicates its compiled representation is as an instance member - /// (Originally from ../FSComp.txt:119) + /// (Originally from ..\FSComp.txt:119) static member ValueNotContainedMutabilityStaticButInstance(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityStaticButInstance",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Module '%s' contains\n %s \nbut its signature specifies\n %s \nThe compiled representation of this method is as an instance member, but the signature indicates its compiled representation is as a static member - /// (Originally from ../FSComp.txt:120) + /// (Originally from ..\FSComp.txt:120) static member ValueNotContainedMutabilityInstanceButStatic(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ValueNotContainedMutabilityInstanceButStatic",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The %s definitions in the signature and implementation are not compatible because the names differ. The type is called '%s' in the signature file but '%s' in implementation. - /// (Originally from ../FSComp.txt:121) + /// (Originally from ..\FSComp.txt:121) static member DefinitionsInSigAndImplNotCompatibleNamesDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (290, GetStringFunc("DefinitionsInSigAndImplNotCompatibleNamesDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the respective type parameter counts differ - /// (Originally from ../FSComp.txt:122) + /// (Originally from ..\FSComp.txt:122) static member DefinitionsInSigAndImplNotCompatibleParameterCountsDiffer(a0 : System.String, a1 : System.String) = (291, GetStringFunc("DefinitionsInSigAndImplNotCompatibleParameterCountsDiffer",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the accessibility specified in the signature is more than that specified in the implementation - /// (Originally from ../FSComp.txt:123) + /// (Originally from ..\FSComp.txt:123) static member DefinitionsInSigAndImplNotCompatibleAccessibilityDiffer(a0 : System.String, a1 : System.String) = (292, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAccessibilityDiffer",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the signature requires that the type supports the interface %s but the interface has not been implemented - /// (Originally from ../FSComp.txt:124) + /// (Originally from ..\FSComp.txt:124) static member DefinitionsInSigAndImplNotCompatibleMissingInterface(a0 : System.String, a1 : System.String, a2 : System.String) = (293, GetStringFunc("DefinitionsInSigAndImplNotCompatibleMissingInterface",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the implementation says this type may use nulls as a representation but the signature does not - /// (Originally from ../FSComp.txt:125) + /// (Originally from ..\FSComp.txt:125) static member DefinitionsInSigAndImplNotCompatibleImplementationSaysNull(a0 : System.String, a1 : System.String) = (294, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationSaysNull",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the implementation says this type may use nulls as an extra value but the signature does not - /// (Originally from ../FSComp.txt:126) + /// (Originally from ..\FSComp.txt:126) static member DefinitionsInSigAndImplNotCompatibleImplementationSaysNull2(a0 : System.String, a1 : System.String) = (294, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationSaysNull2",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the signature says this type may use nulls as a representation but the implementation does not - /// (Originally from ../FSComp.txt:127) + /// (Originally from ..\FSComp.txt:127) static member DefinitionsInSigAndImplNotCompatibleSignatureSaysNull(a0 : System.String, a1 : System.String) = (295, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureSaysNull",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the signature says this type may use nulls as an extra value but the implementation does not - /// (Originally from ../FSComp.txt:128) + /// (Originally from ..\FSComp.txt:128) static member DefinitionsInSigAndImplNotCompatibleSignatureSaysNull2(a0 : System.String, a1 : System.String) = (295, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureSaysNull2",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the implementation type is sealed but the signature implies it is not. Consider adding the [] attribute to the signature. - /// (Originally from ../FSComp.txt:129) + /// (Originally from ..\FSComp.txt:129) static member DefinitionsInSigAndImplNotCompatibleImplementationSealed(a0 : System.String, a1 : System.String) = (296, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationSealed",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the implementation type is not sealed but signature implies it is. Consider adding the [] attribute to the implementation. - /// (Originally from ../FSComp.txt:130) + /// (Originally from ..\FSComp.txt:130) static member DefinitionsInSigAndImplNotCompatibleImplementationIsNotSealed(a0 : System.String, a1 : System.String) = (297, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationIsNotSealed",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the implementation is an abstract class but the signature is not. Consider adding the [] attribute to the signature. - /// (Originally from ../FSComp.txt:131) + /// (Originally from ..\FSComp.txt:131) static member DefinitionsInSigAndImplNotCompatibleImplementationIsAbstract(a0 : System.String, a1 : System.String) = (298, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplementationIsAbstract",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the signature is an abstract class but the implementation is not. Consider adding the [] attribute to the implementation. - /// (Originally from ../FSComp.txt:132) + /// (Originally from ..\FSComp.txt:132) static member DefinitionsInSigAndImplNotCompatibleSignatureIsAbstract(a0 : System.String, a1 : System.String) = (299, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureIsAbstract",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the types have different base types - /// (Originally from ../FSComp.txt:133) + /// (Originally from ..\FSComp.txt:133) static member DefinitionsInSigAndImplNotCompatibleTypesHaveDifferentBaseTypes(a0 : System.String, a1 : System.String) = (300, GetStringFunc("DefinitionsInSigAndImplNotCompatibleTypesHaveDifferentBaseTypes",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the number of %ss differ - /// (Originally from ../FSComp.txt:134) + /// (Originally from ..\FSComp.txt:134) static member DefinitionsInSigAndImplNotCompatibleNumbersDiffer(a0 : System.String, a1 : System.String, a2 : System.String) = (301, GetStringFunc("DefinitionsInSigAndImplNotCompatibleNumbersDiffer",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the signature defines the %s '%s' but the implementation does not (or does, but not in the same order) - /// (Originally from ../FSComp.txt:135) + /// (Originally from ..\FSComp.txt:135) static member DefinitionsInSigAndImplNotCompatibleSignatureDefinesButImplDoesNot(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String) = (302, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureDefinesButImplDoesNot",",,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the implementation defines the %s '%s' but the signature does not (or does, but not in the same order) - /// (Originally from ../FSComp.txt:136) + /// (Originally from ..\FSComp.txt:136) static member DefinitionsInSigAndImplNotCompatibleImplDefinesButSignatureDoesNot(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String) = (303, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplDefinesButSignatureDoesNot",",,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the implementation defines a struct but the signature defines a type with a hidden representation - /// (Originally from ../FSComp.txt:137) + /// (Originally from ..\FSComp.txt:137) static member DefinitionsInSigAndImplNotCompatibleImplDefinesStruct(a0 : System.String, a1 : System.String) = (304, GetStringFunc("DefinitionsInSigAndImplNotCompatibleImplDefinesStruct",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because a CLI type representation is being hidden by a signature - /// (Originally from ../FSComp.txt:138) + /// (Originally from ..\FSComp.txt:138) static member DefinitionsInSigAndImplNotCompatibleDotNetTypeRepresentationIsHidden(a0 : System.String, a1 : System.String) = (305, GetStringFunc("DefinitionsInSigAndImplNotCompatibleDotNetTypeRepresentationIsHidden",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because a type representation is being hidden by a signature - /// (Originally from ../FSComp.txt:139) + /// (Originally from ..\FSComp.txt:139) static member DefinitionsInSigAndImplNotCompatibleTypeIsHidden(a0 : System.String, a1 : System.String) = (306, GetStringFunc("DefinitionsInSigAndImplNotCompatibleTypeIsHidden",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the types are of different kinds - /// (Originally from ../FSComp.txt:140) + /// (Originally from ..\FSComp.txt:140) static member DefinitionsInSigAndImplNotCompatibleTypeIsDifferentKind(a0 : System.String, a1 : System.String) = (307, GetStringFunc("DefinitionsInSigAndImplNotCompatibleTypeIsDifferentKind",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the IL representations differ - /// (Originally from ../FSComp.txt:141) + /// (Originally from ..\FSComp.txt:141) static member DefinitionsInSigAndImplNotCompatibleILDiffer(a0 : System.String, a1 : System.String) = (308, GetStringFunc("DefinitionsInSigAndImplNotCompatibleILDiffer",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the representations differ - /// (Originally from ../FSComp.txt:142) + /// (Originally from ..\FSComp.txt:142) static member DefinitionsInSigAndImplNotCompatibleRepresentationsDiffer(a0 : System.String, a1 : System.String) = (309, GetStringFunc("DefinitionsInSigAndImplNotCompatibleRepresentationsDiffer",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the field %s was present in the implementation but not in the signature - /// (Originally from ../FSComp.txt:143) + /// (Originally from ..\FSComp.txt:143) static member DefinitionsInSigAndImplNotCompatibleFieldWasPresent(a0 : System.String, a1 : System.String, a2 : System.String) = (311, GetStringFunc("DefinitionsInSigAndImplNotCompatibleFieldWasPresent",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the order of the fields is different in the signature and implementation - /// (Originally from ../FSComp.txt:144) + /// (Originally from ..\FSComp.txt:144) static member DefinitionsInSigAndImplNotCompatibleFieldOrderDiffer(a0 : System.String, a1 : System.String) = (312, GetStringFunc("DefinitionsInSigAndImplNotCompatibleFieldOrderDiffer",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the field %s was required by the signature but was not specified by the implementation - /// (Originally from ../FSComp.txt:145) + /// (Originally from ..\FSComp.txt:145) static member DefinitionsInSigAndImplNotCompatibleFieldRequiredButNotSpecified(a0 : System.String, a1 : System.String, a2 : System.String) = (313, GetStringFunc("DefinitionsInSigAndImplNotCompatibleFieldRequiredButNotSpecified",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the field '%s' was present in the implementation but not in the signature. Struct types must now reveal their fields in the signature for the type, though the fields may still be labelled 'private' or 'internal'. - /// (Originally from ../FSComp.txt:146) + /// (Originally from ..\FSComp.txt:146) static member DefinitionsInSigAndImplNotCompatibleFieldIsInImplButNotSig(a0 : System.String, a1 : System.String, a2 : System.String) = (314, GetStringFunc("DefinitionsInSigAndImplNotCompatibleFieldIsInImplButNotSig",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the abstract member '%s' was required by the signature but was not specified by the implementation - /// (Originally from ../FSComp.txt:147) + /// (Originally from ..\FSComp.txt:147) static member DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInImpl(a0 : System.String, a1 : System.String, a2 : System.String) = (315, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInImpl",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the abstract member '%s' was present in the implementation but not in the signature - /// (Originally from ../FSComp.txt:148) + /// (Originally from ..\FSComp.txt:148) static member DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInSig(a0 : System.String, a1 : System.String, a2 : System.String) = (316, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAbstractMemberMissingInSig",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the signature declares a %s while the implementation declares a %s - /// (Originally from ../FSComp.txt:149) + /// (Originally from ..\FSComp.txt:149) static member DefinitionsInSigAndImplNotCompatibleSignatureDeclaresDiffer(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String) = (317, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSignatureDeclaresDiffer",",,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the abbreviations differ: %s versus %s - /// (Originally from ../FSComp.txt:150) + /// (Originally from ..\FSComp.txt:150) static member DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String) = (318, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer",",,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3) /// The %s definitions for type '%s' in the signature and implementation are not compatible because an abbreviation is being hidden by a signature. The abbreviation must be visible to other CLI languages. Consider making the abbreviation visible in the signature. - /// (Originally from ../FSComp.txt:151) + /// (Originally from ..\FSComp.txt:151) static member DefinitionsInSigAndImplNotCompatibleAbbreviationHiddenBySig(a0 : System.String, a1 : System.String) = (319, GetStringFunc("DefinitionsInSigAndImplNotCompatibleAbbreviationHiddenBySig",",,,%s,,,%s,,,") a0 a1) /// The %s definitions for type '%s' in the signature and implementation are not compatible because the signature has an abbreviation while the implementation does not - /// (Originally from ../FSComp.txt:152) + /// (Originally from ..\FSComp.txt:152) static member DefinitionsInSigAndImplNotCompatibleSigHasAbbreviation(a0 : System.String, a1 : System.String) = (320, GetStringFunc("DefinitionsInSigAndImplNotCompatibleSigHasAbbreviation",",,,%s,,,%s,,,") a0 a1) /// The module contains the constructor\n %s \nbut its signature specifies\n %s \nThe names differ - /// (Originally from ../FSComp.txt:153) + /// (Originally from ..\FSComp.txt:153) static member ModuleContainsConstructorButNamesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ModuleContainsConstructorButNamesDiffer",",,,%s,,,%s,,,") a0 a1) /// The module contains the constructor\n %s \nbut its signature specifies\n %s \nThe respective number of data fields differ - /// (Originally from ../FSComp.txt:154) + /// (Originally from ..\FSComp.txt:154) static member ModuleContainsConstructorButDataFieldsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ModuleContainsConstructorButDataFieldsDiffer",",,,%s,,,%s,,,") a0 a1) /// The module contains the constructor\n %s \nbut its signature specifies\n %s \nThe types of the fields differ - /// (Originally from ../FSComp.txt:155) + /// (Originally from ..\FSComp.txt:155) static member ModuleContainsConstructorButTypesOfFieldsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ModuleContainsConstructorButTypesOfFieldsDiffer",",,,%s,,,%s,,,") a0 a1) /// The module contains the constructor\n %s \nbut its signature specifies\n %s \nthe accessibility specified in the signature is more than that specified in the implementation - /// (Originally from ../FSComp.txt:156) + /// (Originally from ..\FSComp.txt:156) static member ModuleContainsConstructorButAccessibilityDiffers(a0 : System.String, a1 : System.String) = (GetStringFunc("ModuleContainsConstructorButAccessibilityDiffers",",,,%s,,,%s,,,") a0 a1) /// The module contains the field\n %s \nbut its signature specifies\n %s \nThe names differ - /// (Originally from ../FSComp.txt:157) + /// (Originally from ..\FSComp.txt:157) static member FieldNotContainedNamesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedNamesDiffer",",,,%s,,,%s,,,") a0 a1) /// The module contains the field\n %s \nbut its signature specifies\n %s \nthe accessibility specified in the signature is more than that specified in the implementation - /// (Originally from ../FSComp.txt:158) + /// (Originally from ..\FSComp.txt:158) static member FieldNotContainedAccessibilitiesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedAccessibilitiesDiffer",",,,%s,,,%s,,,") a0 a1) /// The module contains the field\n %s \nbut its signature specifies\n %s \nThe 'static' modifiers differ - /// (Originally from ../FSComp.txt:159) + /// (Originally from ..\FSComp.txt:159) static member FieldNotContainedStaticsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedStaticsDiffer",",,,%s,,,%s,,,") a0 a1) /// The module contains the field\n %s \nbut its signature specifies\n %s \nThe 'mutable' modifiers differ - /// (Originally from ../FSComp.txt:160) + /// (Originally from ..\FSComp.txt:160) static member FieldNotContainedMutablesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedMutablesDiffer",",,,%s,,,%s,,,") a0 a1) /// The module contains the field\n %s \nbut its signature specifies\n %s \nThe 'literal' modifiers differ - /// (Originally from ../FSComp.txt:161) + /// (Originally from ..\FSComp.txt:161) static member FieldNotContainedLiteralsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedLiteralsDiffer",",,,%s,,,%s,,,") a0 a1) /// The module contains the field\n %s \nbut its signature specifies\n %s \nThe types differ - /// (Originally from ../FSComp.txt:162) + /// (Originally from ..\FSComp.txt:162) static member FieldNotContainedTypesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("FieldNotContainedTypesDiffer",",,,%s,,,%s,,,") a0 a1) /// The implicit instantiation of a generic construct at or near this point could not be resolved because it could resolve to multiple unrelated types, e.g. '%s' and '%s'. Consider using type annotations to resolve the ambiguity - /// (Originally from ../FSComp.txt:163) + /// (Originally from ..\FSComp.txt:163) static member typrelCannotResolveImplicitGenericInstantiation(a0 : System.String, a1 : System.String) = (331, GetStringFunc("typrelCannotResolveImplicitGenericInstantiation",",,,%s,,,%s,,,") a0 a1) /// Could not resolve the ambiguity inherent in the use of a 'printf'-style format string - /// (Originally from ../FSComp.txt:164) + /// (Originally from ..\FSComp.txt:164) static member typrelCannotResolveAmbiguityInPrintf() = (333, GetStringFunc("typrelCannotResolveAmbiguityInPrintf",",,,") ) /// Could not resolve the ambiguity in the use of a generic construct with an 'enum' constraint at or near this position - /// (Originally from ../FSComp.txt:165) + /// (Originally from ..\FSComp.txt:165) static member typrelCannotResolveAmbiguityInEnum() = (334, GetStringFunc("typrelCannotResolveAmbiguityInEnum",",,,") ) /// Could not resolve the ambiguity in the use of a generic construct with a 'delegate' constraint at or near this position - /// (Originally from ../FSComp.txt:166) + /// (Originally from ..\FSComp.txt:166) static member typrelCannotResolveAmbiguityInDelegate() = (335, GetStringFunc("typrelCannotResolveAmbiguityInDelegate",",,,") ) /// Invalid value - /// (Originally from ../FSComp.txt:167) + /// (Originally from ..\FSComp.txt:167) static member typrelInvalidValue() = (337, GetStringFunc("typrelInvalidValue",",,,") ) /// The signature and implementation are not compatible because the respective type parameter counts differ - /// (Originally from ../FSComp.txt:168) + /// (Originally from ..\FSComp.txt:168) static member typrelSigImplNotCompatibleParamCountsDiffer() = (338, GetStringFunc("typrelSigImplNotCompatibleParamCountsDiffer",",,,") ) /// The signature and implementation are not compatible because the type parameter in the class/signature has a different compile-time requirement to the one in the member/implementation - /// (Originally from ../FSComp.txt:169) + /// (Originally from ..\FSComp.txt:169) static member typrelSigImplNotCompatibleCompileTimeRequirementsDiffer() = (339, GetStringFunc("typrelSigImplNotCompatibleCompileTimeRequirementsDiffer",",,,") ) /// The signature and implementation are not compatible because the declaration of the type parameter '%s' requires a constraint of the form %s - /// (Originally from ../FSComp.txt:170) + /// (Originally from ..\FSComp.txt:170) static member typrelSigImplNotCompatibleConstraintsDiffer(a0 : System.String, a1 : System.String) = (340, GetStringFunc("typrelSigImplNotCompatibleConstraintsDiffer",",,,%s,,,%s,,,") a0 a1) /// The signature and implementation are not compatible because the type parameter '%s' has a constraint of the form %s but the implementation does not. Either remove this constraint from the signature or add it to the implementation. - /// (Originally from ../FSComp.txt:171) + /// (Originally from ..\FSComp.txt:171) static member typrelSigImplNotCompatibleConstraintsDifferRemove(a0 : System.String, a1 : System.String) = (341, GetStringFunc("typrelSigImplNotCompatibleConstraintsDifferRemove",",,,%s,,,%s,,,") a0 a1) /// The type '%s' implements 'System.IComparable'. Consider also adding an explicit override for 'Object.Equals' - /// (Originally from ../FSComp.txt:172) + /// (Originally from ..\FSComp.txt:172) static member typrelTypeImplementsIComparableShouldOverrideObjectEquals(a0 : System.String) = (342, GetStringFunc("typrelTypeImplementsIComparableShouldOverrideObjectEquals",",,,%s,,,") a0) /// The type '%s' implements 'System.IComparable' explicitly but provides no corresponding override for 'Object.Equals'. An implementation of 'Object.Equals' has been automatically provided, implemented via 'System.IComparable'. Consider implementing the override 'Object.Equals' explicitly - /// (Originally from ../FSComp.txt:173) + /// (Originally from ..\FSComp.txt:173) static member typrelTypeImplementsIComparableDefaultObjectEqualsProvided(a0 : System.String) = (343, GetStringFunc("typrelTypeImplementsIComparableDefaultObjectEqualsProvided",",,,%s,,,") a0) /// The struct, record or union type '%s' has an explicit implementation of 'Object.GetHashCode' or 'Object.Equals'. You must apply the 'CustomEquality' attribute to the type - /// (Originally from ../FSComp.txt:174) + /// (Originally from ..\FSComp.txt:174) static member typrelExplicitImplementationOfGetHashCodeOrEquals(a0 : System.String) = (344, GetStringFunc("typrelExplicitImplementationOfGetHashCodeOrEquals",",,,%s,,,") a0) /// The struct, record or union type '%s' has an explicit implementation of 'Object.GetHashCode'. Consider implementing a matching override for 'Object.Equals(obj)' - /// (Originally from ../FSComp.txt:175) + /// (Originally from ..\FSComp.txt:175) static member typrelExplicitImplementationOfGetHashCode(a0 : System.String) = (345, GetStringFunc("typrelExplicitImplementationOfGetHashCode",",,,%s,,,") a0) /// The struct, record or union type '%s' has an explicit implementation of 'Object.Equals'. Consider implementing a matching override for 'Object.GetHashCode()' - /// (Originally from ../FSComp.txt:176) + /// (Originally from ..\FSComp.txt:176) static member typrelExplicitImplementationOfEquals(a0 : System.String) = (346, GetStringFunc("typrelExplicitImplementationOfEquals",",,,%s,,,") a0) /// The exception definitions are not compatible because a CLI exception mapping is being hidden by a signature. The exception mapping must be visible to other modules. The module contains the exception definition\n %s \nbut its signature specifies\n\t%s - /// (Originally from ../FSComp.txt:177) + /// (Originally from ..\FSComp.txt:177) static member ExceptionDefsNotCompatibleHiddenBySignature(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleHiddenBySignature",",,,%s,,,%s,,,") a0 a1) /// The exception definitions are not compatible because the CLI representations differ. The module contains the exception definition\n %s \nbut its signature specifies\n\t%s - /// (Originally from ../FSComp.txt:178) + /// (Originally from ..\FSComp.txt:178) static member ExceptionDefsNotCompatibleDotNetRepresentationsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleDotNetRepresentationsDiffer",",,,%s,,,%s,,,") a0 a1) /// The exception definitions are not compatible because the exception abbreviation is being hidden by the signature. The abbreviation must be visible to other CLI languages. Consider making the abbreviation visible in the signature. The module contains the exception definition\n %s \nbut its signature specifies\n\t%s. - /// (Originally from ../FSComp.txt:179) + /// (Originally from ..\FSComp.txt:179) static member ExceptionDefsNotCompatibleAbbreviationHiddenBySignature(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleAbbreviationHiddenBySignature",",,,%s,,,%s,,,") a0 a1) /// The exception definitions are not compatible because the exception abbreviations in the signature and implementation differ. The module contains the exception definition\n %s \nbut its signature specifies\n\t%s. - /// (Originally from ../FSComp.txt:180) + /// (Originally from ..\FSComp.txt:180) static member ExceptionDefsNotCompatibleSignaturesDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleSignaturesDiffer",",,,%s,,,%s,,,") a0 a1) /// The exception definitions are not compatible because the exception declarations differ. The module contains the exception definition\n %s \nbut its signature specifies\n\t%s. - /// (Originally from ../FSComp.txt:181) + /// (Originally from ..\FSComp.txt:181) static member ExceptionDefsNotCompatibleExceptionDeclarationsDiffer(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleExceptionDeclarationsDiffer",",,,%s,,,%s,,,") a0 a1) /// The exception definitions are not compatible because the field '%s' was required by the signature but was not specified by the implementation. The module contains the exception definition\n %s \nbut its signature specifies\n\t%s. - /// (Originally from ../FSComp.txt:182) + /// (Originally from ..\FSComp.txt:182) static member ExceptionDefsNotCompatibleFieldInSigButNotImpl(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleFieldInSigButNotImpl",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The exception definitions are not compatible because the field '%s' was present in the implementation but not in the signature. The module contains the exception definition\n %s \nbut its signature specifies\n\t%s. - /// (Originally from ../FSComp.txt:183) + /// (Originally from ..\FSComp.txt:183) static member ExceptionDefsNotCompatibleFieldInImplButNotSig(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleFieldInImplButNotSig",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The exception definitions are not compatible because the order of the fields is different in the signature and implementation. The module contains the exception definition\n %s \nbut its signature specifies\n\t%s. - /// (Originally from ../FSComp.txt:184) + /// (Originally from ..\FSComp.txt:184) static member ExceptionDefsNotCompatibleFieldOrderDiffers(a0 : System.String, a1 : System.String) = (GetStringFunc("ExceptionDefsNotCompatibleFieldOrderDiffers",",,,%s,,,%s,,,") a0 a1) /// The namespace or module attributes differ between signature and implementation - /// (Originally from ../FSComp.txt:185) + /// (Originally from ..\FSComp.txt:185) static member typrelModuleNamespaceAttributesDifferInSigAndImpl() = (355, GetStringFunc("typrelModuleNamespaceAttributesDifferInSigAndImpl",",,,") ) /// This method is over-constrained in its type parameters - /// (Originally from ../FSComp.txt:186) + /// (Originally from ..\FSComp.txt:186) static member typrelMethodIsOverconstrained() = (356, GetStringFunc("typrelMethodIsOverconstrained",",,,") ) /// No implementations of '%s' had the correct number of arguments and type parameters. The required signature is '%s'. - /// (Originally from ../FSComp.txt:187) + /// (Originally from ..\FSComp.txt:187) static member typrelOverloadNotFound(a0 : System.String, a1 : System.String) = (357, GetStringFunc("typrelOverloadNotFound",",,,%s,,,%s,,,") a0 a1) /// The override for '%s' was ambiguous - /// (Originally from ../FSComp.txt:188) + /// (Originally from ..\FSComp.txt:188) static member typrelOverrideWasAmbiguous(a0 : System.String) = (358, GetStringFunc("typrelOverrideWasAmbiguous",",,,%s,,,") a0) /// More than one override implements '%s' - /// (Originally from ../FSComp.txt:189) + /// (Originally from ..\FSComp.txt:189) static member typrelMoreThenOneOverride(a0 : System.String) = (359, GetStringFunc("typrelMoreThenOneOverride",",,,%s,,,") a0) /// The method '%s' is sealed and cannot be overridden - /// (Originally from ../FSComp.txt:190) + /// (Originally from ..\FSComp.txt:190) static member typrelMethodIsSealed(a0 : System.String) = (360, GetStringFunc("typrelMethodIsSealed",",,,%s,,,") a0) /// The override '%s' implements more than one abstract slot, e.g. '%s' and '%s' - /// (Originally from ../FSComp.txt:191) + /// (Originally from ..\FSComp.txt:191) static member typrelOverrideImplementsMoreThenOneSlot(a0 : System.String, a1 : System.String, a2 : System.String) = (361, GetStringFunc("typrelOverrideImplementsMoreThenOneSlot",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Duplicate or redundant interface - /// (Originally from ../FSComp.txt:192) + /// (Originally from ..\FSComp.txt:192) static member typrelDuplicateInterface() = (362, GetStringFunc("typrelDuplicateInterface",",,,") ) /// The interface '%s' is included in multiple explicitly implemented interface types. Add an explicit implementation of this interface. - /// (Originally from ../FSComp.txt:193) + /// (Originally from ..\FSComp.txt:193) static member typrelNeedExplicitImplementation(a0 : System.String) = (363, GetStringFunc("typrelNeedExplicitImplementation",",,,%s,,,") a0) /// A named argument has been assigned more than one value - /// (Originally from ../FSComp.txt:194) + /// (Originally from ..\FSComp.txt:194) static member typrelNamedArgumentHasBeenAssignedMoreThenOnce() = (364, GetStringFunc("typrelNamedArgumentHasBeenAssignedMoreThenOnce",",,,") ) /// No implementation was given for '%s' - /// (Originally from ../FSComp.txt:195) + /// (Originally from ..\FSComp.txt:195) static member typrelNoImplementationGiven(a0 : System.String) = (365, GetStringFunc("typrelNoImplementationGiven",",,,%s,,,") a0) /// No implementation was given for '%s'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'. - /// (Originally from ../FSComp.txt:196) + /// (Originally from ..\FSComp.txt:196) static member typrelNoImplementationGivenWithSuggestion(a0 : System.String) = (366, GetStringFunc("typrelNoImplementationGivenWithSuggestion",",,,%s,,,") a0) /// The member '%s' does not have the correct number of arguments. The required signature is '%s'. - /// (Originally from ../FSComp.txt:197) + /// (Originally from ..\FSComp.txt:197) static member typrelMemberDoesNotHaveCorrectNumberOfArguments(a0 : System.String, a1 : System.String) = (367, GetStringFunc("typrelMemberDoesNotHaveCorrectNumberOfArguments",",,,%s,,,%s,,,") a0 a1) /// The member '%s' does not have the correct number of method type parameters. The required signature is '%s'. - /// (Originally from ../FSComp.txt:198) + /// (Originally from ..\FSComp.txt:198) static member typrelMemberDoesNotHaveCorrectNumberOfTypeParameters(a0 : System.String, a1 : System.String) = (368, GetStringFunc("typrelMemberDoesNotHaveCorrectNumberOfTypeParameters",",,,%s,,,%s,,,") a0 a1) /// The member '%s' does not have the correct kinds of generic parameters. The required signature is '%s'. - /// (Originally from ../FSComp.txt:199) + /// (Originally from ..\FSComp.txt:199) static member typrelMemberDoesNotHaveCorrectKindsOfGenericParameters(a0 : System.String, a1 : System.String) = (369, GetStringFunc("typrelMemberDoesNotHaveCorrectKindsOfGenericParameters",",,,%s,,,%s,,,") a0 a1) /// The member '%s' cannot be used to implement '%s'. The required signature is '%s'. - /// (Originally from ../FSComp.txt:200) + /// (Originally from ..\FSComp.txt:200) static member typrelMemberCannotImplement(a0 : System.String, a1 : System.String, a2 : System.String) = (370, GetStringFunc("typrelMemberCannotImplement",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Error while parsing embedded IL - /// (Originally from ../FSComp.txt:201) + /// (Originally from ..\FSComp.txt:201) static member astParseEmbeddedILError() = (371, GetStringFunc("astParseEmbeddedILError",",,,") ) /// Error while parsing embedded IL type - /// (Originally from ../FSComp.txt:202) + /// (Originally from ..\FSComp.txt:202) static member astParseEmbeddedILTypeError() = (372, GetStringFunc("astParseEmbeddedILTypeError",",,,") ) /// This indexer notation has been removed from the F# language - /// (Originally from ../FSComp.txt:203) + /// (Originally from ..\FSComp.txt:203) static member astDeprecatedIndexerNotation() = (GetStringFunc("astDeprecatedIndexerNotation",",,,") ) /// Invalid expression on left of assignment - /// (Originally from ../FSComp.txt:204) + /// (Originally from ..\FSComp.txt:204) static member astInvalidExprLeftHandOfAssignment() = (374, GetStringFunc("astInvalidExprLeftHandOfAssignment",",,,") ) /// The 'ReferenceEquality' attribute cannot be used on structs. Consider using the 'StructuralEquality' attribute instead, or implement an override for 'System.Object.Equals(obj)'. - /// (Originally from ../FSComp.txt:205) + /// (Originally from ..\FSComp.txt:205) static member augNoRefEqualsOnStruct() = (376, GetStringFunc("augNoRefEqualsOnStruct",",,,") ) /// This type uses an invalid mix of the attributes 'NoEquality', 'ReferenceEquality', 'StructuralEquality', 'NoComparison' and 'StructuralComparison' - /// (Originally from ../FSComp.txt:206) + /// (Originally from ..\FSComp.txt:206) static member augInvalidAttrs() = (377, GetStringFunc("augInvalidAttrs",",,,") ) /// The 'NoEquality' attribute must be used in conjunction with the 'NoComparison' attribute - /// (Originally from ../FSComp.txt:207) + /// (Originally from ..\FSComp.txt:207) static member augNoEqualityNeedsNoComparison() = (378, GetStringFunc("augNoEqualityNeedsNoComparison",",,,") ) /// The 'StructuralComparison' attribute must be used in conjunction with the 'StructuralEquality' attribute - /// (Originally from ../FSComp.txt:208) + /// (Originally from ..\FSComp.txt:208) static member augStructCompNeedsStructEquality() = (379, GetStringFunc("augStructCompNeedsStructEquality",",,,") ) /// The 'StructuralEquality' attribute must be used in conjunction with the 'NoComparison' or 'StructuralComparison' attributes - /// (Originally from ../FSComp.txt:209) + /// (Originally from ..\FSComp.txt:209) static member augStructEqNeedsNoCompOrStructComp() = (380, GetStringFunc("augStructEqNeedsNoCompOrStructComp",",,,") ) /// A type cannot have both the 'ReferenceEquality' and 'StructuralEquality' or 'StructuralComparison' attributes - /// (Originally from ../FSComp.txt:210) + /// (Originally from ..\FSComp.txt:210) static member augTypeCantHaveRefEqAndStructAttrs() = (381, GetStringFunc("augTypeCantHaveRefEqAndStructAttrs",",,,") ) /// Only record, union, exception and struct types may be augmented with the 'ReferenceEquality', 'StructuralEquality' and 'StructuralComparison' attributes - /// (Originally from ../FSComp.txt:211) + /// (Originally from ..\FSComp.txt:211) static member augOnlyCertainTypesCanHaveAttrs() = (382, GetStringFunc("augOnlyCertainTypesCanHaveAttrs",",,,") ) /// A type with attribute 'ReferenceEquality' cannot have an explicit implementation of 'Object.Equals(obj)', 'System.IEquatable<_>' or 'System.Collections.IStructuralEquatable' - /// (Originally from ../FSComp.txt:212) + /// (Originally from ..\FSComp.txt:212) static member augRefEqCantHaveObjEquals() = (383, GetStringFunc("augRefEqCantHaveObjEquals",",,,") ) /// A type with attribute 'CustomEquality' must have an explicit implementation of at least one of 'Object.Equals(obj)', 'System.IEquatable<_>' or 'System.Collections.IStructuralEquatable' - /// (Originally from ../FSComp.txt:213) + /// (Originally from ..\FSComp.txt:213) static member augCustomEqNeedsObjEquals() = (384, GetStringFunc("augCustomEqNeedsObjEquals",",,,") ) /// A type with attribute 'CustomComparison' must have an explicit implementation of at least one of 'System.IComparable' or 'System.Collections.IStructuralComparable' - /// (Originally from ../FSComp.txt:214) + /// (Originally from ..\FSComp.txt:214) static member augCustomCompareNeedsIComp() = (385, GetStringFunc("augCustomCompareNeedsIComp",",,,") ) /// A type with attribute 'NoEquality' should not usually have an explicit implementation of 'Object.Equals(obj)'. Disable this warning if this is intentional for interoperability purposes - /// (Originally from ../FSComp.txt:215) + /// (Originally from ..\FSComp.txt:215) static member augNoEqNeedsNoObjEquals() = (386, GetStringFunc("augNoEqNeedsNoObjEquals",",,,") ) /// A type with attribute 'NoComparison' should not usually have an explicit implementation of 'System.IComparable', 'System.IComparable<_>' or 'System.Collections.IStructuralComparable'. Disable this warning if this is intentional for interoperability purposes - /// (Originally from ../FSComp.txt:216) + /// (Originally from ..\FSComp.txt:216) static member augNoCompCantImpIComp() = (386, GetStringFunc("augNoCompCantImpIComp",",,,") ) /// The 'CustomEquality' attribute must be used in conjunction with the 'NoComparison' or 'CustomComparison' attributes - /// (Originally from ../FSComp.txt:217) + /// (Originally from ..\FSComp.txt:217) static member augCustomEqNeedsNoCompOrCustomComp() = (387, GetStringFunc("augCustomEqNeedsNoCompOrCustomComp",",,,") ) /// Positional specifiers are not permitted in format strings - /// (Originally from ../FSComp.txt:218) + /// (Originally from ..\FSComp.txt:218) static member forPositionalSpecifiersNotPermitted() = (GetStringFunc("forPositionalSpecifiersNotPermitted",",,,") ) /// Missing format specifier - /// (Originally from ../FSComp.txt:219) + /// (Originally from ..\FSComp.txt:219) static member forMissingFormatSpecifier() = (GetStringFunc("forMissingFormatSpecifier",",,,") ) /// '%s' flag set twice - /// (Originally from ../FSComp.txt:220) + /// (Originally from ..\FSComp.txt:220) static member forFlagSetTwice(a0 : System.String) = (GetStringFunc("forFlagSetTwice",",,,%s,,,") a0) /// Prefix flag (' ' or '+') set twice - /// (Originally from ../FSComp.txt:221) + /// (Originally from ..\FSComp.txt:221) static member forPrefixFlagSpacePlusSetTwice() = (GetStringFunc("forPrefixFlagSpacePlusSetTwice",",,,") ) /// The # formatting modifier is invalid in F# - /// (Originally from ../FSComp.txt:222) + /// (Originally from ..\FSComp.txt:222) static member forHashSpecifierIsInvalid() = (GetStringFunc("forHashSpecifierIsInvalid",",,,") ) /// Bad precision in format specifier - /// (Originally from ../FSComp.txt:223) + /// (Originally from ..\FSComp.txt:223) static member forBadPrecision() = (GetStringFunc("forBadPrecision",",,,") ) /// Bad width in format specifier - /// (Originally from ../FSComp.txt:224) + /// (Originally from ..\FSComp.txt:224) static member forBadWidth() = (GetStringFunc("forBadWidth",",,,") ) /// '%s' format does not support '0' flag - /// (Originally from ../FSComp.txt:225) + /// (Originally from ..\FSComp.txt:225) static member forDoesNotSupportZeroFlag(a0 : System.String) = (GetStringFunc("forDoesNotSupportZeroFlag",",,,%s,,,") a0) /// Precision missing after the '.' - /// (Originally from ../FSComp.txt:226) + /// (Originally from ..\FSComp.txt:226) static member forPrecisionMissingAfterDot() = (GetStringFunc("forPrecisionMissingAfterDot",",,,") ) /// '%s' format does not support precision - /// (Originally from ../FSComp.txt:227) + /// (Originally from ..\FSComp.txt:227) static member forFormatDoesntSupportPrecision(a0 : System.String) = (GetStringFunc("forFormatDoesntSupportPrecision",",,,%s,,,") a0) /// Bad format specifier (after l or L): Expected ld,li,lo,lu,lx or lX. In F# code you can use %%d, %%x, %%o or %%u instead, which are overloaded to work with all basic integer types. - /// (Originally from ../FSComp.txt:228) + /// (Originally from ..\FSComp.txt:228) static member forBadFormatSpecifier() = (GetStringFunc("forBadFormatSpecifier",",,,") ) /// The 'l' or 'L' in this format specifier is unnecessary. In F# code you can use %%d, %%x, %%o or %%u instead, which are overloaded to work with all basic integer types. - /// (Originally from ../FSComp.txt:229) + /// (Originally from ..\FSComp.txt:229) static member forLIsUnnecessary() = (GetStringFunc("forLIsUnnecessary",",,,") ) /// The 'h' or 'H' in this format specifier is unnecessary. You can use %%d, %%x, %%o or %%u instead, which are overloaded to work with all basic integer types. - /// (Originally from ../FSComp.txt:230) + /// (Originally from ..\FSComp.txt:230) static member forHIsUnnecessary() = (GetStringFunc("forHIsUnnecessary",",,,") ) /// '%s' does not support prefix '%s' flag - /// (Originally from ../FSComp.txt:231) + /// (Originally from ..\FSComp.txt:231) static member forDoesNotSupportPrefixFlag(a0 : System.String, a1 : System.String) = (GetStringFunc("forDoesNotSupportPrefixFlag",",,,%s,,,%s,,,") a0 a1) /// Bad format specifier: '%s' - /// (Originally from ../FSComp.txt:232) + /// (Originally from ..\FSComp.txt:232) static member forBadFormatSpecifierGeneral(a0 : System.String) = (GetStringFunc("forBadFormatSpecifierGeneral",",,,%s,,,") a0) /// System.Environment.Exit did not exit - /// (Originally from ../FSComp.txt:233) + /// (Originally from ..\FSComp.txt:233) static member elSysEnvExitDidntExit() = (GetStringFunc("elSysEnvExitDidntExit",",,,") ) /// The treatment of this operator is now handled directly by the F# compiler and its meaning cannot be redefined - /// (Originally from ../FSComp.txt:234) + /// (Originally from ..\FSComp.txt:234) static member elDeprecatedOperator() = (GetStringFunc("elDeprecatedOperator",",,,") ) /// A protected member is called or 'base' is being used. This is only allowed in the direct implementation of members since they could escape their object scope. - /// (Originally from ../FSComp.txt:235) + /// (Originally from ..\FSComp.txt:235) static member chkProtectedOrBaseCalled() = (405, GetStringFunc("chkProtectedOrBaseCalled",",,,") ) /// The byref-typed variable '%s' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions. - /// (Originally from ../FSComp.txt:236) + /// (Originally from ..\FSComp.txt:236) static member chkByrefUsedInInvalidWay(a0 : System.String) = (406, GetStringFunc("chkByrefUsedInInvalidWay",",,,%s,,,") a0) /// The 'base' keyword is used in an invalid way. Base calls cannot be used in closures. Consider using a private member to make base calls. - /// (Originally from ../FSComp.txt:237) + /// (Originally from ..\FSComp.txt:237) static member chkBaseUsedInInvalidWay() = (408, GetStringFunc("chkBaseUsedInInvalidWay",",,,") ) /// The variable '%s' is used in an invalid way - /// (Originally from ../FSComp.txt:238) + /// (Originally from ..\FSComp.txt:238) static member chkVariableUsedInInvalidWay(a0 : System.String) = (GetStringFunc("chkVariableUsedInInvalidWay",",,,%s,,,") a0) /// The type '%s' is less accessible than the value, member or type '%s' it is used in. - /// (Originally from ../FSComp.txt:239) + /// (Originally from ..\FSComp.txt:239) static member chkTypeLessAccessibleThanType(a0 : System.String, a1 : System.String) = (410, GetStringFunc("chkTypeLessAccessibleThanType",",,,%s,,,%s,,,") a0 a1) /// 'System.Void' can only be used as 'typeof' in F# - /// (Originally from ../FSComp.txt:240) + /// (Originally from ..\FSComp.txt:240) static member chkSystemVoidOnlyInTypeof() = (411, GetStringFunc("chkSystemVoidOnlyInTypeof",",,,") ) /// A type instantiation involves a byref type. This is not permitted by the rules of Common IL. - /// (Originally from ../FSComp.txt:241) + /// (Originally from ..\FSComp.txt:241) static member chkErrorUseOfByref() = (412, GetStringFunc("chkErrorUseOfByref",",,,") ) /// Calls to 'reraise' may only occur directly in a handler of a try-with - /// (Originally from ../FSComp.txt:242) + /// (Originally from ..\FSComp.txt:242) static member chkErrorContainsCallToRethrow() = (413, GetStringFunc("chkErrorContainsCallToRethrow",",,,") ) /// Expression-splicing operators may only be used within quotations - /// (Originally from ../FSComp.txt:243) + /// (Originally from ..\FSComp.txt:243) static member chkSplicingOnlyInQuotations() = (414, GetStringFunc("chkSplicingOnlyInQuotations",",,,") ) /// First-class uses of the expression-splicing operator are not permitted - /// (Originally from ../FSComp.txt:244) + /// (Originally from ..\FSComp.txt:244) static member chkNoFirstClassSplicing() = (415, GetStringFunc("chkNoFirstClassSplicing",",,,") ) /// First-class uses of the address-of operators are not permitted - /// (Originally from ../FSComp.txt:245) + /// (Originally from ..\FSComp.txt:245) static member chkNoFirstClassAddressOf() = (416, GetStringFunc("chkNoFirstClassAddressOf",",,,") ) /// First-class uses of the 'reraise' function is not permitted - /// (Originally from ../FSComp.txt:246) + /// (Originally from ..\FSComp.txt:246) static member chkNoFirstClassRethrow() = (417, GetStringFunc("chkNoFirstClassRethrow",",,,") ) /// The byref typed value '%s' cannot be used at this point - /// (Originally from ../FSComp.txt:247) + /// (Originally from ..\FSComp.txt:247) static member chkNoByrefAtThisPoint(a0 : System.String) = (418, GetStringFunc("chkNoByrefAtThisPoint",",,,%s,,,") a0) /// 'base' values may only be used to make direct calls to the base implementations of overridden members - /// (Originally from ../FSComp.txt:248) + /// (Originally from ..\FSComp.txt:248) static member chkLimitationsOfBaseKeyword() = (419, GetStringFunc("chkLimitationsOfBaseKeyword",",,,") ) /// Object constructors cannot directly use try/with and try/finally prior to the initialization of the object. This includes constructs such as 'for x in ...' that may elaborate to uses of these constructs. This is a limitation imposed by Common IL. - /// (Originally from ../FSComp.txt:249) + /// (Originally from ..\FSComp.txt:249) static member chkObjCtorsCantUseExceptionHandling() = (420, GetStringFunc("chkObjCtorsCantUseExceptionHandling",",,,") ) /// The address of the variable '%s' cannot be used at this point - /// (Originally from ../FSComp.txt:250) + /// (Originally from ..\FSComp.txt:250) static member chkNoAddressOfAtThisPoint(a0 : System.String) = (421, GetStringFunc("chkNoAddressOfAtThisPoint",",,,%s,,,") a0) /// The address of the static field '%s' cannot be used at this point - /// (Originally from ../FSComp.txt:251) + /// (Originally from ..\FSComp.txt:251) static member chkNoAddressStaticFieldAtThisPoint(a0 : System.String) = (422, GetStringFunc("chkNoAddressStaticFieldAtThisPoint",",,,%s,,,") a0) /// The address of the field '%s' cannot be used at this point - /// (Originally from ../FSComp.txt:252) + /// (Originally from ..\FSComp.txt:252) static member chkNoAddressFieldAtThisPoint(a0 : System.String) = (423, GetStringFunc("chkNoAddressFieldAtThisPoint",",,,%s,,,") a0) /// The address of an array element cannot be used at this point - /// (Originally from ../FSComp.txt:253) + /// (Originally from ..\FSComp.txt:253) static member chkNoAddressOfArrayElementAtThisPoint() = (424, GetStringFunc("chkNoAddressOfArrayElementAtThisPoint",",,,") ) /// The type of a first-class function cannot contain byrefs - /// (Originally from ../FSComp.txt:254) + /// (Originally from ..\FSComp.txt:254) static member chkFirstClassFuncNoByref() = (425, GetStringFunc("chkFirstClassFuncNoByref",",,,") ) /// A method return type would contain byrefs which is not permitted - /// (Originally from ../FSComp.txt:255) + /// (Originally from ..\FSComp.txt:255) static member chkReturnTypeNoByref() = (426, GetStringFunc("chkReturnTypeNoByref",",,,") ) /// Invalid custom attribute value (not a constant or literal) - /// (Originally from ../FSComp.txt:256) + /// (Originally from ..\FSComp.txt:256) static member chkInvalidCustAttrVal() = (428, GetStringFunc("chkInvalidCustAttrVal",",,,") ) /// The attribute type '%s' has 'AllowMultiple=false'. Multiple instances of this attribute cannot be attached to a single language element. - /// (Originally from ../FSComp.txt:257) + /// (Originally from ..\FSComp.txt:257) static member chkAttrHasAllowMultiFalse(a0 : System.String) = (429, GetStringFunc("chkAttrHasAllowMultiFalse",",,,%s,,,") a0) /// The member '%s' is used in an invalid way. A use of '%s' has been inferred prior to its definition at or near '%s'. This is an invalid forward reference. - /// (Originally from ../FSComp.txt:258) + /// (Originally from ..\FSComp.txt:258) static member chkMemberUsedInInvalidWay(a0 : System.String, a1 : System.String, a2 : System.String) = (430, GetStringFunc("chkMemberUsedInInvalidWay",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// A byref typed value would be stored here. Top-level let-bound byref values are not permitted. - /// (Originally from ../FSComp.txt:259) + /// (Originally from ..\FSComp.txt:259) static member chkNoByrefAsTopValue() = (431, GetStringFunc("chkNoByrefAsTopValue",",,,") ) /// [] terms cannot contain uses of the prefix splice operator '%%' - /// (Originally from ../FSComp.txt:260) + /// (Originally from ..\FSComp.txt:260) static member chkReflectedDefCantSplice() = (432, GetStringFunc("chkReflectedDefCantSplice",",,,") ) /// A function labeled with the 'EntryPointAttribute' attribute must be the last declaration in the last file in the compilation sequence. - /// (Originally from ../FSComp.txt:261) + /// (Originally from ..\FSComp.txt:261) static member chkEntryPointUsage() = (433, GetStringFunc("chkEntryPointUsage",",,,") ) /// compiled form of the union case - /// (Originally from ../FSComp.txt:262) + /// (Originally from ..\FSComp.txt:262) static member chkUnionCaseCompiledForm() = (GetStringFunc("chkUnionCaseCompiledForm",",,,") ) /// default augmentation of the union case - /// (Originally from ../FSComp.txt:263) + /// (Originally from ..\FSComp.txt:263) static member chkUnionCaseDefaultAugmentation() = (GetStringFunc("chkUnionCaseDefaultAugmentation",",,,") ) /// The property '%s' has the same name as a method in type '%s'. - /// (Originally from ../FSComp.txt:264) + /// (Originally from ..\FSComp.txt:264) static member chkPropertySameNameMethod(a0 : System.String, a1 : System.String) = (434, GetStringFunc("chkPropertySameNameMethod",",,,%s,,,%s,,,") a0 a1) /// The property '%s' of type '%s' has a getter and a setter that do not match. If one is abstract then the other must be as well. - /// (Originally from ../FSComp.txt:265) + /// (Originally from ..\FSComp.txt:265) static member chkGetterSetterDoNotMatchAbstract(a0 : System.String, a1 : System.String) = (435, GetStringFunc("chkGetterSetterDoNotMatchAbstract",",,,%s,,,%s,,,") a0 a1) /// The property '%s' has the same name as another property in type '%s', but one takes indexer arguments and the other does not. You may be missing an indexer argument to one of your properties. - /// (Originally from ../FSComp.txt:266) + /// (Originally from ..\FSComp.txt:266) static member chkPropertySameNameIndexer(a0 : System.String, a1 : System.String) = (436, GetStringFunc("chkPropertySameNameIndexer",",,,%s,,,%s,,,") a0 a1) /// A type would store a byref typed value. This is not permitted by Common IL. - /// (Originally from ../FSComp.txt:267) + /// (Originally from ..\FSComp.txt:267) static member chkCantStoreByrefValue() = (437, GetStringFunc("chkCantStoreByrefValue",",,,") ) /// Duplicate method. The method '%s' has the same name and signature as another method in type '%s'. - /// (Originally from ../FSComp.txt:269) + /// (Originally from ..\FSComp.txt:269) static member chkDuplicateMethod(a0 : System.String, a1 : System.String) = (438, GetStringFunc("chkDuplicateMethod",",,,%s,,,%s,,,") a0 a1) /// Duplicate method. The method '%s' has the same name and signature as another method in type '%s' once tuples, functions, units of measure and/or provided types are erased. - /// (Originally from ../FSComp.txt:270) + /// (Originally from ..\FSComp.txt:270) static member chkDuplicateMethodWithSuffix(a0 : System.String, a1 : System.String) = (438, GetStringFunc("chkDuplicateMethodWithSuffix",",,,%s,,,%s,,,") a0 a1) /// The method '%s' has curried arguments but has the same name as another method in type '%s'. Methods with curried arguments cannot be overloaded. Consider using a method taking tupled arguments. - /// (Originally from ../FSComp.txt:271) + /// (Originally from ..\FSComp.txt:271) static member chkDuplicateMethodCurried(a0 : System.String, a1 : System.String) = (439, GetStringFunc("chkDuplicateMethodCurried",",,,%s,,,%s,,,") a0 a1) /// Methods with curried arguments cannot declare 'out', 'ParamArray', 'optional', 'ReflectedDefinition', 'byref', 'CallerLineNumber', 'CallerMemberName', or 'CallerFilePath' arguments - /// (Originally from ../FSComp.txt:272) + /// (Originally from ..\FSComp.txt:272) static member chkCurriedMethodsCantHaveOutParams() = (440, GetStringFunc("chkCurriedMethodsCantHaveOutParams",",,,") ) /// Duplicate property. The property '%s' has the same name and signature as another property in type '%s'. - /// (Originally from ../FSComp.txt:273) + /// (Originally from ..\FSComp.txt:273) static member chkDuplicateProperty(a0 : System.String, a1 : System.String) = (441, GetStringFunc("chkDuplicateProperty",",,,%s,,,%s,,,") a0 a1) /// Duplicate property. The property '%s' has the same name and signature as another property in type '%s' once tuples, functions, units of measure and/or provided types are erased. - /// (Originally from ../FSComp.txt:274) + /// (Originally from ..\FSComp.txt:274) static member chkDuplicatePropertyWithSuffix(a0 : System.String, a1 : System.String) = (441, GetStringFunc("chkDuplicatePropertyWithSuffix",",,,%s,,,%s,,,") a0 a1) /// Duplicate method. The abstract method '%s' has the same name and signature as an abstract method in an inherited type. - /// (Originally from ../FSComp.txt:275) + /// (Originally from ..\FSComp.txt:275) static member chkDuplicateMethodInheritedType(a0 : System.String) = (442, GetStringFunc("chkDuplicateMethodInheritedType",",,,%s,,,") a0) /// Duplicate method. The abstract method '%s' has the same name and signature as an abstract method in an inherited type once tuples, functions, units of measure and/or provided types are erased. - /// (Originally from ../FSComp.txt:276) + /// (Originally from ..\FSComp.txt:276) static member chkDuplicateMethodInheritedTypeWithSuffix(a0 : System.String) = (442, GetStringFunc("chkDuplicateMethodInheritedTypeWithSuffix",",,,%s,,,") a0) /// This type implements the same interface at different generic instantiations '%s' and '%s'. This is not permitted in this version of F#. - /// (Originally from ../FSComp.txt:277) + /// (Originally from ..\FSComp.txt:277) static member chkMultipleGenericInterfaceInstantiations(a0 : System.String, a1 : System.String) = (443, GetStringFunc("chkMultipleGenericInterfaceInstantiations",",,,%s,,,%s,,,") a0 a1) /// The type of a field using the 'DefaultValue' attribute must admit default initialization, i.e. have 'null' as a proper value or be a struct type whose fields all admit default initialization. You can use 'DefaultValue(false)' to disable this check - /// (Originally from ../FSComp.txt:278) + /// (Originally from ..\FSComp.txt:278) static member chkValueWithDefaultValueMustHaveDefaultValue() = (444, GetStringFunc("chkValueWithDefaultValueMustHaveDefaultValue",",,,") ) /// The type abbreviation contains byrefs. This is not permitted by F#. - /// (Originally from ../FSComp.txt:279) + /// (Originally from ..\FSComp.txt:279) static member chkNoByrefInTypeAbbrev() = (445, GetStringFunc("chkNoByrefInTypeAbbrev",",,,") ) /// The variable '%s' is bound in a quotation but is used as part of a spliced expression. This is not permitted since it may escape its scope. - /// (Originally from ../FSComp.txt:280) + /// (Originally from ..\FSComp.txt:280) static member crefBoundVarUsedInSplice(a0 : System.String) = (446, GetStringFunc("crefBoundVarUsedInSplice",",,,%s,,,") a0) /// Quotations cannot contain uses of generic expressions - /// (Originally from ../FSComp.txt:281) + /// (Originally from ..\FSComp.txt:281) static member crefQuotationsCantContainGenericExprs() = (447, GetStringFunc("crefQuotationsCantContainGenericExprs",",,,") ) /// Quotations cannot contain function definitions that are inferred or declared to be generic. Consider adding some type constraints to make this a valid quoted expression. - /// (Originally from ../FSComp.txt:282) + /// (Originally from ..\FSComp.txt:282) static member crefQuotationsCantContainGenericFunctions() = (448, GetStringFunc("crefQuotationsCantContainGenericFunctions",",,,") ) /// Quotations cannot contain object expressions - /// (Originally from ../FSComp.txt:283) + /// (Originally from ..\FSComp.txt:283) static member crefQuotationsCantContainObjExprs() = (449, GetStringFunc("crefQuotationsCantContainObjExprs",",,,") ) /// Quotations cannot contain expressions that take the address of a field - /// (Originally from ../FSComp.txt:284) + /// (Originally from ..\FSComp.txt:284) static member crefQuotationsCantContainAddressOf() = (450, GetStringFunc("crefQuotationsCantContainAddressOf",",,,") ) /// Quotations cannot contain expressions that fetch static fields - /// (Originally from ../FSComp.txt:285) + /// (Originally from ..\FSComp.txt:285) static member crefQuotationsCantContainStaticFieldRef() = (451, GetStringFunc("crefQuotationsCantContainStaticFieldRef",",,,") ) /// Quotations cannot contain inline assembly code or pattern matching on arrays - /// (Originally from ../FSComp.txt:286) + /// (Originally from ..\FSComp.txt:286) static member crefQuotationsCantContainInlineIL() = (452, GetStringFunc("crefQuotationsCantContainInlineIL",",,,") ) /// Quotations cannot contain descending for loops - /// (Originally from ../FSComp.txt:287) + /// (Originally from ..\FSComp.txt:287) static member crefQuotationsCantContainDescendingForLoops() = (453, GetStringFunc("crefQuotationsCantContainDescendingForLoops",",,,") ) /// Quotations cannot contain expressions that fetch union case indexes - /// (Originally from ../FSComp.txt:288) + /// (Originally from ..\FSComp.txt:288) static member crefQuotationsCantFetchUnionIndexes() = (454, GetStringFunc("crefQuotationsCantFetchUnionIndexes",",,,") ) /// Quotations cannot contain expressions that set union case fields - /// (Originally from ../FSComp.txt:289) + /// (Originally from ..\FSComp.txt:289) static member crefQuotationsCantSetUnionFields() = (455, GetStringFunc("crefQuotationsCantSetUnionFields",",,,") ) /// Quotations cannot contain expressions that set fields in exception values - /// (Originally from ../FSComp.txt:290) + /// (Originally from ..\FSComp.txt:290) static member crefQuotationsCantSetExceptionFields() = (456, GetStringFunc("crefQuotationsCantSetExceptionFields",",,,") ) /// Quotations cannot contain expressions that require byref pointers - /// (Originally from ../FSComp.txt:291) + /// (Originally from ..\FSComp.txt:291) static member crefQuotationsCantRequireByref() = (457, GetStringFunc("crefQuotationsCantRequireByref",",,,") ) /// Quotations cannot contain expressions that make member constraint calls, or uses of operators that implicitly resolve to a member constraint call - /// (Originally from ../FSComp.txt:292) + /// (Originally from ..\FSComp.txt:292) static member crefQuotationsCantCallTraitMembers() = (458, GetStringFunc("crefQuotationsCantCallTraitMembers",",,,") ) /// Quotations cannot contain this kind of constant - /// (Originally from ../FSComp.txt:293) + /// (Originally from ..\FSComp.txt:293) static member crefQuotationsCantContainThisConstant() = (459, GetStringFunc("crefQuotationsCantContainThisConstant",",,,") ) /// Quotations cannot contain this kind of pattern match - /// (Originally from ../FSComp.txt:294) + /// (Originally from ..\FSComp.txt:294) static member crefQuotationsCantContainThisPatternMatch() = (460, GetStringFunc("crefQuotationsCantContainThisPatternMatch",",,,") ) /// Quotations cannot contain array pattern matching - /// (Originally from ../FSComp.txt:295) + /// (Originally from ..\FSComp.txt:295) static member crefQuotationsCantContainArrayPatternMatching() = (461, GetStringFunc("crefQuotationsCantContainArrayPatternMatching",",,,") ) /// Quotations cannot contain this kind of type - /// (Originally from ../FSComp.txt:296) + /// (Originally from ..\FSComp.txt:296) static member crefQuotationsCantContainThisType() = (462, GetStringFunc("crefQuotationsCantContainThisType",",,,") ) /// The declared type parameter '%s' cannot be used here since the type parameter cannot be resolved at compile time - /// (Originally from ../FSComp.txt:297) + /// (Originally from ..\FSComp.txt:297) static member csTypeCannotBeResolvedAtCompileTime(a0 : System.String) = (GetStringFunc("csTypeCannotBeResolvedAtCompileTime",",,,%s,,,") a0) /// This code is less generic than indicated by its annotations. A unit-of-measure specified using '_' has been determined to be '1', i.e. dimensionless. Consider making the code generic, or removing the use of '_'. - /// (Originally from ../FSComp.txt:298) + /// (Originally from ..\FSComp.txt:298) static member csCodeLessGeneric() = (464, GetStringFunc("csCodeLessGeneric",",,,") ) /// Type inference problem too complicated (maximum iteration depth reached). Consider adding further type annotations. - /// (Originally from ../FSComp.txt:299) + /// (Originally from ..\FSComp.txt:299) static member csTypeInferenceMaxDepth() = (465, GetStringFunc("csTypeInferenceMaxDepth",",,,") ) /// Expected arguments to an instance member - /// (Originally from ../FSComp.txt:300) + /// (Originally from ..\FSComp.txt:300) static member csExpectedArguments() = (GetStringFunc("csExpectedArguments",",,,") ) /// This indexer expects %d arguments but is here given %d - /// (Originally from ../FSComp.txt:301) + /// (Originally from ..\FSComp.txt:301) static member csIndexArgumentMismatch(a0 : System.Int32, a1 : System.Int32) = (GetStringFunc("csIndexArgumentMismatch",",,,%d,,,%d,,,") a0 a1) /// Expecting a type supporting the operator '%s' but given a function type. You may be missing an argument to a function. - /// (Originally from ../FSComp.txt:302) + /// (Originally from ..\FSComp.txt:302) static member csExpectTypeWithOperatorButGivenFunction(a0 : System.String) = (GetStringFunc("csExpectTypeWithOperatorButGivenFunction",",,,%s,,,") a0) /// Expecting a type supporting the operator '%s' but given a tuple type - /// (Originally from ../FSComp.txt:303) + /// (Originally from ..\FSComp.txt:303) static member csExpectTypeWithOperatorButGivenTuple(a0 : System.String) = (GetStringFunc("csExpectTypeWithOperatorButGivenTuple",",,,%s,,,") a0) /// None of the types '%s' support the operator '%s' - /// (Originally from ../FSComp.txt:304) + /// (Originally from ..\FSComp.txt:304) static member csTypesDoNotSupportOperator(a0 : System.String, a1 : System.String) = (GetStringFunc("csTypesDoNotSupportOperator",",,,%s,,,%s,,,") a0 a1) /// The type '%s' does not support the operator '%s' - /// (Originally from ../FSComp.txt:305) + /// (Originally from ..\FSComp.txt:305) static member csTypeDoesNotSupportOperator(a0 : System.String, a1 : System.String) = (GetStringFunc("csTypeDoesNotSupportOperator",",,,%s,,,%s,,,") a0 a1) /// None of the types '%s' support the operator '%s'. Consider opening the module 'Microsoft.FSharp.Linq.NullableOperators'. - /// (Originally from ../FSComp.txt:306) + /// (Originally from ..\FSComp.txt:306) static member csTypesDoNotSupportOperatorNullable(a0 : System.String, a1 : System.String) = (GetStringFunc("csTypesDoNotSupportOperatorNullable",",,,%s,,,%s,,,") a0 a1) /// The type '%s' does not support the operator '%s'. Consider opening the module 'Microsoft.FSharp.Linq.NullableOperators'. - /// (Originally from ../FSComp.txt:307) + /// (Originally from ..\FSComp.txt:307) static member csTypeDoesNotSupportOperatorNullable(a0 : System.String, a1 : System.String) = (GetStringFunc("csTypeDoesNotSupportOperatorNullable",",,,%s,,,%s,,,") a0 a1) /// The type '%s' does not support a conversion to the type '%s' - /// (Originally from ../FSComp.txt:308) + /// (Originally from ..\FSComp.txt:308) static member csTypeDoesNotSupportConversion(a0 : System.String, a1 : System.String) = (GetStringFunc("csTypeDoesNotSupportConversion",",,,%s,,,%s,,,") a0 a1) /// The type '%s' has a method '%s' (full name '%s'), but the method is static - /// (Originally from ../FSComp.txt:309) + /// (Originally from ..\FSComp.txt:309) static member csMethodFoundButIsStatic(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("csMethodFoundButIsStatic",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The type '%s' has a method '%s' (full name '%s'), but the method is not static - /// (Originally from ../FSComp.txt:310) + /// (Originally from ..\FSComp.txt:310) static member csMethodFoundButIsNotStatic(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("csMethodFoundButIsNotStatic",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The constraints 'struct' and 'not struct' are inconsistent - /// (Originally from ../FSComp.txt:311) + /// (Originally from ..\FSComp.txt:311) static member csStructConstraintInconsistent() = (472, GetStringFunc("csStructConstraintInconsistent",",,,") ) /// The type '%s' does not have 'null' as a proper value - /// (Originally from ../FSComp.txt:312) + /// (Originally from ..\FSComp.txt:312) static member csTypeDoesNotHaveNull(a0 : System.String) = (GetStringFunc("csTypeDoesNotHaveNull",",,,%s,,,") a0) /// The type '%s' does not have 'null' as a proper value. To create a null value for a Nullable type use 'System.Nullable()'. - /// (Originally from ../FSComp.txt:313) + /// (Originally from ..\FSComp.txt:313) static member csNullableTypeDoesNotHaveNull(a0 : System.String) = (GetStringFunc("csNullableTypeDoesNotHaveNull",",,,%s,,,") a0) /// The type '%s' does not support the 'comparison' constraint because it has the 'NoComparison' attribute - /// (Originally from ../FSComp.txt:314) + /// (Originally from ..\FSComp.txt:314) static member csTypeDoesNotSupportComparison1(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportComparison1",",,,%s,,,") a0) /// The type '%s' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface - /// (Originally from ../FSComp.txt:315) + /// (Originally from ..\FSComp.txt:315) static member csTypeDoesNotSupportComparison2(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportComparison2",",,,%s,,,") a0) /// The type '%s' does not support the 'comparison' constraint because it is a record, union or struct with one or more structural element types which do not support the 'comparison' constraint. Either avoid the use of comparison with this type, or add the 'StructuralComparison' attribute to the type to determine which field type does not support comparison - /// (Originally from ../FSComp.txt:316) + /// (Originally from ..\FSComp.txt:316) static member csTypeDoesNotSupportComparison3(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportComparison3",",,,%s,,,") a0) /// The type '%s' does not support the 'equality' constraint because it has the 'NoEquality' attribute - /// (Originally from ../FSComp.txt:317) + /// (Originally from ..\FSComp.txt:317) static member csTypeDoesNotSupportEquality1(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportEquality1",",,,%s,,,") a0) /// The type '%s' does not support the 'equality' constraint because it is a function type - /// (Originally from ../FSComp.txt:318) + /// (Originally from ..\FSComp.txt:318) static member csTypeDoesNotSupportEquality2(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportEquality2",",,,%s,,,") a0) /// The type '%s' does not support the 'equality' constraint because it is a record, union or struct with one or more structural element types which do not support the 'equality' constraint. Either avoid the use of equality with this type, or add the 'StructuralEquality' attribute to the type to determine which field type does not support equality - /// (Originally from ../FSComp.txt:319) + /// (Originally from ..\FSComp.txt:319) static member csTypeDoesNotSupportEquality3(a0 : System.String) = (GetStringFunc("csTypeDoesNotSupportEquality3",",,,%s,,,") a0) /// The type '%s' is not a CLI enum type - /// (Originally from ../FSComp.txt:320) + /// (Originally from ..\FSComp.txt:320) static member csTypeIsNotEnumType(a0 : System.String) = (GetStringFunc("csTypeIsNotEnumType",",,,%s,,,") a0) /// The type '%s' has a non-standard delegate type - /// (Originally from ../FSComp.txt:321) + /// (Originally from ..\FSComp.txt:321) static member csTypeHasNonStandardDelegateType(a0 : System.String) = (GetStringFunc("csTypeHasNonStandardDelegateType",",,,%s,,,") a0) /// The type '%s' is not a CLI delegate type - /// (Originally from ../FSComp.txt:322) + /// (Originally from ..\FSComp.txt:322) static member csTypeIsNotDelegateType(a0 : System.String) = (GetStringFunc("csTypeIsNotDelegateType",",,,%s,,,") a0) /// This type parameter cannot be instantiated to 'Nullable'. This is a restriction imposed in order to ensure the meaning of 'null' in some CLI languages is not confusing when used in conjunction with 'Nullable' values. - /// (Originally from ../FSComp.txt:323) + /// (Originally from ..\FSComp.txt:323) static member csTypeParameterCannotBeNullable() = (GetStringFunc("csTypeParameterCannotBeNullable",",,,") ) /// A generic construct requires that the type '%s' is a CLI or F# struct type - /// (Originally from ../FSComp.txt:324) + /// (Originally from ..\FSComp.txt:324) static member csGenericConstructRequiresStructType(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresStructType",",,,%s,,,") a0) /// A generic construct requires that the type '%s' is an unmanaged type - /// (Originally from ../FSComp.txt:325) + /// (Originally from ..\FSComp.txt:325) static member csGenericConstructRequiresUnmanagedType(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresUnmanagedType",",,,%s,,,") a0) /// The type '%s' is not compatible with any of the types %s, arising from the use of a printf-style format string - /// (Originally from ../FSComp.txt:326) + /// (Originally from ..\FSComp.txt:326) static member csTypeNotCompatibleBecauseOfPrintf(a0 : System.String, a1 : System.String) = (GetStringFunc("csTypeNotCompatibleBecauseOfPrintf",",,,%s,,,%s,,,") a0 a1) /// A generic construct requires that the type '%s' have reference semantics, but it does not, i.e. it is a struct - /// (Originally from ../FSComp.txt:327) + /// (Originally from ..\FSComp.txt:327) static member csGenericConstructRequiresReferenceSemantics(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresReferenceSemantics",",,,%s,,,") a0) /// A generic construct requires that the type '%s' be non-abstract - /// (Originally from ../FSComp.txt:328) + /// (Originally from ..\FSComp.txt:328) static member csGenericConstructRequiresNonAbstract(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresNonAbstract",",,,%s,,,") a0) /// A generic construct requires that the type '%s' have a public default constructor - /// (Originally from ../FSComp.txt:329) + /// (Originally from ..\FSComp.txt:329) static member csGenericConstructRequiresPublicDefaultConstructor(a0 : System.String) = (GetStringFunc("csGenericConstructRequiresPublicDefaultConstructor",",,,%s,,,") a0) /// Type instantiation length mismatch - /// (Originally from ../FSComp.txt:330) + /// (Originally from ..\FSComp.txt:330) static member csTypeInstantiationLengthMismatch() = (483, GetStringFunc("csTypeInstantiationLengthMismatch",",,,") ) /// Optional arguments not permitted here - /// (Originally from ../FSComp.txt:331) + /// (Originally from ..\FSComp.txt:331) static member csOptionalArgumentNotPermittedHere() = (484, GetStringFunc("csOptionalArgumentNotPermittedHere",",,,") ) /// %s is not a static member - /// (Originally from ../FSComp.txt:332) + /// (Originally from ..\FSComp.txt:332) static member csMemberIsNotStatic(a0 : System.String) = (485, GetStringFunc("csMemberIsNotStatic",",,,%s,,,") a0) /// %s is not an instance member - /// (Originally from ../FSComp.txt:333) + /// (Originally from ..\FSComp.txt:333) static member csMemberIsNotInstance(a0 : System.String) = (486, GetStringFunc("csMemberIsNotInstance",",,,%s,,,") a0) /// Argument length mismatch - /// (Originally from ../FSComp.txt:334) + /// (Originally from ..\FSComp.txt:334) static member csArgumentLengthMismatch() = (487, GetStringFunc("csArgumentLengthMismatch",",,,") ) /// The argument types don't match - /// (Originally from ../FSComp.txt:335) + /// (Originally from ..\FSComp.txt:335) static member csArgumentTypesDoNotMatch() = (488, GetStringFunc("csArgumentTypesDoNotMatch",",,,") ) /// This method expects a CLI 'params' parameter in this position. 'params' is a way of passing a variable number of arguments to a method in languages such as C#. Consider passing an array for this argument - /// (Originally from ../FSComp.txt:336) + /// (Originally from ..\FSComp.txt:336) static member csMethodExpectsParams() = (489, GetStringFunc("csMethodExpectsParams",",,,") ) /// The member or object constructor '%s' is not %s - /// (Originally from ../FSComp.txt:337) + /// (Originally from ..\FSComp.txt:337) static member csMemberIsNotAccessible(a0 : System.String, a1 : System.String) = (490, GetStringFunc("csMemberIsNotAccessible",",,,%s,,,%s,,,") a0 a1) /// The member or object constructor '%s' is not %s. Private members may only be accessed from within the declaring type. Protected members may only be accessed from an extending type and cannot be accessed from inner lambda expressions. - /// (Originally from ../FSComp.txt:338) + /// (Originally from ..\FSComp.txt:338) static member csMemberIsNotAccessible2(a0 : System.String, a1 : System.String) = (491, GetStringFunc("csMemberIsNotAccessible2",",,,%s,,,%s,,,") a0 a1) /// %s is not a static method - /// (Originally from ../FSComp.txt:339) + /// (Originally from ..\FSComp.txt:339) static member csMethodIsNotAStaticMethod(a0 : System.String) = (492, GetStringFunc("csMethodIsNotAStaticMethod",",,,%s,,,") a0) /// %s is not an instance method - /// (Originally from ../FSComp.txt:340) + /// (Originally from ..\FSComp.txt:340) static member csMethodIsNotAnInstanceMethod(a0 : System.String) = (493, GetStringFunc("csMethodIsNotAnInstanceMethod",",,,%s,,,") a0) /// The member or object constructor '%s' has no argument or settable return property '%s'. %s. - /// (Originally from ../FSComp.txt:341) + /// (Originally from ..\FSComp.txt:341) static member csMemberHasNoArgumentOrReturnProperty(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("csMemberHasNoArgumentOrReturnProperty",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The object constructor '%s' has no argument or settable return property '%s'. %s. - /// (Originally from ../FSComp.txt:342) + /// (Originally from ..\FSComp.txt:342) static member csCtorHasNoArgumentOrReturnProperty(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("csCtorHasNoArgumentOrReturnProperty",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The required signature is %s - /// (Originally from ../FSComp.txt:343) + /// (Originally from ..\FSComp.txt:343) static member csRequiredSignatureIs(a0 : System.String) = (495, GetStringFunc("csRequiredSignatureIs",",,,%s,,,") a0) /// The member or object constructor '%s' requires %d argument(s). The required signature is '%s'. - /// (Originally from ../FSComp.txt:344) + /// (Originally from ..\FSComp.txt:344) static member csMemberSignatureMismatch(a0 : System.String, a1 : System.Int32, a2 : System.String) = (496, GetStringFunc("csMemberSignatureMismatch",",,,%s,,,%d,,,%s,,,") a0 a1 a2) /// The member or object constructor '%s' requires %d additional argument(s). The required signature is '%s'. - /// (Originally from ../FSComp.txt:345) + /// (Originally from ..\FSComp.txt:345) static member csMemberSignatureMismatch2(a0 : System.String, a1 : System.Int32, a2 : System.String) = (497, GetStringFunc("csMemberSignatureMismatch2",",,,%s,,,%d,,,%s,,,") a0 a1 a2) /// The member or object constructor '%s' requires %d argument(s). The required signature is '%s'. Some names for missing arguments are %s. - /// (Originally from ../FSComp.txt:346) + /// (Originally from ..\FSComp.txt:346) static member csMemberSignatureMismatch3(a0 : System.String, a1 : System.Int32, a2 : System.String, a3 : System.String) = (498, GetStringFunc("csMemberSignatureMismatch3",",,,%s,,,%d,,,%s,,,%s,,,") a0 a1 a2 a3) /// The member or object constructor '%s' requires %d additional argument(s). The required signature is '%s'. Some names for missing arguments are %s. - /// (Originally from ../FSComp.txt:347) + /// (Originally from ..\FSComp.txt:347) static member csMemberSignatureMismatch4(a0 : System.String, a1 : System.Int32, a2 : System.String, a3 : System.String) = (499, GetStringFunc("csMemberSignatureMismatch4",",,,%s,,,%d,,,%s,,,%s,,,") a0 a1 a2 a3) /// The member or object constructor '%s' requires %d argument(s) but is here given %d unnamed and %d named argument(s). The required signature is '%s'. - /// (Originally from ../FSComp.txt:348) + /// (Originally from ..\FSComp.txt:348) static member csMemberSignatureMismatchArityNamed(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.Int32, a4 : System.String) = (500, GetStringFunc("csMemberSignatureMismatchArityNamed",",,,%s,,,%d,,,%d,,,%d,,,%s,,,") a0 a1 a2 a3 a4) /// The member or object constructor '%s' takes %d argument(s) but is here given %d. The required signature is '%s'. - /// (Originally from ../FSComp.txt:349) + /// (Originally from ..\FSComp.txt:349) static member csMemberSignatureMismatchArity(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.String) = (501, GetStringFunc("csMemberSignatureMismatchArity",",,,%s,,,%d,,,%d,,,%s,,,") a0 a1 a2 a3) /// The object constructor '%s' takes %d argument(s) but is here given %d. The required signature is '%s'. - /// (Originally from ../FSComp.txt:350) + /// (Originally from ..\FSComp.txt:350) static member csCtorSignatureMismatchArity(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.String) = (501, GetStringFunc("csCtorSignatureMismatchArity",",,,%s,,,%d,,,%d,,,%s,,,") a0 a1 a2 a3) /// The object constructor '%s' takes %d argument(s) but is here given %d. The required signature is '%s'. If some of the arguments are meant to assign values to properties, consider separating those arguments with a comma (','). - /// (Originally from ../FSComp.txt:351) + /// (Originally from ..\FSComp.txt:351) static member csCtorSignatureMismatchArityProp(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.String) = (501, GetStringFunc("csCtorSignatureMismatchArityProp",",,,%s,,,%d,,,%d,,,%s,,,") a0 a1 a2 a3) /// The member or object constructor '%s' takes %d type argument(s) but is here given %d. The required signature is '%s'. - /// (Originally from ../FSComp.txt:352) + /// (Originally from ..\FSComp.txt:352) static member csMemberSignatureMismatchArityType(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.String) = (502, GetStringFunc("csMemberSignatureMismatchArityType",",,,%s,,,%d,,,%d,,,%s,,,") a0 a1 a2 a3) /// A member or object constructor '%s' taking %d arguments is not accessible from this code location. All accessible versions of method '%s' take %d arguments. - /// (Originally from ../FSComp.txt:353) + /// (Originally from ..\FSComp.txt:353) static member csMemberNotAccessible(a0 : System.String, a1 : System.Int32, a2 : System.String, a3 : System.Int32) = (503, GetStringFunc("csMemberNotAccessible",",,,%s,,,%d,,,%s,,,%d,,,") a0 a1 a2 a3) /// Incorrect generic instantiation. No %s member named '%s' takes %d generic arguments. - /// (Originally from ../FSComp.txt:354) + /// (Originally from ..\FSComp.txt:354) static member csIncorrectGenericInstantiation(a0 : System.String, a1 : System.String, a2 : System.Int32) = (504, GetStringFunc("csIncorrectGenericInstantiation",",,,%s,,,%s,,,%d,,,") a0 a1 a2) /// The member or object constructor '%s' does not take %d argument(s). An overload was found taking %d arguments. - /// (Originally from ../FSComp.txt:355) + /// (Originally from ..\FSComp.txt:355) static member csMemberOverloadArityMismatch(a0 : System.String, a1 : System.Int32, a2 : System.Int32) = (505, GetStringFunc("csMemberOverloadArityMismatch",",,,%s,,,%d,,,%d,,,") a0 a1 a2) /// No %s member or object constructor named '%s' takes %d arguments - /// (Originally from ../FSComp.txt:356) + /// (Originally from ..\FSComp.txt:356) static member csNoMemberTakesTheseArguments(a0 : System.String, a1 : System.String, a2 : System.Int32) = (506, GetStringFunc("csNoMemberTakesTheseArguments",",,,%s,,,%s,,,%d,,,") a0 a1 a2) /// No %s member or object constructor named '%s' takes %d arguments. Note the call to this member also provides %d named arguments. - /// (Originally from ../FSComp.txt:357) + /// (Originally from ..\FSComp.txt:357) static member csNoMemberTakesTheseArguments2(a0 : System.String, a1 : System.String, a2 : System.Int32, a3 : System.Int32) = (507, GetStringFunc("csNoMemberTakesTheseArguments2",",,,%s,,,%s,,,%d,,,%d,,,") a0 a1 a2 a3) /// No %s member or object constructor named '%s' takes %d arguments. The named argument '%s' doesn't correspond to any argument or settable return property for any overload. - /// (Originally from ../FSComp.txt:358) + /// (Originally from ..\FSComp.txt:358) static member csNoMemberTakesTheseArguments3(a0 : System.String, a1 : System.String, a2 : System.Int32, a3 : System.String) = (508, GetStringFunc("csNoMemberTakesTheseArguments3",",,,%s,,,%s,,,%d,,,%s,,,") a0 a1 a2 a3) /// Method or object constructor '%s' not found - /// (Originally from ../FSComp.txt:359) + /// (Originally from ..\FSComp.txt:359) static member csMethodNotFound(a0 : System.String) = (509, GetStringFunc("csMethodNotFound",",,,%s,,,") a0) /// No overloads match for method '%s'. - /// (Originally from ../FSComp.txt:360) + /// (Originally from ..\FSComp.txt:360) static member csNoOverloadsFound(a0 : System.String) = (GetStringFunc("csNoOverloadsFound",",,,%s,,,") a0) /// A unique overload for method '%s' could not be determined based on type information prior to this program point. A type annotation may be needed. - /// (Originally from ../FSComp.txt:361) + /// (Originally from ..\FSComp.txt:361) static member csMethodIsOverloaded(a0 : System.String) = (GetStringFunc("csMethodIsOverloaded",",,,%s,,,") a0) /// Candidates: %s - /// (Originally from ../FSComp.txt:362) + /// (Originally from ..\FSComp.txt:362) static member csCandidates(a0 : System.String) = (GetStringFunc("csCandidates",",,,%s,,,") a0) /// The available overloads are shown below. - /// (Originally from ../FSComp.txt:363) + /// (Originally from ..\FSComp.txt:363) static member csSeeAvailableOverloads() = (GetStringFunc("csSeeAvailableOverloads",",,,") ) /// Accessibility modifiers are not permitted on 'do' bindings, but '%s' was given. - /// (Originally from ../FSComp.txt:364) + /// (Originally from ..\FSComp.txt:364) static member parsDoCannotHaveVisibilityDeclarations(a0 : System.String) = (512, GetStringFunc("parsDoCannotHaveVisibilityDeclarations",",,,%s,,,") a0) /// End of file in #if section begun at or after here - /// (Originally from ../FSComp.txt:365) + /// (Originally from ..\FSComp.txt:365) static member parsEofInHashIf() = (513, GetStringFunc("parsEofInHashIf",",,,") ) /// End of file in string begun at or before here - /// (Originally from ../FSComp.txt:366) + /// (Originally from ..\FSComp.txt:366) static member parsEofInString() = (514, GetStringFunc("parsEofInString",",,,") ) /// End of file in verbatim string begun at or before here - /// (Originally from ../FSComp.txt:367) + /// (Originally from ..\FSComp.txt:367) static member parsEofInVerbatimString() = (515, GetStringFunc("parsEofInVerbatimString",",,,") ) /// End of file in comment begun at or before here - /// (Originally from ../FSComp.txt:368) + /// (Originally from ..\FSComp.txt:368) static member parsEofInComment() = (516, GetStringFunc("parsEofInComment",",,,") ) /// End of file in string embedded in comment begun at or before here - /// (Originally from ../FSComp.txt:369) + /// (Originally from ..\FSComp.txt:369) static member parsEofInStringInComment() = (517, GetStringFunc("parsEofInStringInComment",",,,") ) /// End of file in verbatim string embedded in comment begun at or before here - /// (Originally from ../FSComp.txt:370) + /// (Originally from ..\FSComp.txt:370) static member parsEofInVerbatimStringInComment() = (518, GetStringFunc("parsEofInVerbatimStringInComment",",,,") ) /// End of file in IF-OCAML section begun at or before here - /// (Originally from ../FSComp.txt:371) + /// (Originally from ..\FSComp.txt:371) static member parsEofInIfOcaml() = (519, GetStringFunc("parsEofInIfOcaml",",,,") ) /// End of file in directive begun at or before here - /// (Originally from ../FSComp.txt:372) + /// (Originally from ..\FSComp.txt:372) static member parsEofInDirective() = (520, GetStringFunc("parsEofInDirective",",,,") ) /// No #endif found for #if or #else - /// (Originally from ../FSComp.txt:373) + /// (Originally from ..\FSComp.txt:373) static member parsNoHashEndIfFound() = (521, GetStringFunc("parsNoHashEndIfFound",",,,") ) /// Attributes have been ignored in this construct - /// (Originally from ../FSComp.txt:374) + /// (Originally from ..\FSComp.txt:374) static member parsAttributesIgnored() = (522, GetStringFunc("parsAttributesIgnored",",,,") ) /// 'use' bindings are not permitted in primary constructors - /// (Originally from ../FSComp.txt:375) + /// (Originally from ..\FSComp.txt:375) static member parsUseBindingsIllegalInImplicitClassConstructors() = (523, GetStringFunc("parsUseBindingsIllegalInImplicitClassConstructors",",,,") ) /// 'use' bindings are not permitted in modules and are treated as 'let' bindings - /// (Originally from ../FSComp.txt:376) + /// (Originally from ..\FSComp.txt:376) static member parsUseBindingsIllegalInModules() = (524, GetStringFunc("parsUseBindingsIllegalInModules",",,,") ) /// An integer for loop must use a simple identifier - /// (Originally from ../FSComp.txt:377) + /// (Originally from ..\FSComp.txt:377) static member parsIntegerForLoopRequiresSimpleIdentifier() = (525, GetStringFunc("parsIntegerForLoopRequiresSimpleIdentifier",",,,") ) /// At most one 'with' augmentation is permitted - /// (Originally from ../FSComp.txt:378) + /// (Originally from ..\FSComp.txt:378) static member parsOnlyOneWithAugmentationAllowed() = (526, GetStringFunc("parsOnlyOneWithAugmentationAllowed",",,,") ) /// A semicolon is not expected at this point - /// (Originally from ../FSComp.txt:379) + /// (Originally from ..\FSComp.txt:379) static member parsUnexpectedSemicolon() = (527, GetStringFunc("parsUnexpectedSemicolon",",,,") ) /// Unexpected end of input - /// (Originally from ../FSComp.txt:380) + /// (Originally from ..\FSComp.txt:380) static member parsUnexpectedEndOfFile() = (528, GetStringFunc("parsUnexpectedEndOfFile",",,,") ) /// Accessibility modifiers are not permitted here, but '%s' was given. - /// (Originally from ../FSComp.txt:381) + /// (Originally from ..\FSComp.txt:381) static member parsUnexpectedVisibilityDeclaration(a0 : System.String) = (529, GetStringFunc("parsUnexpectedVisibilityDeclaration",",,,%s,,,") a0) /// Only '#' compiler directives may occur prior to the first 'namespace' declaration - /// (Originally from ../FSComp.txt:382) + /// (Originally from ..\FSComp.txt:382) static member parsOnlyHashDirectivesAllowed() = (530, GetStringFunc("parsOnlyHashDirectivesAllowed",",,,") ) /// Accessibility modifiers should come immediately prior to the identifier naming a construct - /// (Originally from ../FSComp.txt:383) + /// (Originally from ..\FSComp.txt:383) static member parsVisibilityDeclarationsShouldComePriorToIdentifier() = (531, GetStringFunc("parsVisibilityDeclarationsShouldComePriorToIdentifier",",,,") ) /// Files should begin with either a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule', but not both. To define a module within a namespace use 'module SomeModule = ...' - /// (Originally from ../FSComp.txt:384) + /// (Originally from ..\FSComp.txt:384) static member parsNamespaceOrModuleNotBoth() = (532, GetStringFunc("parsNamespaceOrModuleNotBoth",",,,") ) /// A module abbreviation must be a simple name, not a path - /// (Originally from ../FSComp.txt:385) + /// (Originally from ..\FSComp.txt:385) static member parsModuleAbbreviationMustBeSimpleName() = (534, GetStringFunc("parsModuleAbbreviationMustBeSimpleName",",,,") ) /// Ignoring attributes on module abbreviation - /// (Originally from ../FSComp.txt:386) + /// (Originally from ..\FSComp.txt:386) static member parsIgnoreAttributesOnModuleAbbreviation() = (535, GetStringFunc("parsIgnoreAttributesOnModuleAbbreviation",",,,") ) /// The '%s' accessibility attribute is not allowed on module abbreviation. Module abbreviations are always private. - /// (Originally from ../FSComp.txt:387) + /// (Originally from ..\FSComp.txt:387) static member parsIgnoreAttributesOnModuleAbbreviationAlwaysPrivate(a0 : System.String) = (536, GetStringFunc("parsIgnoreAttributesOnModuleAbbreviationAlwaysPrivate",",,,%s,,,") a0) /// The '%s' visibility attribute is not allowed on module abbreviation. Module abbreviations are always private. - /// (Originally from ../FSComp.txt:388) + /// (Originally from ..\FSComp.txt:388) static member parsIgnoreVisibilityOnModuleAbbreviationAlwaysPrivate(a0 : System.String) = (537, GetStringFunc("parsIgnoreVisibilityOnModuleAbbreviationAlwaysPrivate",",,,%s,,,") a0) /// Unclosed block - /// (Originally from ../FSComp.txt:389) + /// (Originally from ..\FSComp.txt:389) static member parsUnClosedBlockInHashLight() = (538, GetStringFunc("parsUnClosedBlockInHashLight",",,,") ) /// Unmatched 'begin' or 'struct' - /// (Originally from ../FSComp.txt:390) + /// (Originally from ..\FSComp.txt:390) static member parsUnmatchedBeginOrStruct() = (539, GetStringFunc("parsUnmatchedBeginOrStruct",",,,") ) /// A module name must be a simple name, not a path - /// (Originally from ../FSComp.txt:391) + /// (Originally from ..\FSComp.txt:391) static member parsModuleDefnMustBeSimpleName() = (541, GetStringFunc("parsModuleDefnMustBeSimpleName",",,,") ) /// Unexpected empty type moduleDefn list - /// (Originally from ../FSComp.txt:392) + /// (Originally from ..\FSComp.txt:392) static member parsUnexpectedEmptyModuleDefn() = (542, GetStringFunc("parsUnexpectedEmptyModuleDefn",",,,") ) /// Attributes should be placed before 'val' - /// (Originally from ../FSComp.txt:393) + /// (Originally from ..\FSComp.txt:393) static member parsAttributesMustComeBeforeVal() = (GetStringFunc("parsAttributesMustComeBeforeVal",",,,") ) /// Attributes are not permitted on interface implementations - /// (Originally from ../FSComp.txt:394) + /// (Originally from ..\FSComp.txt:394) static member parsAttributesAreNotPermittedOnInterfaceImplementations() = (543, GetStringFunc("parsAttributesAreNotPermittedOnInterfaceImplementations",",,,") ) /// Syntax error - /// (Originally from ../FSComp.txt:395) + /// (Originally from ..\FSComp.txt:395) static member parsSyntaxError() = (544, GetStringFunc("parsSyntaxError",",,,") ) /// Augmentations are not permitted on delegate type moduleDefns - /// (Originally from ../FSComp.txt:396) + /// (Originally from ..\FSComp.txt:396) static member parsAugmentationsIllegalOnDelegateType() = (545, GetStringFunc("parsAugmentationsIllegalOnDelegateType",",,,") ) /// Unmatched 'class', 'interface' or 'struct' - /// (Originally from ../FSComp.txt:397) + /// (Originally from ..\FSComp.txt:397) static member parsUnmatchedClassInterfaceOrStruct() = (546, GetStringFunc("parsUnmatchedClassInterfaceOrStruct",",,,") ) /// A type definition requires one or more members or other declarations. If you intend to define an empty class, struct or interface, then use 'type ... = class end', 'interface end' or 'struct end'. - /// (Originally from ../FSComp.txt:398) + /// (Originally from ..\FSComp.txt:398) static member parsEmptyTypeDefinition() = (547, GetStringFunc("parsEmptyTypeDefinition",",,,") ) /// Unmatched 'with' or badly formatted 'with' block - /// (Originally from ../FSComp.txt:399) + /// (Originally from ..\FSComp.txt:399) static member parsUnmatchedWith() = (550, GetStringFunc("parsUnmatchedWith",",,,") ) /// 'get', 'set' or 'get,set' required - /// (Originally from ../FSComp.txt:400) + /// (Originally from ..\FSComp.txt:400) static member parsGetOrSetRequired() = (551, GetStringFunc("parsGetOrSetRequired",",,,") ) /// Only class types may take value arguments - /// (Originally from ../FSComp.txt:401) + /// (Originally from ..\FSComp.txt:401) static member parsOnlyClassCanTakeValueArguments() = (552, GetStringFunc("parsOnlyClassCanTakeValueArguments",",,,") ) /// Unmatched 'begin' - /// (Originally from ../FSComp.txt:402) + /// (Originally from ..\FSComp.txt:402) static member parsUnmatchedBegin() = (553, GetStringFunc("parsUnmatchedBegin",",,,") ) /// Invalid declaration syntax - /// (Originally from ../FSComp.txt:403) + /// (Originally from ..\FSComp.txt:403) static member parsInvalidDeclarationSyntax() = (554, GetStringFunc("parsInvalidDeclarationSyntax",",,,") ) /// 'get' and/or 'set' required - /// (Originally from ../FSComp.txt:404) + /// (Originally from ..\FSComp.txt:404) static member parsGetAndOrSetRequired() = (555, GetStringFunc("parsGetAndOrSetRequired",",,,") ) /// Type annotations on property getters and setters must be given after the 'get()' or 'set(v)', e.g. 'with get() : string = ...' - /// (Originally from ../FSComp.txt:405) + /// (Originally from ..\FSComp.txt:405) static member parsTypeAnnotationsOnGetSet() = (556, GetStringFunc("parsTypeAnnotationsOnGetSet",",,,") ) /// A getter property is expected to be a function, e.g. 'get() = ...' or 'get(index) = ...' - /// (Originally from ../FSComp.txt:406) + /// (Originally from ..\FSComp.txt:406) static member parsGetterMustHaveAtLeastOneArgument() = (557, GetStringFunc("parsGetterMustHaveAtLeastOneArgument",",,,") ) /// Multiple accessibilities given for property getter or setter - /// (Originally from ../FSComp.txt:407) + /// (Originally from ..\FSComp.txt:407) static member parsMultipleAccessibilitiesForGetSet() = (558, GetStringFunc("parsMultipleAccessibilitiesForGetSet",",,,") ) /// Property setters must be defined using 'set value = ', 'set idx value = ' or 'set (idx1,...,idxN) value = ... ' - /// (Originally from ../FSComp.txt:408) + /// (Originally from ..\FSComp.txt:408) static member parsSetSyntax() = (559, GetStringFunc("parsSetSyntax",",,,") ) /// Interfaces always have the same visibility as the enclosing type - /// (Originally from ../FSComp.txt:409) + /// (Originally from ..\FSComp.txt:409) static member parsInterfacesHaveSameVisibilityAsEnclosingType() = (560, GetStringFunc("parsInterfacesHaveSameVisibilityAsEnclosingType",",,,") ) /// Accessibility modifiers are not allowed on this member. Abstract slots always have the same visibility as the enclosing type. - /// (Originally from ../FSComp.txt:410) + /// (Originally from ..\FSComp.txt:410) static member parsAccessibilityModsIllegalForAbstract() = (561, GetStringFunc("parsAccessibilityModsIllegalForAbstract",",,,") ) /// Attributes are not permitted on 'inherit' declarations - /// (Originally from ../FSComp.txt:411) + /// (Originally from ..\FSComp.txt:411) static member parsAttributesIllegalOnInherit() = (562, GetStringFunc("parsAttributesIllegalOnInherit",",,,") ) /// Accessibility modifiers are not permitted on an 'inherits' declaration - /// (Originally from ../FSComp.txt:412) + /// (Originally from ..\FSComp.txt:412) static member parsVisibilityIllegalOnInherit() = (563, GetStringFunc("parsVisibilityIllegalOnInherit",",,,") ) /// 'inherit' declarations cannot have 'as' bindings. To access members of the base class when overriding a method, the syntax 'base.SomeMember' may be used; 'base' is a keyword. Remove this 'as' binding. - /// (Originally from ../FSComp.txt:413) + /// (Originally from ..\FSComp.txt:413) static member parsInheritDeclarationsCannotHaveAsBindings() = (564, GetStringFunc("parsInheritDeclarationsCannotHaveAsBindings",",,,") ) /// Attributes are not allowed here - /// (Originally from ../FSComp.txt:414) + /// (Originally from ..\FSComp.txt:414) static member parsAttributesIllegalHere() = (565, GetStringFunc("parsAttributesIllegalHere",",,,") ) /// Accessibility modifiers are not permitted in this position for type abbreviations - /// (Originally from ../FSComp.txt:415) + /// (Originally from ..\FSComp.txt:415) static member parsTypeAbbreviationsCannotHaveVisibilityDeclarations() = (566, GetStringFunc("parsTypeAbbreviationsCannotHaveVisibilityDeclarations",",,,") ) /// Accessibility modifiers are not permitted in this position for enum types - /// (Originally from ../FSComp.txt:416) + /// (Originally from ..\FSComp.txt:416) static member parsEnumTypesCannotHaveVisibilityDeclarations() = (567, GetStringFunc("parsEnumTypesCannotHaveVisibilityDeclarations",",,,") ) /// All enum fields must be given values - /// (Originally from ../FSComp.txt:417) + /// (Originally from ..\FSComp.txt:417) static member parsAllEnumFieldsRequireValues() = (568, GetStringFunc("parsAllEnumFieldsRequireValues",",,,") ) /// Accessibility modifiers are not permitted on inline assembly code types - /// (Originally from ../FSComp.txt:418) + /// (Originally from ..\FSComp.txt:418) static member parsInlineAssemblyCannotHaveVisibilityDeclarations() = (569, GetStringFunc("parsInlineAssemblyCannotHaveVisibilityDeclarations",",,,") ) /// Unexpected identifier: '%s' - /// (Originally from ../FSComp.txt:419) + /// (Originally from ..\FSComp.txt:419) static member parsUnexpectedIdentifier(a0 : System.String) = (571, GetStringFunc("parsUnexpectedIdentifier",",,,%s,,,") a0) /// Accessibility modifiers are not permitted on union cases. Use 'type U = internal ...' or 'type U = private ...' to give an accessibility to the whole representation. - /// (Originally from ../FSComp.txt:420) + /// (Originally from ..\FSComp.txt:420) static member parsUnionCasesCannotHaveVisibilityDeclarations() = (572, GetStringFunc("parsUnionCasesCannotHaveVisibilityDeclarations",",,,") ) /// Accessibility modifiers are not permitted on enumeration fields - /// (Originally from ../FSComp.txt:421) + /// (Originally from ..\FSComp.txt:421) static member parsEnumFieldsCannotHaveVisibilityDeclarations() = (573, GetStringFunc("parsEnumFieldsCannotHaveVisibilityDeclarations",",,,") ) /// Consider using a separate record type instead - /// (Originally from ../FSComp.txt:422) + /// (Originally from ..\FSComp.txt:422) static member parsConsiderUsingSeparateRecordType() = (GetStringFunc("parsConsiderUsingSeparateRecordType",",,,") ) /// Accessibility modifiers are not permitted on record fields. Use 'type R = internal ...' or 'type R = private ...' to give an accessibility to the whole representation. - /// (Originally from ../FSComp.txt:423) + /// (Originally from ..\FSComp.txt:423) static member parsRecordFieldsCannotHaveVisibilityDeclarations() = (575, GetStringFunc("parsRecordFieldsCannotHaveVisibilityDeclarations",",,,") ) /// The declaration form 'let ... and ...' for non-recursive bindings is not used in F# code. Consider using a sequence of 'let' bindings - /// (Originally from ../FSComp.txt:424) + /// (Originally from ..\FSComp.txt:424) static member parsLetAndForNonRecBindings() = (576, GetStringFunc("parsLetAndForNonRecBindings",",,,") ) /// Unmatched '(' - /// (Originally from ../FSComp.txt:425) + /// (Originally from ..\FSComp.txt:425) static member parsUnmatchedParen() = (583, GetStringFunc("parsUnmatchedParen",",,,") ) /// Successive patterns should be separated by spaces or tupled - /// (Originally from ../FSComp.txt:426) + /// (Originally from ..\FSComp.txt:426) static member parsSuccessivePatternsShouldBeSpacedOrTupled() = (584, GetStringFunc("parsSuccessivePatternsShouldBeSpacedOrTupled",",,,") ) /// No matching 'in' found for this 'let' - /// (Originally from ../FSComp.txt:427) + /// (Originally from ..\FSComp.txt:427) static member parsNoMatchingInForLet() = (586, GetStringFunc("parsNoMatchingInForLet",",,,") ) /// Error in the return expression for this 'let'. Possible incorrect indentation. - /// (Originally from ../FSComp.txt:428) + /// (Originally from ..\FSComp.txt:428) static member parsErrorInReturnForLetIncorrectIndentation() = (587, GetStringFunc("parsErrorInReturnForLetIncorrectIndentation",",,,") ) /// The block following this '%s' is unfinished. Every code block is an expression and must have a result. '%s' cannot be the final code element in a block. Consider giving this block an explicit result. - /// (Originally from ../FSComp.txt:429) + /// (Originally from ..\FSComp.txt:429) static member parsExpectedExpressionAfterLet(a0 : System.String, a1 : System.String) = (588, GetStringFunc("parsExpectedExpressionAfterLet",",,,%s,,,%s,,,") a0 a1) /// Incomplete conditional. Expected 'if then ' or 'if then else '. - /// (Originally from ../FSComp.txt:430) + /// (Originally from ..\FSComp.txt:430) static member parsIncompleteIf() = (589, GetStringFunc("parsIncompleteIf",",,,") ) /// 'assert' may not be used as a first class value. Use 'assert ' instead. - /// (Originally from ../FSComp.txt:431) + /// (Originally from ..\FSComp.txt:431) static member parsAssertIsNotFirstClassValue() = (590, GetStringFunc("parsAssertIsNotFirstClassValue",",,,") ) /// Identifier expected - /// (Originally from ../FSComp.txt:432) + /// (Originally from ..\FSComp.txt:432) static member parsIdentifierExpected() = (594, GetStringFunc("parsIdentifierExpected",",,,") ) /// 'in' or '=' expected - /// (Originally from ../FSComp.txt:433) + /// (Originally from ..\FSComp.txt:433) static member parsInOrEqualExpected() = (595, GetStringFunc("parsInOrEqualExpected",",,,") ) /// The use of '->' in sequence and computation expressions is limited to the form 'for pat in expr -> expr'. Use the syntax 'for ... in ... do ... yield...' to generate elements in more complex sequence expressions. - /// (Originally from ../FSComp.txt:434) + /// (Originally from ..\FSComp.txt:434) static member parsArrowUseIsLimited() = (596, GetStringFunc("parsArrowUseIsLimited",",,,") ) /// Successive arguments should be separated by spaces or tupled, and arguments involving function or method applications should be parenthesized - /// (Originally from ../FSComp.txt:435) + /// (Originally from ..\FSComp.txt:435) static member parsSuccessiveArgsShouldBeSpacedOrTupled() = (597, GetStringFunc("parsSuccessiveArgsShouldBeSpacedOrTupled",",,,") ) /// Unmatched '[' - /// (Originally from ../FSComp.txt:436) + /// (Originally from ..\FSComp.txt:436) static member parsUnmatchedBracket() = (598, GetStringFunc("parsUnmatchedBracket",",,,") ) /// Missing qualification after '.' - /// (Originally from ../FSComp.txt:437) + /// (Originally from ..\FSComp.txt:437) static member parsMissingQualificationAfterDot() = (599, GetStringFunc("parsMissingQualificationAfterDot",",,,") ) /// In F# code you may use 'expr.[expr]'. A type annotation may be required to indicate the first expression is an array - /// (Originally from ../FSComp.txt:438) + /// (Originally from ..\FSComp.txt:438) static member parsParenFormIsForML() = (GetStringFunc("parsParenFormIsForML",",,,") ) /// Mismatched quotation, beginning with '%s' - /// (Originally from ../FSComp.txt:439) + /// (Originally from ..\FSComp.txt:439) static member parsMismatchedQuote(a0 : System.String) = (601, GetStringFunc("parsMismatchedQuote",",,,%s,,,") a0) /// Unmatched '%s' - /// (Originally from ../FSComp.txt:440) + /// (Originally from ..\FSComp.txt:440) static member parsUnmatched(a0 : System.String) = (602, GetStringFunc("parsUnmatched",",,,%s,,,") a0) /// Unmatched '[|' - /// (Originally from ../FSComp.txt:441) + /// (Originally from ..\FSComp.txt:441) static member parsUnmatchedBracketBar() = (603, GetStringFunc("parsUnmatchedBracketBar",",,,") ) /// Unmatched '{' - /// (Originally from ../FSComp.txt:442) + /// (Originally from ..\FSComp.txt:442) static member parsUnmatchedBrace() = (604, GetStringFunc("parsUnmatchedBrace",",,,") ) /// Field bindings must have the form 'id = expr;' - /// (Originally from ../FSComp.txt:443) + /// (Originally from ..\FSComp.txt:443) static member parsFieldBinding() = (609, GetStringFunc("parsFieldBinding",",,,") ) /// This member is not permitted in an object implementation - /// (Originally from ../FSComp.txt:444) + /// (Originally from ..\FSComp.txt:444) static member parsMemberIllegalInObjectImplementation() = (610, GetStringFunc("parsMemberIllegalInObjectImplementation",",,,") ) /// Missing function body - /// (Originally from ../FSComp.txt:445) + /// (Originally from ..\FSComp.txt:445) static member parsMissingFunctionBody() = (611, GetStringFunc("parsMissingFunctionBody",",,,") ) /// Syntax error in labelled type argument - /// (Originally from ../FSComp.txt:446) + /// (Originally from ..\FSComp.txt:446) static member parsSyntaxErrorInLabeledType() = (613, GetStringFunc("parsSyntaxErrorInLabeledType",",,,") ) /// Unexpected infix operator in type expression - /// (Originally from ../FSComp.txt:447) + /// (Originally from ..\FSComp.txt:447) static member parsUnexpectedInfixOperator() = (615, GetStringFunc("parsUnexpectedInfixOperator",",,,") ) /// The syntax '(typ,...,typ) ident' is not used in F# code. Consider using 'ident' instead - /// (Originally from ../FSComp.txt:448) + /// (Originally from ..\FSComp.txt:448) static member parsMultiArgumentGenericTypeFormDeprecated() = (GetStringFunc("parsMultiArgumentGenericTypeFormDeprecated",",,,") ) /// Invalid literal in type - /// (Originally from ../FSComp.txt:449) + /// (Originally from ..\FSComp.txt:449) static member parsInvalidLiteralInType() = (618, GetStringFunc("parsInvalidLiteralInType",",,,") ) /// Unexpected infix operator in unit-of-measure expression. Legal operators are '*', '/' and '^'. - /// (Originally from ../FSComp.txt:450) + /// (Originally from ..\FSComp.txt:450) static member parsUnexpectedOperatorForUnitOfMeasure() = (619, GetStringFunc("parsUnexpectedOperatorForUnitOfMeasure",",,,") ) /// Unexpected integer literal in unit-of-measure expression - /// (Originally from ../FSComp.txt:451) + /// (Originally from ..\FSComp.txt:451) static member parsUnexpectedIntegerLiteralForUnitOfMeasure() = (620, GetStringFunc("parsUnexpectedIntegerLiteralForUnitOfMeasure",",,,") ) /// Syntax error: unexpected type parameter specification - /// (Originally from ../FSComp.txt:452) + /// (Originally from ..\FSComp.txt:452) static member parsUnexpectedTypeParameter() = (621, GetStringFunc("parsUnexpectedTypeParameter",",,,") ) /// Mismatched quotation operator name, beginning with '%s' - /// (Originally from ../FSComp.txt:453) + /// (Originally from ..\FSComp.txt:453) static member parsMismatchedQuotationName(a0 : System.String) = (622, GetStringFunc("parsMismatchedQuotationName",",,,%s,,,") a0) /// Active pattern case identifiers must begin with an uppercase letter - /// (Originally from ../FSComp.txt:454) + /// (Originally from ..\FSComp.txt:454) static member parsActivePatternCaseMustBeginWithUpperCase() = (623, GetStringFunc("parsActivePatternCaseMustBeginWithUpperCase",",,,") ) /// The '|' character is not permitted in active pattern case identifiers - /// (Originally from ../FSComp.txt:455) + /// (Originally from ..\FSComp.txt:455) static member parsActivePatternCaseContainsPipe() = (624, GetStringFunc("parsActivePatternCaseContainsPipe",",,,") ) /// Denominator must not be 0 in unit-of-measure exponent - /// (Originally from ../FSComp.txt:456) + /// (Originally from ..\FSComp.txt:456) static member parsIllegalDenominatorForMeasureExponent() = (625, GetStringFunc("parsIllegalDenominatorForMeasureExponent",",,,") ) /// No '=' symbol should follow a 'namespace' declaration - /// (Originally from ../FSComp.txt:457) + /// (Originally from ..\FSComp.txt:457) static member parsNoEqualShouldFollowNamespace() = (GetStringFunc("parsNoEqualShouldFollowNamespace",",,,") ) /// The syntax 'module ... = struct .. end' is not used in F# code. Consider using 'module ... = begin .. end' - /// (Originally from ../FSComp.txt:458) + /// (Originally from ..\FSComp.txt:458) static member parsSyntaxModuleStructEndDeprecated() = (GetStringFunc("parsSyntaxModuleStructEndDeprecated",",,,") ) /// The syntax 'module ... : sig .. end' is not used in F# code. Consider using 'module ... = begin .. end' - /// (Originally from ../FSComp.txt:459) + /// (Originally from ..\FSComp.txt:459) static member parsSyntaxModuleSigEndDeprecated() = (GetStringFunc("parsSyntaxModuleSigEndDeprecated",",,,") ) /// A static field was used where an instance field is expected - /// (Originally from ../FSComp.txt:460) + /// (Originally from ..\FSComp.txt:460) static member tcStaticFieldUsedWhenInstanceFieldExpected() = (627, GetStringFunc("tcStaticFieldUsedWhenInstanceFieldExpected",",,,") ) /// Method '%s' is not accessible from this code location - /// (Originally from ../FSComp.txt:461) + /// (Originally from ..\FSComp.txt:461) static member tcMethodNotAccessible(a0 : System.String) = (629, GetStringFunc("tcMethodNotAccessible",",,,%s,,,") a0) /// Implicit product of measures following / - /// (Originally from ../FSComp.txt:463) + /// (Originally from ..\FSComp.txt:463) static member tcImplicitMeasureFollowingSlash() = (632, GetStringFunc("tcImplicitMeasureFollowingSlash",",,,") ) /// Unexpected SynMeasure.Anon - /// (Originally from ../FSComp.txt:464) + /// (Originally from ..\FSComp.txt:464) static member tcUnexpectedMeasureAnon() = (633, GetStringFunc("tcUnexpectedMeasureAnon",",,,") ) /// Non-zero constants cannot have generic units. For generic zero, write 0.0<_>. - /// (Originally from ../FSComp.txt:465) + /// (Originally from ..\FSComp.txt:465) static member tcNonZeroConstantCannotHaveGenericUnit() = (634, GetStringFunc("tcNonZeroConstantCannotHaveGenericUnit",",,,") ) /// In sequence expressions, results are generated using 'yield' - /// (Originally from ../FSComp.txt:466) + /// (Originally from ..\FSComp.txt:466) static member tcSeqResultsUseYield() = (635, GetStringFunc("tcSeqResultsUseYield",",,,") ) /// Unexpected big rational constant - /// (Originally from ../FSComp.txt:467) + /// (Originally from ..\FSComp.txt:467) static member tcUnexpectedBigRationalConstant() = (GetStringFunc("tcUnexpectedBigRationalConstant",",,,") ) /// Units-of-measure supported only on float, float32, decimal and signed integer types - /// (Originally from ../FSComp.txt:468) + /// (Originally from ..\FSComp.txt:468) static member tcInvalidTypeForUnitsOfMeasure() = (636, GetStringFunc("tcInvalidTypeForUnitsOfMeasure",",,,") ) /// Unexpected Const_uint16array - /// (Originally from ../FSComp.txt:469) + /// (Originally from ..\FSComp.txt:469) static member tcUnexpectedConstUint16Array() = (GetStringFunc("tcUnexpectedConstUint16Array",",,,") ) /// Unexpected Const_bytearray - /// (Originally from ../FSComp.txt:470) + /// (Originally from ..\FSComp.txt:470) static member tcUnexpectedConstByteArray() = (GetStringFunc("tcUnexpectedConstByteArray",",,,") ) /// A parameter with attributes must also be given a name, e.g. '[] Name : Type' - /// (Originally from ../FSComp.txt:471) + /// (Originally from ..\FSComp.txt:471) static member tcParameterRequiresName() = (640, GetStringFunc("tcParameterRequiresName",",,,") ) /// Return values cannot have names - /// (Originally from ../FSComp.txt:472) + /// (Originally from ..\FSComp.txt:472) static member tcReturnValuesCannotHaveNames() = (641, GetStringFunc("tcReturnValuesCannotHaveNames",",,,") ) /// MemberKind.PropertyGetSet only expected in parse trees - /// (Originally from ../FSComp.txt:473) + /// (Originally from ..\FSComp.txt:473) static member tcMemberKindPropertyGetSetNotExpected() = (GetStringFunc("tcMemberKindPropertyGetSetNotExpected",",,,") ) /// Namespaces cannot contain values. Consider using a module to hold your value declarations. - /// (Originally from ../FSComp.txt:474) + /// (Originally from ..\FSComp.txt:474) static member tcNamespaceCannotContainValues() = (201, GetStringFunc("tcNamespaceCannotContainValues",",,,") ) /// Namespaces cannot contain extension members except in the same file and namespace declaration group where the type is defined. Consider using a module to hold declarations of extension members. - /// (Originally from ../FSComp.txt:475) + /// (Originally from ..\FSComp.txt:475) static member tcNamespaceCannotContainExtensionMembers() = (644, GetStringFunc("tcNamespaceCannotContainExtensionMembers",",,,") ) /// Multiple visibility attributes have been specified for this identifier - /// (Originally from ../FSComp.txt:476) + /// (Originally from ..\FSComp.txt:476) static member tcMultipleVisibilityAttributes() = (645, GetStringFunc("tcMultipleVisibilityAttributes",",,,") ) /// Multiple visibility attributes have been specified for this identifier. 'let' bindings in classes are always private, as are any 'let' bindings inside expressions. - /// (Originally from ../FSComp.txt:477) + /// (Originally from ..\FSComp.txt:477) static member tcMultipleVisibilityAttributesWithLet() = (646, GetStringFunc("tcMultipleVisibilityAttributesWithLet",",,,") ) /// The name '(%s)' should not be used as a member name. To define comparison semantics for a type, implement the 'System.IComparable' interface. If defining a static member for use from other CLI languages then use the name '%s' instead. - /// (Originally from ../FSComp.txt:478) + /// (Originally from ..\FSComp.txt:478) static member tcInvalidMethodNameForRelationalOperator(a0 : System.String, a1 : System.String) = (GetStringFunc("tcInvalidMethodNameForRelationalOperator",",,,%s,,,%s,,,") a0 a1) /// The name '(%s)' should not be used as a member name. To define equality semantics for a type, override the 'Object.Equals' member. If defining a static member for use from other CLI languages then use the name '%s' instead. - /// (Originally from ../FSComp.txt:479) + /// (Originally from ..\FSComp.txt:479) static member tcInvalidMethodNameForEquality(a0 : System.String, a1 : System.String) = (GetStringFunc("tcInvalidMethodNameForEquality",",,,%s,,,%s,,,") a0 a1) /// The name '(%s)' should not be used as a member name. If defining a static member for use from other CLI languages then use the name '%s' instead. - /// (Originally from ../FSComp.txt:480) + /// (Originally from ..\FSComp.txt:480) static member tcInvalidMemberName(a0 : System.String, a1 : System.String) = (GetStringFunc("tcInvalidMemberName",",,,%s,,,%s,,,") a0 a1) /// The name '(%s)' should not be used as a member name because it is given a standard definition in the F# library over fixed types - /// (Originally from ../FSComp.txt:481) + /// (Originally from ..\FSComp.txt:481) static member tcInvalidMemberNameFixedTypes(a0 : System.String) = (GetStringFunc("tcInvalidMemberNameFixedTypes",",,,%s,,,") a0) /// The '%s' operator should not normally be redefined. To define overloaded comparison semantics for a particular type, implement the 'System.IComparable' interface in the definition of that type. - /// (Originally from ../FSComp.txt:482) + /// (Originally from ..\FSComp.txt:482) static member tcInvalidOperatorDefinitionRelational(a0 : System.String) = (GetStringFunc("tcInvalidOperatorDefinitionRelational",",,,%s,,,") a0) /// The '%s' operator should not normally be redefined. To define equality semantics for a type, override the 'Object.Equals' member in the definition of that type. - /// (Originally from ../FSComp.txt:483) + /// (Originally from ..\FSComp.txt:483) static member tcInvalidOperatorDefinitionEquality(a0 : System.String) = (GetStringFunc("tcInvalidOperatorDefinitionEquality",",,,%s,,,") a0) /// The '%s' operator should not normally be redefined. Consider using a different operator name - /// (Originally from ../FSComp.txt:484) + /// (Originally from ..\FSComp.txt:484) static member tcInvalidOperatorDefinition(a0 : System.String) = (GetStringFunc("tcInvalidOperatorDefinition",",,,%s,,,") a0) /// The '%s' operator cannot be redefined. Consider using a different operator name - /// (Originally from ../FSComp.txt:485) + /// (Originally from ..\FSComp.txt:485) static member tcInvalidIndexOperatorDefinition(a0 : System.String) = (GetStringFunc("tcInvalidIndexOperatorDefinition",",,,%s,,,") a0) /// Expected module or namespace parent %s - /// (Originally from ../FSComp.txt:486) + /// (Originally from ..\FSComp.txt:486) static member tcExpectModuleOrNamespaceParent(a0 : System.String) = (GetStringFunc("tcExpectModuleOrNamespaceParent",",,,%s,,,") a0) /// The struct, record or union type '%s' implements the interface 'System.IComparable' explicitly. You must apply the 'CustomComparison' attribute to the type. - /// (Originally from ../FSComp.txt:487) + /// (Originally from ..\FSComp.txt:487) static member tcImplementsIComparableExplicitly(a0 : System.String) = (647, GetStringFunc("tcImplementsIComparableExplicitly",",,,%s,,,") a0) /// The struct, record or union type '%s' implements the interface 'System.IComparable<_>' explicitly. You must apply the 'CustomComparison' attribute to the type, and should also provide a consistent implementation of the non-generic interface System.IComparable. - /// (Originally from ../FSComp.txt:488) + /// (Originally from ..\FSComp.txt:488) static member tcImplementsGenericIComparableExplicitly(a0 : System.String) = (648, GetStringFunc("tcImplementsGenericIComparableExplicitly",",,,%s,,,") a0) /// The struct, record or union type '%s' implements the interface 'System.IStructuralComparable' explicitly. Apply the 'CustomComparison' attribute to the type. - /// (Originally from ../FSComp.txt:489) + /// (Originally from ..\FSComp.txt:489) static member tcImplementsIStructuralComparableExplicitly(a0 : System.String) = (649, GetStringFunc("tcImplementsIStructuralComparableExplicitly",",,,%s,,,") a0) /// This record contains fields from inconsistent types - /// (Originally from ../FSComp.txt:490) + /// (Originally from ..\FSComp.txt:490) static member tcRecordFieldInconsistentTypes() = (656, GetStringFunc("tcRecordFieldInconsistentTypes",",,,") ) /// DLLImport stubs cannot be inlined - /// (Originally from ../FSComp.txt:491) + /// (Originally from ..\FSComp.txt:491) static member tcDllImportStubsCannotBeInlined() = (657, GetStringFunc("tcDllImportStubsCannotBeInlined",",,,") ) /// Structs may only bind a 'this' parameter at member declarations - /// (Originally from ../FSComp.txt:492) + /// (Originally from ..\FSComp.txt:492) static member tcStructsCanOnlyBindThisAtMemberDeclaration() = (658, GetStringFunc("tcStructsCanOnlyBindThisAtMemberDeclaration",",,,") ) /// Unexpected expression at recursive inference point - /// (Originally from ../FSComp.txt:493) + /// (Originally from ..\FSComp.txt:493) static member tcUnexpectedExprAtRecInfPoint() = (659, GetStringFunc("tcUnexpectedExprAtRecInfPoint",",,,") ) /// This code is less generic than required by its annotations because the explicit type variable '%s' could not be generalized. It was constrained to be '%s'. - /// (Originally from ../FSComp.txt:494) + /// (Originally from ..\FSComp.txt:494) static member tcLessGenericBecauseOfAnnotation(a0 : System.String, a1 : System.String) = (660, GetStringFunc("tcLessGenericBecauseOfAnnotation",",,,%s,,,%s,,,") a0 a1) /// One or more of the explicit class or function type variables for this binding could not be generalized, because they were constrained to other types - /// (Originally from ../FSComp.txt:495) + /// (Originally from ..\FSComp.txt:495) static member tcConstrainedTypeVariableCannotBeGeneralized() = (661, GetStringFunc("tcConstrainedTypeVariableCannotBeGeneralized",",,,") ) /// A generic type parameter has been used in a way that constrains it to always be '%s' - /// (Originally from ../FSComp.txt:496) + /// (Originally from ..\FSComp.txt:496) static member tcGenericParameterHasBeenConstrained(a0 : System.String) = (662, GetStringFunc("tcGenericParameterHasBeenConstrained",",,,%s,,,") a0) /// This type parameter has been used in a way that constrains it to always be '%s' - /// (Originally from ../FSComp.txt:497) + /// (Originally from ..\FSComp.txt:497) static member tcTypeParameterHasBeenConstrained(a0 : System.String) = (663, GetStringFunc("tcTypeParameterHasBeenConstrained",",,,%s,,,") a0) /// The type parameters inferred for this value are not stable under the erasure of type abbreviations. This is due to the use of type abbreviations which drop or reorder type parameters, e.g. \n\ttype taggedInt<'a> = int or\n\ttype swap<'a,'b> = 'b * 'a.\nConsider declaring the type parameters for this value explicitly, e.g.\n\tlet f<'a,'b> ((x,y) : swap<'b,'a>) : swap<'a,'b> = (y,x). - /// (Originally from ../FSComp.txt:498) + /// (Originally from ..\FSComp.txt:498) static member tcTypeParametersInferredAreNotStable() = (664, GetStringFunc("tcTypeParametersInferredAreNotStable",",,,") ) /// Explicit type parameters may only be used on module or member bindings - /// (Originally from ../FSComp.txt:499) + /// (Originally from ..\FSComp.txt:499) static member tcExplicitTypeParameterInvalid() = (665, GetStringFunc("tcExplicitTypeParameterInvalid",",,,") ) /// You must explicitly declare either all or no type parameters when overriding a generic abstract method - /// (Originally from ../FSComp.txt:500) + /// (Originally from ..\FSComp.txt:500) static member tcOverridingMethodRequiresAllOrNoTypeParameters() = (666, GetStringFunc("tcOverridingMethodRequiresAllOrNoTypeParameters",",,,") ) /// The field labels and expected type of this record expression or pattern do not uniquely determine a corresponding record type - /// (Originally from ../FSComp.txt:501) + /// (Originally from ..\FSComp.txt:501) static member tcFieldsDoNotDetermineUniqueRecordType() = (667, GetStringFunc("tcFieldsDoNotDetermineUniqueRecordType",",,,") ) /// The field '%s' appears twice in this record expression or pattern - /// (Originally from ../FSComp.txt:502) + /// (Originally from ..\FSComp.txt:502) static member tcFieldAppearsTwiceInRecord(a0 : System.String) = (668, GetStringFunc("tcFieldAppearsTwiceInRecord",",,,%s,,,") a0) /// Unknown union case - /// (Originally from ../FSComp.txt:503) + /// (Originally from ..\FSComp.txt:503) static member tcUnknownUnion() = (669, GetStringFunc("tcUnknownUnion",",,,") ) /// This code is not sufficiently generic. The type variable %s could not be generalized because it would escape its scope. - /// (Originally from ../FSComp.txt:504) + /// (Originally from ..\FSComp.txt:504) static member tcNotSufficientlyGenericBecauseOfScope(a0 : System.String) = (670, GetStringFunc("tcNotSufficientlyGenericBecauseOfScope",",,,%s,,,") a0) /// A property cannot have explicit type parameters. Consider using a method instead. - /// (Originally from ../FSComp.txt:505) + /// (Originally from ..\FSComp.txt:505) static member tcPropertyRequiresExplicitTypeParameters() = (671, GetStringFunc("tcPropertyRequiresExplicitTypeParameters",",,,") ) /// A constructor cannot have explicit type parameters. Consider using a static construction method instead. - /// (Originally from ../FSComp.txt:506) + /// (Originally from ..\FSComp.txt:506) static member tcConstructorCannotHaveTypeParameters() = (672, GetStringFunc("tcConstructorCannotHaveTypeParameters",",,,") ) /// This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args) = ...'. - /// (Originally from ../FSComp.txt:507) + /// (Originally from ..\FSComp.txt:507) static member tcInstanceMemberRequiresTarget() = (673, GetStringFunc("tcInstanceMemberRequiresTarget",",,,") ) /// Unexpected source-level property specification in syntax tree - /// (Originally from ../FSComp.txt:508) + /// (Originally from ..\FSComp.txt:508) static member tcUnexpectedPropertyInSyntaxTree() = (674, GetStringFunc("tcUnexpectedPropertyInSyntaxTree",",,,") ) /// A static initializer requires an argument - /// (Originally from ../FSComp.txt:509) + /// (Originally from ..\FSComp.txt:509) static member tcStaticInitializerRequiresArgument() = (675, GetStringFunc("tcStaticInitializerRequiresArgument",",,,") ) /// An object constructor requires an argument - /// (Originally from ../FSComp.txt:510) + /// (Originally from ..\FSComp.txt:510) static member tcObjectConstructorRequiresArgument() = (676, GetStringFunc("tcObjectConstructorRequiresArgument",",,,") ) /// This static member should not have a 'this' parameter. Consider using the notation 'member Member(args) = ...'. - /// (Originally from ../FSComp.txt:511) + /// (Originally from ..\FSComp.txt:511) static member tcStaticMemberShouldNotHaveThis() = (677, GetStringFunc("tcStaticMemberShouldNotHaveThis",",,,") ) /// An explicit static initializer should use the syntax 'static new(args) = expr' - /// (Originally from ../FSComp.txt:512) + /// (Originally from ..\FSComp.txt:512) static member tcExplicitStaticInitializerSyntax() = (678, GetStringFunc("tcExplicitStaticInitializerSyntax",",,,") ) /// An explicit object constructor should use the syntax 'new(args) = expr' - /// (Originally from ../FSComp.txt:513) + /// (Originally from ..\FSComp.txt:513) static member tcExplicitObjectConstructorSyntax() = (679, GetStringFunc("tcExplicitObjectConstructorSyntax",",,,") ) /// Unexpected source-level property specification - /// (Originally from ../FSComp.txt:514) + /// (Originally from ..\FSComp.txt:514) static member tcUnexpectedPropertySpec() = (680, GetStringFunc("tcUnexpectedPropertySpec",",,,") ) /// This form of object expression is not used in F#. Use 'member this.MemberName ... = ...' to define member implementations in object expressions. - /// (Originally from ../FSComp.txt:515) + /// (Originally from ..\FSComp.txt:515) static member tcObjectExpressionFormDeprecated() = (GetStringFunc("tcObjectExpressionFormDeprecated",",,,") ) /// Invalid declaration - /// (Originally from ../FSComp.txt:516) + /// (Originally from ..\FSComp.txt:516) static member tcInvalidDeclaration() = (682, GetStringFunc("tcInvalidDeclaration",",,,") ) /// Attributes are not allowed within patterns - /// (Originally from ../FSComp.txt:517) + /// (Originally from ..\FSComp.txt:517) static member tcAttributesInvalidInPatterns() = (683, GetStringFunc("tcAttributesInvalidInPatterns",",,,") ) /// The generic function '%s' must be given explicit type argument(s) - /// (Originally from ../FSComp.txt:518) + /// (Originally from ..\FSComp.txt:518) static member tcFunctionRequiresExplicitTypeArguments(a0 : System.String) = (685, GetStringFunc("tcFunctionRequiresExplicitTypeArguments",",,,%s,,,") a0) /// The method or function '%s' should not be given explicit type argument(s) because it does not declare its type parameters explicitly - /// (Originally from ../FSComp.txt:519) + /// (Originally from ..\FSComp.txt:519) static member tcDoesNotAllowExplicitTypeArguments(a0 : System.String) = (686, GetStringFunc("tcDoesNotAllowExplicitTypeArguments",",,,%s,,,") a0) /// This value, type or method expects %d type parameter(s) but was given %d - /// (Originally from ../FSComp.txt:520) + /// (Originally from ..\FSComp.txt:520) static member tcTypeParameterArityMismatch(a0 : System.Int32, a1 : System.Int32) = (687, GetStringFunc("tcTypeParameterArityMismatch",",,,%d,,,%d,,,") a0 a1) /// The default, zero-initializing constructor of a struct type may only be used if all the fields of the struct type admit default initialization - /// (Originally from ../FSComp.txt:521) + /// (Originally from ..\FSComp.txt:521) static member tcDefaultStructConstructorCall() = (688, GetStringFunc("tcDefaultStructConstructorCall",",,,") ) /// Couldn't find Dispose on IDisposable, or it was overloaded - /// (Originally from ../FSComp.txt:522) + /// (Originally from ..\FSComp.txt:522) static member tcCouldNotFindIDisposable() = (GetStringFunc("tcCouldNotFindIDisposable",",,,") ) /// This value is not a literal and cannot be used in a pattern - /// (Originally from ../FSComp.txt:523) + /// (Originally from ..\FSComp.txt:523) static member tcNonLiteralCannotBeUsedInPattern() = (689, GetStringFunc("tcNonLiteralCannotBeUsedInPattern",",,,") ) /// This field is readonly - /// (Originally from ../FSComp.txt:524) + /// (Originally from ..\FSComp.txt:524) static member tcFieldIsReadonly() = (690, GetStringFunc("tcFieldIsReadonly",",,,") ) /// Named arguments must appear after all other arguments - /// (Originally from ../FSComp.txt:525) + /// (Originally from ..\FSComp.txt:525) static member tcNameArgumentsMustAppearLast() = (691, GetStringFunc("tcNameArgumentsMustAppearLast",",,,") ) /// This function value is being used to construct a delegate type whose signature includes a byref argument. You must use an explicit lambda expression taking %d arguments. - /// (Originally from ../FSComp.txt:526) + /// (Originally from ..\FSComp.txt:526) static member tcFunctionRequiresExplicitLambda(a0 : System.Int32) = (692, GetStringFunc("tcFunctionRequiresExplicitLambda",",,,%d,,,") a0) /// The type '%s' is not a type whose values can be enumerated with this syntax, i.e. is not compatible with either seq<_>, IEnumerable<_> or IEnumerable and does not have a GetEnumerator method - /// (Originally from ../FSComp.txt:527) + /// (Originally from ..\FSComp.txt:527) static member tcTypeCannotBeEnumerated(a0 : System.String) = (693, GetStringFunc("tcTypeCannotBeEnumerated",",,,%s,,,") a0) /// This recursive binding uses an invalid mixture of recursive forms - /// (Originally from ../FSComp.txt:528) + /// (Originally from ..\FSComp.txt:528) static member tcInvalidMixtureOfRecursiveForms() = (695, GetStringFunc("tcInvalidMixtureOfRecursiveForms",",,,") ) /// This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor. - /// (Originally from ../FSComp.txt:529) + /// (Originally from ..\FSComp.txt:529) static member tcInvalidObjectConstructionExpression() = (696, GetStringFunc("tcInvalidObjectConstructionExpression",",,,") ) /// Invalid constraint - /// (Originally from ../FSComp.txt:530) + /// (Originally from ..\FSComp.txt:530) static member tcInvalidConstraint() = (697, GetStringFunc("tcInvalidConstraint",",,,") ) /// Invalid constraint: the type used for the constraint is sealed, which means the constraint could only be satisfied by at most one solution - /// (Originally from ../FSComp.txt:531) + /// (Originally from ..\FSComp.txt:531) static member tcInvalidConstraintTypeSealed() = (698, GetStringFunc("tcInvalidConstraintTypeSealed",",,,") ) /// An 'enum' constraint must be of the form 'enum' - /// (Originally from ../FSComp.txt:532) + /// (Originally from ..\FSComp.txt:532) static member tcInvalidEnumConstraint() = (699, GetStringFunc("tcInvalidEnumConstraint",",,,") ) /// 'new' constraints must take one argument of type 'unit' and return the constructed type - /// (Originally from ../FSComp.txt:533) + /// (Originally from ..\FSComp.txt:533) static member tcInvalidNewConstraint() = (700, GetStringFunc("tcInvalidNewConstraint",",,,") ) /// This property has an invalid type. Properties taking multiple indexer arguments should have types of the form 'ty1 * ty2 -> ty3'. Properties returning functions should have types of the form '(ty1 -> ty2)'. - /// (Originally from ../FSComp.txt:534) + /// (Originally from ..\FSComp.txt:534) static member tcInvalidPropertyType() = (701, GetStringFunc("tcInvalidPropertyType",",,,") ) /// Expected unit-of-measure parameter, not type parameter. Explicit unit-of-measure parameters must be marked with the [] attribute. - /// (Originally from ../FSComp.txt:535) + /// (Originally from ..\FSComp.txt:535) static member tcExpectedUnitOfMeasureMarkWithAttribute() = (702, GetStringFunc("tcExpectedUnitOfMeasureMarkWithAttribute",",,,") ) /// Expected type parameter, not unit-of-measure parameter - /// (Originally from ../FSComp.txt:536) + /// (Originally from ..\FSComp.txt:536) static member tcExpectedTypeParameter() = (703, GetStringFunc("tcExpectedTypeParameter",",,,") ) /// Expected type, not unit-of-measure - /// (Originally from ../FSComp.txt:537) + /// (Originally from ..\FSComp.txt:537) static member tcExpectedTypeNotUnitOfMeasure() = (704, GetStringFunc("tcExpectedTypeNotUnitOfMeasure",",,,") ) /// Expected unit-of-measure, not type - /// (Originally from ../FSComp.txt:538) + /// (Originally from ..\FSComp.txt:538) static member tcExpectedUnitOfMeasureNotType() = (705, GetStringFunc("tcExpectedUnitOfMeasureNotType",",,,") ) /// Units-of-measure cannot be used as prefix arguments to a type. Rewrite as postfix arguments in angle brackets. - /// (Originally from ../FSComp.txt:539) + /// (Originally from ..\FSComp.txt:539) static member tcInvalidUnitsOfMeasurePrefix() = (706, GetStringFunc("tcInvalidUnitsOfMeasurePrefix",",,,") ) /// Unit-of-measure cannot be used in type constructor application - /// (Originally from ../FSComp.txt:540) + /// (Originally from ..\FSComp.txt:540) static member tcUnitsOfMeasureInvalidInTypeConstructor() = (707, GetStringFunc("tcUnitsOfMeasureInvalidInTypeConstructor",",,,") ) /// This control construct may only be used if the computation expression builder defines a '%s' method - /// (Originally from ../FSComp.txt:541) + /// (Originally from ..\FSComp.txt:541) static member tcRequireBuilderMethod(a0 : System.String) = (708, GetStringFunc("tcRequireBuilderMethod",",,,%s,,,") a0) /// This type has no nested types - /// (Originally from ../FSComp.txt:542) + /// (Originally from ..\FSComp.txt:542) static member tcTypeHasNoNestedTypes() = (709, GetStringFunc("tcTypeHasNoNestedTypes",",,,") ) /// Unexpected %s in type expression - /// (Originally from ../FSComp.txt:543) + /// (Originally from ..\FSComp.txt:543) static member tcUnexpectedSymbolInTypeExpression(a0 : System.String) = (711, GetStringFunc("tcUnexpectedSymbolInTypeExpression",",,,%s,,,") a0) /// Type parameter cannot be used as type constructor - /// (Originally from ../FSComp.txt:544) + /// (Originally from ..\FSComp.txt:544) static member tcTypeParameterInvalidAsTypeConstructor() = (712, GetStringFunc("tcTypeParameterInvalidAsTypeConstructor",",,,") ) /// Illegal syntax in type expression - /// (Originally from ../FSComp.txt:545) + /// (Originally from ..\FSComp.txt:545) static member tcIllegalSyntaxInTypeExpression() = (713, GetStringFunc("tcIllegalSyntaxInTypeExpression",",,,") ) /// Anonymous unit-of-measure cannot be nested inside another unit-of-measure expression - /// (Originally from ../FSComp.txt:546) + /// (Originally from ..\FSComp.txt:546) static member tcAnonymousUnitsOfMeasureCannotBeNested() = (714, GetStringFunc("tcAnonymousUnitsOfMeasureCannotBeNested",",,,") ) /// Anonymous type variables are not permitted in this declaration - /// (Originally from ../FSComp.txt:547) + /// (Originally from ..\FSComp.txt:547) static member tcAnonymousTypeInvalidInDeclaration() = (715, GetStringFunc("tcAnonymousTypeInvalidInDeclaration",",,,") ) /// Unexpected / in type - /// (Originally from ../FSComp.txt:548) + /// (Originally from ..\FSComp.txt:548) static member tcUnexpectedSlashInType() = (716, GetStringFunc("tcUnexpectedSlashInType",",,,") ) /// Unexpected type arguments - /// (Originally from ../FSComp.txt:549) + /// (Originally from ..\FSComp.txt:549) static member tcUnexpectedTypeArguments() = (717, GetStringFunc("tcUnexpectedTypeArguments",",,,") ) /// Optional arguments are only permitted on type members - /// (Originally from ../FSComp.txt:550) + /// (Originally from ..\FSComp.txt:550) static member tcOptionalArgsOnlyOnMembers() = (718, GetStringFunc("tcOptionalArgsOnlyOnMembers",",,,") ) /// Name '%s' not bound in pattern context - /// (Originally from ../FSComp.txt:551) + /// (Originally from ..\FSComp.txt:551) static member tcNameNotBoundInPattern(a0 : System.String) = (719, GetStringFunc("tcNameNotBoundInPattern",",,,%s,,,") a0) /// Non-primitive numeric literal constants cannot be used in pattern matches because they can be mapped to multiple different types through the use of a NumericLiteral module. Consider using replacing with a variable, and use 'when = ' at the end of the match clause. - /// (Originally from ../FSComp.txt:552) + /// (Originally from ..\FSComp.txt:552) static member tcInvalidNonPrimitiveLiteralInPatternMatch() = (720, GetStringFunc("tcInvalidNonPrimitiveLiteralInPatternMatch",",,,") ) /// Type arguments cannot be specified here - /// (Originally from ../FSComp.txt:553) + /// (Originally from ..\FSComp.txt:553) static member tcInvalidTypeArgumentUsage() = (721, GetStringFunc("tcInvalidTypeArgumentUsage",",,,") ) /// Only active patterns returning exactly one result may accept arguments - /// (Originally from ../FSComp.txt:554) + /// (Originally from ..\FSComp.txt:554) static member tcRequireActivePatternWithOneResult() = (722, GetStringFunc("tcRequireActivePatternWithOneResult",",,,") ) /// Invalid argument to parameterized pattern label - /// (Originally from ../FSComp.txt:555) + /// (Originally from ..\FSComp.txt:555) static member tcInvalidArgForParameterizedPattern() = (723, GetStringFunc("tcInvalidArgForParameterizedPattern",",,,") ) /// Internal error. Invalid index into active pattern array - /// (Originally from ../FSComp.txt:556) + /// (Originally from ..\FSComp.txt:556) static member tcInvalidIndexIntoActivePatternArray() = (724, GetStringFunc("tcInvalidIndexIntoActivePatternArray",",,,") ) /// This union case does not take arguments - /// (Originally from ../FSComp.txt:557) + /// (Originally from ..\FSComp.txt:557) static member tcUnionCaseDoesNotTakeArguments() = (725, GetStringFunc("tcUnionCaseDoesNotTakeArguments",",,,") ) /// This union case takes one argument - /// (Originally from ../FSComp.txt:558) + /// (Originally from ..\FSComp.txt:558) static member tcUnionCaseRequiresOneArgument() = (726, GetStringFunc("tcUnionCaseRequiresOneArgument",",,,") ) /// This union case expects %d arguments in tupled form - /// (Originally from ../FSComp.txt:559) + /// (Originally from ..\FSComp.txt:559) static member tcUnionCaseExpectsTupledArguments(a0 : System.Int32) = (727, GetStringFunc("tcUnionCaseExpectsTupledArguments",",,,%d,,,") a0) /// Field '%s' is not static - /// (Originally from ../FSComp.txt:560) + /// (Originally from ..\FSComp.txt:560) static member tcFieldIsNotStatic(a0 : System.String) = (728, GetStringFunc("tcFieldIsNotStatic",",,,%s,,,") a0) /// This field is not a literal and cannot be used in a pattern - /// (Originally from ../FSComp.txt:561) + /// (Originally from ..\FSComp.txt:561) static member tcFieldNotLiteralCannotBeUsedInPattern() = (729, GetStringFunc("tcFieldNotLiteralCannotBeUsedInPattern",",,,") ) /// This is not a variable, constant, active recognizer or literal - /// (Originally from ../FSComp.txt:562) + /// (Originally from ..\FSComp.txt:562) static member tcRequireVarConstRecogOrLiteral() = (730, GetStringFunc("tcRequireVarConstRecogOrLiteral",",,,") ) /// This is not a valid pattern - /// (Originally from ../FSComp.txt:563) + /// (Originally from ..\FSComp.txt:563) static member tcInvalidPattern() = (731, GetStringFunc("tcInvalidPattern",",,,") ) /// Character range matches have been removed in F#. Consider using a 'when' pattern guard instead. - /// (Originally from ../FSComp.txt:564) + /// (Originally from ..\FSComp.txt:564) static member tcUseWhenPatternGuard() = (GetStringFunc("tcUseWhenPatternGuard",",,,") ) /// Illegal pattern - /// (Originally from ../FSComp.txt:565) + /// (Originally from ..\FSComp.txt:565) static member tcIllegalPattern() = (733, GetStringFunc("tcIllegalPattern",",,,") ) /// Syntax error - unexpected '?' symbol - /// (Originally from ../FSComp.txt:566) + /// (Originally from ..\FSComp.txt:566) static member tcSyntaxErrorUnexpectedQMark() = (734, GetStringFunc("tcSyntaxErrorUnexpectedQMark",",,,") ) /// Expected %d expressions, got %d - /// (Originally from ../FSComp.txt:567) + /// (Originally from ..\FSComp.txt:567) static member tcExpressionCountMisMatch(a0 : System.Int32, a1 : System.Int32) = (735, GetStringFunc("tcExpressionCountMisMatch",",,,%d,,,%d,,,") a0 a1) /// TcExprUndelayed: delayed - /// (Originally from ../FSComp.txt:568) + /// (Originally from ..\FSComp.txt:568) static member tcExprUndelayed() = (736, GetStringFunc("tcExprUndelayed",",,,") ) /// This expression form may only be used in sequence and computation expressions - /// (Originally from ../FSComp.txt:569) + /// (Originally from ..\FSComp.txt:569) static member tcExpressionRequiresSequence() = (737, GetStringFunc("tcExpressionRequiresSequence",",,,") ) /// Invalid object expression. Objects without overrides or interfaces should use the expression form 'new Type(args)' without braces. - /// (Originally from ../FSComp.txt:570) + /// (Originally from ..\FSComp.txt:570) static member tcInvalidObjectExpressionSyntaxForm() = (738, GetStringFunc("tcInvalidObjectExpressionSyntaxForm",",,,") ) /// Invalid object, sequence or record expression - /// (Originally from ../FSComp.txt:571) + /// (Originally from ..\FSComp.txt:571) static member tcInvalidObjectSequenceOrRecordExpression() = (739, GetStringFunc("tcInvalidObjectSequenceOrRecordExpression",",,,") ) /// Invalid record, sequence or computation expression. Sequence expressions should be of the form 'seq { ... }' - /// (Originally from ../FSComp.txt:572) + /// (Originally from ..\FSComp.txt:572) static member tcInvalidSequenceExpressionSyntaxForm() = (740, GetStringFunc("tcInvalidSequenceExpressionSyntaxForm",",,,") ) /// This list or array expression includes an element of the form 'if ... then ... else'. Parenthesize this expression to indicate it is an individual element of the list or array, to disambiguate this from a list generated using a sequence expression - /// (Originally from ../FSComp.txt:573) + /// (Originally from ..\FSComp.txt:573) static member tcExpressionWithIfRequiresParenthesis() = (GetStringFunc("tcExpressionWithIfRequiresParenthesis",",,,") ) /// Unable to parse format string '%s' - /// (Originally from ../FSComp.txt:574) + /// (Originally from ..\FSComp.txt:574) static member tcUnableToParseFormatString(a0 : System.String) = (741, GetStringFunc("tcUnableToParseFormatString",",,,%s,,,") a0) /// This list expression exceeds the maximum size for list literals. Use an array for larger literals and call Array.ToList. - /// (Originally from ../FSComp.txt:575) + /// (Originally from ..\FSComp.txt:575) static member tcListLiteralMaxSize() = (742, GetStringFunc("tcListLiteralMaxSize",",,,") ) /// The expression form 'expr then expr' may only be used as part of an explicit object constructor - /// (Originally from ../FSComp.txt:576) + /// (Originally from ..\FSComp.txt:576) static member tcExpressionFormRequiresObjectConstructor() = (743, GetStringFunc("tcExpressionFormRequiresObjectConstructor",",,,") ) /// Named arguments cannot be given to member trait calls - /// (Originally from ../FSComp.txt:577) + /// (Originally from ..\FSComp.txt:577) static member tcNamedArgumentsCannotBeUsedInMemberTraits() = (744, GetStringFunc("tcNamedArgumentsCannotBeUsedInMemberTraits",",,,") ) /// This is not a valid name for an enumeration case - /// (Originally from ../FSComp.txt:578) + /// (Originally from ..\FSComp.txt:578) static member tcNotValidEnumCaseName() = (745, GetStringFunc("tcNotValidEnumCaseName",",,,") ) /// This field is not mutable - /// (Originally from ../FSComp.txt:579) + /// (Originally from ..\FSComp.txt:579) static member tcFieldIsNotMutable() = (746, GetStringFunc("tcFieldIsNotMutable",",,,") ) /// This construct may only be used within list, array and sequence expressions, e.g. expressions of the form 'seq { ... }', '[ ... ]' or '[| ... |]'. These use the syntax 'for ... in ... do ... yield...' to generate elements - /// (Originally from ../FSComp.txt:580) + /// (Originally from ..\FSComp.txt:580) static member tcConstructRequiresListArrayOrSequence() = (747, GetStringFunc("tcConstructRequiresListArrayOrSequence",",,,") ) /// This construct may only be used within computation expressions. To return a value from an ordinary function simply write the expression without 'return'. - /// (Originally from ../FSComp.txt:581) + /// (Originally from ..\FSComp.txt:581) static member tcConstructRequiresComputationExpressions() = (748, GetStringFunc("tcConstructRequiresComputationExpressions",",,,") ) /// This construct may only be used within sequence or computation expressions - /// (Originally from ../FSComp.txt:582) + /// (Originally from ..\FSComp.txt:582) static member tcConstructRequiresSequenceOrComputations() = (749, GetStringFunc("tcConstructRequiresSequenceOrComputations",",,,") ) /// This construct may only be used within computation expressions - /// (Originally from ../FSComp.txt:583) + /// (Originally from ..\FSComp.txt:583) static member tcConstructRequiresComputationExpression() = (750, GetStringFunc("tcConstructRequiresComputationExpression",",,,") ) /// Invalid indexer expression - /// (Originally from ../FSComp.txt:584) + /// (Originally from ..\FSComp.txt:584) static member tcInvalidIndexerExpression() = (751, GetStringFunc("tcInvalidIndexerExpression",",,,") ) /// The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints - /// (Originally from ../FSComp.txt:585) + /// (Originally from ..\FSComp.txt:585) static member tcObjectOfIndeterminateTypeUsedRequireTypeConstraint() = (752, GetStringFunc("tcObjectOfIndeterminateTypeUsedRequireTypeConstraint",",,,") ) /// Cannot inherit from a variable type - /// (Originally from ../FSComp.txt:586) + /// (Originally from ..\FSComp.txt:586) static member tcCannotInheritFromVariableType() = (753, GetStringFunc("tcCannotInheritFromVariableType",",,,") ) /// Calls to object constructors on type parameters cannot be given arguments - /// (Originally from ../FSComp.txt:587) + /// (Originally from ..\FSComp.txt:587) static member tcObjectConstructorsOnTypeParametersCannotTakeArguments() = (754, GetStringFunc("tcObjectConstructorsOnTypeParametersCannotTakeArguments",",,,") ) /// The 'CompiledName' attribute cannot be used with this language element - /// (Originally from ../FSComp.txt:588) + /// (Originally from ..\FSComp.txt:588) static member tcCompiledNameAttributeMisused() = (755, GetStringFunc("tcCompiledNameAttributeMisused",",,,") ) /// '%s' may only be used with named types - /// (Originally from ../FSComp.txt:589) + /// (Originally from ..\FSComp.txt:589) static member tcNamedTypeRequired(a0 : System.String) = (756, GetStringFunc("tcNamedTypeRequired",",,,%s,,,") a0) /// 'inherit' cannot be used on interface types. Consider implementing the interface by using 'interface ... with ... end' instead. - /// (Originally from ../FSComp.txt:590) + /// (Originally from ..\FSComp.txt:590) static member tcInheritCannotBeUsedOnInterfaceType() = (757, GetStringFunc("tcInheritCannotBeUsedOnInterfaceType",",,,") ) /// 'new' cannot be used on interface types. Consider using an object expression '{ new ... with ... }' instead. - /// (Originally from ../FSComp.txt:591) + /// (Originally from ..\FSComp.txt:591) static member tcNewCannotBeUsedOnInterfaceType() = (758, GetStringFunc("tcNewCannotBeUsedOnInterfaceType",",,,") ) /// Instances of this type cannot be created since it has been marked abstract or not all methods have been given implementations. Consider using an object expression '{ new ... with ... }' instead. - /// (Originally from ../FSComp.txt:592) + /// (Originally from ..\FSComp.txt:592) static member tcAbstractTypeCannotBeInstantiated() = (759, GetStringFunc("tcAbstractTypeCannotBeInstantiated",",,,") ) /// It is recommended that objects supporting the IDisposable interface are created using the syntax 'new Type(args)', rather than 'Type(args)' or 'Type' as a function value representing the constructor, to indicate that resources may be owned by the generated value - /// (Originally from ../FSComp.txt:593) + /// (Originally from ..\FSComp.txt:593) static member tcIDisposableTypeShouldUseNew() = (760, GetStringFunc("tcIDisposableTypeShouldUseNew",",,,") ) /// '%s' may only be used to construct object types - /// (Originally from ../FSComp.txt:594) + /// (Originally from ..\FSComp.txt:594) static member tcSyntaxCanOnlyBeUsedToCreateObjectTypes(a0 : System.String) = (761, GetStringFunc("tcSyntaxCanOnlyBeUsedToCreateObjectTypes",",,,%s,,,") a0) /// Constructors for the type '%s' must directly or indirectly call its implicit object constructor. Use a call to the implicit object constructor instead of a record expression. - /// (Originally from ../FSComp.txt:595) + /// (Originally from ..\FSComp.txt:595) static member tcConstructorRequiresCall(a0 : System.String) = (762, GetStringFunc("tcConstructorRequiresCall",",,,%s,,,") a0) /// The field '%s' has been given a value, but is not present in the type '%s' - /// (Originally from ../FSComp.txt:596) + /// (Originally from ..\FSComp.txt:596) static member tcUndefinedField(a0 : System.String, a1 : System.String) = (763, GetStringFunc("tcUndefinedField",",,,%s,,,%s,,,") a0 a1) /// No assignment given for field '%s' of type '%s' - /// (Originally from ../FSComp.txt:597) + /// (Originally from ..\FSComp.txt:597) static member tcFieldRequiresAssignment(a0 : System.String, a1 : System.String) = (764, GetStringFunc("tcFieldRequiresAssignment",",,,%s,,,%s,,,") a0 a1) /// Extraneous fields have been given values - /// (Originally from ../FSComp.txt:598) + /// (Originally from ..\FSComp.txt:598) static member tcExtraneousFieldsGivenValues() = (765, GetStringFunc("tcExtraneousFieldsGivenValues",",,,") ) /// Only overrides of abstract and virtual members may be specified in object expressions - /// (Originally from ../FSComp.txt:599) + /// (Originally from ..\FSComp.txt:599) static member tcObjectExpressionsCanOnlyOverrideAbstractOrVirtual() = (766, GetStringFunc("tcObjectExpressionsCanOnlyOverrideAbstractOrVirtual",",,,") ) /// The member '%s' does not correspond to any abstract or virtual method available to override or implement. - /// (Originally from ../FSComp.txt:600) + /// (Originally from ..\FSComp.txt:600) static member tcNoAbstractOrVirtualMemberFound(a0 : System.String) = (767, GetStringFunc("tcNoAbstractOrVirtualMemberFound",",,,%s,,,") a0) /// The type %s contains the member '%s' but it is not a virtual or abstract method that is available to override or implement. - /// (Originally from ../FSComp.txt:601) + /// (Originally from ..\FSComp.txt:601) static member tcMemberFoundIsNotAbstractOrVirtual(a0 : System.String, a1 : System.String) = (767, GetStringFunc("tcMemberFoundIsNotAbstractOrVirtual",",,,%s,,,%s,,,") a0 a1) /// The member '%s' does not accept the correct number of arguments. %d argument(s) are expected, but %d were given. The required signature is '%s'.%s - /// (Originally from ../FSComp.txt:602) + /// (Originally from ..\FSComp.txt:602) static member tcArgumentArityMismatch(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.String, a4 : System.String) = (768, GetStringFunc("tcArgumentArityMismatch",",,,%s,,,%d,,,%d,,,%s,,,%s,,,") a0 a1 a2 a3 a4) /// The member '%s' does not accept the correct number of arguments. One overload accepts %d arguments, but %d were given. The required signature is '%s'.%s - /// (Originally from ../FSComp.txt:603) + /// (Originally from ..\FSComp.txt:603) static member tcArgumentArityMismatchOneOverload(a0 : System.String, a1 : System.Int32, a2 : System.Int32, a3 : System.String, a4 : System.String) = (769, GetStringFunc("tcArgumentArityMismatchOneOverload",",,,%s,,,%d,,,%d,,,%s,,,%s,,,") a0 a1 a2 a3 a4) /// A simple method name is required here - /// (Originally from ../FSComp.txt:604) + /// (Originally from ..\FSComp.txt:604) static member tcSimpleMethodNameRequired() = (770, GetStringFunc("tcSimpleMethodNameRequired",",,,") ) /// The types System.ValueType, System.Enum, System.Delegate, System.MulticastDelegate and System.Array cannot be used as super types in an object expression or class - /// (Originally from ../FSComp.txt:605) + /// (Originally from ..\FSComp.txt:605) static member tcPredefinedTypeCannotBeUsedAsSuperType() = (771, GetStringFunc("tcPredefinedTypeCannotBeUsedAsSuperType",",,,") ) /// 'new' must be used with a named type - /// (Originally from ../FSComp.txt:606) + /// (Originally from ..\FSComp.txt:606) static member tcNewMustBeUsedWithNamedType() = (772, GetStringFunc("tcNewMustBeUsedWithNamedType",",,,") ) /// Cannot create an extension of a sealed type - /// (Originally from ../FSComp.txt:607) + /// (Originally from ..\FSComp.txt:607) static member tcCannotCreateExtensionOfSealedType() = (773, GetStringFunc("tcCannotCreateExtensionOfSealedType",",,,") ) /// No arguments may be given when constructing a record value - /// (Originally from ../FSComp.txt:608) + /// (Originally from ..\FSComp.txt:608) static member tcNoArgumentsForRecordValue() = (774, GetStringFunc("tcNoArgumentsForRecordValue",",,,") ) /// Interface implementations cannot be given on construction expressions - /// (Originally from ../FSComp.txt:609) + /// (Originally from ..\FSComp.txt:609) static member tcNoInterfaceImplementationForConstructionExpression() = (775, GetStringFunc("tcNoInterfaceImplementationForConstructionExpression",",,,") ) /// Object construction expressions may only be used to implement constructors in class types - /// (Originally from ../FSComp.txt:610) + /// (Originally from ..\FSComp.txt:610) static member tcObjectConstructionCanOnlyBeUsedInClassTypes() = (776, GetStringFunc("tcObjectConstructionCanOnlyBeUsedInClassTypes",",,,") ) /// Only simple bindings of the form 'id = expr' can be used in construction expressions - /// (Originally from ../FSComp.txt:611) + /// (Originally from ..\FSComp.txt:611) static member tcOnlySimpleBindingsCanBeUsedInConstructionExpressions() = (777, GetStringFunc("tcOnlySimpleBindingsCanBeUsedInConstructionExpressions",",,,") ) /// Objects must be initialized by an object construction expression that calls an inherited object constructor and assigns a value to each field - /// (Originally from ../FSComp.txt:612) + /// (Originally from ..\FSComp.txt:612) static member tcObjectsMustBeInitializedWithObjectExpression() = (778, GetStringFunc("tcObjectsMustBeInitializedWithObjectExpression",",,,") ) /// Expected an interface type - /// (Originally from ../FSComp.txt:613) + /// (Originally from ..\FSComp.txt:613) static member tcExpectedInterfaceType() = (779, GetStringFunc("tcExpectedInterfaceType",",,,") ) /// Constructor expressions for interfaces do not take arguments - /// (Originally from ../FSComp.txt:614) + /// (Originally from ..\FSComp.txt:614) static member tcConstructorForInterfacesDoNotTakeArguments() = (780, GetStringFunc("tcConstructorForInterfacesDoNotTakeArguments",",,,") ) /// This object constructor requires arguments - /// (Originally from ../FSComp.txt:615) + /// (Originally from ..\FSComp.txt:615) static member tcConstructorRequiresArguments() = (781, GetStringFunc("tcConstructorRequiresArguments",",,,") ) /// 'new' may only be used with object constructors - /// (Originally from ../FSComp.txt:616) + /// (Originally from ..\FSComp.txt:616) static member tcNewRequiresObjectConstructor() = (782, GetStringFunc("tcNewRequiresObjectConstructor",",,,") ) /// At least one override did not correctly implement its corresponding abstract member - /// (Originally from ../FSComp.txt:617) + /// (Originally from ..\FSComp.txt:617) static member tcAtLeastOneOverrideIsInvalid() = (783, GetStringFunc("tcAtLeastOneOverrideIsInvalid",",,,") ) /// This numeric literal requires that a module '%s' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope - /// (Originally from ../FSComp.txt:618) + /// (Originally from ..\FSComp.txt:618) static member tcNumericLiteralRequiresModule(a0 : System.String) = (784, GetStringFunc("tcNumericLiteralRequiresModule",",,,%s,,,") a0) /// Invalid record construction - /// (Originally from ../FSComp.txt:619) + /// (Originally from ..\FSComp.txt:619) static member tcInvalidRecordConstruction() = (785, GetStringFunc("tcInvalidRecordConstruction",",,,") ) /// The expression form { expr with ... } may only be used with record types. To build object types use { new Type(...) with ... } - /// (Originally from ../FSComp.txt:620) + /// (Originally from ..\FSComp.txt:620) static member tcExpressionFormRequiresRecordTypes() = (786, GetStringFunc("tcExpressionFormRequiresRecordTypes",",,,") ) /// The inherited type is not an object model type - /// (Originally from ../FSComp.txt:621) + /// (Originally from ..\FSComp.txt:621) static member tcInheritedTypeIsNotObjectModelType() = (787, GetStringFunc("tcInheritedTypeIsNotObjectModelType",",,,") ) /// Object construction expressions (i.e. record expressions with inheritance specifications) may only be used to implement constructors in object model types. Use 'new ObjectType(args)' to construct instances of object model types outside of constructors - /// (Originally from ../FSComp.txt:622) + /// (Originally from ..\FSComp.txt:622) static member tcObjectConstructionExpressionCanOnlyImplementConstructorsInObjectModelTypes() = (788, GetStringFunc("tcObjectConstructionExpressionCanOnlyImplementConstructorsInObjectModelTypes",",,,") ) /// '{ }' is not a valid expression. Records must include at least one field. Empty sequences are specified by using Seq.empty or an empty list '[]'. - /// (Originally from ../FSComp.txt:623) + /// (Originally from ..\FSComp.txt:623) static member tcEmptyRecordInvalid() = (789, GetStringFunc("tcEmptyRecordInvalid",",,,") ) /// This type is not a record type. Values of class and struct types must be created using calls to object constructors. - /// (Originally from ../FSComp.txt:624) + /// (Originally from ..\FSComp.txt:624) static member tcTypeIsNotARecordTypeNeedConstructor() = (790, GetStringFunc("tcTypeIsNotARecordTypeNeedConstructor",",,,") ) /// This type is not a record type - /// (Originally from ../FSComp.txt:625) + /// (Originally from ..\FSComp.txt:625) static member tcTypeIsNotARecordType() = (791, GetStringFunc("tcTypeIsNotARecordType",",,,") ) /// This construct is ambiguous as part of a computation expression. Nested expressions may be written using 'let _ = (...)' and nested computations using 'let! res = builder { ... }'. - /// (Originally from ../FSComp.txt:626) + /// (Originally from ..\FSComp.txt:626) static member tcConstructIsAmbiguousInComputationExpression() = (792, GetStringFunc("tcConstructIsAmbiguousInComputationExpression",",,,") ) /// This construct is ambiguous as part of a sequence expression. Nested expressions may be written using 'let _ = (...)' and nested sequences using 'yield! seq {... }'. - /// (Originally from ../FSComp.txt:627) + /// (Originally from ..\FSComp.txt:627) static member tcConstructIsAmbiguousInSequenceExpression() = (793, GetStringFunc("tcConstructIsAmbiguousInSequenceExpression",",,,") ) /// 'do!' cannot be used within sequence expressions - /// (Originally from ../FSComp.txt:628) + /// (Originally from ..\FSComp.txt:628) static member tcDoBangIllegalInSequenceExpression() = (794, GetStringFunc("tcDoBangIllegalInSequenceExpression",",,,") ) /// The use of 'let! x = coll' in sequence expressions is not permitted. Use 'for x in coll' instead. - /// (Originally from ../FSComp.txt:629) + /// (Originally from ..\FSComp.txt:629) static member tcUseForInSequenceExpression() = (795, GetStringFunc("tcUseForInSequenceExpression",",,,") ) /// 'try'/'with' cannot be used within sequence expressions - /// (Originally from ../FSComp.txt:630) + /// (Originally from ..\FSComp.txt:630) static member tcTryIllegalInSequenceExpression() = (796, GetStringFunc("tcTryIllegalInSequenceExpression",",,,") ) /// In sequence expressions, multiple results are generated using 'yield!' - /// (Originally from ../FSComp.txt:631) + /// (Originally from ..\FSComp.txt:631) static member tcUseYieldBangForMultipleResults() = (797, GetStringFunc("tcUseYieldBangForMultipleResults",",,,") ) /// Invalid assignment - /// (Originally from ../FSComp.txt:632) + /// (Originally from ..\FSComp.txt:632) static member tcInvalidAssignment() = (799, GetStringFunc("tcInvalidAssignment",",,,") ) /// Invalid use of a type name - /// (Originally from ../FSComp.txt:633) + /// (Originally from ..\FSComp.txt:633) static member tcInvalidUseOfTypeName() = (800, GetStringFunc("tcInvalidUseOfTypeName",",,,") ) /// This type has no accessible object constructors - /// (Originally from ../FSComp.txt:634) + /// (Originally from ..\FSComp.txt:634) static member tcTypeHasNoAccessibleConstructor() = (801, GetStringFunc("tcTypeHasNoAccessibleConstructor",",,,") ) /// Invalid use of an interface type - /// (Originally from ../FSComp.txt:637) + /// (Originally from ..\FSComp.txt:637) static member tcInvalidUseOfInterfaceType() = (804, GetStringFunc("tcInvalidUseOfInterfaceType",",,,") ) /// Invalid use of a delegate constructor. Use the syntax 'new Type(args)' or just 'Type(args)'. - /// (Originally from ../FSComp.txt:638) + /// (Originally from ..\FSComp.txt:638) static member tcInvalidUseOfDelegate() = (805, GetStringFunc("tcInvalidUseOfDelegate",",,,") ) /// Property '%s' is not static - /// (Originally from ../FSComp.txt:639) + /// (Originally from ..\FSComp.txt:639) static member tcPropertyIsNotStatic(a0 : System.String) = (806, GetStringFunc("tcPropertyIsNotStatic",",,,%s,,,") a0) /// Property '%s' is not readable - /// (Originally from ../FSComp.txt:640) + /// (Originally from ..\FSComp.txt:640) static member tcPropertyIsNotReadable(a0 : System.String) = (807, GetStringFunc("tcPropertyIsNotReadable",",,,%s,,,") a0) /// This lookup cannot be used here - /// (Originally from ../FSComp.txt:641) + /// (Originally from ..\FSComp.txt:641) static member tcLookupMayNotBeUsedHere() = (808, GetStringFunc("tcLookupMayNotBeUsedHere",",,,") ) /// Property '%s' is static - /// (Originally from ../FSComp.txt:642) + /// (Originally from ..\FSComp.txt:642) static member tcPropertyIsStatic(a0 : System.String) = (809, GetStringFunc("tcPropertyIsStatic",",,,%s,,,") a0) /// Property '%s' cannot be set - /// (Originally from ../FSComp.txt:643) + /// (Originally from ..\FSComp.txt:643) static member tcPropertyCannotBeSet1(a0 : System.String) = (810, GetStringFunc("tcPropertyCannotBeSet1",",,,%s,,,") a0) /// Constructors must be applied to arguments and cannot be used as first-class values. If necessary use an anonymous function '(fun arg1 ... argN -> new Type(arg1,...,argN))'. - /// (Originally from ../FSComp.txt:644) + /// (Originally from ..\FSComp.txt:644) static member tcConstructorsCannotBeFirstClassValues() = (811, GetStringFunc("tcConstructorsCannotBeFirstClassValues",",,,") ) /// The syntax 'expr.id' may only be used with record labels, properties and fields - /// (Originally from ../FSComp.txt:645) + /// (Originally from ..\FSComp.txt:645) static member tcSyntaxFormUsedOnlyWithRecordLabelsPropertiesAndFields() = (812, GetStringFunc("tcSyntaxFormUsedOnlyWithRecordLabelsPropertiesAndFields",",,,") ) /// Event '%s' is static - /// (Originally from ../FSComp.txt:646) + /// (Originally from ..\FSComp.txt:646) static member tcEventIsStatic(a0 : System.String) = (813, GetStringFunc("tcEventIsStatic",",,,%s,,,") a0) /// Event '%s' is not static - /// (Originally from ../FSComp.txt:647) + /// (Originally from ..\FSComp.txt:647) static member tcEventIsNotStatic(a0 : System.String) = (814, GetStringFunc("tcEventIsNotStatic",",,,%s,,,") a0) /// The named argument '%s' did not match any argument or mutable property - /// (Originally from ../FSComp.txt:648) + /// (Originally from ..\FSComp.txt:648) static member tcNamedArgumentDidNotMatch(a0 : System.String) = (815, GetStringFunc("tcNamedArgumentDidNotMatch",",,,%s,,,") a0) /// One or more of the overloads of this method has curried arguments. Consider redesigning these members to take arguments in tupled form. - /// (Originally from ../FSComp.txt:649) + /// (Originally from ..\FSComp.txt:649) static member tcOverloadsCannotHaveCurriedArguments() = (816, GetStringFunc("tcOverloadsCannotHaveCurriedArguments",",,,") ) /// The unnamed arguments do not form a prefix of the arguments of the method called - /// (Originally from ../FSComp.txt:650) + /// (Originally from ..\FSComp.txt:650) static member tcUnnamedArgumentsDoNotFormPrefix() = (GetStringFunc("tcUnnamedArgumentsDoNotFormPrefix",",,,") ) /// Static optimization conditionals are only for use within the F# library - /// (Originally from ../FSComp.txt:651) + /// (Originally from ..\FSComp.txt:651) static member tcStaticOptimizationConditionalsOnlyForFSharpLibrary() = (817, GetStringFunc("tcStaticOptimizationConditionalsOnlyForFSharpLibrary",",,,") ) /// The corresponding formal argument is not optional - /// (Originally from ../FSComp.txt:652) + /// (Originally from ..\FSComp.txt:652) static member tcFormalArgumentIsNotOptional() = (818, GetStringFunc("tcFormalArgumentIsNotOptional",",,,") ) /// Invalid optional assignment to a property or field - /// (Originally from ../FSComp.txt:653) + /// (Originally from ..\FSComp.txt:653) static member tcInvalidOptionalAssignmentToPropertyOrField() = (819, GetStringFunc("tcInvalidOptionalAssignmentToPropertyOrField",",,,") ) /// A delegate constructor must be passed a single function value - /// (Originally from ../FSComp.txt:654) + /// (Originally from ..\FSComp.txt:654) static member tcDelegateConstructorMustBePassed() = (820, GetStringFunc("tcDelegateConstructorMustBePassed",",,,") ) /// A binding cannot be marked both 'use' and 'rec' - /// (Originally from ../FSComp.txt:655) + /// (Originally from ..\FSComp.txt:655) static member tcBindingCannotBeUseAndRec() = (821, GetStringFunc("tcBindingCannotBeUseAndRec",",,,") ) /// The 'VolatileField' attribute may only be used on 'let' bindings in classes - /// (Originally from ../FSComp.txt:656) + /// (Originally from ..\FSComp.txt:656) static member tcVolatileOnlyOnClassLetBindings() = (823, GetStringFunc("tcVolatileOnlyOnClassLetBindings",",,,") ) /// Attributes are not permitted on 'let' bindings in expressions - /// (Originally from ../FSComp.txt:657) + /// (Originally from ..\FSComp.txt:657) static member tcAttributesAreNotPermittedOnLetBindings() = (824, GetStringFunc("tcAttributesAreNotPermittedOnLetBindings",",,,") ) /// The 'DefaultValue' attribute may only be used on 'val' declarations - /// (Originally from ../FSComp.txt:658) + /// (Originally from ..\FSComp.txt:658) static member tcDefaultValueAttributeRequiresVal() = (825, GetStringFunc("tcDefaultValueAttributeRequiresVal",",,,") ) /// The 'ConditionalAttribute' attribute may only be used on members - /// (Originally from ../FSComp.txt:659) + /// (Originally from ..\FSComp.txt:659) static member tcConditionalAttributeRequiresMembers() = (826, GetStringFunc("tcConditionalAttributeRequiresMembers",",,,") ) /// This is not a valid name for an active pattern - /// (Originally from ../FSComp.txt:660) + /// (Originally from ..\FSComp.txt:660) static member tcInvalidActivePatternName() = (827, GetStringFunc("tcInvalidActivePatternName",",,,") ) /// The 'EntryPointAttribute' attribute may only be used on function definitions in modules - /// (Originally from ../FSComp.txt:661) + /// (Originally from ..\FSComp.txt:661) static member tcEntryPointAttributeRequiresFunctionInModule() = (828, GetStringFunc("tcEntryPointAttributeRequiresFunctionInModule",",,,") ) /// Mutable values cannot be marked 'inline' - /// (Originally from ../FSComp.txt:662) + /// (Originally from ..\FSComp.txt:662) static member tcMutableValuesCannotBeInline() = (829, GetStringFunc("tcMutableValuesCannotBeInline",",,,") ) /// Mutable values cannot have generic parameters - /// (Originally from ../FSComp.txt:663) + /// (Originally from ..\FSComp.txt:663) static member tcMutableValuesMayNotHaveGenericParameters() = (830, GetStringFunc("tcMutableValuesMayNotHaveGenericParameters",",,,") ) /// Mutable function values should be written 'let mutable f = (fun args -> ...)' - /// (Originally from ../FSComp.txt:664) + /// (Originally from ..\FSComp.txt:664) static member tcMutableValuesSyntax() = (831, GetStringFunc("tcMutableValuesSyntax",",,,") ) /// Only functions may be marked 'inline' - /// (Originally from ../FSComp.txt:665) + /// (Originally from ..\FSComp.txt:665) static member tcOnlyFunctionsCanBeInline() = (832, GetStringFunc("tcOnlyFunctionsCanBeInline",",,,") ) /// A literal value cannot be given the [] or [] attributes - /// (Originally from ../FSComp.txt:666) + /// (Originally from ..\FSComp.txt:666) static member tcIllegalAttributesForLiteral() = (833, GetStringFunc("tcIllegalAttributesForLiteral",",,,") ) /// A literal value cannot be marked 'mutable' - /// (Originally from ../FSComp.txt:667) + /// (Originally from ..\FSComp.txt:667) static member tcLiteralCannotBeMutable() = (834, GetStringFunc("tcLiteralCannotBeMutable",",,,") ) /// A literal value cannot be marked 'inline' - /// (Originally from ../FSComp.txt:668) + /// (Originally from ..\FSComp.txt:668) static member tcLiteralCannotBeInline() = (835, GetStringFunc("tcLiteralCannotBeInline",",,,") ) /// Literal values cannot have generic parameters - /// (Originally from ../FSComp.txt:669) + /// (Originally from ..\FSComp.txt:669) static member tcLiteralCannotHaveGenericParameters() = (836, GetStringFunc("tcLiteralCannotHaveGenericParameters",",,,") ) /// This is not a valid constant expression - /// (Originally from ../FSComp.txt:670) + /// (Originally from ..\FSComp.txt:670) static member tcInvalidConstantExpression() = (837, GetStringFunc("tcInvalidConstantExpression",",,,") ) /// This type is not accessible from this code location - /// (Originally from ../FSComp.txt:671) + /// (Originally from ..\FSComp.txt:671) static member tcTypeIsInaccessible() = (838, GetStringFunc("tcTypeIsInaccessible",",,,") ) /// Unexpected condition in imported assembly: failed to decode AttributeUsage attribute - /// (Originally from ../FSComp.txt:672) + /// (Originally from ..\FSComp.txt:672) static member tcUnexpectedConditionInImportedAssembly() = (839, GetStringFunc("tcUnexpectedConditionInImportedAssembly",",,,") ) /// Unrecognized attribute target. Valid attribute targets are 'assembly', 'module', 'type', 'method', 'property', 'return', 'param', 'field', 'event', 'constructor'. - /// (Originally from ../FSComp.txt:673) + /// (Originally from ..\FSComp.txt:673) static member tcUnrecognizedAttributeTarget() = (840, GetStringFunc("tcUnrecognizedAttributeTarget",",,,") ) /// This attribute is not valid for use on this language element. Assembly attributes should be attached to a 'do ()' declaration, if necessary within an F# module. - /// (Originally from ../FSComp.txt:674) + /// (Originally from ..\FSComp.txt:674) static member tcAttributeIsNotValidForLanguageElementUseDo() = (841, GetStringFunc("tcAttributeIsNotValidForLanguageElementUseDo",",,,") ) /// This attribute is not valid for use on this language element - /// (Originally from ../FSComp.txt:675) + /// (Originally from ..\FSComp.txt:675) static member tcAttributeIsNotValidForLanguageElement() = (842, GetStringFunc("tcAttributeIsNotValidForLanguageElement",",,,") ) /// Optional arguments cannot be used in custom attributes - /// (Originally from ../FSComp.txt:676) + /// (Originally from ..\FSComp.txt:676) static member tcOptionalArgumentsCannotBeUsedInCustomAttribute() = (843, GetStringFunc("tcOptionalArgumentsCannotBeUsedInCustomAttribute",",,,") ) /// This property cannot be set - /// (Originally from ../FSComp.txt:677) + /// (Originally from ..\FSComp.txt:677) static member tcPropertyCannotBeSet0() = (844, GetStringFunc("tcPropertyCannotBeSet0",",,,") ) /// This property or field was not found on this custom attribute type - /// (Originally from ../FSComp.txt:678) + /// (Originally from ..\FSComp.txt:678) static member tcPropertyOrFieldNotFoundInAttribute() = (845, GetStringFunc("tcPropertyOrFieldNotFoundInAttribute",",,,") ) /// A custom attribute must be a reference type - /// (Originally from ../FSComp.txt:679) + /// (Originally from ..\FSComp.txt:679) static member tcCustomAttributeMustBeReferenceType() = (846, GetStringFunc("tcCustomAttributeMustBeReferenceType",",,,") ) /// The number of args for a custom attribute does not match the expected number of args for the attribute constructor - /// (Originally from ../FSComp.txt:680) + /// (Originally from ..\FSComp.txt:680) static member tcCustomAttributeArgumentMismatch() = (847, GetStringFunc("tcCustomAttributeArgumentMismatch",",,,") ) /// A custom attribute must invoke an object constructor - /// (Originally from ../FSComp.txt:681) + /// (Originally from ..\FSComp.txt:681) static member tcCustomAttributeMustInvokeConstructor() = (848, GetStringFunc("tcCustomAttributeMustInvokeConstructor",",,,") ) /// Attribute expressions must be calls to object constructors - /// (Originally from ../FSComp.txt:682) + /// (Originally from ..\FSComp.txt:682) static member tcAttributeExpressionsMustBeConstructorCalls() = (849, GetStringFunc("tcAttributeExpressionsMustBeConstructorCalls",",,,") ) /// This attribute cannot be used in this version of F# - /// (Originally from ../FSComp.txt:683) + /// (Originally from ..\FSComp.txt:683) static member tcUnsupportedAttribute() = (850, GetStringFunc("tcUnsupportedAttribute",",,,") ) /// Invalid inline specification - /// (Originally from ../FSComp.txt:684) + /// (Originally from ..\FSComp.txt:684) static member tcInvalidInlineSpecification() = (851, GetStringFunc("tcInvalidInlineSpecification",",,,") ) /// 'use' bindings must be of the form 'use = ' - /// (Originally from ../FSComp.txt:685) + /// (Originally from ..\FSComp.txt:685) static member tcInvalidUseBinding() = (852, GetStringFunc("tcInvalidUseBinding",",,,") ) /// Abstract members are not permitted in an augmentation - they must be defined as part of the type itself - /// (Originally from ../FSComp.txt:686) + /// (Originally from ..\FSComp.txt:686) static member tcAbstractMembersIllegalInAugmentation() = (853, GetStringFunc("tcAbstractMembersIllegalInAugmentation",",,,") ) /// Method overrides and interface implementations are not permitted here - /// (Originally from ../FSComp.txt:687) + /// (Originally from ..\FSComp.txt:687) static member tcMethodOverridesIllegalHere() = (854, GetStringFunc("tcMethodOverridesIllegalHere",",,,") ) /// No abstract or interface member was found that corresponds to this override - /// (Originally from ../FSComp.txt:688) + /// (Originally from ..\FSComp.txt:688) static member tcNoMemberFoundForOverride() = (855, GetStringFunc("tcNoMemberFoundForOverride",",,,") ) /// This override takes a different number of arguments to the corresponding abstract member. The following abstract members were found:%s - /// (Originally from ../FSComp.txt:689) + /// (Originally from ..\FSComp.txt:689) static member tcOverrideArityMismatch(a0 : System.String) = (856, GetStringFunc("tcOverrideArityMismatch",",,,%s,,,") a0) /// This method already has a default implementation - /// (Originally from ../FSComp.txt:690) + /// (Originally from ..\FSComp.txt:690) static member tcDefaultImplementationAlreadyExists() = (857, GetStringFunc("tcDefaultImplementationAlreadyExists",",,,") ) /// The method implemented by this default is ambiguous - /// (Originally from ../FSComp.txt:691) + /// (Originally from ..\FSComp.txt:691) static member tcDefaultAmbiguous() = (858, GetStringFunc("tcDefaultAmbiguous",",,,") ) /// No abstract property was found that corresponds to this override - /// (Originally from ../FSComp.txt:692) + /// (Originally from ..\FSComp.txt:692) static member tcNoPropertyFoundForOverride() = (859, GetStringFunc("tcNoPropertyFoundForOverride",",,,") ) /// This property overrides or implements an abstract property but the abstract property doesn't have a corresponding %s - /// (Originally from ../FSComp.txt:693) + /// (Originally from ..\FSComp.txt:693) static member tcAbstractPropertyMissingGetOrSet(a0 : System.String) = (860, GetStringFunc("tcAbstractPropertyMissingGetOrSet",",,,%s,,,") a0) /// Invalid signature for set member - /// (Originally from ../FSComp.txt:694) + /// (Originally from ..\FSComp.txt:694) static member tcInvalidSignatureForSet() = (861, GetStringFunc("tcInvalidSignatureForSet",",,,") ) /// This new member hides the abstract member '%s'. Rename the member or use 'override' instead. - /// (Originally from ../FSComp.txt:695) + /// (Originally from ..\FSComp.txt:695) static member tcNewMemberHidesAbstractMember(a0 : System.String) = (864, GetStringFunc("tcNewMemberHidesAbstractMember",",,,%s,,,") a0) /// This new member hides the abstract member '%s' once tuples, functions, units of measure and/or provided types are erased. Rename the member or use 'override' instead. - /// (Originally from ../FSComp.txt:696) + /// (Originally from ..\FSComp.txt:696) static member tcNewMemberHidesAbstractMemberWithSuffix(a0 : System.String) = (864, GetStringFunc("tcNewMemberHidesAbstractMemberWithSuffix",",,,%s,,,") a0) /// Interfaces cannot contain definitions of static initializers - /// (Originally from ../FSComp.txt:697) + /// (Originally from ..\FSComp.txt:697) static member tcStaticInitializersIllegalInInterface() = (865, GetStringFunc("tcStaticInitializersIllegalInInterface",",,,") ) /// Interfaces cannot contain definitions of object constructors - /// (Originally from ../FSComp.txt:698) + /// (Originally from ..\FSComp.txt:698) static member tcObjectConstructorsIllegalInInterface() = (866, GetStringFunc("tcObjectConstructorsIllegalInInterface",",,,") ) /// Interfaces cannot contain definitions of member overrides - /// (Originally from ../FSComp.txt:699) + /// (Originally from ..\FSComp.txt:699) static member tcMemberOverridesIllegalInInterface() = (867, GetStringFunc("tcMemberOverridesIllegalInInterface",",,,") ) /// Interfaces cannot contain definitions of concrete members. You may need to define a constructor on your type to indicate that the type is a class. - /// (Originally from ../FSComp.txt:700) + /// (Originally from ..\FSComp.txt:700) static member tcConcreteMembersIllegalInInterface() = (868, GetStringFunc("tcConcreteMembersIllegalInInterface",",,,") ) /// Constructors cannot be specified in exception augmentations - /// (Originally from ../FSComp.txt:701) + /// (Originally from ..\FSComp.txt:701) static member tcConstructorsDisallowedInExceptionAugmentation() = (869, GetStringFunc("tcConstructorsDisallowedInExceptionAugmentation",",,,") ) /// Structs cannot have an object constructor with no arguments. This is a restriction imposed on all CLI languages as structs automatically support a default constructor. - /// (Originally from ../FSComp.txt:702) + /// (Originally from ..\FSComp.txt:702) static member tcStructsCannotHaveConstructorWithNoArguments() = (870, GetStringFunc("tcStructsCannotHaveConstructorWithNoArguments",",,,") ) /// Constructors cannot be defined for this type - /// (Originally from ../FSComp.txt:703) + /// (Originally from ..\FSComp.txt:703) static member tcConstructorsIllegalForThisType() = (871, GetStringFunc("tcConstructorsIllegalForThisType",",,,") ) /// Recursive bindings that include member specifications can only occur as a direct augmentation of a type - /// (Originally from ../FSComp.txt:704) + /// (Originally from ..\FSComp.txt:704) static member tcRecursiveBindingsWithMembersMustBeDirectAugmentation() = (872, GetStringFunc("tcRecursiveBindingsWithMembersMustBeDirectAugmentation",",,,") ) /// Only simple variable patterns can be bound in 'let rec' constructs - /// (Originally from ../FSComp.txt:705) + /// (Originally from ..\FSComp.txt:705) static member tcOnlySimplePatternsInLetRec() = (873, GetStringFunc("tcOnlySimplePatternsInLetRec",",,,") ) /// Only record fields and simple, non-recursive 'let' bindings may be marked mutable - /// (Originally from ../FSComp.txt:706) + /// (Originally from ..\FSComp.txt:706) static member tcOnlyRecordFieldsAndSimpleLetCanBeMutable() = (874, GetStringFunc("tcOnlyRecordFieldsAndSimpleLetCanBeMutable",",,,") ) /// This member is not sufficiently generic - /// (Originally from ../FSComp.txt:707) + /// (Originally from ..\FSComp.txt:707) static member tcMemberIsNotSufficientlyGeneric() = (875, GetStringFunc("tcMemberIsNotSufficientlyGeneric",",,,") ) /// A declaration may only be the [] attribute if a constant value is also given, e.g. 'val x : int = 1' - /// (Originally from ../FSComp.txt:708) + /// (Originally from ..\FSComp.txt:708) static member tcLiteralAttributeRequiresConstantValue() = (876, GetStringFunc("tcLiteralAttributeRequiresConstantValue",",,,") ) /// A declaration may only be given a value in a signature if the declaration has the [] attribute - /// (Originally from ../FSComp.txt:709) + /// (Originally from ..\FSComp.txt:709) static member tcValueInSignatureRequiresLiteralAttribute() = (877, GetStringFunc("tcValueInSignatureRequiresLiteralAttribute",",,,") ) /// Thread-static and context-static variables must be static and given the [] attribute to indicate that the value is initialized to the default value on each new thread - /// (Originally from ../FSComp.txt:710) + /// (Originally from ..\FSComp.txt:710) static member tcThreadStaticAndContextStaticMustBeStatic() = (878, GetStringFunc("tcThreadStaticAndContextStaticMustBeStatic",",,,") ) /// Volatile fields must be marked 'mutable' and cannot be thread-static - /// (Originally from ../FSComp.txt:711) + /// (Originally from ..\FSComp.txt:711) static member tcVolatileFieldsMustBeMutable() = (879, GetStringFunc("tcVolatileFieldsMustBeMutable",",,,") ) /// Uninitialized 'val' fields must be mutable and marked with the '[]' attribute. Consider using a 'let' binding instead of a 'val' field. - /// (Originally from ../FSComp.txt:712) + /// (Originally from ..\FSComp.txt:712) static member tcUninitializedValFieldsMustBeMutable() = (880, GetStringFunc("tcUninitializedValFieldsMustBeMutable",",,,") ) /// Static 'val' fields in types must be mutable, private and marked with the '[]' attribute. They are initialized to the 'null' or 'zero' value for their type. Consider also using a 'static let mutable' binding in a class type. - /// (Originally from ../FSComp.txt:713) + /// (Originally from ..\FSComp.txt:713) static member tcStaticValFieldsMustBeMutableAndPrivate() = (881, GetStringFunc("tcStaticValFieldsMustBeMutableAndPrivate",",,,") ) /// This field requires a name - /// (Originally from ../FSComp.txt:714) + /// (Originally from ..\FSComp.txt:714) static member tcFieldRequiresName() = (882, GetStringFunc("tcFieldRequiresName",",,,") ) /// Invalid namespace, module, type or union case name - /// (Originally from ../FSComp.txt:715) + /// (Originally from ..\FSComp.txt:715) static member tcInvalidNamespaceModuleTypeUnionName() = (883, GetStringFunc("tcInvalidNamespaceModuleTypeUnionName",",,,") ) /// Explicit type declarations for constructors must be of the form 'ty1 * ... * tyN -> resTy'. Parentheses may be required around 'resTy' - /// (Originally from ../FSComp.txt:716) + /// (Originally from ..\FSComp.txt:716) static member tcIllegalFormForExplicitTypeDeclaration() = (884, GetStringFunc("tcIllegalFormForExplicitTypeDeclaration",",,,") ) /// Return types of union cases must be identical to the type being defined, up to abbreviations - /// (Originally from ../FSComp.txt:717) + /// (Originally from ..\FSComp.txt:717) static member tcReturnTypesForUnionMustBeSameAsType() = (885, GetStringFunc("tcReturnTypesForUnionMustBeSameAsType",",,,") ) /// This is not a valid value for an enumeration literal - /// (Originally from ../FSComp.txt:718) + /// (Originally from ..\FSComp.txt:718) static member tcInvalidEnumerationLiteral() = (886, GetStringFunc("tcInvalidEnumerationLiteral",",,,") ) /// The type '%s' is not an interface type - /// (Originally from ../FSComp.txt:719) + /// (Originally from ..\FSComp.txt:719) static member tcTypeIsNotInterfaceType1(a0 : System.String) = (887, GetStringFunc("tcTypeIsNotInterfaceType1",",,,%s,,,") a0) /// Duplicate specification of an interface - /// (Originally from ../FSComp.txt:720) + /// (Originally from ..\FSComp.txt:720) static member tcDuplicateSpecOfInterface() = (888, GetStringFunc("tcDuplicateSpecOfInterface",",,,") ) /// A field/val declaration is not permitted here - /// (Originally from ../FSComp.txt:721) + /// (Originally from ..\FSComp.txt:721) static member tcFieldValIllegalHere() = (889, GetStringFunc("tcFieldValIllegalHere",",,,") ) /// A inheritance declaration is not permitted here - /// (Originally from ../FSComp.txt:722) + /// (Originally from ..\FSComp.txt:722) static member tcInheritIllegalHere() = (890, GetStringFunc("tcInheritIllegalHere",",,,") ) /// This declaration opens the module '%s', which is marked as 'RequireQualifiedAccess'. Adjust your code to use qualified references to the elements of the module instead, e.g. 'List.map' instead of 'map'. This change will ensure that your code is robust as new constructs are added to libraries. - /// (Originally from ../FSComp.txt:723) + /// (Originally from ..\FSComp.txt:723) static member tcModuleRequiresQualifiedAccess(a0 : System.String) = (892, GetStringFunc("tcModuleRequiresQualifiedAccess",",,,%s,,,") a0) /// This declaration opens the namespace or module '%s' through a partially qualified path. Adjust this code to use the full path of the namespace. This change will make your code more robust as new constructs are added to the F# and CLI libraries. - /// (Originally from ../FSComp.txt:724) + /// (Originally from ..\FSComp.txt:724) static member tcOpenUsedWithPartiallyQualifiedPath(a0 : System.String) = (893, GetStringFunc("tcOpenUsedWithPartiallyQualifiedPath",",,,%s,,,") a0) /// Local class bindings cannot be marked inline. Consider lifting the definition out of the class or else do not mark it as inline. - /// (Originally from ../FSComp.txt:725) + /// (Originally from ..\FSComp.txt:725) static member tcLocalClassBindingsCannotBeInline() = (894, GetStringFunc("tcLocalClassBindingsCannotBeInline",",,,") ) /// Type abbreviations cannot have members - /// (Originally from ../FSComp.txt:726) + /// (Originally from ..\FSComp.txt:726) static member tcTypeAbbreviationsMayNotHaveMembers() = (895, GetStringFunc("tcTypeAbbreviationsMayNotHaveMembers",",,,") ) /// As of F# 4.1, the accessibility of type abbreviations is checked at compile-time. Consider changing the accessibility of the type abbreviation. Ignoring this warning might lead to runtime errors. - /// (Originally from ../FSComp.txt:727) + /// (Originally from ..\FSComp.txt:727) static member tcTypeAbbreviationsCheckedAtCompileTime() = (GetStringFunc("tcTypeAbbreviationsCheckedAtCompileTime",",,,") ) /// Enumerations cannot have members - /// (Originally from ../FSComp.txt:728) + /// (Originally from ..\FSComp.txt:728) static member tcEnumerationsMayNotHaveMembers() = (896, GetStringFunc("tcEnumerationsMayNotHaveMembers",",,,") ) /// Measure declarations may have only static members - /// (Originally from ../FSComp.txt:729) + /// (Originally from ..\FSComp.txt:729) static member tcMeasureDeclarationsRequireStaticMembers() = (897, GetStringFunc("tcMeasureDeclarationsRequireStaticMembers",",,,") ) /// Structs cannot contain 'do' bindings because the default constructor for structs would not execute these bindings - /// (Originally from ../FSComp.txt:730) + /// (Originally from ..\FSComp.txt:730) static member tcStructsMayNotContainDoBindings() = (GetStringFunc("tcStructsMayNotContainDoBindings",",,,") ) /// Structs cannot contain value definitions because the default constructor for structs will not execute these bindings. Consider adding additional arguments to the primary constructor for the type. - /// (Originally from ../FSComp.txt:731) + /// (Originally from ..\FSComp.txt:731) static member tcStructsMayNotContainLetBindings() = (901, GetStringFunc("tcStructsMayNotContainLetBindings",",,,") ) /// Static value definitions may only be used in types with a primary constructor. Consider adding arguments to the type definition, e.g. 'type X(args) = ...'. - /// (Originally from ../FSComp.txt:732) + /// (Originally from ..\FSComp.txt:732) static member tcStaticLetBindingsRequireClassesWithImplicitConstructors() = (902, GetStringFunc("tcStaticLetBindingsRequireClassesWithImplicitConstructors",",,,") ) /// Measure declarations may have only static members: constructors are not available - /// (Originally from ../FSComp.txt:733) + /// (Originally from ..\FSComp.txt:733) static member tcMeasureDeclarationsRequireStaticMembersNotConstructors() = (904, GetStringFunc("tcMeasureDeclarationsRequireStaticMembersNotConstructors",",,,") ) /// A member and a local class binding both have the name '%s' - /// (Originally from ../FSComp.txt:734) + /// (Originally from ..\FSComp.txt:734) static member tcMemberAndLocalClassBindingHaveSameName(a0 : System.String) = (905, GetStringFunc("tcMemberAndLocalClassBindingHaveSameName",",,,%s,,,") a0) /// Type abbreviations cannot have interface declarations - /// (Originally from ../FSComp.txt:735) + /// (Originally from ..\FSComp.txt:735) static member tcTypeAbbreviationsCannotHaveInterfaceDeclaration() = (906, GetStringFunc("tcTypeAbbreviationsCannotHaveInterfaceDeclaration",",,,") ) /// Enumerations cannot have interface declarations - /// (Originally from ../FSComp.txt:736) + /// (Originally from ..\FSComp.txt:736) static member tcEnumerationsCannotHaveInterfaceDeclaration() = (907, GetStringFunc("tcEnumerationsCannotHaveInterfaceDeclaration",",,,") ) /// This type is not an interface type - /// (Originally from ../FSComp.txt:737) + /// (Originally from ..\FSComp.txt:737) static member tcTypeIsNotInterfaceType0() = (908, GetStringFunc("tcTypeIsNotInterfaceType0",",,,") ) /// All implemented interfaces should be declared on the initial declaration of the type - /// (Originally from ../FSComp.txt:738) + /// (Originally from ..\FSComp.txt:738) static member tcAllImplementedInterfacesShouldBeDeclared() = (909, GetStringFunc("tcAllImplementedInterfacesShouldBeDeclared",",,,") ) /// A default implementation of this interface has already been added because the explicit implementation of the interface was not specified at the definition of the type - /// (Originally from ../FSComp.txt:739) + /// (Originally from ..\FSComp.txt:739) static member tcDefaultImplementationForInterfaceHasAlreadyBeenAdded() = (910, GetStringFunc("tcDefaultImplementationForInterfaceHasAlreadyBeenAdded",",,,") ) /// This member is not permitted in an interface implementation - /// (Originally from ../FSComp.txt:740) + /// (Originally from ..\FSComp.txt:740) static member tcMemberNotPermittedInInterfaceImplementation() = (911, GetStringFunc("tcMemberNotPermittedInInterfaceImplementation",",,,") ) /// This declaration element is not permitted in an augmentation - /// (Originally from ../FSComp.txt:741) + /// (Originally from ..\FSComp.txt:741) static member tcDeclarationElementNotPermittedInAugmentation() = (912, GetStringFunc("tcDeclarationElementNotPermittedInAugmentation",",,,") ) /// Types cannot contain nested type definitions - /// (Originally from ../FSComp.txt:742) + /// (Originally from ..\FSComp.txt:742) static member tcTypesCannotContainNestedTypes() = (913, GetStringFunc("tcTypesCannotContainNestedTypes",",,,") ) /// type, exception or module - /// (Originally from ../FSComp.txt:743) + /// (Originally from ..\FSComp.txt:743) static member tcTypeExceptionOrModule() = (GetStringFunc("tcTypeExceptionOrModule",",,,") ) /// type or module - /// (Originally from ../FSComp.txt:744) + /// (Originally from ..\FSComp.txt:744) static member tcTypeOrModule() = (GetStringFunc("tcTypeOrModule",",,,") ) /// The struct, record or union type '%s' implements the interface 'System.IStructuralEquatable' explicitly. Apply the 'CustomEquality' attribute to the type. - /// (Originally from ../FSComp.txt:745) + /// (Originally from ..\FSComp.txt:745) static member tcImplementsIStructuralEquatableExplicitly(a0 : System.String) = (914, GetStringFunc("tcImplementsIStructuralEquatableExplicitly",",,,%s,,,") a0) /// The struct, record or union type '%s' implements the interface 'System.IEquatable<_>' explicitly. Apply the 'CustomEquality' attribute to the type and provide a consistent implementation of the non-generic override 'System.Object.Equals(obj)'. - /// (Originally from ../FSComp.txt:746) + /// (Originally from ..\FSComp.txt:746) static member tcImplementsIEquatableExplicitly(a0 : System.String) = (915, GetStringFunc("tcImplementsIEquatableExplicitly",",,,%s,,,") a0) /// Explicit type specifications cannot be used for exception constructors - /// (Originally from ../FSComp.txt:747) + /// (Originally from ..\FSComp.txt:747) static member tcExplicitTypeSpecificationCannotBeUsedForExceptionConstructors() = (916, GetStringFunc("tcExplicitTypeSpecificationCannotBeUsedForExceptionConstructors",",,,") ) /// Exception abbreviations should not have argument lists - /// (Originally from ../FSComp.txt:748) + /// (Originally from ..\FSComp.txt:748) static member tcExceptionAbbreviationsShouldNotHaveArgumentList() = (917, GetStringFunc("tcExceptionAbbreviationsShouldNotHaveArgumentList",",,,") ) /// Abbreviations for Common IL exceptions cannot take arguments - /// (Originally from ../FSComp.txt:749) + /// (Originally from ..\FSComp.txt:749) static member tcAbbreviationsFordotNetExceptionsCannotTakeArguments() = (918, GetStringFunc("tcAbbreviationsFordotNetExceptionsCannotTakeArguments",",,,") ) /// Exception abbreviations must refer to existing exceptions or F# types deriving from System.Exception - /// (Originally from ../FSComp.txt:750) + /// (Originally from ..\FSComp.txt:750) static member tcExceptionAbbreviationsMustReferToValidExceptions() = (919, GetStringFunc("tcExceptionAbbreviationsMustReferToValidExceptions",",,,") ) /// Abbreviations for Common IL exception types must have a matching object constructor - /// (Originally from ../FSComp.txt:751) + /// (Originally from ..\FSComp.txt:751) static member tcAbbreviationsFordotNetExceptionsMustHaveMatchingObjectConstructor() = (920, GetStringFunc("tcAbbreviationsFordotNetExceptionsMustHaveMatchingObjectConstructor",",,,") ) /// Not an exception - /// (Originally from ../FSComp.txt:752) + /// (Originally from ..\FSComp.txt:752) static member tcNotAnException() = (921, GetStringFunc("tcNotAnException",",,,") ) /// Invalid module name - /// (Originally from ../FSComp.txt:754) + /// (Originally from ..\FSComp.txt:754) static member tcInvalidModuleName() = (924, GetStringFunc("tcInvalidModuleName",",,,") ) /// Invalid type extension - /// (Originally from ../FSComp.txt:755) + /// (Originally from ..\FSComp.txt:755) static member tcInvalidTypeExtension() = (925, GetStringFunc("tcInvalidTypeExtension",",,,") ) /// The attributes of this type specify multiple kinds for the type - /// (Originally from ../FSComp.txt:756) + /// (Originally from ..\FSComp.txt:756) static member tcAttributesOfTypeSpecifyMultipleKindsForType() = (926, GetStringFunc("tcAttributesOfTypeSpecifyMultipleKindsForType",",,,") ) /// The kind of the type specified by its attributes does not match the kind implied by its definition - /// (Originally from ../FSComp.txt:757) + /// (Originally from ..\FSComp.txt:757) static member tcKindOfTypeSpecifiedDoesNotMatchDefinition() = (927, GetStringFunc("tcKindOfTypeSpecifiedDoesNotMatchDefinition",",,,") ) /// Measure definitions cannot have type parameters - /// (Originally from ../FSComp.txt:758) + /// (Originally from ..\FSComp.txt:758) static member tcMeasureDefinitionsCannotHaveTypeParameters() = (928, GetStringFunc("tcMeasureDefinitionsCannotHaveTypeParameters",",,,") ) /// This type requires a definition - /// (Originally from ../FSComp.txt:759) + /// (Originally from ..\FSComp.txt:759) static member tcTypeRequiresDefinition() = (929, GetStringFunc("tcTypeRequiresDefinition",",,,") ) /// This type abbreviation has one or more declared type parameters that do not appear in the type being abbreviated. Type abbreviations must use all declared type parameters in the type being abbreviated. Consider removing one or more type parameters, or use a concrete type definition that wraps an underlying type, such as 'type C<'a> = C of ...'. - /// (Originally from ../FSComp.txt:760) + /// (Originally from ..\FSComp.txt:760) static member tcTypeAbbreviationHasTypeParametersMissingOnType() = (GetStringFunc("tcTypeAbbreviationHasTypeParametersMissingOnType",",,,") ) /// Structs, interfaces, enums and delegates cannot inherit from other types - /// (Originally from ../FSComp.txt:761) + /// (Originally from ..\FSComp.txt:761) static member tcStructsInterfacesEnumsDelegatesMayNotInheritFromOtherTypes() = (931, GetStringFunc("tcStructsInterfacesEnumsDelegatesMayNotInheritFromOtherTypes",",,,") ) /// Types cannot inherit from multiple concrete types - /// (Originally from ../FSComp.txt:762) + /// (Originally from ..\FSComp.txt:762) static member tcTypesCannotInheritFromMultipleConcreteTypes() = (932, GetStringFunc("tcTypesCannotInheritFromMultipleConcreteTypes",",,,") ) /// Records, union, abbreviations and struct types cannot have the 'AllowNullLiteral' attribute - /// (Originally from ../FSComp.txt:763) + /// (Originally from ..\FSComp.txt:763) static member tcRecordsUnionsAbbreviationsStructsMayNotHaveAllowNullLiteralAttribute() = (934, GetStringFunc("tcRecordsUnionsAbbreviationsStructsMayNotHaveAllowNullLiteralAttribute",",,,") ) /// Types with the 'AllowNullLiteral' attribute may only inherit from or implement types which also allow the use of the null literal - /// (Originally from ../FSComp.txt:764) + /// (Originally from ..\FSComp.txt:764) static member tcAllowNullTypesMayOnlyInheritFromAllowNullTypes() = (935, GetStringFunc("tcAllowNullTypesMayOnlyInheritFromAllowNullTypes",",,,") ) /// Generic types cannot be given the 'StructLayout' attribute - /// (Originally from ../FSComp.txt:765) + /// (Originally from ..\FSComp.txt:765) static member tcGenericTypesCannotHaveStructLayout() = (936, GetStringFunc("tcGenericTypesCannotHaveStructLayout",",,,") ) /// Only structs and classes without primary constructors may be given the 'StructLayout' attribute - /// (Originally from ../FSComp.txt:766) + /// (Originally from ..\FSComp.txt:766) static member tcOnlyStructsCanHaveStructLayout() = (937, GetStringFunc("tcOnlyStructsCanHaveStructLayout",",,,") ) /// The representation of this type is hidden by the signature. It must be given an attribute such as [], [] or [] to indicate the characteristics of the type. - /// (Originally from ../FSComp.txt:767) + /// (Originally from ..\FSComp.txt:767) static member tcRepresentationOfTypeHiddenBySignature() = (938, GetStringFunc("tcRepresentationOfTypeHiddenBySignature",",,,") ) /// Only classes may be given the 'AbstractClass' attribute - /// (Originally from ../FSComp.txt:768) + /// (Originally from ..\FSComp.txt:768) static member tcOnlyClassesCanHaveAbstract() = (939, GetStringFunc("tcOnlyClassesCanHaveAbstract",",,,") ) /// Only types representing units-of-measure may be given the 'Measure' attribute - /// (Originally from ../FSComp.txt:769) + /// (Originally from ..\FSComp.txt:769) static member tcOnlyTypesRepresentingUnitsOfMeasureCanHaveMeasure() = (940, GetStringFunc("tcOnlyTypesRepresentingUnitsOfMeasureCanHaveMeasure",",,,") ) /// Accessibility modifiers are not permitted on overrides or interface implementations - /// (Originally from ../FSComp.txt:770) + /// (Originally from ..\FSComp.txt:770) static member tcOverridesCannotHaveVisibilityDeclarations() = (941, GetStringFunc("tcOverridesCannotHaveVisibilityDeclarations",",,,") ) /// Discriminated union types are always sealed - /// (Originally from ../FSComp.txt:771) + /// (Originally from ..\FSComp.txt:771) static member tcTypesAreAlwaysSealedDU() = (942, GetStringFunc("tcTypesAreAlwaysSealedDU",",,,") ) /// Record types are always sealed - /// (Originally from ../FSComp.txt:772) + /// (Originally from ..\FSComp.txt:772) static member tcTypesAreAlwaysSealedRecord() = (942, GetStringFunc("tcTypesAreAlwaysSealedRecord",",,,") ) /// Assembly code types are always sealed - /// (Originally from ../FSComp.txt:773) + /// (Originally from ..\FSComp.txt:773) static member tcTypesAreAlwaysSealedAssemblyCode() = (942, GetStringFunc("tcTypesAreAlwaysSealedAssemblyCode",",,,") ) /// Struct types are always sealed - /// (Originally from ../FSComp.txt:774) + /// (Originally from ..\FSComp.txt:774) static member tcTypesAreAlwaysSealedStruct() = (942, GetStringFunc("tcTypesAreAlwaysSealedStruct",",,,") ) /// Delegate types are always sealed - /// (Originally from ../FSComp.txt:775) + /// (Originally from ..\FSComp.txt:775) static member tcTypesAreAlwaysSealedDelegate() = (942, GetStringFunc("tcTypesAreAlwaysSealedDelegate",",,,") ) /// Enum types are always sealed - /// (Originally from ../FSComp.txt:776) + /// (Originally from ..\FSComp.txt:776) static member tcTypesAreAlwaysSealedEnum() = (942, GetStringFunc("tcTypesAreAlwaysSealedEnum",",,,") ) /// Interface types and delegate types cannot contain fields - /// (Originally from ../FSComp.txt:777) + /// (Originally from ..\FSComp.txt:777) static member tcInterfaceTypesAndDelegatesCannotContainFields() = (943, GetStringFunc("tcInterfaceTypesAndDelegatesCannotContainFields",",,,") ) /// Abbreviated types cannot be given the 'Sealed' attribute - /// (Originally from ../FSComp.txt:778) + /// (Originally from ..\FSComp.txt:778) static member tcAbbreviatedTypesCannotBeSealed() = (944, GetStringFunc("tcAbbreviatedTypesCannotBeSealed",",,,") ) /// Cannot inherit a sealed type - /// (Originally from ../FSComp.txt:779) + /// (Originally from ..\FSComp.txt:779) static member tcCannotInheritFromSealedType() = (945, GetStringFunc("tcCannotInheritFromSealedType",",,,") ) /// Cannot inherit from interface type. Use interface ... with instead. - /// (Originally from ../FSComp.txt:780) + /// (Originally from ..\FSComp.txt:780) static member tcCannotInheritFromInterfaceType() = (946, GetStringFunc("tcCannotInheritFromInterfaceType",",,,") ) /// Struct types cannot contain abstract members - /// (Originally from ../FSComp.txt:781) + /// (Originally from ..\FSComp.txt:781) static member tcStructTypesCannotContainAbstractMembers() = (947, GetStringFunc("tcStructTypesCannotContainAbstractMembers",",,,") ) /// Interface types cannot be sealed - /// (Originally from ../FSComp.txt:782) + /// (Originally from ..\FSComp.txt:782) static member tcInterfaceTypesCannotBeSealed() = (948, GetStringFunc("tcInterfaceTypesCannotBeSealed",",,,") ) /// Delegate specifications must be of the form 'typ -> typ' - /// (Originally from ../FSComp.txt:783) + /// (Originally from ..\FSComp.txt:783) static member tcInvalidDelegateSpecification() = (949, GetStringFunc("tcInvalidDelegateSpecification",",,,") ) /// Delegate specifications must not be curried types. Use 'typ * ... * typ -> typ' for multi-argument delegates, and 'typ -> (typ -> typ)' for delegates returning function values. - /// (Originally from ../FSComp.txt:784) + /// (Originally from ..\FSComp.txt:784) static member tcDelegatesCannotBeCurried() = (950, GetStringFunc("tcDelegatesCannotBeCurried",",,,") ) /// Literal enumerations must have type int, uint, int16, uint16, int64, uint64, byte, sbyte or char - /// (Originally from ../FSComp.txt:785) + /// (Originally from ..\FSComp.txt:785) static member tcInvalidTypeForLiteralEnumeration() = (951, GetStringFunc("tcInvalidTypeForLiteralEnumeration",",,,") ) /// This type definition involves an immediate cyclic reference through an abbreviation - /// (Originally from ../FSComp.txt:787) + /// (Originally from ..\FSComp.txt:787) static member tcTypeDefinitionIsCyclic() = (953, GetStringFunc("tcTypeDefinitionIsCyclic",",,,") ) /// This type definition involves an immediate cyclic reference through a struct field or inheritance relation - /// (Originally from ../FSComp.txt:788) + /// (Originally from ..\FSComp.txt:788) static member tcTypeDefinitionIsCyclicThroughInheritance() = (954, GetStringFunc("tcTypeDefinitionIsCyclicThroughInheritance",",,,") ) /// The syntax 'type X with ...' is reserved for augmentations. Types whose representations are hidden but which have members are now declared in signatures using 'type X = ...'. You may also need to add the '[] attribute to the type definition in the signature - /// (Originally from ../FSComp.txt:789) + /// (Originally from ..\FSComp.txt:789) static member tcReservedSyntaxForAugmentation() = (GetStringFunc("tcReservedSyntaxForAugmentation",",,,") ) /// Members that extend interface, delegate or enum types must be placed in a module separate to the definition of the type. This module must either have the AutoOpen attribute or be opened explicitly by client code to bring the extension members into scope. - /// (Originally from ../FSComp.txt:790) + /// (Originally from ..\FSComp.txt:790) static member tcMembersThatExtendInterfaceMustBePlacedInSeparateModule() = (956, GetStringFunc("tcMembersThatExtendInterfaceMustBePlacedInSeparateModule",",,,") ) /// One or more of the declared type parameters for this type extension have a missing or wrong type constraint not matching the original type constraints on '%s' - /// (Originally from ../FSComp.txt:791) + /// (Originally from ..\FSComp.txt:791) static member tcDeclaredTypeParametersForExtensionDoNotMatchOriginal(a0 : System.String) = (957, GetStringFunc("tcDeclaredTypeParametersForExtensionDoNotMatchOriginal",",,,%s,,,") a0) /// Type definitions may only have one 'inherit' specification and it must be the first declaration - /// (Originally from ../FSComp.txt:792) + /// (Originally from ..\FSComp.txt:792) static member tcTypeDefinitionsWithImplicitConstructionMustHaveOneInherit() = (959, GetStringFunc("tcTypeDefinitionsWithImplicitConstructionMustHaveOneInherit",",,,") ) /// 'let' and 'do' bindings must come before member and interface definitions in type definitions - /// (Originally from ../FSComp.txt:793) + /// (Originally from ..\FSComp.txt:793) static member tcTypeDefinitionsWithImplicitConstructionMustHaveLocalBindingsBeforeMembers() = (960, GetStringFunc("tcTypeDefinitionsWithImplicitConstructionMustHaveLocalBindingsBeforeMembers",",,,") ) /// This 'inherit' declaration specifies the inherited type but no arguments. Consider supplying arguments, e.g. 'inherit BaseType(args)'. - /// (Originally from ../FSComp.txt:794) + /// (Originally from ..\FSComp.txt:794) static member tcInheritDeclarationMissingArguments() = (961, GetStringFunc("tcInheritDeclarationMissingArguments",",,,") ) /// This 'inherit' declaration has arguments, but is not in a type with a primary constructor. Consider adding arguments to your type definition, e.g. 'type X(args) = ...'. - /// (Originally from ../FSComp.txt:795) + /// (Originally from ..\FSComp.txt:795) static member tcInheritConstructionCallNotPartOfImplicitSequence() = (962, GetStringFunc("tcInheritConstructionCallNotPartOfImplicitSequence",",,,") ) /// This definition may only be used in a type with a primary constructor. Consider adding arguments to your type definition, e.g. 'type X(args) = ...'. - /// (Originally from ../FSComp.txt:796) + /// (Originally from ..\FSComp.txt:796) static member tcLetAndDoRequiresImplicitConstructionSequence() = (963, GetStringFunc("tcLetAndDoRequiresImplicitConstructionSequence",",,,") ) /// Type abbreviations cannot have augmentations - /// (Originally from ../FSComp.txt:797) + /// (Originally from ..\FSComp.txt:797) static member tcTypeAbbreviationsCannotHaveAugmentations() = (964, GetStringFunc("tcTypeAbbreviationsCannotHaveAugmentations",",,,") ) /// The path '%s' is a namespace. A module abbreviation may not abbreviate a namespace. - /// (Originally from ../FSComp.txt:798) + /// (Originally from ..\FSComp.txt:798) static member tcModuleAbbreviationForNamespace(a0 : System.String) = (965, GetStringFunc("tcModuleAbbreviationForNamespace",",,,%s,,,") a0) /// The type '%s' is used in an invalid way. A value prior to '%s' has an inferred type involving '%s', which is an invalid forward reference. - /// (Originally from ../FSComp.txt:799) + /// (Originally from ..\FSComp.txt:799) static member tcTypeUsedInInvalidWay(a0 : System.String, a1 : System.String, a2 : System.String) = (966, GetStringFunc("tcTypeUsedInInvalidWay",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The member '%s' is used in an invalid way. A use of '%s' has been inferred prior to the definition of '%s', which is an invalid forward reference. - /// (Originally from ../FSComp.txt:800) + /// (Originally from ..\FSComp.txt:800) static member tcMemberUsedInInvalidWay(a0 : System.String, a1 : System.String, a2 : System.String) = (967, GetStringFunc("tcMemberUsedInInvalidWay",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The attribute 'AutoOpen(\"%s\")' in the assembly '%s' did not refer to a valid module or namespace in that assembly and has been ignored - /// (Originally from ../FSComp.txt:803) + /// (Originally from ..\FSComp.txt:803) static member tcAttributeAutoOpenWasIgnored(a0 : System.String, a1 : System.String) = (970, GetStringFunc("tcAttributeAutoOpenWasIgnored",",,,%s,,,%s,,,") a0 a1) /// Undefined value '%s' - /// (Originally from ../FSComp.txt:804) + /// (Originally from ..\FSComp.txt:804) static member ilUndefinedValue(a0 : System.String) = (971, GetStringFunc("ilUndefinedValue",",,,%s,,,") a0) /// Label %s not found - /// (Originally from ../FSComp.txt:805) + /// (Originally from ..\FSComp.txt:805) static member ilLabelNotFound(a0 : System.String) = (972, GetStringFunc("ilLabelNotFound",",,,%s,,,") a0) /// Incorrect number of type arguments to local call - /// (Originally from ../FSComp.txt:806) + /// (Originally from ..\FSComp.txt:806) static member ilIncorrectNumberOfTypeArguments() = (973, GetStringFunc("ilIncorrectNumberOfTypeArguments",",,,") ) /// Dynamic invocation of %s is not supported - /// (Originally from ../FSComp.txt:807) + /// (Originally from ..\FSComp.txt:807) static member ilDynamicInvocationNotSupported(a0 : System.String) = (GetStringFunc("ilDynamicInvocationNotSupported",",,,%s,,,") a0) /// Taking the address of a literal field is invalid - /// (Originally from ../FSComp.txt:808) + /// (Originally from ..\FSComp.txt:808) static member ilAddressOfLiteralFieldIsInvalid() = (975, GetStringFunc("ilAddressOfLiteralFieldIsInvalid",",,,") ) /// This operation involves taking the address of a value '%s' represented using a local variable or other special representation. This is invalid. - /// (Originally from ../FSComp.txt:809) + /// (Originally from ..\FSComp.txt:809) static member ilAddressOfValueHereIsInvalid(a0 : System.String) = (976, GetStringFunc("ilAddressOfValueHereIsInvalid",",,,%s,,,") a0) /// Custom marshallers cannot be specified in F# code. Consider using a C# helper function. - /// (Originally from ../FSComp.txt:810) + /// (Originally from ..\FSComp.txt:810) static member ilCustomMarshallersCannotBeUsedInFSharp() = (980, GetStringFunc("ilCustomMarshallersCannotBeUsedInFSharp",",,,") ) /// The MarshalAs attribute could not be decoded - /// (Originally from ../FSComp.txt:811) + /// (Originally from ..\FSComp.txt:811) static member ilMarshalAsAttributeCannotBeDecoded() = (981, GetStringFunc("ilMarshalAsAttributeCannotBeDecoded",",,,") ) /// The signature for this external function contains type parameters. Constrain the argument and return types to indicate the types of the corresponding C function. - /// (Originally from ../FSComp.txt:812) + /// (Originally from ..\FSComp.txt:812) static member ilSignatureForExternalFunctionContainsTypeParameters() = (982, GetStringFunc("ilSignatureForExternalFunctionContainsTypeParameters",",,,") ) /// The DllImport attribute could not be decoded - /// (Originally from ../FSComp.txt:813) + /// (Originally from ..\FSComp.txt:813) static member ilDllImportAttributeCouldNotBeDecoded() = (983, GetStringFunc("ilDllImportAttributeCouldNotBeDecoded",",,,") ) /// Literal fields cannot be set - /// (Originally from ../FSComp.txt:814) + /// (Originally from ..\FSComp.txt:814) static member ilLiteralFieldsCannotBeSet() = (984, GetStringFunc("ilLiteralFieldsCannotBeSet",",,,") ) /// GenSetStorage: %s was represented as a static method but was not an appropriate lambda expression - /// (Originally from ../FSComp.txt:815) + /// (Originally from ..\FSComp.txt:815) static member ilStaticMethodIsNotLambda(a0 : System.String) = (985, GetStringFunc("ilStaticMethodIsNotLambda",",,,%s,,,") a0) /// Mutable variables cannot escape their method - /// (Originally from ../FSComp.txt:816) + /// (Originally from ..\FSComp.txt:816) static member ilMutableVariablesCannotEscapeMethod() = (986, GetStringFunc("ilMutableVariablesCannotEscapeMethod",",,,") ) /// Compiler error: unexpected unrealized value - /// (Originally from ../FSComp.txt:817) + /// (Originally from ..\FSComp.txt:817) static member ilUnexpectedUnrealizedValue() = (987, GetStringFunc("ilUnexpectedUnrealizedValue",",,,") ) /// Main module of program is empty: nothing will happen when it is run - /// (Originally from ../FSComp.txt:818) + /// (Originally from ..\FSComp.txt:818) static member ilMainModuleEmpty() = (988, GetStringFunc("ilMainModuleEmpty",",,,") ) /// This type cannot be used for a literal field - /// (Originally from ../FSComp.txt:819) + /// (Originally from ..\FSComp.txt:819) static member ilTypeCannotBeUsedForLiteralField() = (989, GetStringFunc("ilTypeCannotBeUsedForLiteralField",",,,") ) /// Unexpected GetSet annotation on a property - /// (Originally from ../FSComp.txt:820) + /// (Originally from ..\FSComp.txt:820) static member ilUnexpectedGetSetAnnotation() = (990, GetStringFunc("ilUnexpectedGetSetAnnotation",",,,") ) /// The FieldOffset attribute could not be decoded - /// (Originally from ../FSComp.txt:821) + /// (Originally from ..\FSComp.txt:821) static member ilFieldOffsetAttributeCouldNotBeDecoded() = (991, GetStringFunc("ilFieldOffsetAttributeCouldNotBeDecoded",",,,") ) /// The StructLayout attribute could not be decoded - /// (Originally from ../FSComp.txt:822) + /// (Originally from ..\FSComp.txt:822) static member ilStructLayoutAttributeCouldNotBeDecoded() = (992, GetStringFunc("ilStructLayoutAttributeCouldNotBeDecoded",",,,") ) /// The DefaultAugmentation attribute could not be decoded - /// (Originally from ../FSComp.txt:823) + /// (Originally from ..\FSComp.txt:823) static member ilDefaultAugmentationAttributeCouldNotBeDecoded() = (993, GetStringFunc("ilDefaultAugmentationAttributeCouldNotBeDecoded",",,,") ) /// Reflected definitions cannot contain uses of the prefix splice operator '%%' - /// (Originally from ../FSComp.txt:824) + /// (Originally from ..\FSComp.txt:824) static member ilReflectedDefinitionsCannotUseSliceOperator() = (994, GetStringFunc("ilReflectedDefinitionsCannotUseSliceOperator",",,,") ) /// Problem with codepage '%d': %s - /// (Originally from ../FSComp.txt:825) + /// (Originally from ..\FSComp.txt:825) static member optsProblemWithCodepage(a0 : System.Int32, a1 : System.String) = (1000, GetStringFunc("optsProblemWithCodepage",",,,%d,,,%s,,,") a0 a1) /// Copyright (c) Microsoft Corporation. All Rights Reserved. - /// (Originally from ../FSComp.txt:826) + /// (Originally from ..\FSComp.txt:826) static member optsCopyright() = (GetStringFunc("optsCopyright",",,,") ) /// Freely distributed under the MIT Open Source License. https://github.com/Microsoft/visualfsharp/blob/master/License.txt - /// (Originally from ../FSComp.txt:827) + /// (Originally from ..\FSComp.txt:827) static member optsCopyrightCommunity() = (GetStringFunc("optsCopyrightCommunity",",,,") ) /// Name of the output file (Short form: -o) - /// (Originally from ../FSComp.txt:828) + /// (Originally from ..\FSComp.txt:828) static member optsNameOfOutputFile() = (GetStringFunc("optsNameOfOutputFile",",,,") ) /// Build a console executable - /// (Originally from ../FSComp.txt:829) + /// (Originally from ..\FSComp.txt:829) static member optsBuildConsole() = (GetStringFunc("optsBuildConsole",",,,") ) /// Build a Windows executable - /// (Originally from ../FSComp.txt:830) + /// (Originally from ..\FSComp.txt:830) static member optsBuildWindows() = (GetStringFunc("optsBuildWindows",",,,") ) /// Build a library (Short form: -a) - /// (Originally from ../FSComp.txt:831) + /// (Originally from ..\FSComp.txt:831) static member optsBuildLibrary() = (GetStringFunc("optsBuildLibrary",",,,") ) /// Build a module that can be added to another assembly - /// (Originally from ../FSComp.txt:832) + /// (Originally from ..\FSComp.txt:832) static member optsBuildModule() = (GetStringFunc("optsBuildModule",",,,") ) /// Delay-sign the assembly using only the public portion of the strong name key - /// (Originally from ../FSComp.txt:833) + /// (Originally from ..\FSComp.txt:833) static member optsDelaySign() = (GetStringFunc("optsDelaySign",",,,") ) /// Public-sign the assembly using only the public portion of the strong name key, and mark the assembly as signed - /// (Originally from ../FSComp.txt:834) + /// (Originally from ..\FSComp.txt:834) static member optsPublicSign() = (GetStringFunc("optsPublicSign",",,,") ) /// Write the xmldoc of the assembly to the given file - /// (Originally from ../FSComp.txt:835) + /// (Originally from ..\FSComp.txt:835) static member optsWriteXml() = (GetStringFunc("optsWriteXml",",,,") ) /// Specify a strong name key file - /// (Originally from ../FSComp.txt:836) + /// (Originally from ..\FSComp.txt:836) static member optsStrongKeyFile() = (GetStringFunc("optsStrongKeyFile",",,,") ) /// Specify a strong name key container - /// (Originally from ../FSComp.txt:837) + /// (Originally from ..\FSComp.txt:837) static member optsStrongKeyContainer() = (GetStringFunc("optsStrongKeyContainer",",,,") ) /// Limit which platforms this code can run on: x86, Itanium, x64, anycpu32bitpreferred, or anycpu. The default is anycpu. - /// (Originally from ../FSComp.txt:838) + /// (Originally from ..\FSComp.txt:838) static member optsPlatform() = (GetStringFunc("optsPlatform",",,,") ) /// Only include optimization information essential for implementing inlined constructs. Inhibits cross-module inlining but improves binary compatibility. - /// (Originally from ../FSComp.txt:839) + /// (Originally from ..\FSComp.txt:839) static member optsNoOpt() = (GetStringFunc("optsNoOpt",",,,") ) /// Don't add a resource to the generated assembly containing F#-specific metadata - /// (Originally from ../FSComp.txt:840) + /// (Originally from ..\FSComp.txt:840) static member optsNoInterface() = (GetStringFunc("optsNoInterface",",,,") ) /// Print the inferred interface of the assembly to a file - /// (Originally from ../FSComp.txt:841) + /// (Originally from ..\FSComp.txt:841) static member optsSig() = (GetStringFunc("optsSig",",,,") ) /// Reference an assembly (Short form: -r) - /// (Originally from ../FSComp.txt:842) + /// (Originally from ..\FSComp.txt:842) static member optsReference() = (GetStringFunc("optsReference",",,,") ) /// Specify a Win32 resource file (.res) - /// (Originally from ../FSComp.txt:843) + /// (Originally from ..\FSComp.txt:843) static member optsWin32res() = (GetStringFunc("optsWin32res",",,,") ) /// Specify a Win32 manifest file - /// (Originally from ../FSComp.txt:844) + /// (Originally from ..\FSComp.txt:844) static member optsWin32manifest() = (GetStringFunc("optsWin32manifest",",,,") ) /// Do not include the default Win32 manifest - /// (Originally from ../FSComp.txt:845) + /// (Originally from ..\FSComp.txt:845) static member optsNowin32manifest() = (GetStringFunc("optsNowin32manifest",",,,") ) /// Embed all source files in the portable PDB file - /// (Originally from ../FSComp.txt:846) + /// (Originally from ..\FSComp.txt:846) static member optsEmbedAllSource() = (GetStringFunc("optsEmbedAllSource",",,,") ) /// Embed specific source files in the portable PDB file - /// (Originally from ../FSComp.txt:847) + /// (Originally from ..\FSComp.txt:847) static member optsEmbedSource() = (GetStringFunc("optsEmbedSource",",,,") ) /// Source link information file to embed in the portable PDB file - /// (Originally from ../FSComp.txt:848) + /// (Originally from ..\FSComp.txt:848) static member optsSourceLink() = (GetStringFunc("optsSourceLink",",,,") ) /// --embed switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded) - /// (Originally from ../FSComp.txt:849) + /// (Originally from ..\FSComp.txt:849) static member optsEmbeddedSourceRequirePortablePDBs() = (1501, GetStringFunc("optsEmbeddedSourceRequirePortablePDBs",",,,") ) /// --sourcelink switch only supported when emitting a Portable PDB (--debug:portable or --debug:embedded) - /// (Originally from ../FSComp.txt:850) + /// (Originally from ..\FSComp.txt:850) static member optsSourceLinkRequirePortablePDBs() = (1502, GetStringFunc("optsSourceLinkRequirePortablePDBs",",,,") ) /// Source file is too large to embed in a portable PDB - /// (Originally from ../FSComp.txt:851) + /// (Originally from ..\FSComp.txt:851) static member srcFileTooLarge() = (GetStringFunc("srcFileTooLarge",",,,") ) /// Embed the specified managed resource - /// (Originally from ../FSComp.txt:852) + /// (Originally from ..\FSComp.txt:852) static member optsResource() = (GetStringFunc("optsResource",",,,") ) /// Link the specified resource to this assembly where the resinfo format is [,[,public|private]] - /// (Originally from ../FSComp.txt:853) + /// (Originally from ..\FSComp.txt:853) static member optsLinkresource() = (GetStringFunc("optsLinkresource",",,,") ) /// Emit debug information (Short form: -g) - /// (Originally from ../FSComp.txt:854) + /// (Originally from ..\FSComp.txt:854) static member optsDebugPM() = (GetStringFunc("optsDebugPM",",,,") ) /// Specify debugging type: full, portable, embedded, pdbonly. ('%s' is the default if no debuggging type specified and enables attaching a debugger to a running program, 'portable' is a cross-platform format, 'embedded' is a cross-platform format embedded into the output file). - /// (Originally from ../FSComp.txt:855) + /// (Originally from ..\FSComp.txt:855) static member optsDebug(a0 : System.String) = (GetStringFunc("optsDebug",",,,%s,,,") a0) /// Enable optimizations (Short form: -O) - /// (Originally from ../FSComp.txt:856) + /// (Originally from ..\FSComp.txt:856) static member optsOptimize() = (GetStringFunc("optsOptimize",",,,") ) /// Enable or disable tailcalls - /// (Originally from ../FSComp.txt:857) + /// (Originally from ..\FSComp.txt:857) static member optsTailcalls() = (GetStringFunc("optsTailcalls",",,,") ) /// Produce a deterministic assembly (including module version GUID and timestamp) - /// (Originally from ../FSComp.txt:858) + /// (Originally from ..\FSComp.txt:858) static member optsDeterministic() = (GetStringFunc("optsDeterministic",",,,") ) /// Enable or disable cross-module optimizations - /// (Originally from ../FSComp.txt:859) + /// (Originally from ..\FSComp.txt:859) static member optsCrossoptimize() = (GetStringFunc("optsCrossoptimize",",,,") ) /// Report all warnings as errors - /// (Originally from ../FSComp.txt:860) + /// (Originally from ..\FSComp.txt:860) static member optsWarnaserrorPM() = (GetStringFunc("optsWarnaserrorPM",",,,") ) /// Report specific warnings as errors - /// (Originally from ../FSComp.txt:861) + /// (Originally from ..\FSComp.txt:861) static member optsWarnaserror() = (GetStringFunc("optsWarnaserror",",,,") ) /// Set a warning level (0-5) - /// (Originally from ../FSComp.txt:862) + /// (Originally from ..\FSComp.txt:862) static member optsWarn() = (GetStringFunc("optsWarn",",,,") ) /// Disable specific warning messages - /// (Originally from ../FSComp.txt:863) + /// (Originally from ..\FSComp.txt:863) static member optsNowarn() = (GetStringFunc("optsNowarn",",,,") ) /// Enable specific warnings that may be off by default - /// (Originally from ../FSComp.txt:864) + /// (Originally from ..\FSComp.txt:864) static member optsWarnOn() = (GetStringFunc("optsWarnOn",",,,") ) /// Generate overflow checks - /// (Originally from ../FSComp.txt:865) + /// (Originally from ..\FSComp.txt:865) static member optsChecked() = (GetStringFunc("optsChecked",",,,") ) /// Define conditional compilation symbols (Short form: -d) - /// (Originally from ../FSComp.txt:866) + /// (Originally from ..\FSComp.txt:866) static member optsDefine() = (GetStringFunc("optsDefine",",,,") ) /// Ignore ML compatibility warnings - /// (Originally from ../FSComp.txt:867) + /// (Originally from ..\FSComp.txt:867) static member optsMlcompatibility() = (GetStringFunc("optsMlcompatibility",",,,") ) /// Suppress compiler copyright message - /// (Originally from ../FSComp.txt:868) + /// (Originally from ..\FSComp.txt:868) static member optsNologo() = (GetStringFunc("optsNologo",",,,") ) /// Display this usage message (Short form: -?) - /// (Originally from ../FSComp.txt:869) + /// (Originally from ..\FSComp.txt:869) static member optsHelp() = (GetStringFunc("optsHelp",",,,") ) /// Read response file for more options - /// (Originally from ../FSComp.txt:870) + /// (Originally from ..\FSComp.txt:870) static member optsResponseFile() = (GetStringFunc("optsResponseFile",",,,") ) /// Specify the codepage used to read source files - /// (Originally from ../FSComp.txt:871) + /// (Originally from ..\FSComp.txt:871) static member optsCodepage() = (GetStringFunc("optsCodepage",",,,") ) /// Output messages in UTF-8 encoding - /// (Originally from ../FSComp.txt:872) + /// (Originally from ..\FSComp.txt:872) static member optsUtf8output() = (GetStringFunc("optsUtf8output",",,,") ) /// Output messages with fully qualified paths - /// (Originally from ../FSComp.txt:873) + /// (Originally from ..\FSComp.txt:873) static member optsFullpaths() = (GetStringFunc("optsFullpaths",",,,") ) /// Specify a directory for the include path which is used to resolve source files and assemblies (Short form: -I) - /// (Originally from ../FSComp.txt:874) + /// (Originally from ..\FSComp.txt:874) static member optsLib() = (GetStringFunc("optsLib",",,,") ) /// Base address for the library to be built - /// (Originally from ../FSComp.txt:875) + /// (Originally from ..\FSComp.txt:875) static member optsBaseaddress() = (GetStringFunc("optsBaseaddress",",,,") ) /// Do not reference the default CLI assemblies by default - /// (Originally from ../FSComp.txt:876) + /// (Originally from ..\FSComp.txt:876) static member optsNoframework() = (GetStringFunc("optsNoframework",",,,") ) /// Statically link the F# library and all referenced DLLs that depend on it into the assembly being generated - /// (Originally from ../FSComp.txt:877) + /// (Originally from ..\FSComp.txt:877) static member optsStandalone() = (GetStringFunc("optsStandalone",",,,") ) /// Statically link the given assembly and all referenced DLLs that depend on this assembly. Use an assembly name e.g. mylib, not a DLL name. - /// (Originally from ../FSComp.txt:878) + /// (Originally from ..\FSComp.txt:878) static member optsStaticlink() = (GetStringFunc("optsStaticlink",",,,") ) /// Use a resident background compilation service to improve compiler startup times. - /// (Originally from ../FSComp.txt:879) + /// (Originally from ..\FSComp.txt:879) static member optsResident() = (GetStringFunc("optsResident",",,,") ) /// Name the output debug file - /// (Originally from ../FSComp.txt:880) + /// (Originally from ..\FSComp.txt:880) static member optsPdb() = (GetStringFunc("optsPdb",",,,") ) /// Resolve assembly references using directory-based rules rather than MSBuild resolution - /// (Originally from ../FSComp.txt:881) + /// (Originally from ..\FSComp.txt:881) static member optsSimpleresolution() = (GetStringFunc("optsSimpleresolution",",,,") ) /// Unrecognized target '%s', expected 'exe', 'winexe', 'library' or 'module' - /// (Originally from ../FSComp.txt:882) + /// (Originally from ..\FSComp.txt:882) static member optsUnrecognizedTarget(a0 : System.String) = (1048, GetStringFunc("optsUnrecognizedTarget",",,,%s,,,") a0) /// Unrecognized debug type '%s', expected 'pdbonly' or 'full' - /// (Originally from ../FSComp.txt:883) + /// (Originally from ..\FSComp.txt:883) static member optsUnrecognizedDebugType(a0 : System.String) = (1049, GetStringFunc("optsUnrecognizedDebugType",",,,%s,,,") a0) /// Invalid warning level '%d' - /// (Originally from ../FSComp.txt:884) + /// (Originally from ..\FSComp.txt:884) static member optsInvalidWarningLevel(a0 : System.Int32) = (1050, GetStringFunc("optsInvalidWarningLevel",",,,%d,,,") a0) /// Short form of '%s' - /// (Originally from ../FSComp.txt:885) + /// (Originally from ..\FSComp.txt:885) static member optsShortFormOf(a0 : System.String) = (GetStringFunc("optsShortFormOf",",,,%s,,,") a0) /// The command-line option '--cliroot' has been deprecated. Use an explicit reference to a specific copy of mscorlib.dll instead. - /// (Originally from ../FSComp.txt:886) + /// (Originally from ..\FSComp.txt:886) static member optsClirootDeprecatedMsg() = (GetStringFunc("optsClirootDeprecatedMsg",",,,") ) /// Use to override where the compiler looks for mscorlib.dll and framework components - /// (Originally from ../FSComp.txt:887) + /// (Originally from ..\FSComp.txt:887) static member optsClirootDescription() = (GetStringFunc("optsClirootDescription",",,,") ) /// - OUTPUT FILES - - /// (Originally from ../FSComp.txt:888) + /// (Originally from ..\FSComp.txt:888) static member optsHelpBannerOutputFiles() = (GetStringFunc("optsHelpBannerOutputFiles",",,,") ) /// - INPUT FILES - - /// (Originally from ../FSComp.txt:889) + /// (Originally from ..\FSComp.txt:889) static member optsHelpBannerInputFiles() = (GetStringFunc("optsHelpBannerInputFiles",",,,") ) /// - RESOURCES - - /// (Originally from ../FSComp.txt:890) + /// (Originally from ..\FSComp.txt:890) static member optsHelpBannerResources() = (GetStringFunc("optsHelpBannerResources",",,,") ) /// - CODE GENERATION - - /// (Originally from ../FSComp.txt:891) + /// (Originally from ..\FSComp.txt:891) static member optsHelpBannerCodeGen() = (GetStringFunc("optsHelpBannerCodeGen",",,,") ) /// - ADVANCED - - /// (Originally from ../FSComp.txt:892) + /// (Originally from ..\FSComp.txt:892) static member optsHelpBannerAdvanced() = (GetStringFunc("optsHelpBannerAdvanced",",,,") ) /// - MISCELLANEOUS - - /// (Originally from ../FSComp.txt:893) + /// (Originally from ..\FSComp.txt:893) static member optsHelpBannerMisc() = (GetStringFunc("optsHelpBannerMisc",",,,") ) /// - LANGUAGE - - /// (Originally from ../FSComp.txt:894) + /// (Originally from ..\FSComp.txt:894) static member optsHelpBannerLanguage() = (GetStringFunc("optsHelpBannerLanguage",",,,") ) /// - ERRORS AND WARNINGS - - /// (Originally from ../FSComp.txt:895) + /// (Originally from ..\FSComp.txt:895) static member optsHelpBannerErrsAndWarns() = (GetStringFunc("optsHelpBannerErrsAndWarns",",,,") ) /// Unknown --test argument: '%s' - /// (Originally from ../FSComp.txt:896) + /// (Originally from ..\FSComp.txt:896) static member optsUnknownArgumentToTheTestSwitch(a0 : System.String) = (1063, GetStringFunc("optsUnknownArgumentToTheTestSwitch",",,,%s,,,") a0) /// Unrecognized platform '%s', valid values are 'x86', 'x64', 'Itanium', 'anycpu32bitpreferred', and 'anycpu' - /// (Originally from ../FSComp.txt:897) + /// (Originally from ..\FSComp.txt:897) static member optsUnknownPlatform(a0 : System.String) = (1064, GetStringFunc("optsUnknownPlatform",",,,%s,,,") a0) /// The command-line option '%s' is for test purposes only - /// (Originally from ../FSComp.txt:898) + /// (Originally from ..\FSComp.txt:898) static member optsInternalNoDescription(a0 : System.String) = (GetStringFunc("optsInternalNoDescription",",,,%s,,,") a0) /// The command-line option '%s' has been deprecated - /// (Originally from ../FSComp.txt:899) + /// (Originally from ..\FSComp.txt:899) static member optsDCLONoDescription(a0 : System.String) = (GetStringFunc("optsDCLONoDescription",",,,%s,,,") a0) /// The command-line option '%s' has been deprecated. Use '%s' instead. - /// (Originally from ../FSComp.txt:900) + /// (Originally from ..\FSComp.txt:900) static member optsDCLODeprecatedSuggestAlternative(a0 : System.String, a1 : System.String) = (GetStringFunc("optsDCLODeprecatedSuggestAlternative",",,,%s,,,%s,,,") a0 a1) /// The command-line option '%s' has been deprecated. HTML document generation is now part of the F# Power Pack, via the tool FsHtmlDoc.exe. - /// (Originally from ../FSComp.txt:901) + /// (Originally from ..\FSComp.txt:901) static member optsDCLOHtmlDoc(a0 : System.String) = (GetStringFunc("optsDCLOHtmlDoc",",,,%s,,,") a0) /// Output warning and error messages in color - /// (Originally from ../FSComp.txt:902) + /// (Originally from ..\FSComp.txt:902) static member optsConsoleColors() = (GetStringFunc("optsConsoleColors",",,,") ) /// Enable high-entropy ASLR - /// (Originally from ../FSComp.txt:903) + /// (Originally from ..\FSComp.txt:903) static member optsUseHighEntropyVA() = (GetStringFunc("optsUseHighEntropyVA",",,,") ) /// Specify subsystem version of this assembly - /// (Originally from ../FSComp.txt:904) + /// (Originally from ..\FSComp.txt:904) static member optsSubSystemVersion() = (GetStringFunc("optsSubSystemVersion",",,,") ) /// Specify target framework profile of this assembly. Valid values are mscorlib, netcore or netstandard. Default - mscorlib - /// (Originally from ../FSComp.txt:905) + /// (Originally from ..\FSComp.txt:905) static member optsTargetProfile() = (GetStringFunc("optsTargetProfile",",,,") ) /// Emit debug information in quotations - /// (Originally from ../FSComp.txt:906) + /// (Originally from ..\FSComp.txt:906) static member optsEmitDebugInfoInQuotations() = (GetStringFunc("optsEmitDebugInfoInQuotations",",,,") ) /// Specify the preferred output language culture name (e.g. es-ES, ja-JP) - /// (Originally from ../FSComp.txt:907) + /// (Originally from ..\FSComp.txt:907) static member optsPreferredUiLang() = (GetStringFunc("optsPreferredUiLang",",,,") ) /// Don't copy FSharp.Core.dll along the produced binaries - /// (Originally from ../FSComp.txt:908) + /// (Originally from ..\FSComp.txt:908) static member optsNoCopyFsharpCore() = (GetStringFunc("optsNoCopyFsharpCore",",,,") ) /// Invalid version '%s' for '--subsystemversion'. The version must be 4.00 or greater. - /// (Originally from ../FSComp.txt:909) + /// (Originally from ..\FSComp.txt:909) static member optsInvalidSubSystemVersion(a0 : System.String) = (1051, GetStringFunc("optsInvalidSubSystemVersion",",,,%s,,,") a0) /// Invalid value '%s' for '--targetprofile', valid values are 'mscorlib', 'netcore' or 'netstandard'. - /// (Originally from ../FSComp.txt:910) + /// (Originally from ..\FSComp.txt:910) static member optsInvalidTargetProfile(a0 : System.String) = (1052, GetStringFunc("optsInvalidTargetProfile",",,,%s,,,") a0) /// Full name - /// (Originally from ../FSComp.txt:911) + /// (Originally from ..\FSComp.txt:911) static member typeInfoFullName() = (GetStringFunc("typeInfoFullName",",,,") ) /// and %d other overloads - /// (Originally from ../FSComp.txt:915) + /// (Originally from ..\FSComp.txt:915) static member typeInfoOtherOverloads(a0 : System.Int32) = (GetStringFunc("typeInfoOtherOverloads",",,,%d,,,") a0) /// union case - /// (Originally from ../FSComp.txt:916) + /// (Originally from ..\FSComp.txt:916) static member typeInfoUnionCase() = (GetStringFunc("typeInfoUnionCase",",,,") ) /// active pattern result - /// (Originally from ../FSComp.txt:917) + /// (Originally from ..\FSComp.txt:917) static member typeInfoActivePatternResult() = (GetStringFunc("typeInfoActivePatternResult",",,,") ) /// active recognizer - /// (Originally from ../FSComp.txt:918) + /// (Originally from ..\FSComp.txt:918) static member typeInfoActiveRecognizer() = (GetStringFunc("typeInfoActiveRecognizer",",,,") ) /// field - /// (Originally from ../FSComp.txt:919) + /// (Originally from ..\FSComp.txt:919) static member typeInfoField() = (GetStringFunc("typeInfoField",",,,") ) /// event - /// (Originally from ../FSComp.txt:920) + /// (Originally from ..\FSComp.txt:920) static member typeInfoEvent() = (GetStringFunc("typeInfoEvent",",,,") ) /// property - /// (Originally from ../FSComp.txt:921) + /// (Originally from ..\FSComp.txt:921) static member typeInfoProperty() = (GetStringFunc("typeInfoProperty",",,,") ) /// extension - /// (Originally from ../FSComp.txt:922) + /// (Originally from ..\FSComp.txt:922) static member typeInfoExtension() = (GetStringFunc("typeInfoExtension",",,,") ) /// custom operation - /// (Originally from ../FSComp.txt:923) + /// (Originally from ..\FSComp.txt:923) static member typeInfoCustomOperation() = (GetStringFunc("typeInfoCustomOperation",",,,") ) /// argument - /// (Originally from ../FSComp.txt:924) + /// (Originally from ..\FSComp.txt:924) static member typeInfoArgument() = (GetStringFunc("typeInfoArgument",",,,") ) /// patvar - /// (Originally from ../FSComp.txt:925) + /// (Originally from ..\FSComp.txt:925) static member typeInfoPatternVariable() = (GetStringFunc("typeInfoPatternVariable",",,,") ) /// namespace - /// (Originally from ../FSComp.txt:926) + /// (Originally from ..\FSComp.txt:926) static member typeInfoNamespace() = (GetStringFunc("typeInfoNamespace",",,,") ) /// module - /// (Originally from ../FSComp.txt:927) + /// (Originally from ..\FSComp.txt:927) static member typeInfoModule() = (GetStringFunc("typeInfoModule",",,,") ) /// namespace/module - /// (Originally from ../FSComp.txt:928) + /// (Originally from ..\FSComp.txt:928) static member typeInfoNamespaceOrModule() = (GetStringFunc("typeInfoNamespaceOrModule",",,,") ) /// from %s - /// (Originally from ../FSComp.txt:929) + /// (Originally from ..\FSComp.txt:929) static member typeInfoFromFirst(a0 : System.String) = (GetStringFunc("typeInfoFromFirst",",,,%s,,,") a0) /// also from %s - /// (Originally from ../FSComp.txt:930) + /// (Originally from ..\FSComp.txt:930) static member typeInfoFromNext(a0 : System.String) = (GetStringFunc("typeInfoFromNext",",,,%s,,,") a0) /// generated property - /// (Originally from ../FSComp.txt:931) + /// (Originally from ..\FSComp.txt:931) static member typeInfoGeneratedProperty() = (GetStringFunc("typeInfoGeneratedProperty",",,,") ) /// generated type - /// (Originally from ../FSComp.txt:932) + /// (Originally from ..\FSComp.txt:932) static member typeInfoGeneratedType() = (GetStringFunc("typeInfoGeneratedType",",,,") ) /// Found by AssemblyFolders registry key - /// (Originally from ../FSComp.txt:933) + /// (Originally from ..\FSComp.txt:933) static member assemblyResolutionFoundByAssemblyFoldersKey() = (GetStringFunc("assemblyResolutionFoundByAssemblyFoldersKey",",,,") ) /// Found by AssemblyFoldersEx registry key - /// (Originally from ../FSComp.txt:934) + /// (Originally from ..\FSComp.txt:934) static member assemblyResolutionFoundByAssemblyFoldersExKey() = (GetStringFunc("assemblyResolutionFoundByAssemblyFoldersExKey",",,,") ) /// .NET Framework - /// (Originally from ../FSComp.txt:935) + /// (Originally from ..\FSComp.txt:935) static member assemblyResolutionNetFramework() = (GetStringFunc("assemblyResolutionNetFramework",",,,") ) /// Global Assembly Cache - /// (Originally from ../FSComp.txt:936) + /// (Originally from ..\FSComp.txt:936) static member assemblyResolutionGAC() = (GetStringFunc("assemblyResolutionGAC",",,,") ) /// Recursive class hierarchy in type '%s' - /// (Originally from ../FSComp.txt:937) + /// (Originally from ..\FSComp.txt:937) static member recursiveClassHierarchy(a0 : System.String) = (1089, GetStringFunc("recursiveClassHierarchy",",,,%s,,,") a0) /// Invalid recursive reference to an abstract slot - /// (Originally from ../FSComp.txt:938) + /// (Originally from ..\FSComp.txt:938) static member InvalidRecursiveReferenceToAbstractSlot() = (1090, GetStringFunc("InvalidRecursiveReferenceToAbstractSlot",",,,") ) /// The event '%s' has a non-standard type. If this event is declared in another CLI language, you may need to access this event using the explicit %s and %s methods for the event. If this event is declared in F#, make the type of the event an instantiation of either 'IDelegateEvent<_>' or 'IEvent<_,_>'. - /// (Originally from ../FSComp.txt:939) + /// (Originally from ..\FSComp.txt:939) static member eventHasNonStandardType(a0 : System.String, a1 : System.String, a2 : System.String) = (1091, GetStringFunc("eventHasNonStandardType",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The type '%s' is not accessible from this code location - /// (Originally from ../FSComp.txt:940) + /// (Originally from ..\FSComp.txt:940) static member typeIsNotAccessible(a0 : System.String) = (1092, GetStringFunc("typeIsNotAccessible",",,,%s,,,") a0) /// The union cases or fields of the type '%s' are not accessible from this code location - /// (Originally from ../FSComp.txt:941) + /// (Originally from ..\FSComp.txt:941) static member unionCasesAreNotAccessible(a0 : System.String) = (1093, GetStringFunc("unionCasesAreNotAccessible",",,,%s,,,") a0) /// The value '%s' is not accessible from this code location - /// (Originally from ../FSComp.txt:942) + /// (Originally from ..\FSComp.txt:942) static member valueIsNotAccessible(a0 : System.String) = (1094, GetStringFunc("valueIsNotAccessible",",,,%s,,,") a0) /// The union case '%s' is not accessible from this code location - /// (Originally from ../FSComp.txt:943) + /// (Originally from ..\FSComp.txt:943) static member unionCaseIsNotAccessible(a0 : System.String) = (1095, GetStringFunc("unionCaseIsNotAccessible",",,,%s,,,") a0) /// The record, struct or class field '%s' is not accessible from this code location - /// (Originally from ../FSComp.txt:944) + /// (Originally from ..\FSComp.txt:944) static member fieldIsNotAccessible(a0 : System.String) = (1096, GetStringFunc("fieldIsNotAccessible",",,,%s,,,") a0) /// The struct or class field '%s' is not accessible from this code location - /// (Originally from ../FSComp.txt:945) + /// (Originally from ..\FSComp.txt:945) static member structOrClassFieldIsNotAccessible(a0 : System.String) = (1097, GetStringFunc("structOrClassFieldIsNotAccessible",",,,%s,,,") a0) /// This construct is experimental - /// (Originally from ../FSComp.txt:946) + /// (Originally from ..\FSComp.txt:946) static member experimentalConstruct() = (GetStringFunc("experimentalConstruct",",,,") ) /// No Invoke methods found for delegate type - /// (Originally from ../FSComp.txt:947) + /// (Originally from ..\FSComp.txt:947) static member noInvokeMethodsFound() = (1099, GetStringFunc("noInvokeMethodsFound",",,,") ) /// More than one Invoke method found for delegate type - /// (Originally from ../FSComp.txt:948) + /// (Originally from ..\FSComp.txt:948) static member moreThanOneInvokeMethodFound() = (GetStringFunc("moreThanOneInvokeMethodFound",",,,") ) /// Delegates are not allowed to have curried signatures - /// (Originally from ../FSComp.txt:949) + /// (Originally from ..\FSComp.txt:949) static member delegatesNotAllowedToHaveCurriedSignatures() = (1101, GetStringFunc("delegatesNotAllowedToHaveCurriedSignatures",",,,") ) /// Unexpected Expr.TyChoose - /// (Originally from ../FSComp.txt:950) + /// (Originally from ..\FSComp.txt:950) static member tlrUnexpectedTExpr() = (1102, GetStringFunc("tlrUnexpectedTExpr",",,,") ) /// Note: Lambda-lifting optimizations have not been applied because of the use of this local constrained generic function as a first class value. Adding type constraints may resolve this condition. - /// (Originally from ../FSComp.txt:951) + /// (Originally from ..\FSComp.txt:951) static member tlrLambdaLiftingOptimizationsNotApplied() = (1103, GetStringFunc("tlrLambdaLiftingOptimizationsNotApplied",",,,") ) /// Identifiers containing '@' are reserved for use in F# code generation - /// (Originally from ../FSComp.txt:952) + /// (Originally from ..\FSComp.txt:952) static member lexhlpIdentifiersContainingAtSymbolReserved() = (1104, GetStringFunc("lexhlpIdentifiersContainingAtSymbolReserved",",,,") ) /// The identifier '%s' is reserved for future use by F# - /// (Originally from ../FSComp.txt:953) + /// (Originally from ..\FSComp.txt:953) static member lexhlpIdentifierReserved(a0 : System.String) = (GetStringFunc("lexhlpIdentifierReserved",",,,%s,,,") a0) /// Missing variable '%s' - /// (Originally from ../FSComp.txt:954) + /// (Originally from ..\FSComp.txt:954) static member patcMissingVariable(a0 : System.String) = (1106, GetStringFunc("patcMissingVariable",",,,%s,,,") a0) /// Partial active patterns may only generate one result - /// (Originally from ../FSComp.txt:955) + /// (Originally from ..\FSComp.txt:955) static member patcPartialActivePatternsGenerateOneResult() = (1107, GetStringFunc("patcPartialActivePatternsGenerateOneResult",",,,") ) /// The type '%s' is required here and is unavailable. You must add a reference to assembly '%s'. - /// (Originally from ../FSComp.txt:956) + /// (Originally from ..\FSComp.txt:956) static member impTypeRequiredUnavailable(a0 : System.String, a1 : System.String) = (1108, GetStringFunc("impTypeRequiredUnavailable",",,,%s,,,%s,,,") a0 a1) /// A reference to the type '%s' in assembly '%s' was found, but the type could not be found in that assembly - /// (Originally from ../FSComp.txt:957) + /// (Originally from ..\FSComp.txt:957) static member impReferencedTypeCouldNotBeFoundInAssembly(a0 : System.String, a1 : System.String) = (1109, GetStringFunc("impReferencedTypeCouldNotBeFoundInAssembly",",,,%s,,,%s,,,") a0 a1) /// Internal error or badly formed metadata: not enough type parameters were in scope while importing - /// (Originally from ../FSComp.txt:958) + /// (Originally from ..\FSComp.txt:958) static member impNotEnoughTypeParamsInScopeWhileImporting() = (1110, GetStringFunc("impNotEnoughTypeParamsInScopeWhileImporting",",,,") ) /// A reference to the DLL %s is required by assembly %s. The imported type %s is located in the first assembly and could not be resolved. - /// (Originally from ../FSComp.txt:959) + /// (Originally from ..\FSComp.txt:959) static member impReferenceToDllRequiredByAssembly(a0 : System.String, a1 : System.String, a2 : System.String) = (1111, GetStringFunc("impReferenceToDllRequiredByAssembly",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// An imported assembly uses the type '%s' but that type is not public - /// (Originally from ../FSComp.txt:960) + /// (Originally from ..\FSComp.txt:960) static member impImportedAssemblyUsesNotPublicType(a0 : System.String) = (1112, GetStringFunc("impImportedAssemblyUsesNotPublicType",",,,%s,,,") a0) /// The value '%s' was marked inline but its implementation makes use of an internal or private function which is not sufficiently accessible - /// (Originally from ../FSComp.txt:961) + /// (Originally from ..\FSComp.txt:961) static member optValueMarkedInlineButIncomplete(a0 : System.String) = (1113, GetStringFunc("optValueMarkedInlineButIncomplete",",,,%s,,,") a0) /// The value '%s' was marked inline but was not bound in the optimization environment - /// (Originally from ../FSComp.txt:962) + /// (Originally from ..\FSComp.txt:962) static member optValueMarkedInlineButWasNotBoundInTheOptEnv(a0 : System.String) = (1114, GetStringFunc("optValueMarkedInlineButWasNotBoundInTheOptEnv",",,,%s,,,") a0) /// Local value %s not found during optimization - /// (Originally from ../FSComp.txt:963) + /// (Originally from ..\FSComp.txt:963) static member optLocalValueNotFoundDuringOptimization(a0 : System.String) = (1115, GetStringFunc("optLocalValueNotFoundDuringOptimization",",,,%s,,,") a0) /// A value marked as 'inline' has an unexpected value - /// (Originally from ../FSComp.txt:964) + /// (Originally from ..\FSComp.txt:964) static member optValueMarkedInlineHasUnexpectedValue() = (1116, GetStringFunc("optValueMarkedInlineHasUnexpectedValue",",,,") ) /// A value marked as 'inline' could not be inlined - /// (Originally from ../FSComp.txt:965) + /// (Originally from ..\FSComp.txt:965) static member optValueMarkedInlineCouldNotBeInlined() = (1117, GetStringFunc("optValueMarkedInlineCouldNotBeInlined",",,,") ) /// Failed to inline the value '%s' marked 'inline', perhaps because a recursive value was marked 'inline' - /// (Originally from ../FSComp.txt:966) + /// (Originally from ..\FSComp.txt:966) static member optFailedToInlineValue(a0 : System.String) = (1118, GetStringFunc("optFailedToInlineValue",",,,%s,,,") a0) /// Recursive ValValue %s - /// (Originally from ../FSComp.txt:967) + /// (Originally from ..\FSComp.txt:967) static member optRecursiveValValue(a0 : System.String) = (1119, GetStringFunc("optRecursiveValValue",",,,%s,,,") a0) /// The indentation of this 'in' token is incorrect with respect to the corresponding 'let' - /// (Originally from ../FSComp.txt:968) + /// (Originally from ..\FSComp.txt:968) static member lexfltIncorrentIndentationOfIn() = (GetStringFunc("lexfltIncorrentIndentationOfIn",",,,") ) /// Possible incorrect indentation: this token is offside of context started at position %s. Try indenting this token further or using standard formatting conventions. - /// (Originally from ../FSComp.txt:969) + /// (Originally from ..\FSComp.txt:969) static member lexfltTokenIsOffsideOfContextStartedEarlier(a0 : System.String) = (GetStringFunc("lexfltTokenIsOffsideOfContextStartedEarlier",",,,%s,,,") a0) /// The '|' tokens separating rules of this pattern match are misaligned by one column. Consider realigning your code or using further indentation. - /// (Originally from ../FSComp.txt:970) + /// (Originally from ..\FSComp.txt:970) static member lexfltSeparatorTokensOfPatternMatchMisaligned() = (GetStringFunc("lexfltSeparatorTokensOfPatternMatchMisaligned",",,,") ) /// Invalid module/expression/type - /// (Originally from ../FSComp.txt:971) + /// (Originally from ..\FSComp.txt:971) static member nrInvalidModuleExprType() = (1123, GetStringFunc("nrInvalidModuleExprType",",,,") ) /// Multiple types exist called '%s', taking different numbers of generic parameters. Provide a type instantiation to disambiguate the type resolution, e.g. '%s'. - /// (Originally from ../FSComp.txt:972) + /// (Originally from ..\FSComp.txt:972) static member nrTypeInstantiationNeededToDisambiguateTypesWithSameName(a0 : System.String, a1 : System.String) = (1124, GetStringFunc("nrTypeInstantiationNeededToDisambiguateTypesWithSameName",",,,%s,,,%s,,,") a0 a1) /// The instantiation of the generic type '%s' is missing and can't be inferred from the arguments or return type of this member. Consider providing a type instantiation when accessing this type, e.g. '%s'. - /// (Originally from ../FSComp.txt:973) + /// (Originally from ..\FSComp.txt:973) static member nrTypeInstantiationIsMissingAndCouldNotBeInferred(a0 : System.String, a1 : System.String) = (1125, GetStringFunc("nrTypeInstantiationIsMissingAndCouldNotBeInferred",",,,%s,,,%s,,,") a0 a1) /// 'global' may only be used as the first name in a qualified path - /// (Originally from ../FSComp.txt:974) + /// (Originally from ..\FSComp.txt:974) static member nrGlobalUsedOnlyAsFirstName() = (1126, GetStringFunc("nrGlobalUsedOnlyAsFirstName",",,,") ) /// This is not a constructor or literal, or a constructor is being used incorrectly - /// (Originally from ../FSComp.txt:975) + /// (Originally from ..\FSComp.txt:975) static member nrIsNotConstructorOrLiteral() = (1127, GetStringFunc("nrIsNotConstructorOrLiteral",",,,") ) /// Unexpected empty long identifier - /// (Originally from ../FSComp.txt:976) + /// (Originally from ..\FSComp.txt:976) static member nrUnexpectedEmptyLongId() = (1128, GetStringFunc("nrUnexpectedEmptyLongId",",,,") ) /// The record type '%s' does not contain a label '%s'. - /// (Originally from ../FSComp.txt:977) + /// (Originally from ..\FSComp.txt:977) static member nrRecordDoesNotContainSuchLabel(a0 : System.String, a1 : System.String) = (1129, GetStringFunc("nrRecordDoesNotContainSuchLabel",",,,%s,,,%s,,,") a0 a1) /// Invalid field label - /// (Originally from ../FSComp.txt:978) + /// (Originally from ..\FSComp.txt:978) static member nrInvalidFieldLabel() = (1130, GetStringFunc("nrInvalidFieldLabel",",,,") ) /// Invalid expression '%s' - /// (Originally from ../FSComp.txt:979) + /// (Originally from ..\FSComp.txt:979) static member nrInvalidExpression(a0 : System.String) = (1132, GetStringFunc("nrInvalidExpression",",,,%s,,,") a0) /// No constructors are available for the type '%s' - /// (Originally from ../FSComp.txt:980) + /// (Originally from ..\FSComp.txt:980) static member nrNoConstructorsAvailableForType(a0 : System.String) = (1133, GetStringFunc("nrNoConstructorsAvailableForType",",,,%s,,,") a0) /// The union type for union case '%s' was defined with the RequireQualifiedAccessAttribute. Include the name of the union type ('%s') in the name you are using. - /// (Originally from ../FSComp.txt:981) + /// (Originally from ..\FSComp.txt:981) static member nrUnionTypeNeedsQualifiedAccess(a0 : System.String, a1 : System.String) = (1134, GetStringFunc("nrUnionTypeNeedsQualifiedAccess",",,,%s,,,%s,,,") a0 a1) /// The record type for the record field '%s' was defined with the RequireQualifiedAccessAttribute. Include the name of the record type ('%s') in the name you are using. - /// (Originally from ../FSComp.txt:982) + /// (Originally from ..\FSComp.txt:982) static member nrRecordTypeNeedsQualifiedAccess(a0 : System.String, a1 : System.String) = (1135, GetStringFunc("nrRecordTypeNeedsQualifiedAccess",",,,%s,,,%s,,,") a0 a1) /// Unexpected error creating debug information file '%s' - /// (Originally from ../FSComp.txt:983) + /// (Originally from ..\FSComp.txt:983) static member ilwriteErrorCreatingPdb(a0 : System.String) = (1136, GetStringFunc("ilwriteErrorCreatingPdb",",,,%s,,,") a0) /// This number is outside the allowable range for this integer type - /// (Originally from ../FSComp.txt:984) + /// (Originally from ..\FSComp.txt:984) static member lexOutsideIntegerRange() = (1138, GetStringFunc("lexOutsideIntegerRange",",,,") ) /// '%s' is not permitted as a character in operator names and is reserved for future use - /// (Originally from ../FSComp.txt:988) + /// (Originally from ..\FSComp.txt:988) static member lexCharNotAllowedInOperatorNames(a0 : System.String) = (GetStringFunc("lexCharNotAllowedInOperatorNames",",,,%s,,,") a0) /// Unexpected character '%s' - /// (Originally from ../FSComp.txt:989) + /// (Originally from ..\FSComp.txt:989) static member lexUnexpectedChar(a0 : System.String) = (GetStringFunc("lexUnexpectedChar",",,,%s,,,") a0) /// This byte array literal contains characters that do not encode as a single byte - /// (Originally from ../FSComp.txt:990) + /// (Originally from ..\FSComp.txt:990) static member lexByteArrayCannotEncode() = (1140, GetStringFunc("lexByteArrayCannotEncode",",,,") ) /// Identifiers followed by '%s' are reserved for future use - /// (Originally from ../FSComp.txt:991) + /// (Originally from ..\FSComp.txt:991) static member lexIdentEndInMarkReserved(a0 : System.String) = (1141, GetStringFunc("lexIdentEndInMarkReserved",",,,%s,,,") a0) /// This number is outside the allowable range for 8-bit signed integers - /// (Originally from ../FSComp.txt:992) + /// (Originally from ..\FSComp.txt:992) static member lexOutsideEightBitSigned() = (1142, GetStringFunc("lexOutsideEightBitSigned",",,,") ) /// This number is outside the allowable range for hexadecimal 8-bit signed integers - /// (Originally from ../FSComp.txt:993) + /// (Originally from ..\FSComp.txt:993) static member lexOutsideEightBitSignedHex() = (1143, GetStringFunc("lexOutsideEightBitSignedHex",",,,") ) /// This number is outside the allowable range for 8-bit unsigned integers - /// (Originally from ../FSComp.txt:994) + /// (Originally from ..\FSComp.txt:994) static member lexOutsideEightBitUnsigned() = (1144, GetStringFunc("lexOutsideEightBitUnsigned",",,,") ) /// This number is outside the allowable range for 16-bit signed integers - /// (Originally from ../FSComp.txt:995) + /// (Originally from ..\FSComp.txt:995) static member lexOutsideSixteenBitSigned() = (1145, GetStringFunc("lexOutsideSixteenBitSigned",",,,") ) /// This number is outside the allowable range for 16-bit unsigned integers - /// (Originally from ../FSComp.txt:996) + /// (Originally from ..\FSComp.txt:996) static member lexOutsideSixteenBitUnsigned() = (1146, GetStringFunc("lexOutsideSixteenBitUnsigned",",,,") ) /// This number is outside the allowable range for 32-bit signed integers - /// (Originally from ../FSComp.txt:997) + /// (Originally from ..\FSComp.txt:997) static member lexOutsideThirtyTwoBitSigned() = (1147, GetStringFunc("lexOutsideThirtyTwoBitSigned",",,,") ) /// This number is outside the allowable range for 32-bit unsigned integers - /// (Originally from ../FSComp.txt:998) + /// (Originally from ..\FSComp.txt:998) static member lexOutsideThirtyTwoBitUnsigned() = (1148, GetStringFunc("lexOutsideThirtyTwoBitUnsigned",",,,") ) /// This number is outside the allowable range for 64-bit signed integers - /// (Originally from ../FSComp.txt:999) + /// (Originally from ..\FSComp.txt:999) static member lexOutsideSixtyFourBitSigned() = (1149, GetStringFunc("lexOutsideSixtyFourBitSigned",",,,") ) /// This number is outside the allowable range for 64-bit unsigned integers - /// (Originally from ../FSComp.txt:1000) + /// (Originally from ..\FSComp.txt:1000) static member lexOutsideSixtyFourBitUnsigned() = (1150, GetStringFunc("lexOutsideSixtyFourBitUnsigned",",,,") ) /// This number is outside the allowable range for signed native integers - /// (Originally from ../FSComp.txt:1001) + /// (Originally from ..\FSComp.txt:1001) static member lexOutsideNativeSigned() = (1151, GetStringFunc("lexOutsideNativeSigned",",,,") ) /// This number is outside the allowable range for unsigned native integers - /// (Originally from ../FSComp.txt:1002) + /// (Originally from ..\FSComp.txt:1002) static member lexOutsideNativeUnsigned() = (1152, GetStringFunc("lexOutsideNativeUnsigned",",,,") ) /// Invalid floating point number - /// (Originally from ../FSComp.txt:1003) + /// (Originally from ..\FSComp.txt:1003) static member lexInvalidFloat() = (1153, GetStringFunc("lexInvalidFloat",",,,") ) /// This number is outside the allowable range for decimal literals - /// (Originally from ../FSComp.txt:1004) + /// (Originally from ..\FSComp.txt:1004) static member lexOusideDecimal() = (1154, GetStringFunc("lexOusideDecimal",",,,") ) /// This number is outside the allowable range for 32-bit floats - /// (Originally from ../FSComp.txt:1005) + /// (Originally from ..\FSComp.txt:1005) static member lexOusideThirtyTwoBitFloat() = (1155, GetStringFunc("lexOusideThirtyTwoBitFloat",",,,") ) /// This is not a valid numeric literal. Valid numeric literals include 1, 0x1, 0b0001 (int), 1u (uint32), 1L (int64), 1UL (uint64), 1s (int16), 1y (sbyte), 1uy (byte), 1.0 (float), 1.0f (float32), 1.0m (decimal), 1I (BigInteger). - /// (Originally from ../FSComp.txt:1006) + /// (Originally from ..\FSComp.txt:1006) static member lexInvalidNumericLiteral() = (1156, GetStringFunc("lexInvalidNumericLiteral",",,,") ) /// This is not a valid byte literal - /// (Originally from ../FSComp.txt:1007) + /// (Originally from ..\FSComp.txt:1007) static member lexInvalidByteLiteral() = (1157, GetStringFunc("lexInvalidByteLiteral",",,,") ) /// This is not a valid character literal - /// (Originally from ../FSComp.txt:1008) + /// (Originally from ..\FSComp.txt:1008) static member lexInvalidCharLiteral() = (1158, GetStringFunc("lexInvalidCharLiteral",",,,") ) /// This Unicode encoding is only valid in string literals - /// (Originally from ../FSComp.txt:1009) + /// (Originally from ..\FSComp.txt:1009) static member lexThisUnicodeOnlyInStringLiterals() = (1159, GetStringFunc("lexThisUnicodeOnlyInStringLiterals",",,,") ) /// This token is reserved for future use - /// (Originally from ../FSComp.txt:1010) + /// (Originally from ..\FSComp.txt:1010) static member lexTokenReserved() = (1160, GetStringFunc("lexTokenReserved",",,,") ) /// TABs are not allowed in F# code unless the #indent \"off\" option is used - /// (Originally from ../FSComp.txt:1011) + /// (Originally from ..\FSComp.txt:1011) static member lexTabsNotAllowed() = (1161, GetStringFunc("lexTabsNotAllowed",",,,") ) /// Invalid line number: '%s' - /// (Originally from ../FSComp.txt:1012) + /// (Originally from ..\FSComp.txt:1012) static member lexInvalidLineNumber(a0 : System.String) = (1162, GetStringFunc("lexInvalidLineNumber",",,,%s,,,") a0) /// #if directive must appear as the first non-whitespace character on a line - /// (Originally from ../FSComp.txt:1013) + /// (Originally from ..\FSComp.txt:1013) static member lexHashIfMustBeFirst() = (1163, GetStringFunc("lexHashIfMustBeFirst",",,,") ) /// #else has no matching #if - /// (Originally from ../FSComp.txt:1014) + /// (Originally from ..\FSComp.txt:1014) static member lexHashElseNoMatchingIf() = (GetStringFunc("lexHashElseNoMatchingIf",",,,") ) /// #endif required for #else - /// (Originally from ../FSComp.txt:1015) + /// (Originally from ..\FSComp.txt:1015) static member lexHashEndifRequiredForElse() = (GetStringFunc("lexHashEndifRequiredForElse",",,,") ) /// #else directive must appear as the first non-whitespace character on a line - /// (Originally from ../FSComp.txt:1016) + /// (Originally from ..\FSComp.txt:1016) static member lexHashElseMustBeFirst() = (1166, GetStringFunc("lexHashElseMustBeFirst",",,,") ) /// #endif has no matching #if - /// (Originally from ../FSComp.txt:1017) + /// (Originally from ..\FSComp.txt:1017) static member lexHashEndingNoMatchingIf() = (GetStringFunc("lexHashEndingNoMatchingIf",",,,") ) /// #endif directive must appear as the first non-whitespace character on a line - /// (Originally from ../FSComp.txt:1018) + /// (Originally from ..\FSComp.txt:1018) static member lexHashEndifMustBeFirst() = (1168, GetStringFunc("lexHashEndifMustBeFirst",",,,") ) /// #if directive should be immediately followed by an identifier - /// (Originally from ../FSComp.txt:1019) + /// (Originally from ..\FSComp.txt:1019) static member lexHashIfMustHaveIdent() = (1169, GetStringFunc("lexHashIfMustHaveIdent",",,,") ) /// Syntax error. Wrong nested #endif, unexpected tokens before it. - /// (Originally from ../FSComp.txt:1020) + /// (Originally from ..\FSComp.txt:1020) static member lexWrongNestedHashEndif() = (1170, GetStringFunc("lexWrongNestedHashEndif",",,,") ) /// #! may only appear as the first line at the start of a file. - /// (Originally from ../FSComp.txt:1021) + /// (Originally from ..\FSComp.txt:1021) static member lexHashBangMustBeFirstInFile() = (GetStringFunc("lexHashBangMustBeFirstInFile",",,,") ) /// Expected single line comment or end of line - /// (Originally from ../FSComp.txt:1022) + /// (Originally from ..\FSComp.txt:1022) static member pplexExpectedSingleLineComment() = (1171, GetStringFunc("pplexExpectedSingleLineComment",",,,") ) /// Infix operator member '%s' has no arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - /// (Originally from ../FSComp.txt:1023) + /// (Originally from ..\FSComp.txt:1023) static member memberOperatorDefinitionWithNoArguments(a0 : System.String) = (1172, GetStringFunc("memberOperatorDefinitionWithNoArguments",",,,%s,,,") a0) /// Infix operator member '%s' has %d initial argument(s). Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - /// (Originally from ../FSComp.txt:1024) + /// (Originally from ..\FSComp.txt:1024) static member memberOperatorDefinitionWithNonPairArgument(a0 : System.String, a1 : System.Int32) = (1173, GetStringFunc("memberOperatorDefinitionWithNonPairArgument",",,,%s,,,%d,,,") a0 a1) /// Infix operator member '%s' has extra curried arguments. Expected a tuple of 2 arguments, e.g. static member (+) (x,y) = ... - /// (Originally from ../FSComp.txt:1025) + /// (Originally from ..\FSComp.txt:1025) static member memberOperatorDefinitionWithCurriedArguments(a0 : System.String) = (1174, GetStringFunc("memberOperatorDefinitionWithCurriedArguments",",,,%s,,,") a0) /// All record, union and struct types in FSharp.Core.dll must be explicitly labelled with 'StructuralComparison' or 'NoComparison' - /// (Originally from ../FSComp.txt:1026) + /// (Originally from ..\FSComp.txt:1026) static member tcFSharpCoreRequiresExplicit() = (1175, GetStringFunc("tcFSharpCoreRequiresExplicit",",,,") ) /// The struct, record or union type '%s' has the 'StructuralComparison' attribute but the type parameter '%s' does not satisfy the 'comparison' constraint. Consider adding the 'comparison' constraint to the type parameter - /// (Originally from ../FSComp.txt:1027) + /// (Originally from ..\FSComp.txt:1027) static member tcStructuralComparisonNotSatisfied1(a0 : System.String, a1 : System.String) = (1176, GetStringFunc("tcStructuralComparisonNotSatisfied1",",,,%s,,,%s,,,") a0 a1) /// The struct, record or union type '%s' has the 'StructuralComparison' attribute but the component type '%s' does not satisfy the 'comparison' constraint - /// (Originally from ../FSComp.txt:1028) + /// (Originally from ..\FSComp.txt:1028) static member tcStructuralComparisonNotSatisfied2(a0 : System.String, a1 : System.String) = (1177, GetStringFunc("tcStructuralComparisonNotSatisfied2",",,,%s,,,%s,,,") a0 a1) /// The struct, record or union type '%s' is not structurally comparable because the type parameter %s does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type '%s' to clarify that the type is not comparable - /// (Originally from ../FSComp.txt:1029) + /// (Originally from ..\FSComp.txt:1029) static member tcNoComparisonNeeded1(a0 : System.String, a1 : System.String, a2 : System.String) = (1178, GetStringFunc("tcNoComparisonNeeded1",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The struct, record or union type '%s' is not structurally comparable because the type '%s' does not satisfy the 'comparison' constraint. Consider adding the 'NoComparison' attribute to the type '%s' to clarify that the type is not comparable - /// (Originally from ../FSComp.txt:1030) + /// (Originally from ..\FSComp.txt:1030) static member tcNoComparisonNeeded2(a0 : System.String, a1 : System.String, a2 : System.String) = (1178, GetStringFunc("tcNoComparisonNeeded2",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The struct, record or union type '%s' does not support structural equality because the type parameter %s does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type '%s' to clarify that the type does not support structural equality - /// (Originally from ../FSComp.txt:1031) + /// (Originally from ..\FSComp.txt:1031) static member tcNoEqualityNeeded1(a0 : System.String, a1 : System.String, a2 : System.String) = (1178, GetStringFunc("tcNoEqualityNeeded1",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The struct, record or union type '%s' does not support structural equality because the type '%s' does not satisfy the 'equality' constraint. Consider adding the 'NoEquality' attribute to the type '%s' to clarify that the type does not support structural equality - /// (Originally from ../FSComp.txt:1032) + /// (Originally from ..\FSComp.txt:1032) static member tcNoEqualityNeeded2(a0 : System.String, a1 : System.String, a2 : System.String) = (1178, GetStringFunc("tcNoEqualityNeeded2",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The struct, record or union type '%s' has the 'StructuralEquality' attribute but the type parameter '%s' does not satisfy the 'equality' constraint. Consider adding the 'equality' constraint to the type parameter - /// (Originally from ../FSComp.txt:1033) + /// (Originally from ..\FSComp.txt:1033) static member tcStructuralEqualityNotSatisfied1(a0 : System.String, a1 : System.String) = (1179, GetStringFunc("tcStructuralEqualityNotSatisfied1",",,,%s,,,%s,,,") a0 a1) /// The struct, record or union type '%s' has the 'StructuralEquality' attribute but the component type '%s' does not satisfy the 'equality' constraint - /// (Originally from ../FSComp.txt:1034) + /// (Originally from ..\FSComp.txt:1034) static member tcStructuralEqualityNotSatisfied2(a0 : System.String, a1 : System.String) = (1180, GetStringFunc("tcStructuralEqualityNotSatisfied2",",,,%s,,,%s,,,") a0 a1) /// Each argument of the primary constructor for a struct must be given a type, for example 'type S(x1:int, x2: int) = ...'. These arguments determine the fields of the struct. - /// (Originally from ../FSComp.txt:1035) + /// (Originally from ..\FSComp.txt:1035) static member tcStructsMustDeclareTypesOfImplicitCtorArgsExplicitly() = (1181, GetStringFunc("tcStructsMustDeclareTypesOfImplicitCtorArgsExplicitly",",,,") ) /// The value '%s' is unused - /// (Originally from ../FSComp.txt:1036) + /// (Originally from ..\FSComp.txt:1036) static member chkUnusedValue(a0 : System.String) = (1182, GetStringFunc("chkUnusedValue",",,,%s,,,") a0) /// The recursive object reference '%s' is unused. The presence of a recursive object reference adds runtime initialization checks to members in this and derived types. Consider removing this recursive object reference. - /// (Originally from ../FSComp.txt:1037) + /// (Originally from ..\FSComp.txt:1037) static member chkUnusedThisVariable(a0 : System.String) = (1183, GetStringFunc("chkUnusedThisVariable",",,,%s,,,") a0) /// A getter property may have at most one argument group - /// (Originally from ../FSComp.txt:1038) + /// (Originally from ..\FSComp.txt:1038) static member parsGetterAtMostOneArgument() = (1184, GetStringFunc("parsGetterAtMostOneArgument",",,,") ) /// A setter property may have at most two argument groups - /// (Originally from ../FSComp.txt:1039) + /// (Originally from ..\FSComp.txt:1039) static member parsSetterAtMostTwoArguments() = (1185, GetStringFunc("parsSetterAtMostTwoArguments",",,,") ) /// Invalid property getter or setter - /// (Originally from ../FSComp.txt:1040) + /// (Originally from ..\FSComp.txt:1040) static member parsInvalidProperty() = (1186, GetStringFunc("parsInvalidProperty",",,,") ) /// An indexer property must be given at least one argument - /// (Originally from ../FSComp.txt:1041) + /// (Originally from ..\FSComp.txt:1041) static member parsIndexerPropertyRequiresAtLeastOneArgument() = (1187, GetStringFunc("parsIndexerPropertyRequiresAtLeastOneArgument",",,,") ) /// This operation accesses a mutable top-level value defined in another assembly in an unsupported way. The value cannot be accessed through its address. Consider copying the expression to a mutable local, e.g. 'let mutable x = ...', and if necessary assigning the value back after the completion of the operation - /// (Originally from ../FSComp.txt:1042) + /// (Originally from ..\FSComp.txt:1042) static member tastInvalidAddressOfMutableAcrossAssemblyBoundary() = (1188, GetStringFunc("tastInvalidAddressOfMutableAcrossAssemblyBoundary",",,,") ) /// Type parameters must be placed directly adjacent to the type name, e.g. \"type C<'T>\", not type \"C <'T>\" - /// (Originally from ../FSComp.txt:1043) + /// (Originally from ..\FSComp.txt:1043) static member parsNonAdjacentTypars() = (1189, GetStringFunc("parsNonAdjacentTypars",",,,") ) /// Type arguments must be placed directly adjacent to the type name, e.g. \"C<'T>\", not \"C <'T>\" - /// (Originally from ../FSComp.txt:1044) + /// (Originally from ..\FSComp.txt:1044) static member parsNonAdjacentTyargs() = (1190, GetStringFunc("parsNonAdjacentTyargs",",,,") ) /// The use of the type syntax 'int C' and 'C ' is not permitted here. Consider adjusting this type to be written in the form 'C' - /// (Originally from ../FSComp.txt:1045) + /// (Originally from ..\FSComp.txt:1045) static member parsNonAtomicType() = (GetStringFunc("parsNonAtomicType",",,,") ) /// The module/namespace '%s' from compilation unit '%s' did not contain the module/namespace '%s' - /// (Originally from ../FSComp.txt:1048) + /// (Originally from ..\FSComp.txt:1048) static member tastUndefinedItemRefModuleNamespace(a0 : System.String, a1 : System.String, a2 : System.String) = (1193, GetStringFunc("tastUndefinedItemRefModuleNamespace",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The module/namespace '%s' from compilation unit '%s' did not contain the val '%s' - /// (Originally from ../FSComp.txt:1049) + /// (Originally from ..\FSComp.txt:1049) static member tastUndefinedItemRefVal(a0 : System.String, a1 : System.String, a2 : System.String) = (1194, GetStringFunc("tastUndefinedItemRefVal",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The module/namespace '%s' from compilation unit '%s' did not contain the namespace, module or type '%s' - /// (Originally from ../FSComp.txt:1050) + /// (Originally from ..\FSComp.txt:1050) static member tastUndefinedItemRefModuleNamespaceType(a0 : System.String, a1 : System.String, a2 : System.String) = (1195, GetStringFunc("tastUndefinedItemRefModuleNamespaceType",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The 'UseNullAsTrueValue' attribute flag may only be used with union types that have one nullary case and at least one non-nullary case - /// (Originally from ../FSComp.txt:1051) + /// (Originally from ..\FSComp.txt:1051) static member tcInvalidUseNullAsTrueValue() = (1196, GetStringFunc("tcInvalidUseNullAsTrueValue",",,,") ) /// The parameter '%s' was inferred to have byref type. Parameters of byref type must be given an explicit type annotation, e.g. 'x1: byref'. When used, a byref parameter is implicitly dereferenced. - /// (Originally from ../FSComp.txt:1052) + /// (Originally from ..\FSComp.txt:1052) static member tcParameterInferredByref(a0 : System.String) = (1197, GetStringFunc("tcParameterInferredByref",",,,%s,,,") a0) /// The generic member '%s' has been used at a non-uniform instantiation prior to this program point. Consider reordering the members so this member occurs first. Alternatively, specify the full type of the member explicitly, including argument types, return type and any additional generic parameters and constraints. - /// (Originally from ../FSComp.txt:1053) + /// (Originally from ..\FSComp.txt:1053) static member tcNonUniformMemberUse(a0 : System.String) = (1198, GetStringFunc("tcNonUniformMemberUse",",,,%s,,,") a0) /// The attribute '%s' appears in both the implementation and the signature, but the attribute arguments differ. Only the attribute from the signature will be included in the compiled code. - /// (Originally from ../FSComp.txt:1054) + /// (Originally from ..\FSComp.txt:1054) static member tcAttribArgsDiffer(a0 : System.String) = (1200, GetStringFunc("tcAttribArgsDiffer",",,,%s,,,") a0) /// Cannot call an abstract base member: '%s' - /// (Originally from ../FSComp.txt:1055) + /// (Originally from ..\FSComp.txt:1055) static member tcCannotCallAbstractBaseMember(a0 : System.String) = (1201, GetStringFunc("tcCannotCallAbstractBaseMember",",,,%s,,,") a0) /// Could not resolve the ambiguity in the use of a generic construct with an 'unmanaged' constraint at or near this position - /// (Originally from ../FSComp.txt:1056) + /// (Originally from ..\FSComp.txt:1056) static member typrelCannotResolveAmbiguityInUnmanaged() = (1202, GetStringFunc("typrelCannotResolveAmbiguityInUnmanaged",",,,") ) /// This construct is for ML compatibility. %s. You can disable this warning by using '--mlcompatibility' or '--nowarn:62'. - /// (Originally from ../FSComp.txt:1059) + /// (Originally from ..\FSComp.txt:1059) static member mlCompatMessage(a0 : System.String) = (GetStringFunc("mlCompatMessage",",,,%s,,,") a0) /// The type '%s' has been marked as having an Explicit layout, but the field '%s' has not been marked with the 'FieldOffset' attribute - /// (Originally from ../FSComp.txt:1061) + /// (Originally from ..\FSComp.txt:1061) static member ilFieldDoesNotHaveValidOffsetForStructureLayout(a0 : System.String, a1 : System.String) = (1206, GetStringFunc("ilFieldDoesNotHaveValidOffsetForStructureLayout",",,,%s,,,%s,,,") a0 a1) /// Interfaces inherited by other interfaces should be declared using 'inherit ...' instead of 'interface ...' - /// (Originally from ../FSComp.txt:1062) + /// (Originally from ..\FSComp.txt:1062) static member tcInterfacesShouldUseInheritNotInterface() = (1207, GetStringFunc("tcInterfacesShouldUseInheritNotInterface",",,,") ) /// Invalid prefix operator - /// (Originally from ../FSComp.txt:1063) + /// (Originally from ..\FSComp.txt:1063) static member parsInvalidPrefixOperator() = (1208, GetStringFunc("parsInvalidPrefixOperator",",,,") ) /// Invalid operator definition. Prefix operator definitions must use a valid prefix operator name. - /// (Originally from ../FSComp.txt:1064) + /// (Originally from ..\FSComp.txt:1064) static member parsInvalidPrefixOperatorDefinition() = (1208, GetStringFunc("parsInvalidPrefixOperatorDefinition",",,,") ) /// The file extensions '.ml' and '.mli' are for ML compatibility - /// (Originally from ../FSComp.txt:1065) + /// (Originally from ..\FSComp.txt:1065) static member buildCompilingExtensionIsForML() = (GetStringFunc("buildCompilingExtensionIsForML",",,,") ) /// Consider using a file with extension '.ml' or '.mli' instead - /// (Originally from ../FSComp.txt:1066) + /// (Originally from ..\FSComp.txt:1066) static member lexIndentOffForML() = (GetStringFunc("lexIndentOffForML",",,,") ) /// Active pattern '%s' is not a function - /// (Originally from ../FSComp.txt:1067) + /// (Originally from ..\FSComp.txt:1067) static member activePatternIdentIsNotFunctionTyped(a0 : System.String) = (1209, GetStringFunc("activePatternIdentIsNotFunctionTyped",",,,%s,,,") a0) /// Active pattern '%s' has a result type containing type variables that are not determined by the input. The common cause is a when a result case is not mentioned, e.g. 'let (|A|B|) (x:int) = A x'. This can be fixed with a type constraint, e.g. 'let (|A|B|) (x:int) : Choice = A x' - /// (Originally from ../FSComp.txt:1068) + /// (Originally from ..\FSComp.txt:1068) static member activePatternChoiceHasFreeTypars(a0 : System.String) = (1210, GetStringFunc("activePatternChoiceHasFreeTypars",",,,%s,,,") a0) /// The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit) - /// (Originally from ../FSComp.txt:1069) + /// (Originally from ..\FSComp.txt:1069) static member ilFieldHasOffsetForSequentialLayout() = (1211, GetStringFunc("ilFieldHasOffsetForSequentialLayout",",,,") ) /// Optional arguments must come at the end of the argument list, after any non-optional arguments - /// (Originally from ../FSComp.txt:1070) + /// (Originally from ..\FSComp.txt:1070) static member tcOptionalArgsMustComeAfterNonOptionalArgs() = (1212, GetStringFunc("tcOptionalArgsMustComeAfterNonOptionalArgs",",,,") ) /// Attribute 'System.Diagnostics.ConditionalAttribute' is only valid on methods or attribute classes - /// (Originally from ../FSComp.txt:1071) + /// (Originally from ..\FSComp.txt:1071) static member tcConditionalAttributeUsage() = (1213, GetStringFunc("tcConditionalAttributeUsage",",,,") ) /// Extension members cannot provide operator overloads. Consider defining the operator as part of the type definition instead. - /// (Originally from ../FSComp.txt:1073) + /// (Originally from ..\FSComp.txt:1073) static member tcMemberOperatorDefinitionInExtrinsic() = (1215, GetStringFunc("tcMemberOperatorDefinitionInExtrinsic",",,,") ) /// The name of the MDB file must be .mdb. The --pdb option will be ignored. - /// (Originally from ../FSComp.txt:1074) + /// (Originally from ..\FSComp.txt:1074) static member ilwriteMDBFileNameCannotBeChangedWarning() = (1216, GetStringFunc("ilwriteMDBFileNameCannotBeChangedWarning",",,,") ) /// MDB generation failed. Could not find compatible member %s - /// (Originally from ../FSComp.txt:1075) + /// (Originally from ..\FSComp.txt:1075) static member ilwriteMDBMemberMissing(a0 : System.String) = (1217, GetStringFunc("ilwriteMDBMemberMissing",",,,%s,,,") a0) /// Cannot generate MDB debug information. Failed to load the 'MonoSymbolWriter' type from the 'Mono.CompilerServices.SymbolWriter.dll' assembly. - /// (Originally from ../FSComp.txt:1076) + /// (Originally from ..\FSComp.txt:1076) static member ilwriteErrorCreatingMdb() = (1218, GetStringFunc("ilwriteErrorCreatingMdb",",,,") ) /// The union case named '%s' conflicts with the generated type '%s' - /// (Originally from ../FSComp.txt:1077) + /// (Originally from ..\FSComp.txt:1077) static member tcUnionCaseNameConflictsWithGeneratedType(a0 : System.String, a1 : System.String) = (1219, GetStringFunc("tcUnionCaseNameConflictsWithGeneratedType",",,,%s,,,%s,,,") a0 a1) /// ReflectedDefinitionAttribute may not be applied to an instance member on a struct type, because the instance member takes an implicit 'this' byref parameter - /// (Originally from ../FSComp.txt:1078) + /// (Originally from ..\FSComp.txt:1078) static member chkNoReflectedDefinitionOnStructMember() = (1220, GetStringFunc("chkNoReflectedDefinitionOnStructMember",",,,") ) /// DLLImport bindings must be static members in a class or function definitions in a module - /// (Originally from ../FSComp.txt:1079) + /// (Originally from ..\FSComp.txt:1079) static member tcDllImportNotAllowed() = (1221, GetStringFunc("tcDllImportNotAllowed",",,,") ) /// When mscorlib.dll or FSharp.Core.dll is explicitly referenced the %s option must also be passed - /// (Originally from ../FSComp.txt:1080) + /// (Originally from ..\FSComp.txt:1080) static member buildExplicitCoreLibRequiresNoFramework(a0 : System.String) = (1222, GetStringFunc("buildExplicitCoreLibRequiresNoFramework",",,,%s,,,") a0) /// FSharp.Core.sigdata not found alongside FSharp.Core. File expected in %s. Consider upgrading to a more recent version of FSharp.Core, where this file is no longer be required. - /// (Originally from ../FSComp.txt:1081) + /// (Originally from ..\FSComp.txt:1081) static member buildExpectedSigdataFile(a0 : System.String) = (1223, GetStringFunc("buildExpectedSigdataFile",",,,%s,,,") a0) /// File '%s' not found alongside FSharp.Core. File expected in %s. Consider upgrading to a more recent version of FSharp.Core, where this file is no longer be required. - /// (Originally from ../FSComp.txt:1082) + /// (Originally from ..\FSComp.txt:1082) static member buildExpectedFileAlongSideFSharpCore(a0 : System.String, a1 : System.String) = (1225, GetStringFunc("buildExpectedFileAlongSideFSharpCore",",,,%s,,,%s,,,") a0 a1) /// Filename '%s' contains invalid character '%s' - /// (Originally from ../FSComp.txt:1083) + /// (Originally from ..\FSComp.txt:1083) static member buildUnexpectedFileNameCharacter(a0 : System.String, a1 : System.String) = (1227, GetStringFunc("buildUnexpectedFileNameCharacter",",,,%s,,,%s,,,") a0 a1) /// 'use!' bindings must be of the form 'use! = ' - /// (Originally from ../FSComp.txt:1084) + /// (Originally from ..\FSComp.txt:1084) static member tcInvalidUseBangBinding() = (1228, GetStringFunc("tcInvalidUseBangBinding",",,,") ) /// Inner generic functions are not permitted in quoted expressions. Consider adding some type constraints until this function is no longer generic. - /// (Originally from ../FSComp.txt:1085) + /// (Originally from ..\FSComp.txt:1085) static member crefNoInnerGenericsInQuotations() = (1230, GetStringFunc("crefNoInnerGenericsInQuotations",",,,") ) /// The type '%s' is not a valid enumerator type , i.e. does not have a 'MoveNext()' method returning a bool, and a 'Current' property - /// (Originally from ../FSComp.txt:1086) + /// (Originally from ..\FSComp.txt:1086) static member tcEnumTypeCannotBeEnumerated(a0 : System.String) = (1231, GetStringFunc("tcEnumTypeCannotBeEnumerated",",,,%s,,,") a0) /// End of file in triple-quote string begun at or before here - /// (Originally from ../FSComp.txt:1087) + /// (Originally from ..\FSComp.txt:1087) static member parsEofInTripleQuoteString() = (1232, GetStringFunc("parsEofInTripleQuoteString",",,,") ) /// End of file in triple-quote string embedded in comment begun at or before here - /// (Originally from ../FSComp.txt:1088) + /// (Originally from ..\FSComp.txt:1088) static member parsEofInTripleQuoteStringInComment() = (1233, GetStringFunc("parsEofInTripleQuoteStringInComment",",,,") ) /// This type test or downcast will ignore the unit-of-measure '%s' - /// (Originally from ../FSComp.txt:1089) + /// (Originally from ..\FSComp.txt:1089) static member tcTypeTestLosesMeasures(a0 : System.String) = (1240, GetStringFunc("tcTypeTestLosesMeasures",",,,%s,,,") a0) /// Expected type argument or static argument - /// (Originally from ../FSComp.txt:1090) + /// (Originally from ..\FSComp.txt:1090) static member parsMissingTypeArgs() = (1241, GetStringFunc("parsMissingTypeArgs",",,,") ) /// Unmatched '<'. Expected closing '>' - /// (Originally from ../FSComp.txt:1091) + /// (Originally from ..\FSComp.txt:1091) static member parsMissingGreaterThan() = (1242, GetStringFunc("parsMissingGreaterThan",",,,") ) /// Unexpected quotation operator '<@' in type definition. If you intend to pass a verbatim string as a static argument to a type provider, put a space between the '<' and '@' characters. - /// (Originally from ../FSComp.txt:1092) + /// (Originally from ..\FSComp.txt:1092) static member parsUnexpectedQuotationOperatorInTypeAliasDidYouMeanVerbatimString() = (1243, GetStringFunc("parsUnexpectedQuotationOperatorInTypeAliasDidYouMeanVerbatimString",",,,") ) /// Attempted to parse this as an operator name, but failed - /// (Originally from ../FSComp.txt:1093) + /// (Originally from ..\FSComp.txt:1093) static member parsErrorParsingAsOperatorName() = (1244, GetStringFunc("parsErrorParsingAsOperatorName",",,,") ) /// \U%s is not a valid Unicode character escape sequence - /// (Originally from ../FSComp.txt:1094) + /// (Originally from ..\FSComp.txt:1094) static member lexInvalidUnicodeLiteral(a0 : System.String) = (1245, GetStringFunc("lexInvalidUnicodeLiteral",",,,%s,,,") a0) /// '%s' must be applied to an argument of type '%s', but has been applied to an argument of type '%s' - /// (Originally from ../FSComp.txt:1095) + /// (Originally from ..\FSComp.txt:1095) static member tcCallerInfoWrongType(a0 : System.String, a1 : System.String, a2 : System.String) = (1246, GetStringFunc("tcCallerInfoWrongType",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// '%s' can only be applied to optional arguments - /// (Originally from ../FSComp.txt:1096) + /// (Originally from ..\FSComp.txt:1096) static member tcCallerInfoNotOptional(a0 : System.String) = (1247, GetStringFunc("tcCallerInfoNotOptional",",,,%s,,,") a0) /// The specified .NET Framework version '%s' is not supported. Please specify a value from the enumeration Microsoft.Build.Utilities.TargetDotNetFrameworkVersion. - /// (Originally from ../FSComp.txt:1098) + /// (Originally from ..\FSComp.txt:1098) static member toolLocationHelperUnsupportedFrameworkVersion(a0 : System.String) = (1300, GetStringFunc("toolLocationHelperUnsupportedFrameworkVersion",",,,%s,,,") a0) /// Invalid Magic value in CLR Header - /// (Originally from ../FSComp.txt:1102) + /// (Originally from ..\FSComp.txt:1102) static member ilSignInvalidMagicValue() = (1301, GetStringFunc("ilSignInvalidMagicValue",",,,") ) /// Bad image format - /// (Originally from ../FSComp.txt:1103) + /// (Originally from ..\FSComp.txt:1103) static member ilSignBadImageFormat() = (1302, GetStringFunc("ilSignBadImageFormat",",,,") ) /// Private key expected - /// (Originally from ../FSComp.txt:1104) + /// (Originally from ..\FSComp.txt:1104) static member ilSignPrivateKeyExpected() = (1303, GetStringFunc("ilSignPrivateKeyExpected",",,,") ) /// RSA key expected - /// (Originally from ../FSComp.txt:1105) + /// (Originally from ..\FSComp.txt:1105) static member ilSignRsaKeyExpected() = (1304, GetStringFunc("ilSignRsaKeyExpected",",,,") ) /// Invalid bit Length - /// (Originally from ../FSComp.txt:1106) + /// (Originally from ..\FSComp.txt:1106) static member ilSignInvalidBitLen() = (1305, GetStringFunc("ilSignInvalidBitLen",",,,") ) /// Invalid RSAParameters structure - '{0}' expected - /// (Originally from ../FSComp.txt:1107) + /// (Originally from ..\FSComp.txt:1107) static member ilSignInvalidRSAParams() = (1306, GetStringFunc("ilSignInvalidRSAParams",",,,") ) /// Invalid algId - 'Exponent' expected - /// (Originally from ../FSComp.txt:1108) + /// (Originally from ..\FSComp.txt:1108) static member ilSignInvalidAlgId() = (1307, GetStringFunc("ilSignInvalidAlgId",",,,") ) /// Invalid signature size - /// (Originally from ../FSComp.txt:1109) + /// (Originally from ..\FSComp.txt:1109) static member ilSignInvalidSignatureSize() = (1308, GetStringFunc("ilSignInvalidSignatureSize",",,,") ) /// No signature directory - /// (Originally from ../FSComp.txt:1110) + /// (Originally from ..\FSComp.txt:1110) static member ilSignNoSignatureDirectory() = (1309, GetStringFunc("ilSignNoSignatureDirectory",",,,") ) /// Invalid Public Key blob - /// (Originally from ../FSComp.txt:1111) + /// (Originally from ..\FSComp.txt:1111) static member ilSignInvalidPKBlob() = (1310, GetStringFunc("ilSignInvalidPKBlob",",,,") ) /// Exiting - too many errors - /// (Originally from ../FSComp.txt:1113) + /// (Originally from ..\FSComp.txt:1113) static member fscTooManyErrors() = (GetStringFunc("fscTooManyErrors",",,,") ) /// The documentation file has no .xml suffix - /// (Originally from ../FSComp.txt:1114) + /// (Originally from ..\FSComp.txt:1114) static member docfileNoXmlSuffix() = (2001, GetStringFunc("docfileNoXmlSuffix",",,,") ) /// No implementation files specified - /// (Originally from ../FSComp.txt:1115) + /// (Originally from ..\FSComp.txt:1115) static member fscNoImplementationFiles() = (2002, GetStringFunc("fscNoImplementationFiles",",,,") ) /// The attribute %s specified version '%s', but this value is invalid and has been ignored /// (Originally from ..\FSComp.txt:1116) static member fscBadAssemblyVersion(a0 : System.String, a1 : System.String) = (2003, GetStringFunc("fscBadAssemblyVersion",",,,%s,,,%s,,,") a0 a1) /// Conflicting options specified: 'win32manifest' and 'win32res'. Only one of these can be used. - /// (Originally from ../FSComp.txt:1117) + /// (Originally from ..\FSComp.txt:1117) static member fscTwoResourceManifests() = (2004, GetStringFunc("fscTwoResourceManifests",",,,") ) /// The code in assembly '%s' makes uses of quotation literals. Static linking may not include components that make use of quotation literals unless all assemblies are compiled with at least F# 4.0. - /// (Originally from ../FSComp.txt:1118) + /// (Originally from ..\FSComp.txt:1118) static member fscQuotationLiteralsStaticLinking(a0 : System.String) = (2005, GetStringFunc("fscQuotationLiteralsStaticLinking",",,,%s,,,") a0) /// Code in this assembly makes uses of quotation literals. Static linking may not include components that make use of quotation literals unless all assemblies are compiled with at least F# 4.0. - /// (Originally from ../FSComp.txt:1119) + /// (Originally from ..\FSComp.txt:1119) static member fscQuotationLiteralsStaticLinking0() = (2006, GetStringFunc("fscQuotationLiteralsStaticLinking0",",,,") ) /// Static linking may not include a .EXE - /// (Originally from ../FSComp.txt:1120) + /// (Originally from ..\FSComp.txt:1120) static member fscStaticLinkingNoEXE() = (2007, GetStringFunc("fscStaticLinkingNoEXE",",,,") ) /// Static linking may not include a mixed managed/unmanaged DLL - /// (Originally from ../FSComp.txt:1121) + /// (Originally from ..\FSComp.txt:1121) static member fscStaticLinkingNoMixedDLL() = (2008, GetStringFunc("fscStaticLinkingNoMixedDLL",",,,") ) /// Ignoring mixed managed/unmanaged assembly '%s' during static linking - /// (Originally from ../FSComp.txt:1122) + /// (Originally from ..\FSComp.txt:1122) static member fscIgnoringMixedWhenLinking(a0 : System.String) = (2009, GetStringFunc("fscIgnoringMixedWhenLinking",",,,%s,,,") a0) /// Assembly '%s' was referenced transitively and the assembly could not be resolved automatically. Static linking will assume this DLL has no dependencies on the F# library or other statically linked DLLs. Consider adding an explicit reference to this DLL. - /// (Originally from ../FSComp.txt:1123) + /// (Originally from ..\FSComp.txt:1123) static member fscAssumeStaticLinkContainsNoDependencies(a0 : System.String) = (2011, GetStringFunc("fscAssumeStaticLinkContainsNoDependencies",",,,%s,,,") a0) /// Assembly '%s' not found in dependency set of target binary. Statically linked roots should be specified using an assembly name, without a DLL or EXE extension. If this assembly was referenced explicitly then it is possible the assembly was not actually required by the generated binary, in which case it should not be statically linked. - /// (Originally from ../FSComp.txt:1124) + /// (Originally from ..\FSComp.txt:1124) static member fscAssemblyNotFoundInDependencySet(a0 : System.String) = (2012, GetStringFunc("fscAssemblyNotFoundInDependencySet",",,,%s,,,") a0) /// The key file '%s' could not be opened - /// (Originally from ../FSComp.txt:1125) + /// (Originally from ..\FSComp.txt:1125) static member fscKeyFileCouldNotBeOpened(a0 : System.String) = (2013, GetStringFunc("fscKeyFileCouldNotBeOpened",",,,%s,,,") a0) /// A problem occurred writing the binary '%s': %s - /// (Originally from ../FSComp.txt:1126) + /// (Originally from ..\FSComp.txt:1126) static member fscProblemWritingBinary(a0 : System.String, a1 : System.String) = (2014, GetStringFunc("fscProblemWritingBinary",",,,%s,,,%s,,,") a0 a1) /// The 'AssemblyVersionAttribute' has been ignored because a version was given using a command line option - /// (Originally from ../FSComp.txt:1127) + /// (Originally from ..\FSComp.txt:1127) static member fscAssemblyVersionAttributeIgnored() = (2015, GetStringFunc("fscAssemblyVersionAttributeIgnored",",,,") ) /// Error emitting 'System.Reflection.AssemblyCultureAttribute' attribute -- 'Executables cannot be satellite assemblies, Culture should always be empty' - /// (Originally from ../FSComp.txt:1128) + /// (Originally from ..\FSComp.txt:1128) static member fscAssemblyCultureAttributeError() = (2016, GetStringFunc("fscAssemblyCultureAttributeError",",,,") ) /// Option '--delaysign' overrides attribute 'System.Reflection.AssemblyDelaySignAttribute' given in a source file or added module - /// (Originally from ../FSComp.txt:1129) + /// (Originally from ..\FSComp.txt:1129) static member fscDelaySignWarning() = (2017, GetStringFunc("fscDelaySignWarning",",,,") ) /// Option '--keyfile' overrides attribute 'System.Reflection.AssemblyKeyFileAttribute' given in a source file or added module - /// (Originally from ../FSComp.txt:1130) + /// (Originally from ..\FSComp.txt:1130) static member fscKeyFileWarning() = (2018, GetStringFunc("fscKeyFileWarning",",,,") ) /// Option '--keycontainer' overrides attribute 'System.Reflection.AssemblyNameAttribute' given in a source file or added module - /// (Originally from ../FSComp.txt:1131) + /// (Originally from ..\FSComp.txt:1131) static member fscKeyNameWarning() = (2019, GetStringFunc("fscKeyNameWarning",",,,") ) /// The assembly '%s' is listed on the command line. Assemblies should be referenced using a command line flag such as '-r'. - /// (Originally from ../FSComp.txt:1132) + /// (Originally from ..\FSComp.txt:1132) static member fscReferenceOnCommandLine(a0 : System.String) = (2020, GetStringFunc("fscReferenceOnCommandLine",",,,%s,,,") a0) /// The resident compilation service was not used because a problem occured in communicating with the server. - /// (Originally from ../FSComp.txt:1133) + /// (Originally from ..\FSComp.txt:1133) static member fscRemotingError() = (2021, GetStringFunc("fscRemotingError",",,,") ) /// Problem with filename '%s': Illegal characters in path. - /// (Originally from ../FSComp.txt:1134) + /// (Originally from ..\FSComp.txt:1134) static member pathIsInvalid(a0 : System.String) = (2022, GetStringFunc("pathIsInvalid",",,,%s,,,") a0) /// Passing a .resx file (%s) as a source file to the compiler is deprecated. Use resgen.exe to transform the .resx file into a .resources file to pass as a --resource option. If you are using MSBuild, this can be done via an item in the .fsproj project file. - /// (Originally from ../FSComp.txt:1135) + /// (Originally from ..\FSComp.txt:1135) static member fscResxSourceFileDeprecated(a0 : System.String) = (2023, GetStringFunc("fscResxSourceFileDeprecated",",,,%s,,,") a0) /// Static linking may not be used on an assembly referencing mscorlib (e.g. a .NET Framework assembly) when generating an assembly that references System.Runtime (e.g. a .NET Core or Portable assembly). - /// (Originally from ../FSComp.txt:1136) + /// (Originally from ..\FSComp.txt:1136) static member fscStaticLinkingNoProfileMismatches() = (2024, GetStringFunc("fscStaticLinkingNoProfileMismatches",",,,") ) /// An %s specified version '%s', but this value is a wildcard, and you have requested a deterministic build, these are in conflict. - /// (Originally from ../FSComp.txt:1137) + /// (Originally from ..\FSComp.txt:1137) static member fscAssemblyWildcardAndDeterminism(a0 : System.String, a1 : System.String) = (2025, GetStringFunc("fscAssemblyWildcardAndDeterminism",",,,%s,,,%s,,,") a0 a1) /// Determinstic builds only support portable PDBs (--debug:portable or --debug:embedded) - /// (Originally from ../FSComp.txt:1138) + /// (Originally from ..\FSComp.txt:1138) static member fscDeterministicDebugRequiresPortablePdb() = (2026, GetStringFunc("fscDeterministicDebugRequiresPortablePdb",",,,") ) /// Character '%s' is not allowed in provided namespace name '%s' - /// (Originally from ../FSComp.txt:1139) + /// (Originally from ..\FSComp.txt:1139) static member etIllegalCharactersInNamespaceName(a0 : System.String, a1 : System.String) = (3000, GetStringFunc("etIllegalCharactersInNamespaceName",",,,%s,,,%s,,,") a0 a1) /// The provided type '%s' returned a member with a null or empty member name - /// (Originally from ../FSComp.txt:1140) + /// (Originally from ..\FSComp.txt:1140) static member etNullOrEmptyMemberName(a0 : System.String) = (3001, GetStringFunc("etNullOrEmptyMemberName",",,,%s,,,") a0) /// The provided type '%s' returned a null member - /// (Originally from ../FSComp.txt:1141) + /// (Originally from ..\FSComp.txt:1141) static member etNullMember(a0 : System.String) = (3002, GetStringFunc("etNullMember",",,,%s,,,") a0) /// The provided type '%s' member info '%s' has null declaring type - /// (Originally from ../FSComp.txt:1142) + /// (Originally from ..\FSComp.txt:1142) static member etNullMemberDeclaringType(a0 : System.String, a1 : System.String) = (3003, GetStringFunc("etNullMemberDeclaringType",",,,%s,,,%s,,,") a0 a1) /// The provided type '%s' has member '%s' which has declaring type '%s'. Expected declaring type to be the same as provided type. - /// (Originally from ../FSComp.txt:1143) + /// (Originally from ..\FSComp.txt:1143) static member etNullMemberDeclaringTypeDifferentFromProvidedType(a0 : System.String, a1 : System.String, a2 : System.String) = (3004, GetStringFunc("etNullMemberDeclaringTypeDifferentFromProvidedType",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Referenced assembly '%s' has assembly level attribute '%s' but no public type provider classes were found - /// (Originally from ../FSComp.txt:1144) + /// (Originally from ..\FSComp.txt:1144) static member etHostingAssemblyFoundWithoutHosts(a0 : System.String, a1 : System.String) = (3005, GetStringFunc("etHostingAssemblyFoundWithoutHosts",",,,%s,,,%s,,,") a0 a1) /// Type '%s' from type provider '%s' has an empty namespace. Use 'null' for the global namespace. - /// (Originally from ../FSComp.txt:1145) + /// (Originally from ..\FSComp.txt:1145) static member etEmptyNamespaceOfTypeNotAllowed(a0 : System.String, a1 : System.String) = (3006, GetStringFunc("etEmptyNamespaceOfTypeNotAllowed",",,,%s,,,%s,,,") a0 a1) /// Empty namespace found from the type provider '%s'. Use 'null' for the global namespace. - /// (Originally from ../FSComp.txt:1146) + /// (Originally from ..\FSComp.txt:1146) static member etEmptyNamespaceNotAllowed(a0 : System.String) = (3007, GetStringFunc("etEmptyNamespaceNotAllowed",",,,%s,,,") a0) /// Provided type '%s' has 'IsGenericType' as true, but generic types are not supported. - /// (Originally from ../FSComp.txt:1147) + /// (Originally from ..\FSComp.txt:1147) static member etMustNotBeGeneric(a0 : System.String) = (3011, GetStringFunc("etMustNotBeGeneric",",,,%s,,,") a0) /// Provided type '%s' has 'IsArray' as true, but array types are not supported. - /// (Originally from ../FSComp.txt:1148) + /// (Originally from ..\FSComp.txt:1148) static member etMustNotBeAnArray(a0 : System.String) = (3013, GetStringFunc("etMustNotBeAnArray",",,,%s,,,") a0) /// Invalid member '%s' on provided type '%s'. Provided type members must be public, and not be generic, virtual, or abstract. - /// (Originally from ../FSComp.txt:1149) + /// (Originally from ..\FSComp.txt:1149) static member etMethodHasRequirements(a0 : System.String, a1 : System.String) = (3014, GetStringFunc("etMethodHasRequirements",",,,%s,,,%s,,,") a0 a1) /// Invalid member '%s' on provided type '%s'. Only properties, methods and constructors are allowed - /// (Originally from ../FSComp.txt:1150) + /// (Originally from ..\FSComp.txt:1150) static member etUnsupportedMemberKind(a0 : System.String, a1 : System.String) = (3015, GetStringFunc("etUnsupportedMemberKind",",,,%s,,,%s,,,") a0 a1) /// Property '%s' on provided type '%s' has CanRead=true but there was no value from GetGetMethod() - /// (Originally from ../FSComp.txt:1151) + /// (Originally from ..\FSComp.txt:1151) static member etPropertyCanReadButHasNoGetter(a0 : System.String, a1 : System.String) = (3016, GetStringFunc("etPropertyCanReadButHasNoGetter",",,,%s,,,%s,,,") a0 a1) /// Property '%s' on provided type '%s' has CanRead=false but GetGetMethod() returned a method - /// (Originally from ../FSComp.txt:1152) + /// (Originally from ..\FSComp.txt:1152) static member etPropertyHasGetterButNoCanRead(a0 : System.String, a1 : System.String) = (3017, GetStringFunc("etPropertyHasGetterButNoCanRead",",,,%s,,,%s,,,") a0 a1) /// Property '%s' on provided type '%s' has CanWrite=true but there was no value from GetSetMethod() - /// (Originally from ../FSComp.txt:1153) + /// (Originally from ..\FSComp.txt:1153) static member etPropertyCanWriteButHasNoSetter(a0 : System.String, a1 : System.String) = (3018, GetStringFunc("etPropertyCanWriteButHasNoSetter",",,,%s,,,%s,,,") a0 a1) /// Property '%s' on provided type '%s' has CanWrite=false but GetSetMethod() returned a method - /// (Originally from ../FSComp.txt:1154) + /// (Originally from ..\FSComp.txt:1154) static member etPropertyHasSetterButNoCanWrite(a0 : System.String, a1 : System.String) = (3019, GetStringFunc("etPropertyHasSetterButNoCanWrite",",,,%s,,,%s,,,") a0 a1) /// One or more errors seen during provided type setup - /// (Originally from ../FSComp.txt:1155) + /// (Originally from ..\FSComp.txt:1155) static member etOneOrMoreErrorsSeenDuringExtensionTypeSetting() = (3020, GetStringFunc("etOneOrMoreErrorsSeenDuringExtensionTypeSetting",",,,") ) /// Unexpected exception from provided type '%s' member '%s': %s - /// (Originally from ../FSComp.txt:1156) + /// (Originally from ..\FSComp.txt:1156) static member etUnexpectedExceptionFromProvidedTypeMember(a0 : System.String, a1 : System.String, a2 : System.String) = (3021, GetStringFunc("etUnexpectedExceptionFromProvidedTypeMember",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Unsupported constant type '%s'. Quotations provided by type providers can only contain simple constants. The implementation of the type provider may need to be adjusted by moving a value declared outside a provided quotation literal to be a 'let' binding inside the quotation literal. - /// (Originally from ../FSComp.txt:1157) + /// (Originally from ..\FSComp.txt:1157) static member etUnsupportedConstantType(a0 : System.String) = (3022, GetStringFunc("etUnsupportedConstantType",",,,%s,,,") a0) /// Unsupported expression '%s' from type provider. If you are the author of this type provider, consider adjusting it to provide a different provided expression. - /// (Originally from ../FSComp.txt:1158) + /// (Originally from ..\FSComp.txt:1158) static member etUnsupportedProvidedExpression(a0 : System.String) = (3025, GetStringFunc("etUnsupportedProvidedExpression",",,,%s,,,") a0) /// Expected provided type named '%s' but provided type has 'Name' with value '%s' - /// (Originally from ../FSComp.txt:1159) + /// (Originally from ..\FSComp.txt:1159) static member etProvidedTypeHasUnexpectedName(a0 : System.String, a1 : System.String) = (3028, GetStringFunc("etProvidedTypeHasUnexpectedName",",,,%s,,,%s,,,") a0 a1) /// Event '%s' on provided type '%s' has no value from GetAddMethod() - /// (Originally from ../FSComp.txt:1160) + /// (Originally from ..\FSComp.txt:1160) static member etEventNoAdd(a0 : System.String, a1 : System.String) = (3029, GetStringFunc("etEventNoAdd",",,,%s,,,%s,,,") a0 a1) /// Event '%s' on provided type '%s' has no value from GetRemoveMethod() - /// (Originally from ../FSComp.txt:1161) + /// (Originally from ..\FSComp.txt:1161) static member etEventNoRemove(a0 : System.String, a1 : System.String) = (3030, GetStringFunc("etEventNoRemove",",,,%s,,,%s,,,") a0 a1) /// Assembly attribute '%s' refers to a designer assembly '%s' which cannot be loaded or doesn't exist. %s - /// (Originally from ../FSComp.txt:1162) + /// (Originally from ..\FSComp.txt:1162) static member etProviderHasWrongDesignerAssembly(a0 : System.String, a1 : System.String, a2 : System.String) = (3031, GetStringFunc("etProviderHasWrongDesignerAssembly",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The type provider does not have a valid constructor. A constructor taking either no arguments or one argument of type 'TypeProviderConfig' was expected. - /// (Originally from ../FSComp.txt:1163) + /// (Originally from ..\FSComp.txt:1163) static member etProviderDoesNotHaveValidConstructor() = (3032, GetStringFunc("etProviderDoesNotHaveValidConstructor",",,,") ) /// The type provider '%s' reported an error: %s - /// (Originally from ../FSComp.txt:1164) + /// (Originally from ..\FSComp.txt:1164) static member etProviderError(a0 : System.String, a1 : System.String) = (3033, GetStringFunc("etProviderError",",,,%s,,,%s,,,") a0 a1) /// The type provider '%s' used an invalid parameter in the ParameterExpression: %s - /// (Originally from ../FSComp.txt:1165) + /// (Originally from ..\FSComp.txt:1165) static member etIncorrectParameterExpression(a0 : System.String, a1 : System.String) = (3034, GetStringFunc("etIncorrectParameterExpression",",,,%s,,,%s,,,") a0 a1) /// The type provider '%s' provided a method with a name '%s' and metadata token '%d', which is not reported among its methods of its declaring type '%s' - /// (Originally from ../FSComp.txt:1166) + /// (Originally from ..\FSComp.txt:1166) static member etIncorrectProvidedMethod(a0 : System.String, a1 : System.String, a2 : System.Int32, a3 : System.String) = (3035, GetStringFunc("etIncorrectProvidedMethod",",,,%s,,,%s,,,%d,,,%s,,,") a0 a1 a2 a3) /// The type provider '%s' provided a constructor which is not reported among the constructors of its declaring type '%s' - /// (Originally from ../FSComp.txt:1167) + /// (Originally from ..\FSComp.txt:1167) static member etIncorrectProvidedConstructor(a0 : System.String, a1 : System.String) = (3036, GetStringFunc("etIncorrectProvidedConstructor",",,,%s,,,%s,,,") a0 a1) /// A direct reference to the generated type '%s' is not permitted. Instead, use a type definition, e.g. 'type TypeAlias = '. This indicates that a type provider adds generated types to your assembly. - /// (Originally from ../FSComp.txt:1168) + /// (Originally from ..\FSComp.txt:1168) static member etDirectReferenceToGeneratedTypeNotAllowed(a0 : System.String) = (3039, GetStringFunc("etDirectReferenceToGeneratedTypeNotAllowed",",,,%s,,,") a0) /// Expected provided type with path '%s' but provided type has path '%s' - /// (Originally from ../FSComp.txt:1169) + /// (Originally from ..\FSComp.txt:1169) static member etProvidedTypeHasUnexpectedPath(a0 : System.String, a1 : System.String) = (3041, GetStringFunc("etProvidedTypeHasUnexpectedPath",",,,%s,,,%s,,,") a0 a1) /// Unexpected 'null' return value from provided type '%s' member '%s' - /// (Originally from ../FSComp.txt:1170) + /// (Originally from ..\FSComp.txt:1170) static member etUnexpectedNullFromProvidedTypeMember(a0 : System.String, a1 : System.String) = (3042, GetStringFunc("etUnexpectedNullFromProvidedTypeMember",",,,%s,,,%s,,,") a0 a1) /// Unexpected exception from member '%s' of provided type '%s' member '%s': %s - /// (Originally from ../FSComp.txt:1171) + /// (Originally from ..\FSComp.txt:1171) static member etUnexpectedExceptionFromProvidedMemberMember(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String) = (3043, GetStringFunc("etUnexpectedExceptionFromProvidedMemberMember",",,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3) /// Nested provided types do not take static arguments or generic parameters - /// (Originally from ../FSComp.txt:1172) + /// (Originally from ..\FSComp.txt:1172) static member etNestedProvidedTypesDoNotTakeStaticArgumentsOrGenericParameters() = (3044, GetStringFunc("etNestedProvidedTypesDoNotTakeStaticArgumentsOrGenericParameters",",,,") ) /// Invalid static argument to provided type. Expected an argument of kind '%s'. - /// (Originally from ../FSComp.txt:1173) + /// (Originally from ..\FSComp.txt:1173) static member etInvalidStaticArgument(a0 : System.String) = (3045, GetStringFunc("etInvalidStaticArgument",",,,%s,,,") a0) /// An error occured applying the static arguments to a provided type - /// (Originally from ../FSComp.txt:1174) + /// (Originally from ..\FSComp.txt:1174) static member etErrorApplyingStaticArgumentsToType() = (3046, GetStringFunc("etErrorApplyingStaticArgumentsToType",",,,") ) /// Unknown static argument kind '%s' when resolving a reference to a provided type or method '%s' - /// (Originally from ../FSComp.txt:1175) + /// (Originally from ..\FSComp.txt:1175) static member etUnknownStaticArgumentKind(a0 : System.String, a1 : System.String) = (3047, GetStringFunc("etUnknownStaticArgumentKind",",,,%s,,,%s,,,") a0 a1) /// invalid namespace for provided type - /// (Originally from ../FSComp.txt:1176) + /// (Originally from ..\FSComp.txt:1176) static member invalidNamespaceForProvidedType() = (GetStringFunc("invalidNamespaceForProvidedType",",,,") ) /// invalid full name for provided type - /// (Originally from ../FSComp.txt:1177) + /// (Originally from ..\FSComp.txt:1177) static member invalidFullNameForProvidedType() = (GetStringFunc("invalidFullNameForProvidedType",",,,") ) /// The type provider returned 'null', which is not a valid return value from '%s' - /// (Originally from ../FSComp.txt:1179) + /// (Originally from ..\FSComp.txt:1179) static member etProviderReturnedNull(a0 : System.String) = (3051, GetStringFunc("etProviderReturnedNull",",,,%s,,,") a0) /// The type provider constructor has thrown an exception: %s - /// (Originally from ../FSComp.txt:1180) + /// (Originally from ..\FSComp.txt:1180) static member etTypeProviderConstructorException(a0 : System.String) = (3053, GetStringFunc("etTypeProviderConstructorException",",,,%s,,,") a0) /// Type provider '%s' returned null from GetInvokerExpression. - /// (Originally from ../FSComp.txt:1181) + /// (Originally from ..\FSComp.txt:1181) static member etNullProvidedExpression(a0 : System.String) = (3056, GetStringFunc("etNullProvidedExpression",",,,%s,,,") a0) /// The type provider '%s' returned an invalid type from 'ApplyStaticArguments'. A type with name '%s' was expected, but a type with name '%s' was returned. - /// (Originally from ../FSComp.txt:1182) + /// (Originally from ..\FSComp.txt:1182) static member etProvidedAppliedTypeHadWrongName(a0 : System.String, a1 : System.String, a2 : System.String) = (3057, GetStringFunc("etProvidedAppliedTypeHadWrongName",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// The type provider '%s' returned an invalid method from 'ApplyStaticArgumentsForMethod'. A method with name '%s' was expected, but a method with name '%s' was returned. - /// (Originally from ../FSComp.txt:1183) + /// (Originally from ..\FSComp.txt:1183) static member etProvidedAppliedMethodHadWrongName(a0 : System.String, a1 : System.String, a2 : System.String) = (3058, GetStringFunc("etProvidedAppliedMethodHadWrongName",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// This type test or downcast will erase the provided type '%s' to the type '%s' - /// (Originally from ../FSComp.txt:1184) + /// (Originally from ..\FSComp.txt:1184) static member tcTypeTestLossy(a0 : System.String, a1 : System.String) = (3060, GetStringFunc("tcTypeTestLossy",",,,%s,,,%s,,,") a0 a1) /// This downcast will erase the provided type '%s' to the type '%s'. - /// (Originally from ../FSComp.txt:1185) + /// (Originally from ..\FSComp.txt:1185) static member tcTypeCastErased(a0 : System.String, a1 : System.String) = (3061, GetStringFunc("tcTypeCastErased",",,,%s,,,%s,,,") a0 a1) /// This type test with a provided type '%s' is not allowed because this provided type will be erased to '%s' at runtime. - /// (Originally from ../FSComp.txt:1186) + /// (Originally from ..\FSComp.txt:1186) static member tcTypeTestErased(a0 : System.String, a1 : System.String) = (3062, GetStringFunc("tcTypeTestErased",",,,%s,,,%s,,,") a0 a1) /// Cannot inherit from erased provided type - /// (Originally from ../FSComp.txt:1187) + /// (Originally from ..\FSComp.txt:1187) static member tcCannotInheritFromErasedType() = (3063, GetStringFunc("tcCannotInheritFromErasedType",",,,") ) /// Assembly '%s' hase TypeProviderAssembly attribute with invalid value '%s'. The value should be a valid assembly name - /// (Originally from ../FSComp.txt:1188) + /// (Originally from ..\FSComp.txt:1188) static member etInvalidTypeProviderAssemblyName(a0 : System.String, a1 : System.String) = (3065, GetStringFunc("etInvalidTypeProviderAssemblyName",",,,%s,,,%s,,,") a0 a1) /// Invalid member name. Members may not have name '.ctor' or '.cctor' - /// (Originally from ../FSComp.txt:1189) + /// (Originally from ..\FSComp.txt:1189) static member tcInvalidMemberNameCtor() = (3066, GetStringFunc("tcInvalidMemberNameCtor",",,,") ) /// The function or member '%s' is used in a way that requires further type annotations at its definition to ensure consistency of inferred types. The inferred signature is '%s'. - /// (Originally from ../FSComp.txt:1190) + /// (Originally from ..\FSComp.txt:1190) static member tcInferredGenericTypeGivesRiseToInconsistency(a0 : System.String, a1 : System.String) = (3068, GetStringFunc("tcInferredGenericTypeGivesRiseToInconsistency",",,,%s,,,%s,,,") a0 a1) /// The number of type arguments did not match: '%d' given, '%d' expected. This may be related to a previously reported error. - /// (Originally from ../FSComp.txt:1191) + /// (Originally from ..\FSComp.txt:1191) static member tcInvalidTypeArgumentCount(a0 : System.Int32, a1 : System.Int32) = (3069, GetStringFunc("tcInvalidTypeArgumentCount",",,,%d,,,%d,,,") a0 a1) /// Cannot override inherited member '%s' because it is sealed - /// (Originally from ../FSComp.txt:1192) + /// (Originally from ..\FSComp.txt:1192) static member tcCannotOverrideSealedMethod(a0 : System.String) = (3070, GetStringFunc("tcCannotOverrideSealedMethod",",,,%s,,,") a0) /// The type provider '%s' reported an error in the context of provided type '%s', member '%s'. The error: %s - /// (Originally from ../FSComp.txt:1193) + /// (Originally from ..\FSComp.txt:1193) static member etProviderErrorWithContext(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String) = (3071, GetStringFunc("etProviderErrorWithContext",",,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3) /// An exception occurred when accessing the '%s' of a provided type: %s - /// (Originally from ../FSComp.txt:1194) + /// (Originally from ..\FSComp.txt:1194) static member etProvidedTypeWithNameException(a0 : System.String, a1 : System.String) = (3072, GetStringFunc("etProvidedTypeWithNameException",",,,%s,,,%s,,,") a0 a1) /// The '%s' of a provided type was null or empty. - /// (Originally from ../FSComp.txt:1195) + /// (Originally from ..\FSComp.txt:1195) static member etProvidedTypeWithNullOrEmptyName(a0 : System.String) = (3073, GetStringFunc("etProvidedTypeWithNullOrEmptyName",",,,%s,,,") a0) /// Character '%s' is not allowed in provided type name '%s' - /// (Originally from ../FSComp.txt:1196) + /// (Originally from ..\FSComp.txt:1196) static member etIllegalCharactersInTypeName(a0 : System.String, a1 : System.String) = (3075, GetStringFunc("etIllegalCharactersInTypeName",",,,%s,,,%s,,,") a0 a1) /// In queries, '%s' must use a simple pattern - /// (Originally from ../FSComp.txt:1197) + /// (Originally from ..\FSComp.txt:1197) static member tcJoinMustUseSimplePattern(a0 : System.String) = (3077, GetStringFunc("tcJoinMustUseSimplePattern",",,,%s,,,") a0) /// A custom query operation for '%s' is required but not specified - /// (Originally from ../FSComp.txt:1198) + /// (Originally from ..\FSComp.txt:1198) static member tcMissingCustomOperation(a0 : System.String) = (3078, GetStringFunc("tcMissingCustomOperation",",,,%s,,,") a0) /// Named static arguments must come after all unnamed static arguments - /// (Originally from ../FSComp.txt:1199) + /// (Originally from ..\FSComp.txt:1199) static member etBadUnnamedStaticArgs() = (3080, GetStringFunc("etBadUnnamedStaticArgs",",,,") ) /// The static parameter '%s' of the provided type or method '%s' requires a value. Static parameters to type providers may be optionally specified using named arguments, e.g. '%s<%s=...>'. - /// (Originally from ../FSComp.txt:1200) + /// (Originally from ..\FSComp.txt:1200) static member etStaticParameterRequiresAValue(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String) = (3081, GetStringFunc("etStaticParameterRequiresAValue",",,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3) /// No static parameter exists with name '%s' - /// (Originally from ../FSComp.txt:1201) + /// (Originally from ..\FSComp.txt:1201) static member etNoStaticParameterWithName(a0 : System.String) = (3082, GetStringFunc("etNoStaticParameterWithName",",,,%s,,,") a0) /// The static parameter '%s' has already been given a value - /// (Originally from ../FSComp.txt:1202) + /// (Originally from ..\FSComp.txt:1202) static member etStaticParameterAlreadyHasValue(a0 : System.String) = (3083, GetStringFunc("etStaticParameterAlreadyHasValue",",,,%s,,,") a0) /// Multiple static parameters exist with name '%s' - /// (Originally from ../FSComp.txt:1203) + /// (Originally from ..\FSComp.txt:1203) static member etMultipleStaticParameterWithName(a0 : System.String) = (3084, GetStringFunc("etMultipleStaticParameterWithName",",,,%s,,,") a0) /// A custom operation may not be used in conjunction with a non-value or recursive 'let' binding in another part of this computation expression - /// (Originally from ../FSComp.txt:1204) + /// (Originally from ..\FSComp.txt:1204) static member tcCustomOperationMayNotBeUsedInConjunctionWithNonSimpleLetBindings() = (3085, GetStringFunc("tcCustomOperationMayNotBeUsedInConjunctionWithNonSimpleLetBindings",",,,") ) /// A custom operation may not be used in conjunction with 'use', 'try/with', 'try/finally', 'if/then/else' or 'match' operators within this computation expression - /// (Originally from ../FSComp.txt:1205) + /// (Originally from ..\FSComp.txt:1205) static member tcCustomOperationMayNotBeUsedHere() = (3086, GetStringFunc("tcCustomOperationMayNotBeUsedHere",",,,") ) /// The custom operation '%s' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. - /// (Originally from ../FSComp.txt:1206) + /// (Originally from ..\FSComp.txt:1206) static member tcCustomOperationMayNotBeOverloaded(a0 : System.String) = (3087, GetStringFunc("tcCustomOperationMayNotBeOverloaded",",,,%s,,,") a0) /// An if/then/else expression may not be used within queries. Consider using either an if/then expression, or use a sequence expression instead. - /// (Originally from ../FSComp.txt:1207) + /// (Originally from ..\FSComp.txt:1207) static member tcIfThenElseMayNotBeUsedWithinQueries() = (3090, GetStringFunc("tcIfThenElseMayNotBeUsedWithinQueries",",,,") ) /// Invalid argument to 'methodhandleof' during codegen - /// (Originally from ../FSComp.txt:1208) + /// (Originally from ..\FSComp.txt:1208) static member ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen() = (3091, GetStringFunc("ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen",",,,") ) /// A reference to a provided type was missing a value for the static parameter '%s'. You may need to recompile one or more referenced assemblies. - /// (Originally from ../FSComp.txt:1209) + /// (Originally from ..\FSComp.txt:1209) static member etProvidedTypeReferenceMissingArgument(a0 : System.String) = (3092, GetStringFunc("etProvidedTypeReferenceMissingArgument",",,,%s,,,") a0) /// A reference to a provided type had an invalid value '%s' for a static parameter. You may need to recompile one or more referenced assemblies. - /// (Originally from ../FSComp.txt:1210) + /// (Originally from ..\FSComp.txt:1210) static member etProvidedTypeReferenceInvalidText(a0 : System.String) = (3093, GetStringFunc("etProvidedTypeReferenceInvalidText",",,,%s,,,") a0) /// '%s' is not used correctly. This is a custom operation in this query or computation expression. - /// (Originally from ../FSComp.txt:1211) + /// (Originally from ..\FSComp.txt:1211) static member tcCustomOperationNotUsedCorrectly(a0 : System.String) = (3095, GetStringFunc("tcCustomOperationNotUsedCorrectly",",,,%s,,,") a0) /// '%s' is not used correctly. Usage: %s. This is a custom operation in this query or computation expression. - /// (Originally from ../FSComp.txt:1212) + /// (Originally from ..\FSComp.txt:1212) static member tcCustomOperationNotUsedCorrectly2(a0 : System.String, a1 : System.String) = (3095, GetStringFunc("tcCustomOperationNotUsedCorrectly2",",,,%s,,,%s,,,") a0 a1) /// %s var in collection %s (outerKey = innerKey). Note that parentheses are required after '%s' - /// (Originally from ../FSComp.txt:1213) + /// (Originally from ..\FSComp.txt:1213) static member customOperationTextLikeJoin(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("customOperationTextLikeJoin",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// %s var in collection %s (outerKey = innerKey) into group. Note that parentheses are required after '%s' - /// (Originally from ../FSComp.txt:1214) + /// (Originally from ..\FSComp.txt:1214) static member customOperationTextLikeGroupJoin(a0 : System.String, a1 : System.String, a2 : System.String) = (GetStringFunc("customOperationTextLikeGroupJoin",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// %s var in collection - /// (Originally from ../FSComp.txt:1215) + /// (Originally from ..\FSComp.txt:1215) static member customOperationTextLikeZip(a0 : System.String) = (GetStringFunc("customOperationTextLikeZip",",,,%s,,,") a0) /// '%s' must be followed by a variable name. Usage: %s. - /// (Originally from ../FSComp.txt:1216) + /// (Originally from ..\FSComp.txt:1216) static member tcBinaryOperatorRequiresVariable(a0 : System.String, a1 : System.String) = (3096, GetStringFunc("tcBinaryOperatorRequiresVariable",",,,%s,,,%s,,,") a0 a1) /// Incorrect syntax for '%s'. Usage: %s. - /// (Originally from ../FSComp.txt:1217) + /// (Originally from ..\FSComp.txt:1217) static member tcOperatorIncorrectSyntax(a0 : System.String, a1 : System.String) = (3097, GetStringFunc("tcOperatorIncorrectSyntax",",,,%s,,,%s,,,") a0 a1) /// '%s' must come after a 'for' selection clause and be followed by the rest of the query. Syntax: ... %s ... - /// (Originally from ../FSComp.txt:1218) + /// (Originally from ..\FSComp.txt:1218) static member tcBinaryOperatorRequiresBody(a0 : System.String, a1 : System.String) = (3098, GetStringFunc("tcBinaryOperatorRequiresBody",",,,%s,,,%s,,,") a0 a1) /// '%s' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected %d argument(s), but given %d. - /// (Originally from ../FSComp.txt:1219) + /// (Originally from ..\FSComp.txt:1219) static member tcCustomOperationHasIncorrectArgCount(a0 : System.String, a1 : System.Int32, a2 : System.Int32) = (3099, GetStringFunc("tcCustomOperationHasIncorrectArgCount",",,,%s,,,%d,,,%d,,,") a0 a1 a2) /// Expected an expression after this point - /// (Originally from ../FSComp.txt:1220) + /// (Originally from ..\FSComp.txt:1220) static member parsExpectedExpressionAfterToken() = (3100, GetStringFunc("parsExpectedExpressionAfterToken",",,,") ) /// Expected a type after this point - /// (Originally from ../FSComp.txt:1221) + /// (Originally from ..\FSComp.txt:1221) static member parsExpectedTypeAfterToken() = (3101, GetStringFunc("parsExpectedTypeAfterToken",",,,") ) /// Unmatched '[<'. Expected closing '>]' - /// (Originally from ../FSComp.txt:1222) + /// (Originally from ..\FSComp.txt:1222) static member parsUnmatchedLBrackLess() = (3102, GetStringFunc("parsUnmatchedLBrackLess",",,,") ) /// Unexpected end of input in 'match' expression. Expected 'match with | -> | -> ...'. - /// (Originally from ../FSComp.txt:1223) + /// (Originally from ..\FSComp.txt:1223) static member parsUnexpectedEndOfFileMatch() = (3103, GetStringFunc("parsUnexpectedEndOfFileMatch",",,,") ) /// Unexpected end of input in 'try' expression. Expected 'try with ' or 'try finally '. - /// (Originally from ../FSComp.txt:1224) + /// (Originally from ..\FSComp.txt:1224) static member parsUnexpectedEndOfFileTry() = (3104, GetStringFunc("parsUnexpectedEndOfFileTry",",,,") ) /// Unexpected end of input in 'while' expression. Expected 'while do '. - /// (Originally from ../FSComp.txt:1225) + /// (Originally from ..\FSComp.txt:1225) static member parsUnexpectedEndOfFileWhile() = (3105, GetStringFunc("parsUnexpectedEndOfFileWhile",",,,") ) /// Unexpected end of input in 'for' expression. Expected 'for in do '. - /// (Originally from ../FSComp.txt:1226) + /// (Originally from ..\FSComp.txt:1226) static member parsUnexpectedEndOfFileFor() = (3106, GetStringFunc("parsUnexpectedEndOfFileFor",",,,") ) /// Unexpected end of input in 'match' or 'try' expression - /// (Originally from ../FSComp.txt:1227) + /// (Originally from ..\FSComp.txt:1227) static member parsUnexpectedEndOfFileWith() = (3107, GetStringFunc("parsUnexpectedEndOfFileWith",",,,") ) /// Unexpected end of input in 'then' branch of conditional expression. Expected 'if then ' or 'if then else '. - /// (Originally from ../FSComp.txt:1228) + /// (Originally from ..\FSComp.txt:1228) static member parsUnexpectedEndOfFileThen() = (3108, GetStringFunc("parsUnexpectedEndOfFileThen",",,,") ) /// Unexpected end of input in 'else' branch of conditional expression. Expected 'if then ' or 'if then else '. - /// (Originally from ../FSComp.txt:1229) + /// (Originally from ..\FSComp.txt:1229) static member parsUnexpectedEndOfFileElse() = (3109, GetStringFunc("parsUnexpectedEndOfFileElse",",,,") ) /// Unexpected end of input in body of lambda expression. Expected 'fun ... -> '. - /// (Originally from ../FSComp.txt:1230) + /// (Originally from ..\FSComp.txt:1230) static member parsUnexpectedEndOfFileFunBody() = (3110, GetStringFunc("parsUnexpectedEndOfFileFunBody",",,,") ) /// Unexpected end of input in type arguments - /// (Originally from ../FSComp.txt:1231) + /// (Originally from ..\FSComp.txt:1231) static member parsUnexpectedEndOfFileTypeArgs() = (3111, GetStringFunc("parsUnexpectedEndOfFileTypeArgs",",,,") ) /// Unexpected end of input in type signature - /// (Originally from ../FSComp.txt:1232) + /// (Originally from ..\FSComp.txt:1232) static member parsUnexpectedEndOfFileTypeSignature() = (3112, GetStringFunc("parsUnexpectedEndOfFileTypeSignature",",,,") ) /// Unexpected end of input in type definition - /// (Originally from ../FSComp.txt:1233) + /// (Originally from ..\FSComp.txt:1233) static member parsUnexpectedEndOfFileTypeDefinition() = (3113, GetStringFunc("parsUnexpectedEndOfFileTypeDefinition",",,,") ) /// Unexpected end of input in object members - /// (Originally from ../FSComp.txt:1234) + /// (Originally from ..\FSComp.txt:1234) static member parsUnexpectedEndOfFileObjectMembers() = (3114, GetStringFunc("parsUnexpectedEndOfFileObjectMembers",",,,") ) /// Unexpected end of input in value, function or member definition - /// (Originally from ../FSComp.txt:1235) + /// (Originally from ..\FSComp.txt:1235) static member parsUnexpectedEndOfFileDefinition() = (3115, GetStringFunc("parsUnexpectedEndOfFileDefinition",",,,") ) /// Unexpected end of input in expression - /// (Originally from ../FSComp.txt:1236) + /// (Originally from ..\FSComp.txt:1236) static member parsUnexpectedEndOfFileExpression() = (3116, GetStringFunc("parsUnexpectedEndOfFileExpression",",,,") ) /// Unexpected end of type. Expected a name after this point. - /// (Originally from ../FSComp.txt:1237) + /// (Originally from ..\FSComp.txt:1237) static member parsExpectedNameAfterToken() = (3117, GetStringFunc("parsExpectedNameAfterToken",",,,") ) /// Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let' keyword. - /// (Originally from ../FSComp.txt:1238) + /// (Originally from ..\FSComp.txt:1238) static member parsUnmatchedLet() = (3118, GetStringFunc("parsUnmatchedLet",",,,") ) /// Incomplete value definition. If this is in an expression, the body of the expression must be indented to the same column as the 'let!' keyword. - /// (Originally from ../FSComp.txt:1239) + /// (Originally from ..\FSComp.txt:1239) static member parsUnmatchedLetBang() = (3119, GetStringFunc("parsUnmatchedLetBang",",,,") ) /// Incomplete value definition. If this is in an expression, the body of the expression must be indented to the same column as the 'use!' keyword. - /// (Originally from ../FSComp.txt:1240) + /// (Originally from ..\FSComp.txt:1240) static member parsUnmatchedUseBang() = (3120, GetStringFunc("parsUnmatchedUseBang",",,,") ) /// Incomplete value definition. If this is in an expression, the body of the expression must be indented to the same column as the 'use' keyword. - /// (Originally from ../FSComp.txt:1241) + /// (Originally from ..\FSComp.txt:1241) static member parsUnmatchedUse() = (3121, GetStringFunc("parsUnmatchedUse",",,,") ) /// Missing 'do' in 'while' expression. Expected 'while do '. - /// (Originally from ../FSComp.txt:1242) + /// (Originally from ..\FSComp.txt:1242) static member parsWhileDoExpected() = (3122, GetStringFunc("parsWhileDoExpected",",,,") ) /// Missing 'do' in 'for' expression. Expected 'for in do '. - /// (Originally from ../FSComp.txt:1243) + /// (Originally from ..\FSComp.txt:1243) static member parsForDoExpected() = (3123, GetStringFunc("parsForDoExpected",",,,") ) /// Invalid join relation in '%s'. Expected 'expr expr', where is =, =?, ?= or ?=?. - /// (Originally from ../FSComp.txt:1244) + /// (Originally from ..\FSComp.txt:1244) static member tcInvalidRelationInJoin(a0 : System.String) = (3125, GetStringFunc("tcInvalidRelationInJoin",",,,%s,,,") a0) /// Calls - /// (Originally from ../FSComp.txt:1245) + /// (Originally from ..\FSComp.txt:1245) static member typeInfoCallsWord() = (GetStringFunc("typeInfoCallsWord",",,,") ) /// Invalid number of generic arguments to type '%s' in provided type. Expected '%d' arguments, given '%d'. - /// (Originally from ../FSComp.txt:1246) + /// (Originally from ..\FSComp.txt:1246) static member impInvalidNumberOfGenericArguments(a0 : System.String, a1 : System.Int32, a2 : System.Int32) = (3126, GetStringFunc("impInvalidNumberOfGenericArguments",",,,%s,,,%d,,,%d,,,") a0 a1 a2) /// Invalid value '%s' for unit-of-measure parameter '%s' - /// (Originally from ../FSComp.txt:1247) + /// (Originally from ..\FSComp.txt:1247) static member impInvalidMeasureArgument1(a0 : System.String, a1 : System.String) = (3127, GetStringFunc("impInvalidMeasureArgument1",",,,%s,,,%s,,,") a0 a1) /// Invalid value unit-of-measure parameter '%s' - /// (Originally from ../FSComp.txt:1248) + /// (Originally from ..\FSComp.txt:1248) static member impInvalidMeasureArgument2(a0 : System.String) = (3127, GetStringFunc("impInvalidMeasureArgument2",",,,%s,,,") a0) /// Property '%s' on provided type '%s' is neither readable nor writable as it has CanRead=false and CanWrite=false - /// (Originally from ../FSComp.txt:1249) + /// (Originally from ..\FSComp.txt:1249) static member etPropertyNeedsCanWriteOrCanRead(a0 : System.String, a1 : System.String) = (3128, GetStringFunc("etPropertyNeedsCanWriteOrCanRead",",,,%s,,,%s,,,") a0 a1) /// A use of 'into' must be followed by the remainder of the computation - /// (Originally from ../FSComp.txt:1250) + /// (Originally from ..\FSComp.txt:1250) static member tcIntoNeedsRestOfQuery() = (3129, GetStringFunc("tcIntoNeedsRestOfQuery",",,,") ) /// The operator '%s' does not accept the use of 'into' - /// (Originally from ../FSComp.txt:1251) + /// (Originally from ..\FSComp.txt:1251) static member tcOperatorDoesntAcceptInto(a0 : System.String) = (3130, GetStringFunc("tcOperatorDoesntAcceptInto",",,,%s,,,") a0) /// The definition of the custom operator '%s' does not use a valid combination of attribute flags - /// (Originally from ../FSComp.txt:1252) + /// (Originally from ..\FSComp.txt:1252) static member tcCustomOperationInvalid(a0 : System.String) = (3131, GetStringFunc("tcCustomOperationInvalid",",,,%s,,,") a0) /// This type definition may not have the 'CLIMutable' attribute. Only record types may have this attribute. - /// (Originally from ../FSComp.txt:1253) + /// (Originally from ..\FSComp.txt:1253) static member tcThisTypeMayNotHaveACLIMutableAttribute() = (3132, GetStringFunc("tcThisTypeMayNotHaveACLIMutableAttribute",",,,") ) /// 'member val' definitions are only permitted in types with a primary constructor. Consider adding arguments to your type definition, e.g. 'type X(args) = ...'. - /// (Originally from ../FSComp.txt:1254) + /// (Originally from ..\FSComp.txt:1254) static member tcAutoPropertyRequiresImplicitConstructionSequence() = (3133, GetStringFunc("tcAutoPropertyRequiresImplicitConstructionSequence",",,,") ) /// Property definitions may not be declared mutable. To indicate that this property can be set, use 'member val PropertyName = expr with get,set'. - /// (Originally from ../FSComp.txt:1255) + /// (Originally from ..\FSComp.txt:1255) static member parsMutableOnAutoPropertyShouldBeGetSet() = (3134, GetStringFunc("parsMutableOnAutoPropertyShouldBeGetSet",",,,") ) /// To indicate that this property can be set, use 'member val PropertyName = expr with get,set'. - /// (Originally from ../FSComp.txt:1256) + /// (Originally from ..\FSComp.txt:1256) static member parsMutableOnAutoPropertyShouldBeGetSetNotJustSet() = (3135, GetStringFunc("parsMutableOnAutoPropertyShouldBeGetSetNotJustSet",",,,") ) /// Type '%s' is illegal because in byref, T cannot contain byref types. - /// (Originally from ../FSComp.txt:1257) + /// (Originally from ..\FSComp.txt:1257) static member chkNoByrefsOfByrefs(a0 : System.String) = (3136, GetStringFunc("chkNoByrefsOfByrefs",",,,%s,,,") a0) /// F# supports array ranks between 1 and 32. The value %d is not allowed. - /// (Originally from ../FSComp.txt:1258) + /// (Originally from ..\FSComp.txt:1258) static member tastopsMaxArrayThirtyTwo(a0 : System.Int32) = (3138, GetStringFunc("tastopsMaxArrayThirtyTwo",",,,%d,,,") a0) /// In queries, use the form 'for x in n .. m do ...' for ranging over integers - /// (Originally from ../FSComp.txt:1259) + /// (Originally from ..\FSComp.txt:1259) static member tcNoIntegerForLoopInQuery() = (3139, GetStringFunc("tcNoIntegerForLoopInQuery",",,,") ) /// 'while' expressions may not be used in queries - /// (Originally from ../FSComp.txt:1260) + /// (Originally from ..\FSComp.txt:1260) static member tcNoWhileInQuery() = (3140, GetStringFunc("tcNoWhileInQuery",",,,") ) /// 'try/finally' expressions may not be used in queries - /// (Originally from ../FSComp.txt:1261) + /// (Originally from ..\FSComp.txt:1261) static member tcNoTryFinallyInQuery() = (3141, GetStringFunc("tcNoTryFinallyInQuery",",,,") ) /// 'use' expressions may not be used in queries - /// (Originally from ../FSComp.txt:1262) + /// (Originally from ..\FSComp.txt:1262) static member tcUseMayNotBeUsedInQueries() = (3142, GetStringFunc("tcUseMayNotBeUsedInQueries",",,,") ) /// 'let!', 'use!' and 'do!' expressions may not be used in queries - /// (Originally from ../FSComp.txt:1263) + /// (Originally from ..\FSComp.txt:1263) static member tcBindMayNotBeUsedInQueries() = (3143, GetStringFunc("tcBindMayNotBeUsedInQueries",",,,") ) /// 'return' and 'return!' may not be used in queries - /// (Originally from ../FSComp.txt:1264) + /// (Originally from ..\FSComp.txt:1264) static member tcReturnMayNotBeUsedInQueries() = (3144, GetStringFunc("tcReturnMayNotBeUsedInQueries",",,,") ) /// This is not a known query operator. Query operators are identifiers such as 'select', 'where', 'sortBy', 'thenBy', 'groupBy', 'groupValBy', 'join', 'groupJoin', 'sumBy' and 'averageBy', defined using corresponding methods on the 'QueryBuilder' type. - /// (Originally from ../FSComp.txt:1265) + /// (Originally from ..\FSComp.txt:1265) static member tcUnrecognizedQueryOperator() = (3145, GetStringFunc("tcUnrecognizedQueryOperator",",,,") ) /// 'try/with' expressions may not be used in queries - /// (Originally from ../FSComp.txt:1266) + /// (Originally from ..\FSComp.txt:1266) static member tcTryWithMayNotBeUsedInQueries() = (3146, GetStringFunc("tcTryWithMayNotBeUsedInQueries",",,,") ) /// This 'let' definition may not be used in a query. Only simple value definitions may be used in queries. - /// (Originally from ../FSComp.txt:1267) + /// (Originally from ..\FSComp.txt:1267) static member tcNonSimpleLetBindingInQuery() = (3147, GetStringFunc("tcNonSimpleLetBindingInQuery",",,,") ) /// Too many static parameters. Expected at most %d parameters, but got %d unnamed and %d named parameters. - /// (Originally from ../FSComp.txt:1268) + /// (Originally from ..\FSComp.txt:1268) static member etTooManyStaticParameters(a0 : System.Int32, a1 : System.Int32, a2 : System.Int32) = (3148, GetStringFunc("etTooManyStaticParameters",",,,%d,,,%d,,,%d,,,") a0 a1 a2) /// Invalid provided literal value '%s' - /// (Originally from ../FSComp.txt:1269) + /// (Originally from ..\FSComp.txt:1269) static member infosInvalidProvidedLiteralValue(a0 : System.String) = (3149, GetStringFunc("infosInvalidProvidedLiteralValue",",,,%s,,,") a0) /// The 'anycpu32bitpreferred' platform can only be used with EXE targets. You must use 'anycpu' instead. - /// (Originally from ../FSComp.txt:1270) + /// (Originally from ..\FSComp.txt:1270) static member invalidPlatformTarget() = (3150, GetStringFunc("invalidPlatformTarget",",,,") ) /// This member, function or value declaration may not be declared 'inline' - /// (Originally from ../FSComp.txt:1271) + /// (Originally from ..\FSComp.txt:1271) static member tcThisValueMayNotBeInlined() = (3151, GetStringFunc("tcThisValueMayNotBeInlined",",,,") ) /// The provider '%s' returned a non-generated type '%s' in the context of a set of generated types. Consider adjusting the type provider to only return generated types. - /// (Originally from ../FSComp.txt:1272) + /// (Originally from ..\FSComp.txt:1272) static member etErasedTypeUsedInGeneration(a0 : System.String, a1 : System.String) = (3152, GetStringFunc("etErasedTypeUsedInGeneration",",,,%s,,,%s,,,") a0 a1) /// Arguments to query operators may require parentheses, e.g. 'where (x > y)' or 'groupBy (x.Length / 10)' - /// (Originally from ../FSComp.txt:1273) + /// (Originally from ..\FSComp.txt:1273) static member tcUnrecognizedQueryBinaryOperator() = (3153, GetStringFunc("tcUnrecognizedQueryBinaryOperator",",,,") ) /// A quotation may not involve an assignment to or taking the address of a captured local variable - /// (Originally from ../FSComp.txt:1274) + /// (Originally from ..\FSComp.txt:1274) static member crefNoSetOfHole() = (3155, GetStringFunc("crefNoSetOfHole",",,,") ) /// + 1 overload - /// (Originally from ../FSComp.txt:1275) + /// (Originally from ..\FSComp.txt:1275) static member nicePrintOtherOverloads1() = (GetStringFunc("nicePrintOtherOverloads1",",,,") ) /// + %d overloads - /// (Originally from ../FSComp.txt:1276) + /// (Originally from ..\FSComp.txt:1276) static member nicePrintOtherOverloadsN(a0 : System.Int32) = (GetStringFunc("nicePrintOtherOverloadsN",",,,%d,,,") a0) /// Erased to - /// (Originally from ../FSComp.txt:1277) + /// (Originally from ..\FSComp.txt:1277) static member erasedTo() = (GetStringFunc("erasedTo",",,,") ) /// Unexpected token '%s' or incomplete expression - /// (Originally from ../FSComp.txt:1278) + /// (Originally from ..\FSComp.txt:1278) static member parsUnfinishedExpression(a0 : System.String) = (3156, GetStringFunc("parsUnfinishedExpression",",,,%s,,,") a0) /// Cannot find code target for this attribute, possibly because the code after the attribute is incomplete. - /// (Originally from ../FSComp.txt:1279) + /// (Originally from ..\FSComp.txt:1279) static member parsAttributeOnIncompleteCode() = (3158, GetStringFunc("parsAttributeOnIncompleteCode",",,,") ) /// Type name cannot be empty. - /// (Originally from ../FSComp.txt:1280) + /// (Originally from ..\FSComp.txt:1280) static member parsTypeNameCannotBeEmpty() = (3159, GetStringFunc("parsTypeNameCannotBeEmpty",",,,") ) /// Problem reading assembly '%s': %s - /// (Originally from ../FSComp.txt:1281) + /// (Originally from ..\FSComp.txt:1281) static member buildProblemReadingAssembly(a0 : System.String, a1 : System.String) = (3160, GetStringFunc("buildProblemReadingAssembly",",,,%s,,,%s,,,") a0 a1) /// Invalid provided field. Provided fields of erased provided types must be literals. - /// (Originally from ../FSComp.txt:1282) + /// (Originally from ..\FSComp.txt:1282) static member tcTPFieldMustBeLiteral() = (3161, GetStringFunc("tcTPFieldMustBeLiteral",",,,") ) /// (loading description...) - /// (Originally from ../FSComp.txt:1283) + /// (Originally from ..\FSComp.txt:1283) static member loadingDescription() = (GetStringFunc("loadingDescription",",,,") ) /// (description unavailable...) - /// (Originally from ../FSComp.txt:1284) + /// (Originally from ..\FSComp.txt:1284) static member descriptionUnavailable() = (GetStringFunc("descriptionUnavailable",",,,") ) /// A type variable has been constrained by multiple different class types. A type variable may only have one class constraint. - /// (Originally from ../FSComp.txt:1285) + /// (Originally from ..\FSComp.txt:1285) static member chkTyparMultipleClassConstraints() = (3162, GetStringFunc("chkTyparMultipleClassConstraints",",,,") ) /// 'match' expressions may not be used in queries - /// (Originally from ../FSComp.txt:1286) + /// (Originally from ..\FSComp.txt:1286) static member tcMatchMayNotBeUsedWithQuery() = (3163, GetStringFunc("tcMatchMayNotBeUsedWithQuery",",,,") ) /// Infix operator member '%s' has %d initial argument(s). Expected a tuple of 3 arguments - /// (Originally from ../FSComp.txt:1287) + /// (Originally from ..\FSComp.txt:1287) static member memberOperatorDefinitionWithNonTripleArgument(a0 : System.String, a1 : System.Int32) = (3164, GetStringFunc("memberOperatorDefinitionWithNonTripleArgument",",,,%s,,,%d,,,") a0 a1) /// The operator '%s' cannot be resolved. Consider opening the module 'Microsoft.FSharp.Linq.NullableOperators'. - /// (Originally from ../FSComp.txt:1288) + /// (Originally from ..\FSComp.txt:1288) static member cannotResolveNullableOperators(a0 : System.String) = (3165, GetStringFunc("cannotResolveNullableOperators",",,,%s,,,") a0) /// '%s' must be followed by 'in'. Usage: %s. - /// (Originally from ../FSComp.txt:1289) + /// (Originally from ..\FSComp.txt:1289) static member tcOperatorRequiresIn(a0 : System.String, a1 : System.String) = (3167, GetStringFunc("tcOperatorRequiresIn",",,,%s,,,%s,,,") a0 a1) /// Neither 'member val' nor 'override val' definitions are permitted in object expressions. - /// (Originally from ../FSComp.txt:1290) + /// (Originally from ..\FSComp.txt:1290) static member parsIllegalMemberVarInObjectImplementation() = (3168, GetStringFunc("parsIllegalMemberVarInObjectImplementation",",,,") ) /// Copy-and-update record expressions must include at least one field. - /// (Originally from ../FSComp.txt:1291) + /// (Originally from ..\FSComp.txt:1291) static member tcEmptyCopyAndUpdateRecordInvalid() = (3169, GetStringFunc("tcEmptyCopyAndUpdateRecordInvalid",",,,") ) /// '_' cannot be used as field name - /// (Originally from ../FSComp.txt:1292) + /// (Originally from ..\FSComp.txt:1292) static member parsUnderscoreInvalidFieldName() = (3170, GetStringFunc("parsUnderscoreInvalidFieldName",",,,") ) /// The provided types generated by this use of a type provider may not be used from other F# assemblies and should be marked internal or private. Consider using 'type internal TypeName = ...' or 'type private TypeName = ...'. - /// (Originally from ../FSComp.txt:1293) + /// (Originally from ..\FSComp.txt:1293) static member tcGeneratedTypesShouldBeInternalOrPrivate() = (3171, GetStringFunc("tcGeneratedTypesShouldBeInternalOrPrivate",",,,") ) /// A property's getter and setter must have the same type. Property '%s' has getter of type '%s' but setter of type '%s'. - /// (Originally from ../FSComp.txt:1294) + /// (Originally from ..\FSComp.txt:1294) static member chkGetterAndSetterHaveSamePropertyType(a0 : System.String, a1 : System.String, a2 : System.String) = (3172, GetStringFunc("chkGetterAndSetterHaveSamePropertyType",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// Array method '%s' is supplied by the runtime and cannot be directly used in code. For operations with array elements consider using family of GetArray/SetArray functions from LanguagePrimitives.IntrinsicFunctions module. - /// (Originally from ../FSComp.txt:1295) + /// (Originally from ..\FSComp.txt:1295) static member tcRuntimeSuppliedMethodCannotBeUsedInUserCode(a0 : System.String) = (3173, GetStringFunc("tcRuntimeSuppliedMethodCannotBeUsedInUserCode",",,,%s,,,") a0) /// Union case/exception '%s' does not have field named '%s'. - /// (Originally from ../FSComp.txt:1296) + /// (Originally from ..\FSComp.txt:1296) static member tcUnionCaseConstructorDoesNotHaveFieldWithGivenName(a0 : System.String, a1 : System.String) = (3174, GetStringFunc("tcUnionCaseConstructorDoesNotHaveFieldWithGivenName",",,,%s,,,%s,,,") a0 a1) /// Union case/exception field '%s' cannot be used more than once. - /// (Originally from ../FSComp.txt:1297) + /// (Originally from ..\FSComp.txt:1297) static member tcUnionCaseFieldCannotBeUsedMoreThanOnce(a0 : System.String) = (3175, GetStringFunc("tcUnionCaseFieldCannotBeUsedMoreThanOnce",",,,%s,,,") a0) /// Named field '%s' is used more than once. - /// (Originally from ../FSComp.txt:1298) + /// (Originally from ..\FSComp.txt:1298) static member tcFieldNameIsUsedModeThanOnce(a0 : System.String) = (3176, GetStringFunc("tcFieldNameIsUsedModeThanOnce",",,,%s,,,") a0) /// Named field '%s' conflicts with autogenerated name for anonymous field. - /// (Originally from ../FSComp.txt:1299) + /// (Originally from ..\FSComp.txt:1299) static member tcFieldNameConflictsWithGeneratedNameForAnonymousField(a0 : System.String) = (3176, GetStringFunc("tcFieldNameConflictsWithGeneratedNameForAnonymousField",",,,%s,,,") a0) /// This literal expression or attribute argument results in an arithmetic overflow. - /// (Originally from ../FSComp.txt:1300) + /// (Originally from ..\FSComp.txt:1300) static member tastConstantExpressionOverflow() = (3177, GetStringFunc("tastConstantExpressionOverflow",",,,") ) /// This is not valid literal expression. The [] attribute will be ignored. - /// (Originally from ../FSComp.txt:1301) + /// (Originally from ..\FSComp.txt:1301) static member tcIllegalStructTypeForConstantExpression() = (3178, GetStringFunc("tcIllegalStructTypeForConstantExpression",",,,") ) /// System.Runtime.InteropServices assembly is required to use UnknownWrapper\DispatchWrapper classes. - /// (Originally from ../FSComp.txt:1302) + /// (Originally from ..\FSComp.txt:1302) static member fscSystemRuntimeInteropServicesIsRequired() = (3179, GetStringFunc("fscSystemRuntimeInteropServicesIsRequired",",,,") ) /// The mutable local '%s' is implicitly allocated as a reference cell because it has been captured by a closure. This warning is for informational purposes only to indicate where implicit allocations are performed. - /// (Originally from ../FSComp.txt:1303) + /// (Originally from ..\FSComp.txt:1303) static member abImplicitHeapAllocation(a0 : System.String) = (3180, GetStringFunc("abImplicitHeapAllocation",",,,%s,,,") a0) /// A type provider implemented GetStaticParametersForMethod, but ApplyStaticArgumentsForMethod was not implemented or invalid - /// (Originally from ../FSComp.txt:1304) + /// (Originally from ..\FSComp.txt:1304) static member estApplyStaticArgumentsForMethodNotImplemented() = (GetStringFunc("estApplyStaticArgumentsForMethodNotImplemented",",,,") ) /// An error occured applying the static arguments to a provided method - /// (Originally from ../FSComp.txt:1305) + /// (Originally from ..\FSComp.txt:1305) static member etErrorApplyingStaticArgumentsToMethod() = (3181, GetStringFunc("etErrorApplyingStaticArgumentsToMethod",",,,") ) /// Unexpected character '%s' in preprocessor expression - /// (Originally from ../FSComp.txt:1306) + /// (Originally from ..\FSComp.txt:1306) static member pplexUnexpectedChar(a0 : System.String) = (3182, GetStringFunc("pplexUnexpectedChar",",,,%s,,,") a0) /// Unexpected token '%s' in preprocessor expression - /// (Originally from ../FSComp.txt:1307) + /// (Originally from ..\FSComp.txt:1307) static member ppparsUnexpectedToken(a0 : System.String) = (3183, GetStringFunc("ppparsUnexpectedToken",",,,%s,,,") a0) /// Incomplete preprocessor expression - /// (Originally from ../FSComp.txt:1308) + /// (Originally from ..\FSComp.txt:1308) static member ppparsIncompleteExpression() = (3184, GetStringFunc("ppparsIncompleteExpression",",,,") ) /// Missing token '%s' in preprocessor expression - /// (Originally from ../FSComp.txt:1309) + /// (Originally from ..\FSComp.txt:1309) static member ppparsMissingToken(a0 : System.String) = (3185, GetStringFunc("ppparsMissingToken",",,,%s,,,") a0) /// An error occurred while reading the F# metadata node at position %d in table '%s' of assembly '%s'. The node had no matching declaration. Please report this warning. You may need to recompile the F# assembly you are using. - /// (Originally from ../FSComp.txt:1310) + /// (Originally from ..\FSComp.txt:1310) static member pickleMissingDefinition(a0 : System.Int32, a1 : System.String, a2 : System.String) = (3186, GetStringFunc("pickleMissingDefinition",",,,%d,,,%s,,,%s,,,") a0 a1 a2) /// Type inference caused the type variable %s to escape its scope. Consider adding an explicit type parameter declaration or adjusting your code to be less generic. - /// (Originally from ../FSComp.txt:1311) + /// (Originally from ..\FSComp.txt:1311) static member checkNotSufficientlyGenericBecauseOfScope(a0 : System.String) = (3187, GetStringFunc("checkNotSufficientlyGenericBecauseOfScope",",,,%s,,,") a0) /// Type inference caused an inference type variable to escape its scope. Consider adding type annotations to make your code less generic. - /// (Originally from ../FSComp.txt:1312) + /// (Originally from ..\FSComp.txt:1312) static member checkNotSufficientlyGenericBecauseOfScopeAnon() = (3188, GetStringFunc("checkNotSufficientlyGenericBecauseOfScopeAnon",",,,") ) /// Redundant arguments are being ignored in function '%s'. Expected %d but got %d arguments. - /// (Originally from ../FSComp.txt:1313) + /// (Originally from ..\FSComp.txt:1313) static member checkRaiseFamilyFunctionArgumentCount(a0 : System.String, a1 : System.Int32, a2 : System.Int32) = (3189, GetStringFunc("checkRaiseFamilyFunctionArgumentCount",",,,%s,,,%d,,,%d,,,") a0 a1 a2) /// Lowercase literal '%s' is being shadowed by a new pattern with the same name. Only uppercase and module-prefixed literals can be used as named patterns. - /// (Originally from ../FSComp.txt:1314) + /// (Originally from ..\FSComp.txt:1314) static member checkLowercaseLiteralBindingInPattern(a0 : System.String) = (3190, GetStringFunc("checkLowercaseLiteralBindingInPattern",",,,%s,,,") a0) /// This literal pattern does not take arguments - /// (Originally from ../FSComp.txt:1315) + /// (Originally from ..\FSComp.txt:1315) static member tcLiteralDoesNotTakeArguments() = (3191, GetStringFunc("tcLiteralDoesNotTakeArguments",",,,") ) /// Constructors are not permitted as extension members - they must be defined as part of the original definition of the type - /// (Originally from ../FSComp.txt:1316) + /// (Originally from ..\FSComp.txt:1316) static member tcConstructorsIllegalInAugmentation() = (3192, GetStringFunc("tcConstructorsIllegalInAugmentation",",,,") ) /// Invalid response file '%s' ( '%s' ) - /// (Originally from ../FSComp.txt:1317) + /// (Originally from ..\FSComp.txt:1317) static member optsInvalidResponseFile(a0 : System.String, a1 : System.String) = (3193, GetStringFunc("optsInvalidResponseFile",",,,%s,,,%s,,,") a0 a1) /// Response file '%s' not found in '%s' - /// (Originally from ../FSComp.txt:1318) + /// (Originally from ..\FSComp.txt:1318) static member optsResponseFileNotFound(a0 : System.String, a1 : System.String) = (3194, GetStringFunc("optsResponseFileNotFound",",,,%s,,,%s,,,") a0 a1) /// Response file name '%s' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long - /// (Originally from ../FSComp.txt:1319) + /// (Originally from ..\FSComp.txt:1319) static member optsResponseFileNameInvalid(a0 : System.String) = (3195, GetStringFunc("optsResponseFileNameInvalid",",,,%s,,,") a0) /// Cannot find FSharp.Core.dll in compiler's directory - /// (Originally from ../FSComp.txt:1320) + /// (Originally from ..\FSComp.txt:1320) static member fsharpCoreNotFoundToBeCopied() = (3196, GetStringFunc("fsharpCoreNotFoundToBeCopied",",,,") ) /// One tuple type is a struct tuple, the other is a reference tuple - /// (Originally from ../FSComp.txt:1321) + /// (Originally from ..\FSComp.txt:1321) static member tcTupleStructMismatch() = (GetStringFunc("tcTupleStructMismatch",",,,") ) /// This provided method requires static parameters - /// (Originally from ../FSComp.txt:1322) + /// (Originally from ..\FSComp.txt:1322) static member etMissingStaticArgumentsToMethod() = (3197, GetStringFunc("etMissingStaticArgumentsToMethod",",,,") ) /// The conversion from %s to %s is a compile-time safe upcast, not a downcast. Consider using 'upcast' instead of 'downcast'. - /// (Originally from ../FSComp.txt:1323) + /// (Originally from ..\FSComp.txt:1323) static member considerUpcast(a0 : System.String, a1 : System.String) = (3198, GetStringFunc("considerUpcast",",,,%s,,,%s,,,") a0 a1) /// The conversion from %s to %s is a compile-time safe upcast, not a downcast. Consider using the :> (upcast) operator instead of the :?> (downcast) operator. - /// (Originally from ../FSComp.txt:1324) + /// (Originally from ..\FSComp.txt:1324) static member considerUpcastOperator(a0 : System.String, a1 : System.String) = (3198, GetStringFunc("considerUpcastOperator",",,,%s,,,%s,,,") a0 a1) /// The 'rec' on this module is implied by an outer 'rec' declaration and is being ignored - /// (Originally from ../FSComp.txt:1325) + /// (Originally from ..\FSComp.txt:1325) static member tcRecImplied() = (3199, GetStringFunc("tcRecImplied",",,,") ) /// In a recursive declaration group, 'open' declarations must come first in each module - /// (Originally from ../FSComp.txt:1326) + /// (Originally from ..\FSComp.txt:1326) static member tcOpenFirstInMutRec() = (3200, GetStringFunc("tcOpenFirstInMutRec",",,,") ) /// In a recursive declaration group, module abbreviations must come after all 'open' declarations and before other declarations - /// (Originally from ../FSComp.txt:1327) + /// (Originally from ..\FSComp.txt:1327) static member tcModuleAbbrevFirstInMutRec() = (3201, GetStringFunc("tcModuleAbbrevFirstInMutRec",",,,") ) /// This declaration is not supported in recursive declaration groups - /// (Originally from ../FSComp.txt:1328) + /// (Originally from ..\FSComp.txt:1328) static member tcUnsupportedMutRecDecl() = (3202, GetStringFunc("tcUnsupportedMutRecDecl",",,,") ) /// Invalid use of 'rec' keyword - /// (Originally from ../FSComp.txt:1329) + /// (Originally from ..\FSComp.txt:1329) static member parsInvalidUseOfRec() = (3203, GetStringFunc("parsInvalidUseOfRec",",,,") ) /// If a union type has more than one case and is a struct, then all fields within the union type must be given unique names. - /// (Originally from ../FSComp.txt:1330) + /// (Originally from ..\FSComp.txt:1330) static member tcStructUnionMultiCaseDistinctFields() = (3204, GetStringFunc("tcStructUnionMultiCaseDistinctFields",",,,") ) /// The CallerMemberNameAttribute applied to parameter '%s' will have no effect. It is overridden by the CallerFilePathAttribute. - /// (Originally from ../FSComp.txt:1331) + /// (Originally from ..\FSComp.txt:1331) static member CallerMemberNameIsOverriden(a0 : System.String) = (3206, GetStringFunc("CallerMemberNameIsOverriden",",,,%s,,,") a0) /// 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' - /// (Originally from ../FSComp.txt:1332) + /// (Originally from ..\FSComp.txt:1332) static member tcFixedNotAllowed() = (3207, GetStringFunc("tcFixedNotAllowed",",,,") ) /// Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression. - /// (Originally from ../FSComp.txt:1333) + /// (Originally from ..\FSComp.txt:1333) static member tcCouldNotFindOffsetToStringData() = (3208, GetStringFunc("tcCouldNotFindOffsetToStringData",",,,") ) /// The address of the variable '%s' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - /// (Originally from ../FSComp.txt:1334) + /// (Originally from ..\FSComp.txt:1334) static member chkNoByrefReturnOfLocal(a0 : System.String) = (3209, GetStringFunc("chkNoByrefReturnOfLocal",",,,%s,,,") a0) /// %s is an active pattern and cannot be treated as a discriminated union case with named fields. - /// (Originally from ../FSComp.txt:1335) + /// (Originally from ..\FSComp.txt:1335) static member tcNamedActivePattern(a0 : System.String) = (3210, GetStringFunc("tcNamedActivePattern",",,,%s,,,") a0) /// 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)'. - /// (Originally from ../FSComp.txt:1336) + /// (Originally from ..\FSComp.txt:1336) static member DefaultParameterValueNotAppropriateForArgument() = (3211, GetStringFunc("DefaultParameterValueNotAppropriateForArgument",",,,") ) /// The system type '%s' was required but no referenced system DLL contained this type - /// (Originally from ../FSComp.txt:1337) + /// (Originally from ..\FSComp.txt:1337) static member tcGlobalsSystemTypeNotFound(a0 : System.String) = (GetStringFunc("tcGlobalsSystemTypeNotFound",",,,%s,,,") a0) /// The member '%s' matches multiple overloads of the same method.\nPlease restrict it to one of the following:%s. - /// (Originally from ../FSComp.txt:1338) + /// (Originally from ..\FSComp.txt:1338) static member typrelMemberHasMultiplePossibleDispatchSlots(a0 : System.String, a1 : System.String) = (3213, GetStringFunc("typrelMemberHasMultiplePossibleDispatchSlots",",,,%s,,,%s,,,") a0 a1) /// Method or object constructor '%s' is not static - /// (Originally from ../FSComp.txt:1339) + /// (Originally from ..\FSComp.txt:1339) static member methodIsNotStatic(a0 : System.String) = (3214, GetStringFunc("methodIsNotStatic",",,,%s,,,") a0) /// Unexpected symbol '=' in expression. Did you intend to use 'for x in y .. z do' instead? - /// (Originally from ../FSComp.txt:1340) + /// (Originally from ..\FSComp.txt:1340) static member parsUnexpectedSymbolEqualsInsteadOfIn() = (3215, GetStringFunc("parsUnexpectedSymbolEqualsInsteadOfIn",",,,") ) /// Indicates a method that either has no implementation in the type in which it is declared or that is virtual and has a default implementation. - /// (Originally from ../FSComp.txt:1341) + /// (Originally from ..\FSComp.txt:1341) static member keywordDescriptionAbstract() = (GetStringFunc("keywordDescriptionAbstract",",,,") ) /// Used in mutually recursive bindings, in property declarations, and with multiple constraints on generic parameters. - /// (Originally from ../FSComp.txt:1342) + /// (Originally from ..\FSComp.txt:1342) static member keyworkDescriptionAnd() = (GetStringFunc("keyworkDescriptionAnd",",,,") ) /// Used to give the current class object an object name. Also used to give a name to a whole pattern within a pattern match. - /// (Originally from ../FSComp.txt:1343) + /// (Originally from ..\FSComp.txt:1343) static member keywordDescriptionAs() = (GetStringFunc("keywordDescriptionAs",",,,") ) /// Used to verify code during debugging. - /// (Originally from ../FSComp.txt:1344) + /// (Originally from ..\FSComp.txt:1344) static member keywordDescriptionAssert() = (GetStringFunc("keywordDescriptionAssert",",,,") ) /// Used as the name of the base class object. - /// (Originally from ../FSComp.txt:1345) + /// (Originally from ..\FSComp.txt:1345) static member keywordDescriptionBase() = (GetStringFunc("keywordDescriptionBase",",,,") ) /// In verbose syntax, indicates the start of a code block. - /// (Originally from ../FSComp.txt:1346) + /// (Originally from ..\FSComp.txt:1346) static member keywordDescriptionBegin() = (GetStringFunc("keywordDescriptionBegin",",,,") ) /// In verbose syntax, indicates the start of a class definition. - /// (Originally from ../FSComp.txt:1347) + /// (Originally from ..\FSComp.txt:1347) static member keywordDescriptionClass() = (GetStringFunc("keywordDescriptionClass",",,,") ) /// Indicates an implementation of an abstract method; used together with an abstract method declaration to create a virtual method. - /// (Originally from ../FSComp.txt:1348) + /// (Originally from ..\FSComp.txt:1348) static member keywordDescriptionDefault() = (GetStringFunc("keywordDescriptionDefault",",,,") ) /// Used to declare a delegate. - /// (Originally from ../FSComp.txt:1349) + /// (Originally from ..\FSComp.txt:1349) static member keywordDescriptionDelegate() = (GetStringFunc("keywordDescriptionDelegate",",,,") ) /// Used in looping constructs or to execute imperative code. - /// (Originally from ../FSComp.txt:1350) + /// (Originally from ..\FSComp.txt:1350) static member keywordDescriptionDo() = (GetStringFunc("keywordDescriptionDo",",,,") ) /// In verbose syntax, indicates the end of a block of code in a looping expression. - /// (Originally from ../FSComp.txt:1351) + /// (Originally from ..\FSComp.txt:1351) static member keywordDescriptionDone() = (GetStringFunc("keywordDescriptionDone",",,,") ) /// Used to convert to a type that is lower in the inheritance chain. - /// (Originally from ../FSComp.txt:1352) + /// (Originally from ..\FSComp.txt:1352) static member keywordDescriptionDowncast() = (GetStringFunc("keywordDescriptionDowncast",",,,") ) /// In a for expression, used when counting in reverse. - /// (Originally from ../FSComp.txt:1353) + /// (Originally from ..\FSComp.txt:1353) static member keywordDescriptionDownto() = (GetStringFunc("keywordDescriptionDownto",",,,") ) /// Used in conditional branching. A short form of else if. - /// (Originally from ../FSComp.txt:1354) + /// (Originally from ..\FSComp.txt:1354) static member keywordDescriptionElif() = (GetStringFunc("keywordDescriptionElif",",,,") ) /// Used in conditional branching. - /// (Originally from ../FSComp.txt:1355) + /// (Originally from ..\FSComp.txt:1355) static member keywordDescriptionElse() = (GetStringFunc("keywordDescriptionElse",",,,") ) /// In type definitions and type extensions, indicates the end of a section of member definitions. In verbose syntax, used to specify the end of a code block that starts with the begin keyword. - /// (Originally from ../FSComp.txt:1356) + /// (Originally from ..\FSComp.txt:1356) static member keywordDescriptionEnd() = (GetStringFunc("keywordDescriptionEnd",",,,") ) /// Used to declare an exception type. - /// (Originally from ../FSComp.txt:1357) + /// (Originally from ..\FSComp.txt:1357) static member keywordDescriptionException() = (GetStringFunc("keywordDescriptionException",",,,") ) /// Indicates that a declared program element is defined in another binary or assembly. - /// (Originally from ../FSComp.txt:1358) + /// (Originally from ..\FSComp.txt:1358) static member keywordDescriptionExtern() = (GetStringFunc("keywordDescriptionExtern",",,,") ) /// Used as a Boolean literal. - /// (Originally from ../FSComp.txt:1359) + /// (Originally from ..\FSComp.txt:1359) static member keywordDescriptionTrueFalse() = (GetStringFunc("keywordDescriptionTrueFalse",",,,") ) /// Used together with try to introduce a block of code that executes regardless of whether an exception occurs. - /// (Originally from ../FSComp.txt:1360) + /// (Originally from ..\FSComp.txt:1360) static member keywordDescriptionFinally() = (GetStringFunc("keywordDescriptionFinally",",,,") ) /// Used in looping constructs. - /// (Originally from ../FSComp.txt:1361) + /// (Originally from ..\FSComp.txt:1361) static member keywordDescriptionFor() = (GetStringFunc("keywordDescriptionFor",",,,") ) /// Used in lambda expressions, also known as anonymous functions. - /// (Originally from ../FSComp.txt:1362) + /// (Originally from ..\FSComp.txt:1362) static member keywordDescriptionFun() = (GetStringFunc("keywordDescriptionFun",",,,") ) /// Used as a shorter alternative to the fun keyword and a match expression in a lambda expression that has pattern matching on a single argument. - /// (Originally from ../FSComp.txt:1363) + /// (Originally from ..\FSComp.txt:1363) static member keywordDescriptionFunction() = (GetStringFunc("keywordDescriptionFunction",",,,") ) /// Used to reference the top-level .NET namespace. - /// (Originally from ../FSComp.txt:1364) + /// (Originally from ..\FSComp.txt:1364) static member keywordDescriptionGlobal() = (GetStringFunc("keywordDescriptionGlobal",",,,") ) /// Used in conditional branching constructs. - /// (Originally from ../FSComp.txt:1365) + /// (Originally from ..\FSComp.txt:1365) static member keywordDescriptionIf() = (GetStringFunc("keywordDescriptionIf",",,,") ) /// Used for sequence expressions and, in verbose syntax, to separate expressions from bindings. - /// (Originally from ../FSComp.txt:1366) + /// (Originally from ..\FSComp.txt:1366) static member keywordDescriptionIn() = (GetStringFunc("keywordDescriptionIn",",,,") ) /// Used to specify a base class or base interface. - /// (Originally from ../FSComp.txt:1367) + /// (Originally from ..\FSComp.txt:1367) static member keywordDescriptionInherit() = (GetStringFunc("keywordDescriptionInherit",",,,") ) /// Used to indicate a function that should be integrated directly into the caller's code. - /// (Originally from ../FSComp.txt:1368) + /// (Originally from ..\FSComp.txt:1368) static member keywordDescriptionInline() = (GetStringFunc("keywordDescriptionInline",",,,") ) /// Used to declare and implement interfaces. - /// (Originally from ../FSComp.txt:1369) + /// (Originally from ..\FSComp.txt:1369) static member keywordDescriptionInterface() = (GetStringFunc("keywordDescriptionInterface",",,,") ) /// Used to specify that a member is visible inside an assembly but not outside it. - /// (Originally from ../FSComp.txt:1370) + /// (Originally from ..\FSComp.txt:1370) static member keywordDescriptionInternal() = (GetStringFunc("keywordDescriptionInternal",",,,") ) /// Used to specify a computation that is to be performed only when a result is needed. - /// (Originally from ../FSComp.txt:1371) + /// (Originally from ..\FSComp.txt:1371) static member keywordDescriptionLazy() = (GetStringFunc("keywordDescriptionLazy",",,,") ) /// Used to associate, or bind, a name to a value or function. - /// (Originally from ../FSComp.txt:1372) + /// (Originally from ..\FSComp.txt:1372) static member keywordDescriptionLet() = (GetStringFunc("keywordDescriptionLet",",,,") ) /// Used in asynchronous workflows to bind a name to the result of an asynchronous computation, or, in other computation expressions, used to bind a name to a result, which is of the computation type. - /// (Originally from ../FSComp.txt:1373) + /// (Originally from ..\FSComp.txt:1373) static member keywordDescriptionLetBang() = (GetStringFunc("keywordDescriptionLetBang",",,,") ) /// Used to branch by comparing a value to a pattern. - /// (Originally from ../FSComp.txt:1374) + /// (Originally from ..\FSComp.txt:1374) static member keywordDescriptionMatch() = (GetStringFunc("keywordDescriptionMatch",",,,") ) /// Used in computation expressions to pattern match directly over the result of another computation expression. - /// (Originally from ../FSComp.txt:1375) + /// (Originally from ..\FSComp.txt:1375) static member keywordDescriptionMatchBang() = (GetStringFunc("keywordDescriptionMatchBang",",,,") ) /// Used to declare a property or method in an object type. - /// (Originally from ../FSComp.txt:1376) + /// (Originally from ..\FSComp.txt:1376) static member keywordDescriptionMember() = (GetStringFunc("keywordDescriptionMember",",,,") ) /// Used to associate a name with a group of related types, values, and functions, to logically separate it from other code. - /// (Originally from ../FSComp.txt:1377) + /// (Originally from ..\FSComp.txt:1377) static member keywordDescriptionModule() = (GetStringFunc("keywordDescriptionModule",",,,") ) /// Used to declare a variable, that is, a value that can be changed. - /// (Originally from ../FSComp.txt:1378) + /// (Originally from ..\FSComp.txt:1378) static member keywordDescriptionMutable() = (GetStringFunc("keywordDescriptionMutable",",,,") ) /// Used to associate a name with a group of related types and modules, to logically separate it from other code. - /// (Originally from ../FSComp.txt:1379) + /// (Originally from ..\FSComp.txt:1379) static member keywordDescriptionNamespace() = (GetStringFunc("keywordDescriptionNamespace",",,,") ) /// Used to declare, define, or invoke a constructor that creates or that can create an object. Also used in generic parameter constraints to indicate that a type must have a certain constructor. - /// (Originally from ../FSComp.txt:1380) + /// (Originally from ..\FSComp.txt:1380) static member keywordDescriptionNew() = (GetStringFunc("keywordDescriptionNew",",,,") ) /// Not actually a keyword. However, not struct in combination is used as a generic parameter constraint. - /// (Originally from ../FSComp.txt:1381) + /// (Originally from ..\FSComp.txt:1381) static member keywordDescriptionNot() = (GetStringFunc("keywordDescriptionNot",",,,") ) /// Indicates the absence of an object. Also used in generic parameter constraints. - /// (Originally from ../FSComp.txt:1382) + /// (Originally from ..\FSComp.txt:1382) static member keywordDescriptionNull() = (GetStringFunc("keywordDescriptionNull",",,,") ) /// Used in discriminated unions to indicate the type of categories of values, and in delegate and exception declarations. - /// (Originally from ../FSComp.txt:1383) + /// (Originally from ..\FSComp.txt:1383) static member keywordDescriptionOf() = (GetStringFunc("keywordDescriptionOf",",,,") ) /// Used to make the contents of a namespace or module available without qualification. - /// (Originally from ../FSComp.txt:1384) + /// (Originally from ..\FSComp.txt:1384) static member keywordDescriptionOpen() = (GetStringFunc("keywordDescriptionOpen",",,,") ) /// Used with Boolean conditions as a Boolean or operator. Equivalent to ||. Also used in member constraints. - /// (Originally from ../FSComp.txt:1385) + /// (Originally from ..\FSComp.txt:1385) static member keywordDescriptionOr() = (GetStringFunc("keywordDescriptionOr",",,,") ) /// Used to implement a version of an abstract or virtual method that differs from the base version. - /// (Originally from ../FSComp.txt:1386) + /// (Originally from ..\FSComp.txt:1386) static member keywordDescriptionOverride() = (GetStringFunc("keywordDescriptionOverride",",,,") ) /// Restricts access to a member to code in the same type or module. - /// (Originally from ../FSComp.txt:1387) + /// (Originally from ..\FSComp.txt:1387) static member keywordDescriptionPrivate() = (GetStringFunc("keywordDescriptionPrivate",",,,") ) /// Allows access to a member from outside the type. - /// (Originally from ../FSComp.txt:1388) + /// (Originally from ..\FSComp.txt:1388) static member keywordDescriptionPublic() = (GetStringFunc("keywordDescriptionPublic",",,,") ) /// Used to indicate that a function is recursive. - /// (Originally from ../FSComp.txt:1389) + /// (Originally from ..\FSComp.txt:1389) static member keywordDescriptionRec() = (GetStringFunc("keywordDescriptionRec",",,,") ) /// Used to indicate a value to provide as the result of a computation expression. - /// (Originally from ../FSComp.txt:1390) + /// (Originally from ..\FSComp.txt:1390) static member keywordDescriptionReturn() = (GetStringFunc("keywordDescriptionReturn",",,,") ) /// Used to indicate a computation expression that, when evaluated, provides the result of the containing computation expression. - /// (Originally from ../FSComp.txt:1391) + /// (Originally from ..\FSComp.txt:1391) static member keywordDescriptionReturnBang() = (GetStringFunc("keywordDescriptionReturnBang",",,,") ) /// Used in query expressions to specify what fields or columns to extract. Note that this is a contextual keyword, which means that it is not actually a reserved word and it only acts like a keyword in appropriate context. - /// (Originally from ../FSComp.txt:1392) + /// (Originally from ..\FSComp.txt:1392) static member keywordDescriptionSelect() = (GetStringFunc("keywordDescriptionSelect",",,,") ) /// Used to indicate a method or property that can be called without an instance of a type, or a value member that is shared among all instances of a type. - /// (Originally from ../FSComp.txt:1393) + /// (Originally from ..\FSComp.txt:1393) static member keywordDescriptionStatic() = (GetStringFunc("keywordDescriptionStatic",",,,") ) /// Used to declare a structure type. Also used in generic parameter constraints. Used for OCaml compatibility in module definitions. - /// (Originally from ../FSComp.txt:1394) + /// (Originally from ..\FSComp.txt:1394) static member keywordDescriptionStruct() = (GetStringFunc("keywordDescriptionStruct",",,,") ) /// Used in conditional expressions. Also used to perform side effects after object construction. - /// (Originally from ../FSComp.txt:1395) + /// (Originally from ..\FSComp.txt:1395) static member keywordDescriptionThen() = (GetStringFunc("keywordDescriptionThen",",,,") ) /// Used in for loops to indicate a range. - /// (Originally from ../FSComp.txt:1396) + /// (Originally from ..\FSComp.txt:1396) static member keywordDescriptionTo() = (GetStringFunc("keywordDescriptionTo",",,,") ) /// Used to introduce a block of code that might generate an exception. Used together with with or finally. - /// (Originally from ../FSComp.txt:1397) + /// (Originally from ..\FSComp.txt:1397) static member keywordDescriptionTry() = (GetStringFunc("keywordDescriptionTry",",,,") ) /// Used to declare a class, record, structure, discriminated union, enumeration type, unit of measure, or type abbreviation. - /// (Originally from ../FSComp.txt:1398) + /// (Originally from ..\FSComp.txt:1398) static member keywordDescriptionType() = (GetStringFunc("keywordDescriptionType",",,,") ) /// Used to convert to a type that is higher in the inheritance chain. - /// (Originally from ../FSComp.txt:1399) + /// (Originally from ..\FSComp.txt:1399) static member keywordDescriptionUpcast() = (GetStringFunc("keywordDescriptionUpcast",",,,") ) /// Used instead of let for values that require Dispose to be called to free resources. - /// (Originally from ../FSComp.txt:1400) + /// (Originally from ..\FSComp.txt:1400) static member keywordDescriptionUse() = (GetStringFunc("keywordDescriptionUse",",,,") ) /// Used instead of let! in asynchronous workflows and other computation expressions for values that require Dispose to be called to free resources. - /// (Originally from ../FSComp.txt:1401) + /// (Originally from ..\FSComp.txt:1401) static member keywordDescriptionUseBang() = (GetStringFunc("keywordDescriptionUseBang",",,,") ) /// Used in a signature to indicate a value, or in a type to declare a member, in limited situations. - /// (Originally from ../FSComp.txt:1402) + /// (Originally from ..\FSComp.txt:1402) static member keywordDescriptionVal() = (GetStringFunc("keywordDescriptionVal",",,,") ) /// Indicates the .NET void type. Used when interoperating with other .NET languages. - /// (Originally from ../FSComp.txt:1403) + /// (Originally from ..\FSComp.txt:1403) static member keywordDescriptionVoid() = (GetStringFunc("keywordDescriptionVoid",",,,") ) /// Used for Boolean conditions (when guards) on pattern matches and to introduce a constraint clause for a generic type parameter. - /// (Originally from ../FSComp.txt:1404) + /// (Originally from ..\FSComp.txt:1404) static member keywordDescriptionWhen() = (GetStringFunc("keywordDescriptionWhen",",,,") ) /// Introduces a looping construct. - /// (Originally from ../FSComp.txt:1405) + /// (Originally from ..\FSComp.txt:1405) static member keywordDescriptionWhile() = (GetStringFunc("keywordDescriptionWhile",",,,") ) /// Used together with the match keyword in pattern matching expressions. Also used in object expressions, record copying expressions, and type extensions to introduce member definitions, and to introduce exception handlers. - /// (Originally from ../FSComp.txt:1406) + /// (Originally from ..\FSComp.txt:1406) static member keywordDescriptionWith() = (GetStringFunc("keywordDescriptionWith",",,,") ) /// Used in a sequence expression to produce a value for a sequence. - /// (Originally from ../FSComp.txt:1407) + /// (Originally from ..\FSComp.txt:1407) static member keywordDescriptionYield() = (GetStringFunc("keywordDescriptionYield",",,,") ) /// Used in a computation expression to append the result of a given computation expression to a collection of results for the containing computation expression. - /// (Originally from ../FSComp.txt:1408) + /// (Originally from ..\FSComp.txt:1408) static member keywordDescriptionYieldBang() = (GetStringFunc("keywordDescriptionYieldBang",",,,") ) /// In function types, delimits arguments and return values. Yields an expression (in sequence expressions); equivalent to the yield keyword. Used in match expressions - /// (Originally from ../FSComp.txt:1409) + /// (Originally from ..\FSComp.txt:1409) static member keywordDescriptionRightArrow() = (GetStringFunc("keywordDescriptionRightArrow",",,,") ) /// Assigns a value to a variable. - /// (Originally from ../FSComp.txt:1410) + /// (Originally from ..\FSComp.txt:1410) static member keywordDescriptionLeftArrow() = (GetStringFunc("keywordDescriptionLeftArrow",",,,") ) /// Converts a type to type that is higher in the hierarchy. - /// (Originally from ../FSComp.txt:1411) + /// (Originally from ..\FSComp.txt:1411) static member keywordDescriptionCast() = (GetStringFunc("keywordDescriptionCast",",,,") ) /// Converts a type to a type that is lower in the hierarchy. - /// (Originally from ../FSComp.txt:1412) + /// (Originally from ..\FSComp.txt:1412) static member keywordDescriptionDynamicCast() = (GetStringFunc("keywordDescriptionDynamicCast",",,,") ) /// Delimits a typed code quotation. - /// (Originally from ../FSComp.txt:1413) + /// (Originally from ..\FSComp.txt:1413) static member keywordDescriptionTypedQuotation() = (GetStringFunc("keywordDescriptionTypedQuotation",",,,") ) /// Delimits a untyped code quotation. - /// (Originally from ../FSComp.txt:1414) + /// (Originally from ..\FSComp.txt:1414) static member keywordDescriptionUntypedQuotation() = (GetStringFunc("keywordDescriptionUntypedQuotation",",,,") ) /// %s '%s' not found in assembly '%s'. A possible cause may be a version incompatibility. You may need to explicitly reference the correct version of this assembly to allow all referenced components to use the correct version. - /// (Originally from ../FSComp.txt:1415) + /// (Originally from ..\FSComp.txt:1415) static member itemNotFoundDuringDynamicCodeGen(a0 : System.String, a1 : System.String, a2 : System.String) = (3216, GetStringFunc("itemNotFoundDuringDynamicCodeGen",",,,%s,,,%s,,,%s,,,") a0 a1 a2) /// %s '%s' not found in type '%s' from assembly '%s'. A possible cause may be a version incompatibility. You may need to explicitly reference the correct version of this assembly to allow all referenced components to use the correct version. - /// (Originally from ../FSComp.txt:1416) + /// (Originally from ..\FSComp.txt:1416) static member itemNotFoundInTypeDuringDynamicCodeGen(a0 : System.String, a1 : System.String, a2 : System.String, a3 : System.String) = (3216, GetStringFunc("itemNotFoundInTypeDuringDynamicCodeGen",",,,%s,,,%s,,,%s,,,%s,,,") a0 a1 a2 a3) /// is - /// (Originally from ../FSComp.txt:1417) + /// (Originally from ..\FSComp.txt:1417) static member descriptionWordIs() = (GetStringFunc("descriptionWordIs",",,,") ) /// This value is not a function and cannot be applied. - /// (Originally from ../FSComp.txt:1418) + /// (Originally from ..\FSComp.txt:1418) static member notAFunction() = (GetStringFunc("notAFunction",",,,") ) /// This value is not a function and cannot be applied. Did you intend to access the indexer via %s.[index] instead? - /// (Originally from ../FSComp.txt:1419) + /// (Originally from ..\FSComp.txt:1419) static member notAFunctionButMaybeIndexerWithName(a0 : System.String) = (GetStringFunc("notAFunctionButMaybeIndexerWithName",",,,%s,,,") a0) /// This expression is not a function and cannot be applied. Did you intend to access the indexer via expr.[index] instead? - /// (Originally from ../FSComp.txt:1420) + /// (Originally from ..\FSComp.txt:1420) static member notAFunctionButMaybeIndexer() = (GetStringFunc("notAFunctionButMaybeIndexer",",,,") ) /// - /// (Originally from ../FSComp.txt:1421) + /// (Originally from ..\FSComp.txt:1421) static member notAFunctionButMaybeIndexerErrorCode() = (3217, GetStringFunc("notAFunctionButMaybeIndexerErrorCode",",,,") ) /// This value is not a function and cannot be applied. Did you forget to terminate a declaration? - /// (Originally from ../FSComp.txt:1422) + /// (Originally from ..\FSComp.txt:1422) static member notAFunctionButMaybeDeclaration() = (GetStringFunc("notAFunctionButMaybeDeclaration",",,,") ) /// The argument names in the signature '%s' and implementation '%s' do not match. The argument name from the signature file will be used. This may cause problems when debugging or profiling. - /// (Originally from ../FSComp.txt:1423) + /// (Originally from ..\FSComp.txt:1423) static member ArgumentsInSigAndImplMismatch(a0 : System.String, a1 : System.String) = (3218, GetStringFunc("ArgumentsInSigAndImplMismatch",",,,%s,,,%s,,,") a0 a1) /// An error occurred while reading the F# metadata of assembly '%s'. A reserved construct was utilized. You may need to upgrade your F# compiler or use an earlier version of the assembly that doesn't make use of a specific construct. - /// (Originally from ../FSComp.txt:1424) + /// (Originally from ..\FSComp.txt:1424) static member pickleUnexpectedNonZero(a0 : System.String) = (3219, GetStringFunc("pickleUnexpectedNonZero",",,,%s,,,") a0) /// This method or property is not normally used from F# code, use an explicit tuple pattern for deconstruction instead. - /// (Originally from ../FSComp.txt:1425) + /// (Originally from ..\FSComp.txt:1425) static member tcTupleMemberNotNormallyUsed() = (3220, GetStringFunc("tcTupleMemberNotNormallyUsed",",,,") ) /// 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'. - /// (Originally from ../FSComp.txt:1426) + /// (Originally from ..\FSComp.txt:1426) static member implicitlyDiscardedInSequenceExpression(a0 : System.String) = (3221, GetStringFunc("implicitlyDiscardedInSequenceExpression",",,,%s,,,") a0) /// 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!'. - /// (Originally from ../FSComp.txt:1427) + /// (Originally from ..\FSComp.txt:1427) static member implicitlyDiscardedSequenceInSequenceExpression(a0 : System.String) = (3222, GetStringFunc("implicitlyDiscardedSequenceInSequenceExpression",",,,%s,,,") a0) /// The file '%s' changed on disk unexpectedly, please reload. - /// (Originally from ..\FSComp.txt:1427) + /// (Originally from ..\FSComp.txt:1428) static member ilreadFileChanged(a0 : System.String) = (3223, GetStringFunc("ilreadFileChanged",",,,%s,,,") a0) /// The byref pointer is readonly, so this write is not permitted. - /// (Originally from ..\FSComp.txt:1428) + /// (Originally from ..\FSComp.txt:1429) static member writeToReadOnlyByref() = (3224, GetStringFunc("writeToReadOnlyByref",",,,") ) /// A ReadOnly attribute has been applied to a struct type with a mutable field. - /// (Originally from ..\FSComp.txt:1429) + /// (Originally from ..\FSComp.txt:1430) static member readOnlyAttributeOnStructWithMutableField() = (3225, GetStringFunc("readOnlyAttributeOnStructWithMutableField",",,,") ) + /// 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)'. + /// (Originally from ..\FSComp.txt:1431) + static member tcByrefReturnImplicitlyDereferenced() = (3226, GetStringFunc("tcByrefReturnImplicitlyDereferenced",",,,") ) /// Call this method once to validate that all known resources are valid; throws if not static member RunStartupValidation() = @@ -5722,4 +5725,5 @@ type internal SR private() = ignore(GetString("ilreadFileChanged")) ignore(GetString("writeToReadOnlyByref")) ignore(GetString("readOnlyAttributeOnStructWithMutableField")) + ignore(GetString("tcByrefReturnImplicitlyDereferenced")) () diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index 257f135fdb..cf98b7e13f 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -181,7 +181,7 @@ All branches of an 'if' expression must have the same type. This expression was expected to have type '{0}', but here has type '{1}'. - 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}'. + 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}'. A pattern match guard must be of type 'bool', but this 'when' expression is of type '{0}'. @@ -4321,4 +4321,7 @@ A ReadOnly attribute has been applied to a struct type with a mutable field. + + 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)'. + \ No newline at end of file diff --git a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl index da7df92104..f295dc0d47 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_22.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_22.bsl @@ -1,4 +1,6 @@ +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' but here has type From 36e59ab42b070d6155a48ecd6e558d1cfcc332cf Mon Sep 17 00:00:00 2001 From: Don Syme Date: Fri, 1 Jun 2018 14:54:09 +0100 Subject: [PATCH 50/61] fix baselines --- tests/service/ExprTests.fs | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 2770265abf..f2e0819310 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -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 (compiledAsStaticField,let x: Microsoft.FSharp.Core.int = compiledAsStaticField in ClassWithImplicitConstructor.compiledAsGenericStaticMethod (x)) @ (57,26--57,101)"; "member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)"; - //"member ToString(__) (unitVar1) = Operators.op_Addition (base.ToString(),Operators.ToString (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 (x) @ (102,40--102,52)"; - //"let functionWithCoercion(x) = Operators.op_PipeRight (Operators.op_PipeRight (IntrinsicFunctions.UnboxGeneric (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 (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 (888) } @ (114,3--114,55)"; - //"let functionThatUsesObjectExpressionWithInterfaceImpl(unitVar0) = { new Object() with member x.ToString(unitVar1) = Operators.ToString (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>> (x,y) @ (122,70--122,75)"; - "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &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 (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress,false,ILArrayShape [(Some 0, None)],TypeVar 0us)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (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 = x in let y2: Microsoft.FSharp.Core.byref = &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 (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress,false,ILArrayShapeFIX,!0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (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 (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 = &dt2 in let dt7: System.TimeSpan = Operators.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 (x,100) do x <- Operators.op_Addition (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 (compiledAsStaticField,ClassWithImplicitConstructor.compiledAsGenericStaticMethod (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 (value) in match (if Operators.op_Equality (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 (x) in match (if Operators.op_Equality (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 (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 (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 (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 (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 (value) in match (if Operators.op_Equality (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 (value) in match (if Operators.op_Equality (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 (x) in match (if Operators.op_Equality (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 (x) in match (if Operators.op_Equality (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>> (x,y) @ (122,70--122,75)"; - "let testFunctionThatUsesAddressesAndByrefs(x) = let mutable w: Microsoft.FSharp.Core.int = 4 in let y1: Microsoft.FSharp.Core.byref = x in let y2: Microsoft.FSharp.Core.byref = &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 (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress,false,ILArrayShapeFIX,TypeVar 0us)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (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 = x in let y2: Microsoft.FSharp.Core.byref = &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 (3) in let y3: Microsoft.FSharp.Core.byref = [I_ldelema (NormalAddress,false,ILArrayShapeFIX,!0)](arr,0) in let y4: Microsoft.FSharp.Core.byref = &r.contents in let z: Microsoft.FSharp.Core.int = Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (x,y1),y2),y3) in (w <- 3; (x <- 4; (y2 <- 4; (y3 <- 5; Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (Operators.op_Addition (z,x),y1),y2),y3),y4),IntrinsicFunctions.GetArray (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 = &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 (x,100) do x <- Operators.op_Addition (x,1) done; x) @ (152,15--152,16)"; From 2e36e588ddbf6f169840897e13a12596be2c351c Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 2 Jun 2018 15:33:02 +0100 Subject: [PATCH 51/61] updates for new test cases --- src/absil/illib.fs | 7 + .../FSharp.Compiler.Private/FSComp.fs | 2 +- .../FSharp.Compiler.Private/FSComp.resx | 2 +- src/fsharp/FSComp.txt | 5 +- src/fsharp/PostInferenceChecks.fs | 721 ++++++++++-------- src/fsharp/TastOps.fs | 17 +- src/fsharp/TastOps.fsi | 1 + src/fsharp/xlf/FSComp.txt.cs.xlf | 19 +- src/fsharp/xlf/FSComp.txt.de.xlf | 19 +- src/fsharp/xlf/FSComp.txt.en.xlf | 19 +- src/fsharp/xlf/FSComp.txt.es.xlf | 19 +- src/fsharp/xlf/FSComp.txt.fr.xlf | 19 +- src/fsharp/xlf/FSComp.txt.it.xlf | 19 +- src/fsharp/xlf/FSComp.txt.ja.xlf | 19 +- src/fsharp/xlf/FSComp.txt.ko.xlf | 19 +- src/fsharp/xlf/FSComp.txt.pl.xlf | 19 +- src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 19 +- src/fsharp/xlf/FSComp.txt.ru.xlf | 19 +- src/fsharp/xlf/FSComp.txt.tr.xlf | 19 +- src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 19 +- src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 19 +- tests/fsharp/core/span/test.fsx | 46 ++ tests/fsharp/typecheck/sigs/neg63.bsl | 4 +- tests/fsharp/typecheck/sigs/neg_byref_7.bsl | 2 +- 24 files changed, 720 insertions(+), 353 deletions(-) diff --git a/src/absil/illib.fs b/src/absil/illib.fs index 2050634f7b..627b5151ec 100644 --- a/src/absil/illib.fs +++ b/src/absil/illib.fs @@ -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 diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index ab6e1ba319..9aa6f5a554 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -4027,7 +4027,7 @@ type internal SR private() = /// Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression. /// (Originally from ..\FSComp.txt:1333) static member tcCouldNotFindOffsetToStringData() = (3208, GetStringFunc("tcCouldNotFindOffsetToStringData",",,,") ) - /// The address of the variable '%s' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . + /// The address of the variable '%s' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not escape its scope. /// (Originally from ..\FSComp.txt:1334) static member chkNoByrefReturnOfLocal(a0 : System.String) = (3209, GetStringFunc("chkNoByrefReturnOfLocal",",,,%s,,,") a0) /// %s is an active pattern and cannot be treated as a discriminated union case with named fields. diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index cf98b7e13f..089ac330cd 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -4030,7 +4030,7 @@ Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression. - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . + The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not escape its scope. {0} is an active pattern and cannot be treated as a discriminated union case with named fields. diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 1675c1702c..4c3edcecaa 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -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. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. ." +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" @@ -1429,3 +1429,6 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 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." +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 ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope." diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 48b6e10097..aeb688f7f7 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -40,51 +40,6 @@ let testHookMemberBody (membInfo: ValMemberInfo) (expr:Expr) = m.EndLine m.EndColumn -//-------------------------------------------------------------------------- -// NOTES: byref safety checks -// -// The .NET runtime has safety requirements on the use of byrefs. -// These include: -// A1: No generic type/method can be instantiated with byref types (meaning contains byref type). -// A2: No object field may be byref typed. -// -// In F# TAST level, byref types can be introduced/consumed at: -// B1: lambda ... (v:byref) ... -- binding sites for values. -// B2: &m -- address of operator, where m is local mutable or reference cell. -// B3: ms.M() -- method calls on mutable structs. -// B4: *br -- dereference byref -// B5: br <- x -- assign byref -// B6: expr@[byrefType] -- any type instantiation could introduce byref types. -// B7: asm -- TExpr_asm forms that create/consume byrefs. -// a) I_ldfld expr -// b) I_stfld -// -// Closures imply objects. -// Closures are either: -// a) explicit lambda expressions. -// b) functions partially applied below their known arity. -// -// Checks: -// C1: check no instantiation can contain byref types. -// C2: check type declarations to ensure no object field will have byref type. -// C3: check no explicit lambda expressions capture any free byref typed expression. -// C4: check byref type expr occur only as: -// C4.a) arg to functions occurring within their known arity. -// C4.b) arg to IL method calls, e.g. arising from calls to instance methods on mutable structs. -// C4.c) arg to property getter on mutable struct (record field projection) -// C4.d) rhs of byref typed binding (aliasing). -// Note [1] aliasing should not effect safety. The restrictions on RHS byref will also apply to alias. -// Note [2] aliasing happens in the generated hash/compare code. -// C5: when is a byref-typed-binding acceptable? -// a) if it will be a method local, ok. -// b) if it will be a top-level value stored as a field, then no. [These should have arity info]. -// -// Check commentary: -// The C4 checks ensure byref expressions are only passed directly as method arguments (or aliased). -// The C3 check ensures byref expressions are never captured, e.g. passed as direct method arg under a capturing thunk. -// The C2 checks no type can store byrefs (C4 ensures F# code would never actually store them). -// The C1 checks no generic type could be instanced to store byrefs. - //-------------------------------------------------------------------------- // NOTES: reraise safety checks //-------------------------------------------------------------------------- @@ -130,7 +85,7 @@ type env = /// "module remap info", i.e. hiding information down the signature chain, used to compute what's hidden by a signature sigToImplRemapInfo: (Remap * SignatureHidingInfo) list /// Constructor limited - are we in the prelude of a constructor, prior to object initialization - limited: bool + ctorLimitedZone: bool /// Are we in a quotation? quote : bool /// Are we under []? @@ -155,11 +110,12 @@ let BindTypars g env (tps:Typar list) = /// Set the set of vals which are arguments in the active lambda. We are allowed to return /// byref arguments as byref returns. -let SetArgVals env (vs: Val list) = +let BindArgVals env (vs: Val list) = { env with argVals = ValMap.OfList (List.map (fun v -> (v,())) vs) } type cenv = { boundVals: Dictionary // really a hash set + limitVals: Dictionary // really a hash set mutable potentialUnboundUsesOfVals: StampMap g: TcGlobals amap: Import.ImportMap @@ -174,6 +130,9 @@ type cenv = mutable usesQuotations : bool mutable entryPointGiven:bool } +let LimitVal cenv (v:Val) = + cenv.limitVals.[v.Stamp] <- 1 + let BindVal cenv env (v:Val) = //printfn "binding %s..." v.DisplayName let alreadyDone = cenv.boundVals.ContainsKey v.Stamp @@ -246,7 +205,8 @@ let rec CheckTypeDeep ((visitTyp,visitTyconRefOpt,visitAppTyOpt,visitTraitSoluti | Some visitTypar -> visitTypar (env,tp) -and CheckTypesDeep f g env tys = List.iter (CheckTypeDeep f g env true) tys +and CheckTypesDeep f g env tys = + tys |> List.iter (CheckTypeDeep f g env true) and CheckTypeConstraintDeep f g env x = match x with @@ -263,6 +223,7 @@ and CheckTypeConstraintDeep f g env x = | TyparConstraint.IsUnmanaged _ | TyparConstraint.IsReferenceType _ | TyparConstraint.RequiresDefaultConstructor _ -> () + and CheckTraitInfoDeep ((_,_,_,visitTraitSolutionOpt,_) as f) g env (TTrait(typs,_,_,argtys,rty,soln)) = CheckTypesDeep f g env typs CheckTypesDeep f g env argtys @@ -271,18 +232,13 @@ and CheckTraitInfoDeep ((_,_,_,visitTraitSolutionOpt,_) as f) g env (TTrait(typs | Some visitTraitSolution, Some sln -> visitTraitSolution sln | _ -> () -//-------------------------------------------------------------------------- -// check for byref types -//-------------------------------------------------------------------------- - +/// Check for byref types let CheckForByrefLikeType cenv env m typ check = CheckTypeDeep (ignore, Some (fun _deep tcref -> if isByrefLikeTyconRef cenv.g m tcref then check()), None, None, None) cenv.g env false typ -//-------------------------------------------------------------------------- -// check captures under lambdas -//-------------------------------------------------------------------------- - +/// check captures under lambdas +/// /// This is the definition of what can/can't be free in a lambda expression. This is checked at lambdas OR TBind(v,e) nodes OR TObjExprMethod nodes. /// For TBind(v,e) nodes we may know an 'arity' which gives as a larger set of legitimate syntactic arguments for a lambda. /// For TObjExprMethod(v,e) nodes we always know the legitimate syntactic arguments. @@ -325,16 +281,13 @@ let CheckEscapes cenv allowProtected m syntacticArgs body = (* m is a range suit None -//-------------------------------------------------------------------------- -// check type access -//-------------------------------------------------------------------------- - +/// Check type access let AccessInternalsVisibleToAsInternal thisCompPath internalsVisibleToPaths access = - // Each internalsVisibleToPath is a compPath for the internals of some assembly. - // Replace those by the compPath for the internals of this assembly. - // This makes those internals visible here, but still internal. Bug://3737 - (access,internalsVisibleToPaths) ||> List.fold (fun access internalsVisibleToPath -> - accessSubstPaths (thisCompPath,internalsVisibleToPath) access) + // Each internalsVisibleToPath is a compPath for the internals of some assembly. + // Replace those by the compPath for the internals of this assembly. + // This makes those internals visible here, but still internal. Bug://3737 + (access,internalsVisibleToPaths) ||> List.fold (fun access internalsVisibleToPath -> + accessSubstPaths (thisCompPath,internalsVisibleToPath) access) let CheckTypeForAccess (cenv:cenv) env objName valAcc m ty = @@ -371,15 +324,81 @@ let WarnOnWrongTypeForAccess (cenv:cenv) env objName valAcc m ty = CheckTypeDeep (visitType, None, None, None, None) cenv.g env false ty -//-------------------------------------------------------------------------- -// check type instantiations -//-------------------------------------------------------------------------- +/// Indicates whether a byref or byref-like type is permitted at a particular location +[] +type PermitByRefType = + /// Don't permit any byref or byref-like types + | None + + /// Permit only an outermost Span or IsByRefLike type + | OuterSpanLike + + /// Permit only an outermost Span, IsByRefLike, inref, outref or byref type + | OuterByRefLike + /// Permit all byref and byref-like types + | All + + +/// Indicates whether an address-of operation is permitted at a particular location [] -type PermitByrefs = None | Outer | All +type PermitByRefExpr = + /// Permit a tuple of arguments where elements can be byrefs + | YesTupleOfArgs of int + + /// Context allows for byref typed expr. + | Yes + + /// Context allows for byref typed expr, but the byref must be returnable + | YesReturnable + + /// General (address-of expr and byref values not allowed) + | No + + member context.Disallow = + match context with + | PermitByRefExpr.Yes + | PermitByRefExpr.YesReturnable -> false + | _ -> true + + member context.PermitOnlyReturnable = + match context with + | PermitByRefExpr.YesReturnable -> true + | _ -> false + +let ignoreLimit (_limit: bool) = () + +let mkArgsPermit isByRefReturnCall n = + if n=1 then + if isByRefReturnCall then PermitByRefExpr.YesReturnable else PermitByRefExpr.Yes + else PermitByRefExpr.YesTupleOfArgs n + +/// Work out what byref-values are allowed at input positions to named F# functions or members +let mkArgsForAppliedVal isBaseCall isByRefReturnCall (vref:ValRef) argsl = + match vref.ValReprInfo with + | Some topValInfo -> + let argArities = topValInfo.AritiesOfArgs + let argArities = if isBaseCall && argArities.Length >= 1 then List.tail argArities else argArities + // Check for partial applications: arguments to partial applciations don't get to use byrefs + if List.length argsl >= argArities.Length then + List.map (mkArgsPermit isByRefReturnCall) argArities + else + [] + | None -> [] + +/// Work out what byref-values are allowed at input positions to functions +let rec mkArgsForAppliedExpr isBaseCall isByRefReturnCall argsl x = + match stripExpr x with + // recognise val + | Expr.Val (vref,_,_) -> mkArgsForAppliedVal isBaseCall isByRefReturnCall vref argsl + // step through instantiations + | Expr.App(f,_fty,_tyargs,[],_) -> mkArgsForAppliedExpr isBaseCall isByRefReturnCall argsl f + // step through subsumption coercions + | Expr.Op(TOp.Coerce,_,[f],_) -> mkArgsForAppliedExpr isBaseCall isByRefReturnCall argsl f + | _ -> [] /// Check types occurring in the TAST. -let CheckType permitByrefs (cenv:cenv) env m ty = +let CheckType permitByRefLike (cenv:cenv) env m ty = if cenv.reportErrors then let visitTypar (env,tp) = if not (env.boundTypars.ContainsKey tp) then @@ -389,8 +408,16 @@ let CheckType permitByrefs (cenv:cenv) env m ty = errorR (Error(FSComp.SR.checkNotSufficientlyGenericBecauseOfScope(tp.DisplayName),m)) let visitTyconRef isInner tcref = - if (permitByrefs = PermitByrefs.None || permitByrefs = PermitByrefs.Outer && isInner) && isByrefLikeTyconRef cenv.g m tcref then + + match permitByRefLike with + | PermitByRefType.None when isByrefLikeTyconRef cenv.g m tcref -> + errorR(Error(FSComp.SR.chkErrorUseOfByref(), m)) + | PermitByRefType.OuterSpanLike when isInner && isByrefTyconRef cenv.g tcref -> + errorR(Error(FSComp.SR.chkErrorUseOfByref(), m)) + | PermitByRefType.OuterByRefLike when isInner && isByrefLikeTyconRef cenv.g m tcref -> errorR(Error(FSComp.SR.chkErrorUseOfByref(), m)) + | _ -> () + if tyconRefEq cenv.g cenv.g.system_Void_tcref tcref then errorR(Error(FSComp.SR.chkSystemVoidOnlyInTypeof(), m)) @@ -401,7 +428,7 @@ let CheckType permitByrefs (cenv:cenv) env m ty = match tryDestAppTy cenv.g ty0 with | None -> () | Some tcref -> - if isByrefLikeTyconRef cenv.g m tcref then + if isByrefTyconRef cenv.g tcref then errorR(Error(FSComp.SR.chkNoByrefsOfByrefs(NicePrint.minimalStringOfType cenv.denv ty), m)) CheckTypesDeep (visitType, None, None, None, None) cenv.g env tinst @@ -419,13 +446,16 @@ let CheckType permitByrefs (cenv:cenv) env m ty = /// Check types occurring in TAST (like CheckType) and additionally reject any byrefs. /// The additional byref checks are to catch "byref instantiations" - one place were byref are not permitted. -let CheckTypeNoByrefs (cenv:cenv) env m ty = CheckType PermitByrefs.None cenv env m ty +let CheckTypeNoByrefs (cenv:cenv) env m ty = CheckType PermitByRefType.None cenv env m ty /// Check types occurring in TAST but allow an outer byref. -let CheckTypePermitOuterByref (cenv:cenv) env m ty = CheckType PermitByrefs.Outer cenv env m ty +let CheckTypePermitOuterByRefLike (cenv:cenv) env m ty = CheckType PermitByRefType.OuterByRefLike cenv env m ty + +/// Check types occurring in TAST but allow an outer Span or similar +let CheckTypePermitOuterSpanLike (cenv:cenv) env m ty = CheckType PermitByRefType.OuterSpanLike cenv env m ty /// Check types occurring in TAST but allow all byrefs. Only used on internally-generated types -let CheckTypePermitAllByrefs (cenv:cenv) env m ty = CheckType PermitByrefs.All cenv env m ty +let CheckTypePermitAllByrefs (cenv:cenv) env m ty = CheckType PermitByRefType.All cenv env m ty let CheckTypeInstNoByrefs cenv env m tyargs = tyargs |> List.iter (CheckTypeNoByrefs cenv env m) @@ -433,51 +463,6 @@ let CheckTypeInstNoByrefs cenv env m tyargs = let CheckTypeInstPermitAllByrefs cenv env m tyargs = tyargs |> List.iter (CheckTypePermitAllByrefs cenv env m) - -//-------------------------------------------------------------------------- -// check exprs etc -//-------------------------------------------------------------------------- - -type ByrefContext = - /// Tuple of arguments where elements can be byrefs - | TupleOfArgsPermitByrefs of int - /// Context allows for byref typed expr. Flag indicates if this is a byref-return position - | PermitByref of isReturn: bool - /// General (byref type expr not allowed) - | NoByrefs - -let noByrefs context = match context with PermitByref _ -> false | _ -> true - -let mkArgsPermitByrefs isByrefReturnCall n = - if n=1 then PermitByref isByrefReturnCall - else TupleOfArgsPermitByrefs n - -/// Work out what byref-values are allowed at input positions to named F# functions or members -let mkArgsForAppliedVal isBaseCall isByrefReturnCall (vref:ValRef) argsl = - match vref.ValReprInfo with - | Some topValInfo -> - let argArities = topValInfo.AritiesOfArgs - let argArities = if isBaseCall && argArities.Length >= 1 then List.tail argArities else argArities - // Check for partial applications: arguments to partial applciations don't get to use byrefs - if List.length argsl >= argArities.Length then - List.map (mkArgsPermitByrefs isByrefReturnCall) argArities - else - [] - | None -> [] - -/// Work out what byref-values are allowed at input positions to functions -let rec mkArgsForAppliedExpr isBaseCall isByrefReturnCall argsl x = - match x with - // recognise val - | Expr.Val (vref,_,_) -> mkArgsForAppliedVal isBaseCall isByrefReturnCall vref argsl - // step through reclink - | Expr.Link eref -> mkArgsForAppliedExpr isBaseCall isByrefReturnCall argsl !eref - // step through instantiations - | Expr.App(f,_fty,_tyargs,[],_) -> mkArgsForAppliedExpr isBaseCall isByrefReturnCall argsl f - // step through subsumption coercions - | Expr.Op(TOp.Coerce,_,[f],_) -> mkArgsForAppliedExpr isBaseCall isByrefReturnCall argsl f - | _ -> [] - /// Applied functions get wrapped in coerce nodes for subsumption coercions let (|OptionalCoerce|) = function | Expr.Op(TOp.Coerce _, _, [Expr.App(f, _, _, [], _)], _) -> f @@ -513,66 +498,97 @@ let CheckMultipleInterfaceInstantiations cenv interfaces m = errorR(Error(FSComp.SR.chkMultipleGenericInterfaceInstantiations((NicePrint.minimalStringOfType cenv.denv typ1), (NicePrint.minimalStringOfType cenv.denv typ2)),m)) /// Check an expression, where the expression is in a position where byrefs can be generated -let rec CheckExprNoByrefs (cenv:cenv) (env:env) expr = - CheckExpr cenv env expr NoByrefs +let rec CheckExprNoByrefs cenv env expr = + CheckExpr cenv env expr PermitByRefExpr.No |> ignoreLimit /// Check a value -and CheckVal (cenv:cenv) (env:env) v m context = +and CheckVal (cenv:cenv) (env:env) v m (context: PermitByRefExpr) = + if cenv.reportErrors then if isSpliceOperator cenv.g v && not env.quote then errorR(Error(FSComp.SR.chkSplicingOnlyInQuotations(), m)) if isSpliceOperator cenv.g v then errorR(Error(FSComp.SR.chkNoFirstClassSplicing(), m)) if valRefEq cenv.g v cenv.g.addrof_vref then errorR(Error(FSComp.SR.chkNoFirstClassAddressOf(), m)) if valRefEq cenv.g v cenv.g.reraise_vref then errorR(Error(FSComp.SR.chkNoFirstClassRethrow(), m)) - if noByrefs context && isByrefLikeTy cenv.g m v.Type then - // byref typed val can only occur in permitting contexts + + // ByRefLike-typed values can only occur in permitting contexts + if context.Disallow && isByrefLikeTy cenv.g m v.Type then errorR(Error(FSComp.SR.chkNoByrefAtThisPoint(v.DisplayName), m)) + CheckTypePermitAllByrefs cenv env m v.Type // the byref checks are done at the actual binding of the value /// Check an expression, given information about the position of the expression -and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = +and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = + let g = cenv.g let expr = stripExpr expr match expr with | Expr.Sequential (e1,e2,dir,_,_) -> CheckExprNoByrefs cenv env e1 match dir with - | NormalSeq -> CheckExpr cenv env e2 context // carry context into _;RHS (normal sequencing only) - | ThenDoSeq -> CheckExprNoByrefs cenv {env with limited=false} e2 + | NormalSeq -> + CheckExpr cenv env e2 context // carry context into _;RHS (normal sequencing only) + | ThenDoSeq -> + CheckExprNoByrefs cenv {env with ctorLimitedZone=false} e2 + false | Expr.Let (bind,body,_,_) -> - CheckBinding cenv env false bind + let limit = CheckBinding cenv env false bind BindVal cenv env bind.Var + if limit then + LimitVal cenv bind.Var CheckExpr cenv env body context | Expr.Const (_,m,ty) -> - CheckTypePermitOuterByref cenv env m ty + CheckTypePermitOuterByRefLike cenv env m ty + false | Expr.Val (v,vFlags,m) -> - if cenv.reportErrors then - if v.BaseOrThisInfo = BaseVal then + + // Is this a Span-typed value that is limited (i.e. can't be returned) + let limit = + isByrefLikeTy g m v.Type && + not (isByrefTy g v.Type) && + // The value is a local.... + v.ValReprInfo.IsNone && + // The value is a non-argument byref or is a ctorLimitedZone Span + cenv.limitVals.ContainsKey(v.Stamp) + + if cenv.reportErrors then + + if v.BaseOrThisInfo = BaseVal then errorR(Error(FSComp.SR.chkLimitationsOfBaseKeyword(), m)) - if (match vFlags with NormalValUse -> true | _ -> false) && - v.IsConstructor && - (match v.DeclaringEntity with Parent tcref -> isAbstractTycon tcref.Deref | _ -> false) then + + let isCallOfConstructorOfAbstractType = + (match vFlags with NormalValUse -> true | _ -> false) && + v.IsConstructor && + (match v.DeclaringEntity with Parent tcref -> isAbstractTycon tcref.Deref | _ -> false) + + if isCallOfConstructorOfAbstractType then errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(),m)) - if isByrefLikeTy cenv.g m v.Type && - // A byref return location... - (match context with PermitByref isReturn -> isReturn | _ -> false) && - // The value is a local.... - v.ValReprInfo.IsNone && - // The value is not an argument... - not (env.argVals.ContainsVal(v.Deref)) then + let isReturnExprBuiltUsingByRefLocal = + isByrefTy g v.Type && + context.PermitOnlyReturnable && + // The value is a local.... + v.ValReprInfo.IsNone && + // The value is not an argument.... + not (env.argVals.ContainsVal(v.Deref)) + + if isReturnExprBuiltUsingByRefLocal then errorR(Error(FSComp.SR.chkNoByrefReturnOfLocal(v.DisplayName), m)) - CheckVal cenv env v m context + CheckVal cenv env v m context + limit | Expr.Quote(ast,savedConv,_isFromQueryExpression,m,ty) -> CheckExprNoByrefs cenv {env with quote=true} ast + if cenv.reportErrors then cenv.usesQuotations <- true + + // Translate to quotation data try - let qscope = QuotationTranslator.QuotationGenerationScope.Create (cenv.g,cenv.amap,cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.No) + let qscope = QuotationTranslator.QuotationGenerationScope.Create (g,cenv.amap,cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.No) let qdata = QuotationTranslator.ConvExprPublic qscope QuotationTranslator.QuotationTranslationEnv.Empty ast let typeDefs,spliceTypes,spliceExprs = qscope.Close() match savedConv.Value with @@ -582,31 +598,36 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = errorRecovery e m CheckTypeNoByrefs cenv env m ty + false | Expr.Obj (_,typ,basev,superInitCall,overrides,iimpls,m) -> - CheckExprNoByrefs cenv env superInitCall - CheckMethods cenv env basev overrides - CheckInterfaceImpls cenv env basev iimpls - CheckTypeNoByrefs cenv env m typ - let interfaces = - [ if isInterfaceTy cenv.g typ then - yield! AllSuperTypesOfType cenv.g cenv.amap m AllowMultiIntfInstantiations.Yes typ - for (ty,_) in iimpls do - yield! AllSuperTypesOfType cenv.g cenv.amap m AllowMultiIntfInstantiations.Yes ty ] - |> List.filter (isInterfaceTy cenv.g) - CheckMultipleInterfaceInstantiations cenv interfaces m + CheckExprNoByrefs cenv env superInitCall + CheckMethods cenv env basev overrides + CheckInterfaceImpls cenv env basev iimpls + CheckTypeNoByrefs cenv env m typ + + let interfaces = + [ if isInterfaceTy g typ then + yield! AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes typ + for (ty,_) in iimpls do + yield! AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes ty ] + |> List.filter (isInterfaceTy g) + + CheckMultipleInterfaceInstantiations cenv interfaces m + false // Allow base calls to F# methods | Expr.App((InnerExprPat(ExprValWithPossibleTypeInst(v,vFlags,_,_) as f)),_fty,tyargs,(Expr.Val(baseVal,_,_) :: rest),m) when ((match vFlags with VSlotDirectCall -> true | _ -> false) && baseVal.BaseOrThisInfo = BaseVal) -> - // dprintfn "GOT BASE VAL USE" + let memberInfo = Option.get v.MemberInfo if memberInfo.MemberFlags.IsDispatchSlot then errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(v.DisplayName),m)) + false else - CheckVal cenv env v m NoByrefs - CheckVal cenv env baseVal m NoByrefs + CheckVal cenv env v m PermitByRefExpr.No + CheckVal cenv env baseVal m PermitByRefExpr.No CheckTypeInstNoByrefs cenv env m tyargs CheckExprs cenv env rest (mkArgsForAppliedExpr true false rest f) @@ -615,7 +636,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = when not virt && baseVal.BaseOrThisInfo = BaseVal -> // Disallow calls to abstract base methods on IL types. - match tryDestAppTy cenv.g baseVal.Type with + match tryDestAppTy g baseVal.Type with | Some tcref when tcref.IsILTycon -> try // This is awkward - we have to explicitly re-resolve back to the IL metadata to determine if the method is abstract. @@ -627,31 +648,38 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(mdef.Name),m)) with _ -> () // defensive coding | _ -> () + CheckTypeInstNoByrefs cenv env m tyargs CheckTypeInstNoByrefs cenv env m enclTypeArgs CheckTypeInstNoByrefs cenv env m methTypeArgs CheckTypeInstNoByrefs cenv env m tys - CheckVal cenv env baseVal m NoByrefs - CheckExprsPermitByrefs cenv env rest + CheckVal cenv env baseVal m PermitByRefExpr.No + CheckExprsPermitByRefLike cenv env rest | Expr.Op (c,tyargs,args,m) -> CheckExprOp cenv env (c,tyargs,args,m) context expr // Allow 'typeof' calls as a special case, the only accepted use of System.Void! - | TypeOfExpr cenv.g ty when isVoidTy cenv.g ty -> - () // typeof allowed. Special case. No further checks. + | TypeOfExpr g ty when isVoidTy g ty -> + false - | TypeDefOfExpr cenv.g ty when isVoidTy cenv.g ty -> - () // typedefof allowed. Special case. No further checks. + // Allow 'typedefof' calls as a special case, the only accepted use of System.Void! + | TypeDefOfExpr g ty when isVoidTy g ty -> + false // Allow '%expr' in quotations - | Expr.App(Expr.Val(vref,_,_),_,tinst,[arg],m) when isSpliceOperator cenv.g vref && env.quote -> + | Expr.App(Expr.Val(vref,_,_),_,tinst,[arg],m) when isSpliceOperator g vref && env.quote -> CheckTypeInstPermitAllByrefs cenv env m tinst // it's the splice operator, a byref instantiation is allowed CheckExprNoByrefs cenv env arg + false + // Check an application | Expr.App(f,_fty,tyargs,argsl,m) -> + if cenv.reportErrors then - let g = cenv.g + + // Special diagnostics for `raise`, `failwith`, `failwithf`, `nullArg`, `invalidOp` library intrinsics commonly used to raise exceptions + // to warn on over-application. match f with | OptionalCoerce(Expr.Val(v, _, funcRange)) when (valRefEq g v g.raise_vref || valRefEq g v g.failwith_vref || valRefEq g v g.null_arg_vref || valRefEq g v g.invalid_op_vref) -> @@ -659,11 +687,13 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = | [] | [_] -> () | _ :: _ :: _ -> warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 1, List.length argsl), funcRange)) + | OptionalCoerce(Expr.Val(v, _, funcRange)) when valRefEq g v g.invalid_arg_vref -> match argsl with | [] | [_] | [_; _] -> () | _ :: _ :: _ :: _ -> warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 2, List.length argsl), funcRange)) + | OptionalCoerce(Expr.Val(failwithfFunc, _, funcRange)) when valRefEq g failwithfFunc g.failwithf_vref -> match argsl with | Expr.App (Expr.Val(newFormat, _, _), _, [_; typB; typC; _; _], [Expr.Const(Const.String formatString, formatRange, _)], _) :: xs when valRefEq g newFormat g.new_format_vref -> @@ -681,14 +711,12 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = CheckTypeInstNoByrefs cenv env m tyargs CheckExprNoByrefs cenv env f - let isByrefReturnCall = - // if return is a byref, and being used as a return, then all arguments must be usable as byref returns - match context with - | PermitByref true when isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) -> true - | _ -> false - CheckExprs cenv env argsl (mkArgsForAppliedExpr false isByrefReturnCall argsl f) - - // REVIEW: fold the next two cases together + + // If return is a byref, and being used as a return, then all arguments must be usable as byref returns + let isByRefReturnCall = context.PermitOnlyReturnable && isByrefTy g (tyOfExpr g expr) + + CheckExprs cenv env argsl (mkArgsForAppliedExpr false isByRefReturnCall argsl f) + | Expr.Lambda(_,_ctorThisValOpt,_baseValOpt,argvs,_,m,rty) -> let topValInfo = ValReprInfo ([],[argvs |> List.map (fun _ -> ValReprInfo.unnamedTopArg1)],ValReprInfo.unnamedRetVal) let ty = mkMultiLambdaTy m argvs rty in @@ -700,8 +728,9 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = CheckLambdas false None cenv env false topValInfo false expr m ty | Expr.TyChoose(tps,e1,_) -> - let env = BindTypars cenv.g env tps + let env = BindTypars g env tps CheckExprNoByrefs cenv env e1 + false | Expr.Match(_,_,dtree,targets,m,ty) -> CheckTypePermitAllByrefs cenv env m ty // computed byrefs allowed at each branch @@ -712,6 +741,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = BindVals cenv env (valsOfBinds binds) CheckBindings cenv env binds CheckExprNoByrefs cenv env e + false | Expr.StaticOptimization (constraints,e2,e3,m) -> CheckExprNoByrefs cenv env e2 @@ -722,20 +752,24 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:ByrefContext) = CheckTypeNoByrefs cenv env m ty2 | TTyconIsStruct(ty1) -> CheckTypeNoByrefs cenv env m ty1) + false | Expr.Link _ -> failwith "Unexpected reclink" -and CheckMethods cenv env baseValOpt l = - l |> List.iter (CheckMethod cenv env baseValOpt) +and CheckMethods cenv env baseValOpt methods = + methods |> List.iter (CheckMethod cenv env baseValOpt) and CheckMethod cenv env baseValOpt (TObjExprMethod(_,attribs,tps,vs,body,m)) = let env = BindTypars cenv.g env tps let vs = List.concat vs + let env = BindArgVals env vs CheckAttribs cenv env attribs CheckNoReraise cenv None body CheckEscapes cenv true m (match baseValOpt with Some x -> x:: vs | None -> vs) body |> ignore - CheckExprPermitByref cenv env body + let limit = CheckExprPermitReturnableByRef cenv env body + if limit then + errorR(Error(FSComp.SR.chkNoReturnOfLimitedSpan(), body.Range)) and CheckInterfaceImpls cenv env baseValOpt l = l |> List.iter (CheckInterfaceImpl cenv env baseValOpt) @@ -745,31 +779,33 @@ and CheckInterfaceImpl cenv env baseValOpt (_ty,overrides) = and CheckExprOp cenv env (op,tyargs,args,m) context expr = let limitedCheck() = - if env.limited then errorR(Error(FSComp.SR.chkObjCtorsCantUseExceptionHandling(), m)) + if env.ctorLimitedZone then errorR(Error(FSComp.SR.chkObjCtorsCantUseExceptionHandling(), m)) (* Special cases *) match op,tyargs,args with // Handle these as special cases since mutables are allowed inside their bodies | TOp.While _,_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_)] -> CheckTypeInstNoByrefs cenv env m tyargs - CheckExprsNoByrefs cenv env [e1;e2] + CheckExprsNoByRefLike cenv env [e1;e2] | TOp.TryFinally _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],e2,_,_)] -> CheckTypeInstPermitAllByrefs cenv env m tyargs // result of a try/finally can be a byref limitedCheck() - CheckExpr cenv env e1 context // result of a try/finally can be a byref if in a position where the overall expression is can be a byref + let limit = CheckExpr cenv env e1 context // result of a try/finally can be a byref if in a position where the overall expression is can be a byref CheckExprNoByrefs cenv env e2 + limit | TOp.For(_),_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_);Expr.Lambda(_,_,_,[_],e3,_,_)] -> CheckTypeInstNoByrefs cenv env m tyargs - CheckExprsNoByrefs cenv env [e1;e2;e3] + CheckExprsNoByRefLike cenv env [e1;e2;e3] | TOp.TryCatch _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],_e2,_,_); Expr.Lambda(_,_,_,[_],e3,_,_)] -> CheckTypeInstPermitAllByrefs cenv env m tyargs // result of a try/catch can be a byref limitedCheck() - CheckExpr cenv env e1 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref + let limit1 = CheckExpr cenv env e1 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref // [(* e2; -- don't check filter body - duplicates logic in 'catch' body *) e3] - CheckExpr cenv env e3 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref + let limit2 = CheckExpr cenv env e3 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref + limit1 || limit2 | TOp.ILCall (_,_,_,_,_,_,_,_,enclTypeArgs,methTypeArgs,tys),_,_ -> CheckTypeInstNoByrefs cenv env m tyargs @@ -778,55 +814,57 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckTypeInstPermitAllByrefs cenv env m tys // permit byref returns // if return is a byref, and being used as a return, then all arguments must be usable as byref returns - match context,tys with - | PermitByref true, [ty] when isByrefLikeTy cenv.g m ty -> CheckExprsPermitByrefReturns cenv env args - | _ -> CheckExprsPermitByrefs cenv env args + match tys with + | [ty] when context.PermitOnlyReturnable && isByrefLikeTy cenv.g m ty -> CheckExprsPermitReturnableByRef cenv env args + | _ -> CheckExprsPermitByRefLike cenv env args | TOp.Tuple tupInfo,_,_ when not (evalTupInfoIsStruct tupInfo) -> match context with - | TupleOfArgsPermitByrefs nArity -> + | PermitByRefExpr.YesTupleOfArgs nArity -> if cenv.reportErrors then if args.Length <> nArity then errorR(InternalError("Tuple arity does not correspond to planned function argument arity",m)) // This tuple should not be generated. The known function arity // means it just bundles arguments. - CheckExprsPermitByrefs cenv env args + CheckExprsPermitByRefLike cenv env args | _ -> CheckTypeInstNoByrefs cenv env m tyargs - CheckExprsNoByrefs cenv env args + CheckExprsNoByRefLike cenv env args | TOp.LValueOp(LGetAddr _,v),_,_ -> if cenv.reportErrors then - if noByrefs context && cenv.reportErrors then + + if context.Disallow then errorR(Error(FSComp.SR.chkNoAddressOfAtThisPoint(v.DisplayName), m)) - elif (// The context is a byref return.... - match context with PermitByref isReturn -> isReturn | _ -> false) && - // The value is a local.... - v.ValReprInfo.IsNone && - // The value is not an argument... - not (env.argVals.ContainsVal(v.Deref)) then - errorR(Error(FSComp.SR.chkNoByrefReturnOfLocal(v.DisplayName), m)) + + let returningAddrOfLocal = + context.PermitOnlyReturnable && + // The value is a local.... + v.ValReprInfo.IsNone && + // The value is not an argument... + not (env.argVals.ContainsVal(v.Deref)) + + if returningAddrOfLocal then + errorR(Error(FSComp.SR.chkNoByrefAddressOfLocal(v.DisplayName), m)) - // Address-of operator generates byref, and context permits this. - CheckExprsNoByrefs cenv env args + CheckExprsNoByRefLike cenv env args | TOp.TupleFieldGet _,_,[arg1] -> CheckTypeInstNoByrefs cenv env m tyargs - CheckExprsPermitByrefs cenv env [arg1] (* Compiled pattern matches on immutable value structs come through here. *) + CheckExprsPermitByRefLike cenv env [arg1] (* Compiled pattern matches on immutable value structs come through here. *) | TOp.ValFieldGet _rf,_,[arg1] -> CheckTypeInstNoByrefs cenv env m tyargs //See mkRecdFieldGetViaExprAddr -- byref arg1 when #args =1 // Property getters on mutable structs come through here. - CheckExprsPermitByrefs cenv env [arg1] + CheckExprsPermitByRefLike cenv env [arg1] | TOp.ValFieldSet _rf,_,[arg1;arg2] -> CheckTypeInstNoByrefs cenv env m tyargs // See mkRecdFieldSetViaExprAddr -- byref arg1 when #args=2 // Field setters on mutable structs come through here - CheckExprsPermitByrefs cenv env [arg1] - CheckExprsNoByrefs cenv env [arg2] + CheckExprsPermitByRefLike cenv env [arg1; arg2] | TOp.Coerce,[_ty1;_ty2],[x] -> // Subsumption coercions of functions may involve byrefs in other argument positions @@ -834,75 +872,94 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExpr cenv env x context | TOp.Reraise,[_ty1],[] -> - CheckTypeInstNoByrefs cenv env m tyargs + CheckTypeInstNoByrefs cenv env m tyargs + false + // Check get of static field | TOp.ValFieldGetAddr (rfref, _readonly),tyargs,[] -> - if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + + if context.Disallow && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressStaticFieldAtThisPoint(rfref.FieldName), m)) + CheckTypeInstNoByrefs cenv env m tyargs - // NOTE: there are no arg exprs to check in this case + false + + // Check get of instance field + | TOp.ValFieldGetAddr (rfref, _readonly),tyargs,[obj] -> - | TOp.ValFieldGetAddr (rfref, _readonly),tyargs,[rx] -> - if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + if context.Disallow && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(rfref.FieldName), m)) + // This construct is used for &(rx.rfield) and &(rx->rfield). Relax to permit byref types for rx. [See Bug 1263]. CheckTypeInstNoByrefs cenv env m tyargs - CheckExprPermitByref cenv env rx + CheckExprPermitByRefLike cenv env obj | TOp.UnionCaseFieldGet _,_,[arg1] -> CheckTypeInstNoByrefs cenv env m tyargs - CheckExprPermitByref cenv env arg1 + CheckExprPermitByRefLike cenv env arg1 | TOp.UnionCaseTagGet _,_,[arg1] -> CheckTypeInstNoByrefs cenv env m tyargs - CheckExprPermitByref cenv env arg1 // allow byref - it may be address-of-struct + CheckExprPermitByRefLike cenv env arg1 // allow byref - it may be address-of-struct | TOp.UnionCaseFieldGetAddr (uref, _idx, _readonly),tyargs,[rx] -> - if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + + if context.Disallow && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(uref.CaseName), m)) + CheckTypeInstNoByrefs cenv env m tyargs // allow rx to be byref here, for struct unions - CheckExprPermitByref cenv env rx + CheckExprPermitByRefLike cenv env rx | TOp.ILAsm (instrs,tys),_,_ -> CheckTypeInstPermitAllByrefs cenv env m tys CheckTypeInstNoByrefs cenv env m tyargs match instrs,args with - | [ I_stfld (_alignment,_vol,_fspec) ],[lhs;rhs] -> + // Write a .NET instance field + | [ I_stfld (_alignment,_vol,_fspec) ],_ -> // permit byref for lhs lvalue - CheckExprPermitByref cenv env lhs - CheckExprNoByrefs cenv env rhs - | [ I_ldfld (_alignment,_vol,_fspec) ],[lhs] -> + // permit byref for rhs lvalue (field would have to have ByRefLike type, i.e. be a field in another ByRefLike type) + CheckExprsPermitByRefLike cenv env args + + // Read a .NET instance field + | [ I_ldfld (_alignment,_vol,_fspec) ],_ -> // permit byref for lhs lvalue - CheckExprPermitByref cenv env lhs - | [ I_ldfld (_alignment,_vol,_fspec); AI_nop ],[lhs] -> + CheckExprsPermitByRefLike cenv env args + + // Read a .NET instance field + | [ I_ldfld (_alignment,_vol,_fspec); AI_nop ],_ -> // permit byref for lhs lvalue of readonly value - CheckExprPermitByref cenv env lhs - | [ I_ldflda (fspec) | I_ldsflda (fspec) ],[lhs] -> - if noByrefs context && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + CheckExprsPermitByRefLike cenv env args + + | [ I_ldflda (fspec) | I_ldsflda (fspec) ],_ -> + if context.Disallow && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(fspec.Name), m)) // permit byref for lhs lvalue - CheckExprPermitByref cenv env lhs + CheckExprsPermitByRefLike cenv env args + | [ I_ldelema (_,isNativePtr,_,_) ],lhsArray::indices -> - if noByrefs context && cenv.reportErrors && not isNativePtr && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + if context.Disallow && cenv.reportErrors && not isNativePtr && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then errorR(Error(FSComp.SR.chkNoAddressOfArrayElementAtThisPoint(), m)) // permit byref for lhs lvalue - CheckExprPermitByref cenv env lhsArray - CheckExprsNoByrefs cenv env indices + let limit = CheckExprPermitByRefLike cenv env lhsArray + CheckExprsNoByRefLike cenv env indices |> ignoreLimit + limit + | [ AI_conv _ ],_ -> // permit byref for args to conv - CheckExprsPermitByrefs cenv env args + CheckExprsPermitByRefLike cenv env args + | _ -> - CheckExprsNoByrefs cenv env args + CheckExprsNoByRefLike cenv env args | TOp.TraitCall _,_,_ -> CheckTypeInstNoByrefs cenv env m tyargs // allow args to be byref here - CheckExprsPermitByrefs cenv env args + CheckExprsPermitByRefLike cenv env args | _ -> CheckTypeInstNoByrefs cenv env m tyargs - CheckExprsNoByrefs cenv env args + CheckExprsNoByRefLike cenv env args and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValInfo alwaysCheckNoReraise e m ety = // The topValInfo here says we are _guaranteeing_ to compile a function value @@ -920,7 +977,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn let thisAndBase = Option.toList ctorThisValOpt @ Option.toList baseValOpt let restArgs = List.concat vsl let syntacticArgs = thisAndBase @ restArgs - let env = SetArgVals env restArgs + let env = BindArgVals env restArgs match memInfo with | None -> () @@ -949,11 +1006,13 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn CheckNoReraise cenv freesOpt body // Check the body of the lambda - if (not (isNil tps) || not (isNil vsl)) && isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g m bodyty then - // allow byref to occur as return position for byref-typed top level function or method - CheckExprPermitByrefReturn cenv env body - else - CheckExprNoByrefs cenv env body + let limit = + if isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g m bodyty then + // allow byref to occur as return position for byref-typed top level function or method + CheckExprPermitReturnableByRef cenv env body + else + CheckExprNoByrefs cenv env body + false // Check byref return types if cenv.reportErrors then @@ -966,44 +1025,58 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn CheckForByrefLikeType cenv env m (destByrefTy cenv.g bodyty) (fun () -> errorR(Error(FSComp.SR.chkReturnTypeNoByref(), m))) + if limit then + errorR(Error(FSComp.SR.chkNoReturnOfLimitedSpan(), m)) + for tp in tps do if tp.Constraints |> List.sumBy (function TyparConstraint.CoercesTo(ty,_) when isClassTy cenv.g ty -> 1 | _ -> 0) > 1 then errorR(Error(FSComp.SR.chkTyparMultipleClassConstraints(), m)) + + false // This path is for expression bindings that are not actually lambdas | _ -> // Permit byrefs for let x = ... CheckTypePermitAllByrefs cenv env m ety - if not inlined && (isByrefLikeTy cenv.g m ety || isNativePtrTy cenv.g ety) then - // allow byref to occur as RHS of byref binding. - CheckExprPermitByref cenv env e - else - CheckExprNoByrefs cenv env e + let limit = + if not inlined && (isByrefLikeTy cenv.g m ety || isNativePtrTy cenv.g ety) then + // allow byref to occur as RHS of byref binding. + CheckExprPermitByRefLike cenv env e + else + CheckExprNoByrefs cenv env e + false + if alwaysCheckNoReraise then CheckNoReraise cenv None e + limit -and CheckExprs cenv env exprs contexts = +and CheckExprs cenv env exprs contexts : bool = let contexts = Array.ofList contexts - let argArity i = if i < contexts.Length then contexts.[i] else NoByrefs - exprs |> List.iteri (fun i exp -> CheckExpr cenv env exp (argArity i)) + let argArity i = if i < contexts.Length then contexts.[i] else PermitByRefExpr.No + let limits = exprs |> List.mapi (fun i exp -> CheckExpr cenv env exp (argArity i)) + limits |> List.existsTrue -and CheckExprsNoByrefs cenv env exprs = +and CheckExprsNoByRefLike cenv env exprs : bool = exprs |> List.iter (CheckExprNoByrefs cenv env) + false -and CheckExprsPermitByrefs cenv env exprs = - exprs |> List.iter (CheckExprPermitByref cenv env) +and CheckExprsPermitByRefLike cenv env exprs = + let limits = exprs |> List.map (CheckExprPermitByRefLike cenv env) + limits |> List.existsTrue -and CheckExprsPermitByrefReturns cenv env exprs = - exprs |> List.iter (CheckExprPermitByrefReturn cenv env) +and CheckExprsPermitReturnableByRef cenv env exprs : bool = + let limits = exprs |> List.map (CheckExprPermitReturnableByRef cenv env) + limits |> List.existsTrue -and CheckExprPermitByref cenv env expr = - CheckExpr cenv env expr (PermitByref false) +and CheckExprPermitByRefLike cenv env expr = + CheckExpr cenv env expr PermitByRefExpr.Yes -and CheckExprPermitByrefReturn cenv env expr = - CheckExpr cenv env expr (PermitByref true) +and CheckExprPermitReturnableByRef cenv env expr : bool = + CheckExpr cenv env expr PermitByRefExpr.YesReturnable and CheckDecisionTreeTargets cenv env targets context = - targets |> Array.iter (CheckDecisionTreeTarget cenv env context) + let limits = targets |> Array.map (CheckDecisionTreeTarget cenv env context) + limits |> Array.existsTrue and CheckDecisionTreeTarget cenv env context (TTarget(vs,e,_)) = BindVals cenv env vs @@ -1012,12 +1085,16 @@ and CheckDecisionTreeTarget cenv env context (TTarget(vs,e,_)) = and CheckDecisionTree cenv env x = match x with - | TDSuccess (es,_) -> CheckExprsNoByrefs cenv env es - | TDBind(bind,rest) -> CheckBinding cenv env false bind; CheckDecisionTree cenv env rest - | TDSwitch (e,cases,dflt,m) -> CheckDecisionTreeSwitch cenv env (e,cases,dflt,m) + | TDSuccess (es,_) -> + CheckExprsNoByRefLike cenv env es |> ignoreLimit + | TDBind(bind,rest) -> + CheckBinding cenv env false bind |> ignoreLimit + CheckDecisionTree cenv env rest + | TDSwitch (e,cases,dflt,m) -> + CheckDecisionTreeSwitch cenv env (e,cases,dflt,m) and CheckDecisionTreeSwitch cenv env (e,cases,dflt,m) = - CheckExprPermitByref cenv env e // can be byref for struct union switch + CheckExprPermitByRefLike cenv env e |> ignoreLimit // can be byref for struct union switch cases |> List.iter (fun (TCase(discrim,e)) -> CheckDecisionTreeTest cenv env m discrim; CheckDecisionTree cenv env e) dflt |> Option.iter (CheckDecisionTree cenv env) @@ -1124,7 +1201,7 @@ and AdjustAccess isHidden (cpath: unit -> CompilationPath) access = else access -and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = +and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) : bool = let isTop = Option.isSome bind.Var.ValReprInfo //printfn "visiting %s..." v.DisplayName @@ -1153,7 +1230,7 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = let access = AdjustAccess (IsHiddenVal env.sigToImplRemapInfo v) (fun () -> v.TopValDeclaringEntity.CompilationPath) v.Accessibility CheckTypeForAccess cenv env (fun () -> NicePrint.stringOfQualifiedValOrMember cenv.denv v) access v.Range v.Type - let env = if v.IsConstructor && not v.IsIncrClassConstructor then { env with limited=true } else env + let env = if v.IsConstructor && not v.IsIncrClassConstructor then { env with ctorLimitedZone=true } else env if cenv.reportErrors then @@ -1223,7 +1300,8 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) = CheckLambdas isTop v.MemberInfo cenv env v.MustInline topValInfo alwaysCheckNoReraise bindRhs v.Range v.Type -and CheckBindings cenv env xs = List.iter (CheckBinding cenv env false) xs +and CheckBindings cenv env xs = + xs |> List.iter (CheckBinding cenv env false >> ignoreLimit) // Top binds introduce expression, check they are reraise free. let CheckModuleBinding cenv env (TBind(v,e,_) as bind) = @@ -1350,44 +1428,61 @@ let CheckModuleBinding cenv env (TBind(v,e,_) as bind) = with e -> errorRecovery e v.Range end - CheckBinding cenv env true bind + CheckBinding cenv env true bind |> ignoreLimit -let CheckModuleBindings cenv env binds = List.iter (CheckModuleBinding cenv env) binds +let CheckModuleBindings cenv env binds = + binds |> List.iter (CheckModuleBinding cenv env) //-------------------------------------------------------------------------- // check tycons //-------------------------------------------------------------------------- let CheckRecdField isUnion cenv env (tycon:Tycon) (rfield:RecdField) = + let g = cenv.g + let tcref = mkLocalTyconRef tycon + let m = rfield.Range let isHidden = IsHiddenTycon env.sigToImplRemapInfo tycon || IsHiddenTyconRepr env.sigToImplRemapInfo tycon || - (not isUnion && IsHiddenRecdField env.sigToImplRemapInfo ((mkLocalTyconRef tycon).MakeNestedRecdFieldRef rfield)) + (not isUnion && IsHiddenRecdField env.sigToImplRemapInfo (tcref.MakeNestedRecdFieldRef rfield)) let access = AdjustAccess isHidden (fun () -> tycon.CompilationPath) rfield.Accessibility - CheckTypeForAccess cenv env (fun () -> rfield.Name) access rfield.Range rfield.FormalType - CheckTypeNoByrefs cenv env rfield.Range rfield.FormalType + CheckTypeForAccess cenv env (fun () -> rfield.Name) access m rfield.FormalType + + if TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref then + // Permit Span fields in IsByRefLike types + CheckTypePermitOuterSpanLike cenv env m rfield.FormalType + else + CheckTypeNoByrefs cenv env m rfield.FormalType + if cenv.reportErrors then + CheckForByrefLikeType cenv env m rfield.FormalType (fun () -> errorR(Error(FSComp.SR.chkCantStoreByrefValue(), tycon.Range))) + CheckAttribs cenv env rfield.PropertyAttribs CheckAttribs cenv env rfield.FieldAttribs - if cenv.reportErrors then - CheckForByrefLikeType cenv env rfield.Range rfield.FormalType (fun () -> errorR(Error(FSComp.SR.chkCantStoreByrefValue(), tycon.Range))) let CheckEntityDefn cenv env (tycon:Entity) = #if !NO_EXTENSIONTYPING if not tycon.IsProvidedGeneratedTycon then #endif - let env = { env with reflect = env.reflect || HasFSharpAttribute cenv.g cenv.g.attrib_ReflectedDefinitionAttribute tycon.Attribs } + let g = cenv.g let m = tycon.Range - let env = BindTypars cenv.g env (tycon.Typars(m)) + let tcref = mkLocalTyconRef tycon + let typ = generalizedTyconRef tcref + + let env = { env with reflect = env.reflect || HasFSharpAttribute g g.attrib_ReflectedDefinitionAttribute tycon.Attribs } + let env = BindTypars g env (tycon.Typars(m)) + CheckAttribs cenv env tycon.Attribs + match tycon.TypeAbbrev with | Some abbrev -> WarnOnWrongTypeForAccess cenv env (fun () -> tycon.CompiledName) tycon.Accessibility tycon.Range abbrev | _ -> () if cenv.reportErrors then + if not tycon.IsTypeAbbrev then - let typ = generalizedTyconRef (mkLocalTyconRef tycon) + let allVirtualMethsInParent = - match GetSuperTypeOfType cenv.g cenv.amap m typ with + match GetSuperTypeOfType g cenv.amap m typ with | Some super -> GetIntrinsicMethInfosOfType cenv.infoReader (None,AccessibleFromSomewhere,AllowMultiIntfInstantiations.Yes) IgnoreOverrides m super |> List.filter (fun minfo -> minfo.IsVirtual) @@ -1397,14 +1492,14 @@ let CheckEntityDefn cenv env (tycon:Entity) = let methodUniquenessIncludesReturnType (minfo:MethInfo) = List.contains minfo.LogicalName namesOfMethodsThatMayDifferOnlyInReturnType let MethInfosEquivWrtUniqueness eraseFlag m minfo minfo2 = if methodUniquenessIncludesReturnType minfo - then MethInfosEquivByNameAndSig eraseFlag true cenv.g cenv.amap m minfo minfo2 - else MethInfosEquivByNameAndPartialSig eraseFlag true cenv.g cenv.amap m minfo minfo2 (* partial ignores return type *) + then MethInfosEquivByNameAndSig eraseFlag true g cenv.amap m minfo minfo2 + else MethInfosEquivByNameAndPartialSig eraseFlag true g cenv.amap m minfo minfo2 (* partial ignores return type *) let immediateMeths = - [ for v in tycon.AllGeneratedValues do yield FSMeth (cenv.g,typ,v,None) - yield! GetImmediateIntrinsicMethInfosOfType (None,AccessibleFromSomewhere) cenv.g cenv.amap m typ ] + [ for v in tycon.AllGeneratedValues do yield FSMeth (g,typ,v,None) + yield! GetImmediateIntrinsicMethInfosOfType (None,AccessibleFromSomewhere) g cenv.amap m typ ] - let immediateProps = GetImmediateIntrinsicPropInfosOfType (None,AccessibleFromSomewhere) cenv.g cenv.amap m typ + let immediateProps = GetImmediateIntrinsicPropInfosOfType (None,AccessibleFromSomewhere) g cenv.amap m typ let getHash (hash:Dictionary) nm = match hash.TryGetValue(nm) with @@ -1460,7 +1555,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = if numCurriedArgSets > 1 && (minfo.GetParamDatas(cenv.amap, m, minfo.FormalMethodInst) |> List.existsSquared (fun (ParamData(isParamArrayArg, _isInArg, isOutArg, optArgInfo, callerInfoInfo, _, reflArgInfo, ty)) -> - isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefLikeTy cenv.g m ty)) then + isParamArrayArg || isOutArg || reflArgInfo.AutoQuote || optArgInfo.IsOptional || callerInfoInfo <> NoCallerInfo || isByrefLikeTy g m ty)) then errorR(Error(FSComp.SR.chkCurriedMethodsCantHaveOutParams(), m)) if numCurriedArgSets = 1 then @@ -1471,23 +1566,23 @@ let CheckEntityDefn cenv env (tycon:Entity) = | _, NoCallerInfo -> () | NotOptional, _ -> errorR(Error(FSComp.SR.tcCallerInfoNotOptional(callerInfoInfo.ToString()),m)) | CallerSide(_), CallerLineNumber -> - if not (typeEquiv cenv.g cenv.g.int32_ty ty) then + if not (typeEquiv g g.int32_ty ty) then errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "int", NicePrint.minimalStringOfType cenv.denv ty),m)) | CalleeSide, CallerLineNumber -> - if not ((isOptionTy cenv.g ty) && (typeEquiv cenv.g cenv.g.int32_ty (destOptionTy cenv.g ty))) then - errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "int", NicePrint.minimalStringOfType cenv.denv (destOptionTy cenv.g ty)),m)) + if not ((isOptionTy g ty) && (typeEquiv g g.int32_ty (destOptionTy g ty))) then + errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "int", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)),m)) | CallerSide(_), CallerFilePath -> - if not (typeEquiv cenv.g cenv.g.string_ty ty) then + if not (typeEquiv g g.string_ty ty) then errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv ty),m)) | CalleeSide, CallerFilePath -> - if not ((isOptionTy cenv.g ty) && (typeEquiv cenv.g cenv.g.string_ty (destOptionTy cenv.g ty))) then - errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy cenv.g ty)),m)) + if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then + errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)),m)) | CallerSide(_), CallerMemberName -> - if not (typeEquiv cenv.g cenv.g.string_ty ty) then + if not (typeEquiv g g.string_ty ty) then errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv ty),m)) | CalleeSide, CallerMemberName -> - if not ((isOptionTy cenv.g ty) && (typeEquiv cenv.g cenv.g.string_ty (destOptionTy cenv.g ty))) then - errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy cenv.g ty)),m))) + if not ((isOptionTy g ty) && (typeEquiv g g.string_ty (destOptionTy g ty))) then + errorR(Error(FSComp.SR.tcCallerInfoWrongType(callerInfoInfo.ToString(), "string", NicePrint.minimalStringOfType cenv.denv (destOptionTy g ty)),m))) for pinfo in immediateProps do let nm = pinfo.PropertyName @@ -1510,7 +1605,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = x.IsDispatchSlot && y.IsDefiniteFSharpOverride not (IsAbstractDefaultPair pinfo pinfo2 || IsAbstractDefaultPair pinfo2 pinfo) - && PropInfosEquivByNameAndPartialSig erasureFlag cenv.g cenv.amap m pinfo pinfo2 (* partial ignores return type *) + && PropInfosEquivByNameAndPartialSig erasureFlag g cenv.amap m pinfo pinfo2 (* partial ignores return type *) if others |> List.exists (checkForDup EraseAll) then if others |> List.exists (checkForDup EraseNone) then @@ -1540,7 +1635,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = hashOfImmediateProps.[nm] <- pinfo::others - if not (isInterfaceTy cenv.g typ) then + if not (isInterfaceTy g typ) then let hashOfAllVirtualMethsInParent = new Dictionary() for minfo in allVirtualMethsInParent do let nm = minfo.LogicalName @@ -1551,7 +1646,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = let nm = minfo.LogicalName let m = (match minfo.ArbitraryValRef with None -> m | Some vref -> vref.DefinitionRange) let parentMethsOfSameName = getHash hashOfAllVirtualMethsInParent nm - let checkForDup erasureFlag (minfo2:MethInfo) = minfo2.IsDispatchSlot && MethInfosEquivByNameAndSig erasureFlag true cenv.g cenv.amap m minfo minfo2 + let checkForDup erasureFlag (minfo2:MethInfo) = minfo2.IsDispatchSlot && MethInfosEquivByNameAndSig erasureFlag true g cenv.amap m minfo minfo2 match parentMethsOfSameName |> List.tryFind (checkForDup EraseAll) with | None -> () | Some minfo -> @@ -1566,7 +1661,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = let nm = minfo.LogicalName let m = (match minfo.ArbitraryValRef with None -> m | Some vref -> vref.DefinitionRange) let parentMethsOfSameName = getHash hashOfAllVirtualMethsInParent nm - let checkForDup erasureFlag minfo2 = MethInfosEquivByNameAndSig erasureFlag true cenv.g cenv.amap m minfo minfo2 + let checkForDup erasureFlag minfo2 = MethInfosEquivByNameAndSig erasureFlag true g cenv.amap m minfo minfo2 //if minfo.NumArgs.Length > 1 then // warning(Error(sprintf "Abstract methods taking curried arguments Duplicate method. The method '%s' has curried arguments but has the same name as another method in this type. Methods with curried arguments may not be overloaded" nm,(match minfo.ArbitraryValRef with None -> m | Some vref -> vref.DefinitionRange))) if parentMethsOfSameName |> List.exists (checkForDup EraseAll) then @@ -1574,6 +1669,10 @@ let CheckEntityDefn cenv env (tycon:Entity) = errorR(Error(FSComp.SR.chkDuplicateMethodInheritedType(nm),m)) else errorR(Error(FSComp.SR.chkDuplicateMethodInheritedTypeWithSuffix(nm),m)) + + if TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref && not tycon.IsStructOrEnumTycon then + errorR(Error(FSComp.SR.tcByRefLikeNotStruct(), tycon.Range)) + // Considers TFSharpObjectRepr, TRecdRepr and TUnionRepr. // [Review] are all cases covered: TILObjectRepr,TAsmRepr. [Yes - these are FSharp.Core.dll only] tycon.AllFieldsArray |> Array.iter (CheckRecdField false cenv env tycon) @@ -1582,19 +1681,19 @@ let CheckEntityDefn cenv env (tycon:Entity) = for vref in abstractSlotValsOfTycons [tycon] do match vref.ValReprInfo with | Some topValInfo -> - let tps, argtysl, rty, _ = GetTopValTypeInFSharpForm cenv.g topValInfo vref.Type m - let env = BindTypars cenv.g env tps + let tps, argtysl, rty, _ = GetTopValTypeInFSharpForm g topValInfo vref.Type m + let env = BindTypars g env tps for argtys in argtysl do for (argty, _) in argtys do - CheckTypePermitOuterByref cenv env m argty - CheckTypePermitOuterByref cenv env m rty + CheckTypePermitOuterByRefLike cenv env m argty + CheckTypePermitOuterByRefLike cenv env m rty | None -> () // Supported interface may not have byrefs tycon.ImmediateInterfaceTypesOfFSharpTycon |> List.iter (CheckTypeNoByrefs cenv env m) - superOfTycon cenv.g tycon |> CheckTypeNoByrefs cenv env m + superOfTycon g tycon |> CheckTypeNoByrefs cenv env m if tycon.IsUnionTycon then tycon.UnionCasesAsList |> List.iter (fun uc -> @@ -1607,10 +1706,10 @@ let CheckEntityDefn cenv env (tycon:Entity) = abstractSlotValsOfTycons [tycon] |> List.iter (typeOfVal >> visitType) - superOfTycon cenv.g tycon |> visitType + superOfTycon g tycon |> visitType // We do not have to check access of interface implementations. See FSharp 1.0 5042 - //implements_of_tycon cenv.g tycon |> List.iter visitType + //implements_of_tycon g tycon |> List.iter visitType if tycon.IsFSharpDelegateTycon then match tycon.TypeReprInfo with | TFSharpObjectRepr r -> @@ -1624,24 +1723,22 @@ let CheckEntityDefn cenv env (tycon:Entity) = | _ -> () - let tcref = mkLocalTyconRef tycon let interfaces = - AllSuperTypesOfType cenv.g cenv.amap tycon.Range AllowMultiIntfInstantiations.Yes (generalizedTyconRef tcref) - |> List.filter (isInterfaceTy cenv.g) + AllSuperTypesOfType g cenv.amap tycon.Range AllowMultiIntfInstantiations.Yes typ + |> List.filter (isInterfaceTy g) if tycon.IsFSharpInterfaceTycon then List.iter visitType interfaces // Check inherited interface is as accessible - if not (isRecdOrStructTyconRefAssumedImmutable cenv.g tcref) && isRecdOrStructTyconRefReadOnly cenv.g m tcref then + if not (isRecdOrStructTyconRefAssumedImmutable g tcref) && isRecdOrStructTyconRefReadOnly g m tcref then errorR(Error(FSComp.SR.readOnlyAttributeOnStructWithMutableField(),m)) if cenv.reportErrors then if not tycon.IsTypeAbbrev then - let typ = generalizedTyconRef (mkLocalTyconRef tycon) - let immediateInterfaces = GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes cenv.g cenv.amap m typ + let immediateInterfaces = GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g cenv.amap m typ let interfaces = [ for ty in immediateInterfaces do - yield! AllSuperTypesOfType cenv.g cenv.amap m AllowMultiIntfInstantiations.Yes ty ] + yield! AllSuperTypesOfType g cenv.amap m AllowMultiIntfInstantiations.Yes ty ] CheckMultipleInterfaceInstantiations cenv interfaces m // Check struct fields. We check these late because we have to have first checked that the structs are @@ -1649,10 +1746,9 @@ let CheckEntityDefn cenv env (tycon:Entity) = if tycon.IsStructOrEnumTycon then for f in tycon.AllInstanceFieldsAsList do // Check if it's marked unsafe - let zeroInitUnsafe = TryFindFSharpBoolAttribute cenv.g cenv.g.attrib_DefaultValueAttribute f.FieldAttribs + let zeroInitUnsafe = TryFindFSharpBoolAttribute g g.attrib_DefaultValueAttribute f.FieldAttribs if zeroInitUnsafe = Some(true) then - let ty' = generalizedTyconRef (mkLocalTyconRef tycon) - if not (TypeHasDefaultValue cenv.g m ty') then + if not (TypeHasDefaultValue g m typ) then errorR(Error(FSComp.SR.chkValueWithDefaultValueMustHaveDefaultValue(), m)) // Check type abbreviations @@ -1660,7 +1756,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = | None -> () | Some typ -> // Library-defined outref<'T> and inref<'T> contain byrefs on the r.h.s. - if not cenv.g.compilingFslib then + if not g.compilingFslib then CheckForByrefLikeType cenv env m typ (fun () -> errorR(Error(FSComp.SR.chkNoByrefInTypeAbbrev(), tycon.Range))) let CheckEntityDefns cenv env tycons = @@ -1717,6 +1813,7 @@ let CheckTopImpl (g,amap,reportErrors,infoReader,internalsVisibleToPaths,viewCcu { g =g reportErrors=reportErrors boundVals= new Dictionary<_,_>(100, HashIdentity.Structural) + limitVals= new Dictionary<_,_>(100, HashIdentity.Structural) potentialUnboundUsesOfVals=Map.empty usesQuotations=false infoReader=infoReader @@ -1741,7 +1838,7 @@ let CheckTopImpl (g,amap,reportErrors,infoReader,internalsVisibleToPaths,viewCcu let env = { sigToImplRemapInfo=[] quote=false - limited=false + ctorLimitedZone=false boundTyparNames=[] argVals = ValMap.Empty boundTypars= TyparMap.Empty diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index ca39c68230..11a664c989 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -2935,6 +2935,15 @@ 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 && @@ -2942,13 +2951,7 @@ let isByrefLikeTyconRef (g: TcGlobals) m (tcref: TyconRef) = | Some res -> res | None -> let res = - (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 || + isByrefTyconRef g tcref || TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref tcref.SetIsByRefLike res res diff --git a/src/fsharp/TastOps.fsi b/src/fsharp/TastOps.fsi index 6c213690b3..5628704e56 100755 --- a/src/fsharp/TastOps.fsi +++ b/src/fsharp/TastOps.fsi @@ -1433,6 +1433,7 @@ val isNativePtrTy : TcGlobals -> TType -> bool val destByrefTy : TcGlobals -> TType -> TType val destNativePtrTy : TcGlobals -> TType -> TType +val isByrefTyconRef : TcGlobals -> TyconRef -> bool val isByrefLikeTyconRef : TcGlobals -> range -> TyconRef -> bool val isByrefLikeTy : TcGlobals -> range -> TType -> bool diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 27c5da3682..11a3ed832a 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 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. + 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. + 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. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index 6ce373f9e9..9a80d8b66c 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 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. + 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. + 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. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.en.xlf b/src/fsharp/xlf/FSComp.txt.en.xlf index 24290de3d6..efea229869 100644 --- a/src/fsharp/xlf/FSComp.txt.en.xlf +++ b/src/fsharp/xlf/FSComp.txt.en.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . + 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. + 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. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 8941c33f9a..de8ee3a6a6 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 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. + 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. + 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. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index f90da76524..cc7ec0e928 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 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. + 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. + 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. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index f2069bf118..046e22bc80 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 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. + 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. + 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. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 190f2e6a72..f3b671a16e 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 変数 '{0}' のアドレスはこのポイントでは使用できません。メソッドまたは関数がこのローカル値のアドレスを返さない可能性があります。 + 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. + 変数 '{0}' のアドレスはこのポイントでは使用できません。メソッドまたは関数がこのローカル値のアドレスを返さない可能性があります。 @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index 92d0de171d..d3733c4f94 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 지금은 '{0}' 변수의 주소를 사용할 수 없습니다. 메서드 또는 함수가 이 로컬 값의 주소를 반환할 수 없습니다. + 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. + 지금은 '{0}' 변수의 주소를 사용할 수 없습니다. 메서드 또는 함수가 이 로컬 값의 주소를 반환할 수 없습니다. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index aef65bae42..70180a654d 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 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. + 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. + 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. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index b357f6e988..7d99d0bc7b 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 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. + 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. + 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. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 22cdcaf9e2..1fa00fc866 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - Адрес переменной "{0}" сейчас невозможно использовать. Метод или функция могут не возвратить адрес этого локального значения. + 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. + Адрес переменной "{0}" сейчас невозможно использовать. Метод или функция могут не возвратить адрес этого локального значения. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index d47ab9dad6..e75da76026 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - '{0}' değişkeninin adresi bu noktada kullanılamaz. Bir metot veya işlev, bu yerel değerin adresini döndüremez. + 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. + '{0}' değişkeninin adresi bu noktada kullanılamaz. Bir metot veya işlev, bu yerel değerin adresini döndüremez. @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index f01b5cd0d2..23cc61a32a 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 当前无法使用变量 {0} 的地址。方法或函数可能没有返回该本地值的地址。 + 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. + 当前无法使用变量 {0} 的地址。方法或函数可能没有返回该本地值的地址。 @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 04929cd133..c04f64363e 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -6518,8 +6518,8 @@ - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . - 目前無法使用變數 '{0}' 的位址。方法或函式無法傳回此本機值的位址。 + 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. + 目前無法使用變數 '{0}' 的位址。方法或函式無法傳回此本機值的位址。 @@ -7007,6 +7007,21 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. + + + + 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. + 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. + + + + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + \ No newline at end of file diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index 07aa2eafea..849b0d839d 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -163,6 +163,52 @@ namespace Tests let data = Span<'T>.Empty data.[0] <- Unchecked.defaultof<'T> + module CheckReturnOfSpan1 = + let test () = + let s = Span.Empty + s + + module CheckReturnOfSpan2 = + + type Jopac() = + + member this.Create() = + let mutable x = 1 + this.Create(&x) + + member __.Create(x: byref) = + Span.Empty + + module CheckReturnOfSpan3 = + type Jopac_NotCompile_WhichIsMightBeIncorrect() = + + member __.Create(x: byref) = + Span.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 CheckReturnOfSpan4 = + type Jopac_NotCompile_WhichIsCorrect() = + + member __.Create(x: byref) = + &x + + member this.Create() = + let mutable x = 1 + let x = &this.Create(&x) + &x + + member this.CreateAgain() = + let mutable x = 1 + &this.Create(&x) + #if NEGATIVE diff --git a/tests/fsharp/typecheck/sigs/neg63.bsl b/tests/fsharp/typecheck/sigs/neg63.bsl index 3d1df0e77a..83bce82a07 100644 --- a/tests/fsharp/typecheck/sigs/neg63.bsl +++ b/tests/fsharp/typecheck/sigs/neg63.bsl @@ -9,6 +9,6 @@ neg63.fs(11,5,11,13): typecheck error FS0412: A type instantiation involves a by neg63.fs(14,8,14,9): typecheck error FS3155: A quotation may not involve an assignment to or taking the address of a captured local variable -neg63.fs(18,6,18,7): typecheck error FS3209: The address of the variable 'x' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . +neg63.fs(18,6,18,7): typecheck error FS3209: The address of the variable 'x' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. 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. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . +neg63.fs(26,6,26,10): typecheck error FS3209: The address of the variable 'addr' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not escape its scope. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_7.bsl b/tests/fsharp/typecheck/sigs/neg_byref_7.bsl index b3a58fdb75..79add245f5 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_7.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_7.bsl @@ -19,4 +19,4 @@ neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg_byref_7.fs(4,41,4,42): typecheck error FS3209: The address of the variable 'y' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not esacape its scope. . +neg_byref_7.fs(4,41,4,42): typecheck error FS3209: The address of the variable 'y' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not escape its scope. From a7e8e82212117b03378b633c399d95d129bd8634 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 2 Jun 2018 15:33:16 +0100 Subject: [PATCH 52/61] updates for new test cases --- tests/fsharp/core/span/test.fsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index 849b0d839d..2fb8298998 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -194,6 +194,9 @@ namespace Tests let mutable x = 1 this.Create(&x) + +#if NEGATIVE + module CheckReturnOfSpan4 = type Jopac_NotCompile_WhichIsCorrect() = @@ -209,9 +212,6 @@ namespace Tests let mutable x = 1 &this.Create(&x) - -#if NEGATIVE - // Disallow this: [] type DisallowedIsReadOnlyStruct = From 1bccfb6169002fce7a8f80cc5687d86454d89720 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 2 Jun 2018 15:59:00 +0100 Subject: [PATCH 53/61] test updates and byref-to-byreflike --- src/fsharp/PostInferenceChecks.fs | 15 ++-- tests/fsharp/core/byrefs/test.fsx | 1 - tests/fsharp/core/span/test.fsx | 79 ++++++++++++++++++++- tests/fsharp/typecheck/sigs/neg63.bsl | 4 +- tests/fsharp/typecheck/sigs/neg_byref_7.bsl | 2 +- 5 files changed, 88 insertions(+), 13 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index aeb688f7f7..792b1c80f8 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -232,10 +232,13 @@ and CheckTraitInfoDeep ((_,_,_,visitTraitSolutionOpt,_) as f) g env (TTrait(typs | Some visitTraitSolution, Some sln -> visitTraitSolution sln | _ -> () -/// Check for byref types +/// Check for byref-like types let CheckForByrefLikeType cenv env m typ check = CheckTypeDeep (ignore, Some (fun _deep tcref -> if isByrefLikeTyconRef cenv.g m tcref then check()), None, None, None) cenv.g env false typ +/// Check for byref types +let CheckForByrefType cenv env typ check = + CheckTypeDeep (ignore, Some (fun _deep tcref -> if isByrefTyconRef cenv.g tcref then check()), None, None, None) cenv.g env false typ /// check captures under lambdas /// @@ -427,8 +430,8 @@ let CheckType permitByRefLike (cenv:cenv) env m ty = let visitType ty0 = match tryDestAppTy cenv.g ty0 with | None -> () - | Some tcref -> - if isByrefTyconRef cenv.g tcref then + | Some tcref2 -> + if isByrefTyconRef cenv.g tcref2 then errorR(Error(FSComp.SR.chkNoByrefsOfByrefs(NicePrint.minimalStringOfType cenv.denv ty), m)) CheckTypesDeep (visitType, None, None, None, None) cenv.g env tinst @@ -1016,13 +1019,13 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // Check byref return types if cenv.reportErrors then - if (not inlined && (isNil tps && isNil vsl)) || not isTop then + if not isTop then CheckForByrefLikeType cenv env m bodyty (fun () -> errorR(Error(FSComp.SR.chkFirstClassFuncNoByref(), m))) elif not cenv.g.compilingFslib && isByrefTy cenv.g bodyty then // check no byrefs-in-the-byref - CheckForByrefLikeType cenv env m (destByrefTy cenv.g bodyty) (fun () -> + CheckForByrefType cenv env (destByrefTy cenv.g bodyty) (fun () -> errorR(Error(FSComp.SR.chkReturnTypeNoByref(), m))) if limit then @@ -1757,7 +1760,7 @@ let CheckEntityDefn cenv env (tycon:Entity) = | Some typ -> // Library-defined outref<'T> and inref<'T> contain byrefs on the r.h.s. if not g.compilingFslib then - CheckForByrefLikeType cenv env m typ (fun () -> errorR(Error(FSComp.SR.chkNoByrefInTypeAbbrev(), tycon.Range))) + CheckForByrefType cenv env typ (fun () -> errorR(Error(FSComp.SR.chkNoByrefInTypeAbbrev(), tycon.Range))) let CheckEntityDefns cenv env tycons = tycons |> List.iter (CheckEntityDefn cenv env) diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 323f9e365f..967b610662 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -4,7 +4,6 @@ module Core_byrefs #endif -#light let failures = ref false let report_failure (s) = stderr.WriteLine ("NO: " + s); failures := true diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index 2fb8298998..8291f29404 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -20,6 +20,25 @@ namespace Tests open System open System.Runtime.CompilerServices open System.Runtime.InteropServices + open FSharp.NativeInterop + + [] + 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 [] @@ -194,6 +213,60 @@ namespace Tests let mutable x = 1 this.Create(&x) + module ByRefSpanParam = + type C() = + static member M(x: byref>) = x.[0] <- 5 + + let Test() = + let mutable res = 9 + let mutable span = Span(NativePtr.toVoidPtr &&res,1) + let v = C.M(&span) + check "cwvereweoiwekl4" res 5 + + let minfo = typeof.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>) = x.[0] <- x.[0] + 1; &x + + let Test() = + let mutable res = 9 + let mutable span = Span(NativePtr.toVoidPtr &&res,1) + let v = &C.M(&span) + check "cwvereweoiwvw4" v.[0] 10 + + let minfo = typeof.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>) = x.[0] <- x.[0] + 1; x + + let Test() = + let mutable res = 9 + let mutable span = Span(NativePtr.toVoidPtr &&res,1) + let v = C.M(&span) + check "cwvereweoiwvw4" v.[0] 10 + + let minfo = typeof.GetMethod("M") + check "cwnoreeker6d" (minfo.GetParameters().[0].GetRequiredCustomModifiers().Length) 0 + check "cwnoreekerr" (minfo.ReturnParameter.IsIn) false + check "cwnoreekert" (minfo.ReturnParameter.IsOut) false + + Test() + + #if NEGATIVE @@ -221,13 +294,13 @@ type DisallowedIsReadOnlyStruct = #if NOT_YET // Allow this: -[] +[] type ByRefLikeStructWithSpanField(count1: Span, count2: int) = member x.Count1 = count1 member x.Count2 = count2 -[] -type ByRefLikeStructWithByrefField(count1: byref, count2: int) = +[] +type ByRefLikeStructWithByrefField(count1: Span, count2: int) = member x.Count1 = count1 member x.Count2 = count2 #endif diff --git a/tests/fsharp/typecheck/sigs/neg63.bsl b/tests/fsharp/typecheck/sigs/neg63.bsl index 83bce82a07..b5df880f02 100644 --- a/tests/fsharp/typecheck/sigs/neg63.bsl +++ b/tests/fsharp/typecheck/sigs/neg63.bsl @@ -9,6 +9,6 @@ neg63.fs(11,5,11,13): typecheck error FS0412: A type instantiation involves a by neg63.fs(14,8,14,9): typecheck error FS3155: A quotation may not involve an assignment to or taking the address of a captured local variable -neg63.fs(18,6,18,7): typecheck error FS3209: The address of the variable 'x' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not escape its scope. +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. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not escape its scope. +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. diff --git a/tests/fsharp/typecheck/sigs/neg_byref_7.bsl b/tests/fsharp/typecheck/sigs/neg_byref_7.bsl index 79add245f5..ef21f974eb 100644 --- a/tests/fsharp/typecheck/sigs/neg_byref_7.bsl +++ b/tests/fsharp/typecheck/sigs/neg_byref_7.bsl @@ -19,4 +19,4 @@ neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves neg_byref_7.fs(2,47,2,53): typecheck error FS0412: A type instantiation involves a byref type. This is not permitted by the rules of Common IL. -neg_byref_7.fs(4,41,4,42): typecheck error FS3209: The address of the variable 'y' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not escape its scope. +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. From 3be2542bc0455fa4b90f09fa653fc4a3d4844e2b Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 2 Jun 2018 17:06:40 +0100 Subject: [PATCH 54/61] deal with 'M() <- expr' --- src/fsharp/PostInferenceChecks.fs | 27 ++++-- src/fsharp/TypeChecker.fs | 5 + src/fsharp/ast.fs | 10 +- src/fsharp/service/ServiceAssemblyContent.fs | 3 + .../service/ServiceInterfaceStubGenerator.fs | 5 + src/fsharp/service/ServiceParseTreeWalk.fs | 3 +- src/fsharp/service/ServiceStructure.fs | 10 +- src/fsharp/service/ServiceUntypedParse.fs | 13 +++ tests/fsharp/core/byrefs/test.fsx | 11 +++ tests/fsharp/core/span/test.fsx | 91 +++++++++++++++++++ tests/service/ProjectOptionsTests.fs | 2 +- 11 files changed, 167 insertions(+), 13 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 792b1c80f8..1a56d8f21c 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -79,17 +79,28 @@ let testHookMemberBody (membInfo: ValMemberInfo) (expr:Expr) = //-------------------------------------------------------------------------- type env = - { boundTyparNames: string list + { + /// The bound type parameter names in scope + boundTyparNames: string list + + /// The bound type parameters in scope boundTypars: TyparMap + + /// The set of arguments to this method/function argVals: ValMap + /// "module remap info", i.e. hiding information down the signature chain, used to compute what's hidden by a signature sigToImplRemapInfo: (Remap * SignatureHidingInfo) list + /// Constructor limited - are we in the prelude of a constructor, prior to object initialization ctorLimitedZone: bool + /// Are we in a quotation? quote : bool + /// Are we under []? reflect : bool + /// Are we in an extern declaration? external : bool } @@ -553,8 +564,8 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = not (isByrefTy g v.Type) && // The value is a local.... v.ValReprInfo.IsNone && - // The value is a non-argument byref or is a ctorLimitedZone Span - cenv.limitVals.ContainsKey(v.Stamp) + // The value is a limited Span or might have become one through mutation + (v.IsMutable || cenv.limitVals.ContainsKey(v.Stamp)) if cenv.reportErrors then @@ -660,15 +671,15 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = CheckExprsPermitByRefLike cenv env rest | Expr.Op (c,tyargs,args,m) -> - CheckExprOp cenv env (c,tyargs,args,m) context expr + CheckExprOp cenv env (c,tyargs,args,m) context expr // Allow 'typeof' calls as a special case, the only accepted use of System.Void! | TypeOfExpr g ty when isVoidTy g ty -> - false + false // Allow 'typedefof' calls as a special case, the only accepted use of System.Void! | TypeDefOfExpr g ty when isVoidTy g ty -> - false + false // Allow '%expr' in quotations | Expr.App(Expr.Val(vref,_,_),_,tinst,[arg],m) when isSpliceOperator g vref && env.quote -> @@ -821,7 +832,6 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = | [ty] when context.PermitOnlyReturnable && isByrefLikeTy cenv.g m ty -> CheckExprsPermitReturnableByRef cenv env args | _ -> CheckExprsPermitByRefLike cenv env args - | TOp.Tuple tupInfo,_,_ when not (evalTupInfoIsStruct tupInfo) -> match context with | PermitByRefExpr.YesTupleOfArgs nArity -> @@ -853,6 +863,9 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprsNoByRefLike cenv env args + | TOp.LValueOp(LByrefSet _, _),_,_ -> + CheckExprsPermitByRefLike cenv env args + | TOp.TupleFieldGet _,_,[arg1] -> CheckTypeInstNoByrefs cenv env m tyargs CheckExprsPermitByRefLike cenv env [arg1] (* Compiled pattern matches on immutable value structs come through here. *) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 02dde793b4..ca8fa82dab 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -6012,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 @@ -8854,6 +8858,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 _ diff --git a/src/fsharp/ast.fs b/src/fsharp/ast.fs index 8094995e68..caf84422bc 100644 --- a/src/fsharp/ast.fs +++ b/src/fsharp/ast.fs @@ -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,_) -> diff --git a/src/fsharp/service/ServiceAssemblyContent.fs b/src/fsharp/service/ServiceAssemblyContent.fs index f4a7ac416c..4f6b547fa5 100644 --- a/src/fsharp/service/ServiceAssemblyContent.fs +++ b/src/fsharp/service/ServiceAssemblyContent.fs @@ -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 diff --git a/src/fsharp/service/ServiceInterfaceStubGenerator.fs b/src/fsharp/service/ServiceInterfaceStubGenerator.fs index 7532449dc9..2d42bb7c60 100644 --- a/src/fsharp/service/ServiceInterfaceStubGenerator.fs +++ b/src/fsharp/service/ServiceInterfaceStubGenerator.fs @@ -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) diff --git a/src/fsharp/service/ServiceParseTreeWalk.fs b/src/fsharp/service/ServiceParseTreeWalk.fs index 74777d0e2e..a8eb0bfed2 100755 --- a/src/fsharp/service/ServiceParseTreeWalk.fs +++ b/src/fsharp/service/ServiceParseTreeWalk.fs @@ -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 diff --git a/src/fsharp/service/ServiceStructure.fs b/src/fsharp/service/ServiceStructure.fs index ffe2461d95..e2f1c8780d 100644 --- a/src/fsharp/service/ServiceStructure.fs +++ b/src/fsharp/service/ServiceStructure.fs @@ -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 diff --git a/src/fsharp/service/ServiceUntypedParse.fs b/src/fsharp/service/ServiceUntypedParse.fs index 211bcc5833..a9f1fcbb21 100755 --- a/src/fsharp/service/ServiceUntypedParse.fs +++ b/src/fsharp/service/ServiceUntypedParse.fs @@ -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] diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 967b610662..4534963ebd 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -1023,6 +1023,17 @@ module ByrefReturnMemberTests = F1() + module TestAssignToReturnByref2 = + let mutable v = System.DateTime.Now + let M() = &v + + let F1() = + let today = System.DateTime.Now.Date + M() <- today + check "cwecjc" v today + + F1() + module BaseCallByref = type Incrementor(z) = diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index 8291f29404..88fff28af7 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -266,7 +266,98 @@ namespace Tests Test() + module SpanSafetyTests0 = + type SpanLikeType = Span + + let m1 (x: byref>) (y: Span) = + // this is all valid, unconcerned with stack-referring stuff + let local = SpanLikeType() + x <- local + x + + module SpanSafetyTests1 = + type SpanLikeType = Span + let m1 (x: byref>) (y: Span) = + // this is all valid, unconcerned with stack-referring stuff + let local = SpanLikeType() + x <- local + x + let test1 (param1: byref>) (param2: Span) = + let mutable stackReferringBecauseMutable1 = Span() + + //let stackReferringBecauseMutable1 = Span(NativePtr.toVoidPtr(&&x), 1) + //let stackReferringBecauseMutable1 = Span(NativePtr.toVoidPtr(NativePtr.ofByRef(&&x)), 1) + //let stackReferring1 = Span(NativePtr.toVoidPtr(NativePtr.stackalloc< byte>(100), 1) + + let mutable stackReferring2 = Span() + + // this is allowed + stackReferring2 <- m1 &stackReferring2 stackReferringBecauseMutable1 + + // this is NOT allowed + stackReferring2 <- m1 ¶m1 stackReferringBecauseMutable1 + + // this is NOT allowed + param1 <- m1 &stackReferring2 stackReferringBecauseMutable1 + + // this is NOT allowed + let param2 = stackReferringBecauseMutable1.Slice(10) + + // this is allowed + param1 <- Span() + + // this is allowed + stackReferring2 <- param1 + + module SpanSafetyTests2 = + let m2 (x: byref>) = + // should compile + &x + + module SpanSafetyTests3 = + type SpanLikeType = Span + let m1 (x: byref>) (y: Span) = + // this is all valid, unconcerned with stack-referring stuff + let local = SpanLikeType() + x <- local + x + let m2 (x: byref>) = + // should compile + &x + + let test2 (param1: byref>) (param2: Span) = + let mutable stackReferringBecauseMutable1 = Span() + let mutable stackReferring2 = Span() + + let stackReferring3 = &(m2 &stackReferring2) + + // this is allowed + stackReferring3 <- m1 &stackReferring2 stackReferringBecauseMutable1 + + // this is allowed + m2(&stackReferring3) <- stackReferring2 + +#if NEGATIVE + // this is NOT allowed + m1(¶m1) <- stackReferring2 +#endif + + // this is NOT allowed + param1 <- stackReferring3 + +#if NEGATIVE + // this is NOT allowed + &stackReferring3 +#endif + + // this is allowed + //¶m1 - uncomment to test return + + module SpanSafetyTests4 = + let test2 (param1: byref>) (param2: Span) = + // this is allowed + ¶m1 // uncomment to test return #if NEGATIVE diff --git a/tests/service/ProjectOptionsTests.fs b/tests/service/ProjectOptionsTests.fs index 3ab2e1c2da..b390f53e62 100644 --- a/tests/service/ProjectOptionsTests.fs +++ b/tests/service/ProjectOptionsTests.fs @@ -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" From b8f29fc4b453e6e0529a160ca42ae8e971a7d18a Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 2 Jun 2018 18:56:53 +0100 Subject: [PATCH 55/61] restrict addresses of immutable top-level things --- .../FSharp.Compiler.Private/FSComp.fs | 26 +- .../FSharp.Compiler.Private/FSComp.resx | 19 +- src/fsharp/FSComp.txt | 4 +- src/fsharp/IlxGen.fs | 5 +- src/fsharp/Optimizer.fs | 4 +- src/fsharp/PostInferenceChecks.fs | 207 +++++++++------- src/fsharp/QuotationTranslator.fs | 4 +- src/fsharp/TastOps.fs | 228 +++++++++--------- src/fsharp/TastPickle.fs | 4 +- src/fsharp/TypeChecker.fs | 2 +- src/fsharp/autobox.fs | 2 +- src/fsharp/symbols/Exprs.fs | 4 +- src/fsharp/tast.fs | 4 +- src/fsharp/xlf/FSComp.txt.cs.xlf | 14 +- src/fsharp/xlf/FSComp.txt.de.xlf | 14 +- src/fsharp/xlf/FSComp.txt.en.xlf | 14 +- src/fsharp/xlf/FSComp.txt.es.xlf | 14 +- src/fsharp/xlf/FSComp.txt.fr.xlf | 14 +- src/fsharp/xlf/FSComp.txt.it.xlf | 14 +- src/fsharp/xlf/FSComp.txt.ja.xlf | 14 +- src/fsharp/xlf/FSComp.txt.ko.xlf | 14 +- src/fsharp/xlf/FSComp.txt.pl.xlf | 14 +- src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 14 +- src/fsharp/xlf/FSComp.txt.ru.xlf | 14 +- src/fsharp/xlf/FSComp.txt.tr.xlf | 14 +- src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 14 +- src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 14 +- tests/fsharp/core/byrefs/test.fsx | 68 ++++-- tests/fsharp/core/span/test.fsx | 63 ++--- 29 files changed, 543 insertions(+), 297 deletions(-) diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index 9aa6f5a554..5fa332202c 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -4027,9 +4027,9 @@ type internal SR private() = /// Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression. /// (Originally from ..\FSComp.txt:1333) static member tcCouldNotFindOffsetToStringData() = (3208, GetStringFunc("tcCouldNotFindOffsetToStringData",",,,") ) - /// The address of the variable '%s' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not escape its scope. + /// 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. /// (Originally from ..\FSComp.txt:1334) - static member chkNoByrefReturnOfLocal(a0 : System.String) = (3209, GetStringFunc("chkNoByrefReturnOfLocal",",,,%s,,,") a0) + static member chkNoByrefAddressOfLocal(a0 : System.String) = (3209, GetStringFunc("chkNoByrefAddressOfLocal",",,,%s,,,") a0) /// %s is an active pattern and cannot be treated as a discriminated union case with named fields. /// (Originally from ..\FSComp.txt:1335) static member tcNamedActivePattern(a0 : System.String) = (3210, GetStringFunc("tcNamedActivePattern",",,,%s,,,") a0) @@ -4321,6 +4321,21 @@ type internal SR private() = /// 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)'. /// (Originally from ..\FSComp.txt:1431) static member tcByrefReturnImplicitlyDereferenced() = (3226, GetStringFunc("tcByrefReturnImplicitlyDereferenced",",,,") ) + /// A type annotated with IsByRefLike must also be a struct. + /// (Originally from ..\FSComp.txt:1432) + static member tcByRefLikeNotStruct() = (3227, GetStringFunc("tcByRefLikeNotStruct",",,,") ) + /// 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. + /// (Originally from ..\FSComp.txt:1433) + static member chkNoByrefReturnOfLocal(a0 : System.String) = (3228, GetStringFunc("chkNoByrefReturnOfLocal",",,,%s,,,") a0) + /// The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + /// (Originally from ..\FSComp.txt:1434) + static member chkNoReturnOfLimitedSpan() = (3229, GetStringFunc("chkNoReturnOfLimitedSpan",",,,") ) + /// 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. + /// (Originally from ..\FSComp.txt:1435) + static member chkNoWriteToLimitedSpan(a0 : System.String) = (3230, GetStringFunc("chkNoWriteToLimitedSpan",",,,%s,,,") a0) + /// A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + /// (Originally from ..\FSComp.txt:1436) + static member tastValueMustBeLocal() = (3231, GetStringFunc("tastValueMustBeLocal",",,,") ) /// Call this method once to validate that all known resources are valid; throws if not static member RunStartupValidation() = @@ -5628,7 +5643,7 @@ type internal SR private() = ignore(GetString("CallerMemberNameIsOverriden")) ignore(GetString("tcFixedNotAllowed")) ignore(GetString("tcCouldNotFindOffsetToStringData")) - ignore(GetString("chkNoByrefReturnOfLocal")) + ignore(GetString("chkNoByrefAddressOfLocal")) ignore(GetString("tcNamedActivePattern")) ignore(GetString("DefaultParameterValueNotAppropriateForArgument")) ignore(GetString("tcGlobalsSystemTypeNotFound")) @@ -5726,4 +5741,9 @@ type internal SR private() = ignore(GetString("writeToReadOnlyByref")) ignore(GetString("readOnlyAttributeOnStructWithMutableField")) ignore(GetString("tcByrefReturnImplicitlyDereferenced")) + ignore(GetString("tcByRefLikeNotStruct")) + ignore(GetString("chkNoByrefReturnOfLocal")) + ignore(GetString("chkNoReturnOfLimitedSpan")) + ignore(GetString("chkNoWriteToLimitedSpan")) + ignore(GetString("tastValueMustBeLocal")) () diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index 089ac330cd..38380196ea 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -4029,8 +4029,8 @@ Could not find method System.Runtime.CompilerServices.OffsetToStringData in references when building 'fixed' expression. - - The address of the variable '{0}' cannot be used at this point. The address of this local value may not be passed to a call returning a byref-like type which is then subsequently returned from this method or function. This is to ensure the address of the local value does not escape its scope. + + 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. {0} is an active pattern and cannot be treated as a discriminated union case with named fields. @@ -4324,4 +4324,19 @@ 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)'. + + A type annotated with IsByRefLike must also be a struct. + + + 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. + + + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + 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. + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + \ No newline at end of file diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index 4c3edcecaa..f777801574 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1431,4 +1431,6 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 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." 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 ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their 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 = ...'" diff --git a/src/fsharp/IlxGen.fs b/src/fsharp/IlxGen.fs index 4710a42beb..7b8a43db80 100644 --- a/src/fsharp/IlxGen.fs +++ b/src/fsharp/IlxGen.fs @@ -1955,7 +1955,7 @@ let rec GenExpr (cenv:cenv) (cgbuf:CodeGenBuffer) eenv sp 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 @@ -3387,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 -> diff --git a/src/fsharp/Optimizer.fs b/src/fsharp/Optimizer.fs index 8de0fdcd8d..7066a47ac1 100644 --- a/src/fsharp/Optimizer.fs +++ b/src/fsharp/Optimizer.fs @@ -1276,7 +1276,7 @@ and OpHasEffect g m op = | 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 (LGetAddr _, lv) -> lv.IsMutable + | TOp.LValueOp (LAddrOf _, lv) -> lv.IsMutable | TOp.UnionCaseFieldSet _ | TOp.ExnFieldSet _ | TOp.Coerce @@ -1791,7 +1791,7 @@ and OptimizeExprOp cenv env (op, tyargs, args, m) = MightMakeCriticalTailcall=false Info=UnknownValue } (* Handle addresses *) - | TOp.LValueOp ((LGetAddr _ as lop), lv), _, _ -> + | TOp.LValueOp ((LAddrOf _ as lop), lv), _, _ -> let e, _ = OptimizeExpr cenv env (exprForValRef m lv) let op' = match e with diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 1a56d8f21c..edd25cff7f 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -516,7 +516,7 @@ let rec CheckExprNoByrefs cenv env expr = CheckExpr cenv env expr PermitByRefExpr.No |> ignoreLimit /// Check a value -and CheckVal (cenv:cenv) (env:env) v m (context: PermitByRefExpr) = +and CheckValRef (cenv:cenv) (env:env) v m (context: PermitByRefExpr) = if cenv.reportErrors then if isSpliceOperator cenv.g v && not env.quote then errorR(Error(FSComp.SR.chkSplicingOnlyInQuotations(), m)) @@ -529,6 +529,53 @@ and CheckVal (cenv:cenv) (env:env) v m (context: PermitByRefExpr) = errorR(Error(FSComp.SR.chkNoByrefAtThisPoint(v.DisplayName), m)) CheckTypePermitAllByrefs cenv env m v.Type // the byref checks are done at the actual binding of the value + +and IsLimitedType g m ty = + isByrefLikeTy g m ty && + not (isByrefTy g ty) + +and IsLimited cenv env m (vref: ValRef) = + IsLimitedType cenv.g m vref.Type && + // The value is a arg/local.... + vref.ValReprInfo.IsNone && + // The value is a limited Span or might have become one through mutation + let isMutableLocal = not (env.argVals.ContainsVal(vref.Deref)) && vref.IsMutable + let isLimitedLocal = cenv.limitVals.ContainsKey(vref.Stamp) + isMutableLocal || isLimitedLocal + +/// Check a use of a value +and CheckValUse (cenv: cenv) (env: env) (vref: ValRef, vFlags, m) (context: PermitByRefExpr) = + + let g = cenv.g + // Is this a Span-typed value that is limited (i.e. can't be returned) + let limit = IsLimited cenv env m vref + + if cenv.reportErrors then + + if vref.BaseOrThisInfo = BaseVal then + errorR(Error(FSComp.SR.chkLimitationsOfBaseKeyword(), m)) + + let isCallOfConstructorOfAbstractType = + (match vFlags with NormalValUse -> true | _ -> false) && + vref.IsConstructor && + (match vref.DeclaringEntity with Parent tcref -> isAbstractTycon tcref.Deref | _ -> false) + + if isCallOfConstructorOfAbstractType then + errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(),m)) + + let isReturnExprBuiltUsingByRefLocal = + isByrefTy g vref.Type && + context.PermitOnlyReturnable && + // The value is a local.... + vref.ValReprInfo.IsNone && + // The value is not an argument.... + not (env.argVals.ContainsVal(vref.Deref)) + + if isReturnExprBuiltUsingByRefLocal then + errorR(Error(FSComp.SR.chkNoByrefReturnOfLocal(vref.DisplayName), m)) + + CheckValRef cenv env vref m context + limit /// Check an expression, given information about the position of the expression and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = @@ -556,63 +603,27 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = CheckTypePermitOuterByRefLike cenv env m ty false - | Expr.Val (v,vFlags,m) -> - - // Is this a Span-typed value that is limited (i.e. can't be returned) - let limit = - isByrefLikeTy g m v.Type && - not (isByrefTy g v.Type) && - // The value is a local.... - v.ValReprInfo.IsNone && - // The value is a limited Span or might have become one through mutation - (v.IsMutable || cenv.limitVals.ContainsKey(v.Stamp)) - - if cenv.reportErrors then - - if v.BaseOrThisInfo = BaseVal then - errorR(Error(FSComp.SR.chkLimitationsOfBaseKeyword(), m)) - - let isCallOfConstructorOfAbstractType = - (match vFlags with NormalValUse -> true | _ -> false) && - v.IsConstructor && - (match v.DeclaringEntity with Parent tcref -> isAbstractTycon tcref.Deref | _ -> false) - - if isCallOfConstructorOfAbstractType then - errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(),m)) - - let isReturnExprBuiltUsingByRefLocal = - isByrefTy g v.Type && - context.PermitOnlyReturnable && - // The value is a local.... - v.ValReprInfo.IsNone && - // The value is not an argument.... - not (env.argVals.ContainsVal(v.Deref)) - - if isReturnExprBuiltUsingByRefLocal then - errorR(Error(FSComp.SR.chkNoByrefReturnOfLocal(v.DisplayName), m)) - - CheckVal cenv env v m context - limit + | Expr.Val (vref,vFlags,m) -> + CheckValUse cenv env (vref, vFlags, m) context | Expr.Quote(ast,savedConv,_isFromQueryExpression,m,ty) -> - CheckExprNoByrefs cenv {env with quote=true} ast - - if cenv.reportErrors then - cenv.usesQuotations <- true - - // Translate to quotation data - try - let qscope = QuotationTranslator.QuotationGenerationScope.Create (g,cenv.amap,cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.No) - let qdata = QuotationTranslator.ConvExprPublic qscope QuotationTranslator.QuotationTranslationEnv.Empty ast - let typeDefs,spliceTypes,spliceExprs = qscope.Close() - match savedConv.Value with - | None -> savedConv:= Some (typeDefs, List.map fst spliceTypes, List.map fst spliceExprs, qdata) - | Some _ -> () - with QuotationTranslator.InvalidQuotedTerm e -> - errorRecovery e m + CheckExprNoByrefs cenv {env with quote=true} ast + if cenv.reportErrors then + cenv.usesQuotations <- true + + // Translate to quotation data + try + let qscope = QuotationTranslator.QuotationGenerationScope.Create (g,cenv.amap,cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.No) + let qdata = QuotationTranslator.ConvExprPublic qscope QuotationTranslator.QuotationTranslationEnv.Empty ast + let typeDefs,spliceTypes,spliceExprs = qscope.Close() + match savedConv.Value with + | None -> savedConv:= Some (typeDefs, List.map fst spliceTypes, List.map fst spliceExprs, qdata) + | Some _ -> () + with QuotationTranslator.InvalidQuotedTerm e -> + errorRecovery e m - CheckTypeNoByrefs cenv env m ty - false + CheckTypeNoByrefs cenv env m ty + false | Expr.Obj (_,typ,basev,superInitCall,overrides,iimpls,m) -> CheckExprNoByrefs cenv env superInitCall @@ -640,8 +651,8 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(v.DisplayName),m)) false else - CheckVal cenv env v m PermitByRefExpr.No - CheckVal cenv env baseVal m PermitByRefExpr.No + CheckValRef cenv env v m PermitByRefExpr.No + CheckValRef cenv env baseVal m PermitByRefExpr.No CheckTypeInstNoByrefs cenv env m tyargs CheckExprs cenv env rest (mkArgsForAppliedExpr true false rest f) @@ -667,7 +678,7 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = CheckTypeInstNoByrefs cenv env m enclTypeArgs CheckTypeInstNoByrefs cenv env m methTypeArgs CheckTypeInstNoByrefs cenv env m tys - CheckVal cenv env baseVal m PermitByRefExpr.No + CheckValRef cenv env baseVal m PermitByRefExpr.No CheckExprsPermitByRefLike cenv env rest | Expr.Op (c,tyargs,args,m) -> @@ -792,7 +803,8 @@ and CheckInterfaceImpl cenv env baseValOpt (_ty,overrides) = CheckMethods cenv env baseValOpt overrides and CheckExprOp cenv env (op,tyargs,args,m) context expr = - let limitedCheck() = + let g = cenv.g + let ctorLimitedZoneCheck() = if env.ctorLimitedZone then errorR(Error(FSComp.SR.chkObjCtorsCantUseExceptionHandling(), m)) (* Special cases *) @@ -804,7 +816,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = | TOp.TryFinally _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],e2,_,_)] -> CheckTypeInstPermitAllByrefs cenv env m tyargs // result of a try/finally can be a byref - limitedCheck() + ctorLimitedZoneCheck() let limit = CheckExpr cenv env e1 context // result of a try/finally can be a byref if in a position where the overall expression is can be a byref CheckExprNoByrefs cenv env e2 limit @@ -815,7 +827,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = | TOp.TryCatch _,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],_e2,_,_); Expr.Lambda(_,_,_,[_],e3,_,_)] -> CheckTypeInstPermitAllByrefs cenv env m tyargs // result of a try/catch can be a byref - limitedCheck() + ctorLimitedZoneCheck() let limit1 = CheckExpr cenv env e1 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref // [(* e2; -- don't check filter body - duplicates logic in 'catch' body *) e3] let limit2 = CheckExpr cenv env e3 context // result of a try/catch can be a byref if in a position where the overall expression is can be a byref @@ -829,7 +841,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // if return is a byref, and being used as a return, then all arguments must be usable as byref returns match tys with - | [ty] when context.PermitOnlyReturnable && isByrefLikeTy cenv.g m ty -> CheckExprsPermitReturnableByRef cenv env args + | [ty] when context.PermitOnlyReturnable && isByrefLikeTy g m ty -> CheckExprsPermitReturnableByRef cenv env args | _ -> CheckExprsPermitByRefLike cenv env args | TOp.Tuple tupInfo,_,_ when not (evalTupInfoIsStruct tupInfo) -> @@ -845,26 +857,43 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckTypeInstNoByrefs cenv env m tyargs CheckExprsNoByRefLike cenv env args - | TOp.LValueOp(LGetAddr _,v),_,_ -> + | TOp.LValueOp(LAddrOf _,vref),_,_ -> if cenv.reportErrors then if context.Disallow then - errorR(Error(FSComp.SR.chkNoAddressOfAtThisPoint(v.DisplayName), m)) + errorR(Error(FSComp.SR.chkNoAddressOfAtThisPoint(vref.DisplayName), m)) let returningAddrOfLocal = context.PermitOnlyReturnable && // The value is a local.... - v.ValReprInfo.IsNone && + vref.ValReprInfo.IsNone && // The value is not an argument... - not (env.argVals.ContainsVal(v.Deref)) + not (env.argVals.ContainsVal(vref.Deref)) if returningAddrOfLocal then - errorR(Error(FSComp.SR.chkNoByrefAddressOfLocal(v.DisplayName), m)) + errorR(Error(FSComp.SR.chkNoByrefAddressOfLocal(vref.DisplayName), m)) - CheckExprsNoByRefLike cenv env args + let limit1 = IsLimited cenv env m vref + let limit2 = CheckExprsNoByRefLike cenv env args + limit1 || limit2 + + | TOp.LValueOp(LByrefSet,vref),_,[arg] -> + let limit1 = IsLimitedType g m (tyOfExpr g arg) && not (env.argVals.ContainsVal(vref.Deref)) + let limit2 = CheckExprPermitByRefLike cenv env arg + if not limit1 && limit2 then + errorR(Error(FSComp.SR.chkNoWriteToLimitedSpan(vref.DisplayName), m)) + false - | TOp.LValueOp(LByrefSet _, _),_,_ -> - CheckExprsPermitByRefLike cenv env args + | TOp.LValueOp(LByrefGet,vref),_,[] -> + let limit1 = isByrefTy g vref.Type && IsLimitedType g m (destByrefTy g vref.Type) && not (env.argVals.ContainsVal(vref.Deref)) + limit1 + + | TOp.LValueOp(LSet _, vref),_,[arg] -> + let limit1 = IsLimited cenv env m vref + let limit2 = CheckExprPermitByRefLike cenv env arg + if not limit1 && limit2 then + errorR(Error(FSComp.SR.chkNoWriteToLimitedSpan(vref.DisplayName), m)) + false | TOp.TupleFieldGet _,_,[arg1] -> CheckTypeInstNoByrefs cenv env m tyargs @@ -894,7 +923,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // Check get of static field | TOp.ValFieldGetAddr (rfref, _readonly),tyargs,[] -> - if context.Disallow && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then errorR(Error(FSComp.SR.chkNoAddressStaticFieldAtThisPoint(rfref.FieldName), m)) CheckTypeInstNoByrefs cenv env m tyargs @@ -903,7 +932,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // Check get of instance field | TOp.ValFieldGetAddr (rfref, _readonly),tyargs,[obj] -> - if context.Disallow && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(rfref.FieldName), m)) // This construct is used for &(rx.rfield) and &(rx->rfield). Relax to permit byref types for rx. [See Bug 1263]. @@ -920,7 +949,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = | TOp.UnionCaseFieldGetAddr (uref, _idx, _readonly),tyargs,[rx] -> - if context.Disallow && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(uref.CaseName), m)) CheckTypeInstNoByrefs cenv env m tyargs @@ -948,13 +977,13 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprsPermitByRefLike cenv env args | [ I_ldflda (fspec) | I_ldsflda (fspec) ],_ -> - if context.Disallow && cenv.reportErrors && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(fspec.Name), m)) // permit byref for lhs lvalue CheckExprsPermitByRefLike cenv env args | [ I_ldelema (_,isNativePtr,_,_) ],lhsArray::indices -> - if context.Disallow && cenv.reportErrors && not isNativePtr && isByrefLikeTy cenv.g m (tyOfExpr cenv.g expr) then + if context.Disallow && cenv.reportErrors && not isNativePtr && isByrefLikeTy g m (tyOfExpr g expr) then errorR(Error(FSComp.SR.chkNoAddressOfArrayElementAtThisPoint(), m)) // permit byref for lhs lvalue let limit = CheckExprPermitByRefLike cenv env lhsArray @@ -978,18 +1007,19 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprsNoByRefLike cenv env args and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValInfo alwaysCheckNoReraise e m ety = + let g = cenv.g // The topValInfo here says we are _guaranteeing_ to compile a function value // as a .NET method with precisely the corresponding argument counts. match e with | Expr.TyChoose(tps,e1,m) -> - let env = BindTypars cenv.g env tps + let env = BindTypars g env tps CheckLambdas isTop memInfo cenv env inlined topValInfo alwaysCheckNoReraise e1 m ety | Expr.Lambda (_,_,_,_,_,m,_) | Expr.TyLambda(_,_,_,m,_) -> - let tps,ctorThisValOpt,baseValOpt,vsl,body,bodyty = destTopLambda cenv.g cenv.amap topValInfo (e, ety) in - let env = BindTypars cenv.g env tps + let tps,ctorThisValOpt,baseValOpt,vsl,body,bodyty = destTopLambda g cenv.amap topValInfo (e, ety) in + let env = BindTypars g env tps let thisAndBase = Option.toList ctorThisValOpt @ Option.toList baseValOpt let restArgs = List.concat vsl let syntacticArgs = thisAndBase @ restArgs @@ -1005,7 +1035,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn | true, firstArg::_ -> firstArg.SetHasBeenReferenced() | _ -> () // any byRef arguments are considered used, as they may be 'out's - restArgs |> List.iter (fun arg -> if isByrefTy cenv.g arg.Type then arg.SetHasBeenReferenced()) + restArgs |> List.iter (fun arg -> if isByrefTy g arg.Type then arg.SetHasBeenReferenced()) syntacticArgs |> List.iter (CheckValSpec cenv env) syntacticArgs |> List.iter (BindVal cenv env) @@ -1023,7 +1053,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // Check the body of the lambda let limit = - if isTop && not cenv.g.compilingFslib && isByrefLikeTy cenv.g m bodyty then + if isTop && not g.compilingFslib && isByrefLikeTy g m bodyty then // allow byref to occur as return position for byref-typed top level function or method CheckExprPermitReturnableByRef cenv env body else @@ -1036,16 +1066,16 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn CheckForByrefLikeType cenv env m bodyty (fun () -> errorR(Error(FSComp.SR.chkFirstClassFuncNoByref(), m))) - elif not cenv.g.compilingFslib && isByrefTy cenv.g bodyty then + elif not g.compilingFslib && isByrefTy g bodyty then // check no byrefs-in-the-byref - CheckForByrefType cenv env (destByrefTy cenv.g bodyty) (fun () -> + CheckForByrefType cenv env (destByrefTy g bodyty) (fun () -> errorR(Error(FSComp.SR.chkReturnTypeNoByref(), m))) if limit then errorR(Error(FSComp.SR.chkNoReturnOfLimitedSpan(), m)) for tp in tps do - if tp.Constraints |> List.sumBy (function TyparConstraint.CoercesTo(ty,_) when isClassTy cenv.g ty -> 1 | _ -> 0) > 1 then + if tp.Constraints |> List.sumBy (function TyparConstraint.CoercesTo(ty,_) when isClassTy g ty -> 1 | _ -> 0) > 1 then errorR(Error(FSComp.SR.chkTyparMultipleClassConstraints(), m)) false @@ -1055,7 +1085,7 @@ and CheckLambdas isTop (memInfo: ValMemberInfo option) cenv env inlined topValIn // Permit byrefs for let x = ... CheckTypePermitAllByrefs cenv env m ety let limit = - if not inlined && (isByrefLikeTy cenv.g m ety || isNativePtrTy cenv.g ety) then + if not inlined && (isByrefLikeTy g m ety || isNativePtrTy g ety) then // allow byref to occur as RHS of byref binding. CheckExprPermitByRefLike cenv env e else @@ -1134,6 +1164,7 @@ and CheckAttribExpr cenv env (AttribExpr(expr,vexpr)) = CheckAttribArgExpr cenv env vexpr and CheckAttribArgExpr cenv env expr = + let g = cenv.g match expr with // Detect standard constants @@ -1160,15 +1191,15 @@ and CheckAttribArgExpr cenv env expr = | Expr.Op(TOp.Array,[_elemTy],args,_m) -> List.iter (CheckAttribArgExpr cenv env) args - | TypeOfExpr cenv.g _ -> + | TypeOfExpr g _ -> () - | TypeDefOfExpr cenv.g _ -> + | TypeDefOfExpr g _ -> () | Expr.Op(TOp.Coerce,_,[arg],_) -> CheckAttribArgExpr cenv env arg - | EnumExpr cenv.g arg1 -> + | EnumExpr g arg1 -> CheckAttribArgExpr cenv env arg1 - | AttribBitwiseOrExpr cenv.g (arg1,arg2) -> + | AttribBitwiseOrExpr g (arg1,arg2) -> CheckAttribArgExpr cenv env arg1 CheckAttribArgExpr cenv env arg2 | _ -> diff --git a/src/fsharp/QuotationTranslator.fs b/src/fsharp/QuotationTranslator.fs index d383138b9e..f9eac0c07a 100644 --- a/src/fsharp/QuotationTranslator.fs +++ b/src/fsharp/QuotationTranslator.fs @@ -518,7 +518,7 @@ and private ConvExprCore cenv (env : QuotationTranslationEnv) (expr: Expr) : QP. // rebuild reraise() 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] -> @@ -665,7 +665,7 @@ 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.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 diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 11a664c989..861a341277 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -1329,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 readonly v = Expr.Op (TOp.LValueOp (LGetAddr readonly, v), [], [], m) +let mkValAddr m readonly v = Expr.Op (TOp.LValueOp (LAddrOf readonly, v), [], [], m) //-------------------------------------------------------------------------- // Maps tracking extra information for values @@ -3145,7 +3145,7 @@ module DebugPrint = begin let lvalopL x = match x with - | LGetAddr readonly -> wordL (tagText (sprintf "LGetAddr(%b)" readonly)) + | LAddrOf readonly -> wordL (tagText (sprintf "LAddrOf(%b)" readonly)) | LByrefGet -> wordL (tagText "LByrefGet") | LSet -> wordL (tagText "LSet") | LByrefSet -> wordL (tagText "LByrefSet") @@ -5424,7 +5424,7 @@ let rec tyOfExpr g e = | 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 readonly, v) -> mkByrefTyWithFlag g readonly v.Type + | 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") @@ -5691,26 +5691,30 @@ let isRecdOrStructTyReadOnly (g: TcGlobals) m 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 m (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 && + 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 match mut with | NeverMutates -> true - | PossiblyMutates -> isRecdOrStructTyReadOnly g m v.Type + | PossiblyMutates -> isRecdOrStructTyReadOnly g m vref.Type | DefinitelyMutates -> false | AddressOfOp -> true // you can take the address but you might get a (readonly) inref as a result -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 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 @@ -5729,111 +5733,115 @@ let CanTakeAddressOfUnionFieldRef (g:TcGlobals) m (uref: UnionCaseRef) 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 readonly pointer (e.g. the address of /// -let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m = - if not mustTakeAddress then - None, e, false - else - match e with - // LVALUE: "x" where "x" is byref - | Expr.Op (TOp.LValueOp (LByrefGet, v), _, [], m) -> - let readonly = isInByrefTy g v.Type - None, exprForValRef m v, readonly - - // 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 m v mut -> - let readonly = not (MustTakeAddressOfVal g v) - None, mkValAddr m readonly v, readonly - - // LVALUE: "x" where "e.x" is record field. - | Expr.Op (TOp.ValFieldGet rfref, tinst, [e], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref mut -> - let exprty = tyOfExpr g e - let wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m - let readonly = readonly || not (MustTakeAddressOfRecdFieldRef rfref) - wrap, mkRecdFieldGetAddrViaExprAddr(readonly, expra, rfref, tinst, m), readonly - - // LVALUE: "x" where "e.x" is union field - | Expr.Op (TOp.UnionCaseFieldGet (uref, cidx), tinst, [e], m) when MustTakeAddressOfRecdField (uref.FieldByIndex(cidx)) || CanTakeAddressOfUnionFieldRef g m uref mut -> - let exprty = tyOfExpr g e - let wrap, expra, readonly = mkExprAddrOfExprAux g (isStructTy g exprty) false mut e None m - let readonly = readonly || not (MustTakeAddressOfRecdField (uref.FieldByIndex(cidx))) - wrap, mkUnionCaseFieldGetAddrProvenViaExprAddr(readonly, expra, uref, tinst, cidx, m), readonly - - // LVALUE: "x" where "e.x" is a .NET static field. - | Expr.Op (TOp.ILAsm ([IL.I_ldsfld(_vol, fspec)], [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 - // 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 e 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 m rfref 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) -> +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) -> + let readonly = isInByrefTy g vref.Type + None, exprForValRef m vref, readonly + + // 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 of "e.f" where "f" is record field. + | Expr.Op (TOp.ValFieldGet rfref, tinst, [obje], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref 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 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) -> + 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 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 of "f" where "f" is a static F# field. + | Expr.Op (TOp.ValFieldGet rfref, tinst, [], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref mut -> + let readonly = not (MustTakeAddressOfRecdFieldRef rfref) + None, mkStaticRecdFieldGetAddr(readonly, rfref, tinst, m), readonly + + // LVALUE of "e.[n]" where e is an array of structs + | Expr.App(Expr.Val(vf, _, _), _, [elemTy], [aexpr;nexpr], _) when (valRefEq g vf g.array_get_vref) -> - let readonly = false // array address is never forced to be readonly - let shape = ILArrayShape.SingleDimensional - 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, 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) -> + let readonly = false // array address is never forced to be readonly + let shape = ILArrayShape.SingleDimensional + 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, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, [aexpr; nexpr], m), readonly + + // 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 ilInstrReadOnlyAnnotation = if isTyparTy g elemTy && useReadonlyForGenericArrayAddress then ReadonlyAddress else NormalAddress - let isNativePtr = - match addrExprVal with - | Some(vf) -> valRefEq g vf g.addrof2_vref - | _ -> false + let readonly = false // array address is never forced to be readonly + let shape = ILArrayShape.FromRank args.Length + 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, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, (aexpr::args), m), readonly + None, mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, (aexpr::args), m), readonly - | Expr.Val(v, _, m) when isByrefTy g v.Type -> - error(Error(FSComp.SR.tastUnexpectedByRef(), m)) + // 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(v, _, m) when (mut = DefinitelyMutates || mut = AddressOfOp) && v.IsMutable -> - error(Error(FSComp.SR.tastInvalidAddressOfMutableAcrossAssemblyBoundary(), 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 DefinitelyMutates on immutable values - | Expr.Val _ when mut = DefinitelyMutates -> - error(Error(FSComp.SR.tastValueMustBeMutable(), m)) + // Give a nice error message for AddressOfOp on immutable values + | Expr.Val _ when mut = AddressOfOp -> + error(Error(FSComp.SR.tastValueMustBeLocal(), m)) + + | Expr.Val _ when mut = DefinitelyMutates -> + error(Error(FSComp.SR.tastValueMustBeMutable(), m)) - // LVALUE: "&meth(args)" where meth has a byref return. Includes "&span.[idx]". - | Expr.Let(TBind(v, e, _), Expr.Op(TOp.LValueOp (LByrefGet, v2), _, _, _), _, _) when isByrefTy g v.Type && (valRefEq g (mkLocalValRef v) v2) -> - let readonly = isInByrefTy g (tyOfExpr g e) - None, e, readonly + // LVALUE: "&meth(args)" where meth has a byref return. Includes "&span.[idx]". + | Expr.Let(TBind(vref, e, _), Expr.Op(TOp.LValueOp (LByrefGet, vref2), _, _, _), _, _) when isByrefTy g vref.Type && (valRefEq g (mkLocalValRef vref) vref2) -> + let readonly = isInByrefTy g (tyOfExpr g e) + None, e, readonly - | _ -> - let ty = tyOfExpr g e - if isStructTy g ty then - match mut with - | NeverMutates -> () - | AddressOfOp -> () // we get an inref - | DefinitelyMutates -> - errorR(Error(FSComp.SR.tastInvalidMutationOfConstant(), m)); - | PossiblyMutates -> - warning(DefensiveCopyWarning(FSComp.SR.tastValueHasBeenCopied(), m)); - let tmp, _ = - match mut with - | NeverMutates -> mkCompGenLocal m "copyOfStruct" ty - | _ -> mkMutableCompGenLocal m "copyOfStruct" ty - let readonly = true - Some (tmp, e), (mkValAddr m readonly (mkLocalValRef tmp)), readonly + | _ -> + 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)); + | PossiblyMutates -> + warning(DefensiveCopyWarning(FSComp.SR.tastValueHasBeenCopied(), m)); + let tmp, _ = + match mut with + | NeverMutates -> mkCompGenLocal m "copyOfStruct" ty + | _ -> mkMutableCompGenLocal m "copyOfStruct" ty + let readonly = true + Some (tmp, expr), (mkValAddr m readonly (mkLocalValRef tmp)), readonly + else + None, expr, false let mkExprAddrOfExpr g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m = let optBind, addre, readonly = mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress mut e addrExprVal m diff --git a/src/fsharp/TastPickle.fs b/src/fsharp/TastPickle.fs index 77b8883a28..ceceb737ca 100755 --- a/src/fsharp/TastPickle.fs +++ b/src/fsharp/TastPickle.fs @@ -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 false + | 0 -> LAddrOf false | 1 -> LByrefGet | 2 -> LSet | 3 -> LByrefSet diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index ca8fa82dab..f3b4c24aa6 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -12696,7 +12696,7 @@ module IncrClassChecking = Some (localRep.MakeValueAssign thisValOpt thisTyInst safeStaticInitInfo v arg m) // Rewrite taking the address of mutable values stored as fields - | Expr.Op(TOp.LValueOp (LGetAddr readonly, ValDeref v), [], [] , m) + | Expr.Op(TOp.LValueOp (LAddrOf readonly, ValDeref v), [], [] , m) when localRep.IsValWithRepresentation(v) -> Some (localRep.MakeValueGetAddress readonly thisValOpt thisTyInst safeStaticInitInfo v m) diff --git a/src/fsharp/autobox.fs b/src/fsharp/autobox.fs index fc6bfcf902..35f2ec04ec 100644 --- a/src/fsharp/autobox.fs +++ b/src/fsharp/autobox.fs @@ -147,7 +147,7 @@ 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 readonly, 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 (readonly, nve, mkRefCellContentsRef g, [v.Type], m)) diff --git a/src/fsharp/symbols/Exprs.fs b/src/fsharp/symbols/Exprs.fs index d393a66612..31aa2e29d7 100644 --- a/src/fsharp/symbols/Exprs.fs +++ b/src/fsharp/symbols/Exprs.fs @@ -302,7 +302,7 @@ module FSharpExprConvert = match expr with | Expr.Op(op, tyargs, args, m) -> match op, args, tyargs with - | TOp.LValueOp(LGetAddr _, vref), _, _ -> exprForValRef m vref + | TOp.LValueOp(LAddrOf _, vref), _, _ -> exprForValRef m vref | TOp.ValFieldGetAddr(rfref, _), [], _ -> mkStaticRecdFieldGet(rfref, tyargs, m) | TOp.ValFieldGetAddr(rfref, _), [arg], _ -> mkRecdFieldGetViaExprAddr(exprOfExprAddr cenv arg, rfref, tyargs, m) | TOp.UnionCaseFieldGetAddr(uref, n, _), [arg], _ -> mkUnionCaseFieldGetProvenViaExprAddr(exprOfExprAddr cenv arg, uref, tyargs, n, m) @@ -755,7 +755,7 @@ module FSharpExprConvert = // rebuild reraise() 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] -> diff --git a/src/fsharp/tast.fs b/src/fsharp/tast.fs index 78be995b91..e1f089ae4a 100644 --- a/src/fsharp/tast.fs +++ b/src/fsharp/tast.fs @@ -4767,12 +4767,12 @@ and ForLoopStyle = /// Indicates what kind of pointer operation this is. and LValueOperation = /// In C syntax this is: &localv - | LGetAddr of readonly: bool + | LAddrOf of readonly: bool /// In C syntax this is: *localv_ptr | LByrefGet - /// In C syntax this is: localv = e , note == *(&localv) = e == LGetAddr; LByrefSet + /// In C syntax this is: localv = e , note == *(&localv) = e == LAddrOf; LByrefSet | LSet /// In C syntax this is: *localv_ptr = e diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 11a3ed832a..4c81fb81a0 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index 9a80d8b66c..b4a3c5c87b 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.en.xlf b/src/fsharp/xlf/FSComp.txt.en.xlf index efea229869..74cccf06fd 100644 --- a/src/fsharp/xlf/FSComp.txt.en.xlf +++ b/src/fsharp/xlf/FSComp.txt.en.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index de8ee3a6a6..0332cf8abe 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index cc7ec0e928..27a44625a1 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 046e22bc80..92bee6457b 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index f3b671a16e..d77bc884bb 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index d3733c4f94..744117a34a 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index 70180a654d..63f9a6b249 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index 7d99d0bc7b..5cb9ca0287 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 1fa00fc866..861ddeeddb 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index e75da76026..e244a77706 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 23cc61a32a..7a38c78c4b 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index c04f64363e..9ea0697b42 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -7018,8 +7018,18 @@ - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. - The ByRef-like expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + The IsByRefLike expression cannot be returned from this function or method, because it is composed using elements that may escape their scope. + + + + 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. + 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. + + + + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 4534963ebd..605a576395 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -213,20 +213,24 @@ module InRefParam_ExplicitInAttribute = module InRefParam_ExplicitInAttributeDateTime = type C() = static member M([] x: inref) = x - let res = System.DateTime.Now - let v = C.M(&res) - check "cweweoiwe519cw" v res + let Test() = + let res = System.DateTime.Now + let v = C.M(&res) + check "cweweoiwe519cw" v res + Test() module InRefParam = type C() = static member M(x: inref) = x - let res = System.DateTime.Now - let v = C.M(&res) - check "cweweoiwe51btw" v res + let Test() = + let res = System.DateTime.Now + let v = C.M(&res) + check "cweweoiwe51btw" v res - let minfo = typeof.GetMethod("M") - check "cwnoreekerf" (minfo.GetParameters().[0].IsIn) true - check "cwnoreekerg" (minfo.GetParameters().[0].IsOut) false + let minfo = typeof.GetMethod("M") + check "cwnoreekerf" (minfo.GetParameters().[0].IsIn) true + check "cwnoreekerg" (minfo.GetParameters().[0].IsOut) false + Test() module InRefParamOverload_ExplicitAddressOfAtCallSite = type C() = @@ -234,12 +238,15 @@ module InRefParamOverload_ExplicitAddressOfAtCallSite = static member M(x: inref) = x.AddDays(2.0) static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) static member M2(x: inref, y: int) = x.AddDays(2.0) - let res = System.DateTime.Now - let v = C.M(&res) - check "cweweoiwe51btw8" v (res.AddDays(2.0)) - let v2 = C.M2(&res, 0) - check "cweweoiwe51btw6" v2 (res.AddDays(2.0)) + let Test() = + let res = System.DateTime.Now + let v = C.M(&res) + check "cweweoiwe51btw8" v (res.AddDays(2.0)) + let v2 = C.M2(&res, 0) + check "cweweoiwe51btw6" v2 (res.AddDays(2.0)) + + Test() module InRefParamOverload_ImplicitAddressOfAtCallSite = type C() = @@ -254,6 +261,21 @@ module InRefParamOverload_ImplicitAddressOfAtCallSite = check "cweweoiwe51btw2" v2 (res.AddDays(1.0)) +module InRefParamOverload_ImplicitAddressOfAtCallSite2 = + type C() = + static member M(x: System.DateTime) = x.AddDays(1.0) + static member M(x: inref) = x.AddDays(2.0) + static member M2(x: System.DateTime, y: int) = x.AddDays(1.0) + static member M2(x: inref, y: int) = x.AddDays(2.0) + let Test() = + let res = System.DateTime.Now + let v = C.M(res) + check "cweweoiwe51btw1" v (res.AddDays(1.0)) + let v2 = C.M2(res, 4) + check "cweweoiwe51btw2" v2 (res.AddDays(1.0)) + Test() + + module InRefParam_DateTime = type C() = static member M(x: inref) = x @@ -291,17 +313,21 @@ module InRefParam_DateTime_ImplicitAddressOfAtCallSite4 = module InRefParam_Generic_ExplicitAddressOfAttCallSite1 = type C() = static member M(x: inref<'T>) = x - let res = "abc" - let v = C.M(&res) - check "lmvjvwo2" res "abc" - check "lmvjvwo3" v "abc" + let Test() = + let res = "abc" + let v = C.M(&res) + check "lmvjvwo2" res "abc" + check "lmvjvwo3" v "abc" + Test() module InRefParam_Generic_ExplicitAddressOfAttCallSite2 = type C() = static member M(x: inref<'T>) = x - let res = "abc" - let v = C.M(&res) - check "lmvjvwo4" v "abc" + let Test() = + let res = "abc" + let v = C.M(&res) + check "lmvjvwo4" v "abc" + Test() module ByrefReturnTests = diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index 88fff28af7..2754cf0a2f 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -290,25 +290,27 @@ namespace Tests //let stackReferringBecauseMutable1 = Span(NativePtr.toVoidPtr(NativePtr.ofByRef(&&x)), 1) //let stackReferring1 = Span(NativePtr.toVoidPtr(NativePtr.stackalloc< byte>(100), 1) - let mutable stackReferring2 = Span() + let mutable stackReferringBecauseMutable2 = Span() // this is allowed - stackReferring2 <- m1 &stackReferring2 stackReferringBecauseMutable1 + stackReferringBecauseMutable2 <- m1 &stackReferringBecauseMutable2 stackReferringBecauseMutable1 - // this is NOT allowed - stackReferring2 <- m1 ¶m1 stackReferringBecauseMutable1 + // this is allowed + stackReferringBecauseMutable2 <- m1 ¶m1 stackReferringBecauseMutable1 +#if NEGATIVE // this is NOT allowed - param1 <- m1 &stackReferring2 stackReferringBecauseMutable1 + param1 <- m1 &stackReferringBecauseMutable2 stackReferringBecauseMutable1 // this is NOT allowed - let param2 = stackReferringBecauseMutable1.Slice(10) + param1 <- stackReferringBecauseMutable2.Slice(10) +#endif // this is allowed param1 <- Span() // this is allowed - stackReferring2 <- param1 + stackReferringBecauseMutable2 <- param1 module SpanSafetyTests2 = let m2 (x: byref>) = @@ -328,25 +330,23 @@ namespace Tests let test2 (param1: byref>) (param2: Span) = let mutable stackReferringBecauseMutable1 = Span() - let mutable stackReferring2 = Span() + let mutable stackReferringBecauseMutable2 = Span() - let stackReferring3 = &(m2 &stackReferring2) + let stackReferring3 = &(m2 &stackReferringBecauseMutable2) // this is allowed - stackReferring3 <- m1 &stackReferring2 stackReferringBecauseMutable1 + stackReferring3 <- m1 &stackReferringBecauseMutable2 stackReferringBecauseMutable1 // this is allowed - m2(&stackReferring3) <- stackReferring2 + m2(&stackReferring3) <- stackReferringBecauseMutable2 -#if NEGATIVE +#if NEGATIVE2 // this is NOT allowed - m1(¶m1) <- stackReferring2 -#endif + m1(¶m1) <- stackReferringBecauseMutable2 // this is NOT allowed param1 <- stackReferring3 -#if NEGATIVE // this is NOT allowed &stackReferring3 #endif @@ -376,23 +376,26 @@ namespace Tests let mutable x = 1 &this.Create(&x) -// Disallow this: -[] -type DisallowedIsReadOnlyStruct = - [] - val mutable X : int #endif #if NOT_YET -// Allow this: -[] -type ByRefLikeStructWithSpanField(count1: Span, count2: int) = - member x.Count1 = count1 - member x.Count2 = count2 - -[] -type ByRefLikeStructWithByrefField(count1: Span, count2: int) = - member x.Count1 = count1 - member x.Count2 = count2 + + // Disallow this: + [] + type DisallowedIsReadOnlyStruct = + [] + val mutable X : int + + + // Allow this: + [] + type ByRefLikeStructWithSpanField(count1: Span, count2: int) = + member x.Count1 = count1 + member x.Count2 = count2 + + [] + type ByRefLikeStructWithByrefField(count1: Span, count2: int) = + member x.Count1 = count1 + member x.Count2 = count2 #endif From e10c464ed66bbe0d9fb08fbcae1ba6cf8d07f7dc Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 2 Jun 2018 20:04:42 +0100 Subject: [PATCH 56/61] fix IsByRefLike on struct --- .../FSharp.Compiler.Private/FSComp.fs | 6 +++++- .../FSharp.Compiler.Private/FSComp.resx | 5 ++++- src/fsharp/AugmentWithHashCompare.fs | 14 ++++++++++++-- src/fsharp/FSComp.txt | 3 ++- src/fsharp/PostInferenceChecks.fs | 3 +++ src/fsharp/xlf/FSComp.txt.cs.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.de.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.en.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.es.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.fr.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.it.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.ja.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.ko.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.pl.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.ru.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.tr.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 9 +++++++-- src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 9 +++++++-- tests/fsharp/core/span/test.fsx | 4 ++-- 20 files changed, 126 insertions(+), 35 deletions(-) diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index 5fa332202c..76f0b94465 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -4321,7 +4321,7 @@ type internal SR private() = /// 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)'. /// (Originally from ..\FSComp.txt:1431) static member tcByrefReturnImplicitlyDereferenced() = (3226, GetStringFunc("tcByrefReturnImplicitlyDereferenced",",,,") ) - /// A type annotated with IsByRefLike must also be a struct. + /// A type annotated with IsByRefLike must also be a struct. Consider adding the [] attribute to the type. /// (Originally from ..\FSComp.txt:1432) static member tcByRefLikeNotStruct() = (3227, GetStringFunc("tcByRefLikeNotStruct",",,,") ) /// 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. @@ -4336,6 +4336,9 @@ type internal SR private() = /// A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' /// (Originally from ..\FSComp.txt:1436) static member tastValueMustBeLocal() = (3231, GetStringFunc("tastValueMustBeLocal",",,,") ) + /// A type annotated with IsReadOnly must also be a struct. Consider adding the [] attribute to the type. + /// (Originally from ..\FSComp.txt:1437) + static member tcIsReadOnlyNotStruct() = (3232, GetStringFunc("tcIsReadOnlyNotStruct",",,,") ) /// Call this method once to validate that all known resources are valid; throws if not static member RunStartupValidation() = @@ -5746,4 +5749,5 @@ type internal SR private() = ignore(GetString("chkNoReturnOfLimitedSpan")) ignore(GetString("chkNoWriteToLimitedSpan")) ignore(GetString("tastValueMustBeLocal")) + ignore(GetString("tcIsReadOnlyNotStruct")) () diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index 38380196ea..fad71d9eb0 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -4325,7 +4325,7 @@ 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)'. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. 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. @@ -4339,4 +4339,7 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + \ No newline at end of file diff --git a/src/fsharp/AugmentWithHashCompare.fs b/src/fsharp/AugmentWithHashCompare.fs index 3c11de5df5..8654766526 100644 --- a/src/fsharp/AugmentWithHashCompare.fs +++ b/src/fsharp/AugmentWithHashCompare.fs @@ -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) @@ -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 // [< >] diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index f777801574..a910af72fc 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1429,8 +1429,9 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 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." +3227,tcByRefLikeNotStruct,"A type annotated with IsByRefLike must also be a struct. Consider adding the [] 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 [] attribute to the type." diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index edd25cff7f..83962ce7d8 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -1720,6 +1720,9 @@ let CheckEntityDefn cenv env (tycon:Entity) = if TyconRefHasAttribute g m g.attrib_IsByRefLikeAttribute tcref && not tycon.IsStructOrEnumTycon then errorR(Error(FSComp.SR.tcByRefLikeNotStruct(), tycon.Range)) + if TyconRefHasAttribute g m g.attrib_IsReadOnlyAttribute tcref && not tycon.IsStructOrEnumTycon then + errorR(Error(FSComp.SR.tcIsReadOnlyNotStruct(), tycon.Range)) + // Considers TFSharpObjectRepr, TRecdRepr and TUnionRepr. // [Review] are all cases covered: TILObjectRepr,TAsmRepr. [Yes - these are FSharp.Core.dll only] tycon.AllFieldsArray |> Array.iter (CheckRecdField false cenv env tycon) diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 4c81fb81a0..5885e6fca1 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index b4a3c5c87b..9106651ec0 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.en.xlf b/src/fsharp/xlf/FSComp.txt.en.xlf index 74cccf06fd..8ad4c84857 100644 --- a/src/fsharp/xlf/FSComp.txt.en.xlf +++ b/src/fsharp/xlf/FSComp.txt.en.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 0332cf8abe..c2fddbe0d3 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index 27a44625a1..9116b97814 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 92bee6457b..f82cf58132 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index d77bc884bb..20c8051dbc 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index 744117a34a..9e54b5d635 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index 63f9a6b249..a85843080d 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index 5cb9ca0287..be52f280a8 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 861ddeeddb..5dfa2e9be4 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index e244a77706..06490cb582 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index 7a38c78c4b..f24e47d5c2 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 9ea0697b42..cab0fb452e 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -7008,8 +7008,8 @@ - A type annotated with IsByRefLike must also be a struct. - A type annotated with IsByRefLike must also be a struct. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsByRefLike must also be a struct. Consider adding the [<Struct>] attribute to the type. @@ -7032,6 +7032,11 @@ A value defined in a module must be mutable in order to take its address, e.g. 'let mutable x = ...' + + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + \ No newline at end of file diff --git a/tests/fsharp/core/span/test.fsx b/tests/fsharp/core/span/test.fsx index 2754cf0a2f..b6bbf9bb9f 100644 --- a/tests/fsharp/core/span/test.fsx +++ b/tests/fsharp/core/span/test.fsx @@ -41,12 +41,12 @@ namespace Tests let check2 s expected actual = check s actual expected - [] + [] type ReadOnlyStruct(count1: int, count2: int) = member x.Count1 = count1 member x.Count2 = count2 - [] + [] type ByRefLikeStruct(count1: int, count2: int) = member x.Count1 = count1 member x.Count2 = count2 From 937673db611399986392546f7fbdadf50a5d04e5 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sat, 2 Jun 2018 20:10:08 +0100 Subject: [PATCH 57/61] update tests --- tests/fsharp/typecheck/sigs/neg106.bsl | 56 ++++++++++++------------ tests/fsharp/typecheck/sigs/neg106.fs | 34 +++++++++----- tests/fsharp/typecheck/sigs/neg106.vsbsl | 56 ++++++++++++------------ 3 files changed, 82 insertions(+), 64 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg106.bsl b/tests/fsharp/typecheck/sigs/neg106.bsl index 3eba5fcba5..aa30f56a61 100644 --- a/tests/fsharp/typecheck/sigs/neg106.bsl +++ b/tests/fsharp/typecheck/sigs/neg106.bsl @@ -1,120 +1,122 @@ -neg106.fs(8,14,8,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type +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, value: int, comparand: int) : int'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,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 +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' is not compatible with type 'byref<'a>' . -neg106.fs(11,14,11,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type +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, value: int, comparand: int) : int'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,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 +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' is not compatible with type 'byref<'a>' . -neg106.fs(16,31,16,35): typecheck error FS0001: Type mismatch. Expecting a +neg106.fs(23,35,23,39): typecheck error FS0001: Type mismatch. Expecting a 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' -neg106.fs(22,18,22,22): typecheck error FS0001: Type mismatch. Expecting a +neg106.fs(31,22,31,26): typecheck error FS0001: Type mismatch. Expecting a 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' -neg106.fs(29,14,29,28): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type +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 -> unit'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type +neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type 'string' is not compatible with type 'int' . -neg106.fs(30,15,30,27): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type +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 -> unit'. Type constraint mismatch. The type 'int' is not compatible with type 'string' . -neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type +neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(36,18,36,22): typecheck error FS0001: Type mismatch. Expecting a +neg106.fs(49,22,49,26): typecheck error FS0001: Type mismatch. Expecting a 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' -neg106.fs(46,9,46,25): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted. +neg106.fs(60,9,60,25): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted. -neg106.fs(51,42,51,48): 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. diff --git a/tests/fsharp/typecheck/sigs/neg106.fs b/tests/fsharp/typecheck/sigs/neg106.fs index cf1357ca2d..e292f2dc05 100644 --- a/tests/fsharp/typecheck/sigs/neg106.fs +++ b/tests/fsharp/typecheck/sigs/neg106.fs @@ -7,33 +7,47 @@ module CompareExchangeTests_Negative1 = let x = 3 let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) // No overloads match for method 'CompareExchange'. 'inref' is not compatible with type 'byref' +module CompareExchangeTests_Negative1b = + let Test() = + let x = 3 + let v = System.Threading.Interlocked.CompareExchange(&x, 3, 4) // No overloads match for method 'CompareExchange'. 'inref' is not compatible with type 'byref' + () + module CompareExchangeTests_Negative2 = let v = System.Threading.Interlocked.CompareExchange(&3, 3, 4) // 'inref' is not compatible with type 'byref' module TryGetValueTests_Negative1 = - let d = dict [ (3,4) ] - let res = 9 - let v = d.TryGetValue(3, &res) // 'inref' is not compatible with type 'byref' + let Test() = + let d = dict [ (3,4) ] + let res = 9 + let v = d.TryGetValue(3, &res) // 'inref' is not compatible with type 'byref' + () module FSharpDeclaredOutParamTest_Negaative1 = type C() = static member M([] x: byref) = () - let res = 9 - let v = C.M(&res) //'inref' is not compatible with type 'byref' + let Test() = + let res = 9 + let v = C.M(&res) //'inref' is not compatible with type 'byref' + () module FSharpDeclaredOverloadedOutParamTest_Negative1 = type C() = static member M(a: int, [] x: byref) = x <- 7 static member M(a: string, [] x: byref) = x <- 8 - let res = 9 - let v = C.M("a", &res) //'inref' is not compatible with type 'byref' - let v2 = C.M(3, &res) //'inref' is not compatible with type 'byref' + let Test() = + let res = 9 + let v = C.M("a", &res) //'inref' is not compatible with type 'byref' + let v2 = C.M(3, &res) //'inref' is not compatible with type 'byref' + () module FSharpDeclaredOutParamTest_Negative1 = type C() = static member M([] x: byref) = () - let res = 9 - let v = C.M(&res) // 'inref' is not compatible with type 'byref' + let Test() = + let res = 9 + let v = C.M(&res) // 'inref' is not compatible with type 'byref' + () module TestOneArgumentInRefThenMutate_Negative1 = diff --git a/tests/fsharp/typecheck/sigs/neg106.vsbsl b/tests/fsharp/typecheck/sigs/neg106.vsbsl index 3eba5fcba5..aa30f56a61 100644 --- a/tests/fsharp/typecheck/sigs/neg106.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg106.vsbsl @@ -1,120 +1,122 @@ -neg106.fs(8,14,8,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type +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, value: int, comparand: int) : int'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type +neg106.fs(13,18,13,72): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(8,14,8,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 +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' is not compatible with type 'byref<'a>' . -neg106.fs(11,14,11,68): typecheck error FS0041: No overloads match for method 'CompareExchange'. The available overloads are shown below. -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int, comparand: int) : int'. Type constraint mismatch. The type +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, value: int, comparand: int) : int'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: int64, comparand: int64) : int64'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float32, comparand: float32) : float32'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: float, comparand: float) : float'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: obj, comparand: obj) : obj'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type +neg106.fs(17,14,17,68): typecheck error FS0041: Possible overload: 'System.Threading.Interlocked.CompareExchange(location1: byref, value: nativeint, comparand: nativeint) : nativeint'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(11,14,11,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 +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' is not compatible with type 'byref<'a>' . -neg106.fs(16,31,16,35): typecheck error FS0001: Type mismatch. Expecting a +neg106.fs(23,35,23,39): typecheck error FS0001: Type mismatch. Expecting a 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' -neg106.fs(22,18,22,22): typecheck error FS0001: Type mismatch. Expecting a +neg106.fs(31,22,31,26): typecheck error FS0001: Type mismatch. Expecting a 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' -neg106.fs(29,14,29,28): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type +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 -> unit'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(29,14,29,28): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type +neg106.fs(40,18,40,32): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type 'string' is not compatible with type 'int' . -neg106.fs(30,15,30,27): typecheck error FS0041: No overloads match for method 'M'. The available overloads are shown below. -neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:string * x:byref -> unit'. Type constraint mismatch. The type +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 -> unit'. Type constraint mismatch. The type 'int' is not compatible with type 'string' . -neg106.fs(30,15,30,27): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type +neg106.fs(41,19,41,31): typecheck error FS0041: Possible overload: 'static member C.M : a:int * x:byref -> unit'. Type constraint mismatch. The type 'inref' is not compatible with type 'byref' . -neg106.fs(36,18,36,22): typecheck error FS0001: Type mismatch. Expecting a +neg106.fs(49,22,49,26): typecheck error FS0001: Type mismatch. Expecting a 'byref' but given a 'inref' The type 'ByRefKinds.InOut' does not match the type 'ByRefKinds.In' -neg106.fs(46,9,46,25): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted. +neg106.fs(60,9,60,25): typecheck error FS3224: The byref pointer is readonly, so this write is not permitted. -neg106.fs(51,42,51,48): 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. From d0cad1f39498fb8556739c5e649117a866a77309 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sun, 3 Jun 2018 10:43:37 +0100 Subject: [PATCH 58/61] fix test --- src/fsharp/PostInferenceChecks.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 83962ce7d8..f557a976b0 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -911,9 +911,9 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // Field setters on mutable structs come through here CheckExprsPermitByRefLike cenv env [arg1; arg2] - | TOp.Coerce,[_ty1;_ty2],[x] -> - // Subsumption coercions of functions may involve byrefs in other argument positions - CheckTypeInstPermitAllByrefs cenv env m tyargs + | TOp.Coerce,[ty1;ty2],[x] -> + if not (typeEquiv g ty1 ty2) then + CheckTypeInstNoByrefs cenv env m tyargs CheckExpr cenv env x context | TOp.Reraise,[_ty1],[] -> From 7453ab7846f8685ab580039d151897777cef94a0 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Sun, 3 Jun 2018 10:56:38 +0100 Subject: [PATCH 59/61] fix test --- src/fsharp/PostInferenceChecks.fs | 9 ++++++--- .../ByrefSafetyAnalysis/E_SetFieldToByref04.fs | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index f557a976b0..86655c4fbc 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -911,10 +911,13 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // Field setters on mutable structs come through here CheckExprsPermitByRefLike cenv env [arg1; arg2] - | TOp.Coerce,[ty1;ty2],[x] -> - if not (typeEquiv g ty1 ty2) then + | TOp.Coerce,[tgty;srcty],[x] -> + if TypeRelations.TypeDefinitelySubsumesTypeNoCoercion 0 cenv.g cenv.amap m tgty srcty then + CheckExpr cenv env x context + else CheckTypeInstNoByrefs cenv env m tyargs - CheckExpr cenv env x context + CheckExprNoByrefs cenv env x + false | TOp.Reraise,[_ty1],[] -> CheckTypeInstNoByrefs cenv env m tyargs diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SetFieldToByref04.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SetFieldToByref04.fs index af9e70f512..14bcac4570 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SetFieldToByref04.fs +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SetFieldToByref04.fs @@ -3,6 +3,7 @@ // object field. (Disallowed by the CLR.) +//A type instantiation involves a byref type\. This is not permitted by the rules of Common IL\.$ //The address of the variable 'x' cannot be used at this point$ //A type instantiation involves a byref type\. This is not permitted by the rules of Common IL\.$ let mutable mutableObjectField : obj = null From e1b4985563c836a941bc3c126daf36c1f159fe3c Mon Sep 17 00:00:00 2001 From: Don Syme Date: Mon, 4 Jun 2018 14:07:23 +0100 Subject: [PATCH 60/61] improve check for no-return-of-struct-field-addresses --- .../FSharp.Compiler.Private/FSComp.fs | 4 + .../FSharp.Compiler.Private/FSComp.resx | 3 + src/fsharp/FSComp.txt | 1 + src/fsharp/PostInferenceChecks.fs | 107 ++++++++++++------ src/fsharp/TastOps.fs | 65 +++++++---- src/fsharp/TypeChecker.fs | 3 +- src/fsharp/xlf/FSComp.txt.cs.xlf | 5 + src/fsharp/xlf/FSComp.txt.de.xlf | 5 + src/fsharp/xlf/FSComp.txt.en.xlf | 5 + src/fsharp/xlf/FSComp.txt.es.xlf | 5 + src/fsharp/xlf/FSComp.txt.fr.xlf | 5 + src/fsharp/xlf/FSComp.txt.it.xlf | 5 + src/fsharp/xlf/FSComp.txt.ja.xlf | 5 + src/fsharp/xlf/FSComp.txt.ko.xlf | 5 + src/fsharp/xlf/FSComp.txt.pl.xlf | 5 + src/fsharp/xlf/FSComp.txt.pt-BR.xlf | 5 + src/fsharp/xlf/FSComp.txt.ru.xlf | 5 + src/fsharp/xlf/FSComp.txt.tr.xlf | 5 + src/fsharp/xlf/FSComp.txt.zh-Hans.xlf | 5 + src/fsharp/xlf/FSComp.txt.zh-Hant.xlf | 5 + tests/fsharp/core/byrefs/test.fsx | 41 ++++++- tests/fsharp/typecheck/sigs/neg106.bsl | 2 + tests/fsharp/typecheck/sigs/neg106.fs | 8 ++ tests/fsharp/typecheck/sigs/neg106.vsbsl | 2 + tests/fsharp/typecheck/sigs/neg107.bsl | 10 ++ tests/fsharp/typecheck/sigs/neg107.fsx | 30 +++++ tests/fsharp/typecheck/sigs/neg107.vsbsl | 10 ++ 27 files changed, 291 insertions(+), 65 deletions(-) diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs index 76f0b94465..c3672425eb 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.fs @@ -4339,6 +4339,9 @@ type internal SR private() = /// A type annotated with IsReadOnly must also be a struct. Consider adding the [] attribute to the type. /// (Originally from ..\FSComp.txt:1437) static member tcIsReadOnlyNotStruct() = (3232, GetStringFunc("tcIsReadOnlyNotStruct",",,,") ) + /// Struct members cannot return 'this' or fields by reference + /// (Originally from ..\FSComp.txt:1438) + static member chkStructsMayNotReturnAddressesOfContents() = (3234, GetStringFunc("chkStructsMayNotReturnAddressesOfContents",",,,") ) /// Call this method once to validate that all known resources are valid; throws if not static member RunStartupValidation() = @@ -5750,4 +5753,5 @@ type internal SR private() = ignore(GetString("chkNoWriteToLimitedSpan")) ignore(GetString("tastValueMustBeLocal")) ignore(GetString("tcIsReadOnlyNotStruct")) + ignore(GetString("chkStructsMayNotReturnAddressesOfContents")) () diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx index fad71d9eb0..2289e761c7 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx +++ b/src/buildfromsource/FSharp.Compiler.Private/FSComp.resx @@ -4342,4 +4342,7 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return 'this' or fields by reference + \ No newline at end of file diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index a910af72fc..76a75e7555 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1435,3 +1435,4 @@ notAFunctionButMaybeDeclaration,"This value is not a function and cannot be appl 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 [] attribute to the type." +3234,chkStructsMayNotReturnAddressesOfContents,"Struct members cannot return the address of fields of the struct by reference" diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 86655c4fbc..1bf1509540 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -564,8 +564,8 @@ and CheckValUse (cenv: cenv) (env: env) (vref: ValRef, vFlags, m) (context: Perm errorR(Error(FSComp.SR.tcAbstractTypeCannotBeInstantiated(),m)) let isReturnExprBuiltUsingByRefLocal = - isByrefTy g vref.Type && context.PermitOnlyReturnable && + isByrefTy g vref.Type && // The value is a local.... vref.ValReprInfo.IsNone && // The value is not an argument.... @@ -574,12 +574,21 @@ and CheckValUse (cenv: cenv) (env: env) (vref: ValRef, vFlags, m) (context: Perm if isReturnExprBuiltUsingByRefLocal then errorR(Error(FSComp.SR.chkNoByrefReturnOfLocal(vref.DisplayName), m)) + let isReturnOfStructThis = + context.PermitOnlyReturnable && + isByrefTy g vref.Type && + (vref.BaseOrThisInfo = MemberThisVal) + + if isReturnOfStructThis then + errorR(Error(FSComp.SR.chkStructsMayNotReturnAddressesOfContents(), m)) + CheckValRef cenv env vref m context limit /// Check an expression, given information about the position of the expression and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = let g = cenv.g + let expr = NormalizeAndAdjustPossibleSubsumptionExprs g expr let expr = stripExpr expr match expr with @@ -912,7 +921,7 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckExprsPermitByRefLike cenv env [arg1; arg2] | TOp.Coerce,[tgty;srcty],[x] -> - if TypeRelations.TypeDefinitelySubsumesTypeNoCoercion 0 cenv.g cenv.amap m tgty srcty then + if TypeRelations.TypeDefinitelySubsumesTypeNoCoercion 0 g cenv.amap m tgty srcty then CheckExpr cenv env x context else CheckTypeInstNoByrefs cenv env m tyargs @@ -935,12 +944,23 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // Check get of instance field | TOp.ValFieldGetAddr (rfref, _readonly),tyargs,[obj] -> + if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then + errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(rfref.FieldName), m)) + + // C# applies a rule where the APIs to struct types can't return the addresses of fields in that struct. + // There seems no particular reason for this given that other protections in the language, though allowing + // it would mean "readonly" on a struct doesn't imply immutabality-of-contents - it only implies + if context.PermitOnlyReturnable && (match obj with Expr.Val(vref, _, _) -> vref.BaseOrThisInfo = MemberThisVal | _ -> false) && isByrefTy g (tyOfExpr g obj) then + errorR(Error(FSComp.SR.chkStructsMayNotReturnAddressesOfContents(), m)) + if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(rfref.FieldName), m)) // This construct is used for &(rx.rfield) and &(rx->rfield). Relax to permit byref types for rx. [See Bug 1263]. CheckTypeInstNoByrefs cenv env m tyargs - CheckExprPermitByRefLike cenv env obj + + // Recursively check in same context, e.g. if at PermitOnlyReturnable the obj arg must also be returnable + CheckExpr cenv env obj context | TOp.UnionCaseFieldGet _,_,[arg1] -> CheckTypeInstNoByrefs cenv env m tyargs @@ -950,14 +970,18 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = CheckTypeInstNoByrefs cenv env m tyargs CheckExprPermitByRefLike cenv env arg1 // allow byref - it may be address-of-struct - | TOp.UnionCaseFieldGetAddr (uref, _idx, _readonly),tyargs,[rx] -> + | TOp.UnionCaseFieldGetAddr (uref, _idx, _readonly),tyargs,[obj] -> if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(uref.CaseName), m)) + if context.PermitOnlyReturnable && (match obj with Expr.Val(vref, _, _) -> vref.BaseOrThisInfo = MemberThisVal | _ -> false) && isByrefTy g (tyOfExpr g obj) then + errorR(Error(FSComp.SR.chkStructsMayNotReturnAddressesOfContents(), m)) + CheckTypeInstNoByrefs cenv env m tyargs - // allow rx to be byref here, for struct unions - CheckExprPermitByRefLike cenv env rx + + // Recursively check in same context, e.g. if at PermitOnlyReturnable the obj arg must also be returnable + CheckExpr cenv env obj context | TOp.ILAsm (instrs,tys),_,_ -> CheckTypeInstPermitAllByrefs cenv env m tys @@ -979,11 +1003,18 @@ and CheckExprOp cenv env (op,tyargs,args,m) context expr = // permit byref for lhs lvalue of readonly value CheckExprsPermitByRefLike cenv env args - | [ I_ldflda (fspec) | I_ldsflda (fspec) ],_ -> + | [ I_ldsflda (fspec) ], [] -> if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(fspec.Name), m)) - // permit byref for lhs lvalue - CheckExprsPermitByRefLike cenv env args + + false + + | [ I_ldflda (fspec) ], [obj] -> + if context.Disallow && cenv.reportErrors && isByrefLikeTy g m (tyOfExpr g expr) then + errorR(Error(FSComp.SR.chkNoAddressFieldAtThisPoint(fspec.Name), m)) + + // Recursively check in same context, e.g. if at PermitOnlyReturnable the obj arg must also be returnable + CheckExpr cenv env obj context | [ I_ldelema (_,isNativePtr,_,_) ],lhsArray::indices -> if context.Disallow && cenv.reportErrors && not isNativePtr && isByrefLikeTy g m (tyOfExpr g expr) then @@ -1252,15 +1283,16 @@ and AdjustAccess isHidden (cpath: unit -> CompilationPath) access = access and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) : bool = + let g = cenv.g let isTop = Option.isSome bind.Var.ValReprInfo //printfn "visiting %s..." v.DisplayName - let env = { env with external = env.external || cenv.g.attrib_DllImportAttribute |> Option.exists (fun attr -> HasFSharpAttribute cenv.g attr v.Attribs) } + let env = { env with external = env.external || g.attrib_DllImportAttribute |> Option.exists (fun attr -> HasFSharpAttribute g attr v.Attribs) } // Check that active patterns don't have free type variables in their result match TryGetActivePatternInfo (mkLocalValRef v) with | Some _apinfo when _apinfo.ActiveTags.Length > 1 -> - if doesActivePatternHaveFreeTypars cenv.g (mkLocalValRef v) then + if doesActivePatternHaveFreeTypars g (mkLocalValRef v) then errorR(Error(FSComp.SR.activePatternChoiceHasFreeTypars(v.LogicalName),v.Range)) | _ -> () @@ -1299,11 +1331,11 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) : bo (// Check the attributes on any enclosing module env.reflect || // Check the attributes on the value - HasFSharpAttribute cenv.g cenv.g.attrib_ReflectedDefinitionAttribute v.Attribs || + HasFSharpAttribute g g.attrib_ReflectedDefinitionAttribute v.Attribs || // Also check the enclosing type for members - for historical reasons, in the TAST member values // are stored in the entity that encloses the type, hence we will not have noticed the ReflectedDefinition // on the enclosing type at this point. - HasFSharpAttribute cenv.g cenv.g.attrib_ReflectedDefinitionAttribute v.TopValDeclaringEntity.Attribs) then + HasFSharpAttribute g g.attrib_ReflectedDefinitionAttribute v.TopValDeclaringEntity.Attribs) then if v.IsInstanceMember && v.MemberApparentEntity.IsStructOrEnumTycon then errorR(Error(FSComp.SR.chkNoReflectedDefinitionOnStructMember(),v.Range)) @@ -1318,13 +1350,13 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) : bo // no real need for that except that it helps us to bundle all reflected definitions up into // one blob for pickling to the binary format try - let ety = tyOfExpr cenv.g bindRhs + let ety = tyOfExpr g bindRhs let tps,taue,_ = match bindRhs with - | Expr.TyLambda (_,tps,b,_,_) -> tps,b,applyForallTy cenv.g ety (List.map mkTyparTy tps) + | Expr.TyLambda (_,tps,b,_,_) -> tps,b,applyForallTy g ety (List.map mkTyparTy tps) | _ -> [],bindRhs,ety let env = QuotationTranslator.QuotationTranslationEnv.Empty.BindTypars tps - let qscope = QuotationTranslator.QuotationGenerationScope.Create (cenv.g,cenv.amap,cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.Yes) + let qscope = QuotationTranslator.QuotationGenerationScope.Create (g,cenv.amap,cenv.viewCcu, QuotationTranslator.IsReflectedDefinition.Yes) QuotationTranslator.ConvExprPublic qscope env taue |> ignore let _,_,argExprs = qscope.Close() if not (isNil argExprs) then @@ -1339,8 +1371,8 @@ and CheckBinding cenv env alwaysCheckNoReraise (TBind(v,bindRhs,_) as bind) : bo match memberInfo.MemberFlags.MemberKind with | (MemberKind.PropertySet | MemberKind.PropertyGet) -> // These routines raise errors for ill-formed properties - v |> ReturnTypeOfPropertyVal cenv.g |> ignore - v |> ArgInfosOfPropertyVal cenv.g |> ignore + v |> ReturnTypeOfPropertyVal g |> ignore + v |> ArgInfosOfPropertyVal g |> ignore | _ -> () @@ -1355,7 +1387,8 @@ and CheckBindings cenv env xs = // Top binds introduce expression, check they are reraise free. let CheckModuleBinding cenv env (TBind(v,e,_) as bind) = - let isExplicitEntryPoint = HasFSharpAttribute cenv.g cenv.g.attrib_EntryPointAttribute v.Attribs + let g = cenv.g + let isExplicitEntryPoint = HasFSharpAttribute g g.attrib_EntryPointAttribute v.Attribs if isExplicitEntryPoint then cenv.entryPointGiven <- true let isLastCompiland = fst cenv.isLastCompiland @@ -1366,14 +1399,14 @@ let CheckModuleBinding cenv env (TBind(v,e,_) as bind) = if // Mutable values always have fields not v.IsMutable && // Literals always have fields - not (HasFSharpAttribute cenv.g cenv.g.attrib_LiteralAttribute v.Attribs) && - not (HasFSharpAttributeOpt cenv.g cenv.g.attrib_ThreadStaticAttribute v.Attribs) && - not (HasFSharpAttributeOpt cenv.g cenv.g.attrib_ContextStaticAttribute v.Attribs) && + not (HasFSharpAttribute g g.attrib_LiteralAttribute v.Attribs) && + not (HasFSharpAttributeOpt g g.attrib_ThreadStaticAttribute v.Attribs) && + not (HasFSharpAttributeOpt g g.attrib_ContextStaticAttribute v.Attribs) && // Having a field makes the binding a static initialization trigger - IsSimpleSyntacticConstantExpr cenv.g e && + IsSimpleSyntacticConstantExpr g e && // Check the thing is actually compiled as a property - IsCompiledAsStaticProperty cenv.g v || - (cenv.g.compilingFslib && v.Attribs |> List.exists(fun (Attrib(tc,_,_,_,_,_,_)) -> tc.CompiledName = "ValueAsStaticPropertyAttribute")) + IsCompiledAsStaticProperty g v || + (g.compilingFslib && v.Attribs |> List.exists(fun (Attrib(tc,_,_,_,_,_,_)) -> tc.CompiledName = "ValueAsStaticPropertyAttribute")) then v.SetIsCompiledAsStaticPropertyWithoutField() @@ -1384,7 +1417,7 @@ let CheckModuleBinding cenv env (TBind(v,e,_) as bind) = // Skip compiler generated values if v.IsCompilerGenerated then () else // Skip explicit implementations of interface methods - if ValIsExplicitImpl cenv.g v then () else + if ValIsExplicitImpl g v then () else match v.DeclaringEntity with | ParentNone -> () // this case can happen after error recovery from earlier error @@ -1392,7 +1425,7 @@ let CheckModuleBinding cenv env (TBind(v,e,_) as bind) = let tcref = v.TopValDeclaringEntity let hasDefaultAugmentation = tcref.IsUnionTycon && - match TryFindFSharpAttribute cenv.g cenv.g.attrib_DefaultAugmentationAttribute tcref.Attribs with + match TryFindFSharpAttribute g g.attrib_DefaultAugmentationAttribute tcref.Attribs with | Some(Attrib(_,_,[ AttribBoolArg(b) ],_,_,_,_)) -> b | _ -> true (* not hiddenRepr *) @@ -1456,10 +1489,10 @@ let CheckModuleBinding cenv env (TBind(v,e,_) as bind) = if v.IsExtensionMember then tcref.ModuleOrNamespaceType.AllValsAndMembersByLogicalNameUncached.[v.LogicalName] |> List.iter (fun v2 -> if v2.IsExtensionMember && not (valEq v v2) && v.CompiledName = v2.CompiledName then - let minfo1 = FSMeth(cenv.g, generalizedTyconRef tcref, mkLocalValRef v, Some 0UL) - let minfo2 = FSMeth(cenv.g, generalizedTyconRef tcref, mkLocalValRef v2, Some 0UL) - if tyconRefEq cenv.g v.MemberApparentEntity v2.MemberApparentEntity && - MethInfosEquivByNameAndSig EraseAll true cenv.g cenv.amap v.Range minfo1 minfo2 then + let minfo1 = FSMeth(g, generalizedTyconRef tcref, mkLocalValRef v, Some 0UL) + let minfo2 = FSMeth(g, generalizedTyconRef tcref, mkLocalValRef v2, Some 0UL) + if tyconRefEq g v.MemberApparentEntity v2.MemberApparentEntity && + MethInfosEquivByNameAndSig EraseAll true g cenv.amap v.Range minfo1 minfo2 then errorR(Duplicate(kind,v.DisplayName,v.Range))) @@ -1880,13 +1913,13 @@ let CheckTopImpl (g,amap,reportErrors,infoReader,internalsVisibleToPaths,viewCcu // Certain type equality checks go faster if these TyconRefs are pre-resolved. // This is because pre-resolving allows tycon equality to be determined by pointer equality on the entities. // See primEntityRefEq. - cenv.g.system_Void_tcref.TryDeref |> ignore - cenv.g.byref_tcr.TryDeref |> ignore + g.system_Void_tcref.TryDeref |> ignore + g.byref_tcr.TryDeref |> ignore let resolve = function Some(t : TyconRef) -> ignore(t.TryDeref) | _ -> () - resolve cenv.g.system_TypedReference_tcref - resolve cenv.g.system_ArgIterator_tcref - resolve cenv.g.system_RuntimeArgumentHandle_tcref + resolve g.system_TypedReference_tcref + resolve g.system_ArgIterator_tcref + resolve g.system_RuntimeArgumentHandle_tcref let env = { sigToImplRemapInfo=[] @@ -1900,6 +1933,6 @@ let CheckTopImpl (g,amap,reportErrors,infoReader,internalsVisibleToPaths,viewCcu CheckModuleExpr cenv env mexpr CheckAttribs cenv env extraAttribs - if cenv.usesQuotations && QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat(cenv.g) = QuotationTranslator.QuotationSerializationFormat.FSharp_20_Plus then + if cenv.usesQuotations && QuotationTranslator.QuotationGenerationScope.ComputeQuotationFormat(g) = QuotationTranslator.QuotationSerializationFormat.FSharp_20_Plus then viewCcu.UsesFSharp20PlusQuotations <- true cenv.entryPointGiven diff --git a/src/fsharp/TastOps.fs b/src/fsharp/TastOps.fs index 861a341277..729553b212 100644 --- a/src/fsharp/TastOps.fs +++ b/src/fsharp/TastOps.fs @@ -5676,6 +5676,13 @@ let isRecdOrStructTyReadOnly (g: TcGlobals) m ty = | 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 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 @@ -5700,17 +5707,20 @@ let CanTakeAddressOfImmutableVal (g: TcGlobals) m (vref:ValRef) mut = // || 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 - match mut with - | NeverMutates -> true - | PossiblyMutates -> isRecdOrStructTyReadOnly g m vref.Type - | DefinitelyMutates -> false - | AddressOfOp -> true // you can take the address but you might get a (readonly) inref as a result + CanTakeAddressOf g m vref.Type mut let MustTakeAddressOfVal (g:TcGlobals) (vref:ValRef) = vref.IsMutable && // We can only take the address of mutable values in the same assembly valRefInThisAssembly g.compilingFslib vref +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 rfref.IsStatic && @@ -5718,27 +5728,28 @@ let MustTakeAddressOfRecdField (rfref: RecdField) = let MustTakeAddressOfRecdFieldRef (rfref: RecdFieldRef) = MustTakeAddressOfRecdField rfref.RecdField -let CanTakeAddressOfRecdFieldRef (g:TcGlobals) m (rfref: RecdFieldRef) mut = - 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 && - isRecdOrStructTyconRefReadOnly g m rfref.TyconRef + not rfref.RecdField.IsMutable && + CanTakeAddressOf g m (actualTyOfRecdFieldRef rfref tinst) mut -let CanTakeAddressOfUnionFieldRef (g:TcGlobals) m (uref: UnionCaseRef) mut = - 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 && - isRecdOrStructTyconRefReadOnly g m uref.TyconRef + 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 readonly pointer (e.g. the address of -/// +/// 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) -> - let readonly = isInByrefTy g vref.Type + | 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 // LVALUE of "x" where "x" is mutable local, mutable intra-assembly module/static binding, or operation doesn't mutate. @@ -5748,14 +5759,14 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress None, mkValAddr m readonly vref, readonly // LVALUE of "e.f" where "f" is record field. - | Expr.Op (TOp.ValFieldGet rfref, tinst, [obje], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref mut -> + | 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 mut -> + | 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))) @@ -5774,7 +5785,7 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress wrap, Expr.Op (TOp.ILAsm ([IL.I_ldflda(fspec)], [mkByrefTyWithFlag g readonly ty2]), tinst, [expra], m), readonly // LVALUE of "f" where "f" is a static F# field. - | Expr.Op (TOp.ValFieldGet rfref, tinst, [], m) when MustTakeAddressOfRecdFieldRef rfref || CanTakeAddressOfRecdFieldRef g m rfref mut -> + | 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 @@ -5804,6 +5815,11 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress None, mkArrayElemAddress g (readonly, ilInstrReadOnlyAnnotation, isNativePtr, shape, elemTy, (aexpr::args), m), readonly + // 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)) @@ -5816,14 +5832,10 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress | 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)) - // LVALUE: "&meth(args)" where meth has a byref return. Includes "&span.[idx]". - | Expr.Let(TBind(vref, e, _), Expr.Op(TOp.LValueOp (LByrefGet, vref2), _, _, _), _, _) when isByrefTy g vref.Type && (valRefEq g (mkLocalValRef vref) vref2) -> - let readonly = isInByrefTy g (tyOfExpr g e) - None, e, readonly - | _ -> let ty = tyOfExpr g expr if isStructTy g ty then @@ -5831,9 +5843,12 @@ let rec mkExprAddrOfExprAux g mustTakeAddress useReadonlyForGenericArrayAddress | 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 diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index f3b4c24aa6..8be658fc73 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -8421,8 +8421,7 @@ and TcDelayed cenv overallTy env tpenv mExpr expr exprty (atomicFlag:ExprAtomicF 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 - if readonly then error(Error(FSComp.SR.tcInvalidAssignment(), mStmt)) + 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 diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 5885e6fca1..ceb6d658d5 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index 9106651ec0..957653a606 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.en.xlf b/src/fsharp/xlf/FSComp.txt.en.xlf index 8ad4c84857..fb84a93857 100644 --- a/src/fsharp/xlf/FSComp.txt.en.xlf +++ b/src/fsharp/xlf/FSComp.txt.en.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index c2fddbe0d3..8187e6b689 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index 9116b97814..7596000991 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index f82cf58132..220d7a72a9 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index 20c8051dbc..20af7a1608 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index 9e54b5d635..5b84f48e06 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index a85843080d..7b58742f3e 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index be52f280a8..a7f4e1c252 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 5dfa2e9be4..d8cbe9424c 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 06490cb582..211cead74d 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index f24e47d5c2..f61822ca96 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index cab0fb452e..e6f85883d1 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -7037,6 +7037,11 @@ A type annotated with IsReadOnly must also be a struct. Consider adding the [<Struct>] attribute to the type. + + Struct members cannot return the address of fields of the struct by reference + Struct members cannot return the address of fields of the struct by reference + + \ No newline at end of file diff --git a/tests/fsharp/core/byrefs/test.fsx b/tests/fsharp/core/byrefs/test.fsx index 605a576395..21416333c1 100644 --- a/tests/fsharp/core/byrefs/test.fsx +++ b/tests/fsharp/core/byrefs/test.fsx @@ -1204,7 +1204,46 @@ module ByrefReturnMemberTests = beef 0 &x check "vruoer3rvvrebae" x 3uy - + module TestInRefMutation = + [] + type TestMut = + + val mutable x : int + + member this.AnAction() = + this.x <- 1 + + let testAction (m: inref) = + m.AnAction() + check "vleoij" m.x 0 + + let test() = + let x = TestMut() + //testIn (&x) + testAction (&x) + x + test() + + module MutateInRef3 = + [] + type TestMut(x: int ref) = + + member this.X = x.contents + member this.XAddr = &x.contents + + let testIn (m: inref) = + // If the struct API indirectly reveals a byref return of a field in a reference type then + // there is nothing stopping it being written to. + m.XAddr <- 1 + + let test() = + let m = TestMut(ref 0) + testIn (&m) + check "vleoij" m.X 1 + + test() + + let aa = if !failures then (stdout.WriteLine "Test Failed"; exit 1) else (stdout.WriteLine "Test Passed"; diff --git a/tests/fsharp/typecheck/sigs/neg106.bsl b/tests/fsharp/typecheck/sigs/neg106.bsl index aa30f56a61..ac6228a569 100644 --- a/tests/fsharp/typecheck/sigs/neg106.bsl +++ b/tests/fsharp/typecheck/sigs/neg106.bsl @@ -120,3 +120,5 @@ 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 = ...'. diff --git a/tests/fsharp/typecheck/sigs/neg106.fs b/tests/fsharp/typecheck/sigs/neg106.fs index e292f2dc05..938d13309b 100644 --- a/tests/fsharp/typecheck/sigs/neg106.fs +++ b/tests/fsharp/typecheck/sigs/neg106.fs @@ -64,3 +64,11 @@ module EvilStruct_Negative1 = type EvilStruct(s: int) = member x.Replace(y:EvilStruct) = x <- y +module MutateInRef1 = + [] + type TestMut = + + val mutable x : int + + let testIn (m: inref) = + m.x <- 1 diff --git a/tests/fsharp/typecheck/sigs/neg106.vsbsl b/tests/fsharp/typecheck/sigs/neg106.vsbsl index aa30f56a61..ac6228a569 100644 --- a/tests/fsharp/typecheck/sigs/neg106.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg106.vsbsl @@ -120,3 +120,5 @@ 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 = ...'. diff --git a/tests/fsharp/typecheck/sigs/neg107.bsl b/tests/fsharp/typecheck/sigs/neg107.bsl index 401484eb33..8fd63e7a80 100644 --- a/tests/fsharp/typecheck/sigs/neg107.bsl +++ b/tests/fsharp/typecheck/sigs/neg107.bsl @@ -54,3 +54,13 @@ neg107.fsx(34,56,34,61): typecheck error FS0425: The type of a first-class funct 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 diff --git a/tests/fsharp/typecheck/sigs/neg107.fsx b/tests/fsharp/typecheck/sigs/neg107.fsx index 3bca46d42c..2dcaafee7a 100644 --- a/tests/fsharp/typecheck/sigs/neg107.fsx +++ b/tests/fsharp/typecheck/sigs/neg107.fsx @@ -35,3 +35,33 @@ namespace Test module Span_Negative2 = let TestLocal1 () = let x = Span() in x + + module MutateInRef2 = + [] + 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 = + [] + 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 = + [] + type TestMut1 = + + val mutable x : int + + [] + 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 diff --git a/tests/fsharp/typecheck/sigs/neg107.vsbsl b/tests/fsharp/typecheck/sigs/neg107.vsbsl index 401484eb33..8fd63e7a80 100644 --- a/tests/fsharp/typecheck/sigs/neg107.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg107.vsbsl @@ -54,3 +54,13 @@ neg107.fsx(34,56,34,61): typecheck error FS0425: The type of a first-class funct 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 From 0a9316fe92332e9596c0847b6942712e70e791b5 Mon Sep 17 00:00:00 2001 From: Don Syme Date: Mon, 4 Jun 2018 15:18:54 +0100 Subject: [PATCH 61/61] fix test case --- src/fsharp/PostInferenceChecks.fs | 83 +++++++++++-------- .../E_SetFieldToByref04.fs | 1 - 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/fsharp/PostInferenceChecks.fs b/src/fsharp/PostInferenceChecks.fs index 1bf1509540..0b72eb994d 100644 --- a/src/fsharp/PostInferenceChecks.fs +++ b/src/fsharp/PostInferenceChecks.fs @@ -586,9 +586,55 @@ and CheckValUse (cenv: cenv) (env: env) (vref: ValRef, vFlags, m) (context: Perm limit /// Check an expression, given information about the position of the expression -and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = +and CheckForOverAppliedExceptionRaisingPrimitive (cenv:cenv) expr = let g = cenv.g - let expr = NormalizeAndAdjustPossibleSubsumptionExprs g expr + let expr = stripExpr expr + + // Some things are more easily checked prior to NormalizeAndAdjustPossibleSubsumptionExprs + match expr with + | Expr.App(f,_fty,_tyargs,argsl,_m) -> + + if cenv.reportErrors then + + // Special diagnostics for `raise`, `failwith`, `failwithf`, `nullArg`, `invalidOp` library intrinsics commonly used to raise exceptions + // to warn on over-application. + match f with + | OptionalCoerce(Expr.Val(v, _, funcRange)) + when (valRefEq g v g.raise_vref || valRefEq g v g.failwith_vref || valRefEq g v g.null_arg_vref || valRefEq g v g.invalid_op_vref) -> + match argsl with + | [] | [_] -> () + | _ :: _ :: _ -> + warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 1, argsl.Length), funcRange)) + + | OptionalCoerce(Expr.Val(v, _, funcRange)) when valRefEq g v g.invalid_arg_vref -> + match argsl with + | [] | [_] | [_; _] -> () + | _ :: _ :: _ :: _ -> + warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 2, argsl.Length), funcRange)) + + | OptionalCoerce(Expr.Val(failwithfFunc, _, funcRange)) when valRefEq g failwithfFunc g.failwithf_vref -> + match argsl with + | Expr.App (Expr.Val(newFormat, _, _), _, [_; typB; typC; _; _], [Expr.Const(Const.String formatString, formatRange, _)], _) :: xs when valRefEq g newFormat g.new_format_vref -> + match CheckFormatStrings.TryCountFormatStringArguments formatRange g formatString typB typC with + | Some n -> + let expected = n + 1 + let actual = List.length xs + 1 + if expected < actual then + warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(failwithfFunc.DisplayName, expected, actual), funcRange)) + | None -> () + | _ -> () + | _ -> () + | _ -> () + +/// Check an expression, given information about the position of the expression +and CheckExpr (cenv:cenv) (env:env) origExpr (context:PermitByRefExpr) : bool = + let g = cenv.g + + let origExpr = stripExpr origExpr + + // CheckForOverAppliedExceptionRaisingPrimitive is more easily checked prior to NormalizeAndAdjustPossibleSubsumptionExprs + CheckForOverAppliedExceptionRaisingPrimitive cenv origExpr + let expr = NormalizeAndAdjustPossibleSubsumptionExprs g origExpr let expr = stripExpr expr match expr with @@ -710,39 +756,6 @@ and CheckExpr (cenv:cenv) (env:env) expr (context:PermitByRefExpr) : bool = // Check an application | Expr.App(f,_fty,tyargs,argsl,m) -> - if cenv.reportErrors then - - // Special diagnostics for `raise`, `failwith`, `failwithf`, `nullArg`, `invalidOp` library intrinsics commonly used to raise exceptions - // to warn on over-application. - match f with - | OptionalCoerce(Expr.Val(v, _, funcRange)) - when (valRefEq g v g.raise_vref || valRefEq g v g.failwith_vref || valRefEq g v g.null_arg_vref || valRefEq g v g.invalid_op_vref) -> - match argsl with - | [] | [_] -> () - | _ :: _ :: _ -> - warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 1, List.length argsl), funcRange)) - - | OptionalCoerce(Expr.Val(v, _, funcRange)) when valRefEq g v g.invalid_arg_vref -> - match argsl with - | [] | [_] | [_; _] -> () - | _ :: _ :: _ :: _ -> - warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(v.DisplayName, 2, List.length argsl), funcRange)) - - | OptionalCoerce(Expr.Val(failwithfFunc, _, funcRange)) when valRefEq g failwithfFunc g.failwithf_vref -> - match argsl with - | Expr.App (Expr.Val(newFormat, _, _), _, [_; typB; typC; _; _], [Expr.Const(Const.String formatString, formatRange, _)], _) :: xs when valRefEq g newFormat g.new_format_vref -> - match CheckFormatStrings.TryCountFormatStringArguments formatRange g formatString typB typC with - | Some n -> - let expected = n + 1 - let actual = List.length xs + 1 - if expected < actual then - warning(Error(FSComp.SR.checkRaiseFamilyFunctionArgumentCount(failwithfFunc.DisplayName, expected, actual), funcRange)) - | None -> () - | _ -> - () - | _ -> - () - CheckTypeInstNoByrefs cenv env m tyargs CheckExprNoByrefs cenv env f diff --git a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SetFieldToByref04.fs b/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SetFieldToByref04.fs index 14bcac4570..f192ad47c2 100644 --- a/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SetFieldToByref04.fs +++ b/tests/fsharpqa/Source/Conformance/InferenceProcedures/ByrefSafetyAnalysis/E_SetFieldToByref04.fs @@ -2,7 +2,6 @@ // Verify appropriate error if attempting to assign a ByRef value to an // object field. (Disallowed by the CLR.) - //A type instantiation involves a byref type\. This is not permitted by the rules of Common IL\.$ //The address of the variable 'x' cannot be used at this point$ //A type instantiation involves a byref type\. This is not permitted by the rules of Common IL\.$