From c14b2b7bfec6cbaadea1951196118a6cb95aeb4a Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Tue, 23 Jul 2024 12:50:14 +0200 Subject: [PATCH 01/13] Update azure-pipelines.yml --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e0c4349b26b..b4f235359af 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -29,7 +29,7 @@ variables: # Should be 'current' release branch name, i.e. 'release/dev17.10' in dotnet/fsharp/refs/heads/main, 'release/dev17.10' in dotnet/fsharp/refs/heads/release/dev17.10 and 'release/dev17.9' in dotnet/fsharp/refs/heads/release/dev17.9 # Should **never** be 'main' in dotnet/fsharp/refs/heads/main, since it will start inserting to VS twice. - name: FSharpReleaseBranchName - value: release/dev17.11 + value: release/dev17.12 # VS Insertion branch name (NOT the same as F# branch) # Should be previous release branch or 'main' in 'main' and 'main' in release branch # (since for all *new* release branches we insert into VS main and for all *previous* releases we insert into corresponding VS release), @@ -85,7 +85,7 @@ extends: # Signed build # #-------------------------------------------------------------------------------------------------------------------# # Localization: we only run it for specific release branches - - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/dev17.11') }}: + - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/release/dev17.12') }}: - template: /eng/common/templates-official/job/onelocbuild.yml@self parameters: MirrorRepo: fsharp From 6b4c4d52eb3cbefe041b5117464d07c8a4383220 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 6 Aug 2024 08:18:57 -0700 Subject: [PATCH 02/13] Refactor CE checking (#17464) (#17493) Co-authored-by: Vlad Zarytovskii Co-authored-by: vzarytovskii <1260985+vzarytovskii@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../CheckComputationExpressions.fs | 4920 +++++++++-------- 1 file changed, 2604 insertions(+), 2316 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs index 55ed6c9761d..2b66af3eea9 100644 --- a/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckComputationExpressions.fs @@ -24,6 +24,7 @@ open FSharp.Compiler.Text open FSharp.Compiler.Text.Range open FSharp.Compiler.TypedTree open FSharp.Compiler.TypedTreeOps +open System.Collections.Generic type cenv = TcFileState @@ -39,88 +40,44 @@ type CustomOperationsMode = | Allowed | Denied +[] +type ComputationExpressionContext<'a> = + { + cenv: TcFileState + env: TcEnv + tpenv: UnscopedTyparEnv + customOperationMethodsIndexedByKeyword: + IDictionary * MethInfo>> + customOperationMethodsIndexedByMethodName: + IDictionary * MethInfo>> + sourceMethInfo: 'a list + builderValName: string + ad: AccessorDomain + builderTy: TType + isQuery: bool + enableImplicitYield: bool + origComp: SynExpr + mWhole: range + emptyVarSpace: LazyWithContext * TcEnv, range> + } + let inline TryFindIntrinsicOrExtensionMethInfo collectionSettings (cenv: cenv) (env: TcEnv) m ad nm ty = AllMethInfosOfTypeInScope collectionSettings cenv.infoReader env.NameEnv (Some nm) ad IgnoreOverrides m ty /// Ignores an attribute let inline IgnoreAttribute _ = None -[] -let (|ExprAsPat|_|) (f: SynExpr) = - match f with - | SingleIdent v1 - | SynExprParen(SingleIdent v1, _, _, _) -> ValueSome(mkSynPatVar None v1) - | SynExprParen(SynExpr.Tuple(false, elems, commas, _), _, _, _) -> - let elems = elems |> List.map (|SingleIdent|_|) - - if elems |> List.forall (fun x -> x.IsSome) then - ValueSome(SynPat.Tuple(false, (elems |> List.map (fun x -> mkSynPatVar None x.Value)), commas, f.Range)) - else - ValueNone - | _ -> ValueNone - -// For join clauses that join on nullable, we syntactically insert the creation of nullable values on the appropriate side of the condition, -// then pull the syntax apart again -[] -let (|JoinRelation|_|) cenv env (expr: SynExpr) = - let m = expr.Range - let ad = env.eAccessRights - - let isOpName opName vref s = - (s = opName) - && match - ResolveExprLongIdent - cenv.tcSink - cenv.nameResolver - m - ad - env.eNameResEnv - TypeNameResolutionInfo.Default - [ ident (opName, m) ] - None - with - | Result(_, Item.Value vref2, []) -> valRefEq cenv.g vref vref2 - | _ -> false - - match expr with - | BinOpExpr(opId, a, b) when isOpName opNameEquals cenv.g.equals_operator_vref opId.idText -> ValueSome(a, b) - - | BinOpExpr(opId, a, b) when isOpName opNameEqualsNullable cenv.g.equals_nullable_operator_vref opId.idText -> - - let a = - SynExpr.App(ExprAtomicFlag.Atomic, false, mkSynLidGet a.Range [ MangledGlobalName; "System" ] "Nullable", a, a.Range) - - ValueSome(a, b) - - | BinOpExpr(opId, a, b) when isOpName opNameNullableEquals cenv.g.nullable_equals_operator_vref opId.idText -> - - let b = - SynExpr.App(ExprAtomicFlag.Atomic, false, mkSynLidGet b.Range [ MangledGlobalName; "System" ] "Nullable", b, b.Range) - - ValueSome(a, b) - - | BinOpExpr(opId, a, b) when isOpName opNameNullableEqualsNullable cenv.g.nullable_equals_nullable_operator_vref opId.idText -> - - ValueSome(a, b) - - | _ -> ValueNone +let inline arbPat (m: range) = + mkSynPatVar None (mkSynId (m.MakeSynthetic()) "_missingVar") -let (|ForEachThen|_|) synExpr = - match synExpr with - | SynExpr.ForEach(_spFor, - _spIn, - SeqExprOnly false, - isFromSource, - pat1, - expr1, - SynExpr.Sequential(isTrueSeq = true; expr1 = clause; expr2 = rest), - _) -> Some(isFromSource, pat1, expr1, clause, rest) - | _ -> None +let inline arbKeySelectors m = + mkSynBifix m "=" (arbExpr ("_keySelectors", m)) (arbExpr ("_keySelector2", m)) -let (|CustomOpId|_|) isCustomOperation predicate synExpr = - match synExpr with - | SingleIdent nm when isCustomOperation nm && predicate nm -> Some nm - | _ -> None +// Flag that a debug point should get emitted prior to both the evaluation of 'rhsExpr' and the call to Using +let inline addBindDebugPoint spBind e = + match spBind with + | DebugPointAtBinding.Yes m -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, e) + | _ -> e let inline mkSynDelay2 (e: SynExpr) = mkSynDelay (e.Range.MakeSynthetic()) e @@ -149,40 +106,37 @@ let mkSourceExprConditional isFromSource callExpr sourceMethInfo builderValName else callExpr -let hasMethInfo nm cenv env mBuilderVal ad builderTy = - match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad nm builderTy with - | [] -> false - | _ -> true - -/// Used for all computation expressions except sequence expressions -let TcComputationExpression (cenv: TcFileState) env (overallTy: OverallTy) tpenv (mWhole, interpExpr: Expr, builderTy, comp: SynExpr) = - let overallTy = overallTy.Commit +let inline mkSynLambda p e m = + SynExpr.Lambda(false, false, p, e, None, m, SynExprLambdaTrivia.Zero) - let g = cenv.g - let ad = env.eAccessRights +let mkExprForVarSpace m (patvs: Val list) = + match patvs with + | [] -> SynExpr.Const(SynConst.Unit, m) + | [ v ] -> SynExpr.Ident v.Id + | vs -> SynExpr.Tuple(false, (vs |> List.map (fun v -> SynExpr.Ident(v.Id))), [], m) - let builderValName = CompilerGeneratedName "builder" - let mBuilderVal = interpExpr.Range +let mkSimplePatForVarSpace m (patvs: Val list) = + let spats = + match patvs with + | [] -> [] + | [ v ] -> [ mkSynSimplePatVar false v.Id ] + | vs -> vs |> List.map (fun v -> mkSynSimplePatVar false v.Id) - // Give bespoke error messages for the FSharp.Core "query" builder - let isQuery = - match stripDebugPoints interpExpr with - // An unparameterized custom builder, e.g., `query`, `async`. - | Expr.Val(vref, _, m) - // A parameterized custom builder, e.g., `builder<…>`, `builder ()`. - | Expr.App(funcExpr = Expr.Val(vref, _, m)) when not vref.IsMember || vref.IsConstructor -> - let item = Item.CustomBuilder(vref.DisplayName, vref) - CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) - valRefEq cenv.g vref cenv.g.query_value_vref - | _ -> false + SynSimplePats.SimplePats(spats, [], m) - let sourceMethInfo = - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad "Source" builderTy +let mkPatForVarSpace m (patvs: Val list) = + match patvs with + | [] -> SynPat.Const(SynConst.Unit, m) + | [ v ] -> mkSynPatVar None v.Id + | vs -> SynPat.Tuple(false, (vs |> List.map (fun x -> mkSynPatVar None x.Id)), [], m) - /// Decide if the builder is an auto-quote builder - let isAutoQuote = hasMethInfo "Quote" cenv env mBuilderVal ad builderTy +let hasMethInfo nm cenv env mBuilderVal ad builderTy = + match TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad nm builderTy with + | [] -> false + | _ -> true - let customOperationMethods = +let getCustomOperationMethods (cenv: TcFileState) (env: TcEnv) ad mBuilderVal builderTy = + let allMethInfos = AllMethInfosOfTypeInScope ResultCollectionSettings.AllResults cenv.infoReader @@ -192,10 +146,10 @@ let TcComputationExpression (cenv: TcFileState) env (overallTy: OverallTy) tpenv IgnoreOverrides mBuilderVal builderTy - |> List.choose (fun methInfo -> - if not (IsMethInfoAccessible cenv.amap mBuilderVal ad methInfo) then - None - else + + [ + for methInfo in allMethInfos do + if IsMethInfoAccessible cenv.amap mBuilderVal ad methInfo then let nameSearch = TryBindMethInfoAttribute cenv.g @@ -217,7 +171,7 @@ let TcComputationExpression (cenv: TcFileState) env (overallTy: OverallTy) tpenv IgnoreAttribute // We do not respect this attribute for provided methods match nameSearch with - | None -> None + | None -> () | Some nm -> let joinConditionWord = TryBindMethInfoAttribute @@ -252,1596 +206,1854 @@ let TcComputationExpression (cenv: TcFileState) env (overallTy: OverallTy) tpenv let isLikeJoin = defaultArg (flagSearch "IsLikeJoin") false let isLikeGroupJoin = defaultArg (flagSearch "IsLikeGroupJoin") false - Some( - nm, - maintainsVarSpaceUsingBind, - maintainsVarSpace, - allowInto, - isLikeZip, - isLikeJoin, - isLikeGroupJoin, - joinConditionWord, - methInfo - )) + nm, + maintainsVarSpaceUsingBind, + maintainsVarSpace, + allowInto, + isLikeZip, + isLikeJoin, + isLikeGroupJoin, + joinConditionWord, + methInfo + ] + +/// Decide if the identifier represents a use of a custom query operator +let tryGetDataForCustomOperation (nm: Ident) ceenv = + let isOpDataCountAllowed opDatas = + match opDatas with + | [ _ ] -> true + | _ :: _ -> ceenv.cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations + | _ -> false - let customOperationMethodsIndexedByKeyword = - if cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations then - customOperationMethods - |> Seq.groupBy (fun (nm, _, _, _, _, _, _, _, _) -> nm) - |> Seq.map (fun (nm, group) -> (nm, group |> Seq.toList)) - else - customOperationMethods - |> Seq.groupBy (fun (nm, _, _, _, _, _, _, _, _) -> nm) - |> Seq.map (fun (nm, g) -> (nm, Seq.toList g)) - |> dict + match ceenv.customOperationMethodsIndexedByKeyword.TryGetValue nm.idText with + | true, opDatas when isOpDataCountAllowed opDatas -> + for opData in opDatas do + let (opName, + maintainsVarSpaceUsingBind, + maintainsVarSpace, + _allowInto, + isLikeZip, + isLikeJoin, + isLikeGroupJoin, + _joinConditionWord, + methInfo) = + opData - // Check for duplicates by method name (keywords and method names must be 1:1) - let customOperationMethodsIndexedByMethodName = - if cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations then - customOperationMethods - |> Seq.groupBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) - |> Seq.map (fun (nm, group) -> (nm, group |> Seq.toList)) - else - customOperationMethods - |> Seq.groupBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) - |> Seq.map (fun (nm, g) -> (nm, Seq.toList g)) - |> dict + if + (maintainsVarSpaceUsingBind && maintainsVarSpace) + || (isLikeZip && isLikeJoin) + || (isLikeZip && isLikeGroupJoin) + || (isLikeJoin && isLikeGroupJoin) + then + errorR (Error(FSComp.SR.tcCustomOperationInvalid opName, nm.idRange)) - /// Decide if the identifier represents a use of a custom query operator - let tryGetDataForCustomOperation (nm: Ident) = - let isOpDataCountAllowed opDatas = - match opDatas with - | [ _ ] -> true - | _ :: _ -> cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations - | _ -> false - - match customOperationMethodsIndexedByKeyword.TryGetValue nm.idText with - | true, opDatas when isOpDataCountAllowed opDatas -> - for opData in opDatas do - let (opName, - maintainsVarSpaceUsingBind, - maintainsVarSpace, - _allowInto, - isLikeZip, - isLikeJoin, - isLikeGroupJoin, - _joinConditionWord, - methInfo) = - opData - - if - (maintainsVarSpaceUsingBind && maintainsVarSpace) - || (isLikeZip && isLikeJoin) - || (isLikeZip && isLikeGroupJoin) - || (isLikeJoin && isLikeGroupJoin) - then - errorR (Error(FSComp.SR.tcCustomOperationInvalid opName, nm.idRange)) - - if not (cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations) then - match customOperationMethodsIndexedByMethodName.TryGetValue methInfo.LogicalName with - | true, [ _ ] -> () - | _ -> errorR (Error(FSComp.SR.tcCustomOperationMayNotBeOverloaded nm.idText, nm.idRange)) - - Some opDatas - | true, opData :: _ -> - errorR (Error(FSComp.SR.tcCustomOperationMayNotBeOverloaded nm.idText, nm.idRange)) - Some [ opData ] - | _ -> None + if not (ceenv.cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations) then + match ceenv.customOperationMethodsIndexedByMethodName.TryGetValue methInfo.LogicalName with + | true, [ _ ] -> () + | _ -> errorR (Error(FSComp.SR.tcCustomOperationMayNotBeOverloaded nm.idText, nm.idRange)) - /// Decide if the identifier represents a use of a custom query operator - let hasCustomOperations () = - if isNil customOperationMethods then - CustomOperationsMode.Denied - else - CustomOperationsMode.Allowed - - let isCustomOperation nm = - tryGetDataForCustomOperation nm |> Option.isSome - - let customOperationCheckValidity m f opDatas = - let vs = opDatas |> List.map f - let v0 = vs[0] - - let (opName, - _maintainsVarSpaceUsingBind, - _maintainsVarSpace, - _allowInto, - _isLikeZip, - _isLikeJoin, - _isLikeGroupJoin, - _joinConditionWord, - _methInfo) = - opDatas[0] - - if not (List.allEqual vs) then - errorR (Error(FSComp.SR.tcCustomOperationInvalid opName, m)) - - v0 - - // Check for the MaintainsVariableSpace on custom operation - let customOperationMaintainsVarSpace (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some opDatas -> - opDatas - |> customOperationCheckValidity - nm.idRange - (fun - (_nm, - _maintainsVarSpaceUsingBind, - maintainsVarSpace, - _allowInto, - _isLikeZip, - _isLikeJoin, - _isLikeGroupJoin, - _joinConditionWord, - _methInfo) -> maintainsVarSpace) - - let customOperationMaintainsVarSpaceUsingBind (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some opDatas -> - opDatas - |> customOperationCheckValidity - nm.idRange - (fun - (_nm, - maintainsVarSpaceUsingBind, - _maintainsVarSpace, - _allowInto, - _isLikeZip, - _isLikeJoin, - _isLikeGroupJoin, - _joinConditionWord, - _methInfo) -> maintainsVarSpaceUsingBind) - - let customOperationIsLikeZip (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some opDatas -> - opDatas - |> customOperationCheckValidity - nm.idRange - (fun - (_nm, - _maintainsVarSpaceUsingBind, - _maintainsVarSpace, - _allowInto, - isLikeZip, - _isLikeJoin, - _isLikeGroupJoin, - _joinConditionWord, - _methInfo) -> isLikeZip) - - let customOperationIsLikeJoin (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some opDatas -> - opDatas - |> customOperationCheckValidity - nm.idRange - (fun - (_nm, - _maintainsVarSpaceUsingBind, - _maintainsVarSpace, - _allowInto, - _isLikeZip, - isLikeJoin, - _isLikeGroupJoin, - _joinConditionWord, - _methInfo) -> isLikeJoin) - - let customOperationIsLikeGroupJoin (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some opDatas -> - opDatas - |> customOperationCheckValidity - nm.idRange - (fun - (_nm, - _maintainsVarSpaceUsingBind, - _maintainsVarSpace, - _allowInto, - _isLikeZip, - _isLikeJoin, - isLikeGroupJoin, - _joinConditionWord, - _methInfo) -> isLikeGroupJoin) - - let customOperationJoinConditionWord (nm: Ident) = - match tryGetDataForCustomOperation nm with - | Some opDatas -> - opDatas - |> customOperationCheckValidity - nm.idRange - (fun - (_nm, - _maintainsVarSpaceUsingBind, - _maintainsVarSpace, - _allowInto, - _isLikeZip, - _isLikeJoin, - _isLikeGroupJoin, - joinConditionWord, - _methInfo) -> joinConditionWord) - |> function - | None -> "on" - | Some v -> v - | _ -> "on" - - let customOperationAllowsInto (nm: Ident) = - match tryGetDataForCustomOperation nm with - | None -> false - | Some opDatas -> - opDatas - |> customOperationCheckValidity - nm.idRange - (fun - (_nm, - _maintainsVarSpaceUsingBind, - _maintainsVarSpace, - allowInto, - _isLikeZip, - _isLikeJoin, - _isLikeGroupJoin, - _joinConditionWord, - _methInfo) -> allowInto) - - let customOpUsageText nm = - match tryGetDataForCustomOperation nm with - | Some((_nm, - _maintainsVarSpaceUsingBind, - _maintainsVarSpace, - _allowInto, - isLikeZip, - isLikeJoin, - isLikeGroupJoin, - _joinConditionWord, - _methInfo) :: _) -> - if isLikeGroupJoin then - Some( - FSComp.SR.customOperationTextLikeGroupJoin ( - nm.idText, - customOperationJoinConditionWord nm, - customOperationJoinConditionWord nm - ) + Some opDatas + | true, opData :: _ -> + errorR (Error(FSComp.SR.tcCustomOperationMayNotBeOverloaded nm.idText, nm.idRange)) + Some [ opData ] + | _ -> None + +let isCustomOperation ceenv nm = + tryGetDataForCustomOperation nm ceenv |> Option.isSome + +let customOperationCheckValidity m f opDatas = + let vs = List.map f opDatas + let v0 = vs[0] + + let (opName, + _maintainsVarSpaceUsingBind, + _maintainsVarSpace, + _allowInto, + _isLikeZip, + _isLikeJoin, + _isLikeGroupJoin, + _joinConditionWord, + _methInfo) = + opDatas[0] + + if not (List.allEqual vs) then + errorR (Error(FSComp.SR.tcCustomOperationInvalid opName, m)) + + v0 + +// Check for the MaintainsVariableSpace on custom operation +let customOperationMaintainsVarSpace ceenv (nm: Ident) = + match tryGetDataForCustomOperation nm ceenv with + | None -> false + | Some opDatas -> + opDatas + |> customOperationCheckValidity + nm.idRange + (fun + (_nm, + _maintainsVarSpaceUsingBind, + maintainsVarSpace, + _allowInto, + _isLikeZip, + _isLikeJoin, + _isLikeGroupJoin, + _joinConditionWord, + _methInfo) -> maintainsVarSpace) + +let customOperationMaintainsVarSpaceUsingBind ceenv (nm: Ident) = + match tryGetDataForCustomOperation nm ceenv with + | None -> false + | Some opDatas -> + opDatas + |> customOperationCheckValidity + nm.idRange + (fun + (_nm, + maintainsVarSpaceUsingBind, + _maintainsVarSpace, + _allowInto, + _isLikeZip, + _isLikeJoin, + _isLikeGroupJoin, + _joinConditionWord, + _methInfo) -> maintainsVarSpaceUsingBind) + +let customOperationIsLikeZip ceenv (nm: Ident) = + match tryGetDataForCustomOperation nm ceenv with + | None -> false + | Some opDatas -> + opDatas + |> customOperationCheckValidity + nm.idRange + (fun + (_nm, + _maintainsVarSpaceUsingBind, + _maintainsVarSpace, + _allowInto, + isLikeZip, + _isLikeJoin, + _isLikeGroupJoin, + _joinConditionWord, + _methInfo) -> isLikeZip) + +let customOperationIsLikeJoin ceenv (nm: Ident) = + match tryGetDataForCustomOperation nm ceenv with + | None -> false + | Some opDatas -> + opDatas + |> customOperationCheckValidity + nm.idRange + (fun + (_nm, + _maintainsVarSpaceUsingBind, + _maintainsVarSpace, + _allowInto, + _isLikeZip, + isLikeJoin, + _isLikeGroupJoin, + _joinConditionWord, + _methInfo) -> isLikeJoin) + +let customOperationIsLikeGroupJoin ceenv (nm: Ident) = + match tryGetDataForCustomOperation nm ceenv with + | None -> false + | Some opDatas -> + opDatas + |> customOperationCheckValidity + nm.idRange + (fun + (_nm, + _maintainsVarSpaceUsingBind, + _maintainsVarSpace, + _allowInto, + _isLikeZip, + _isLikeJoin, + isLikeGroupJoin, + _joinConditionWord, + _methInfo) -> isLikeGroupJoin) + +let customOperationJoinConditionWord ceenv (nm: Ident) = + match tryGetDataForCustomOperation nm ceenv with + | Some opDatas -> + opDatas + |> customOperationCheckValidity + nm.idRange + (fun + (_nm, + _maintainsVarSpaceUsingBind, + _maintainsVarSpace, + _allowInto, + _isLikeZip, + _isLikeJoin, + _isLikeGroupJoin, + joinConditionWord, + _methInfo) -> joinConditionWord) + |> function + | None -> "on" + | Some v -> v + | _ -> "on" + +let customOperationAllowsInto ceenv (nm: Ident) = + match tryGetDataForCustomOperation nm ceenv with + | None -> false + | Some opDatas -> + opDatas + |> customOperationCheckValidity + nm.idRange + (fun + (_nm, + _maintainsVarSpaceUsingBind, + _maintainsVarSpace, + allowInto, + _isLikeZip, + _isLikeJoin, + _isLikeGroupJoin, + _joinConditionWord, + _methInfo) -> allowInto) + +let customOpUsageText ceenv nm = + match tryGetDataForCustomOperation nm ceenv with + | Some((_nm, + _maintainsVarSpaceUsingBind, + _maintainsVarSpace, + _allowInto, + isLikeZip, + isLikeJoin, + isLikeGroupJoin, + _joinConditionWord, + _methInfo) :: _) -> + if isLikeGroupJoin then + Some( + FSComp.SR.customOperationTextLikeGroupJoin ( + nm.idText, + customOperationJoinConditionWord ceenv nm, + customOperationJoinConditionWord ceenv nm ) - elif isLikeJoin then - Some( - FSComp.SR.customOperationTextLikeJoin ( - nm.idText, - customOperationJoinConditionWord nm, - customOperationJoinConditionWord nm - ) + ) + elif isLikeJoin then + Some( + FSComp.SR.customOperationTextLikeJoin ( + nm.idText, + customOperationJoinConditionWord ceenv nm, + customOperationJoinConditionWord ceenv nm ) - elif isLikeZip then - Some(FSComp.SR.customOperationTextLikeZip (nm.idText)) - else - None - | _ -> None - - /// Inside the 'query { ... }' use a modified name environment that contains fake 'CustomOperation' entries - /// for all custom operations. This adds them to the completion lists and prevents them being used as values inside - /// the query. - let env = - if List.isEmpty customOperationMethods then - env + ) + elif isLikeZip then + Some(FSComp.SR.customOperationTextLikeZip (nm.idText)) else - { env with - eNameResEnv = - (env.eNameResEnv, customOperationMethods) - ||> Seq.fold (fun nenv (nm, _, _, _, _, _, _, _, methInfo) -> - AddFakeNameToNameEnv - nm - nenv - (Item.CustomOperation(nm, (fun () -> customOpUsageText (ident (nm, mBuilderVal))), Some methInfo))) - } - - // Environment is needed for completions - CallEnvSink cenv.tcSink (comp.Range, env.NameEnv, ad) - - let tryGetArgAttribsForCustomOperator (nm: Ident) = - match tryGetDataForCustomOperation nm with - | Some argInfos -> - argInfos - |> List.map - (fun - (_nm, - __maintainsVarSpaceUsingBind, - _maintainsVarSpace, - _allowInto, - _isLikeZip, - _isLikeJoin, - _isLikeGroupJoin, - _joinConditionWord, - methInfo) -> - match methInfo.GetParamAttribs(cenv.amap, mWhole) with - | [ curriedArgInfo ] -> Some curriedArgInfo // one for the actual argument group - | _ -> None) - |> Some - | _ -> None - - let tryGetArgInfosForCustomOperator (nm: Ident) = - match tryGetDataForCustomOperation nm with - | Some argInfos -> - argInfos - |> List.map - (fun - (_nm, - __maintainsVarSpaceUsingBind, - _maintainsVarSpace, - _allowInto, - _isLikeZip, - _isLikeJoin, - _isLikeGroupJoin, - _joinConditionWord, - methInfo) -> - match methInfo with - | FSMeth(_, _, vref, _) -> - match ArgInfosOfMember cenv.g vref with - | [ curriedArgInfo ] -> Some curriedArgInfo - | _ -> None - | _ -> None) - |> Some - | _ -> None + None + | _ -> None - let tryExpectedArgCountForCustomOperator (nm: Ident) = - match tryGetArgAttribsForCustomOperator nm with - | None -> None - | Some argInfosForOverloads -> - let nums = - argInfosForOverloads - |> List.map (function - | None -> -1 - | Some argInfos -> List.length argInfos) - - // Prior to 'OverloadsForCustomOperations' we count exact arguments. - // - // With 'OverloadsForCustomOperations' we don't compute an exact expected argument count - // if any arguments are optional, out or ParamArray. - let isSpecial = - if cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations then - argInfosForOverloads - |> List.exists (fun info -> - match info with - | None -> false - | Some args -> - args - |> List.exists - (fun (ParamAttribs(isParamArrayArg, _isInArg, isOutArg, optArgInfo, _callerInfo, _reflArgInfo)) -> - isParamArrayArg || isOutArg || optArgInfo.IsOptional)) - else - false +let tryGetArgAttribsForCustomOperator ceenv (nm: Ident) = + match tryGetDataForCustomOperation nm ceenv with + | Some argInfos -> + argInfos + |> List.map + (fun + (_nm, + __maintainsVarSpaceUsingBind, + _maintainsVarSpace, + _allowInto, + _isLikeZip, + _isLikeJoin, + _isLikeGroupJoin, + _joinConditionWord, + methInfo) -> + match methInfo.GetParamAttribs(ceenv.cenv.amap, ceenv.mWhole) with + | [ curriedArgInfo ] -> Some curriedArgInfo // one for the actual argument group + | _ -> None) + |> Some + | _ -> None - if not isSpecial && nums |> List.forall (fun v -> v >= 0 && v = nums[0]) then - Some(max (nums[0] - 1) 0) // drop the computation context argument - else - None +let tryGetArgInfosForCustomOperator ceenv (nm: Ident) = + match tryGetDataForCustomOperation nm ceenv with + | Some argInfos -> + argInfos + |> List.map + (fun + (_nm, + __maintainsVarSpaceUsingBind, + _maintainsVarSpace, + _allowInto, + _isLikeZip, + _isLikeJoin, + _isLikeGroupJoin, + _joinConditionWord, + methInfo) -> + match methInfo with + | FSMeth(_, _, vref, _) -> + match ArgInfosOfMember ceenv.cenv.g vref with + | [ curriedArgInfo ] -> Some curriedArgInfo + | _ -> None + | _ -> None) + |> Some + | _ -> None - // Check for the [] attribute on an argument position - let isCustomOperationProjectionParameter i (nm: Ident) = - match tryGetArgInfosForCustomOperator nm with - | None -> false - | Some argInfosForOverloads -> - let vs = +let tryExpectedArgCountForCustomOperator ceenv (nm: Ident) = + match tryGetArgAttribsForCustomOperator ceenv nm with + | None -> None + | Some argInfosForOverloads -> + let nums = + argInfosForOverloads + |> List.map (function + | None -> -1 + | Some argInfos -> List.length argInfos) + + // Prior to 'OverloadsForCustomOperations' we count exact arguments. + // + // With 'OverloadsForCustomOperations' we don't compute an exact expected argument count + // if any arguments are optional, out or ParamArray. + let isSpecial = + if ceenv.cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations then argInfosForOverloads - |> List.map (function + |> List.exists (fun info -> + match info with | None -> false - | Some argInfos -> - i < argInfos.Length - && let _, argInfo = List.item i argInfos in - HasFSharpAttribute cenv.g cenv.g.attrib_ProjectionParameterAttribute argInfo.Attribs) - - if List.allEqual vs then - vs[0] + | Some args -> + args + |> List.exists (fun (ParamAttribs(isParamArrayArg, _isInArg, isOutArg, optArgInfo, _callerInfo, _reflArgInfo)) -> + isParamArrayArg || isOutArg || optArgInfo.IsOptional)) else - let opDatas = (tryGetDataForCustomOperation nm).Value - let opName, _, _, _, _, _, _, _j, _ = opDatas[0] - errorR (Error(FSComp.SR.tcCustomOperationInvalid opName, nm.idRange)) false - // e1 in e2 ('in' is parsed as 'JOIN_IN') - let (|InExpr|_|) synExpr = - match synExpr with - | SynExpr.JoinIn(e1, _, e2, mApp) -> Some(e1, e2, mApp) - | _ -> None + if not isSpecial && nums |> List.forall (fun v -> v >= 0 && v = nums[0]) then + Some(max (nums[0] - 1) 0) // drop the computation context argument + else + None - // e1 on e2 (note: 'on' is the 'JoinConditionWord') - let (|OnExpr|_|) nm synExpr = - match tryGetDataForCustomOperation nm with - | None -> None - | Some _ -> - match synExpr with - | SynExpr.App(funcExpr = SynExpr.App(funcExpr = e1; argExpr = SingleIdent opName); argExpr = e2) when - opName.idText = customOperationJoinConditionWord nm - -> - let item = Item.CustomOperation(opName.idText, (fun () -> None), None) - CallNameResolutionSink cenv.tcSink (opName.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.AccessRights) - Some(e1, e2) - | _ -> None - - // e1 into e2 - let (|IntoSuffix|_|) (e: SynExpr) = - match e with - | SynExpr.App(funcExpr = SynExpr.App(funcExpr = x; argExpr = SingleIdent nm2); argExpr = ExprAsPat intoPat) when - nm2.idText = CustomOperations.Into - -> - Some(x, nm2.idRange, intoPat) - | _ -> None +// Check for the [] attribute on an argument position +let isCustomOperationProjectionParameter ceenv i (nm: Ident) = + match tryGetArgInfosForCustomOperator ceenv nm with + | None -> false + | Some argInfosForOverloads -> + let vs = + argInfosForOverloads + |> List.map (function + | None -> false + | Some argInfos -> + i < argInfos.Length + && let _, argInfo = List.item i argInfos in + HasFSharpAttribute ceenv.cenv.g ceenv.cenv.g.attrib_ProjectionParameterAttribute argInfo.Attribs) + + if List.allEqual vs then + vs[0] + else + let opDatas = (tryGetDataForCustomOperation nm ceenv).Value - let arbPat (m: range) = - mkSynPatVar None (mkSynId (m.MakeSynthetic()) "_missingVar") + let opName, _, _, _, _, _, _, _j, _ = opDatas[0] + errorR (Error(FSComp.SR.tcCustomOperationInvalid opName, nm.idRange)) + false - let MatchIntoSuffixOrRecover alreadyGivenError (nm: Ident) synExpr = - match synExpr with - | IntoSuffix(x, intoWordRange, intoPat) -> - // record the "into" as a custom operation for colorization - let item = Item.CustomOperation("into", (fun () -> None), None) - CallNameResolutionSink cenv.tcSink (intoWordRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) - (x, intoPat, alreadyGivenError) - | _ -> - if not alreadyGivenError then - errorR (Error(FSComp.SR.tcOperatorIncorrectSyntax (nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - - (synExpr, arbPat synExpr.Range, true) - - let MatchOnExprOrRecover alreadyGivenError nm (onExpr: SynExpr) = - match onExpr with - | OnExpr nm (innerSource, SynExprParen(keySelectors, _, _, _)) -> (innerSource, keySelectors) - | _ -> - if not alreadyGivenError then - suppressErrorReporting (fun () -> TcExprOfUnknownType cenv env tpenv onExpr) - |> ignore - - errorR (Error(FSComp.SR.tcOperatorIncorrectSyntax (nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - - (arbExpr ("_innerSource", onExpr.Range), - mkSynBifix onExpr.Range "=" (arbExpr ("_keySelectors", onExpr.Range)) (arbExpr ("_keySelector2", onExpr.Range))) - - let JoinOrGroupJoinOp detector synExpr = - match synExpr with - | SynExpr.App(_, _, CustomOpId isCustomOperation detector nm, ExprAsPat innerSourcePat, mJoinCore) -> - Some(nm, innerSourcePat, mJoinCore, false) - // join with bad pattern (gives error on "join" and continues) - | SynExpr.App(_, _, CustomOpId isCustomOperation detector nm, _innerSourcePatExpr, mJoinCore) -> - errorR (Error(FSComp.SR.tcBinaryOperatorRequiresVariable (nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - Some(nm, arbPat mJoinCore, mJoinCore, true) - // join (without anything after - gives error on "join" and continues) - | CustomOpId isCustomOperation detector nm -> - errorR (Error(FSComp.SR.tcBinaryOperatorRequiresVariable (nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - Some(nm, arbPat synExpr.Range, synExpr.Range, true) - | _ -> None - // JoinOrGroupJoinOp customOperationIsLikeJoin +[] +let (|ExprAsPat|_|) (f: SynExpr) = + match f with + | SingleIdent v1 + | SynExprParen(SingleIdent v1, _, _, _) -> ValueSome(mkSynPatVar None v1) + | SynExprParen(SynExpr.Tuple(false, elems, commas, _), _, _, _) -> + let elems = elems |> List.map (|SingleIdent|_|) - let (|JoinOp|_|) synExpr = - JoinOrGroupJoinOp customOperationIsLikeJoin synExpr + if elems |> List.forall (fun x -> x.IsSome) then + ValueSome(SynPat.Tuple(false, (elems |> List.map (fun x -> mkSynPatVar None x.Value)), commas, f.Range)) + else + ValueNone + | _ -> ValueNone - let (|GroupJoinOp|_|) synExpr = - JoinOrGroupJoinOp customOperationIsLikeGroupJoin synExpr +// For join clauses that join on nullable, we syntactically insert the creation of nullable values on the appropriate side of the condition, +// then pull the syntax apart again +[] +let (|JoinRelation|_|) ceenv (expr: SynExpr) = + let m = expr.Range + let ad = ceenv.env.eAccessRights - let arbKeySelectors m = - mkSynBifix m "=" (arbExpr ("_keySelectors", m)) (arbExpr ("_keySelector2", m)) + let isOpName opName vref s = + (s = opName) + && match + ResolveExprLongIdent + ceenv.cenv.tcSink + ceenv.cenv.nameResolver + m + ad + ceenv.env.eNameResEnv + TypeNameResolutionInfo.Default + [ ident (opName, m) ] + None + with + | Result(_, Item.Value vref2, []) -> valRefEq ceenv.cenv.g vref vref2 + | _ -> false - let (|JoinExpr|_|) synExpr = - match synExpr with - | InExpr(JoinOp(nm, innerSourcePat, _, alreadyGivenError), onExpr, mJoinCore) -> - let innerSource, keySelectors = MatchOnExprOrRecover alreadyGivenError nm onExpr - Some(nm, innerSourcePat, innerSource, keySelectors, mJoinCore) - | JoinOp(nm, innerSourcePat, mJoinCore, alreadyGivenError) -> - if alreadyGivenError then - errorR (Error(FSComp.SR.tcOperatorRequiresIn (nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - - Some(nm, innerSourcePat, arbExpr ("_innerSource", synExpr.Range), arbKeySelectors synExpr.Range, mJoinCore) - | _ -> None + match expr with + | BinOpExpr(opId, a, b) when isOpName opNameEquals ceenv.cenv.g.equals_operator_vref opId.idText -> ValueSome(a, b) - let (|GroupJoinExpr|_|) synExpr = - match synExpr with - | InExpr(GroupJoinOp(nm, innerSourcePat, _, alreadyGivenError), intoExpr, mGroupJoinCore) -> - let onExpr, intoPat, alreadyGivenError = - MatchIntoSuffixOrRecover alreadyGivenError nm intoExpr + | BinOpExpr(opId, a, b) when isOpName opNameEqualsNullable ceenv.cenv.g.equals_nullable_operator_vref opId.idText -> - let innerSource, keySelectors = MatchOnExprOrRecover alreadyGivenError nm onExpr - Some(nm, innerSourcePat, innerSource, keySelectors, intoPat, mGroupJoinCore) - | GroupJoinOp(nm, innerSourcePat, mGroupJoinCore, alreadyGivenError) -> - if alreadyGivenError then - errorR (Error(FSComp.SR.tcOperatorRequiresIn (nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + let a = + SynExpr.App(ExprAtomicFlag.Atomic, false, mkSynLidGet a.Range [ MangledGlobalName; "System" ] "Nullable", a, a.Range) - Some( - nm, - innerSourcePat, - arbExpr ("_innerSource", synExpr.Range), - arbKeySelectors synExpr.Range, - arbPat synExpr.Range, - mGroupJoinCore - ) - | _ -> None + ValueSome(a, b) - let (|JoinOrGroupJoinOrZipClause|_|) synExpr = + | BinOpExpr(opId, a, b) when isOpName opNameNullableEquals ceenv.cenv.g.nullable_equals_operator_vref opId.idText -> - match synExpr with - // join innerSourcePat in innerSource on (keySelector1 = keySelector2) - | JoinExpr(nm, innerSourcePat, innerSource, keySelectors, mJoinCore) -> - Some(nm, innerSourcePat, innerSource, Some keySelectors, None, mJoinCore) + let b = + SynExpr.App(ExprAtomicFlag.Atomic, false, mkSynLidGet b.Range [ MangledGlobalName; "System" ] "Nullable", b, b.Range) - // groupJoin innerSourcePat in innerSource on (keySelector1 = keySelector2) into intoPat - | GroupJoinExpr(nm, innerSourcePat, innerSource, keySelectors, intoPat, mGroupJoinCore) -> - Some(nm, innerSourcePat, innerSource, Some keySelectors, Some intoPat, mGroupJoinCore) + ValueSome(a, b) - // zip intoPat in secondSource - | InExpr(SynExpr.App(_, _, CustomOpId isCustomOperation customOperationIsLikeZip nm, ExprAsPat secondSourcePat, _), - secondSource, - mZipCore) -> Some(nm, secondSourcePat, secondSource, None, None, mZipCore) + | BinOpExpr(opId, a, b) when isOpName opNameNullableEqualsNullable ceenv.cenv.g.nullable_equals_nullable_operator_vref opId.idText -> - // zip (without secondSource or in - gives error) - | CustomOpId isCustomOperation customOperationIsLikeZip nm -> - errorR (Error(FSComp.SR.tcOperatorIncorrectSyntax (nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - Some(nm, arbPat synExpr.Range, arbExpr ("_secondSource", synExpr.Range), None, None, synExpr.Range) + ValueSome(a, b) - // zip secondSource (without in - gives error) - | SynExpr.App(_, _, CustomOpId isCustomOperation customOperationIsLikeZip nm, ExprAsPat secondSourcePat, mZipCore) -> - errorR (Error(FSComp.SR.tcOperatorIncorrectSyntax (nm.idText, Option.get (customOpUsageText nm)), mZipCore)) - Some(nm, secondSourcePat, arbExpr ("_innerSource", synExpr.Range), None, None, mZipCore) + | _ -> ValueNone - | _ -> None +let (|ForEachThen|_|) synExpr = + match synExpr with + | SynExpr.ForEach(_spFor, + _spIn, + SeqExprOnly false, + isFromSource, + pat1, + expr1, + SynExpr.Sequential(isTrueSeq = true; expr1 = clause; expr2 = rest), + _) -> Some(isFromSource, pat1, expr1, clause, rest) + | _ -> None + +let (|CustomOpId|_|) isCustomOperation predicate synExpr = + match synExpr with + | SingleIdent nm when isCustomOperation nm && predicate nm -> Some nm + | _ -> None + +// e1 in e2 ('in' is parsed as 'JOIN_IN') +let (|InExpr|_|) synExpr = + match synExpr with + | SynExpr.JoinIn(e1, _, e2, mApp) -> Some(e1, e2, mApp) + | _ -> None - let (|ForEachThenJoinOrGroupJoinOrZipClause|_|) strict synExpr = +// e1 on e2 (note: 'on' is the 'JoinConditionWord') +let (|OnExpr|_|) ceenv nm synExpr = + match tryGetDataForCustomOperation nm ceenv with + | None -> None + | Some _ -> match synExpr with - | ForEachThen(isFromSource, - firstSourcePat, - firstSource, - JoinOrGroupJoinOrZipClause(nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore), - innerComp) when - (let _firstSourceSimplePats, later1 = - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - SimplePatsOfPat cenv.synArgNameGenerator firstSourcePat - - Option.isNone later1) + | SynExpr.App(funcExpr = SynExpr.App(funcExpr = e1; argExpr = SingleIdent opName); argExpr = e2) when + opName.idText = customOperationJoinConditionWord ceenv nm -> - Some(isFromSource, firstSourcePat, firstSource, nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore, innerComp) + let item = Item.CustomOperation(opName.idText, (fun () -> None), None) - | JoinOrGroupJoinOrZipClause(nm, pat2, expr2, expr3, pat3opt, mOpCore) when strict -> - errorR (Error(FSComp.SR.tcBinaryOperatorRequiresBody (nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) - - Some( - true, - arbPat synExpr.Range, - arbExpr ("_outerSource", synExpr.Range), - nm, - pat2, - expr2, - expr3, - pat3opt, - mOpCore, - arbExpr ("_innerComp", synExpr.Range) - ) + CallNameResolutionSink + ceenv.cenv.tcSink + (opName.idRange, ceenv.env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ceenv.env.AccessRights) + Some(e1, e2) | _ -> None - let (|StripApps|) e = - let rec strip e = - match e with - | SynExpr.FromParseError(SynExpr.App(funcExpr = f; argExpr = arg), _) - | SynExpr.App(funcExpr = f; argExpr = arg) -> - let g, acc = strip f - g, (arg :: acc) - | _ -> e, [] +// e1 into e2 +let (|IntoSuffix|_|) (e: SynExpr) = + match e with + | SynExpr.App(funcExpr = SynExpr.App(funcExpr = x; argExpr = SingleIdent nm2); argExpr = ExprAsPat intoPat) when + nm2.idText = CustomOperations.Into + -> + Some(x, nm2.idRange, intoPat) + | _ -> None - let g, acc = strip e - g, List.rev acc +let JoinOrGroupJoinOp ceenv detector synExpr = + match synExpr with + | SynExpr.App(_, _, CustomOpId (isCustomOperation ceenv) detector nm, ExprAsPat innerSourcePat, mJoinCore) -> + Some(nm, innerSourcePat, mJoinCore, false) + // join with bad pattern (gives error on "join" and continues) + | SynExpr.App(_, _, CustomOpId (isCustomOperation ceenv) detector nm, _innerSourcePatExpr, mJoinCore) -> + errorR (Error(FSComp.SR.tcBinaryOperatorRequiresVariable (nm.idText, Option.get (customOpUsageText ceenv nm)), nm.idRange)) + + Some(nm, arbPat mJoinCore, mJoinCore, true) + // join (without anything after - gives error on "join" and continues) + | CustomOpId (isCustomOperation ceenv) detector nm -> + errorR (Error(FSComp.SR.tcBinaryOperatorRequiresVariable (nm.idText, Option.get (customOpUsageText ceenv nm)), nm.idRange)) + + Some(nm, arbPat synExpr.Range, synExpr.Range, true) + | _ -> None +// JoinOrGroupJoinOp customOperationIsLikeJoin - let (|OptionalIntoSuffix|) e = - match e with - | IntoSuffix(body, intoWordRange, intoInfo) -> (body, Some(intoWordRange, intoInfo)) - | body -> (body, None) +let (|JoinOp|_|) ceenv synExpr = + JoinOrGroupJoinOp ceenv (customOperationIsLikeJoin ceenv) synExpr - let (|CustomOperationClause|_|) e = - match e with - | OptionalIntoSuffix(StripApps(SingleIdent nm, _) as core, intoOpt) when isCustomOperation nm -> - // Now we know we have a custom operation, commit the name resolution - let intoInfoOpt = - match intoOpt with - | Some(intoWordRange, intoInfo) -> - let item = Item.CustomOperation("into", (fun () -> None), None) +let (|GroupJoinOp|_|) ceenv synExpr = + JoinOrGroupJoinOp ceenv (customOperationIsLikeGroupJoin ceenv) synExpr - CallNameResolutionSink - cenv.tcSink - (intoWordRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) +let MatchIntoSuffixOrRecover ceenv alreadyGivenError (nm: Ident) synExpr = + match synExpr with + | IntoSuffix(x, intoWordRange, intoPat) -> + // record the "into" as a custom operation for colorization + let item = Item.CustomOperation("into", (fun () -> None), None) - Some intoInfo - | None -> None + CallNameResolutionSink + ceenv.cenv.tcSink + (intoWordRange, ceenv.env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ceenv.env.eAccessRights) - Some(nm, Option.get (tryGetDataForCustomOperation nm), core, core.Range, intoInfoOpt) - | _ -> None + (x, intoPat, alreadyGivenError) + | _ -> + if not alreadyGivenError then + errorR (Error(FSComp.SR.tcOperatorIncorrectSyntax (nm.idText, Option.get (customOpUsageText ceenv nm)), nm.idRange)) - let mkSynLambda p e m = - SynExpr.Lambda(false, false, p, e, None, m, SynExprLambdaTrivia.Zero) + (synExpr, arbPat synExpr.Range, true) - let mkExprForVarSpace m (patvs: Val list) = - match patvs with - | [] -> SynExpr.Const(SynConst.Unit, m) - | [ v ] -> SynExpr.Ident v.Id - | vs -> SynExpr.Tuple(false, (vs |> List.map (fun v -> SynExpr.Ident(v.Id))), [], m) +let MatchOnExprOrRecover ceenv alreadyGivenError nm (onExpr: SynExpr) = + match onExpr with + | OnExpr ceenv nm (innerSource, SynExprParen(keySelectors, _, _, _)) -> (innerSource, keySelectors) + | _ -> + if not alreadyGivenError then + suppressErrorReporting (fun () -> TcExprOfUnknownType ceenv.cenv ceenv.env ceenv.tpenv onExpr) + |> ignore - let mkSimplePatForVarSpace m (patvs: Val list) = - let spats = - match patvs with - | [] -> [] - | [ v ] -> [ mkSynSimplePatVar false v.Id ] - | vs -> vs |> List.map (fun v -> mkSynSimplePatVar false v.Id) + errorR (Error(FSComp.SR.tcOperatorIncorrectSyntax (nm.idText, Option.get (customOpUsageText ceenv nm)), nm.idRange)) - SynSimplePats.SimplePats(spats, [], m) + (arbExpr ("_innerSource", onExpr.Range), + mkSynBifix onExpr.Range "=" (arbExpr ("_keySelectors", onExpr.Range)) (arbExpr ("_keySelector2", onExpr.Range))) - let mkPatForVarSpace m (patvs: Val list) = - match patvs with - | [] -> SynPat.Const(SynConst.Unit, m) - | [ v ] -> mkSynPatVar None v.Id - | vs -> SynPat.Tuple(false, (vs |> List.map (fun x -> mkSynPatVar None x.Id)), [], m) +let (|JoinExpr|_|) (ceenv: ComputationExpressionContext<'a>) synExpr = + match synExpr with + | InExpr(JoinOp ceenv (nm, innerSourcePat, _, alreadyGivenError), onExpr, mJoinCore) -> + let innerSource, keySelectors = + MatchOnExprOrRecover ceenv alreadyGivenError nm onExpr - let (|OptionalSequential|) e = - match e with - | SynExpr.Sequential(debugPoint = _sp; isTrueSeq = true; expr1 = dataComp1; expr2 = dataComp2) -> (dataComp1, Some dataComp2) - | _ -> (e, None) - - // "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1) - // This is not pretty - we have to decide which range markers we use for the calls to Combine and Delay - // NOTE: we should probably suppress these sequence points altogether - let rangeForCombine innerComp1 = - let m = - match innerComp1 with - | SynExpr.IfThenElse(trivia = { IfToThenRange = mIfToThen }) -> mIfToThen - | SynExpr.Match(matchDebugPoint = DebugPointAtBinding.Yes mMatch) -> mMatch - | SynExpr.TryWith(trivia = { TryKeyword = mTry }) -> mTry - | SynExpr.TryFinally(trivia = { TryKeyword = mTry }) -> mTry - | SynExpr.For(forDebugPoint = DebugPointAtFor.Yes mBind) -> mBind - | SynExpr.ForEach(forDebugPoint = DebugPointAtFor.Yes mBind) -> mBind - | SynExpr.While(whileDebugPoint = DebugPointAtWhile.Yes mWhile) -> mWhile - | _ -> innerComp1.Range - - m.NoteSourceConstruct(NotedSourceConstruct.Combine) - - // Check for 'where x > y', 'select x, y' and other mis-applications of infix operators, give a good error message, and return a flag - let checkForBinaryApp comp = - match comp with - | StripApps(SingleIdent nm, [ StripApps(SingleIdent nm2, args); arg2 ]) when - IsLogicalInfixOpName nm.idText - && (match tryExpectedArgCountForCustomOperator nm2 with - | Some n -> n > 0 - | _ -> false) - && not (List.isEmpty args) - -> - let estimatedRangeOfIntendedLeftAndRightArguments = - unionRanges (List.last args).Range arg2.Range - - errorR (Error(FSComp.SR.tcUnrecognizedQueryBinaryOperator (), estimatedRangeOfIntendedLeftAndRightArguments)) - true - | SynExpr.Tuple(false, StripApps(SingleIdent nm2, args) :: _, _, m) when - (match tryExpectedArgCountForCustomOperator nm2 with - | Some n -> n > 0 - | _ -> false) - && not (List.isEmpty args) - -> - let estimatedRangeOfIntendedLeftAndRightArguments = - unionRanges (List.last args).Range m.EndRange + Some(nm, innerSourcePat, innerSource, keySelectors, mJoinCore) + | JoinOp ceenv (nm, innerSourcePat, mJoinCore, alreadyGivenError) -> + if alreadyGivenError then + errorR (Error(FSComp.SR.tcOperatorRequiresIn (nm.idText, Option.get (customOpUsageText ceenv nm)), nm.idRange)) - errorR (Error(FSComp.SR.tcUnrecognizedQueryBinaryOperator (), estimatedRangeOfIntendedLeftAndRightArguments)) - true - | _ -> false + Some(nm, innerSourcePat, arbExpr ("_innerSource", synExpr.Range), arbKeySelectors synExpr.Range, mJoinCore) + | _ -> None - let addVarsToVarSpace (varSpace: LazyWithContext) f = - LazyWithContext.Create( - (fun m -> - let (patvs: Val list, env) = varSpace.Force m - let vs, envinner = f m env +let (|GroupJoinExpr|_|) ceenv synExpr = + match synExpr with + | InExpr(GroupJoinOp ceenv (nm, innerSourcePat, _, alreadyGivenError), intoExpr, mGroupJoinCore) -> + let onExpr, intoPat, alreadyGivenError = + MatchIntoSuffixOrRecover ceenv alreadyGivenError nm intoExpr + + let innerSource, keySelectors = + MatchOnExprOrRecover ceenv alreadyGivenError nm onExpr + + Some(nm, innerSourcePat, innerSource, keySelectors, intoPat, mGroupJoinCore) + | GroupJoinOp ceenv (nm, innerSourcePat, mGroupJoinCore, alreadyGivenError) -> + if alreadyGivenError then + errorR (Error(FSComp.SR.tcOperatorRequiresIn (nm.idText, Option.get (customOpUsageText ceenv nm)), nm.idRange)) + + Some( + nm, + innerSourcePat, + arbExpr ("_innerSource", synExpr.Range), + arbKeySelectors synExpr.Range, + arbPat synExpr.Range, + mGroupJoinCore + ) + | _ -> None - let patvs = - List.append - patvs - (vs - |> List.filter (fun v -> not (patvs |> List.exists (fun v2 -> v.LogicalName = v2.LogicalName)))) +let (|JoinOrGroupJoinOrZipClause|_|) (ceenv: ComputationExpressionContext<'a>) synExpr = - patvs, envinner), - id - ) + match synExpr with + // join innerSourcePat in innerSource on (keySelector1 = keySelector2) + | JoinExpr ceenv (nm, innerSourcePat, innerSource, keySelectors, mJoinCore) -> + Some(nm, innerSourcePat, innerSource, Some keySelectors, None, mJoinCore) - // Flag that a debug point should get emitted prior to both the evaluation of 'rhsExpr' and the call to Using - let addBindDebugPoint spBind e = - match spBind with - | DebugPointAtBinding.Yes m -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, e) - | _ -> e + // groupJoin innerSourcePat in innerSource on (keySelector1 = keySelector2) into intoPat + | GroupJoinExpr ceenv (nm, innerSourcePat, innerSource, keySelectors, intoPat, mGroupJoinCore) -> + Some(nm, innerSourcePat, innerSource, Some keySelectors, Some intoPat, mGroupJoinCore) - let emptyVarSpace = LazyWithContext.NotLazy([], env) + // zip intoPat in secondSource + | InExpr(SynExpr.App(_, _, CustomOpId (isCustomOperation ceenv) (customOperationIsLikeZip ceenv) nm, ExprAsPat secondSourcePat, _), + secondSource, + mZipCore) -> Some(nm, secondSourcePat, secondSource, None, None, mZipCore) - // If there are no 'yield' in the computation expression, and the builder supports 'Yield', - // then allow the type-directed rule interpreting non-unit-typed expressions in statement - // positions as 'yield'. 'yield!' may be present in the computation expression. - let enableImplicitYield = - cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield - && (hasMethInfo "Yield" cenv env mBuilderVal ad builderTy - && hasMethInfo "Combine" cenv env mBuilderVal ad builderTy - && hasMethInfo "Delay" cenv env mBuilderVal ad builderTy - && YieldFree cenv comp) + // zip (without secondSource or in - gives error) + | CustomOpId (isCustomOperation ceenv) (customOperationIsLikeZip ceenv) nm -> + errorR (Error(FSComp.SR.tcOperatorIncorrectSyntax (nm.idText, Option.get (customOpUsageText ceenv nm)), nm.idRange)) - let origComp = comp + Some(nm, arbPat synExpr.Range, arbExpr ("_secondSource", synExpr.Range), None, None, synExpr.Range) - /// - /// Try translate the syntax sugar - /// - /// - /// a flag indicating if custom operators are allowed. They are not allowed inside try/with, try/finally, if/then/else etc. - /// a lazy data structure indicating the variables bound so far in the overall computation - /// the computation expression being analyzed - /// represents the translation of the context in which the computation expression 'comp' occurs, - /// up to a hole to be filled by (part of) the results of translating 'comp'. - let rec tryTrans - (firstTry: CompExprTranslationPass) - (q: CustomOperationsMode) - (varSpace: LazyWithContext<(Val list * TcEnv), range>) - (comp: SynExpr) - (translatedCtxt: SynExpr -> SynExpr) - : SynExpr option = - // Guard the stack for deeply nested computation expressions - cenv.stackGuard.Guard - <| fun () -> + // zip secondSource (without in - gives error) + | SynExpr.App(_, _, CustomOpId (isCustomOperation ceenv) (customOperationIsLikeZip ceenv) nm, ExprAsPat secondSourcePat, mZipCore) -> + errorR (Error(FSComp.SR.tcOperatorIncorrectSyntax (nm.idText, Option.get (customOpUsageText ceenv nm)), mZipCore)) - match comp with + Some(nm, secondSourcePat, arbExpr ("_innerSource", synExpr.Range), None, None, mZipCore) - // for firstSourcePat in firstSource do - // join secondSourcePat in expr2 on (expr3 = expr4) - // ... - // --> - // join expr1 expr2 (fun firstSourcePat -> expr3) (fun secondSourcePat -> expr4) (fun firstSourcePat secondSourcePat -> ...) - - // for firstSourcePat in firstSource do - // groupJoin secondSourcePat in expr2 on (expr3 = expr4) into groupPat - // ... - // --> - // groupJoin expr1 expr2 (fun firstSourcePat -> expr3) (fun secondSourcePat -> expr4) (fun firstSourcePat groupPat -> ...) - - // for firstSourcePat in firstSource do - // zip secondSource into secondSourcePat - // ... - // --> - // zip expr1 expr2 (fun pat1 pat3 -> ...) - | ForEachThenJoinOrGroupJoinOrZipClause true (isFromSource, - firstSourcePat, - firstSource, - nm, - secondSourcePat, - secondSource, - keySelectorsOpt, - secondResultPatOpt, - mOpCore, - innerComp) -> - match q with - | CustomOperationsMode.Denied -> error (Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere (), nm.idRange)) - | CustomOperationsMode.Allowed -> - - let firstSource = - mkSourceExprConditional isFromSource firstSource sourceMethInfo builderValName - - let secondSource = mkSourceExpr secondSource sourceMethInfo builderValName - - // Add the variables to the variable space, on demand - let varSpaceWithFirstVars = - addVarsToVarSpace varSpace (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + | _ -> None - let _, _, vspecs, envinner, _ = - TcMatchPattern cenv (NewInferenceType g) env tpenv firstSourcePat None +let (|ForEachThenJoinOrGroupJoinOrZipClause|_|) (ceenv: ComputationExpressionContext<'a>) strict synExpr = + match synExpr with + | ForEachThen(isFromSource, + firstSourcePat, + firstSource, + JoinOrGroupJoinOrZipClause ceenv (nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore), + innerComp) when + (let _firstSourceSimplePats, later1 = + use _holder = TemporarilySuspendReportingTypecheckResultsToSink ceenv.cenv.tcSink + SimplePatsOfPat ceenv.cenv.synArgNameGenerator firstSourcePat + + Option.isNone later1) + -> + Some(isFromSource, firstSourcePat, firstSource, nm, secondSourcePat, secondSource, keySelectorsOpt, pat3opt, mOpCore, innerComp) + + | JoinOrGroupJoinOrZipClause ceenv (nm, pat2, expr2, expr3, pat3opt, mOpCore) when strict -> + errorR (Error(FSComp.SR.tcBinaryOperatorRequiresBody (nm.idText, Option.get (customOpUsageText ceenv nm)), nm.idRange)) + + Some( + true, + arbPat synExpr.Range, + arbExpr ("_outerSource", synExpr.Range), + nm, + pat2, + expr2, + expr3, + pat3opt, + mOpCore, + arbExpr ("_innerComp", synExpr.Range) + ) - vspecs, envinner) + | _ -> None - let varSpaceWithSecondVars = - addVarsToVarSpace varSpaceWithFirstVars (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink +let (|StripApps|) e = + let rec strip e = + match e with + | SynExpr.FromParseError(SynExpr.App(funcExpr = f; argExpr = arg), _) + | SynExpr.App(funcExpr = f; argExpr = arg) -> + let g, acc = strip f + g, (arg :: acc) + | _ -> e, [] + + let g, acc = strip e + g, List.rev acc + +let (|OptionalIntoSuffix|) e = + match e with + | IntoSuffix(body, intoWordRange, intoInfo) -> (body, Some(intoWordRange, intoInfo)) + | body -> (body, None) + +let (|CustomOperationClause|_|) ceenv e = + match e with + | OptionalIntoSuffix(StripApps(SingleIdent nm, _) as core, intoOpt) when isCustomOperation ceenv nm -> + // Now we know we have a custom operation, commit the name resolution + let intoInfoOpt = + match intoOpt with + | Some(intoWordRange, intoInfo) -> + let item = Item.CustomOperation("into", (fun () -> None), None) + + CallNameResolutionSink + ceenv.cenv.tcSink + (intoWordRange, ceenv.env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ceenv.env.eAccessRights) + + Some intoInfo + | None -> None - let _, _, vspecs, envinner, _ = - TcMatchPattern cenv (NewInferenceType g) env tpenv secondSourcePat None + Some(nm, Option.get (tryGetDataForCustomOperation nm ceenv), core, core.Range, intoInfoOpt) + | _ -> None - vspecs, envinner) +let (|OptionalSequential|) e = + match e with + | SynExpr.Sequential(debugPoint = _sp; isTrueSeq = true; expr1 = dataComp1; expr2 = dataComp2) -> (dataComp1, Some dataComp2) + | _ -> (e, None) + +// "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1) +// This is not pretty - we have to decide which range markers we use for the calls to Combine and Delay +// NOTE: we should probably suppress these sequence points altogether +let rangeForCombine innerComp1 = + let m = + match innerComp1 with + | SynExpr.IfThenElse(trivia = { IfToThenRange = mIfToThen }) -> mIfToThen + | SynExpr.Match(matchDebugPoint = DebugPointAtBinding.Yes mMatch) -> mMatch + | SynExpr.TryWith(trivia = { TryKeyword = mTry }) -> mTry + | SynExpr.TryFinally(trivia = { TryKeyword = mTry }) -> mTry + | SynExpr.For(forDebugPoint = DebugPointAtFor.Yes mBind) -> mBind + | SynExpr.ForEach(forDebugPoint = DebugPointAtFor.Yes mBind) -> mBind + | SynExpr.While(whileDebugPoint = DebugPointAtWhile.Yes mWhile) -> mWhile + | _ -> innerComp1.Range + + m.NoteSourceConstruct(NotedSourceConstruct.Combine) + +// Check for 'where x > y', 'select x, y' and other mis-applications of infix operators, give a good error message, and return a flag +let checkForBinaryApp ceenv comp = + match comp with + | StripApps(SingleIdent nm, [ StripApps(SingleIdent nm2, args); arg2 ]) when + IsLogicalInfixOpName nm.idText + && (match tryExpectedArgCountForCustomOperator ceenv nm2 with + | Some n -> n > 0 + | _ -> false) + && not (List.isEmpty args) + -> + let estimatedRangeOfIntendedLeftAndRightArguments = + unionRanges (List.last args).Range arg2.Range + + errorR (Error(FSComp.SR.tcUnrecognizedQueryBinaryOperator (), estimatedRangeOfIntendedLeftAndRightArguments)) + true + | SynExpr.Tuple(false, StripApps(SingleIdent nm2, args) :: _, _, m) when + (match tryExpectedArgCountForCustomOperator ceenv nm2 with + | Some n -> n > 0 + | _ -> false) + && not (List.isEmpty args) + -> + let estimatedRangeOfIntendedLeftAndRightArguments = + unionRanges (List.last args).Range m.EndRange + + errorR (Error(FSComp.SR.tcUnrecognizedQueryBinaryOperator (), estimatedRangeOfIntendedLeftAndRightArguments)) + true + | _ -> false + +let inline addVarsToVarSpace (varSpace: LazyWithContext) f = + LazyWithContext.Create( + (fun m -> + let (patvs: Val list, env) = varSpace.Force m + let vs, envinner = f m env + + let patvs = + List.append + patvs + (vs + |> List.filter (fun v -> not (patvs |> List.exists (fun v2 -> v.LogicalName = v2.LogicalName)))) + + patvs, envinner), + id + ) + +/// +/// Try translate the syntax sugar +/// +/// Computation expression context (carrying caches, environments, ranges, etc) +/// Flag if it's inital check +/// a flag indicating if custom operators are allowed. They are not allowed inside try/with, try/finally, if/then/else etc. +/// a lazy data structure indicating the variables bound so far in the overall computation +/// the computation expression being analyzed +/// represents the translation of the context in which the computation expression 'comp' occurs, +/// up to a hole to be filled by (part of) the results of translating 'comp'. +/// +/// +let rec TryTranslateComputationExpression + (ceenv: ComputationExpressionContext<'a>) + (firstTry: CompExprTranslationPass) + (q: CustomOperationsMode) + (varSpace: LazyWithContext<(Val list * TcEnv), range>) + (comp: SynExpr) + (translatedCtxt: SynExpr -> SynExpr) + : SynExpr option = + // Guard the stack for deeply nested computation expressions + + let cenv = ceenv.cenv + + cenv.stackGuard.Guard + <| fun () -> - let varSpaceWithGroupJoinVars = - match secondResultPatOpt with - | Some pat3 -> - addVarsToVarSpace varSpaceWithFirstVars (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - - let _, _, vspecs, envinner, _ = - TcMatchPattern cenv (NewInferenceType g) env tpenv pat3 None - - vspecs, envinner) - | None -> varSpace - - let firstSourceSimplePats, later1 = - SimplePatsOfPat cenv.synArgNameGenerator firstSourcePat - - let secondSourceSimplePats, later2 = - SimplePatsOfPat cenv.synArgNameGenerator secondSourcePat - - if Option.isSome later1 then - errorR (Error(FSComp.SR.tcJoinMustUseSimplePattern (nm.idText), firstSourcePat.Range)) - - if Option.isSome later2 then - errorR (Error(FSComp.SR.tcJoinMustUseSimplePattern (nm.idText), secondSourcePat.Range)) - - // check 'join' or 'groupJoin' or 'zip' is permitted for this builder - match tryGetDataForCustomOperation nm with - | None -> error (Error(FSComp.SR.tcMissingCustomOperation (nm.idText), nm.idRange)) - | Some opDatas -> - let opName, _, _, _, _, _, _, _, methInfo = opDatas[0] - - // Record the resolution of the custom operation for posterity - let item = - Item.CustomOperation(opName, (fun () -> customOpUsageText nm), Some methInfo) - - // FUTURE: consider whether we can do better than emptyTyparInst here, in order to display instantiations - // of type variables in the quick info provided in the IDE. - CallNameResolutionSink - cenv.tcSink - (nm.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) - - let mkJoinExpr keySelector1 keySelector2 innerPat e = - let mSynthetic = mOpCore.MakeSynthetic() - - mkSynCall - methInfo.DisplayName - mOpCore - [ - firstSource - secondSource - mkSynLambda firstSourceSimplePats keySelector1 mSynthetic - mkSynLambda secondSourceSimplePats keySelector2 mSynthetic - mkSynLambda firstSourceSimplePats (mkSynLambda innerPat e mSynthetic) mSynthetic - ] - - let mkZipExpr e = - let mSynthetic = mOpCore.MakeSynthetic() - - mkSynCall - methInfo.DisplayName - mOpCore - [ - firstSource - secondSource - mkSynLambda firstSourceSimplePats (mkSynLambda secondSourceSimplePats e mSynthetic) mSynthetic - ] - - // wraps given expression into sequence with result produced by arbExpr so result will look like: - // l; SynExpr.ArbitraryAfterError (...) - // this allows to handle cases like 'on (a > b)' // '>' is not permitted as correct join relation - // after wrapping a and b can still be typechecked (so we'll have correct completion inside 'on' part) - // but presence of SynExpr.ArbitraryAfterError allows to avoid errors about incompatible types in cases like - // query { - // for a in [1] do - // join b in [""] on (a > b) - // } - // if we typecheck raw 'a' and 'b' then we'll end up with 2 errors: - // 1. incorrect join relation - // 2. incompatible types: int and string - // with SynExpr.ArbitraryAfterError we have only first one - let wrapInArbErrSequence l caption = - SynExpr.Sequential( - DebugPointAtSequential.SuppressNeither, - true, - l, - (arbExpr (caption, l.Range.EndRange)), - l.Range, - SynExprSequentialTrivia.Zero - ) + match comp with - let mkOverallExprGivenVarSpaceExpr, varSpaceInner = - - let isNullableOp opId = - match ConvertValLogicalNameToDisplayNameCore opId with - | "?=" - | "=?" - | "?=?" -> true - | _ -> false - - match secondResultPatOpt, keySelectorsOpt with - // groupJoin - | Some secondResultPat, Some relExpr when customOperationIsLikeGroupJoin nm -> - let secondResultSimplePats, later3 = - SimplePatsOfPat cenv.synArgNameGenerator secondResultPat - - if Option.isSome later3 then - errorR (Error(FSComp.SR.tcJoinMustUseSimplePattern (nm.idText), secondResultPat.Range)) - - match relExpr with - | JoinRelation cenv env (keySelector1, keySelector2) -> - mkJoinExpr keySelector1 keySelector2 secondResultSimplePats, varSpaceWithGroupJoinVars - | BinOpExpr(opId, l, r) -> - if isNullableOp opId.idText then - // When we cannot resolve NullableOps, recommend the relevant namespace to be added - errorR ( - Error( - FSComp.SR.cannotResolveNullableOperators ( - ConvertValLogicalNameToDisplayNameCore opId.idText - ), - relExpr.Range - ) - ) - else - errorR (Error(FSComp.SR.tcInvalidRelationInJoin (nm.idText), relExpr.Range)) - - let l = wrapInArbErrSequence l "_keySelector1" - let r = wrapInArbErrSequence r "_keySelector2" - // this is not correct JoinRelation but it is still binary operation - // we've already reported error now we can use operands of binary operation as join components - mkJoinExpr l r secondResultSimplePats, varSpaceWithGroupJoinVars - | _ -> - errorR (Error(FSComp.SR.tcInvalidRelationInJoin (nm.idText), relExpr.Range)) - // since the shape of relExpr doesn't match our expectations (JoinRelation) - // then we assume that this is l.h.s. of the join relation - // so typechecker will treat relExpr as body of outerKeySelector lambda parameter in GroupJoin method - mkJoinExpr relExpr (arbExpr ("_keySelector2", relExpr.Range)) secondResultSimplePats, - varSpaceWithGroupJoinVars - - | None, Some relExpr when customOperationIsLikeJoin nm -> - match relExpr with - | JoinRelation cenv env (keySelector1, keySelector2) -> - mkJoinExpr keySelector1 keySelector2 secondSourceSimplePats, varSpaceWithSecondVars - | BinOpExpr(opId, l, r) -> - if isNullableOp opId.idText then - // When we cannot resolve NullableOps, recommend the relevant namespace to be added - errorR ( - Error( - FSComp.SR.cannotResolveNullableOperators ( - ConvertValLogicalNameToDisplayNameCore opId.idText - ), - relExpr.Range - ) - ) - else - errorR (Error(FSComp.SR.tcInvalidRelationInJoin (nm.idText), relExpr.Range)) - // this is not correct JoinRelation but it is still binary operation - // we've already reported error now we can use operands of binary operation as join components - let l = wrapInArbErrSequence l "_keySelector1" - let r = wrapInArbErrSequence r "_keySelector2" - mkJoinExpr l r secondSourceSimplePats, varSpaceWithGroupJoinVars - | _ -> - errorR (Error(FSComp.SR.tcInvalidRelationInJoin (nm.idText), relExpr.Range)) - // since the shape of relExpr doesn't match our expectations (JoinRelation) - // then we assume that this is l.h.s. of the join relation - // so typechecker will treat relExpr as body of outerKeySelector lambda parameter in Join method - mkJoinExpr relExpr (arbExpr ("_keySelector2", relExpr.Range)) secondSourceSimplePats, - varSpaceWithGroupJoinVars + // for firstSourcePat in firstSource do + // join secondSourcePat in expr2 on (expr3 = expr4) + // ... + // --> + // join expr1 expr2 (fun firstSourcePat -> expr3) (fun secondSourcePat -> expr4) (fun firstSourcePat secondSourcePat -> ...) + + // for firstSourcePat in firstSource do + // groupJoin secondSourcePat in expr2 on (expr3 = expr4) into groupPat + // ... + // --> + // groupJoin expr1 expr2 (fun firstSourcePat -> expr3) (fun secondSourcePat -> expr4) (fun firstSourcePat groupPat -> ...) + + // for firstSourcePat in firstSource do + // zip secondSource into secondSourcePat + // ... + // --> + // zip expr1 expr2 (fun pat1 pat3 -> ...) + | ForEachThenJoinOrGroupJoinOrZipClause ceenv true (isFromSource, + firstSourcePat, + firstSource, + nm, + secondSourcePat, + secondSource, + keySelectorsOpt, + secondResultPatOpt, + mOpCore, + innerComp) -> + match q with + | CustomOperationsMode.Denied -> error (Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere (), nm.idRange)) + | CustomOperationsMode.Allowed -> + + let firstSource = + mkSourceExprConditional isFromSource firstSource ceenv.sourceMethInfo ceenv.builderValName + + let secondSource = + mkSourceExpr secondSource ceenv.sourceMethInfo ceenv.builderValName + + // Add the variables to the variable space, on demand + let varSpaceWithFirstVars = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - | None, None when customOperationIsLikeZip nm -> mkZipExpr, varSpaceWithSecondVars + let _, _, vspecs, envinner, _ = + TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv firstSourcePat None - | _ -> - assert false - failwith "unreachable" + vspecs, envinner) - // Case from C# spec: A query expression with a join clause with an into followed by something other than a select clause - // Case from C# spec: A query expression with a join clause without an into followed by something other than a select clause - let valsInner, _env = varSpaceInner.Force mOpCore - let varSpaceExpr = mkExprForVarSpace mOpCore valsInner - let varSpacePat = mkPatForVarSpace mOpCore valsInner - let joinExpr = mkOverallExprGivenVarSpaceExpr varSpaceExpr builderValName + let varSpaceWithSecondVars = + addVarsToVarSpace varSpaceWithFirstVars (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - let consumingExpr = - SynExpr.ForEach( - DebugPointAtFor.No, - DebugPointAtInOrTo.No, - SeqExprOnly false, - false, - varSpacePat, - joinExpr, - innerComp, - mOpCore - ) + let _, _, vspecs, envinner, _ = + TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv secondSourcePat None - Some(trans CompExprTranslationPass.Initial q varSpaceInner consumingExpr translatedCtxt) + vspecs, envinner) - | SynExpr.ForEach(spFor, spIn, SeqExprOnly _seqExprOnly, isFromSource, pat, sourceExpr, innerComp, _mEntireForEach) -> - let sourceExpr = - match RewriteRangeExpr sourceExpr with - | Some e -> e - | None -> sourceExpr + let varSpaceWithGroupJoinVars = + match secondResultPatOpt with + | Some pat3 -> + addVarsToVarSpace varSpaceWithFirstVars (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - let wrappedSourceExpr = - mkSourceExprConditional isFromSource sourceExpr sourceMethInfo builderValName + let _, _, vspecs, envinner, _ = + TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat3 None - let mFor = - match spFor with - | DebugPointAtFor.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.For) - | DebugPointAtFor.No -> pat.Range + vspecs, envinner) + | None -> varSpace - // For computation expressions, 'in' or 'to' is hit on each MoveNext. - // To support this a named debug point for the "in" keyword is available to inlined code. - match spIn with - | DebugPointAtInOrTo.Yes mIn -> - cenv.namedDebugPointsForInlinedCode[{ - Range = mFor - Name = "ForLoop.InOrToKeyword" - }] <- mIn - | _ -> () + let firstSourceSimplePats, later1 = + SimplePatsOfPat cenv.synArgNameGenerator firstSourcePat - let mPat = pat.Range + let secondSourceSimplePats, later2 = + SimplePatsOfPat cenv.synArgNameGenerator secondSourcePat - if - isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mFor ad "For" builderTy) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("For"), mFor)) + if Option.isSome later1 then + errorR (Error(FSComp.SR.tcJoinMustUseSimplePattern (nm.idText), firstSourcePat.Range)) - // Add the variables to the query variable space, on demand - let varSpace = - addVarsToVarSpace varSpace (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + if Option.isSome later2 then + errorR (Error(FSComp.SR.tcJoinMustUseSimplePattern (nm.idText), secondSourcePat.Range)) - let _, _, vspecs, envinner, _ = - TcMatchPattern cenv (NewInferenceType g) env tpenv pat None + // check 'join' or 'groupJoin' or 'zip' is permitted for this builder + match tryGetDataForCustomOperation nm ceenv with + | None -> error (Error(FSComp.SR.tcMissingCustomOperation (nm.idText), nm.idRange)) + | Some opDatas -> + let opName, _, _, _, _, _, _, _, methInfo = opDatas[0] - vspecs, envinner) + // Record the resolution of the custom operation for posterity + let item = + Item.CustomOperation(opName, (fun () -> customOpUsageText ceenv nm), Some methInfo) - Some( - trans CompExprTranslationPass.Initial q varSpace innerComp (fun innerCompR -> - - let forCall = - mkSynCall - "For" - mFor - [ - wrappedSourceExpr - SynExpr.MatchLambda( - false, - mPat, - [ - SynMatchClause(pat, None, innerCompR, mPat, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero) - ], - DebugPointAtBinding.NoneAtInvisible, - mFor - ) - ] - builderValName + // FUTURE: consider whether we can do better than emptyTyparInst here, in order to display instantiations + // of type variables in the quick info provided in the IDE. + CallNameResolutionSink + cenv.tcSink + (nm.idRange, ceenv.env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ceenv.env.eAccessRights) - let forCall = - match spFor with - | DebugPointAtFor.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mFor, false, forCall) - | DebugPointAtFor.No -> forCall + let mkJoinExpr keySelector1 keySelector2 innerPat e = + let mSynthetic = mOpCore.MakeSynthetic() - translatedCtxt forCall) - ) + mkSynCall + methInfo.DisplayName + mOpCore + [ + firstSource + secondSource + mkSynLambda firstSourceSimplePats keySelector1 mSynthetic + mkSynLambda secondSourceSimplePats keySelector2 mSynthetic + mkSynLambda firstSourceSimplePats (mkSynLambda innerPat e mSynthetic) mSynthetic + ] - | SynExpr.For( - forDebugPoint = spFor - toDebugPoint = spTo - ident = id - identBody = start - direction = dir - toBody = finish - doBody = innerComp - range = m) -> - let mFor = - match spFor with - | DebugPointAtFor.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.For) - | _ -> m + let mkZipExpr e = + let mSynthetic = mOpCore.MakeSynthetic() - if isQuery then - errorR (Error(FSComp.SR.tcNoIntegerForLoopInQuery (), mFor)) + mkSynCall + methInfo.DisplayName + mOpCore + [ + firstSource + secondSource + mkSynLambda firstSourceSimplePats (mkSynLambda secondSourceSimplePats e mSynthetic) mSynthetic + ] - let reduced = - elimFastIntegerForLoop (spFor, spTo, id, start, dir, finish, innerComp, m) + // wraps given expression into sequence with result produced by arbExpr so result will look like: + // l; SynExpr.ArbitraryAfterError (...) + // this allows to handle cases like 'on (a > b)' // '>' is not permitted as correct join relation + // after wrapping a and b can still be typechecked (so we'll have correct completion inside 'on' part) + // but presence of SynExpr.ArbitraryAfterError allows to avoid errors about incompatible types in cases like + // query { + // for a in [1] do + // join b in [""] on (a > b) + // } + // if we typecheck raw 'a' and 'b' then we'll end up with 2 errors: + // 1. incorrect join relation + // 2. incompatible types: int and string + // with SynExpr.ArbitraryAfterError we have only first one + let wrapInArbErrSequence l caption = + SynExpr.Sequential( + DebugPointAtSequential.SuppressNeither, + true, + l, + (arbExpr (caption, l.Range.EndRange)), + l.Range, + SynExprSequentialTrivia.Zero + ) - Some(trans CompExprTranslationPass.Initial q varSpace reduced translatedCtxt) + let mkOverallExprGivenVarSpaceExpr, varSpaceInner = + + let isNullableOp opId = + match ConvertValLogicalNameToDisplayNameCore opId with + | "?=" + | "=?" + | "?=?" -> true + | _ -> false + + match secondResultPatOpt, keySelectorsOpt with + // groupJoin + | Some secondResultPat, Some relExpr when customOperationIsLikeGroupJoin ceenv nm -> + let secondResultSimplePats, later3 = + SimplePatsOfPat cenv.synArgNameGenerator secondResultPat + + if Option.isSome later3 then + errorR (Error(FSComp.SR.tcJoinMustUseSimplePattern (nm.idText), secondResultPat.Range)) + + match relExpr with + | JoinRelation ceenv (keySelector1, keySelector2) -> + mkJoinExpr keySelector1 keySelector2 secondResultSimplePats, varSpaceWithGroupJoinVars + | BinOpExpr(opId, l, r) -> + if isNullableOp opId.idText then + // When we cannot resolve NullableOps, recommend the relevant namespace to be added + errorR ( + Error( + FSComp.SR.cannotResolveNullableOperators (ConvertValLogicalNameToDisplayNameCore opId.idText), + relExpr.Range + ) + ) + else + errorR (Error(FSComp.SR.tcInvalidRelationInJoin (nm.idText), relExpr.Range)) - | SynExpr.While(spWhile, guardExpr, innerComp, _) -> - let mGuard = guardExpr.Range + let l = wrapInArbErrSequence l "_keySelector1" + let r = wrapInArbErrSequence r "_keySelector2" + // this is not correct JoinRelation but it is still binary operation + // we've already reported error now we can use operands of binary operation as join components + mkJoinExpr l r secondResultSimplePats, varSpaceWithGroupJoinVars + | _ -> + errorR (Error(FSComp.SR.tcInvalidRelationInJoin (nm.idText), relExpr.Range)) + // since the shape of relExpr doesn't match our expectations (JoinRelation) + // then we assume that this is l.h.s. of the join relation + // so typechecker will treat relExpr as body of outerKeySelector lambda parameter in GroupJoin method + mkJoinExpr relExpr (arbExpr ("_keySelector2", relExpr.Range)) secondResultSimplePats, + varSpaceWithGroupJoinVars + + | None, Some relExpr when customOperationIsLikeJoin ceenv nm -> + match relExpr with + | JoinRelation ceenv (keySelector1, keySelector2) -> + mkJoinExpr keySelector1 keySelector2 secondSourceSimplePats, varSpaceWithSecondVars + | BinOpExpr(opId, l, r) -> + if isNullableOp opId.idText then + // When we cannot resolve NullableOps, recommend the relevant namespace to be added + errorR ( + Error( + FSComp.SR.cannotResolveNullableOperators (ConvertValLogicalNameToDisplayNameCore opId.idText), + relExpr.Range + ) + ) + else + errorR (Error(FSComp.SR.tcInvalidRelationInJoin (nm.idText), relExpr.Range)) + // this is not correct JoinRelation but it is still binary operation + // we've already reported error now we can use operands of binary operation as join components + let l = wrapInArbErrSequence l "_keySelector1" + let r = wrapInArbErrSequence r "_keySelector2" + mkJoinExpr l r secondSourceSimplePats, varSpaceWithGroupJoinVars + | _ -> + errorR (Error(FSComp.SR.tcInvalidRelationInJoin (nm.idText), relExpr.Range)) + // since the shape of relExpr doesn't match our expectations (JoinRelation) + // then we assume that this is l.h.s. of the join relation + // so typechecker will treat relExpr as body of outerKeySelector lambda parameter in Join method + mkJoinExpr relExpr (arbExpr ("_keySelector2", relExpr.Range)) secondSourceSimplePats, + varSpaceWithGroupJoinVars - let mWhile = - match spWhile with - | DebugPointAtWhile.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.While) - | _ -> mGuard + | None, None when customOperationIsLikeZip ceenv nm -> mkZipExpr, varSpaceWithSecondVars - if isQuery then - error (Error(FSComp.SR.tcNoWhileInQuery (), mWhile)) + | _ -> + assert false + failwith "unreachable" + + // Case from C# spec: A query expression with a join clause with an into followed by something other than a select clause + // Case from C# spec: A query expression with a join clause without an into followed by something other than a select clause + let valsInner, _env = varSpaceInner.Force mOpCore + let varSpaceExpr = mkExprForVarSpace mOpCore valsInner + let varSpacePat = mkPatForVarSpace mOpCore valsInner + let joinExpr = mkOverallExprGivenVarSpaceExpr varSpaceExpr ceenv.builderValName + + let consumingExpr = + SynExpr.ForEach( + DebugPointAtFor.No, + DebugPointAtInOrTo.No, + SeqExprOnly false, + false, + varSpacePat, + joinExpr, + innerComp, + mOpCore + ) - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mWhile ad "While" builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("While"), mWhile)) + Some(TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpaceInner consumingExpr translatedCtxt) - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mWhile ad "Delay" builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Delay"), mWhile)) + | SynExpr.ForEach(spFor, spIn, SeqExprOnly _seqExprOnly, isFromSource, pat, sourceExpr, innerComp, _mEntireForEach) -> + let sourceExpr = + match RewriteRangeExpr sourceExpr with + | Some e -> e + | None -> sourceExpr - // 'while' is hit just before each time the guard is called - let guardExpr = - match spWhile with - | DebugPointAtWhile.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mWhile, false, guardExpr) - | DebugPointAtWhile.No -> guardExpr + let wrappedSourceExpr = + mkSourceExprConditional isFromSource sourceExpr ceenv.sourceMethInfo ceenv.builderValName - Some( - trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> - translatedCtxt ( - mkSynCall - "While" - mWhile - [ - mkSynDelay2 guardExpr - mkSynCall "Delay" mWhile [ mkSynDelay innerComp.Range holeFill ] builderValName - ] - builderValName - )) - ) + let mFor = + match spFor with + | DebugPointAtFor.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.For) + | DebugPointAtFor.No -> pat.Range - | SynExpr.WhileBang(spWhile, guardExpr, innerComp, mOrig) -> - let mGuard = guardExpr.Range - - let mWhile = - match spWhile with - | DebugPointAtWhile.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.While) - | _ -> mGuard - - let mGuard = mGuard.MakeSynthetic() - - // 'while!' is hit just before each time the guard is called - let guardExpr = - match spWhile with - | DebugPointAtWhile.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mWhile, false, guardExpr) - | DebugPointAtWhile.No -> guardExpr - - let rewrittenWhileExpr = - let idFirst = mkSynId mGuard (CompilerGeneratedName "first") - let patFirst = mkSynPatVar None idFirst - - let body = - let idCond = mkSynId mGuard (CompilerGeneratedName "cond") - let patCond = mkSynPatVar None idCond - - let condBinding = - mkSynBinding - (Xml.PreXmlDoc.Empty, patCond) - (None, - false, - true, - mGuard, - DebugPointAtBinding.NoneAtSticky, - None, - SynExpr.Ident idFirst, - mGuard, - [], - [], - None, - SynBindingTrivia.Zero) - - let setCondExpr = SynExpr.Set(SynExpr.Ident idCond, SynExpr.Ident idFirst, mGuard) - - let bindCondExpr = - SynExpr.LetOrUseBang( - DebugPointAtBinding.NoneAtSticky, - false, - true, - patFirst, - guardExpr, - [], - setCondExpr, - mGuard, - SynExprLetOrUseBangTrivia.Zero - ) + // For computation expressions, 'in' or 'to' is hit on each MoveNext. + // To support this a named debug point for the "in" keyword is available to inlined code. + match spIn with + | DebugPointAtInOrTo.Yes mIn -> + cenv.namedDebugPointsForInlinedCode[{ + Range = mFor + Name = "ForLoop.InOrToKeyword" + }] <- mIn + | _ -> () - let whileExpr = - SynExpr.While( - DebugPointAtWhile.No, - SynExpr.Ident idCond, - SynExpr.Sequential( - DebugPointAtSequential.SuppressBoth, - true, - innerComp, - bindCondExpr, - mWhile, - SynExprSequentialTrivia.Zero - ), - mOrig - ) + let mPat = pat.Range - SynExpr.LetOrUse(false, false, [ condBinding ], whileExpr, mGuard, SynExprLetOrUseTrivia.Zero) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mFor + ceenv.ad + "For" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("For"), mFor)) - SynExpr.LetOrUseBang( - DebugPointAtBinding.NoneAtSticky, - false, - true, - patFirst, - guardExpr, - [], - body, - mGuard, - SynExprLetOrUseBangTrivia.Zero - ) + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - tryTrans CompExprTranslationPass.Initial q varSpace rewrittenWhileExpr translatedCtxt + let _, _, vspecs, envinner, _ = + TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat None - | SynExpr.TryFinally(innerComp, unwindExpr, _mTryToLast, spTry, spFinally, trivia) -> + vspecs, envinner) - let mTry = - match spTry with - | DebugPointAtTry.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.Try) - | _ -> trivia.TryKeyword + Some( + TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace innerComp (fun innerCompR -> - let mFinally = - match spFinally with - | DebugPointAtFinally.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.Finally) - | _ -> trivia.FinallyKeyword + let forCall = + mkSynCall + "For" + mFor + [ + wrappedSourceExpr + SynExpr.MatchLambda( + false, + mPat, + [ + SynMatchClause(pat, None, innerCompR, mPat, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero) + ], + DebugPointAtBinding.NoneAtInvisible, + mFor + ) + ] + ceenv.builderValName - // Put down a debug point for the 'finally' - let unwindExpr2 = - match spFinally with - | DebugPointAtFinally.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mFinally, true, unwindExpr) - | DebugPointAtFinally.No -> unwindExpr + let forCall = + match spFor with + | DebugPointAtFor.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mFor, false, forCall) + | DebugPointAtFor.No -> forCall - if isQuery then - error (Error(FSComp.SR.tcNoTryFinallyInQuery (), mTry)) + translatedCtxt forCall) + ) - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "TryFinally" builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("TryFinally"), mTry)) + | SynExpr.For( + forDebugPoint = spFor + toDebugPoint = spTo + ident = id + identBody = start + direction = dir + toBody = finish + doBody = innerComp + range = m) -> + let mFor = + match spFor with + | DebugPointAtFor.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.For) + | _ -> m + + if ceenv.isQuery then + errorR (Error(FSComp.SR.tcNoIntegerForLoopInQuery (), mFor)) + + let reduced = + elimFastIntegerForLoop (spFor, spTo, id, start, dir, finish, innerComp, m) + + Some(TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace reduced translatedCtxt) + | SynExpr.While(spWhile, guardExpr, innerComp, _) -> + let mGuard = guardExpr.Range + + let mWhile = + match spWhile with + | DebugPointAtWhile.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.While) + | _ -> mGuard + + if ceenv.isQuery then + error (Error(FSComp.SR.tcNoWhileInQuery (), mWhile)) - if - isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "Delay" builderTy) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Delay"), mTry)) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mWhile + ceenv.ad + "While" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("While"), mWhile)) - let innerExpr = transNoQueryOps innerComp + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mWhile + ceenv.ad + "Delay" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Delay"), mWhile)) - let innerExpr = - match spTry with - | DebugPointAtTry.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mTry, true, innerExpr) - | _ -> innerExpr + // 'while' is hit just before each time the guard is called + let guardExpr = + match spWhile with + | DebugPointAtWhile.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mWhile, false, guardExpr) + | DebugPointAtWhile.No -> guardExpr - Some( + Some( + TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> translatedCtxt ( mkSynCall - "TryFinally" - mTry + "While" + mWhile [ - mkSynCall "Delay" mTry [ mkSynDelay innerComp.Range innerExpr ] builderValName - mkSynDelay2 unwindExpr2 + mkSynDelay2 guardExpr + mkSynCall "Delay" mWhile [ mkSynDelay innerComp.Range holeFill ] ceenv.builderValName ] - builderValName - ) + ceenv.builderValName + )) + ) + + | SynExpr.WhileBang(spWhile, guardExpr, innerComp, mOrig) -> + let mGuard = guardExpr.Range + + let mWhile = + match spWhile with + | DebugPointAtWhile.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.While) + | _ -> mGuard + + let mGuard = mGuard.MakeSynthetic() + + // 'while!' is hit just before each time the guard is called + let guardExpr = + match spWhile with + | DebugPointAtWhile.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mWhile, false, guardExpr) + | DebugPointAtWhile.No -> guardExpr + + let rewrittenWhileExpr = + let idFirst = mkSynId mGuard (CompilerGeneratedName "first") + let patFirst = mkSynPatVar None idFirst + + let body = + let idCond = mkSynId mGuard (CompilerGeneratedName "cond") + let patCond = mkSynPatVar None idCond + + let condBinding = + mkSynBinding + (Xml.PreXmlDoc.Empty, patCond) + (None, + false, + true, + mGuard, + DebugPointAtBinding.NoneAtSticky, + None, + SynExpr.Ident idFirst, + mGuard, + [], + [], + None, + SynBindingTrivia.Zero) + + let setCondExpr = SynExpr.Set(SynExpr.Ident idCond, SynExpr.Ident idFirst, mGuard) + + let bindCondExpr = + SynExpr.LetOrUseBang( + DebugPointAtBinding.NoneAtSticky, + false, + true, + patFirst, + guardExpr, + [], + setCondExpr, + mGuard, + SynExprLetOrUseBangTrivia.Zero + ) + + let whileExpr = + SynExpr.While( + DebugPointAtWhile.No, + SynExpr.Ident idCond, + SynExpr.Sequential( + DebugPointAtSequential.SuppressBoth, + true, + innerComp, + bindCondExpr, + mWhile, + SynExprSequentialTrivia.Zero + ), + mOrig + ) + + SynExpr.LetOrUse(false, false, [ condBinding ], whileExpr, mGuard, SynExprLetOrUseTrivia.Zero) + + SynExpr.LetOrUseBang( + DebugPointAtBinding.NoneAtSticky, + false, + true, + patFirst, + guardExpr, + [], + body, + mGuard, + SynExprLetOrUseBangTrivia.Zero ) - | SynExpr.Paren(range = m) -> error (Error(FSComp.SR.tcConstructIsAmbiguousInComputationExpression (), m)) - - // In some cases the node produced by `mkSynCall "Zero" m []` may be discarded in the case - // of implicit yields - for example "list { 1; 2 }" when each expression checks as an implicit yield. - // If it is not discarded, the syntax node will later be checked and the existence/non-existence of the Zero method - // will be checked/reported appropriately (though the error message won't mention computation expressions - // like our other error messages for missing methods). - | SynExpr.ImplicitZero m -> - if - (not enableImplicitYield) - && isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Zero" builderTy) - then - match origComp with - // builder { } - // - // The compiler inserts a dummy () in CheckExpressions.fs for - // empty-bodied computation expressions. In this case, the user - // has not actually written any "control construct" in the body, - // and so we use a more specific error message for clarity. - | SynExpr.Const(SynConst.Unit, mUnit) when - g.langVersion.SupportsFeature LanguageFeature.EmptyBodiedComputationExpressions - && Range.equals mUnit range0 - -> - error (Error(FSComp.SR.tcEmptyBodyRequiresBuilderZeroMethod (), mWhole)) - | _ -> error (Error(FSComp.SR.tcRequireBuilderMethod ("Zero"), m)) - - Some(translatedCtxt (mkSynCall "Zero" m [] builderValName)) - - | OptionalSequential(JoinOrGroupJoinOrZipClause(_, _, _, _, _, mClause), _) when firstTry = CompExprTranslationPass.Initial -> - - // 'join' clauses preceded by 'let' and other constructs get processed by repackaging with a 'for' loop. - let patvs, _env = varSpace.Force comp.Range - let varSpaceExpr = mkExprForVarSpace mClause patvs - let varSpacePat = mkPatForVarSpace mClause patvs + TryTranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace rewrittenWhileExpr translatedCtxt - let dataCompPrior = - translatedCtxt (transNoQueryOps (SynExpr.YieldOrReturn((true, false), varSpaceExpr, mClause))) + | SynExpr.TryFinally(innerComp, unwindExpr, _mTryToLast, spTry, spFinally, trivia) -> - // Rebind using for ... - let rebind = - SynExpr.ForEach( - DebugPointAtFor.No, - DebugPointAtInOrTo.No, - SeqExprOnly false, - false, - varSpacePat, - dataCompPrior, - comp, - comp.Range - ) + let mTry = + match spTry with + | DebugPointAtTry.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.Try) + | _ -> trivia.TryKeyword - // Retry with the 'for' loop packaging. Set firstTry=false just in case 'join' processing fails - tryTrans CompExprTranslationPass.Subsequent q varSpace rebind id + let mFinally = + match spFinally with + | DebugPointAtFinally.Yes m -> m.NoteSourceConstruct(NotedSourceConstruct.Finally) + | _ -> trivia.FinallyKeyword - | OptionalSequential(CustomOperationClause(nm, _, opExpr, mClause, _), _) -> + // Put down a debug point for the 'finally' + let unwindExpr2 = + match spFinally with + | DebugPointAtFinally.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mFinally, true, unwindExpr) + | DebugPointAtFinally.No -> unwindExpr - match q with - | CustomOperationsMode.Denied -> error (Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere (), opExpr.Range)) - | CustomOperationsMode.Allowed -> - let patvs, _env = varSpace.Force comp.Range - let varSpaceExpr = mkExprForVarSpace mClause patvs + if ceenv.isQuery then + error (Error(FSComp.SR.tcNoTryFinallyInQuery (), mTry)) - let dataCompPriorToOp = - let isYield = not (customOperationMaintainsVarSpaceUsingBind nm) - translatedCtxt (transNoQueryOps (SynExpr.YieldOrReturn((isYield, false), varSpaceExpr, mClause))) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mTry + ceenv.ad + "TryFinally" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("TryFinally"), mTry)) - // Now run the consumeCustomOpClauses - Some(consumeCustomOpClauses q varSpace dataCompPriorToOp comp false mClause) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mTry + ceenv.ad + "Delay" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Delay"), mTry)) - | SynExpr.Sequential(sp, true, innerComp1, innerComp2, m, _) -> + let innerExpr = TranslateComputationExpressionNoQueryOps ceenv innerComp - // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore innerComp1 - if isQuery && checkForBinaryApp innerComp1 then - Some(trans CompExprTranslationPass.Initial q varSpace innerComp2 translatedCtxt) + let innerExpr = + match spTry with + | DebugPointAtTry.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mTry, true, innerExpr) + | _ -> innerExpr - else + Some( + translatedCtxt ( + mkSynCall + "TryFinally" + mTry + [ + mkSynCall "Delay" mTry [ mkSynDelay innerComp.Range innerExpr ] ceenv.builderValName + mkSynDelay2 unwindExpr2 + ] + ceenv.builderValName + ) + ) - if isQuery && not (innerComp1.IsArbExprAndThusAlreadyReportedError) then - match innerComp1 with - | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential - | _ -> errorR (Error(FSComp.SR.tcUnrecognizedQueryOperator (), innerComp1.RangeOfFirstPortion)) - - match tryTrans CompExprTranslationPass.Initial CustomOperationsMode.Denied varSpace innerComp1 id with - | Some c -> - // "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1) - let m1 = rangeForCombine innerComp1 - - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo - ResultCollectionSettings.AtMostOneResult - cenv - env - m - ad - "Combine" - builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Combine"), m)) + | SynExpr.Paren(range = m) -> error (Error(FSComp.SR.tcConstructIsAmbiguousInComputationExpression (), m)) - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Delay" builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Delay"), m)) + // In some cases the node produced by `mkSynCall "Zero" m []` may be discarded in the case + // of implicit yields - for example "list { 1; 2 }" when each expression checks as an implicit yield. + // If it is not discarded, the syntax node will later be checked and the existence/non-existence of the Zero method + // will be checked/reported appropriately (though the error message won't mention computation expressions + // like our other error messages for missing methods). + | SynExpr.ImplicitZero m -> + if + (not ceenv.enableImplicitYield) + && isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + m + ceenv.ad + "Zero" + ceenv.builderTy + ) + then + match ceenv.origComp with + // builder { } + // + // The compiler inserts a dummy () in CheckExpressions.fs for + // empty-bodied computation expressions. In this case, the user + // has not actually written any "control construct" in the body, + // and so we use a more specific error message for clarity. + | SynExpr.Const(SynConst.Unit, mUnit) when + cenv.g.langVersion.SupportsFeature LanguageFeature.EmptyBodiedComputationExpressions + && Range.equals mUnit range0 + -> + error (Error(FSComp.SR.tcEmptyBodyRequiresBuilderZeroMethod (), ceenv.mWhole)) + | _ -> error (Error(FSComp.SR.tcRequireBuilderMethod ("Zero"), m)) + + Some(translatedCtxt (mkSynCall "Zero" m [] ceenv.builderValName)) + + | OptionalSequential(JoinOrGroupJoinOrZipClause ceenv (_, _, _, _, _, mClause), _) when firstTry = CompExprTranslationPass.Initial -> + + // 'join' clauses preceded by 'let' and other constructs get processed by repackaging with a 'for' loop. + let patvs, _env = varSpace.Force comp.Range + let varSpaceExpr = mkExprForVarSpace mClause patvs + let varSpacePat = mkPatForVarSpace mClause patvs - let combineCall = - mkSynCall - "Combine" - m1 - [ - c - mkSynCall "Delay" m1 [ mkSynDelay innerComp2.Range (transNoQueryOps innerComp2) ] builderValName - ] - builderValName - - Some(translatedCtxt combineCall) - - | None -> - // "do! expr; cexpr" is treated as { let! () = expr in cexpr } - match innerComp1 with - | SynExpr.DoBang(rhsExpr, m) -> - let sp = - match sp with - | DebugPointAtSequential.SuppressExpr -> DebugPointAtBinding.NoneAtDo - | DebugPointAtSequential.SuppressBoth -> DebugPointAtBinding.NoneAtDo - | DebugPointAtSequential.SuppressStmt -> DebugPointAtBinding.Yes m - | DebugPointAtSequential.SuppressNeither -> DebugPointAtBinding.Yes m - - Some( - trans - CompExprTranslationPass.Initial - q - varSpace - (SynExpr.LetOrUseBang( - sp, - false, - true, - SynPat.Const(SynConst.Unit, rhsExpr.Range), - rhsExpr, - [], - innerComp2, - m, - SynExprLetOrUseBangTrivia.Zero - )) - translatedCtxt - ) + let dataCompPrior = + translatedCtxt ( + TranslateComputationExpressionNoQueryOps ceenv (SynExpr.YieldOrReturn((true, false), varSpaceExpr, mClause)) + ) - // "expr; cexpr" is treated as sequential execution - | _ -> - Some( - trans CompExprTranslationPass.Initial q varSpace innerComp2 (fun holeFill -> - let fillExpr = - if enableImplicitYield then - // When implicit yields are enabled, then if the 'innerComp1' checks as type - // 'unit' we interpret the expression as a sequential, and when it doesn't - // have type 'unit' we interpret it as a 'Yield + Combine'. - let combineExpr = - let m1 = rangeForCombine innerComp1 - let implicitYieldExpr = mkSynCall "Yield" comp.Range [ innerComp1 ] builderValName - - mkSynCall - "Combine" - m1 - [ - implicitYieldExpr - mkSynCall "Delay" m1 [ mkSynDelay holeFill.Range holeFill ] builderValName - ] - builderValName - - SynExpr.SequentialOrImplicitYield(sp, innerComp1, holeFill, combineExpr, m) - else - SynExpr.Sequential(sp, true, innerComp1, holeFill, m, SynExprSequentialTrivia.Zero) - - translatedCtxt fillExpr) - ) + // Rebind using for ... + let rebind = + SynExpr.ForEach( + DebugPointAtFor.No, + DebugPointAtInOrTo.No, + SeqExprOnly false, + false, + varSpacePat, + dataCompPrior, + comp, + comp.Range + ) - | SynExpr.IfThenElse(guardExpr, thenComp, elseCompOpt, spIfToThen, isRecovery, mIfToEndOfElseBranch, trivia) -> - match elseCompOpt with - | Some elseComp -> - if isQuery then - error (Error(FSComp.SR.tcIfThenElseMayNotBeUsedWithinQueries (), trivia.IfToThenRange)) + // Retry with the 'for' loop packaging. Set firstTry=false just in case 'join' processing fails + TryTranslateComputationExpression ceenv CompExprTranslationPass.Subsequent q varSpace rebind id - Some( - translatedCtxt ( - SynExpr.IfThenElse( - guardExpr, - transNoQueryOps thenComp, - Some(transNoQueryOps elseComp), - spIfToThen, - isRecovery, - mIfToEndOfElseBranch, - trivia - ) - ) - ) - | None -> - let elseComp = - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo - ResultCollectionSettings.AtMostOneResult - cenv - env - trivia.IfToThenRange - ad - "Zero" - builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Zero"), trivia.IfToThenRange)) + | OptionalSequential(CustomOperationClause ceenv (nm, _, opExpr, mClause, _), _) -> + + match q with + | CustomOperationsMode.Denied -> error (Error(FSComp.SR.tcCustomOperationMayNotBeUsedHere (), opExpr.Range)) + | CustomOperationsMode.Allowed -> + let patvs, _env = varSpace.Force comp.Range + let varSpaceExpr = mkExprForVarSpace mClause patvs - mkSynCall "Zero" trivia.IfToThenRange [] builderValName + let dataCompPriorToOp = + let isYield = not (customOperationMaintainsVarSpaceUsingBind ceenv nm) - Some( - trans CompExprTranslationPass.Initial q varSpace thenComp (fun holeFill -> - translatedCtxt ( - SynExpr.IfThenElse( - guardExpr, - holeFill, - Some elseComp, - spIfToThen, - isRecovery, - mIfToEndOfElseBranch, - trivia - ) - )) + translatedCtxt ( + TranslateComputationExpressionNoQueryOps ceenv (SynExpr.YieldOrReturn((isYield, false), varSpaceExpr, mClause)) ) - // 'let binds in expr' - | SynExpr.LetOrUse(isRec, false, binds, innerComp, m, trivia) -> + // Now run the consumeCustomOpClauses + Some(ConsumeCustomOpClauses ceenv comp q varSpace dataCompPriorToOp comp false mClause) - // For 'query' check immediately - if isQuery then - match (List.map (BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env) binds) with - | [ NormalizedBinding(_, SynBindingKind.Normal, false, false, _, _, _, _, _, _, _, _) ] when not isRec -> () - | normalizedBindings -> - let failAt m = - error (Error(FSComp.SR.tcNonSimpleLetBindingInQuery (), m)) + | SynExpr.Sequential(sp, true, innerComp1, innerComp2, m, _) -> - match normalizedBindings with - | NormalizedBinding(mBinding = mBinding) :: _ -> failAt mBinding - | _ -> failAt m + // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore innerComp1 + if ceenv.isQuery && checkForBinaryApp ceenv innerComp1 then + Some(TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace innerComp2 translatedCtxt) - // Add the variables to the query variable space, on demand - let varSpace = - addVarsToVarSpace varSpace (fun mQueryOp env -> - // Normalize the bindings before detecting the bound variables - match (List.map (BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env) binds) with - | [ NormalizedBinding(kind = SynBindingKind.Normal; shouldInline = false; isMutable = false; pat = pat) ] -> - // successful case - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + else - let _, _, vspecs, envinner, _ = - TcMatchPattern cenv (NewInferenceType g) env tpenv pat None + if ceenv.isQuery && not (innerComp1.IsArbExprAndThusAlreadyReportedError) then + match innerComp1 with + | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential + | _ -> errorR (Error(FSComp.SR.tcUnrecognizedQueryOperator (), innerComp1.RangeOfFirstPortion)) + + match + TryTranslateComputationExpression + ceenv + CompExprTranslationPass.Initial + CustomOperationsMode.Denied + varSpace + innerComp1 + id + with + | Some c -> + // "cexpr; cexpr" is treated as builder.Combine(cexpr1, cexpr1) + let m1 = rangeForCombine innerComp1 + + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + m + ceenv.ad + "Combine" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Combine"), m)) - vspecs, envinner - | _ -> - // error case - error (Error(FSComp.SR.tcCustomOperationMayNotBeUsedInConjunctionWithNonSimpleLetBindings (), mQueryOp))) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + m + ceenv.ad + "Delay" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Delay"), m)) - Some( - trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> - translatedCtxt (SynExpr.LetOrUse(isRec, false, binds, holeFill, m, trivia))) - ) + let combineCall = + mkSynCall + "Combine" + m1 + [ + c + mkSynCall + "Delay" + m1 + [ + mkSynDelay innerComp2.Range (TranslateComputationExpressionNoQueryOps ceenv innerComp2) + ] + ceenv.builderValName + ] + ceenv.builderValName - // 'use x = expr in expr' - | SynExpr.LetOrUse( - isUse = true - bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr; debugPoint = spBind) ] - body = innerComp) -> - let mBind = - match spBind with - | DebugPointAtBinding.Yes m -> m - | _ -> rhsExpr.Range + Some(translatedCtxt combineCall) - if isQuery then - error (Error(FSComp.SR.tcUseMayNotBeUsedInQueries (), mBind)) + | None -> + // "do! expr; cexpr" is treated as { let! () = expr in cexpr } + match innerComp1 with + | SynExpr.DoBang(rhsExpr, m) -> + let sp = + match sp with + | DebugPointAtSequential.SuppressExpr -> DebugPointAtBinding.NoneAtDo + | DebugPointAtSequential.SuppressBoth -> DebugPointAtBinding.NoneAtDo + | DebugPointAtSequential.SuppressStmt -> DebugPointAtBinding.Yes m + | DebugPointAtSequential.SuppressNeither -> DebugPointAtBinding.Yes m - let innerCompRange = innerComp.Range + Some( + TranslateComputationExpression + ceenv + CompExprTranslationPass.Initial + q + varSpace + (SynExpr.LetOrUseBang( + sp, + false, + true, + SynPat.Const(SynConst.Unit, rhsExpr.Range), + rhsExpr, + [], + innerComp2, + m, + SynExprLetOrUseBangTrivia.Zero + )) + translatedCtxt + ) - let consumeExpr = - SynExpr.MatchLambda( + // "expr; cexpr" is treated as sequential execution + | _ -> + Some( + TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace innerComp2 (fun holeFill -> + let fillExpr = + if ceenv.enableImplicitYield then + // When implicit yields are enabled, then if the 'innerComp1' checks as type + // 'unit' we interpret the expression as a sequential, and when it doesn't + // have type 'unit' we interpret it as a 'Yield + Combine'. + let combineExpr = + let m1 = rangeForCombine innerComp1 + + let implicitYieldExpr = + mkSynCall "Yield" comp.Range [ innerComp1 ] ceenv.builderValName + + mkSynCall + "Combine" + m1 + [ + implicitYieldExpr + mkSynCall "Delay" m1 [ mkSynDelay holeFill.Range holeFill ] ceenv.builderValName + ] + ceenv.builderValName + + SynExpr.SequentialOrImplicitYield(sp, innerComp1, holeFill, combineExpr, m) + else + SynExpr.Sequential(sp, true, innerComp1, holeFill, m, SynExprSequentialTrivia.Zero) + + translatedCtxt fillExpr) + ) + + | SynExpr.IfThenElse(guardExpr, thenComp, elseCompOpt, spIfToThen, isRecovery, mIfToEndOfElseBranch, trivia) -> + match elseCompOpt with + | Some elseComp -> + if ceenv.isQuery then + error (Error(FSComp.SR.tcIfThenElseMayNotBeUsedWithinQueries (), trivia.IfToThenRange)) + + Some( + translatedCtxt ( + SynExpr.IfThenElse( + guardExpr, + TranslateComputationExpressionNoQueryOps ceenv thenComp, + Some(TranslateComputationExpressionNoQueryOps ceenv elseComp), + spIfToThen, + isRecovery, + mIfToEndOfElseBranch, + trivia + ) + ) + ) + | None -> + let elseComp = + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + trivia.IfToThenRange + ceenv.ad + "Zero" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Zero"), trivia.IfToThenRange)) + + mkSynCall "Zero" trivia.IfToThenRange [] ceenv.builderValName + + Some( + TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace thenComp (fun holeFill -> + translatedCtxt ( + SynExpr.IfThenElse(guardExpr, holeFill, Some elseComp, spIfToThen, isRecovery, mIfToEndOfElseBranch, trivia) + )) + ) + + // 'let binds in expr' + | SynExpr.LetOrUse(isRec, false, binds, innerComp, m, trivia) -> + + // For 'query' check immediately + if ceenv.isQuery then + match (List.map (BindingNormalization.NormalizeBinding ValOrMemberBinding cenv ceenv.env) binds) with + | [ NormalizedBinding(_, SynBindingKind.Normal, false, false, _, _, _, _, _, _, _, _) ] when not isRec -> () + | normalizedBindings -> + let failAt m = + error (Error(FSComp.SR.tcNonSimpleLetBindingInQuery (), m)) + + match normalizedBindings with + | NormalizedBinding(mBinding = mBinding) :: _ -> failAt mBinding + | _ -> failAt m + + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun mQueryOp env -> + // Normalize the bindings before detecting the bound variables + match (List.map (BindingNormalization.NormalizeBinding ValOrMemberBinding cenv env) binds) with + | [ NormalizedBinding(kind = SynBindingKind.Normal; shouldInline = false; isMutable = false; pat = pat) ] -> + // successful case + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + + let _, _, vspecs, envinner, _ = + TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat None + + vspecs, envinner + | _ -> + // error case + error (Error(FSComp.SR.tcCustomOperationMayNotBeUsedInConjunctionWithNonSimpleLetBindings (), mQueryOp))) + + Some( + TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> + translatedCtxt (SynExpr.LetOrUse(isRec, false, binds, holeFill, m, trivia))) + ) + + // 'use x = expr in expr' + | SynExpr.LetOrUse( + isUse = true + bindings = [ SynBinding(kind = SynBindingKind.Normal; headPat = pat; expr = rhsExpr; debugPoint = spBind) ] + body = innerComp) -> + let mBind = + match spBind with + | DebugPointAtBinding.Yes m -> m + | _ -> rhsExpr.Range + + if ceenv.isQuery then + error (Error(FSComp.SR.tcUseMayNotBeUsedInQueries (), mBind)) + + let innerCompRange = innerComp.Range + + let consumeExpr = + SynExpr.MatchLambda( + false, + innerCompRange, + [ + SynMatchClause( + pat, + None, + TranslateComputationExpressionNoQueryOps ceenv innerComp, + innerCompRange, + DebugPointAtTarget.Yes, + SynMatchClauseTrivia.Zero + ) + ], + DebugPointAtBinding.NoneAtInvisible, + innerCompRange + ) + + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mBind + ceenv.ad + "Using" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Using"), mBind)) + + Some( + translatedCtxt (mkSynCall "Using" mBind [ rhsExpr; consumeExpr ] ceenv.builderValName) + |> addBindDebugPoint spBind + ) + + // 'let! pat = expr in expr' + // --> build.Bind(e1, (fun _argN -> match _argN with pat -> expr)) + // or + // --> build.BindReturn(e1, (fun _argN -> match _argN with pat -> expr-without-return)) + | SynExpr.LetOrUseBang( + bindDebugPoint = spBind; isUse = false; isFromSource = isFromSource; pat = pat; rhs = rhsExpr; andBangs = []; body = innerComp) -> + + let mBind = + match spBind with + | DebugPointAtBinding.Yes m -> m + | _ -> rhsExpr.Range + + if ceenv.isQuery then + error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), mBind)) + + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + + let _, _, vspecs, envinner, _ = + TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat None + + vspecs, envinner) + + let rhsExpr = + mkSourceExprConditional isFromSource rhsExpr ceenv.sourceMethInfo ceenv.builderValName + + Some( + TranslateComputationExpressionBind + ceenv + comp + q + varSpace + mBind + (addBindDebugPoint spBind) + "Bind" + [ rhsExpr ] + pat + innerComp + translatedCtxt + ) + + // 'use! pat = e1 in e2' --> build.Bind(e1, (function _argN -> match _argN with pat -> build.Using(x, (fun _argN -> match _argN with pat -> e2)))) + | SynExpr.LetOrUseBang( + bindDebugPoint = spBind + isUse = true + isFromSource = isFromSource + pat = SynPat.Named(ident = SynIdent(id, _); isThisVal = false) as pat + rhs = rhsExpr + andBangs = [] + body = innerComp) + | SynExpr.LetOrUseBang( + bindDebugPoint = spBind + isUse = true + isFromSource = isFromSource + pat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ id ])) as pat + rhs = rhsExpr + andBangs = [] + body = innerComp) -> + + let mBind = + match spBind with + | DebugPointAtBinding.Yes m -> m + | _ -> rhsExpr.Range + + if ceenv.isQuery then + error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), mBind)) + + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mBind + ceenv.ad + "Using" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Using"), mBind)) + + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mBind + ceenv.ad + "Bind" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Bind"), mBind)) + + let bindExpr = + let consumeExpr = + SynExpr.MatchLambda( false, - innerCompRange, + mBind, [ SynMatchClause( pat, None, - transNoQueryOps innerComp, - innerCompRange, + TranslateComputationExpressionNoQueryOps ceenv innerComp, + innerComp.Range, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero ) ], DebugPointAtBinding.NoneAtInvisible, - innerCompRange + mBind ) - if - isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBind ad "Using" builderTy) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Using"), mBind)) + let consumeExpr = + mkSynCall "Using" mBind [ SynExpr.Ident id; consumeExpr ] ceenv.builderValName - Some( - translatedCtxt (mkSynCall "Using" mBind [ rhsExpr; consumeExpr ] builderValName) - |> addBindDebugPoint spBind + let consumeExpr = + SynExpr.MatchLambda( + false, + mBind, + [ + SynMatchClause(pat, None, consumeExpr, id.idRange, DebugPointAtTarget.No, SynMatchClauseTrivia.Zero) + ], + DebugPointAtBinding.NoneAtInvisible, + mBind + ) + + let rhsExpr = + mkSourceExprConditional isFromSource rhsExpr ceenv.sourceMethInfo ceenv.builderValName + + mkSynCall "Bind" mBind [ rhsExpr; consumeExpr ] ceenv.builderValName + |> addBindDebugPoint spBind + + Some(translatedCtxt bindExpr) + + // 'use! pat = e1 ... in e2' where 'pat' is not a simple name --> error + | SynExpr.LetOrUseBang(isUse = true; pat = pat; andBangs = andBangs) -> + if isNil andBangs then + error (Error(FSComp.SR.tcInvalidUseBangBinding (), pat.Range)) + else + error (Error(FSComp.SR.tcInvalidUseBangBindingNoAndBangs (), comp.Range)) + + // 'let! pat1 = expr1 and! pat2 = expr2 in ...' --> + // build.BindN(expr1, expr2, ...) + // or + // build.BindNReturn(expr1, expr2, ...) + // or + // build.Bind(build.MergeSources(expr1, expr2), ...) + | SynExpr.LetOrUseBang( + bindDebugPoint = spBind + isUse = false + isFromSource = isFromSource + pat = letPat + rhs = letRhsExpr + andBangs = andBangBindings + body = innerComp + range = letBindRange) -> + if not (cenv.g.langVersion.SupportsFeature LanguageFeature.AndBang) then + error (Error(FSComp.SR.tcAndBangNotSupported (), comp.Range)) + + if ceenv.isQuery then + error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), letBindRange)) + + let mBind = + match spBind with + | DebugPointAtBinding.Yes m -> m + | _ -> letRhsExpr.Range + + let sources = + (letRhsExpr + :: [ for SynExprAndBang(body = andExpr) in andBangBindings -> andExpr ]) + |> List.map (fun expr -> mkSourceExprConditional isFromSource expr ceenv.sourceMethInfo ceenv.builderValName) + + let pats = + letPat :: [ for SynExprAndBang(pat = andPat) in andBangBindings -> andPat ] + + let sourcesRange = sources |> List.map (fun e -> e.Range) |> List.reduce unionRanges + + let numSources = sources.Length + let bindReturnNName = "Bind" + string numSources + "Return" + let bindNName = "Bind" + string numSources + + // Check if this is a Bind2Return etc. + let hasBindReturnN = + not ( + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mBind + ceenv.ad + bindReturnNName + ceenv.builderTy + ) ) - // 'let! pat = expr in expr' - // --> build.Bind(e1, (fun _argN -> match _argN with pat -> expr)) - // or - // --> build.BindReturn(e1, (fun _argN -> match _argN with pat -> expr-without-return)) - | SynExpr.LetOrUseBang( - bindDebugPoint = spBind - isUse = false - isFromSource = isFromSource - pat = pat - rhs = rhsExpr - andBangs = [] - body = innerComp) -> - - let mBind = - match spBind with - | DebugPointAtBinding.Yes m -> m - | _ -> rhsExpr.Range - - if isQuery then - error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), mBind)) + if + hasBindReturnN + && Option.isSome (convertSimpleReturnToExpr ceenv comp varSpace innerComp) + then + let consumePat = SynPat.Tuple(false, pats, [], letPat.Range) // Add the variables to the query variable space, on demand let varSpace = @@ -1849,155 +2061,43 @@ let TcComputationExpression (cenv: TcFileState) env (overallTy: OverallTy) tpenv use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink let _, _, vspecs, envinner, _ = - TcMatchPattern cenv (NewInferenceType g) env tpenv pat None + TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv consumePat None vspecs, envinner) - let rhsExpr = - mkSourceExprConditional isFromSource rhsExpr sourceMethInfo builderValName - - Some(transBind q varSpace mBind (addBindDebugPoint spBind) "Bind" [ rhsExpr ] pat innerComp translatedCtxt) - - // 'use! pat = e1 in e2' --> build.Bind(e1, (function _argN -> match _argN with pat -> build.Using(x, (fun _argN -> match _argN with pat -> e2)))) - | SynExpr.LetOrUseBang( - bindDebugPoint = spBind - isUse = true - isFromSource = isFromSource - pat = SynPat.Named(ident = SynIdent(id, _); isThisVal = false) as pat - rhs = rhsExpr - andBangs = [] - body = innerComp) - | SynExpr.LetOrUseBang( - bindDebugPoint = spBind - isUse = true - isFromSource = isFromSource - pat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ id ])) as pat - rhs = rhsExpr - andBangs = [] - body = innerComp) -> - - let mBind = - match spBind with - | DebugPointAtBinding.Yes m -> m - | _ -> rhsExpr.Range - - if isQuery then - error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), mBind)) - - if - isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBind ad "Using" builderTy) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Using"), mBind)) - - if - isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBind ad "Bind" builderTy) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Bind"), mBind)) - - let bindExpr = - let consumeExpr = - SynExpr.MatchLambda( - false, - mBind, - [ - SynMatchClause( - pat, - None, - transNoQueryOps innerComp, - innerComp.Range, - DebugPointAtTarget.Yes, - SynMatchClauseTrivia.Zero - ) - ], - DebugPointAtBinding.NoneAtInvisible, - mBind - ) - - let consumeExpr = - mkSynCall "Using" mBind [ SynExpr.Ident id; consumeExpr ] builderValName - - let consumeExpr = - SynExpr.MatchLambda( - false, - mBind, - [ - SynMatchClause(pat, None, consumeExpr, id.idRange, DebugPointAtTarget.No, SynMatchClauseTrivia.Zero) - ], - DebugPointAtBinding.NoneAtInvisible, - mBind - ) - - let rhsExpr = - mkSourceExprConditional isFromSource rhsExpr sourceMethInfo builderValName - - mkSynCall "Bind" mBind [ rhsExpr; consumeExpr ] builderValName - |> addBindDebugPoint spBind + Some( + TranslateComputationExpressionBind + ceenv + comp + q + varSpace + mBind + (addBindDebugPoint spBind) + bindNName + sources + consumePat + innerComp + translatedCtxt + ) - Some(translatedCtxt bindExpr) + else - // 'use! pat = e1 ... in e2' where 'pat' is not a simple name --> error - | SynExpr.LetOrUseBang(isUse = true; pat = pat; andBangs = andBangs) -> - if isNil andBangs then - error (Error(FSComp.SR.tcInvalidUseBangBinding (), pat.Range)) - else - error (Error(FSComp.SR.tcInvalidUseBangBindingNoAndBangs (), comp.Range)) - - // 'let! pat1 = expr1 and! pat2 = expr2 in ...' --> - // build.BindN(expr1, expr2, ...) - // or - // build.BindNReturn(expr1, expr2, ...) - // or - // build.Bind(build.MergeSources(expr1, expr2), ...) - | SynExpr.LetOrUseBang( - bindDebugPoint = spBind - isUse = false - isFromSource = isFromSource - pat = letPat - rhs = letRhsExpr - andBangs = andBangBindings - body = innerComp - range = letBindRange) -> - if not (cenv.g.langVersion.SupportsFeature LanguageFeature.AndBang) then - error (Error(FSComp.SR.tcAndBangNotSupported (), comp.Range)) - - if isQuery then - error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), letBindRange)) - - let mBind = - match spBind with - | DebugPointAtBinding.Yes m -> m - | _ -> letRhsExpr.Range - - let sources = - (letRhsExpr - :: [ for SynExprAndBang(body = andExpr) in andBangBindings -> andExpr ]) - |> List.map (fun expr -> mkSourceExprConditional isFromSource expr sourceMethInfo builderValName) - - let pats = - letPat :: [ for SynExprAndBang(pat = andPat) in andBangBindings -> andPat ] - - let sourcesRange = sources |> List.map (fun e -> e.Range) |> List.reduce unionRanges - - let numSources = sources.Length - let bindReturnNName = "Bind" + string numSources + "Return" - let bindNName = "Bind" + string numSources - - // Check if this is a Bind2Return etc. - let hasBindReturnN = + // Check if this is a Bind2 etc. + let hasBindN = not ( isNil ( TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv - env + ceenv.env mBind - ad - bindReturnNName - builderTy + ceenv.ad + bindNName + ceenv.builderTy ) ) - if hasBindReturnN && Option.isSome (convertSimpleReturnToExpr varSpace innerComp) then + if hasBindN then let consumePat = SynPat.Tuple(false, pats, [], letPat.Range) // Add the variables to the query variable space, on demand @@ -2006,581 +2106,842 @@ let TcComputationExpression (cenv: TcFileState) env (overallTy: OverallTy) tpenv use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink let _, _, vspecs, envinner, _ = - TcMatchPattern cenv (NewInferenceType g) env tpenv consumePat None + TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv consumePat None vspecs, envinner) - Some(transBind q varSpace mBind (addBindDebugPoint spBind) bindNName sources consumePat innerComp translatedCtxt) - + Some( + TranslateComputationExpressionBind + ceenv + comp + q + varSpace + mBind + (addBindDebugPoint spBind) + bindNName + sources + consumePat + innerComp + translatedCtxt + ) else - // Check if this is a Bind2 etc. - let hasBindN = - not ( - isNil ( - TryFindIntrinsicOrExtensionMethInfo - ResultCollectionSettings.AtMostOneResult - cenv - env - mBind - ad - bindNName - builderTy - ) - ) + // Look for the maximum supported MergeSources, MergeSources3, ... + let mkMergeSourcesName n = + if n = 2 then + "MergeSources" + else + "MergeSources" + (string n) + + let maxMergeSources = + let rec loop (n: int) = + let mergeSourcesName = mkMergeSourcesName n + + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mBind + ceenv.ad + mergeSourcesName + ceenv.builderTy + ) + then + (n - 1) + else + loop (n + 1) - if hasBindN then - let consumePat = SynPat.Tuple(false, pats, [], letPat.Range) + loop 2 - // Add the variables to the query variable space, on demand - let varSpace = - addVarsToVarSpace varSpace (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + if maxMergeSources = 1 then + error (Error(FSComp.SR.tcRequireMergeSourcesOrBindN (bindNName), mBind)) - let _, _, vspecs, envinner, _ = - TcMatchPattern cenv (NewInferenceType g) env tpenv consumePat None + let rec mergeSources (sourcesAndPats: (SynExpr * SynPat) list) = + let numSourcesAndPats = sourcesAndPats.Length + assert (numSourcesAndPats <> 0) - vspecs, envinner) + if numSourcesAndPats = 1 then + sourcesAndPats[0] - Some(transBind q varSpace mBind (addBindDebugPoint spBind) bindNName sources consumePat innerComp translatedCtxt) - else + elif numSourcesAndPats <= maxMergeSources then - // Look for the maximum supported MergeSources, MergeSources3, ... - let mkMergeSourcesName n = - if n = 2 then - "MergeSources" - else - "MergeSources" + (string n) - - let maxMergeSources = - let rec loop (n: int) = - let mergeSourcesName = mkMergeSourcesName n - - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo - ResultCollectionSettings.AtMostOneResult - cenv - env - mBind - ad - mergeSourcesName - builderTy - ) - then - (n - 1) - else - loop (n + 1) + // Call MergeSources2(e1, e2), MergeSources3(e1, e2, e3) etc + let mergeSourcesName = mkMergeSourcesName numSourcesAndPats - loop 2 + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mBind + ceenv.ad + mergeSourcesName + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireMergeSourcesOrBindN (bindNName), mBind)) - if maxMergeSources = 1 then - error (Error(FSComp.SR.tcRequireMergeSourcesOrBindN (bindNName), mBind)) + let source = + mkSynCall mergeSourcesName sourcesRange (List.map fst sourcesAndPats) ceenv.builderValName - let rec mergeSources (sourcesAndPats: (SynExpr * SynPat) list) = - let numSourcesAndPats = sourcesAndPats.Length - assert (numSourcesAndPats <> 0) + let pat = SynPat.Tuple(false, List.map snd sourcesAndPats, [], letPat.Range) + source, pat - if numSourcesAndPats = 1 then - sourcesAndPats[0] + else - elif numSourcesAndPats <= maxMergeSources then + // Call MergeSourcesMax(e1, e2, e3, e4, (...)) + let nowSourcesAndPats, laterSourcesAndPats = + List.splitAt (maxMergeSources - 1) sourcesAndPats - // Call MergeSources2(e1, e2), MergeSources3(e1, e2, e3) etc - let mergeSourcesName = mkMergeSourcesName numSourcesAndPats + let mergeSourcesName = mkMergeSourcesName maxMergeSources - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo - ResultCollectionSettings.AtMostOneResult - cenv - env - mBind - ad - mergeSourcesName - builderTy - ) - then - error (Error(FSComp.SR.tcRequireMergeSourcesOrBindN (bindNName), mBind)) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mBind + ceenv.ad + mergeSourcesName + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireMergeSourcesOrBindN (bindNName), mBind)) - let source = - mkSynCall mergeSourcesName sourcesRange (List.map fst sourcesAndPats) builderValName + let laterSource, laterPat = mergeSources laterSourcesAndPats - let pat = SynPat.Tuple(false, List.map snd sourcesAndPats, [], letPat.Range) - source, pat + let source = + mkSynCall + mergeSourcesName + sourcesRange + (List.map fst nowSourcesAndPats @ [ laterSource ]) + ceenv.builderValName - else + let pat = + SynPat.Tuple(false, List.map snd nowSourcesAndPats @ [ laterPat ], [], letPat.Range) - // Call MergeSourcesMax(e1, e2, e3, e4, (...)) - let nowSourcesAndPats, laterSourcesAndPats = - List.splitAt (maxMergeSources - 1) sourcesAndPats - - let mergeSourcesName = mkMergeSourcesName maxMergeSources - - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo - ResultCollectionSettings.AtMostOneResult - cenv - env - mBind - ad - mergeSourcesName - builderTy - ) - then - error (Error(FSComp.SR.tcRequireMergeSourcesOrBindN (bindNName), mBind)) + source, pat - let laterSource, laterPat = mergeSources laterSourcesAndPats + let mergedSources, consumePat = mergeSources (List.zip sources pats) - let source = - mkSynCall - mergeSourcesName - sourcesRange - (List.map fst nowSourcesAndPats @ [ laterSource ]) - builderValName + // Add the variables to the query variable space, on demand + let varSpace = + addVarsToVarSpace varSpace (fun _mCustomOp env -> + use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink - let pat = - SynPat.Tuple(false, List.map snd nowSourcesAndPats @ [ laterPat ], [], letPat.Range) + let _, _, vspecs, envinner, _ = + TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv consumePat None - source, pat + vspecs, envinner) - let mergedSources, consumePat = mergeSources (List.zip sources pats) + // Build the 'Bind' call + Some( + TranslateComputationExpressionBind + ceenv + comp + q + varSpace + mBind + (addBindDebugPoint spBind) + "Bind" + [ mergedSources ] + consumePat + innerComp + translatedCtxt + ) - // Add the variables to the query variable space, on demand - let varSpace = - addVarsToVarSpace varSpace (fun _mCustomOp env -> - use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink + | SynExpr.Match(spMatch, expr, clauses, m, trivia) -> + if ceenv.isQuery then + error (Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery (), trivia.MatchKeyword)) - let _, _, vspecs, envinner, _ = - TcMatchPattern cenv (NewInferenceType g) env tpenv consumePat None + let clauses = + clauses + |> List.map (fun (SynMatchClause(pat, cond, innerComp, patm, sp, trivia)) -> + SynMatchClause(pat, cond, TranslateComputationExpressionNoQueryOps ceenv innerComp, patm, sp, trivia)) - vspecs, envinner) + Some(translatedCtxt (SynExpr.Match(spMatch, expr, clauses, m, trivia))) - // Build the 'Bind' call - Some( - transBind - q - varSpace - mBind - (addBindDebugPoint spBind) - "Bind" - [ mergedSources ] - consumePat - innerComp - translatedCtxt - ) + // 'match! expr with pats ...' --> build.Bind(e1, (function pats ...)) + // FUTURE: consider allowing translation to BindReturn + | SynExpr.MatchBang(spMatch, expr, clauses, _m, trivia) -> + let inputExpr = mkSourceExpr expr ceenv.sourceMethInfo ceenv.builderValName - | SynExpr.Match(spMatch, expr, clauses, m, trivia) -> - if isQuery then - error (Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery (), trivia.MatchKeyword)) + if ceenv.isQuery then + error (Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery (), trivia.MatchBangKeyword)) - let clauses = - clauses - |> List.map (fun (SynMatchClause(pat, cond, innerComp, patm, sp, trivia)) -> - SynMatchClause(pat, cond, transNoQueryOps innerComp, patm, sp, trivia)) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + trivia.MatchBangKeyword + ceenv.ad + "Bind" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Bind"), trivia.MatchBangKeyword)) - Some(translatedCtxt (SynExpr.Match(spMatch, expr, clauses, m, trivia))) + let clauses = + clauses + |> List.map (fun (SynMatchClause(pat, cond, innerComp, patm, sp, trivia)) -> + SynMatchClause(pat, cond, TranslateComputationExpressionNoQueryOps ceenv innerComp, patm, sp, trivia)) - // 'match! expr with pats ...' --> build.Bind(e1, (function pats ...)) - // FUTURE: consider allowing translation to BindReturn - | SynExpr.MatchBang(spMatch, expr, clauses, _m, trivia) -> - let inputExpr = mkSourceExpr expr sourceMethInfo builderValName + let consumeExpr = + SynExpr.MatchLambda(false, trivia.MatchBangKeyword, clauses, DebugPointAtBinding.NoneAtInvisible, trivia.MatchBangKeyword) - if isQuery then - error (Error(FSComp.SR.tcMatchMayNotBeUsedWithQuery (), trivia.MatchBangKeyword)) + let callExpr = + mkSynCall "Bind" trivia.MatchBangKeyword [ inputExpr; consumeExpr ] ceenv.builderValName + |> addBindDebugPoint spMatch - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo - ResultCollectionSettings.AtMostOneResult - cenv - env - trivia.MatchBangKeyword - ad - "Bind" - builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Bind"), trivia.MatchBangKeyword)) + Some(translatedCtxt callExpr) - let clauses = - clauses - |> List.map (fun (SynMatchClause(pat, cond, innerComp, patm, sp, trivia)) -> - SynMatchClause(pat, cond, transNoQueryOps innerComp, patm, sp, trivia)) + | SynExpr.TryWith(innerComp, clauses, mTryToLast, spTry, spWith, trivia) -> + let mTry = + match spTry with + | DebugPointAtTry.Yes _ -> trivia.TryKeyword.NoteSourceConstruct(NotedSourceConstruct.Try) + | _ -> trivia.TryKeyword - let consumeExpr = - SynExpr.MatchLambda( - false, - trivia.MatchBangKeyword, - clauses, - DebugPointAtBinding.NoneAtInvisible, - trivia.MatchBangKeyword - ) + let spWith2 = + match spWith with + | DebugPointAtWith.Yes _ -> DebugPointAtBinding.Yes trivia.WithKeyword + | _ -> DebugPointAtBinding.NoneAtInvisible - let callExpr = - mkSynCall "Bind" trivia.MatchBangKeyword [ inputExpr; consumeExpr ] builderValName - |> addBindDebugPoint spMatch + if ceenv.isQuery then + error (Error(FSComp.SR.tcTryWithMayNotBeUsedInQueries (), mTry)) - Some(translatedCtxt callExpr) + let clauses = + clauses + |> List.map (fun (SynMatchClause(pat, cond, clauseComp, patm, sp, trivia)) -> + SynMatchClause(pat, cond, TranslateComputationExpressionNoQueryOps ceenv clauseComp, patm, sp, trivia)) - | SynExpr.TryWith(innerComp, clauses, mTryToLast, spTry, spWith, trivia) -> - let mTry = - match spTry with - | DebugPointAtTry.Yes _ -> trivia.TryKeyword.NoteSourceConstruct(NotedSourceConstruct.Try) - | _ -> trivia.TryKeyword + let consumeExpr = + SynExpr.MatchLambda(true, mTryToLast, clauses, spWith2, mTryToLast) - let spWith2 = - match spWith with - | DebugPointAtWith.Yes _ -> DebugPointAtBinding.Yes trivia.WithKeyword - | _ -> DebugPointAtBinding.NoneAtInvisible + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mTry + ceenv.ad + "TryWith" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("TryWith"), mTry)) - if isQuery then - error (Error(FSComp.SR.tcTryWithMayNotBeUsedInQueries (), mTry)) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + mTry + ceenv.ad + "Delay" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("Delay"), mTry)) - let clauses = - clauses - |> List.map (fun (SynMatchClause(pat, cond, clauseComp, patm, sp, trivia)) -> - SynMatchClause(pat, cond, transNoQueryOps clauseComp, patm, sp, trivia)) + let innerExpr = TranslateComputationExpressionNoQueryOps ceenv innerComp - let consumeExpr = - SynExpr.MatchLambda(true, mTryToLast, clauses, spWith2, mTryToLast) + let innerExpr = + match spTry with + | DebugPointAtTry.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mTry, true, innerExpr) + | _ -> innerExpr - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "TryWith" builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("TryWith"), mTry)) + let callExpr = + mkSynCall + "TryWith" + mTry + [ + mkSynCall "Delay" mTry [ mkSynDelay2 innerExpr ] ceenv.builderValName + consumeExpr + ] + ceenv.builderValName - if - isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mTry ad "Delay" builderTy) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("Delay"), mTry)) + Some(translatedCtxt callExpr) - let innerExpr = transNoQueryOps innerComp + | SynExpr.YieldOrReturnFrom((true, _), synYieldExpr, m) -> + let yieldFromExpr = + mkSourceExpr synYieldExpr ceenv.sourceMethInfo ceenv.builderValName - let innerExpr = - match spTry with - | DebugPointAtTry.Yes _ -> SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes mTry, true, innerExpr) - | _ -> innerExpr + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + m + ceenv.ad + "YieldFrom" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("YieldFrom"), m)) - let callExpr = - mkSynCall "TryWith" mTry [ mkSynCall "Delay" mTry [ mkSynDelay2 innerExpr ] builderValName; consumeExpr ] builderValName + let yieldFromCall = mkSynCall "YieldFrom" m [ yieldFromExpr ] ceenv.builderValName - Some(translatedCtxt callExpr) + let yieldFromCall = + if IsControlFlowExpression synYieldExpr then + yieldFromCall + else + SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, yieldFromCall) - | SynExpr.YieldOrReturnFrom((true, _), synYieldExpr, m) -> - let yieldFromExpr = mkSourceExpr synYieldExpr sourceMethInfo builderValName + Some(translatedCtxt yieldFromCall) - if - isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "YieldFrom" builderTy) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("YieldFrom"), m)) + | SynExpr.YieldOrReturnFrom((false, _), synReturnExpr, m) -> + let returnFromExpr = + mkSourceExpr synReturnExpr ceenv.sourceMethInfo ceenv.builderValName - let yieldFromCall = mkSynCall "YieldFrom" m [ yieldFromExpr ] builderValName + if ceenv.isQuery then + error (Error(FSComp.SR.tcReturnMayNotBeUsedInQueries (), m)) - let yieldFromCall = - if IsControlFlowExpression synYieldExpr then - yieldFromCall - else - SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, yieldFromCall) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + m + ceenv.ad + "ReturnFrom" + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod ("ReturnFrom"), m)) - Some(translatedCtxt yieldFromCall) + let returnFromCall = + mkSynCall "ReturnFrom" m [ returnFromExpr ] ceenv.builderValName - | SynExpr.YieldOrReturnFrom((false, _), synReturnExpr, m) -> - let returnFromExpr = mkSourceExpr synReturnExpr sourceMethInfo builderValName + let returnFromCall = + if IsControlFlowExpression synReturnExpr then + returnFromCall + else + SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, returnFromCall) - if isQuery then - error (Error(FSComp.SR.tcReturnMayNotBeUsedInQueries (), m)) + Some(translatedCtxt returnFromCall) - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "ReturnFrom" builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod ("ReturnFrom"), m)) + | SynExpr.YieldOrReturn((isYield, _), synYieldOrReturnExpr, m) -> + let methName = (if isYield then "Yield" else "Return") - let returnFromCall = mkSynCall "ReturnFrom" m [ returnFromExpr ] builderValName + if ceenv.isQuery && not isYield then + error (Error(FSComp.SR.tcReturnMayNotBeUsedInQueries (), m)) - let returnFromCall = - if IsControlFlowExpression synReturnExpr then - returnFromCall - else - SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, returnFromCall) + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + cenv + ceenv.env + m + ceenv.ad + methName + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod (methName), m)) - Some(translatedCtxt returnFromCall) + let yieldOrReturnCall = + mkSynCall methName m [ synYieldOrReturnExpr ] ceenv.builderValName - | SynExpr.YieldOrReturn((isYield, _), synYieldOrReturnExpr, m) -> - let methName = (if isYield then "Yield" else "Return") + let yieldOrReturnCall = + if IsControlFlowExpression synYieldOrReturnExpr then + yieldOrReturnCall + else + SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, yieldOrReturnCall) - if isQuery && not isYield then - error (Error(FSComp.SR.tcReturnMayNotBeUsedInQueries (), m)) + Some(translatedCtxt yieldOrReturnCall) - if - isNil (TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad methName builderTy) - then - error (Error(FSComp.SR.tcRequireBuilderMethod (methName), m)) + | _ -> None - let yieldOrReturnCall = mkSynCall methName m [ synYieldOrReturnExpr ] builderValName +and ConsumeCustomOpClauses + (ceenv: ComputationExpressionContext<'a>) + (comp: SynExpr) + q + (varSpace: LazyWithContext<_, _>) + dataCompPrior + compClausesExpr + lastUsesBind + mClause + = - let yieldOrReturnCall = - if IsControlFlowExpression synYieldOrReturnExpr then - yieldOrReturnCall - else - SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, yieldOrReturnCall) + // Substitute 'yield ' into the context - Some(translatedCtxt yieldOrReturnCall) + let patvs, _env = varSpace.Force comp.Range + let varSpaceSimplePat = mkSimplePatForVarSpace mClause patvs + let varSpacePat = mkPatForVarSpace mClause patvs - | _ -> None + match compClausesExpr with - and consumeCustomOpClauses q (varSpace: LazyWithContext<_, _>) dataCompPrior compClausesExpr lastUsesBind mClause = + // Detect one custom operation... This clause will always match at least once... + | OptionalSequential(CustomOperationClause ceenv (nm, opDatas, opExpr, mClause, optionalIntoPat), optionalCont) -> - // Substitute 'yield ' into the context + let opName, _, _, _, _, _, _, _, methInfo = opDatas[0] - let patvs, _env = varSpace.Force comp.Range - let varSpaceSimplePat = mkSimplePatForVarSpace mClause patvs - let varSpacePat = mkPatForVarSpace mClause patvs + let isLikeZip = customOperationIsLikeZip ceenv nm - match compClausesExpr with + let isLikeJoin = customOperationIsLikeJoin ceenv nm - // Detect one custom operation... This clause will always match at least once... - | OptionalSequential(CustomOperationClause(nm, opDatas, opExpr, mClause, optionalIntoPat), optionalCont) -> + let isLikeGroupJoin = customOperationIsLikeZip ceenv nm - let opName, _, _, _, _, _, _, _, methInfo = opDatas[0] - let isLikeZip = customOperationIsLikeZip nm - let isLikeJoin = customOperationIsLikeJoin nm - let isLikeGroupJoin = customOperationIsLikeZip nm + // Record the resolution of the custom operation for posterity + let item = + Item.CustomOperation(opName, (fun () -> customOpUsageText ceenv nm), Some methInfo) - // Record the resolution of the custom operation for posterity - let item = - Item.CustomOperation(opName, (fun () -> customOpUsageText nm), Some methInfo) + // FUTURE: consider whether we can do better than emptyTyparInst here, in order to display instantiations + // of type variables in the quick info provided in the IDE. + CallNameResolutionSink + ceenv.cenv.tcSink + (nm.idRange, ceenv.env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, ceenv.env.eAccessRights) - // FUTURE: consider whether we can do better than emptyTyparInst here, in order to display instantiations - // of type variables in the quick info provided in the IDE. - CallNameResolutionSink cenv.tcSink (nm.idRange, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + if isLikeZip || isLikeJoin || isLikeGroupJoin then + errorR (Error(FSComp.SR.tcBinaryOperatorRequiresBody (nm.idText, Option.get (customOpUsageText ceenv nm)), nm.idRange)) - if isLikeZip || isLikeJoin || isLikeGroupJoin then - errorR (Error(FSComp.SR.tcBinaryOperatorRequiresBody (nm.idText, Option.get (customOpUsageText nm)), nm.idRange)) + match optionalCont with + | None -> + // we are about to drop the 'opExpr' AST on the floor. we've already reported an error. attempt to get name resolutions before dropping it + RecordNameAndTypeResolutions ceenv.cenv ceenv.env ceenv.tpenv opExpr + dataCompPrior + | Some contExpr -> ConsumeCustomOpClauses ceenv comp q varSpace dataCompPrior contExpr lastUsesBind mClause + else - match optionalCont with - | None -> - // we are about to drop the 'opExpr' AST on the floor. we've already reported an error. attempt to get name resolutions before dropping it - RecordNameAndTypeResolutions cenv env tpenv opExpr - dataCompPrior - | Some contExpr -> consumeCustomOpClauses q varSpace dataCompPrior contExpr lastUsesBind mClause - else + let maintainsVarSpace = customOperationMaintainsVarSpace ceenv nm - let maintainsVarSpace = customOperationMaintainsVarSpace nm - let maintainsVarSpaceUsingBind = customOperationMaintainsVarSpaceUsingBind nm - - let expectedArgCount = tryExpectedArgCountForCustomOperator nm - - let dataCompAfterOp = - match opExpr with - | StripApps(SingleIdent nm, args) -> - let argCountsMatch = - match expectedArgCount with - | Some n -> n = args.Length - | None -> cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations - - if argCountsMatch then - // Check for the [] attribute on each argument position - let args = - args - |> List.mapi (fun i arg -> - if isCustomOperationProjectionParameter (i + 1) nm then - SynExpr.Lambda( - false, - false, - varSpaceSimplePat, - arg, - None, - arg.Range.MakeSynthetic(), - SynExprLambdaTrivia.Zero - ) - else - arg) + let maintainsVarSpaceUsingBind = customOperationMaintainsVarSpaceUsingBind ceenv nm - mkSynCall methInfo.DisplayName mClause (dataCompPrior :: args) builderValName - else - let expectedArgCount = defaultArg expectedArgCount 0 + let expectedArgCount = tryExpectedArgCountForCustomOperator ceenv nm - errorR ( - Error( - FSComp.SR.tcCustomOperationHasIncorrectArgCount (nm.idText, expectedArgCount, args.Length), - nm.idRange - ) + let dataCompAfterOp = + match opExpr with + | StripApps(SingleIdent nm, args) -> + let argCountsMatch = + match expectedArgCount with + | Some n -> n = args.Length + | None -> ceenv.cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations + + if argCountsMatch then + // Check for the [] attribute on each argument position + let args = + args + |> List.mapi (fun i arg -> + if isCustomOperationProjectionParameter ceenv (i + 1) nm then + SynExpr.Lambda( + false, + false, + varSpaceSimplePat, + arg, + None, + arg.Range.MakeSynthetic(), + SynExprLambdaTrivia.Zero + ) + else + arg) + + mkSynCall methInfo.DisplayName mClause (dataCompPrior :: args) ceenv.builderValName + else + let expectedArgCount = defaultArg expectedArgCount 0 + + errorR ( + Error(FSComp.SR.tcCustomOperationHasIncorrectArgCount (nm.idText, expectedArgCount, args.Length), nm.idRange) + ) + + mkSynCall + methInfo.DisplayName + mClause + ([ dataCompPrior ] + @ List.init expectedArgCount (fun i -> arbExpr ("_arg" + string i, mClause))) + ceenv.builderValName + | _ -> failwith "unreachable" + + match optionalCont with + | None -> + match optionalIntoPat with + | Some intoPat -> errorR (Error(FSComp.SR.tcIntoNeedsRestOfQuery (), intoPat.Range)) + | None -> () + + dataCompAfterOp + + | Some contExpr -> + + // select a.Name into name; ... + // distinct into d; ... + // + // Rebind the into pattern and process the rest of the clauses + match optionalIntoPat with + | Some intoPat -> + if not (customOperationAllowsInto ceenv nm) then + error (Error(FSComp.SR.tcOperatorDoesntAcceptInto (nm.idText), intoPat.Range)) + + // Rebind using either for ... or let!.... + let rebind = + if maintainsVarSpaceUsingBind then + SynExpr.LetOrUseBang( + DebugPointAtBinding.NoneAtLet, + false, + false, + intoPat, + dataCompAfterOp, + [], + contExpr, + intoPat.Range, + SynExprLetOrUseBangTrivia.Zero + ) + else + SynExpr.ForEach( + DebugPointAtFor.No, + DebugPointAtInOrTo.No, + SeqExprOnly false, + false, + intoPat, + dataCompAfterOp, + contExpr, + intoPat.Range ) - mkSynCall - methInfo.DisplayName - mClause - ([ dataCompPrior ] - @ List.init expectedArgCount (fun i -> arbExpr ("_arg" + string i, mClause))) - builderValName - | _ -> failwith "unreachable" + TranslateComputationExpression ceenv CompExprTranslationPass.Initial q ceenv.emptyVarSpace rebind id - match optionalCont with + // select a.Name; ... + // distinct; ... + // + // Process the rest of the clauses | None -> - match optionalIntoPat with - | Some intoPat -> errorR (Error(FSComp.SR.tcIntoNeedsRestOfQuery (), intoPat.Range)) - | None -> () - - dataCompAfterOp - - | Some contExpr -> - - // select a.Name into name; ... - // distinct into d; ... - // - // Rebind the into pattern and process the rest of the clauses - match optionalIntoPat with - | Some intoPat -> - if not (customOperationAllowsInto nm) then - error (Error(FSComp.SR.tcOperatorDoesntAcceptInto (nm.idText), intoPat.Range)) - - // Rebind using either for ... or let!.... - let rebind = - if maintainsVarSpaceUsingBind then - SynExpr.LetOrUseBang( - DebugPointAtBinding.NoneAtLet, - false, - false, - intoPat, - dataCompAfterOp, - [], - contExpr, - intoPat.Range, - SynExprLetOrUseBangTrivia.Zero - ) - else - SynExpr.ForEach( - DebugPointAtFor.No, - DebugPointAtInOrTo.No, - SeqExprOnly false, - false, - intoPat, - dataCompAfterOp, - contExpr, - intoPat.Range - ) + if maintainsVarSpace || maintainsVarSpaceUsingBind then + ConsumeCustomOpClauses ceenv comp q varSpace dataCompAfterOp contExpr maintainsVarSpaceUsingBind mClause + else + ConsumeCustomOpClauses ceenv comp q ceenv.emptyVarSpace dataCompAfterOp contExpr false mClause + + // No more custom operator clauses in compClausesExpr, but there may be clauses like join, yield etc. + // Bind/iterate the dataCompPrior and use compClausesExpr as the body. + | _ -> + // Rebind using either for ... or let!.... + let rebind = + if lastUsesBind then + SynExpr.LetOrUseBang( + DebugPointAtBinding.NoneAtLet, + false, + false, + varSpacePat, + dataCompPrior, + [], + compClausesExpr, + compClausesExpr.Range, + SynExprLetOrUseBangTrivia.Zero + ) + else + SynExpr.ForEach( + DebugPointAtFor.No, + DebugPointAtInOrTo.No, + SeqExprOnly false, + false, + varSpacePat, + dataCompPrior, + compClausesExpr, + compClausesExpr.Range + ) - trans CompExprTranslationPass.Initial q emptyVarSpace rebind id + TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace rebind id + +and TranslateComputationExpressionNoQueryOps ceenv comp = + TranslateComputationExpression ceenv CompExprTranslationPass.Initial CustomOperationsMode.Denied ceenv.emptyVarSpace comp id + +and TranslateComputationExpressionBind + (ceenv: ComputationExpressionContext<'a>) + comp + q + varSpace + bindRange + addBindDebugPoint + bindName + (bindArgs: SynExpr list) + (consumePat: SynPat) + (innerComp: SynExpr) + translatedCtxt + = + + let innerRange = innerComp.Range + + let innerCompReturn = + if ceenv.cenv.g.langVersion.SupportsFeature LanguageFeature.AndBang then + convertSimpleReturnToExpr ceenv comp varSpace innerComp + else + None - // select a.Name; ... - // distinct; ... - // - // Process the rest of the clauses - | None -> - if maintainsVarSpace || maintainsVarSpaceUsingBind then - consumeCustomOpClauses q varSpace dataCompAfterOp contExpr maintainsVarSpaceUsingBind mClause - else - consumeCustomOpClauses q emptyVarSpace dataCompAfterOp contExpr false mClause + match innerCompReturn with + | Some(innerExpr, customOpInfo) when + (let bindName = bindName + "Return" + + not ( + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + ceenv.cenv + ceenv.env + bindRange + ceenv.ad + bindName + ceenv.builderTy + ) + )) + -> + + let bindName = bindName + "Return" + + // Build the `BindReturn` call + let dataCompPriorToOp = + let consumeExpr = + SynExpr.MatchLambda( + false, + consumePat.Range, + [ + SynMatchClause(consumePat, None, innerExpr, innerRange, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero) + ], + DebugPointAtBinding.NoneAtInvisible, + innerRange + ) - // No more custom operator clauses in compClausesExpr, but there may be clauses like join, yield etc. - // Bind/iterate the dataCompPrior and use compClausesExpr as the body. - | _ -> - // Rebind using either for ... or let!.... - let rebind = - if lastUsesBind then - SynExpr.LetOrUseBang( - DebugPointAtBinding.NoneAtLet, - false, - false, - varSpacePat, - dataCompPrior, - [], - compClausesExpr, - compClausesExpr.Range, - SynExprLetOrUseBangTrivia.Zero - ) - else - SynExpr.ForEach( - DebugPointAtFor.No, - DebugPointAtInOrTo.No, - SeqExprOnly false, - false, - varSpacePat, - dataCompPrior, - compClausesExpr, - compClausesExpr.Range - ) + translatedCtxt (mkSynCall bindName bindRange (bindArgs @ [ consumeExpr ]) ceenv.builderValName) + + match customOpInfo with + | None -> dataCompPriorToOp + | Some(innerComp, mClause) -> + // If the `BindReturn` was forced by a custom operation, continue to process the clauses of the CustomOp + ConsumeCustomOpClauses ceenv comp q varSpace dataCompPriorToOp innerComp false mClause + + | _ -> + + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + ceenv.cenv + ceenv.env + bindRange + ceenv.ad + bindName + ceenv.builderTy + ) + then + error (Error(FSComp.SR.tcRequireBuilderMethod (bindName), bindRange)) + + // Build the `Bind` call + TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> + let consumeExpr = + SynExpr.MatchLambda( + false, + consumePat.Range, + [ + SynMatchClause(consumePat, None, holeFill, innerRange, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero) + ], + DebugPointAtBinding.NoneAtInvisible, + innerRange + ) - trans CompExprTranslationPass.Initial q varSpace rebind id + let bindCall = + mkSynCall bindName bindRange (bindArgs @ [ consumeExpr ]) ceenv.builderValName - and transNoQueryOps comp = - trans CompExprTranslationPass.Initial CustomOperationsMode.Denied emptyVarSpace comp id + translatedCtxt (bindCall |> addBindDebugPoint)) - and trans firstTry q varSpace comp translatedCtxt = - cenv.stackGuard.Guard - <| fun () -> - match tryTrans firstTry q varSpace comp translatedCtxt with - | Some e -> e - | None -> - // This only occurs in final position in a sequence - match comp with - // "do! expr;" in final position is treated as { let! () = expr in return () } when Return is provided (and no Zero with Default attribute is available) or as { let! () = expr in zero } otherwise - | SynExpr.DoBang(rhsExpr, m) -> - let mUnit = rhsExpr.Range - let rhsExpr = mkSourceExpr rhsExpr sourceMethInfo builderValName - - if isQuery then - error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), m)) - - let bodyExpr = - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo - ResultCollectionSettings.AtMostOneResult - cenv - env - m - ad - "Return" - builderTy - ) - then - SynExpr.ImplicitZero m - else - match - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env m ad "Zero" builderTy - with - | minfo :: _ when MethInfoHasAttribute cenv.g m cenv.g.attrib_DefaultValueAttribute minfo -> - SynExpr.ImplicitZero m - | _ -> SynExpr.YieldOrReturn((false, true), SynExpr.Const(SynConst.Unit, m), m) - - let letBangBind = - SynExpr.LetOrUseBang( - DebugPointAtBinding.NoneAtDo, - false, - false, - SynPat.Const(SynConst.Unit, mUnit), - rhsExpr, - [], - bodyExpr, - m, - SynExprLetOrUseBangTrivia.Zero - ) +/// This function is for desugaring into .Bind{N}Return calls if possible +/// The outer option indicates if .BindReturn is possible. When it returns None, .BindReturn cannot be used +/// The inner option indicates if a custom operation is involved inside +and convertSimpleReturnToExpr (ceenv: ComputationExpressionContext<'a>) comp varSpace innerComp = + match innerComp with + | SynExpr.YieldOrReturn((false, _), returnExpr, m) -> + let returnExpr = SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, returnExpr) + Some(returnExpr, None) + + | SynExpr.Match(spMatch, expr, clauses, m, trivia) -> + let clauses = + clauses + |> List.map (fun (SynMatchClause(pat, cond, innerComp2, patm, sp, trivia)) -> + match convertSimpleReturnToExpr ceenv comp varSpace innerComp2 with + | None -> None // failure + | Some(_, Some _) -> None // custom op on branch = failure + | Some(innerExpr2, None) -> Some(SynMatchClause(pat, cond, innerExpr2, patm, sp, trivia))) + + if clauses |> List.forall Option.isSome then + Some(SynExpr.Match(spMatch, expr, (clauses |> List.map Option.get), m, trivia), None) + else + None + + | SynExpr.IfThenElse(guardExpr, thenComp, elseCompOpt, spIfToThen, isRecovery, mIfToEndOfElseBranch, trivia) -> + match convertSimpleReturnToExpr ceenv comp varSpace thenComp with + | None -> None + | Some(_, Some _) -> None + | Some(thenExpr, None) -> + let elseExprOptOpt = + match elseCompOpt with + // When we are missing an 'else' part alltogether in case of 'if cond then return exp', we fallback from BindReturn into regular Bind+Return + | None -> None + | Some elseComp -> + match convertSimpleReturnToExpr ceenv comp varSpace elseComp with + | None -> None // failure + | Some(_, Some _) -> None // custom op on branch = failure + | Some(elseExpr, None) -> Some(Some elseExpr) + + match elseExprOptOpt with + | None -> None + | Some elseExprOpt -> + Some(SynExpr.IfThenElse(guardExpr, thenExpr, elseExprOpt, spIfToThen, isRecovery, mIfToEndOfElseBranch, trivia), None) - trans CompExprTranslationPass.Initial q varSpace letBangBind translatedCtxt + | SynExpr.LetOrUse(isRec, false, binds, innerComp, m, trivia) -> + match convertSimpleReturnToExpr ceenv comp varSpace innerComp with + | None -> None + | Some(_, Some _) -> None + | Some(innerExpr, None) -> Some(SynExpr.LetOrUse(isRec, false, binds, innerExpr, m, trivia), None) + + | OptionalSequential(CustomOperationClause ceenv (nm, _, _, mClause, _), _) when customOperationMaintainsVarSpaceUsingBind ceenv nm -> + + let patvs, _env = varSpace.Force comp.Range + let varSpaceExpr = mkExprForVarSpace mClause patvs + + Some(varSpaceExpr, Some(innerComp, mClause)) + + | SynExpr.Sequential(sp, true, innerComp1, innerComp2, m, trivia) -> + + // Check the first part isn't a computation expression construct + if (isSimpleExpr ceenv innerComp1) then + // Check the second part is a simple return + match convertSimpleReturnToExpr ceenv comp varSpace innerComp2 with + | None -> None + | Some(innerExpr2, optionalCont) -> Some(SynExpr.Sequential(sp, true, innerComp1, innerExpr2, m, trivia), optionalCont) + else + None + + | _ -> None + +/// Check if an expression has no computation expression constructs +and isSimpleExpr ceenv comp = + + match comp with + | ForEachThenJoinOrGroupJoinOrZipClause ceenv false _ -> false + | SynExpr.ForEach _ -> false + | SynExpr.For _ -> false + | SynExpr.While _ -> false + | SynExpr.WhileBang _ -> false + | SynExpr.TryFinally _ -> false + | SynExpr.ImplicitZero _ -> false + | OptionalSequential(JoinOrGroupJoinOrZipClause ceenv _, _) -> false + | OptionalSequential(CustomOperationClause ceenv _, _) -> false + | SynExpr.Sequential(expr1 = innerComp1; expr2 = innerComp2) -> isSimpleExpr ceenv innerComp1 && isSimpleExpr ceenv innerComp2 + | SynExpr.IfThenElse(thenExpr = thenComp; elseExpr = elseCompOpt) -> + isSimpleExpr ceenv thenComp + && (match elseCompOpt with + | None -> true + | Some c -> isSimpleExpr ceenv c) + | SynExpr.LetOrUse(body = innerComp) -> isSimpleExpr ceenv innerComp + | SynExpr.LetOrUseBang _ -> false + | SynExpr.Match(clauses = clauses) -> + clauses + |> List.forall (fun (SynMatchClause(resultExpr = innerComp)) -> isSimpleExpr ceenv innerComp) + | SynExpr.MatchBang _ -> false + | SynExpr.TryWith(tryExpr = innerComp; withCases = clauses) -> + isSimpleExpr ceenv innerComp + && clauses + |> List.forall (fun (SynMatchClause(resultExpr = clauseComp)) -> isSimpleExpr ceenv clauseComp) + | SynExpr.YieldOrReturnFrom _ -> false + | SynExpr.YieldOrReturn _ -> false + | SynExpr.DoBang _ -> false + | _ -> true - // "expr;" in final position is treated as { expr; zero } - // Suppress the sequence point on the "zero" - | _ -> - // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore comp - if isQuery && checkForBinaryApp comp then - trans CompExprTranslationPass.Initial q varSpace (SynExpr.ImplicitZero comp.Range) translatedCtxt +and TranslateComputationExpression (ceenv: ComputationExpressionContext<'a>) firstTry q varSpace comp translatedCtxt = + + ceenv.cenv.stackGuard.Guard + <| fun () -> + match TryTranslateComputationExpression ceenv firstTry q varSpace comp translatedCtxt with + | Some e -> e + | None -> + // This only occurs in final position in a sequence + match comp with + // "do! expr;" in final position is treated as { let! () = expr in return () } when Return is provided (and no Zero with Default attribute is available) or as { let! () = expr in zero } otherwise + | SynExpr.DoBang(rhsExpr, m) -> + let mUnit = rhsExpr.Range + let rhsExpr = mkSourceExpr rhsExpr ceenv.sourceMethInfo ceenv.builderValName + + if ceenv.isQuery then + error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), m)) + + let bodyExpr = + if + isNil ( + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + ceenv.cenv + ceenv.env + m + ceenv.ad + "Return" + ceenv.builderTy + ) + then + SynExpr.ImplicitZero m else - if isQuery && not comp.IsArbExprAndThusAlreadyReportedError then - match comp with - | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential - | _ -> errorR (Error(FSComp.SR.tcUnrecognizedQueryOperator (), comp.RangeOfFirstPortion)) + match + TryFindIntrinsicOrExtensionMethInfo + ResultCollectionSettings.AtMostOneResult + ceenv.cenv + ceenv.env + m + ceenv.ad + "Zero" + ceenv.builderTy + with + | minfo :: _ when MethInfoHasAttribute ceenv.cenv.g m ceenv.cenv.g.attrib_DefaultValueAttribute minfo -> + SynExpr.ImplicitZero m + | _ -> SynExpr.YieldOrReturn((false, true), SynExpr.Const(SynConst.Unit, m), m) - trans CompExprTranslationPass.Initial q varSpace (SynExpr.ImplicitZero comp.Range) (fun holeFill -> + let letBangBind = + SynExpr.LetOrUseBang( + DebugPointAtBinding.NoneAtDo, + false, + false, + SynPat.Const(SynConst.Unit, mUnit), + rhsExpr, + [], + bodyExpr, + m, + SynExprLetOrUseBangTrivia.Zero + ) + + TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace letBangBind translatedCtxt + + // "expr;" in final position is treated as { expr; zero } + // Suppress the sequence point on the "zero" + | _ -> + // Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore comp + if ceenv.isQuery && checkForBinaryApp ceenv comp then + TranslateComputationExpression + ceenv + CompExprTranslationPass.Initial + q + varSpace + (SynExpr.ImplicitZero comp.Range) + translatedCtxt + else + if ceenv.isQuery && not comp.IsArbExprAndThusAlreadyReportedError then + match comp with + | SynExpr.JoinIn _ -> () // an error will be reported later when we process innerComp1 as a sequential + | _ -> errorR (Error(FSComp.SR.tcUnrecognizedQueryOperator (), comp.RangeOfFirstPortion)) + + TranslateComputationExpression + ceenv + CompExprTranslationPass.Initial + q + varSpace + (SynExpr.ImplicitZero comp.Range) + (fun holeFill -> let fillExpr = - if enableImplicitYield then - let implicitYieldExpr = mkSynCall "Yield" comp.Range [ comp ] builderValName + if ceenv.enableImplicitYield then + let implicitYieldExpr = mkSynCall "Yield" comp.Range [ comp ] ceenv.builderValName SynExpr.SequentialOrImplicitYield( DebugPointAtSequential.SuppressExpr, @@ -2601,192 +2962,119 @@ let TcComputationExpression (cenv: TcFileState) env (overallTy: OverallTy) tpenv translatedCtxt fillExpr) - and transBind - q - varSpace - bindRange - addBindDebugPoint - bindName - (bindArgs: SynExpr list) - (consumePat: SynPat) - (innerComp: SynExpr) - translatedCtxt - = - - let innerRange = innerComp.Range - - let innerCompReturn = - if cenv.g.langVersion.SupportsFeature LanguageFeature.AndBang then - convertSimpleReturnToExpr varSpace innerComp - else - None - - match innerCompReturn with - | Some(innerExpr, customOpInfo) when - (let bindName = bindName + "Return" - - not ( - isNil ( - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad bindName builderTy - ) - )) - -> - - let bindName = bindName + "Return" - - // Build the `BindReturn` call - let dataCompPriorToOp = - let consumeExpr = - SynExpr.MatchLambda( - false, - consumePat.Range, - [ - SynMatchClause(consumePat, None, innerExpr, innerRange, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero) - ], - DebugPointAtBinding.NoneAtInvisible, - innerRange - ) - - translatedCtxt (mkSynCall bindName bindRange (bindArgs @ [ consumeExpr ]) builderValName) - - match customOpInfo with - | None -> dataCompPriorToOp - | Some(innerComp, mClause) -> - // If the `BindReturn` was forced by a custom operation, continue to process the clauses of the CustomOp - consumeCustomOpClauses q varSpace dataCompPriorToOp innerComp false mClause - - | _ -> - - if - isNil ( - TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env bindRange ad bindName builderTy - ) - then - error (Error(FSComp.SR.tcRequireBuilderMethod (bindName), bindRange)) - - // Build the `Bind` call - trans CompExprTranslationPass.Initial q varSpace innerComp (fun holeFill -> - let consumeExpr = - SynExpr.MatchLambda( - false, - consumePat.Range, - [ - SynMatchClause(consumePat, None, holeFill, innerRange, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero) - ], - DebugPointAtBinding.NoneAtInvisible, - innerRange - ) +/// Used for all computation expressions except sequence expressions +let TcComputationExpression (cenv: TcFileState) env (overallTy: OverallTy) tpenv (mWhole, interpExpr: Expr, builderTy, comp: SynExpr) = + let overallTy = overallTy.Commit - let bindCall = - mkSynCall bindName bindRange (bindArgs @ [ consumeExpr ]) builderValName + let ad = env.eAccessRights - translatedCtxt (bindCall |> addBindDebugPoint)) + let builderValName = CompilerGeneratedName "builder" + let mBuilderVal = interpExpr.Range - /// This function is for desugaring into .Bind{N}Return calls if possible - /// The outer option indicates if .BindReturn is possible. When it returns None, .BindReturn cannot be used - /// The inner option indicates if a custom operation is involved inside - and convertSimpleReturnToExpr varSpace innerComp = - match innerComp with - | SynExpr.YieldOrReturn((false, _), returnExpr, m) -> - let returnExpr = SynExpr.DebugPoint(DebugPointAtLeafExpr.Yes m, false, returnExpr) - Some(returnExpr, None) + // Give bespoke error messages for the FSharp.Core "query" builder + let isQuery = + match stripDebugPoints interpExpr with + // An unparameterized custom builder, e.g., `query`, `async`. + | Expr.Val(vref, _, m) + // A parameterized custom builder, e.g., `builder<…>`, `builder ()`. + | Expr.App(funcExpr = Expr.Val(vref, _, m)) when not vref.IsMember || vref.IsConstructor -> + let item = Item.CustomBuilder(vref.DisplayName, vref) + CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) + valRefEq cenv.g vref cenv.g.query_value_vref + | _ -> false - | SynExpr.Match(spMatch, expr, clauses, m, trivia) -> - let clauses = - clauses - |> List.map (fun (SynMatchClause(pat, cond, innerComp2, patm, sp, trivia)) -> - match convertSimpleReturnToExpr varSpace innerComp2 with - | None -> None // failure - | Some(_, Some _) -> None // custom op on branch = failure - | Some(innerExpr2, None) -> Some(SynMatchClause(pat, cond, innerExpr2, patm, sp, trivia))) + let sourceMethInfo = + TryFindIntrinsicOrExtensionMethInfo ResultCollectionSettings.AtMostOneResult cenv env mBuilderVal ad "Source" builderTy - if clauses |> List.forall Option.isSome then - Some(SynExpr.Match(spMatch, expr, (clauses |> List.map Option.get), m, trivia), None) - else - None + /// Decide if the builder is an auto-quote builder + let isAutoQuote = hasMethInfo "Quote" cenv env mBuilderVal ad builderTy - | SynExpr.IfThenElse(guardExpr, thenComp, elseCompOpt, spIfToThen, isRecovery, mIfToEndOfElseBranch, trivia) -> - match convertSimpleReturnToExpr varSpace thenComp with - | None -> None - | Some(_, Some _) -> None - | Some(thenExpr, None) -> - let elseExprOptOpt = - match elseCompOpt with - // When we are missing an 'else' part alltogether in case of 'if cond then return exp', we fallback from BindReturn into regular Bind+Return - | None -> None - | Some elseComp -> - match convertSimpleReturnToExpr varSpace elseComp with - | None -> None // failure - | Some(_, Some _) -> None // custom op on branch = failure - | Some(elseExpr, None) -> Some(Some elseExpr) - - match elseExprOptOpt with - | None -> None - | Some elseExprOpt -> - Some(SynExpr.IfThenElse(guardExpr, thenExpr, elseExprOpt, spIfToThen, isRecovery, mIfToEndOfElseBranch, trivia), None) + let customOperationMethods = + getCustomOperationMethods cenv env ad mBuilderVal builderTy - | SynExpr.LetOrUse(isRec, false, binds, innerComp, m, trivia) -> - match convertSimpleReturnToExpr varSpace innerComp with - | None -> None - | Some(_, Some _) -> None - | Some(innerExpr, None) -> Some(SynExpr.LetOrUse(isRec, false, binds, innerExpr, m, trivia), None) + /// Decide if the identifier represents a use of a custom query operator + let hasCustomOperations = + match customOperationMethods with + | [] -> CustomOperationsMode.Denied + | _ -> CustomOperationsMode.Allowed - | OptionalSequential(CustomOperationClause(nm, _, _, mClause, _), _) when customOperationMaintainsVarSpaceUsingBind nm -> + let customOperationMethodsIndexedByKeyword = + if cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations then + customOperationMethods + |> Seq.groupBy (fun (nm, _, _, _, _, _, _, _, _) -> nm) + |> Seq.map (fun (nm, group) -> (nm, Seq.toList group)) + else + customOperationMethods + |> Seq.groupBy (fun (nm, _, _, _, _, _, _, _, _) -> nm) + |> Seq.map (fun (nm, group) -> (nm, Seq.toList group)) + |> dict - let patvs, _env = varSpace.Force comp.Range - let varSpaceExpr = mkExprForVarSpace mClause patvs + // Check for duplicates by method name (keywords and method names must be 1:1) + let customOperationMethodsIndexedByMethodName = + if cenv.g.langVersion.SupportsFeature LanguageFeature.OverloadsForCustomOperations then + customOperationMethods + |> Seq.groupBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) + |> Seq.map (fun (nm, group) -> (nm, Seq.toList group)) + else + customOperationMethods + |> Seq.groupBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) + |> Seq.map (fun (nm, group) -> (nm, Seq.toList group)) + |> dict - Some(varSpaceExpr, Some(innerComp, mClause)) + // If there are no 'yield' in the computation expression, and the builder supports 'Yield', + // then allow the type-directed rule interpreting non-unit-typed expressions in statement + // positions as 'yield'. 'yield!' may be present in the computation expression. + let enableImplicitYield = + cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield + && (hasMethInfo "Yield" cenv env mBuilderVal ad builderTy + && hasMethInfo "Combine" cenv env mBuilderVal ad builderTy + && hasMethInfo "Delay" cenv env mBuilderVal ad builderTy + && YieldFree cenv comp) - | SynExpr.Sequential(sp, true, innerComp1, innerComp2, m, trivia) -> + let origComp = comp - // Check the first part isn't a computation expression construct - if isSimpleExpr innerComp1 then - // Check the second part is a simple return - match convertSimpleReturnToExpr varSpace innerComp2 with - | None -> None - | Some(innerExpr2, optionalCont) -> Some(SynExpr.Sequential(sp, true, innerComp1, innerExpr2, m, trivia), optionalCont) - else - None + let ceenv = + { + cenv = cenv + env = env + tpenv = tpenv + customOperationMethodsIndexedByKeyword = customOperationMethodsIndexedByKeyword + customOperationMethodsIndexedByMethodName = customOperationMethodsIndexedByMethodName + sourceMethInfo = sourceMethInfo + builderValName = builderValName + ad = ad + builderTy = builderTy + isQuery = isQuery + enableImplicitYield = enableImplicitYield + origComp = origComp + mWhole = mWhole + emptyVarSpace = LazyWithContext.NotLazy([], env) + } - | _ -> None + /// Inside the 'query { ... }' use a modified name environment that contains fake 'CustomOperation' entries + /// for all custom operations. This adds them to the completion lists and prevents them being used as values inside + /// the query. + let env = + if List.isEmpty customOperationMethods then + env + else + { env with + eNameResEnv = + (env.eNameResEnv, customOperationMethods) + ||> Seq.fold (fun nenv (nm, _, _, _, _, _, _, _, methInfo) -> + AddFakeNameToNameEnv + nm + nenv + (Item.CustomOperation(nm, (fun () -> customOpUsageText ceenv (ident (nm, mBuilderVal))), Some methInfo))) + } - /// Check if an expression has no computation expression constructs - and isSimpleExpr comp = + // Environment is needed for completions + CallEnvSink cenv.tcSink (comp.Range, env.NameEnv, ad) - match comp with - | ForEachThenJoinOrGroupJoinOrZipClause false _ -> false - | SynExpr.ForEach _ -> false - | SynExpr.For _ -> false - | SynExpr.While _ -> false - | SynExpr.WhileBang _ -> false - | SynExpr.TryFinally _ -> false - | SynExpr.ImplicitZero _ -> false - | OptionalSequential(JoinOrGroupJoinOrZipClause _, _) -> false - | OptionalSequential(CustomOperationClause _, _) -> false - | SynExpr.Sequential(expr1 = innerComp1; expr2 = innerComp2) -> isSimpleExpr innerComp1 && isSimpleExpr innerComp2 - | SynExpr.IfThenElse(thenExpr = thenComp; elseExpr = elseCompOpt) -> - isSimpleExpr thenComp - && (match elseCompOpt with - | None -> true - | Some c -> isSimpleExpr c) - | SynExpr.LetOrUse(body = innerComp) -> isSimpleExpr innerComp - | SynExpr.LetOrUseBang _ -> false - | SynExpr.Match(clauses = clauses) -> - clauses - |> List.forall (fun (SynMatchClause(resultExpr = innerComp)) -> isSimpleExpr innerComp) - | SynExpr.MatchBang _ -> false - | SynExpr.TryWith(tryExpr = innerComp; withCases = clauses) -> - isSimpleExpr innerComp - && clauses - |> List.forall (fun (SynMatchClause(resultExpr = clauseComp)) -> isSimpleExpr clauseComp) - | SynExpr.YieldOrReturnFrom _ -> false - | SynExpr.YieldOrReturn _ -> false - | SynExpr.DoBang _ -> false - | _ -> true + let ceenv = { ceenv with env = env } let basicSynExpr = - trans CompExprTranslationPass.Initial (hasCustomOperations ()) (LazyWithContext.NotLazy([], env)) comp id + TranslateComputationExpression ceenv CompExprTranslationPass.Initial hasCustomOperations (LazyWithContext.NotLazy([], env)) comp id let mDelayOrQuoteOrRun = mBuilderVal @@ -2836,7 +3124,7 @@ let TcComputationExpression (cenv: TcFileState) env (overallTy: OverallTy) tpenv | _ -> env let lambdaExpr, tpenv = - TcExpr cenv (MustEqual(mkFunTy g builderTy overallTy)) env tpenv lambdaExpr + TcExpr cenv (MustEqual(mkFunTy cenv.g builderTy overallTy)) env tpenv lambdaExpr // beta-var-reduce to bind the builder using a 'let' binding let coreExpr = From b444e519dfcf09034ad1e4faecca7cb9955dff8e Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Thu, 22 Aug 2024 11:26:45 +0200 Subject: [PATCH 03/13] Update azure-pipelines.yml --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2a051012d01..b4f235359af 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -35,7 +35,7 @@ variables: # (since for all *new* release branches we insert into VS main and for all *previous* releases we insert into corresponding VS release), # i.e. 'rel/d17.9' *or* 'main' in dotnet/fsharp/refs/heads/main and 'main' in F# dotnet/fsharp/refs/heads/release/dev17.10 (latest release branch) - name: VSInsertionTargetBranchName - value: rel/d17.11 + value: main - name: _TeamName value: FSharp - name: TeamName From 2b02b7d065ad296fd1c596ebf3de905e09a50200 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 27 Aug 2024 01:58:39 -0700 Subject: [PATCH 04/13] Localized file check-in by OneLocBuild Task: Build definition ID 499: Build ID 2524346 (#17610) --- src/Compiler/xlf/FSComp.txt.cs.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.de.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.es.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.fr.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.it.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.ja.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.ko.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.pl.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.ru.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.tr.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 24 +++++++++---------- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 24 +++++++++---------- src/Compiler/xlf/FSStrings.cs.xlf | 2 +- src/Compiler/xlf/FSStrings.de.xlf | 2 +- src/Compiler/xlf/FSStrings.es.xlf | 2 +- src/Compiler/xlf/FSStrings.fr.xlf | 2 +- src/Compiler/xlf/FSStrings.it.xlf | 2 +- src/Compiler/xlf/FSStrings.ja.xlf | 2 +- src/Compiler/xlf/FSStrings.ko.xlf | 2 +- src/Compiler/xlf/FSStrings.pl.xlf | 2 +- src/Compiler/xlf/FSStrings.pt-BR.xlf | 2 +- src/Compiler/xlf/FSStrings.ru.xlf | 2 +- src/Compiler/xlf/FSStrings.tr.xlf | 2 +- src/Compiler/xlf/FSStrings.zh-Hans.xlf | 2 +- src/Compiler/xlf/FSStrings.zh-Hant.xlf | 2 +- src/FSharp.Core/xlf/FSCore.cs.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.de.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.es.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.fr.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.it.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.ja.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.ko.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.pl.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.pt-BR.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.ru.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.tr.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.zh-Hans.xlf | 4 ++-- src/FSharp.Core/xlf/FSCore.zh-Hant.xlf | 4 ++-- .../xlf/FSDependencyManager.txt.cs.xlf | 2 +- .../xlf/FSDependencyManager.txt.de.xlf | 2 +- .../xlf/FSDependencyManager.txt.es.xlf | 2 +- .../xlf/FSDependencyManager.txt.fr.xlf | 2 +- .../xlf/FSDependencyManager.txt.it.xlf | 2 +- .../xlf/FSDependencyManager.txt.ja.xlf | 2 +- .../xlf/FSDependencyManager.txt.ko.xlf | 2 +- .../xlf/FSDependencyManager.txt.pl.xlf | 2 +- .../xlf/FSDependencyManager.txt.pt-BR.xlf | 2 +- .../xlf/FSDependencyManager.txt.ru.xlf | 2 +- .../xlf/FSDependencyManager.txt.tr.xlf | 2 +- .../xlf/FSDependencyManager.txt.zh-Hans.xlf | 2 +- .../xlf/FSDependencyManager.txt.zh-Hant.xlf | 2 +- .../Template/xlf/Tutorial.fsx.cs.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.de.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.es.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.fr.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.it.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.ja.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.ko.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.pl.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.pt-BR.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.ru.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.tr.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.zh-Hans.xlf | 8 +++---- .../Template/xlf/Tutorial.fsx.zh-Hant.xlf | 8 +++---- ...rosoft.VisualStudio.Package.Project.cs.xlf | 2 +- ...rosoft.VisualStudio.Package.Project.de.xlf | 2 +- ...rosoft.VisualStudio.Package.Project.es.xlf | 2 +- ...rosoft.VisualStudio.Package.Project.fr.xlf | 2 +- ...rosoft.VisualStudio.Package.Project.it.xlf | 2 +- ...rosoft.VisualStudio.Package.Project.ja.xlf | 2 +- ...rosoft.VisualStudio.Package.Project.ko.xlf | 2 +- ...rosoft.VisualStudio.Package.Project.pl.xlf | 2 +- ...oft.VisualStudio.Package.Project.pt-BR.xlf | 2 +- ...rosoft.VisualStudio.Package.Project.ru.xlf | 2 +- ...rosoft.VisualStudio.Package.Project.tr.xlf | 2 +- ...t.VisualStudio.Package.Project.zh-Hans.xlf | 2 +- ...t.VisualStudio.Package.Project.zh-Hant.xlf | 2 +- .../Resources/xlf/WCF.cs.xlf | 2 +- .../Resources/xlf/WCF.de.xlf | 2 +- .../Resources/xlf/WCF.es.xlf | 2 +- .../Resources/xlf/WCF.fr.xlf | 2 +- .../Resources/xlf/WCF.it.xlf | 2 +- .../Resources/xlf/WCF.ja.xlf | 2 +- .../Resources/xlf/WCF.ko.xlf | 2 +- .../Resources/xlf/WCF.pl.xlf | 2 +- .../Resources/xlf/WCF.pt-BR.xlf | 2 +- .../Resources/xlf/WCF.ru.xlf | 2 +- .../Resources/xlf/WCF.tr.xlf | 2 +- .../Resources/xlf/WCF.zh-Hans.xlf | 2 +- .../Resources/xlf/WCF.zh-Hant.xlf | 2 +- 91 files changed, 286 insertions(+), 286 deletions(-) diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index f48c78209bf..06fd0f4a451 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -539,7 +539,7 @@ whitespace relaxation - uvolnění prázdných znaků + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - Ve specifikaci obnovitelného kódu došlo k omezené obecné konstrukci. + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - Ve specifikaci obnovitelného kódu došlo k „let rec“. + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Je třeba inicializovat následující požadované vlastnosti:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Neplatný obnovitelný kód. Ve specifikaci obnovitelného kódu došlo k „let rec“. + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - Zadejte typ ladění: full, portable, embedded, pdbonly. ({0} je výchozí hodnota v případě, že není zadaný žádný typ ladění, a umožňuje připojení ladicího programu ke spuštěnému programu, portable je formát pro různé platformy, embedded je formát pro různé platformy vložený do výstupního souboru). + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - Rezidentní kompilační služba se nepoužila, protože došlo k potížím při komunikaci se serverem. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - Při použití statických argumentů u poskytnutého typu došlo k chybě. + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - Základní atribut TypeProviderAssembly sestavení {0} má neplatnou hodnotu {1}. Hodnotou by měl být platný název sestavení. + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - Při použití statických argumentů u poskytnuté metody došlo k chybě. + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - Atribut CallerMemberNameAttribute použitý pro parametr {0} nebude mít žádný účinek. Přepisuje ho atribut CallerFilePathAttribute. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Slouží k uvození bloku kódu, který může vygenerovat výjimku. Používá se společně s with nebo finally. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 7420a6afdc4..7cfc5383bac 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -539,7 +539,7 @@ whitespace relaxation - Lockerung für Leerraum + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - In der fortsetzbaren Codespezifikation ist ein eingeschränktes generisches Konstrukt aufgetreten. + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - "Let rec" ist in der fortsetzbaren Codespezifikation aufgetreten. + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Die folgenden erforderlichen Eigenschaften müssen initialisiert werden:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Ungültiger fortsetzbarer Code. "Let rec" ist in der fortsetzbaren Codespezifikation aufgetreten + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - Geben Sie den Debugtyp an: full, portable, embedded, pdbonly. ("{0}" ist der Standardwert, wenn kein Debugtyp angegeben wird, und ermöglicht das Anfügen eines Debuggers an ein aktuell ausgeführtes Programm. "portable" ist ein plattformübergreifendes Format, "embedded" ein plattformübergreifendes, in die Ausgabedatei eingebettetes Format). + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - Der residente Kompilierungsdienst wurde nicht verwendet, da bei der Kommunikation mit dem Server ein Problem aufgetreten ist. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - Fehler beim Anwenden des statischen Arguments auf einen angegebenen Typ. + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - Assembly '{0}' verfügt über ein TypeProviderAssembly-Attribut mit dem ungültigen Wert '{1}'. Beim Wert sollte es sich um einen gültigen Assemblynamen handeln. + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - Fehler beim Anwenden der statischen Argumente auf eine angegebene Methode. + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - Das auf Parameter "{0}" angewendete CallerMemberNameAttribute hat keine Auswirkung. Es wird vom CallerFilePathAttribute überschrieben. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Wird verwendet, um einen Codeblock einzuführen, der unter Umständen eine Ausnahme generiert. Wird zusammen mit "with" oder "finally" verwendet. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 845bd6a8ca8..bde79300402 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -539,7 +539,7 @@ whitespace relaxation - relajación de espacio en blanco + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - En la especificación del código resumible aparecía una construcción genérica restringida + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - Se ha producido "let rec" en la especificación de código reanudable + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Se deben inicializar las siguientes propiedades necesarias:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Código reanudable no válido. Se ha producido "let rec" en la especificación de código reanudable + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - Especifique el tipo de depuración: full, portable, embedded, pdbonly. ('{0}' es el valor predeterminado si no se especifica ningún tipo de depuración y permite conectar un depurador a un programa en ejecución, 'portable' es un formato multiplataforma, 'embedded' es un formato multiplataforma insertado en el archivo de salida). + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - El servicio de compilación residente no se usó porque se produjo un problema en la comunicación con el servidor. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - Error al aplicar los argumentos estáticos a un tipo proporcionado. + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - El ensamblado '{0}' tiene el atributo TypeProviderAssembly con el valor '{1}' no válido. El valor debe ser un nombre de ensamblado válido. + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - Se produjo un error al aplicar los argumentos estáticos a un método proporcionado + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - El CallerMemberNameAttribute aplicado al parámetro '{0}' no tendrá ningún efecto. Este se reemplaza por CallerFilePathAttribute. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Se usa para incluir un bloque de código que puede generar una excepción. Se usa junto con with o finally. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 85ce7e5e43c..6df9cecf2f8 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -539,7 +539,7 @@ whitespace relaxation - assouplissement de la mise en retrait avec des espaces blancs + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - Une construction générique contrainte s'est produite dans la spécification de code de reprise + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - Un «let rec» s’est produit dans la spécification de code pouvant être repris + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Les propriétés requises suivantes doivent être initialisées :{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Code pouvant être reprise non valide. Un «let rec» s’est produit dans la spécification de code pouvant être repris + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - Spécifiez le type de débogage : full, portable, embedded, pdbonly. ('{0}' est la valeur par défaut si aucun type de débogage n'est spécifié. Cette valeur permet d'attacher un débogueur à un programme en cours d'exécution, 'portable' est un format multiplateforme, 'embedded' est un format multiplateforme incorporé dans le fichier de sortie). + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - Le service de compilation résident n'a pas été utilisé en raison d'un problème lors de la communication avec le serveur. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - Une erreur s'est produite lors de l'application des arguments statiques à un type fourni + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - L'assembly '{0}' a un attribut TypeProviderAssembly comportant la valeur non valide '{1}'. La valeur doit être un nom d'assembly valide + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - Une erreur s'est produite durant l'application des arguments statiques à une méthode fournie + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - CallerMemberNameAttribute, qui est appliqué au paramètre '{0}', n'aura aucun effet. Il est remplacé par CallerFilePathAttribute. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Permet d'introduire un bloc de code pouvant générer une exception. Utilisé avec with ou finally. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 887bd6e57cd..07e60c7ee1f 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -539,7 +539,7 @@ whitespace relaxation - uso meno restrittivo degli spazi vuoti + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - Costrutto generico vincolato nella specifica del codice ripristinabile + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - È stata rilevata una funzione 'let rec' nella specifica del codice ripristinabile + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - È necessario inizializzare le proprietà obbligatorie seguenti:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Codice ripristinabile non valido. È stato rilevata una funzione 'let rec' nella specifica del codice ripristinabile + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - Consente di specificare il tipo di debug: full, portable, embedded, pdbonly. '{0}' è l'impostazione predefinita se non viene specificato il tipo di debug e consente di associare un debugger a un programma in esecuzione. 'portable' è un formato multipiattaforma. 'embedded' è un formato multipiattaforma incorporato nel file di output. + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - Il servizio di compilazione residente non è stato usato perché si è verificato un problema nella comunicazione con il server. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - Errore durante l'applicazione degli argomenti statici a un tipo fornito + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - Valore '{1}' non valido dell'attributo TypeProviderAssembly nell'assembly '{0}'. Il valore deve essere un nome di assembly valido. + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - Si è verificato un errore durante l'applicazione degli argomenti statici a un metodo fornito + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - CallerMemberNameAttribute applicato al parametro '{0}' non avrà alcun effetto. CallerFilePathAttribute ne eseguirà l'override. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Usata per introdurre un blocco di codice che potrebbe generare un'eccezione. Usata insieme a with o finally. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 1d5a0740a1e..602e97429bd 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -539,7 +539,7 @@ whitespace relaxation - 空白の緩和 + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 再開可能なコード指定で制約付きジェネリック コンストラクトが発生しました + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - 再開可能なコード仕様で 'let rec' が発生しました + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - 次の必須プロパティを初期化する必要があります:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 再開可能なコードが無効です。再開可能なコード仕様で 'let rec' が発生しました + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - デバッグの種類 full、portable、pdbonly を指定します (デバッグの種類が指定されない場合には '{0}' が既定で、実行中のプログラムにデバッガーを付加することができます。'portable' はクロスプラットフォーム形式、'embedded' は出力ファイルに埋め込まれたクロスプラットフォーム形式です)。 + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - サーバーとの通信で問題が発生したため、常駐コンパイル サービスが使用されませんでした。 + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - 指定された型に静的引数を適用する際にエラーが発生しました + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - アセンブリ '{0}' の TypeProviderAssembly 属性に、無効な値 '{1}' が含まれています。この値は有効なアセンブリ名であることが必要です + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - 静的な引数を指定されたメソッドに適用する際エラーが発生しました + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - パラメーター '{0}' に適用された CallerMemberNameAttribute は、CallerFilePathAttribute.によってオーバーライドされるため無効となります。 + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 例外を生成する可能性があるコード ブロックを開始するために使用します。with または finally と一緒に使用します。 + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index e8eebabddf5..617ea55c7ca 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -539,7 +539,7 @@ whitespace relaxation - 공백 완화 + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 다시 시작 가능한 코드 사양에서 제약이 있는 제네릭 구문이 발생했습니다. + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - 다시 시작 가능한 코드 사양에서 'let rec'가 발생했습니다. + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - 다음 필수 속성을 초기화해야 합니다. {0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 다시 시작 가능한 코드가 잘못되었습니다. 다시 시작 가능한 코드 사양에서 'let rec'가 발생했습니다. + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - 디버깅 형식(full, portable, embedded, pdbonly)을 지정합니다. '{0}'은(는) 디버깅 형식을 지정하지 않은 경우 기본값이며 디버거를 실행 중인 프로그램에 연결할 수 있습니다. 'portable'은 플랫폼 간 형식이고, 'embedded'는 출력 파일에 포함된 플랫폼 간 형식입니다. + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 서버와 통신하는 동안 문제가 발생하여 상주 컴파일 서비스를 사용하지 않았습니다. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - 제공된 형식에 정적 인수를 적용하는 동안 오류가 발생했습니다. + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - {0}' 어셈블리에 포함된 TypeProviderAssembly 특성의 값('{1}')이 잘못되었습니다. 값은 올바른 어셈블리 이름이어야 합니다. + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - 제공된 메서드에 정적 인수를 적용하는 동안 오류가 발생했습니다. + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - {0}' 매개 변수에 적용되는 CallerMemberNameAttribute는 효과가 없습니다. CallerFilePathAttribute에서 재정의합니다. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 예외를 생성할 수 있는 코드 블록을 지정하는 데 사용됩니다. with 또는 finally와 함께 사용됩니다. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index ca1b6a407b3..0947910e7eb 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -539,7 +539,7 @@ whitespace relaxation - rozluźnianie reguł dotyczących odstępów + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - W specyfikacji kodu z możliwością wznowienia wystąpiła ograniczona konstrukcja ogólna + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - W specyfikacji kodu z możliwością wznowienia, wystąpił błąd "let rec" + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Następujące wymagane właściwości muszą zostać zainicjowane:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Nieprawidłowy kod z możliwością wznowienia. W specyfikacji kodu z możliwością wznowienia wystąpił element "let rec" + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - Określ typ debugowania: full, portable, pdbonly. Wartość „{0}” jest wartością domyślną, jeśli nie określono typu debugowania, i umożliwia dołączenie debugera do działającego programu. Wartość „portable” określa format międzyplatformowy. Wartość „embedded” określa format międzyplatformowy osadzony w pliku wyjściowym. + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - Rezydentna usługa kompilacji nie została użyta, ponieważ wystąpił problem z komunikowaniem się z serwerem. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - Wystąpił błąd podczas stosowania argumentów statycznych do udostępnionego typu + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - Zestaw „{0}” ma atrybut TypeProviderAssembly z nieprawidłową wartością „{1}”. Wartość powinna być prawidłową nazwą zestawu + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - Wystąpił błąd podczas stosowania argumentów statycznych dla podanej metody + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - Zastosowanie elementu CallerMemberNameAttribute do parametru „{0}” nie odniesie żadnego skutku. Jest on przesłaniany przez element CallerFilePathAttribute. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Używane do wprowadzania bloku kodu, który może generować wyjątek. Używane razem ze słowem kluczowym with lub finally. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index f927f204fae..d52a33bf8df 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -539,7 +539,7 @@ whitespace relaxation - atenuação de espaço em branco + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - Um constructo genérico restrito ocorreu na especificação de código retomável + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - Ocorreu um "let rec" na especificação do código retomável + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - As seguintes propriedades necessárias precisam ser inicializadas:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Código inválido retomável. Ocorreu um "let rec" na especificação do código retomável + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - Especificar tipo de depuração: completo, portátil, incorporado, somente PDB. ('{0}' será o padrão se nenhum tipo de depuração for especificado e permite anexar um depurador a um programa em execução; 'portátil' é um formato multiplataforma; 'incorporado' é um formato multiplataforma incorporado no arquivo de saída). + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - O serviço de compilação residente não foi usado porque houve um problema de comunicação com o servidor. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - Erro ao aplicar os argumentos estáticos a um tipo fornecido + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - O assembly '{0}' possui um atributo TypeProviderAssembly com valor inválido '{1}'. O valor deve ser um nome de assembly válido + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - Ocorreu um erro ao aplicar os argumentos estáticos para um método fornecido + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - O CallerMemberNameAttribute aplicado ao parâmetro "{0}" não terá efeito. Ele é substituído pelo CallerFilePathAttribute. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Usado para introduzir um bloco de código que pode gerar uma exceção. Usado junto com with ou finally. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 5c3701a06de..0516ef816df 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -539,7 +539,7 @@ whitespace relaxation - уменьшение строгости для пробелов + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - В спецификации возобновляемого кода возникла ограниченная универсальная конструкция + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - В спецификации возобновляемого кода возникла ошибка "let rec" + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Необходимо инициализировать следующие обязательные свойства:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Недопустимый возобновляемый код. В спецификации возобновляемого кода возникла ошибка "let rec" + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - Укажите тип отладки: full, portable, embedded, pdbonly (если тип отладки не указан, по умолчанию используется тип "{0}", позволяющий подключить отладчик к выполняющейся программе; тип portable представляет собой кроссплатформенный формат; тип embedded — кроссплатформенный формат, встроенный в выходной файл). + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - Служба резидентной компиляции не использовалась, поскольку возникла проблема при взаимодействии с сервером. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - Ошибка при применении статических аргументов к предоставленному типу + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - У сборки "{0}" имеется атрибут TypeProviderAssembly с недопустимым значением "{1}". Значение должно представлять собой допустимое имя сборки + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - Произошла ошибка при применении статических аргументов к предоставленному методу + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - Атрибут CallerMemberNameAttribute, примененный для параметра "{0}", не будет действовать. Он будет переопределен атрибутом CallerFilePathAttribute. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Используется для введения блока кода, который может создать исключение. Используется вместе с with или finally. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 9b13279b1eb..61334f3d1bf 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -539,7 +539,7 @@ whitespace relaxation - boşluk genişlemesi + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - Sürdürülebilir kod belirtiminde kısıtlanmış bir genel yapı oluştu + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - Sürdürülebilir kod belirtiminde 'let rec' oluştu + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - Aşağıdaki gerekli özelliklerin başlatılması gerekiyor:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - Geçersiz sürdürülebilir kod. Sürdürülebilir kod belirtiminde bir 'let rec' oluştu + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - Hata ayıklama türünü belirtin: full, portable, embedded, pdbonly. (Hata ayıklama türü belirtilmemişse '{0}' varsayılandır ve çalışan bir programa hata ayıklayıcı iliştirmeyi etkinleştirir. 'portable' bir çoklu platform biçimidir, 'embedded' çıkış dosyasına gömülü bir çoklu platform biçimidir). + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - Sunucuyla iletişimde bir sorun oluştuğu için yerleşik derleme hizmeti kullanılmadı. + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - Sağlanan türe statik bağımsız değişkenler uygulanırken bir hata oluştu + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - {0}' bütünleştirilmiş kodunun geçersiz '{1}' değerli TypeProviderAssembly özniteliği var. Bu değer geçerli bir bütünleştirilmiş kod adı olmalıdır + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - Sağlanan metoda statik bağımsız değişkenler uygulanırken bir sorun oluştu + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - {0}' parametresi için geçerli olan CallerMemberNameAttribute öğesinin hiçbir etkisi olmaz. CallerFilePathAttribute tarafından geçersiz kılındı. + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - Özel durum oluşturabilen bir kod bloğunu tanıtmak için kullanılır. with veya finally ile birlikte kullanılır. + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index c583e45c53d..cb58cfa5636 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -539,7 +539,7 @@ whitespace relaxation - 空格松弛法 + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 可恢复代码规范中发生受约束的泛型构造 + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - 可恢复代码规范中出现 "let rec" + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - 必须初始化以下必需属性: {0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 可恢复代码无效。可恢复代码规范中出现 "let rec" + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - 指定调试类型: full、portable、embedded、pdbonly。(若未指定调试类型,则默认为“{0}”,它允许将调试程序附加到正在运行的程序。"portable" 是跨平台格式,"embedded" 是嵌入到输出文件中的跨平台格式)。 + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 未使用驻留编译服务,因为与服务器通信时发生问题。 + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - 将静态参数应用于所提供类型时发生错误 + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 程序集“{0}”的 TypeProviderAssembly 特性具有无效值“{1}”。该值应为有效的程序集名称 + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - 将静态参数应用于提供的方法时发生错误 + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 应用于参数“{0}”的 CallerMemberNameAttribute 不会起作用。它已由 CallerFilePathAttribute 替代。 + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 用于引入可能产生异常的代码块。与 with 或 finally 配合使用。 + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 17fc8934c3c..ffd023a8af3 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -539,7 +539,7 @@ whitespace relaxation - 空白字元放寬 + whitespace relaxation @@ -1124,7 +1124,7 @@ A constrained generic construct occurred in the resumable code specification - 可繼續的程式碼規格中出現了限制式泛型建構 + A constrained generic construct occurred in the resumable code specification @@ -1139,7 +1139,7 @@ A 'let rec' occurred in the resumable code specification - 可繼續的程式碼規格中發生 'let rec' + A 'let rec' occurred in the resumable code specification @@ -1444,7 +1444,7 @@ The following required properties have to be initialized:{0} - 下列必要的屬性必須初始化:{0} + The following required properties have to be initialized:{0} @@ -1569,7 +1569,7 @@ Invalid resumable code. A 'let rec' occurred in the resumable code specification - 可繼續的程式碼無效。可繼續的程式碼規格中發生 'let rec' + Invalid resumable code. A 'let rec' occurred in the resumable code specification @@ -5889,7 +5889,7 @@ Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). - 指定偵錯類型: full、portable、embedded、pdbonly。(如果未指定偵錯類型,即預設為 '{0}',並允許將偵錯工具附加到正在執行的程式,'portable' 為跨平台格式,'embedded' 為輸出檔案內嵌的跨平台格式)。 + Specify debugging type: full, portable, embedded, pdbonly. ('{0}' is the default if no debugging 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). @@ -7144,7 +7144,7 @@ The resident compilation service was not used because a problem occurred in communicating with the server. - 未使用常駐編譯服務,因為伺服器發生通訊問題。 + The resident compilation service was not used because a problem occurred in communicating with the server. @@ -7344,7 +7344,7 @@ An error occurred applying the static arguments to a provided type - 將靜態引數套用至提供的類型時發生錯誤 + An error occurred applying the static arguments to a provided type @@ -7409,7 +7409,7 @@ Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name - 組件 '{0}' 的 TypeProviderAssembly 屬性值 '{1}' 無效。此值必須是有效的屬性名稱 + Assembly '{0}' has TypeProviderAssembly attribute with invalid value '{1}'. The value should be a valid assembly name @@ -7994,7 +7994,7 @@ An error occurred applying the static arguments to a provided method - 將靜態引數套用至所提供的方法時,發生錯誤 + An error occurred applying the static arguments to a provided method @@ -8124,7 +8124,7 @@ The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. - 套用至參數 '{0}' 的 CallerMemberNameAttribute 將不會有作用。CallerFilePathAttribute 會加以覆寫。 + The CallerMemberNameAttribute applied to parameter '{0}' will have no effect. It is overridden by the CallerFilePathAttribute. @@ -8439,7 +8439,7 @@ Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. - 用於引入可能會產生例外狀況的程式碼區塊。這會與 with 或 finally 並用。 + Used to introduce a block of code that might generate an exception. Used together with 'with' or 'finally'. diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf index 810091c59f0..86a6be9d7e0 100644 --- a/src/Compiler/xlf/FSStrings.cs.xlf +++ b/src/Compiler/xlf/FSStrings.cs.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - {0} {1} se nedá definovat, protože název {2} a {3} {4} v tomto typu nebo modulu jsou v konfliktu. + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf index 12a7cc8d720..3b7f46a9769 100644 --- a/src/Compiler/xlf/FSStrings.de.xlf +++ b/src/Compiler/xlf/FSStrings.de.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - {0} "{1}" kann nicht definiert werden, weil der Name "{2}" einen Konflikt mit {3} "{4}" in diesem Typ oder Modul verursacht. + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf index 85b2e6b1cd4..f2b6d8ed1ca 100644 --- a/src/Compiler/xlf/FSStrings.es.xlf +++ b/src/Compiler/xlf/FSStrings.es.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - No se puede definir el {0} '{1}' porque el nombre '{2}' está en conflicto con el {3} '{4}' de este tipo o módulo. + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf index b3627df28f8..f3621e55e63 100644 --- a/src/Compiler/xlf/FSStrings.fr.xlf +++ b/src/Compiler/xlf/FSStrings.fr.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - Impossible de définir le {0} '{1}', car le nom '{2}' est en conflit avec le {3} '{4}' dans ce type ou module + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf index b042d7704b2..d67bbd27dca 100644 --- a/src/Compiler/xlf/FSStrings.it.xlf +++ b/src/Compiler/xlf/FSStrings.it.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - Non è possibile definire {0} '{1}' perché il nome '{2}' è in conflitto con {3} '{4}' in questo tipo o modulo + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf index 3b9c4d98e21..486c2fac349 100644 --- a/src/Compiler/xlf/FSStrings.ja.xlf +++ b/src/Compiler/xlf/FSStrings.ja.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 名前 '{2}' がこの型またはモジュールの {3} '{4}' と競合するため、{0} '{1}' を定義できません + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf index 51c8cb1365f..506b9b9e2de 100644 --- a/src/Compiler/xlf/FSStrings.ko.xlf +++ b/src/Compiler/xlf/FSStrings.ko.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 이름 '{2}'이(가) 이 형식 또는 모듈의 {3} '{4}'과(와) 충돌하므로 {0} '{1}'을(를) 정의할 수 없습니다. + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf index 29e36ab5bc9..30f8155bfc8 100644 --- a/src/Compiler/xlf/FSStrings.pl.xlf +++ b/src/Compiler/xlf/FSStrings.pl.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - Nie można zdefiniować elementu {0} „{1}”, ponieważ nazwa „{2}” powoduje konflikt z elementem {3} „{4}” w tym typie lub module + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf index b606d7339c5..cf7e3a94822 100644 --- a/src/Compiler/xlf/FSStrings.pt-BR.xlf +++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - O {0} '{1}' não pode ser definido porque o nome '{2}' conflita com {3} '{4}' neste tipo ou módulo + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf index 6367fb6f835..34278a4b234 100644 --- a/src/Compiler/xlf/FSStrings.ru.xlf +++ b/src/Compiler/xlf/FSStrings.ru.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - {0} "{1}" не удается определить, так как имя "{2}" конфликтует с {3} "{4}" в данном типе или модуле + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf index 029b16cd9b5..a2601885c52 100644 --- a/src/Compiler/xlf/FSStrings.tr.xlf +++ b/src/Compiler/xlf/FSStrings.tr.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - {2}' adı bu türde veya modülde {3} '{4}' ile çakıştığı için {0} '{1}' tanımlanamıyor + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf index 54599b23672..66a54f3d2bb 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 无法定义 {0}“{1}”,因为名称“{2}”与此类型或模块中的 {3}“{4}”冲突 + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf index c200aa576c1..35280cee60f 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf @@ -204,7 +204,7 @@ The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module - 無法定義 {0} '{1}',因為名稱 '{2}' 與這個類型或模組中的 {3} '{4}' 相衝突 + The {0} '{1}' cannot be defined because the name '{2}' clashes with the {3} '{4}' in this type or module diff --git a/src/FSharp.Core/xlf/FSCore.cs.xlf b/src/FSharp.Core/xlf/FSCore.cs.xlf index 436ba705358..a122fa694dd 100644 --- a/src/FSharp.Core/xlf/FSCore.cs.xlf +++ b/src/FSharp.Core/xlf/FSCore.cs.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Dynamickému formátovacímu modulu byla předána chybná celočíselná hodnota. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Chybný specifikátor formátu (přesnost) + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.de.xlf b/src/FSharp.Core/xlf/FSCore.de.xlf index df2b28aaecb..28ad0276d47 100644 --- a/src/FSharp.Core/xlf/FSCore.de.xlf +++ b/src/FSharp.Core/xlf/FSCore.de.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Für den dynamischen Formatierer wurde ein ungültiger Integer bereitgestellt. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Ungültiger Formatbezeichner (precision) + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.es.xlf b/src/FSharp.Core/xlf/FSCore.es.xlf index a1e7d0f7fa8..55f8c1c965d 100644 --- a/src/FSharp.Core/xlf/FSCore.es.xlf +++ b/src/FSharp.Core/xlf/FSCore.es.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Se proporcionó un entero incorrecto a un formateador dinámico. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Especificador de formato incorrecto (precisión). + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.fr.xlf b/src/FSharp.Core/xlf/FSCore.fr.xlf index ff8acfc83c4..a7499ae558b 100644 --- a/src/FSharp.Core/xlf/FSCore.fr.xlf +++ b/src/FSharp.Core/xlf/FSCore.fr.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Entier incorrect fourni au formateur dynamique + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Spécificateur de format incorrect (précision) + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.it.xlf b/src/FSharp.Core/xlf/FSCore.it.xlf index 3643c1ce16c..a4abe452956 100644 --- a/src/FSharp.Core/xlf/FSCore.it.xlf +++ b/src/FSharp.Core/xlf/FSCore.it.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Intero non valido fornito al formattatore dinamico + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Identificatore di formato non valido (precision) + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.ja.xlf b/src/FSharp.Core/xlf/FSCore.ja.xlf index 285dfb02872..147f7c018cd 100644 --- a/src/FSharp.Core/xlf/FSCore.ja.xlf +++ b/src/FSharp.Core/xlf/FSCore.ja.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - 動的フォーマッタに対して指定された整数が正しくありません + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 書式指定子 (精度) が正しくありません + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.ko.xlf b/src/FSharp.Core/xlf/FSCore.ko.xlf index e5a88b267b0..8341b342f7a 100644 --- a/src/FSharp.Core/xlf/FSCore.ko.xlf +++ b/src/FSharp.Core/xlf/FSCore.ko.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - 동적 포맷터에 제공된 정수가 잘못되었습니다. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 잘못된 형식 지정자(전체 자릿수) + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.pl.xlf b/src/FSharp.Core/xlf/FSCore.pl.xlf index a64948b4609..6ddd003084a 100644 --- a/src/FSharp.Core/xlf/FSCore.pl.xlf +++ b/src/FSharp.Core/xlf/FSCore.pl.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Do dynamicznego modułu formatującego została przekazana błędna liczba całkowita. + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Błędny specyfikator formatu (dokładności). + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.pt-BR.xlf b/src/FSharp.Core/xlf/FSCore.pt-BR.xlf index 591a8e6560f..956db72820d 100644 --- a/src/FSharp.Core/xlf/FSCore.pt-BR.xlf +++ b/src/FSharp.Core/xlf/FSCore.pt-BR.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Inteiro incorreto fornecido a formatador dinâmico + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Especificador de formato incorreto (precisão) + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.ru.xlf b/src/FSharp.Core/xlf/FSCore.ru.xlf index edb281a0102..cb0ca39bd08 100644 --- a/src/FSharp.Core/xlf/FSCore.ru.xlf +++ b/src/FSharp.Core/xlf/FSCore.ru.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Динамическому форматтеру передано неверное целое + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Неверный спецификатор формата (точность) + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.tr.xlf b/src/FSharp.Core/xlf/FSCore.tr.xlf index d0ab6c80129..b4c445d67ee 100644 --- a/src/FSharp.Core/xlf/FSCore.tr.xlf +++ b/src/FSharp.Core/xlf/FSCore.tr.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - Dinamik biçimlendiriciye yanlış tamsayı sağlandı + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - Hatalı biçim belirticisi (duyarlık) + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.zh-Hans.xlf b/src/FSharp.Core/xlf/FSCore.zh-Hans.xlf index 498188f67af..dc922154be2 100644 --- a/src/FSharp.Core/xlf/FSCore.zh-Hans.xlf +++ b/src/FSharp.Core/xlf/FSCore.zh-Hans.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - 提供给动态格式化程序的整数错误 + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 错误的格式说明符(精度) + Bad format specifier (precision) diff --git a/src/FSharp.Core/xlf/FSCore.zh-Hant.xlf b/src/FSharp.Core/xlf/FSCore.zh-Hant.xlf index 7e5727be136..9d2cb35be7a 100644 --- a/src/FSharp.Core/xlf/FSCore.zh-Hant.xlf +++ b/src/FSharp.Core/xlf/FSCore.zh-Hant.xlf @@ -564,7 +564,7 @@ Bad integer supplied to dynamic formatter - 提供給動態格式器的整數錯誤 + Bad integer supplied to dynamic formatter @@ -594,7 +594,7 @@ Bad format specifier (precision) - 不正確的格式修飾詞 (精確度) + Bad format specifier (precision) diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf index 2f9b9728cd8..800c2e40248 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.cs.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager se nemůže odkazovat na systémový balíček {0}. + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf index 233c6a93dd3..f3762130515 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.de.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager kann nicht auf das Systempaket "{0}" verweisen. + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf index 2f7b192634c..2851c230dab 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.es.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager no puede hacer referencia al paquete del sistema "{0}". + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf index 5d83dfd795a..8ab1dccc35f 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.fr.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager ne peut pas référencer le package système '{0}' + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf index 9a40ea0246c..c605c4af3ba 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.it.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager non può fare riferimento al pacchetto di sistema '{0}' + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf index 74a4a7a452c..2e19d06a10f 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ja.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager がシステム パッケージ '{0}' を参照できません + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf index 9837ed7ad3a..01d252b6243 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ko.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager에서 시스템 패키지 '{0}'을(를) 참조할 수 없습니다. + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf index 6b7b5475c99..4ae0d2e448e 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pl.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - Program PacketManager nie może odwoływać się do pakietu systemowego „{0}” + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf index 2fb1ed02a8a..7e8409fd8d7 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.pt-BR.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager não pode referenciar o pacote do sistema '{0}' + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf index c1193b57c8b..dafbfb8243d 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.ru.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager не может ссылаться на системный пакет "{0}" + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf index 5a870233d01..312793af714 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.tr.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager, '{0}' Sistem Paketine başvuramıyor + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf index 520ae8c35a4..7e04d921b0a 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hans.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager 无法引用系统包“{0}” + PackageManager cannot reference the System Package '{0}' diff --git a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf index e8bde94aaff..d82293b0cf2 100644 --- a/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf +++ b/src/FSharp.DependencyManager.Nuget/xlf/FSDependencyManager.txt.zh-Hant.xlf @@ -4,7 +4,7 @@ PackageManager cannot reference the System Package '{0}' - PackageManager 無法參考系統套件 '{0}' + PackageManager cannot reference the System Package '{0}' diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.cs.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.cs.xlf index d43dc577c61..b969107b017 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.cs.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.cs.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - Můžete upravit obsah elementu pole pomocí operátoru přiřazení s šipkou doleva. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - Rozlišované sjednocení může také představovat hodnotu hrací karty. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - Při vyjadřování dat se běžně používají záznamy i rozlišovaná sjednocení. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Rozlišovaná sjednocení podporují i rekurzivní definice. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf index a8a789025d7..e2023a345a0 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.de.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - Sie können die Inhalte eines Arrayelements mithilfe des Zuweisungsoperators "Pfeil nach links" ändern. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - Eine diskriminierte Union kann auch verwendet werden, um den Rang einer Spielkarte darzustellen. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - Beim Darstellen von Daten werden häufig sowohl Datensätze als auch diskriminierte Unions verwendet. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Diskriminierte Unions unterstützen auch rekursive Definitionen. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.es.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.es.xlf index 3041197dd6c..ce9964fbe25 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.es.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.es.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - Puede modificar el contenido de un elemento de matriz mediante el operador de asignación de flecha izquierda. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - También se puede usar una unión discriminada para representar el rango de una carta. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - Es habitual utilizar tanto registros como uniones discriminadas cuando se representan datos. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Las uniones discriminadas admiten también definiciones recursivas. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.fr.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.fr.xlf index 79b126ad3f4..3c515e263e8 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.fr.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.fr.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - Vous pouvez modifier le contenu d'un élément de tableau à l'aide de l'opérateur d'assignation flèche gauche. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - Une union discriminée peut également servir à représenter le rang d'une carte à jouer. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - Il est fréquent d'utiliser à la fois des enregistrements et des unions discriminées pour représenter des données. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Les unions discriminées prennent également en charge les définitions récursives. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf index 5b17d36350e..79c43274cc4 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.it.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - È possibile modificare il contenuto di un elemento di matrice usando l'operatore di assegnazione freccia sinistra. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - È possibile usare un'unione discriminata anche per rappresentare il valore di una carta da gioco. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - Per la rappresentazione dei dati si usano in genere record e unioni discriminate. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Le unioni discriminate supportano anche definizioni ricorsive. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf index 3275255ba6a..33ba6422ea1 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ja.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 左矢印代入演算子を使用して、配列要素の内容を変更できます。 + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 判別共用体はトランプのランクを表すためにも使用できます。 + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - データを表すときには、レコードと判別共用体の両方を使用するのが一般的です。 + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - 判別共用体は再帰的な定義もサポートしています。 + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf index f6668949ef9..c5f198ffa1b 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ko.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 왼쪽 화살표 대입 연산자를 사용하여 배열 요소의 내용을 수정할 수 있습니다. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 구분된 공용 구조체를 사용하여 플레잉 카드의 순위를 나타낼 수도 있습니다. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - 일반적으로 레코드와 구분된 공용 구조체를 모두 사용하여 데이터를 나타냅니다. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - 구분된 공용 구조체는 재귀 정의도 지원합니다. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pl.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pl.xlf index 80135046c87..5bdcd939c42 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pl.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pl.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - Możesz zmodyfikować zawartość elementu tablicy za pomocą operatora przypisania „strzałka w lewo”. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - Unii rozłącznej można również użyć do reprezentowania wartości karty do gry. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - Często używa się rekordów i unii rozłącznych w przypadku reprezentowania danych. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Unie rozłączne obsługują również definicje rekursywne. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf index 433113974ba..736952384fc 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.pt-BR.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - Você pode modificar o conteúdo de um elemento de matriz usando o operador de atribuição de seta para a esquerda. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - Uma União Discriminada também pode ser usada para representar a classificação de uma carta de baralho. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - É comum usar Registros e Uniões Discriminadas ao representar dados. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Uniões Discriminadas também dão suporte a definições recursivas. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ru.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ru.xlf index 21d0c088dd7..85b57d7d25a 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ru.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.ru.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - Изменить содержимое элемента массива можно с помощью оператора присваивания в виде стрелки влево. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - Размеченное объединение также может использоваться для представления ранга игральной карты. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - Как правило, при представлении данных используются как записи, так и размеченные объединения. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Размеченные объединения также поддерживают рекурсивные определения. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf index e16ddac1fd6..31a61d248a3 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.tr.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - Bir dizi öğesinin içeriğini sol ok atama işlecini kullanarak değiştirebilirsiniz. + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - Bir iskambil kartının sırasını göstermek için bir Ayırt Edici Birleşim de kullanılabilir. + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - Verileri temsil ederken Kayıtları ve Ayırt Edici Birleşimleri birlikte kullanmak yaygındır. + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - Ayırt Edici Birleşimler ayrıca özyinelemeli tanımları da destekler. + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf index 070f72756fa..3520e8975c5 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hans.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 可使用左箭头赋值运算符来修改数组元素的内容。 + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 可区分联合还可用来表示纸牌的设置级别。 + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - 表示数据时同时使用记录和可区分联合是很常见的。 + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - 可区分联合还支持递归定义。 + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf index 9dc5b4cb19b..ceef6ffcd83 100644 --- a/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf +++ b/vsintegration/ProjectTemplates/TutorialProject/Template/xlf/Tutorial.fsx.zh-Hant.xlf @@ -744,7 +744,7 @@ You can modify the contents of an array element by using the left arrow assignment operator. - 您可以使用向左鍵指派運算子來修改陣列元素的內容。 + You can modify the contents of an array element by using the left arrow assignment operator. @@ -1009,7 +1009,7 @@ A Discriminated Union can also be used to represent the rank of a playing card. - 差異聯集也可用以代表一張撲克牌的順位。 + A Discriminated Union can also be used to represent the rank of a playing card. @@ -1029,7 +1029,7 @@ It's common to use both Records and Discriminated Unions when representing data. - 代表資料時,通常會使用記錄與差異聯集。 + It's common to use both Records and Discriminated Unions when representing data. @@ -1089,7 +1089,7 @@ Discriminated Unions also support recursive definitions. - 差異聯集也支援遞迴定義。 + Discriminated Unions also support recursive definitions. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf index 918eaa00dd1..03000fae564 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.cs.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - Soubor {0} se nedá uložit, protože není otevřený v editoru. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf index 2e55caa77b9..6fad4701b9b 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.de.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - {0} kann nicht gespeichert werden, da sie nicht im Editor geöffnet ist. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf index 653231ad5ac..be43129d5dd 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.es.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - No se puede guardar '{0}' mientras no esté abierto en el editor. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf index e9adf9f0495..d39840bf98d 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.fr.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - Impossible d'enregistrer '{0}', car il n'est pas ouvert dans l'éditeur. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf index 898ffd57a94..a670ee0b5eb 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.it.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - Non è possibile salvare '{0}' perché non è aperto nell'editor. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf index 083d889314f..71c72fab37b 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ja.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - '{0}' はエディターで開かれていないため、保存できません。 + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf index 55f3e53d51b..fe6c1427f3a 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ko.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - '{0}'은(는) 편집기에 열려 있지 않으므로 저장할 수 없습니다. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf index 18625d46839..c04569fb685 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pl.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - Nie można zapisać pliku „{0}”, ponieważ nie jest on otwarty w edytorze. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf index 9fa73a42708..3675c79cfac 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.pt-BR.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - Não é possível salvar '{0}' porque não está aberto no editor. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf index 72a92f4a0da..05086731665 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.ru.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - Не удается сохранить "{0}": файл не открыт в редакторе. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf index 54aaf598233..0951ab5fd9c 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.tr.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - '{0}' düzenleyicide açık olmadığından kaydedilemedi. + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf index ab86371cb21..43915ea3d1b 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hans.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - 无法保存“{0}”,因为它未在编辑器中打开。 + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf index c0d9d60d48c..e1e78242403 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.Base/xlf/Microsoft.VisualStudio.Package.Project.zh-Hant.xlf @@ -79,7 +79,7 @@ Cannot save '{0}' as it is not open in the editor. - 因為 '{0}' 不是在編輯器中開啟的,所以無法儲存。 + Cannot save '{0}' as it is not open in the editor. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.cs.xlf index d21bda7ce61..25314d551e8 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.cs.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.cs.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - Pro zobrazení operací služby vyberte její kontrakt. + Pro zobrazení operací služby vyberte její kontrakt. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.de.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.de.xlf index 8708f62ecc4..26a027b9373 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.de.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - Wählen Sie einen Dienstvertrag aus, um seine Abläufe anzuzeigen. + Wählen Sie einen Dienstvertrag aus, um seine Abläufe anzuzeigen. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.es.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.es.xlf index 38b3575e7b2..f3cc2f9d02f 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.es.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.es.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - Seleccione un contrato de servicio para ver sus operaciones. + Seleccione un contrato de servicio para ver sus operaciones. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.fr.xlf index 114ba9c1282..45939fa9731 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.fr.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - Sélectionnez un contrat de service pour afficher ses opérations. + Sélectionnez un contrat de service pour afficher ses opérations. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.it.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.it.xlf index 21ad2a8ed21..0c089a12fad 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.it.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.it.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - Selezionare un contratto di servizio per visualizzarne le operazioni. + Selezionare un contratto di servizio per visualizzarne le operazioni. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf index c9eb3786c4e..a8cf12c61fc 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ja.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - サービス コントラクトを選択して操作を表示します。 + サービス コントラクトを選択して操作を表示します。 This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf index 4034e9c1db5..1e50815dd99 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ko.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - 서비스 계약을 선택하여 해당 작업을 확인하세요. + 서비스 계약을 선택하여 해당 작업을 확인하세요. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pl.xlf index 617b27ff745..3bba978e142 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pl.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pl.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - Wybierz kontrakt usługi, aby wyświetlić jego operacje. + Wybierz kontrakt usługi, aby wyświetlić jego operacje. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pt-BR.xlf index 3192d1ed7d5..a4409c25843 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pt-BR.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.pt-BR.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - Selecione um contrato de serviço para exibir as operações. + Selecione um contrato de serviço para exibir as operações. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ru.xlf index 0452ba7258a..59ca2f46eed 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ru.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.ru.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - Чтобы просмотреть операции службы, выберете контракт службы. + Чтобы просмотреть операции службы, выберете контракт службы. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.tr.xlf index 26d060af8d0..e701e4334aa 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.tr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.tr.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - İşlemlerini görüntülemek için bir hizmet sözleşmesi seçin. + İşlemlerini görüntülemek için bir hizmet sözleşmesi seçin. This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hans.xlf index cbdbf10daa2..a0d96560d7e 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hans.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hans.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - 选择服务协定可查看其操作。 + 选择服务协定可查看其操作。 This is the message displayed when user selects non-contract nodes. diff --git a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf index 7c896bf2e6c..bfc580c97b4 100644 --- a/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.PropertyPages/Resources/xlf/WCF.zh-Hant.xlf @@ -159,7 +159,7 @@ Select a service contract to view its operations. - 選取要檢視其作業的服務合約。 + 選取要檢視其作業的服務合約。 This is the message displayed when user selects non-contract nodes. From 5236b25328e58c4b66e98ac1312bfd360e54f989 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Wed, 31 Jul 2024 04:24:46 -0700 Subject: [PATCH 05/13] Fixes #17447 -MethodAccessException on equality comparison of a record with private fields (#17467) * Fix17447 * tests + readme --- .../Checking/AugmentWithHashCompare.fs | 4 +- .../GenericComparison/CrossAssembly.fs | 272 ++++++++++++++---- .../GenericComparison/GenericComparison.fs | 1 - tests/FSharp.Test.Utilities/Compiler.fs | 6 + 4 files changed, 220 insertions(+), 63 deletions(-) diff --git a/src/Compiler/Checking/AugmentWithHashCompare.fs b/src/Compiler/Checking/AugmentWithHashCompare.fs index 4326ac6ccfc..acdddf84258 100644 --- a/src/Compiler/Checking/AugmentWithHashCompare.fs +++ b/src/Compiler/Checking/AugmentWithHashCompare.fs @@ -1333,7 +1333,7 @@ let MakeValsForEqualsAugmentation g (tcref: TyconRef) = g tcref ty - vis + tcref.Accessibility (if tcref.Deref.IsFSharpException then None else @@ -1376,7 +1376,7 @@ let MakeValsForEqualityWithComparerAugmentation g (tcref: TyconRef) = g tcref ty - vis + tcref.Accessibility // This doesn't implement any interface. None "Equals" diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/CrossAssembly.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/CrossAssembly.fs index 8e2cd0853c0..a93d48635fe 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/CrossAssembly.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/CrossAssembly.fs @@ -7,87 +7,239 @@ open FSharp.Test.Compiler module GenericComparisonCrossAssembly = - [] - let ``fslib``() = + [] // RealSig + [] // Regular + [] + let ``fslib``(realsig) = FSharpWithFileName "Program.fs" """ ValueSome (1, 2) = ValueSome (2, 3) |> ignore""" + |> withRealInternalSignature realsig |> withOptimize |> compileExeAndRun |> shouldSucceed |> verifyIL [ """ - .method assembly specialname static void staticInitialization@() cil managed - { - - .maxstack 8 - IL_0000: ldc.i4.1 - IL_0001: ldc.i4.2 - IL_0002: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, - !1) - IL_0007: call valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1>::NewValueSome(!0) - IL_000c: stsfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1> Program::x@1 - IL_0011: ldc.i4.2 - IL_0012: ldc.i4.3 - IL_0013: newobj instance void class [runtime]System.Tuple`2::.ctor(!0, - !1) - IL_0018: call valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1 valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1>::NewValueSome(!0) - IL_001d: stsfld valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1> Program::y@1 - IL_0022: ldsflda valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1> Program::x@1 - IL_0027: call valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1> Program::get_y@1() IL_002c: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() IL_0031: call instance bool valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1>::Equals(valuetype [FSharp.Core]Microsoft.FSharp.Core.FSharpValueOption`1, - class [runtime]System.Collections.IEqualityComparer) - IL_0036: stsfld bool Program::arg@1 - IL_003b: ret - } """ ] - [] - let ``Another assembly``() = - let module1 = + [] // RealSig + [] // Regular + [] + let ``Another Assembly - record with private fields`` (realsig) = + let library = FSharpWithFileName "Module1.fs" """ module Module1 - [] - type Struct(v: int, u: int) = - member _.V = v - member _.U = u """ +type Value = + private { value: uint32 } + + static member Zero = { value = 0u } + static member Create(value: int) = { value = uint value } """ + |> withRealInternalSignature realsig |> withOptimize |> asLibrary |> withName "module1" - let module2 = + let mainModule = FSharpWithFileName "Program.fs" - """ -Module1.Struct(1, 2) = Module1.Struct(2, 3) |> ignore""" + $""" +open Module1 +Value.Zero = Value.Create 0 |> ignore""" - module2 - |> withReferences [module1] + mainModule + |> withRealInternalSignature realsig + |> withReferences [ library ] + |> compileExeAndRun + |> shouldSucceed + + [] // Legacy, private WrapType, private visibility in IL + [] // RealSig, internal WrapType, assembly visibility in IL + [] // Legacy, public WrapType, public visibility in IL + [] // RealSig, private WrapType, private visibility in IL + [] // RealSig, internal WrapType, assembly visibility in IL + [] // RealSig, public WrapType, public visibility in IL + [] + let ``Generated typed Equals`` (realsig, typeScope, targetVisibility) = + let library = + FSharpWithFileName "Program.fs" + $""" +module Module1 = + + [] + type {typeScope} Struct(v: int, u: int) = + member _.V = v + member _.U = u""" + + library + |> asExe + |> withNoWarn 988 + |> withRealInternalSignature realsig |> withOptimize + |> compile + |> shouldSucceed + |> verifyIL [ + $""" + .method {targetVisibility} hidebysig instance bool + Equals(valuetype Program/Module1/Struct obj, + class [runtime]System.Collections.IEqualityComparer comp) cil managed + {{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 Program/Module1/Struct::v + IL_0006: ldarga.s obj + IL_0008: ldfld int32 Program/Module1/Struct::v + IL_000d: bne.un.s IL_001f + + IL_000f: ldarg.0 + IL_0010: ldfld int32 Program/Module1/Struct::u + IL_0015: ldarga.s obj + IL_0017: ldfld int32 Program/Module1/Struct::u + IL_001c: ceq + IL_001e: ret + + IL_001f: ldc.i4.0 + IL_0020: ret + }} """ ] + + + [] // Legacy, private record fields, private visibility in IL + [] // RealSig, internal record fields, assembly visibility in IL + [] // Legacy, public record fields, public visibility in IL + [] // RealSig, private record fields, private visibility in IL + [] // RealSig, internal record fields, assembly visibility in IL + [] // RealSig, public record fields, public visibility in IL + [] + let ``Record with various fields`` (realsig, fieldScope) = + + let mainModule = + FSharpWithFileName "Program.fs" + $""" +module Module1 = + type Value = + {fieldScope} {{ value: uint32 }} + + static member Zero = {{ value = 0u }} + static member Create(value: int) = {{ value = uint value }} + + Value.Zero = Value.Create 0 |> ignore + printfn "Hello, World" """ + + mainModule + |> withRealInternalSignature realsig |> compileExeAndRun |> shouldSucceed - |> verifyIL [ """ - .method assembly specialname static void staticInitialization@() cil managed - { - - .maxstack 8 - IL_0000: ldc.i4.1 - IL_0001: ldc.i4.2 - IL_0002: newobj instance void [module1]Module1/Struct::.ctor(int32, - int32) - IL_0007: stsfld valuetype [module1]Module1/Struct Program::x@1 - IL_000c: ldc.i4.2 - IL_000d: ldc.i4.3 - IL_000e: newobj instance void [module1]Module1/Struct::.ctor(int32, - int32) - IL_0013: stsfld valuetype [module1]Module1/Struct Program::y@1 - IL_0018: ldsflda valuetype [module1]Module1/Struct Program::x@1 - IL_001d: call valuetype [module1]Module1/Struct Program::get_y@1() - IL_0022: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0027: call instance bool [module1]Module1/Struct::Equals(valuetype [module1]Module1/Struct, - class [runtime]System.Collections.IEqualityComparer) - IL_002c: stsfld bool Program::arg@1 - IL_0031: ret - } -""" ] + |> verifyIL [ + """ + .method public hidebysig virtual final instance bool Equals(class Program/Module1/Value obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0017 + + IL_0003: ldarg.1 + IL_0004: brfalse.s IL_0015 + + IL_0006: ldarg.0 + IL_0007: ldfld uint32 Program/Module1/Value::value@ + IL_000c: ldarg.1 + IL_000d: ldfld uint32 Program/Module1/Value::value@ + IL_0012: ceq + IL_0014: ret + + IL_0015: ldc.i4.0 + IL_0016: ret + + IL_0017: ldarg.1 + IL_0018: ldnull + IL_0019: cgt.un + IL_001b: ldc.i4.0 + IL_001c: ceq + IL_001e: ret + } """ + """ + IL_0020: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0025: callvirt instance bool Program/Module1/Value::Equals(class Program/Module1/Value, + class [runtime]System.Collections.IEqualityComparer) + """ ] + + + [] // Legacy, private WrapType, private visibility in IL + [] // RealSig, internal WrapType, assembly visibility in IL + [] // Legacy, public WrapType, public visibility in IL + [] // RealSig, private WrapType, private visibility in IL + [] // RealSig, internal WrapType, assembly visibility in IL + [] // RealSig, public WrapType, public visibility in IL + [] + let ``scoped type arg`` (realsig, argScope, targetVisibility) = + let mainModule = + FSharpWithFileName "Program.fs" + $""" +module IPartialEqualityComparer = + open System.Collections.Generic + + [] + type {argScope} WrapType<'T> = Wrap of 'T +""" + mainModule + |> asExe + |> withNoWarn 988 + |> withRealInternalSignature realsig + |> withOptimize + |> compile + |> shouldSucceed + |> verifyIL [ + $""" + .method {targetVisibility} hidebysig instance bool + Equals(class Program/IPartialEqualityComparer/WrapType`1 obj, + class [runtime]System.Collections.IEqualityComparer comp) cil managed + {{ + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 5 + .locals init (class Program/IPartialEqualityComparer/WrapType`1 V_0, + class Program/IPartialEqualityComparer/WrapType`1 V_1, + !T V_2, + !T V_3) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_0027 + + IL_0003: ldarg.1 + IL_0004: brfalse.s IL_0025 + + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: stloc.0 + IL_000a: ldarg.1 + IL_000b: stloc.1 + IL_000c: ldloc.0 + IL_000d: ldfld !0 class Program/IPartialEqualityComparer/WrapType`1::item + IL_0012: stloc.2 + IL_0013: ldloc.1 + IL_0014: ldfld !0 class Program/IPartialEqualityComparer/WrapType`1::item + IL_0019: stloc.3 + IL_001a: ldarg.2 + IL_001b: ldloc.2 + IL_001c: ldloc.3 + IL_001d: tail. + IL_001f: call bool [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives/HashCompare::GenericEqualityWithComparerIntrinsic(class [runtime]System.Collections.IEqualityComparer, + !!0, + !!0) + IL_0024: ret + + IL_0025: ldc.i4.0 + IL_0026: ret + + IL_0027: ldarg.1 + IL_0028: ldnull + IL_0029: cgt.un + IL_002b: ldc.i4.0 + IL_002c: ceq + IL_002e: ret + }} """ ] diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/GenericComparison.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/GenericComparison.fs index 2fd53e46b56..091817ee76d 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/GenericComparison.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/GenericComparison.fs @@ -85,7 +85,6 @@ module GenericComparison = |> verifyCompilation - // SOURCE=Hash01.fsx SCFLAGS="-a -g --optimize+" COMPILE_ONLY=1 POSTCMD="..\\CompareIL.cmd Hash01.dll" # Hash01.fs - [] let ``Hash01_fsx`` compilation = diff --git a/tests/FSharp.Test.Utilities/Compiler.fs b/tests/FSharp.Test.Utilities/Compiler.fs index 1cbf3a3aade..2f99ac52061 100644 --- a/tests/FSharp.Test.Utilities/Compiler.fs +++ b/tests/FSharp.Test.Utilities/Compiler.fs @@ -598,6 +598,12 @@ module rec Compiler = | FS fs -> FS { fs with Options = fs.Options @ ["--realsig+"] } | _ -> failwith "withRealInternalSignatureOn only supported by f#" + let withRealInternalSignature (realSig: bool) (cUnit: CompilationUnit) : CompilationUnit = + if realSig then + cUnit |> withRealInternalSignatureOn + else + cUnit |> withRealInternalSignatureOff + let asExe (cUnit: CompilationUnit) : CompilationUnit = withOutputType CompileOutput.Exe cUnit From d01da337822534b756e167238fe5f32c64375699 Mon Sep 17 00:00:00 2001 From: "Kevin Ransom (msft)" Date: Mon, 19 Aug 2024 02:57:18 -0700 Subject: [PATCH 06/13] fixes #17541 - Equals visibility for DU's (#17548) --- .../Checking/AugmentWithHashCompare.fs | 25 +++---- .../IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs | 4 +- .../Types/UnionTypes/UnionStructTypes.fs | 3 +- .../EmittedIL/ByRefTests.fs | 16 ++--- .../CCtorDUWithMember/CCtorDUWithMember.fs | 56 +++++++++++++++ .../GenericComparison/CrossAssembly.fs | 71 +++++++++---------- .../Equals16.fsx.il.net472.bsl | 16 ++--- .../Equals16.fsx.il.netcore.bsl | 16 ++--- .../Equals17.fsx.il.net472.bsl | 16 ++--- .../Equals17.fsx.il.netcore.bsl | 16 ++--- .../Equals18.fsx.il.net472.bsl | 20 ++---- .../Equals18.fsx.il.netcore.bsl | 16 ++--- tests/FSharp.Test.Utilities/ILChecker.fs | 9 +-- .../EmittedIL/ReferenceAssemblyTests.fs | 7 +- 14 files changed, 139 insertions(+), 152 deletions(-) diff --git a/src/Compiler/Checking/AugmentWithHashCompare.fs b/src/Compiler/Checking/AugmentWithHashCompare.fs index acdddf84258..5e66b087c56 100644 --- a/src/Compiler/Checking/AugmentWithHashCompare.fs +++ b/src/Compiler/Checking/AugmentWithHashCompare.fs @@ -1322,7 +1322,7 @@ let MakeValsForCompareWithComparerAugmentation g (tcref: TyconRef) = let MakeValsForEqualsAugmentation g (tcref: TyconRef) = let m = tcref.Range let _, ty = mkMinimalTy g tcref - let vis = tcref.TypeReprAccessibility + let vis = tcref.Accessibility let tps = tcref.Typars m let objEqualsVal = @@ -1333,7 +1333,7 @@ let MakeValsForEqualsAugmentation g (tcref: TyconRef) = g tcref ty - tcref.Accessibility + vis (if tcref.Deref.IsFSharpException then None else @@ -1347,16 +1347,13 @@ let MakeValsForEqualsAugmentation g (tcref: TyconRef) = let MakeValsForEqualityWithComparerAugmentation g (tcref: TyconRef) = let _, ty = mkMinimalTy g tcref - let vis = - // Equality method for union types match the union type visibility rather than the TypeReprAccessibility - if tcref.IsUnionTycon then tcref.Accessibility - else tcref.TypeReprAccessibility + let vis = tcref.Accessibility let tps = tcref.Typars tcref.Range let objGetHashCodeVal = mkValSpec g tcref ty vis (Some(mkGetHashCodeSlotSig g)) "GetHashCode" (tps +-> (mkHashTy g ty)) unitArg false - let withcGetHashCodeVal = + let withGetHashCodeVal = mkValSpec g tcref @@ -1368,27 +1365,27 @@ let MakeValsForEqualityWithComparerAugmentation g (tcref: TyconRef) = unaryArg false - let withcEqualsVal = + let withEqualsVal = mkValSpec g tcref ty vis (Some(mkIStructuralEquatableEqualsSlotSig g)) "Equals" (tps +-> (mkEqualsWithComparerTy g ty)) tupArg false - let withcEqualsValExact = + let withEqualsExactWithComparer = + let vis = TAccess (updateSyntaxAccessForCompPath (vis.CompilationPaths) SyntaxAccess.Public) mkValSpec g tcref ty - tcref.Accessibility + vis // This doesn't implement any interface. None "Equals" (tps +-> (mkEqualsWithComparerTyExact g ty)) tupArg false - { GetHashCode = objGetHashCodeVal - GetHashCodeWithComparer = withcGetHashCodeVal - EqualsWithComparer = withcEqualsVal - EqualsExactWithComparer = withcEqualsValExact + GetHashCodeWithComparer = withGetHashCodeVal + EqualsWithComparer = withEqualsVal + EqualsExactWithComparer = withEqualsExactWithComparer } let MakeBindingsForCompareAugmentation g (tycon: Tycon) = diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs index aa959306198..f546ef5de3e 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/TypeConstraints/IWSAMsAndSRTPs/IWSAMsAndSRTPsTests.fs @@ -769,9 +769,7 @@ let main _ = |> shouldSucceed |> verifyIL [ """ - .method public specialname static class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2 - '|IsEqual|IsNonEqual|'<(class [Potato]Potato.Lib/IPotato`1) T>(!!T x, - !!T y) cil managed + .method public specialname static class [FSharp.Core]Microsoft.FSharp.Core.FSharpChoice`2 '|IsEqual|IsNonEqual|'<(class [Potato]Potato.Lib/IPotato`1) T>(!!T x, !!T y) cil managed { .maxstack 8 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/UnionTypes/UnionStructTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/UnionTypes/UnionStructTypes.fs index 574f1695d62..55277618b1f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Types/UnionTypes/UnionStructTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Types/UnionTypes/UnionStructTypes.fs @@ -877,8 +877,7 @@ let main args = IL_0002: newobj instance void Foo/StructUnion::.ctor(int32) IL_0007: ret }""";(*This is a 'maker method' New{CaseName} used for cases which do have fields associated with them, + the _tag gets initialized*)""" - NewCase3(string _field1_3, - string _field2_3) cil managed + NewCase3(string _field1_3, string _field2_3) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 02 00 00 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ByRefTests.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ByRefTests.fs index ef8dbac0f0d..b0648b3037a 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ByRefTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ByRefTests.fs @@ -283,9 +283,7 @@ type C() = .get instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) Test/C::get_X() }""" - let verifyMethod = """.method public hidebysig specialname - instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) - get_X() cil managed + let verifyMethod = """.method public hidebysig specialname instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) get_X() cil managed { .param [0] .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" @@ -313,9 +311,7 @@ type C() = .get instance int32& modreq([netstandard]System.Runtime.InteropServices.InAttribute) Test/C::get_X() }""" - let verifyMethod = """.method public hidebysig specialname - instance int32& modreq([netstandard]System.Runtime.InteropServices.InAttribute) - get_X() cil managed + let verifyMethod = """.method public hidebysig specialname instance int32& modreq([netstandard]System.Runtime.InteropServices.InAttribute) get_X() cil managed { .param [0] .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" @@ -452,9 +448,7 @@ type C<'T>() = abstract X<'U> : unit -> inref<'U> """ - let verifyMethod = """.method public hidebysig abstract virtual - instance !!U& modreq([runtime]System.Runtime.InteropServices.InAttribute) - X() cil managed + let verifyMethod = """.method public hidebysig abstract virtual instance !!U& modreq([runtime]System.Runtime.InteropServices.InAttribute) X() cil managed { .param [0] .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" @@ -481,9 +475,7 @@ type C = .get instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) Test/C::get_X() }""" - let verifyMethod = """.method public hidebysig specialname abstract virtual - instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) - get_X() cil managed + let verifyMethod = """.method public hidebysig specialname abstract virtual instance int32& modreq([runtime]System.Runtime.InteropServices.InAttribute) get_X() cil managed { .param [0] .custom instance void [runtime]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 )""" diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/CCtorDUWithMember/CCtorDUWithMember.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CCtorDUWithMember/CCtorDUWithMember.fs index 248532a1638..8949bc912a2 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/CCtorDUWithMember/CCtorDUWithMember.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/CCtorDUWithMember/CCtorDUWithMember.fs @@ -146,3 +146,59 @@ type ILArrayShape = ] |> shouldSucceed + [] // RealSig + [] // Regular + [] + let ``private DU in module`` (realSig, expected) = + FSharp """ +module RealInternalSignature +module Module = + type private DU = ABC | YYZ + + let publicFunction () : bool = + ABC = YYZ + +Module.publicFunction () |> printfn "%b" +""" + |> asExe + |> withRealInternalSignature realSig + |> compileAndRun + |> withILContains [ + $$""" + .method {{expected}} hidebysig instance bool Equals(class RealInternalSignature/Module/DU obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 4 + .locals init (int32 V_0, + int32 V_1) + IL_0000: ldarg.0 + IL_0001: brfalse.s IL_001b + + IL_0003: ldarg.1 + IL_0004: brfalse.s IL_0019 + + IL_0006: ldarg.0 + IL_0007: ldfld int32 RealInternalSignature/Module/DU::_tag + IL_000c: stloc.0 + IL_000d: ldarg.1 + IL_000e: ldfld int32 RealInternalSignature/Module/DU::_tag + IL_0013: stloc.1 + IL_0014: ldloc.0 + IL_0015: ldloc.1 + IL_0016: ceq + IL_0018: ret + + IL_0019: ldc.i4.0 + IL_001a: ret + + IL_001b: ldarg.1 + IL_001c: ldnull + IL_001d: cgt.un + IL_001f: ldc.i4.0 + IL_0020: ceq + IL_0022: ret + } +""" + ] + |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/CrossAssembly.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/CrossAssembly.fs index a93d48635fe..d3a9e06a113 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/CrossAssembly.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/CrossAssembly.fs @@ -54,11 +54,11 @@ Value.Zero = Value.Create 0 |> ignore""" |> compileExeAndRun |> shouldSucceed - [] // Legacy, private WrapType, private visibility in IL + [] // Legacy, private WrapType, assembly visibility in IL [] // RealSig, internal WrapType, assembly visibility in IL [] // Legacy, public WrapType, public visibility in IL - [] // RealSig, private WrapType, private visibility in IL - [] // RealSig, internal WrapType, assembly visibility in IL + [] // RealSig, private WrapType, public visibility in IL + [] // RealSig, internal WrapType, public visibility in IL [] // RealSig, public WrapType, public visibility in IL [] let ``Generated typed Equals`` (realsig, typeScope, targetVisibility) = @@ -81,9 +81,7 @@ module Module1 = |> shouldSucceed |> verifyIL [ $""" - .method {targetVisibility} hidebysig instance bool - Equals(valuetype Program/Module1/Struct obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method {targetVisibility} hidebysig instance bool Equals(valuetype Program/Module1/Struct obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed {{ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -106,24 +104,24 @@ module Module1 = }} """ ] - [] // Legacy, private record fields, private visibility in IL - [] // RealSig, internal record fields, assembly visibility in IL - [] // Legacy, public record fields, public visibility in IL - [] // RealSig, private record fields, private visibility in IL - [] // RealSig, internal record fields, assembly visibility in IL - [] // RealSig, public record fields, public visibility in IL + [] // Legacy, private WrapType + [] // RealSig, internal WrapType + [] // Legacy, public WrapType + [] // RealSig, private WrapType + [] // RealSig, internal WrapType + [] // RealSig, public WrapType [] - let ``Record with various fields`` (realsig, fieldScope) = + let ``Record with various scoped fields`` (realsig, fieldScope) = let mainModule = FSharpWithFileName "Program.fs" - $""" + $$""" module Module1 = type Value = - {fieldScope} {{ value: uint32 }} + {{fieldScope}} { value: uint32 } - static member Zero = {{ value = 0u }} - static member Create(value: int) = {{ value = uint value }} + static member Zero = { value = 0u } + static member Create(value: int) = { value = uint value } Value.Zero = Value.Create 0 |> ignore printfn "Hello, World" """ @@ -134,7 +132,7 @@ module Module1 = |> shouldSucceed |> verifyIL [ """ - .method public hidebysig virtual final instance bool Equals(class Program/Module1/Value obj) cil managed + .method public hidebysig instance bool Equals(class Program/Module1/Value obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -161,26 +159,27 @@ module Module1 = IL_001b: ldc.i4.0 IL_001c: ceq IL_001e: ret - } """ - """ - IL_0020: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() - IL_0025: callvirt instance bool Program/Module1/Value::Equals(class Program/Module1/Value, - class [runtime]System.Collections.IEqualityComparer) - """ ] - - - [] // Legacy, private WrapType, private visibility in IL - [] // RealSig, internal WrapType, assembly visibility in IL - [] // Legacy, public WrapType, public visibility in IL - [] // RealSig, private WrapType, private visibility in IL - [] // RealSig, internal WrapType, assembly visibility in IL - [] // RealSig, public WrapType, public visibility in IL + } """ ] + + + [] // public module - Legacy, private WrapType, private visibility in IL + [] // public module - RealSig, internal WrapType, assembly visibility in IL + [] // public module - Legacy, public WrapType, public visibility in IL + [] // public module - RealSig, private WrapType, public visibility in IL + [] // public module - RealSig, internal WrapType, public visibility in IL + [] // public module - RealSig, public WrapType, public visibility in IL + [] // private module - Legacy, private WrapType, private visibility in IL + [] // private module - RealSig, internal WrapType, assembly visibility in IL + [] // private module - Legacy, public WrapType, assembly visibility in IL + [] // private module - RealSig, private WrapType, public visibility in IL + [] // private module - RealSig, internal WrapType, public visibility in IL + [] // private module - RealSig, public WrapType, public visibility in IL [] - let ``scoped type arg`` (realsig, argScope, targetVisibility) = + let ``scoped main and scoped type Equals`` (realsig, moduleScope, argScope, targetVisibility) = let mainModule = FSharpWithFileName "Program.fs" $""" -module IPartialEqualityComparer = +module {moduleScope} IPartialEqualityComparer = open System.Collections.Generic [] @@ -195,9 +194,7 @@ module IPartialEqualityComparer = |> shouldSucceed |> verifyIL [ $""" - .method {targetVisibility} hidebysig instance bool - Equals(class Program/IPartialEqualityComparer/WrapType`1 obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method {targetVisibility} hidebysig instance bool Equals(class Program/IPartialEqualityComparer/WrapType`1 obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed {{ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals16.fsx.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals16.fsx.il.net472.bsl index be3fd3e5662..8560c4bab9f 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals16.fsx.il.net472.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals16.fsx.il.net472.bsl @@ -128,9 +128,7 @@ IL_000c: ret } - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [runtime]System.Collections.IComparer comp) cil managed + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -235,9 +233,7 @@ IL_000b: ret } - .method assembly hidebysig instance bool - Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeStruct obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig instance bool Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeStruct obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -259,9 +255,7 @@ IL_0020: ret } - .method public hidebysig virtual final - instance bool Equals(object obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -285,9 +279,7 @@ IL_0019: ret } - .method public specialname rtspecialname - instance void .ctor(int32 v, - int32 u) cil managed + .method public specialname rtspecialname instance void .ctor(int32 v, int32 u) cil managed { .maxstack 8 diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals16.fsx.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals16.fsx.il.netcore.bsl index be3fd3e5662..8560c4bab9f 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals16.fsx.il.netcore.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals16.fsx.il.netcore.bsl @@ -128,9 +128,7 @@ IL_000c: ret } - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [runtime]System.Collections.IComparer comp) cil managed + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -235,9 +233,7 @@ IL_000b: ret } - .method assembly hidebysig instance bool - Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeStruct obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig instance bool Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeStruct obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -259,9 +255,7 @@ IL_0020: ret } - .method public hidebysig virtual final - instance bool Equals(object obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -285,9 +279,7 @@ IL_0019: ret } - .method public specialname rtspecialname - instance void .ctor(int32 v, - int32 u) cil managed + .method public specialname rtspecialname instance void .ctor(int32 v, int32 u) cil managed { .maxstack 8 diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals17.fsx.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals17.fsx.il.net472.bsl index 1bfb13e46ab..555c1075b46 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals17.fsx.il.net472.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals17.fsx.il.net472.bsl @@ -67,9 +67,7 @@ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly static valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeUnion - NewSomeUnion(int32 item1, - int32 item2) cil managed + .method assembly static valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeUnion NewSomeUnion(int32 item1, int32 item2) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) @@ -222,9 +220,7 @@ IL_000c: ret } - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [runtime]System.Collections.IComparer comp) cil managed + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -335,9 +331,7 @@ IL_000b: ret } - .method assembly hidebysig instance bool - Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeUnion obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig instance bool Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeUnion obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -361,9 +355,7 @@ IL_0022: ret } - .method public hidebysig virtual final - instance bool Equals(object obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals17.fsx.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals17.fsx.il.netcore.bsl index 4387b3cb60f..da37efd4e38 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals17.fsx.il.netcore.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals17.fsx.il.netcore.bsl @@ -67,9 +67,7 @@ .custom instance void [runtime]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [runtime]System.Diagnostics.DebuggerBrowsableState) = ( 01 00 00 00 00 00 00 00 ) .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method assembly static valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeUnion - NewSomeUnion(int32 item1, - int32 item2) cil managed + .method assembly static valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeUnion NewSomeUnion(int32 item1, int32 item2) cil managed { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags, int32) = ( 01 00 08 00 00 00 00 00 00 00 00 00 ) @@ -222,9 +220,7 @@ IL_000c: ret } - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [runtime]System.Collections.IComparer comp) cil managed + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -335,9 +331,7 @@ IL_000b: ret } - .method assembly hidebysig instance bool - Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeUnion obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig instance bool Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeUnion obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -361,9 +355,7 @@ IL_0022: ret } - .method public hidebysig virtual final - instance bool Equals(object obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals18.fsx.il.net472.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals18.fsx.il.net472.bsl index 26f5a4f110f..3842d59c063 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals18.fsx.il.net472.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals18.fsx.il.net472.bsl @@ -87,9 +87,7 @@ IL_0006: ret } - .method assembly specialname rtspecialname - instance void .ctor(int32 v, - int32 u) cil managed + .method assembly specialname rtspecialname instance void .ctor(int32 v, int32 u) cil managed { .custom instance void System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 39 45 71 75 61 6C 73 31 38 2B @@ -191,9 +189,7 @@ IL_000c: ret } - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [runtime]System.Collections.IComparer comp) cil managed + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -298,9 +294,7 @@ IL_000b: ret } - .method assembly hidebysig instance bool - Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeRecord obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig instance bool Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeRecord obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -322,9 +316,7 @@ IL_0020: ret } - .method public hidebysig virtual final - instance bool Equals(object obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -560,9 +552,7 @@ .field private class [runtime]System.Type Type@ .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType, - class [runtime]System.Type Type) cil managed + .method public specialname rtspecialname instance void .ctor(valuetype System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes MemberType, class [runtime]System.Type Type) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [runtime]System.Diagnostics.DebuggerNonUserCodeAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals18.fsx.il.netcore.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals18.fsx.il.netcore.bsl index 1247f45339f..1605434d18a 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals18.fsx.il.netcore.bsl +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/GenericComparison/Equals18.fsx.il.netcore.bsl @@ -87,9 +87,7 @@ IL_0006: ret } - .method assembly specialname rtspecialname - instance void .ctor(int32 v, - int32 u) cil managed + .method assembly specialname rtspecialname instance void .ctor(int32 v, int32 u) cil managed { .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 39 45 71 75 61 6C 73 31 38 2B @@ -191,9 +189,7 @@ IL_000c: ret } - .method public hidebysig virtual final - instance int32 CompareTo(object obj, - class [runtime]System.Collections.IComparer comp) cil managed + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -298,9 +294,7 @@ IL_000b: ret } - .method assembly hidebysig instance bool - Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeRecord obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig instance bool Equals(valuetype assembly/EqualsMicroPerfAndCodeGenerationTests/SomeRecord obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) @@ -322,9 +316,7 @@ IL_0020: ret } - .method public hidebysig virtual final - instance bool Equals(object obj, - class [runtime]System.Collections.IEqualityComparer comp) cil managed + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed { .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/tests/FSharp.Test.Utilities/ILChecker.fs b/tests/FSharp.Test.Utilities/ILChecker.fs index 3c60114d85e..5325841de7b 100644 --- a/tests/FSharp.Test.Utilities/ILChecker.fs +++ b/tests/FSharp.Test.Utilities/ILChecker.fs @@ -36,8 +36,8 @@ module ILChecker = let strings = @"""((\\[^\n]|[^""\n])*)""" let verbatimStrings = @"@(""[^""]*"")+" let methodSingleLine = "^(\s*\.method.*)(?: \s*)$[\r?\n?]^(\s*\{)" - let methodMultiLine = "^(\s*\.method.*)(?: \s*)$[\r?\n?]^(?: \s*)(.*)\s*$[\r?\n?]^(\s*\{)" - + let methodDoubleLine = "^(\s*\.method.*)(?: \s*)$[\r?\n?]^(?: \s*)(.*)\s*$[\r?\n?]^(\s*\{)" + let methodTripleLine = "^(\s*\.method.*)(?: \s*)$[\r?\n?]^(?: \s*)(.*)\s*$[\r?\n?]^(?: \s*)(.*)\s*$[\r?\n?]^(\s*\{)" let normalizeNewLines (text: string) = text.Replace("\r\n", "\n").Replace("\r\n", "\r") let stripComments (text:string) = @@ -52,8 +52,9 @@ module ILChecker = let unifyMethodLine (text:string) = let text1 = Regex.Replace(text, $"{methodSingleLine}", (fun me -> $"{me.Groups[1].Value}\n{me.Groups[2].Value}"), RegexOptions.Multiline) - let text2 = Regex.Replace(text1, $"{methodMultiLine}", (fun me -> $"{me.Groups[1].Value} {me.Groups[2].Value}\n{me.Groups[3].Value}"), RegexOptions.Multiline) - text2 + let text2 = Regex.Replace(text1, $"{methodDoubleLine}", (fun me -> $"{me.Groups[1].Value} {me.Groups[2].Value}\n{me.Groups[3].Value}"), RegexOptions.Multiline) + let text3 = Regex.Replace(text2, $"{methodTripleLine}", (fun me -> $"{me.Groups[1].Value} {me.Groups[2].Value} {me.Groups[3].Value}\n{me.Groups[4].Value}"), RegexOptions.Multiline) + text3 let replace input (pattern, replacement: string) = Regex.Replace(input, pattern, replacement, RegexOptions.Singleline) diff --git a/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs b/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs index ddf93122ee3..e3fd6a0d2f8 100644 --- a/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs +++ b/tests/fsharp/Compiler/CodeGen/EmittedIL/ReferenceAssemblyTests.fs @@ -203,8 +203,7 @@ module Nested = IL_0001: throw } - .method public specialname rtspecialname - instance void .ctor(int32 x) cil managed + .method public specialname rtspecialname instance void .ctor(int32 x) cil managed { .custom instance void [runtime]System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute::.ctor(valuetype [runtime]System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes, class [runtime]System.Type) = ( 01 00 60 06 00 00 1D 52 65 66 65 72 65 6E 63 65 @@ -1216,9 +1215,7 @@ type Person(name : string, age : int) = extends [runtime]System.Object { .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) - .method public specialname rtspecialname - instance void .ctor(string name, - int32 age) cil managed + .method public specialname rtspecialname instance void .ctor(string name, int32 age) cil managed { .maxstack 8 From 5cb3356089b57017fdcf58c7bccf65e6fc7bd0a8 Mon Sep 17 00:00:00 2001 From: Kevin Ransom Date: Tue, 24 Sep 2024 12:27:20 -0700 Subject: [PATCH 07/13] update version number --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index a3e567c7036..9ffa20c0baf 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -14,7 +14,7 @@ 8 0 - 401 + 402 0 From 44f5feb139081471b412d623c5f138634f861748 Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Thu, 26 Sep 2024 06:08:28 -0700 Subject: [PATCH 08/13] Switch to new VMR control set (#17703) (port from main) (#17788) * Now that fsharp is on 9.0, we can switch to the new control set. Generally: - DotNetBuildFromSource -> DotNetBuildSourceOnly - Building a source-only build. - DotnetBuildFromSourceFlavor == Product -> DotNetBuildOrchestrator == true - Building in the VMR, could be source-only or MS's build. - ArcadeBuildFromSource -> DotNetBuildRepo == true -> Indicates an outer repo build. - ExcludeFromSourceBuild -> ExcludeFromSourceOnlyBuild * Split out source build args * Split out source build args * Remove unnecessary source build env var set * Add properties to the bootstrap compiler build * BuildRepo -> BuildInnerRepo * Only build proto repo in inner build * Additional VMR properties for completeness * Rename sourcebuild.props -> dotnetbuild.props --------- Co-authored-by: Petr --- Directory.Build.props | 4 ++-- Directory.Build.targets | 2 +- FSharpBuild.Directory.Build.props | 4 ++-- eng/Build.ps1 | 4 +++- eng/{SourceBuild.props => DotNetBuild.props} | 8 ++++---- eng/build.sh | 9 +++++++-- eng/test-determinism.ps1 | 2 +- proto.proj | 6 ++++-- setup/Directory.Build.props | 2 +- setup/Swix/Directory.Build.targets | 2 +- src/fsc/fscAnyCpuProject/fscAnyCpu.fsproj | 2 +- src/fsc/fscArm64Project/fscArm64.fsproj | 2 +- src/fsi/fsiAnyCpuProject/fsiAnyCpu.fsproj | 2 +- src/fsi/fsiArm64Project/fsiArm64.fsproj | 2 +- tests/Directory.Build.props | 2 +- .../FSharp.Compiler.ComponentTests.fsproj | 2 +- .../FSharp.Compiler.Private.Scripting.UnitTests.fsproj | 2 +- vsintegration/Directory.Build.props | 2 +- .../tests/MockTypeProviders/Directory.Build.props | 2 +- 19 files changed, 35 insertions(+), 26 deletions(-) rename eng/{SourceBuild.props => DotNetBuild.props} (87%) diff --git a/Directory.Build.props b/Directory.Build.props index 719838f0a0d..7f5b362cb34 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,7 +7,7 @@ $(MSBuildThisFileDirectory) true net9.0 - $(DotNetBuildFromSource) + $(DotNetBuildSourceOnly) - + $(NetCurrent) diff --git a/Directory.Build.targets b/Directory.Build.targets index df0677f7673..c43425cc369 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -26,7 +26,7 @@ When .NET gets built from source, make the SDK aware there are bootstrap packages for Microsoft.NETCore.App.Runtime. and Microsoft.NETCore.App.Crossgen2.. --> - + %(RuntimePackRuntimeIdentifiers);$(NETCoreSdkRuntimeIdentifier) diff --git a/FSharpBuild.Directory.Build.props b/FSharpBuild.Directory.Build.props index b2b9ae303cb..148d9c95116 100644 --- a/FSharpBuild.Directory.Build.props +++ b/FSharpBuild.Directory.Build.props @@ -73,8 +73,8 @@ false - - + + false diff --git a/eng/Build.ps1 b/eng/Build.ps1 index a6bda85ef6b..6305083d0df 100644 --- a/eng/Build.ps1 +++ b/eng/Build.ps1 @@ -292,6 +292,8 @@ function BuildSolution([string] $solutionName, $nopack) { # Do not set the property to true explicitly, since that would override value projects might set. $suppressExtensionDeployment = if (!$deployExtensions) { "/p:DeployExtension=false" } else { "" } + $sourceBuildArgs = if ($sourceBuild) { "/p:DotNetBuildSourceOnly=true /p:DotNetBuildRepo=true" } else { "" } + $BUILDING_USING_DOTNET_ORIG = $env:BUILDING_USING_DOTNET $env:BUILDING_USING_DOTNET="false" @@ -314,10 +316,10 @@ function BuildSolution([string] $solutionName, $nopack) { /p:QuietRestore=$quietRestore ` /p:QuietRestoreBinaryLog=$binaryLog ` /p:TestTargetFrameworks=$testTargetFrameworks ` - /p:DotNetBuildFromSource=$sourceBuild ` /p:CompressAllMetadata=$CompressAllMetadata ` /p:BuildNoRealsig=$buildnorealsig ` /v:$verbosity ` + $sourceBuildArgs ` $suppressExtensionDeployment ` @properties diff --git a/eng/SourceBuild.props b/eng/DotNetBuild.props similarity index 87% rename from eng/SourceBuild.props rename to eng/DotNetBuild.props index c1759d53260..c7bc688ba3e 100644 --- a/eng/SourceBuild.props +++ b/eng/DotNetBuild.props @@ -13,7 +13,7 @@ --> + Condition="'$(DotNetBuildSourceOnly)' == 'true'"> $(InnerBuildArgs) /p:Projects="$(InnerSourceBuildRepoRoot)\Microsoft.FSharp.Compiler.sln" @@ -26,7 +26,7 @@ + Condition="'$(DotNetBuildSourceOnly)' == 'true'"> --tfm $(SourceBuildBootstrapTfm) @@ -41,9 +41,9 @@ -bl enables the binlogs for the tools and Proto builds, which make debugging failures here easier --> + EnvironmentVariables="@(InnerBuildEnv)" /> diff --git a/eng/build.sh b/eng/build.sh index 8544de1e72e..90260cbfa4f 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -241,6 +241,11 @@ function BuildSolution { if [[ "$UNAME" == "Darwin" ]]; then enable_analyzers=false fi + + local source_build_args="" + if [[ "$source_build" == true ]]; then + source_build_args="/p:DotNetBuildRepo=true /p:DotNetBuildSourceOnly=true" + fi # NuGet often exceeds the limit of open files on Mac and Linux # https://github.com/NuGet/Home/issues/2163 @@ -274,7 +279,7 @@ function BuildSolution { fi BuildMessage="Error building tools" - local args=" publish $repo_root/proto.proj $blrestore $bltools /p:Configuration=Proto /p:ArcadeBuildFromSource=$source_build $properties" + local args=" publish $repo_root/proto.proj $blrestore $bltools /p:Configuration=Proto $source_build_args $properties" echo $args "$DOTNET_INSTALL_DIR/dotnet" $args #$args || exit $? fi @@ -296,8 +301,8 @@ function BuildSolution { /p:ContinuousIntegrationBuild=$ci \ /p:QuietRestore=$quiet_restore \ /p:QuietRestoreBinaryLog="$binary_log" \ - /p:ArcadeBuildFromSource=$source_build \ /p:BuildNoRealsig=$buildnorealsig \ + $source_build_args \ $properties fi } diff --git a/eng/test-determinism.ps1 b/eng/test-determinism.ps1 index fcb5495f434..8056de2b371 100644 --- a/eng/test-determinism.ps1 +++ b/eng/test-determinism.ps1 @@ -78,7 +78,7 @@ function Run-Build([string]$rootDir, [string]$increment) { /p:ContinuousIntegrationBuild=false ` /p:OfficialBuildId="" ` /p:QuietRestore=false ` - /p:DotNetBuildFromSource=false ` + /p:DotNetBuildSourceOnly=false ` /p:Deterministic=true ` /p:DebugDeterminism=true ` /p:Features="debug-determinism" ` diff --git a/proto.proj b/proto.proj index 2d07b389fa6..eb0814976ea 100644 --- a/proto.proj +++ b/proto.proj @@ -4,8 +4,10 @@ Bootstrap - - + + diff --git a/setup/Directory.Build.props b/setup/Directory.Build.props index cca2c04ebcf..47bbe960ea3 100644 --- a/setup/Directory.Build.props +++ b/setup/Directory.Build.props @@ -12,7 +12,7 @@ $(ArtifactsDir)\VSSetup.obj\$(Configuration)\$(MSBuildProjectName) $(SetupRootFolder)..\artifacts\VSSetup\$(Configuration) $(SetupRootFolder)..\artifacts\VSSetup\$(Configuration)\Insertion - true + true Neutral diff --git a/setup/Swix/Directory.Build.targets b/setup/Swix/Directory.Build.targets index 5e826e8da63..85048309295 100644 --- a/setup/Swix/Directory.Build.targets +++ b/setup/Swix/Directory.Build.targets @@ -15,7 +15,7 @@ + Condition="'$(DotNetBuildSourceOnly)' != 'true'"> diff --git a/src/fsc/fscAnyCpuProject/fscAnyCpu.fsproj b/src/fsc/fscAnyCpuProject/fscAnyCpu.fsproj index 3fac5305cae..a813df67d88 100644 --- a/src/fsc/fscAnyCpuProject/fscAnyCpu.fsproj +++ b/src/fsc/fscAnyCpuProject/fscAnyCpu.fsproj @@ -5,7 +5,7 @@ net472 anycpu - true + true diff --git a/src/fsc/fscArm64Project/fscArm64.fsproj b/src/fsc/fscArm64Project/fscArm64.fsproj index c7c42ca1adf..bcc20db5d6a 100644 --- a/src/fsc/fscArm64Project/fscArm64.fsproj +++ b/src/fsc/fscArm64Project/fscArm64.fsproj @@ -5,7 +5,7 @@ net472 arm64 - true + true diff --git a/src/fsi/fsiAnyCpuProject/fsiAnyCpu.fsproj b/src/fsi/fsiAnyCpuProject/fsiAnyCpu.fsproj index f11e2783e44..ae7238e556a 100644 --- a/src/fsi/fsiAnyCpuProject/fsiAnyCpu.fsproj +++ b/src/fsi/fsiAnyCpuProject/fsiAnyCpu.fsproj @@ -5,7 +5,7 @@ net472 anycpu - true + true $(DefineConstants);FSI_SHADOW_COPY_REFERENCES;FSI_SERVER diff --git a/src/fsi/fsiArm64Project/fsiArm64.fsproj b/src/fsi/fsiArm64Project/fsiArm64.fsproj index 07e19f49d5e..acb66346e8a 100644 --- a/src/fsi/fsiArm64Project/fsiArm64.fsproj +++ b/src/fsi/fsiArm64Project/fsiArm64.fsproj @@ -5,7 +5,7 @@ net472 arm64 - true + true $(DefineConstants);FSI_SHADOW_COPY_REFERENCES;FSI_SERVER diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props index 06697bc35ed..80708062652 100644 --- a/tests/Directory.Build.props +++ b/tests/Directory.Build.props @@ -3,7 +3,7 @@ - true + true portable diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index f7e63b79621..96265fdd24b 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -10,7 +10,7 @@ true xunit true - true + true false false $(OtherFlags) --warnon:1182 diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj index 8f69b337c5a..3bf2d528a4f 100644 --- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj @@ -7,7 +7,7 @@ Library true xunit - true + true $(NoWarn);44 diff --git a/vsintegration/Directory.Build.props b/vsintegration/Directory.Build.props index 3506c3888d2..5a203ce69e2 100644 --- a/vsintegration/Directory.Build.props +++ b/vsintegration/Directory.Build.props @@ -4,7 +4,7 @@ net472 v4.7.2 true - true + true Neutral true diff --git a/vsintegration/tests/MockTypeProviders/Directory.Build.props b/vsintegration/tests/MockTypeProviders/Directory.Build.props index e97fa719a30..3a1978537b7 100644 --- a/vsintegration/tests/MockTypeProviders/Directory.Build.props +++ b/vsintegration/tests/MockTypeProviders/Directory.Build.props @@ -5,7 +5,7 @@ false - true + true From 9e4f926de39e408f7b2a2e87f8651e81f5b7c571 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 27 Sep 2024 09:25:43 +0200 Subject: [PATCH 09/13] respect generic arity in method uniqueness --- src/Compiler/AbstractIL/il.fs | 1 + .../FSharpScriptTests.fs | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 9ed1822676b..2aadea335e1 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -5690,6 +5690,7 @@ let resolveILMethodRefWithRescope r (td: ILTypeDef) (mref: ILMethodRef) = mref.CallingConv = md.CallingConv && (md.Parameters, argTypes) ||> List.lengthsEqAndForall2 (fun p1 p2 -> r p1.Type = p2) + && md.GenericParams.Length = mref.GenericArity && // REVIEW: this uses equality on ILType. For CMOD_OPTIONAL this is not going to be correct r md.Return.Type = retType) diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs index 50c354da629..a8739d93390 100644 --- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs @@ -486,3 +486,17 @@ test pfloat "1.234" let opt = script.Eval(code) |> getValue let value = opt.Value Assert.True(true = downcast value.ReflectionValue) + + [] + member _.``Nuget package with method duplicates differing only in generic arity``() = + // regression test for: https://github.com/dotnet/fsharp/issues/17796 + // Was an internal error + let code = """ +#r "nuget: Microsoft.Extensions.DependencyInjection.Abstractions" +open Microsoft.Extensions.DependencyInjection +let add (col:IServiceCollection) = + col.AddSingleton() +""" + use script = new FSharpScript(additionalArgs=[| |]) + let _value,diag = script.Eval(code) + Assert.Empty(diag) From 6b652cd1d5c02d6f331818ef16479499161b5b6d Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Fri, 27 Sep 2024 12:03:01 +0200 Subject: [PATCH 10/13] [17.12] Turn off realsig when building product and proto (#17808) --- eng/Build.ps1 | 2 +- eng/build.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Build.ps1 b/eng/Build.ps1 index 6305083d0df..b38ecbbd321 100644 --- a/eng/Build.ps1 +++ b/eng/Build.ps1 @@ -71,7 +71,7 @@ param ( [switch]$sourceBuild, [switch]$skipBuild, [switch]$compressAllMetadata, - [switch]$buildnorealsig, + [switch]$buildnorealsig = $true, [switch]$verifypackageshipstatus = $false, [parameter(ValueFromRemainingArguments = $true)][string[]]$properties) diff --git a/eng/build.sh b/eng/build.sh index 90260cbfa4f..8ac4d0a9fa1 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -71,7 +71,7 @@ skip_analyzers=false skip_build=false prepare_machine=false source_build=false -buildnorealsig=false +buildnorealsig=true properties="" docker=false From d470fe86a5784f07f855df17c048fb2411b0addf Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 16 Sep 2024 12:02:09 +0200 Subject: [PATCH 11/13] Bugfix : make sure nullness does not break XmlDoc info import for methods and types (#17741) * Remove nullness signal in string-based type encoding of a symbol (since it is used for xmldoc lookup) * release notes * Discard unused values From 19610c0b654766eec49d044cb97ca6eaa2a63d16 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 30 Sep 2024 16:16:59 +0200 Subject: [PATCH 12/13] Rendering AllowsRefStruct for type parameters (#17706) --- .../.FSharp.Compiler.Service/9.0.100.md | 3 +- src/Compiler/Checking/ConstraintSolver.fs | 2 + .../Checking/Expressions/CheckExpressions.fs | 1 + src/Compiler/Checking/NicePrint.fs | 15 +++++- src/Compiler/Checking/PostInferenceChecks.fs | 1 + src/Compiler/Checking/SignatureHash.fs | 1 + src/Compiler/Checking/TypeHierarchy.fs | 6 ++- src/Compiler/Checking/TypeRelations.fs | 19 ++++---- src/Compiler/Checking/import.fs | 2 + src/Compiler/TypedTree/TypedTree.fs | 3 ++ src/Compiler/TypedTree/TypedTree.fsi | 3 ++ src/Compiler/TypedTree/TypedTreeOps.fs | 8 +++- src/Compiler/TypedTree/TypedTreePickle.fs | 22 +++++---- .../TooltipTests.fs | 47 ++++++++++++++++++- tests/FSharp.Test.Utilities/Assert.fs | 6 +++ 15 files changed, 113 insertions(+), 26 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md index 22eee3e2e5b..1455a1f0479 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md @@ -36,10 +36,11 @@ * Enable FSharp 9.0 Language Version ([Issue #17497](https://github.com/dotnet/fsharp/issues/17438)), [PR](https://github.com/dotnet/fsharp/pull/17500))) * Enable LanguageFeature.EnforceAttributeTargets in F# 9.0. ([Issue #17514](https://github.com/dotnet/fsharp/issues/17558), [PR #17516](https://github.com/dotnet/fsharp/pull/17558)) * Parser: better recovery for unfinished patterns ([PR #17231](https://github.com/dotnet/fsharp/pull/17231), [PR #17232](https://github.com/dotnet/fsharp/pull/17232))) -* Enable consuming generic arguments defined as `allows ref struct` in C# ([Issue #17597](https://github.com/dotnet/fsharp/issues/17597) +* Enable consuming generic arguments defined as `allows ref struct` in C# ([Issue #17597](https://github.com/dotnet/fsharp/issues/17597), display them in tooltips [PR #17706](https://github.com/dotnet/fsharp/pull/17706)) * Trivia for SynTypeConstraint.WhereTyparNotSupportsNull. ([Issue #17721](https://github.com/dotnet/fsharp/issues/17721), [PR #17745](https://github.com/dotnet/fsharp/pull/17745)) * Trivia for SynType.WithNull. ([Issue #17720](https://github.com/dotnet/fsharp/issues/17720), [PR #17745](https://github.com/dotnet/fsharp/pull/17745)) + ### Changed * Change compiler default setting realsig+ when building assemblies ([Issue #17384](https://github.com/dotnet/fsharp/issues/17384), [PR #17378](https://github.com/dotnet/fsharp/pull/17385)) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 196a62c3fec..f9ed37fe9ca 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -1024,6 +1024,7 @@ and SolveTypMeetsTyparConstraints (csenv: ConstraintSolverEnv) ndeep m2 trace ty | TyparConstraint.IsDelegate(aty, bty, m2) -> SolveTypeIsDelegate csenv ndeep m2 trace ty aty bty | TyparConstraint.IsNonNullableStruct m2 -> SolveTypeIsNonNullableValueType csenv ndeep m2 trace ty | TyparConstraint.IsUnmanaged m2 -> SolveTypeIsUnmanaged csenv ndeep m2 trace ty + | TyparConstraint.AllowsRefStruct _ -> CompleteD | TyparConstraint.IsReferenceType m2 -> SolveTypeIsReferenceType csenv ndeep m2 trace ty | TyparConstraint.RequiresDefaultConstructor m2 -> SolveTypeRequiresDefaultConstructor csenv ndeep m2 trace ty | TyparConstraint.SimpleChoice(tys, m2) -> SolveTypeChoice csenv ndeep m2 trace ty tys @@ -2465,6 +2466,7 @@ and CheckConstraintImplication (csenv: ConstraintSolverEnv) tpc1 tpc2 = | TyparConstraint.NotSupportsNull _, TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _ + | TyparConstraint.AllowsRefStruct _, TyparConstraint.AllowsRefStruct _ | TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _ | TyparConstraint.RequiresDefaultConstructor _, TyparConstraint.RequiresDefaultConstructor _ -> true | TyparConstraint.SimpleChoice (tys1, _), TyparConstraint.SimpleChoice (tys2, _) -> ListSet.isSubsetOf (typeEquiv g) tys1 tys2 diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index 615e4251893..b5cc414e721 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -5163,6 +5163,7 @@ and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags | TyparConstraint.SupportsComparison _ | TyparConstraint.SupportsEquality _ | TyparConstraint.DefaultsTo (ty = Unit) + | TyparConstraint.AllowsRefStruct _ | TyparConstraint.MayResolveMember _ -> true // Any other kind of constraint is incompatible with unit. diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index ccb99f12139..812837a3edd 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -773,8 +773,13 @@ module PrintTypes = | _ -> if denv.abbreviateAdditionalConstraints then wordL (tagKeyword "when") ^^ wordL(tagText "") - elif denv.shortConstraints then - LeftL.leftParen ^^ wordL (tagKeyword "requires") ^^ sepListL (wordL (tagKeyword "and")) cxsL ^^ RightL.rightParen + elif denv.shortConstraints then + match cxs with + | (_,TyparConstraint.AllowsRefStruct _) :: _ -> + // If the first constraint is 'allows ref struct', we do not want to prefix it with 'requires', because that just reads wrong. + LeftL.leftParen ^^ sepListL (wordL (tagKeyword "and")) cxsL ^^ RightL.rightParen + | _ -> + LeftL.leftParen ^^ wordL (tagKeyword "requires") ^^ sepListL (wordL (tagKeyword "and")) cxsL ^^ RightL.rightParen else wordL (tagKeyword "when") ^^ sepListL (wordL (tagKeyword "and")) cxsL @@ -834,6 +839,12 @@ module PrintTypes = [wordL (tagKeyword "unmanaged")] else [wordL (tagKeyword "unmanaged") |> longConstraintPrefix] + + | TyparConstraint.AllowsRefStruct _ -> + if denv.shortConstraints then + [wordL (tagKeyword "allows ref struct")] + else + [wordL (tagKeyword "allows ref struct") |> longConstraintPrefix] | TyparConstraint.IsReferenceType _ -> if denv.shortConstraints then diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs index 06ef1b9766a..e9860a76efa 100644 --- a/src/Compiler/Checking/PostInferenceChecks.fs +++ b/src/Compiler/Checking/PostInferenceChecks.fs @@ -448,6 +448,7 @@ and CheckTypeConstraintDeep cenv f g env x = | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsUnmanaged _ + | TyparConstraint.AllowsRefStruct _ | TyparConstraint.IsReferenceType _ | TyparConstraint.RequiresDefaultConstructor _ -> () diff --git a/src/Compiler/Checking/SignatureHash.fs b/src/Compiler/Checking/SignatureHash.fs index f3f81b2fee3..66aeb0912c7 100644 --- a/src/Compiler/Checking/SignatureHash.fs +++ b/src/Compiler/Checking/SignatureHash.fs @@ -165,6 +165,7 @@ module rec HashTypes = | TyparConstraint.SimpleChoice(tys, _) -> tpHash @@ 12 @@ (tys |> hashListOrderIndependent (hashTType g)) | TyparConstraint.RequiresDefaultConstructor _ -> tpHash @@ 13 | TyparConstraint.NotSupportsNull(_) -> tpHash @@ 14 + | TyparConstraint.AllowsRefStruct _ -> tpHash @@ 15 /// Hash type parameter constraints let private hashConstraints (g: TcGlobals) cxs = diff --git a/src/Compiler/Checking/TypeHierarchy.fs b/src/Compiler/Checking/TypeHierarchy.fs index 102f36908fe..1ccde31b75e 100644 --- a/src/Compiler/Checking/TypeHierarchy.fs +++ b/src/Compiler/Checking/TypeHierarchy.fs @@ -285,6 +285,7 @@ let FoldHierarchyOfTypeAux followInterfaces allowMultiIntfInst skipUnref visitor | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsUnmanaged _ + | TyparConstraint.AllowsRefStruct _ | TyparConstraint.IsReferenceType _ | TyparConstraint.SimpleChoice _ | TyparConstraint.RequiresDefaultConstructor _ -> vacc @@ -412,7 +413,9 @@ let ImportReturnTypeFromMetadata amap m nullnessSource ilTy scoref tinst minst = let CopyTyparConstraints m tprefInst (tporig: Typar) = tporig.Constraints - |> List.map (fun tpc -> + // F# does not have escape analysis for authoring 'allows ref struct' generic code. Therefore, typar is not copied, can only come from C# authored code + |> List.filter (fun tp -> match tp with | TyparConstraint.AllowsRefStruct _ -> false | _ -> true) + |> List.map (fun tpc -> match tpc with | TyparConstraint.CoercesTo(ty, _) -> TyparConstraint.CoercesTo (instType tprefInst ty, m) @@ -434,6 +437,7 @@ let CopyTyparConstraints m tprefInst (tporig: Typar) = TyparConstraint.IsNonNullableStruct m | TyparConstraint.IsUnmanaged _ -> TyparConstraint.IsUnmanaged m + | TyparConstraint.AllowsRefStruct _ -> failwith "impossible, filtered above" | TyparConstraint.IsReferenceType _ -> TyparConstraint.IsReferenceType m | TyparConstraint.SimpleChoice (tys, _) -> diff --git a/src/Compiler/Checking/TypeRelations.fs b/src/Compiler/Checking/TypeRelations.fs index 16ed5e9f9d3..b52a1da1574 100644 --- a/src/Compiler/Checking/TypeRelations.fs +++ b/src/Compiler/Checking/TypeRelations.fs @@ -151,19 +151,13 @@ let ChooseTyparSolutionAndRange (g: TcGlobals) amap (tp:Typar) = match tpc with | TyparConstraint.CoercesTo(x, m) -> join m x, m - | TyparConstraint.MayResolveMember(_traitInfo, m) -> - (maxTy, isRefined), m | TyparConstraint.SimpleChoice(_, m) -> errorR(Error(FSComp.SR.typrelCannotResolveAmbiguityInPrintf(), m)) (maxTy, isRefined), m | TyparConstraint.SupportsNull m -> ((addNullnessToTy KnownWithNull maxTy), isRefined), m - | TyparConstraint.NotSupportsNull m -> - (maxTy, isRefined), m // NOTE: this doesn't "force" non-nullness, since it is the default choice in 'obj' or 'int' | TyparConstraint.SupportsComparison m -> join m g.mk_IComparable_ty, m - | TyparConstraint.SupportsEquality m -> - (maxTy, isRefined), m | TyparConstraint.IsEnum(_, m) -> errorR(Error(FSComp.SR.typrelCannotResolveAmbiguityInEnum(), m)) (maxTy, isRefined), m @@ -175,12 +169,15 @@ let ChooseTyparSolutionAndRange (g: TcGlobals) amap (tp:Typar) = | TyparConstraint.IsUnmanaged m -> errorR(Error(FSComp.SR.typrelCannotResolveAmbiguityInUnmanaged(), m)) (maxTy, isRefined), m - | TyparConstraint.RequiresDefaultConstructor m -> - (maxTy, isRefined), m - | TyparConstraint.IsReferenceType m -> + | TyparConstraint.NotSupportsNull m // NOTE: this doesn't "force" non-nullness, since it is the default choice in 'obj' or 'int' + | TyparConstraint.SupportsEquality m + | TyparConstraint.AllowsRefStruct m + | TyparConstraint.RequiresDefaultConstructor m + | TyparConstraint.IsReferenceType m + | TyparConstraint.MayResolveMember(_, m) + | TyparConstraint.DefaultsTo(_,_, m) -> (maxTy, isRefined), m - | TyparConstraint.DefaultsTo(_priority, _ty, m) -> - (maxTy, isRefined), m) + ) if g.langVersion.SupportsFeature LanguageFeature.DiagnosticForObjInference then match tp.Kind with diff --git a/src/Compiler/Checking/import.fs b/src/Compiler/Checking/import.fs index 68e3512864b..1c1b0ed9ea1 100644 --- a/src/Compiler/Checking/import.fs +++ b/src/Compiler/Checking/import.fs @@ -653,6 +653,8 @@ let ImportILGenericParameters amap m scoref tinst (nullableFallback:Nullness.Nul TyparConstraint.IsNonNullableStruct(m) if gp.HasReferenceTypeConstraint then TyparConstraint.IsReferenceType(m) + if gp.HasAllowsRefStruct then + TyparConstraint.AllowsRefStruct(m) for ilTy in gp.Constraints do TyparConstraint.CoercesTo(ImportILType amap m importInst (rescopeILType scoref ilTy), m) ] diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs index daf31357df3..b948e91fb65 100644 --- a/src/Compiler/TypedTree/TypedTree.fs +++ b/src/Compiler/TypedTree/TypedTree.fs @@ -2531,6 +2531,9 @@ type TyparConstraint = /// A constraint that a type is .NET unmanaged type | IsUnmanaged of range: range + + /// An anti-constraint indicating that ref structs (e.g. Span<>) are allowed here + | AllowsRefStruct of range:range // %+A formatting is used, so this is not needed //[] diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi index 3ba4f5c12ba..d357895728d 100644 --- a/src/Compiler/TypedTree/TypedTree.fsi +++ b/src/Compiler/TypedTree/TypedTree.fsi @@ -1694,6 +1694,9 @@ type TyparConstraint = /// A constraint that a type is .NET unmanaged type | IsUnmanaged of range: range + /// An anti-constraint indicating that ref structs (e.g. Span<>) are allowed here + | AllowsRefStruct of range: range + override ToString: unit -> string [] diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index 333b29cd78f..e7c4576b24e 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -272,7 +272,8 @@ and remapTyparConstraintsAux tyenv cs = | TyparConstraint.SupportsEquality _ | TyparConstraint.SupportsNull _ | TyparConstraint.NotSupportsNull _ - | TyparConstraint.IsUnmanaged _ + | TyparConstraint.IsUnmanaged _ + | TyparConstraint.AllowsRefStruct _ | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsReferenceType _ | TyparConstraint.RequiresDefaultConstructor _ -> Some x) @@ -1039,6 +1040,7 @@ and typarConstraintsAEquivAux erasureFlag g aenv tpc1 tpc2 = | TyparConstraint.IsNonNullableStruct _, TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsReferenceType _, TyparConstraint.IsReferenceType _ | TyparConstraint.IsUnmanaged _, TyparConstraint.IsUnmanaged _ + | TyparConstraint.AllowsRefStruct _, TyparConstraint.AllowsRefStruct _ | TyparConstraint.RequiresDefaultConstructor _, TyparConstraint.RequiresDefaultConstructor _ -> true | _ -> false @@ -2345,6 +2347,7 @@ and accFreeInTyparConstraint opts tpc acc = | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsReferenceType _ | TyparConstraint.IsUnmanaged _ + | TyparConstraint.AllowsRefStruct _ | TyparConstraint.RequiresDefaultConstructor _ -> acc and accFreeInTrait opts (TTrait(tys, _, _, argTys, retTy, _, sln)) acc = @@ -2480,6 +2483,7 @@ and accFreeInTyparConstraintLeftToRight g cxFlag thruFlag acc tpc = | TyparConstraint.NotSupportsNull _ | TyparConstraint.IsNonNullableStruct _ | TyparConstraint.IsUnmanaged _ + | TyparConstraint.AllowsRefStruct _ | TyparConstraint.IsReferenceType _ | TyparConstraint.RequiresDefaultConstructor _ -> acc @@ -4223,6 +4227,8 @@ module DebugPrint = wordL (tagText "not null") |> constraintPrefix | TyparConstraint.IsUnmanaged _ -> wordL (tagText "unmanaged") |> constraintPrefix + | TyparConstraint.AllowsRefStruct _ -> + wordL (tagText "allows ref struct") |> constraintPrefix | TyparConstraint.SimpleChoice(tys, _) -> bracketL (sepListL (sepL (tagText "|")) (List.map (auxTypeL env) tys)) |> constraintPrefix | TyparConstraint.RequiresDefaultConstructor _ -> diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs index 9ade306d77c..9515d49b80d 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fs +++ b/src/Compiler/TypedTree/TypedTreePickle.fs @@ -1612,19 +1612,22 @@ let p_tyar_constraint x st = | TyparConstraint.SupportsComparison _ -> p_byte 10 st | TyparConstraint.SupportsEquality _ -> p_byte 11 st | TyparConstraint.IsUnmanaged _ -> p_byte 12 st - | TyparConstraint.NotSupportsNull _ -> - failwith "NotSupportsNull constraints should only be emitted to streamB" + + | TyparConstraint.NotSupportsNull _ + | TyparConstraint.AllowsRefStruct _ -> + failwith $"%A{x} constraints should only be emitted to streamB" -// Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers +// Some extra F#9+ constraints are stored in stream B, these will be ignored by earlier F# compilers let p_tyar_constraintB x st = match x with | TyparConstraint.NotSupportsNull _ -> p_byteB 1 st - | _ -> failwith "only NotSupportsNull constraints should be emitted to streamB" + | TyparConstraint.AllowsRefStruct _ -> p_byteB 2 st + | _ -> failwith "only NotSupportsNull and AllowsRefStruct constraints should be emitted to streamB" let p_tyar_constraints cxs st = - let cxs1, cxs2 = cxs |> List.partition (function TyparConstraint.NotSupportsNull _ -> false | _ -> true) + let cxs1, cxs2 = cxs |> List.partition (function TyparConstraint.NotSupportsNull _ | TyparConstraint.AllowsRefStruct _ -> false | _ -> true) p_list p_tyar_constraint cxs1 st - // Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers + // Some extra F#9+ constraints are stored in stream B, these will be ignored by earlier F# compilers p_listB p_tyar_constraintB cxs2 st let u_tyar_constraint st = @@ -1645,16 +1648,17 @@ let u_tyar_constraint st = | 12 -> (fun _ -> TyparConstraint.IsUnmanaged range0) | _ -> ufailwith st "u_tyar_constraint" -// Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers +// Some extra F#9+ constraints are stored in stream B, these will be ignored by earlier F# compilers let u_tyar_constraintB st = let tag = u_byteB st match tag with - | 1 -> TyparConstraint.NotSupportsNull range0 + | 1 -> TyparConstraint.NotSupportsNull range0 + | 2 -> TyparConstraint.AllowsRefStruct range0 | _ -> ufailwith st "u_tyar_constraintB - unexpected constraint in streamB" let u_tyar_constraints st = let cxs1 = u_list_revi u_tyar_constraint st - // Some extra F# 5.0 constraints are stored in stream B, these will be ignored by earlier F# compilers + // Some extra F#9+ constraints are stored in stream B, these will be ignored by earlier F# compilers // // If the B stream is not present (e.g. reading F# 4.5 components) then this list will be empty // via the implementation of u_listB. diff --git a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs index e9ce93a37cd..0b30a5a61e8 100644 --- a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs @@ -514,4 +514,49 @@ let success,version = System.Version.TryParse(null) checkResults.GetToolTip(2, 45, "let success,version = System.Version.TryParse(null)", [ "TryParse" ], FSharpTokenTag.Identifier,width=100) |> assertAndGetSingleToolTipText |> Assert.shouldBeEquivalentTo ("""System.Version.TryParse([] input: string | null, - [] result: byref) : bool""" |> normalize) \ No newline at end of file + [] result: byref) : bool""" |> normalize) + +[] +let ``Allows ref struct is shown on BCL interface declaration`` () = + let source = """module Foo +open System +let myAction : Action | null = null +""" + let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|] + checkResults.GetToolTip(3, 21, "let myAction : Action | null = null", [ "Action" ], FSharpTokenTag.Identifier) + |> assertAndGetSingleToolTipText + |> Assert.shouldStartWith ("""type Action<'T (allows ref struct)>""" |> normalize) + +[] +let ``Allows ref struct is shown for each T on BCL interface declaration`` () = + let source = """module Foo +open System +let myAction : Action | null = null +""" + let checkResults = getCheckResults source [|"--checknulls+";"--langversion:preview"|] + checkResults.GetToolTip(3, 21, "let myAction : Action | null = null", [ "Action" ], FSharpTokenTag.Identifier) + |> assertAndGetSingleToolTipText + |> Assert.shouldStartWith ("""type Action<'T1,'T2,'T3,'T4 (allows ref struct and allows ref struct and allows ref struct and allows ref struct)>""" |> normalize) + +[] +let ``Allows ref struct is shown on BCL method usage`` () = + let source = """module Foo +open System +open System.Collections.Generic +let doIt (dict:Dictionary<'a,'b>) = dict.GetAlternateLookup<'a,'b,ReadOnlySpan>() +""" + let checkResults = getCheckResults source [|"--langversion:preview"|] + checkResults.GetToolTip(4, 59, "let doIt (dict:Dictionary<'a,'b>) = dict.GetAlternateLookup<'a,'b,ReadOnlySpan>()", [ "GetAlternateLookup" ], FSharpTokenTag.Identifier) + |> assertAndGetSingleToolTipText + |> Assert.shouldContain ("""'TAlternateKey (allows ref struct)""" |> normalize) + +[] +let ``Allows ref struct is not shown on BCL interface usage`` () = + let source = """module Foo +open System +let doIt(myAction : Action) = myAction.Invoke(42) +""" + let checkResults = getCheckResults source [|"--langversion:preview"|] + checkResults.GetToolTip(3, 43, "let doIt(myAction : Action) = myAction.Invoke(42)", [ "myAction" ], FSharpTokenTag.Identifier) + |> assertAndGetSingleToolTipText + |> Assert.shouldBeEquivalentTo ("""val myAction: Action""" |> normalize) \ No newline at end of file diff --git a/tests/FSharp.Test.Utilities/Assert.fs b/tests/FSharp.Test.Utilities/Assert.fs index dfed4bf123e..fc36129666f 100644 --- a/tests/FSharp.Test.Utilities/Assert.fs +++ b/tests/FSharp.Test.Utilities/Assert.fs @@ -11,6 +11,12 @@ module Assert = let inline shouldBeEquivalentTo (expected : ^T) (actual : ^U) = actual.Should().BeEquivalentTo(expected, "") |> ignore + + let inline shouldStartWith (expected : string) (actual : string) = + actual.Should().StartWith(expected) |> ignore + + let inline shouldContain (needle : string) (haystack : string) = + haystack.Should().Contain(needle) |> ignore let inline shouldBe (expected : ^T) (actual : ^U) = actual.Should().Be(expected, "") |> ignore From d4e0b5a89a5f0034e4b2097b7316f60fa5a653a0 Mon Sep 17 00:00:00 2001 From: Vlad Zarytovskii Date: Mon, 7 Oct 2024 14:29:42 +0200 Subject: [PATCH 13/13] Update azure-pipelines.yml --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b4f235359af..a8155022e68 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -35,7 +35,7 @@ variables: # (since for all *new* release branches we insert into VS main and for all *previous* releases we insert into corresponding VS release), # i.e. 'rel/d17.9' *or* 'main' in dotnet/fsharp/refs/heads/main and 'main' in F# dotnet/fsharp/refs/heads/release/dev17.10 (latest release branch) - name: VSInsertionTargetBranchName - value: main + value: rel/d17.12 - name: _TeamName value: FSharp - name: TeamName