From 770057dc5909dabc55248a32bdccf8c0146738fd Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 25 Aug 2026 20:09:46 +0200 Subject: [PATCH 1/8] Rotate [] attributes during binding normalization Since #19738 the parser moved attributes written as [] in front of a binding out of SynBinding.attributes and into SynValInfo.retInfo. The untyped tree then reported no attributes for source that visibly has one, which every consumer of the parse tree sees: formatters, analyzers, source generators and refactoring tools. The move was also lossy. The attribute list range narrowed from the [< >] span to the attribute alone, and all return attributes were collected into a single synthesized list, so [] and [][] produced identical trees. Neither can be printed back to its original form. Do the rotation in BindingNormalization.NormalizeBinding instead, the single funnel from SynBinding to NormalizedBinding and already a lowering step. Everything downstream still reads retInfo as the single source of truth, so the fixes for #17904 and #19020 are unchanged, but the parse tree again says what was written. Add parse baselines for both the common [] partial active pattern and for attribute grouping, neither of which had any coverage before. --- .../Checking/Expressions/CheckExpressions.fs | 5 +- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 30 ++--- src/Compiler/SyntaxTree/SyntaxTreeOps.fsi | 9 ++ ...urnTargetedAttributeGroupingIsPreserved.fs | 13 ++ ...argetedAttributeGroupingIsPreserved.fs.bsl | 124 ++++++++++++++++++ .../ReturnTargetedAttributeStaysOnBinding.fs | 4 + ...turnTargetedAttributeStaysOnBinding.fs.bsl | 45 +++++++ 7 files changed, 208 insertions(+), 22 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeGroupingIsPreserved.fs create mode 100644 tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeGroupingIsPreserved.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeStaysOnBinding.fs create mode 100644 tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeStaysOnBinding.fs.bsl diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index a89f17f0402..c2e4f3a70bb 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -2630,6 +2630,9 @@ module BindingNormalization = let paramNames = Some valSynData.SynValInfo.ArgNames let checkXmlDocs = cenv.diagnosticOptions.CheckXmlDocs let xmlDoc = xmlDoc.ToXmlDoc(checkXmlDocs, paramNames) + // Rotate [] from the binding to the return value. This is done here rather than in + // the parser so that SynBinding.attributes keeps reporting the attributes where they were written. + let attrs, valSynData = SynInfo.RotateReturnAttributes attrs valSynData NormalizedBinding(vis, kind, isInline, isMutable, attrs, xmlDoc, typars, valSynData, pat, rhsExpr, mBinding, debugPoint) //------------------------------------------------------------------------- @@ -11545,7 +11548,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt attrs // [] attributes are moved out of the binding's prefix and into - // SynValData.SynValInfo.retInfo by SynInfo.RotateReturnAttributes in mkSynBinding, + // SynValData.SynValInfo.retInfo by SynInfo.RotateReturnAttributes in BindingNormalization, // alongside any attributes on the return type annotation populated by InferSynReturnData. // Use that as the single source of truth. let valAttribs = TcAttrs attrTgt false attrs diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index ffca6718f56..5f157cca8f4 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -765,27 +765,17 @@ module SynInfo = /// arity-info return position (`SynValInfo.retInfo`). Without this, downstream code that /// reads `Val.Attribs` would incorrectly see them alongside method-targeted attributes /// (see issues #17904 and #19020). - let RotateReturnAttributes (attrs: SynAttributes) (valSynData: SynValData) : SynAttributes * SynValData = + /// + /// This is a lowering step, applied while normalizing a binding for checking rather than in + /// the parser, so `SynBinding.attributes` keeps reporting the attributes where they were + /// written. Tools reading the untyped tree (formatters, analyzers, source generators) depend + /// on that. + let RotateReturnAttributes (attrs: SynAttribute list) (valSynData: SynValData) : SynAttribute list * SynValData = // Fast path: avoid all allocation when there's nothing to rotate (the common case). - let hasReturn = - attrs - |> List.exists (fun lst -> lst.Attributes |> List.exists isReturnTargetedAttribute) - - if not hasReturn then + if not (List.exists isReturnTargetedAttribute attrs) then attrs, valSynData else - let mutable returnTargeted = [] - - let newAttrs = - attrs - |> List.choose (fun lst -> - let ret, kept = lst.Attributes |> List.partition isReturnTargetedAttribute - returnTargeted <- returnTargeted @ ret - - if List.isEmpty kept then - None - else - Some { lst with Attributes = kept }) + let returnTargeted, kept = attrs |> List.partition isReturnTargetedAttribute let (SynValData(memFlags, SynValInfo(args, SynArgInfo(retAttrs, opt, retId)), thisIdOpt)) = valSynData @@ -796,7 +786,7 @@ module SynInfo = Range = (List.head returnTargeted).Range } - newAttrs, SynValData(memFlags, SynValInfo(args, SynArgInfo(retList :: retAttrs, opt, retId)), thisIdOpt) + kept, SynValData(memFlags, SynValInfo(args, SynArgInfo(retList :: retAttrs, opt, retId)), thisIdOpt) let mkSynBindingRhs staticOptimizations rhsExpr mRhs retInfo = let rhsExpr = @@ -817,8 +807,6 @@ let mkSynBinding let info = SynInfo.InferSynValData(memberFlagsOpt, Some headPat, Option.map snd retInfo, origRhsExpr) - let attrs, info = SynInfo.RotateReturnAttributes attrs info - let rhsExpr, retTyOpt = mkSynBindingRhs staticOptimizations origRhsExpr mRhs retInfo let mBind = unionRangeWithXmlDoc xmlDoc mBind SynBinding(vis, SynBindingKind.Normal, isInline, isMutable, attrs, xmlDoc, info, headPat, retTyOpt, rhsExpr, mBind, spBind, trivia) diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi index c4915300652..d65abed05d6 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi @@ -275,6 +275,15 @@ module SynInfo = val emptySynArgInfo: SynArgInfo + /// Rotate any `[]` attributes from a binding's prefix attribute list into the + /// arity-info return position (`SynValInfo.retInfo`), so that the attributes reach the + /// return-value metadata slot rather than `Val.Attribs`. + /// + /// This is a lowering step, applied while normalizing a binding for checking rather than in + /// the parser, so `SynBinding.attributes` keeps reporting the attributes where they were + /// written. + val RotateReturnAttributes: attrs: SynAttribute list -> valSynData: SynValData -> SynAttribute list * SynValData + /// Infer the syntactic information for a 'let' or 'member' definition, based on the argument pattern, /// any declared return information (e.g. .NET attributes on the return element), and the r.h.s. expression /// in the case of 'let' definitions. diff --git a/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeGroupingIsPreserved.fs b/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeGroupingIsPreserved.fs new file mode 100644 index 00000000000..166db689f84 --- /dev/null +++ b/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeGroupingIsPreserved.fs @@ -0,0 +1,13 @@ +module M + +open System + +[] +type AAttribute() = + inherit Attribute() + +[][] +let f () = () + +[] +let g () = () diff --git a/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeGroupingIsPreserved.fs.bsl b/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeGroupingIsPreserved.fs.bsl new file mode 100644 index 00000000000..d886f0b72ab --- /dev/null +++ b/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeGroupingIsPreserved.fs.bsl @@ -0,0 +1,124 @@ +ImplFile + (ParsedImplFileInput + ("/root/Attribute/ReturnTargetedAttributeGroupingIsPreserved.fs", false, + QualifiedNameOfFile M, [], + [SynModuleOrNamespace + ([M], false, NamedModule, + [Open + (ModuleOrNamespace + (SynLongIdent ([System], [], [None]), (3,5--3,11)), (3,0--3,11)); + Types + ([SynTypeDefn + (SynComponentInfo + ([{ Attributes = + [{ TypeName = + SynLongIdent ([AttributeUsage], [], [None]) + ArgExpr = + Paren + (Tuple + (false, + [LongIdent + (false, + SynLongIdent + ([AttributeTargets; ReturnValue], + [(5,33--5,34)], [None; None]), None, + (5,17--5,45)); + App + (NonAtomic, false, + App + (NonAtomic, true, + LongIdent + (false, + SynLongIdent + ([op_Equality], [], + [Some (OriginalNotation "=")]), + None, (5,61--5,62)), + Ident AllowMultiple, (5,47--5,62)), + Const (Bool true, (5,63--5,67)), + (5,47--5,67))], [(5,45--5,46)], + (5,17--5,67)), (5,16--5,17), + Some (5,67--5,68), (5,16--5,68)) + Target = None + AppliesToGetterAndSetter = false + Range = (5,2--5,68) }] + Range = (5,0--5,70) }], None, [], + Some (LongIdent (SynLongIdent ([AAttribute], [], [None]))), + PreXmlDoc ((5,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (6,5--6,15)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], Const (Unit, (6,15--6,17)), None, + PreXmlDoc ((6,15), FSharp.Compiler.Xml.XmlDocCollector), + (6,5--6,15), { AsKeyword = None }); + ImplicitInherit + (LongIdent (SynLongIdent ([Attribute], [], [None])), + Const (Unit, (7,21--7,23)), None, (7,4--7,23), + { InheritKeyword = (7,4--7,11) })], (7,4--7,23)), [], + Some + (ImplicitCtor + (None, [], Const (Unit, (6,15--6,17)), None, + PreXmlDoc ((6,15), FSharp.Compiler.Xml.XmlDocCollector), + (6,5--6,15), { AsKeyword = None })), (5,0--7,23), + { LeadingKeyword = Type (6,0--6,4) + EqualsRange = Some (6,18--6,19) + WithKeyword = None })], (5,0--7,23)); + Let + (false, + [SynBinding + (None, Normal, false, false, + [{ Attributes = [{ TypeName = SynLongIdent ([A], [], [None]) + ArgExpr = Const (Unit, (9,10--9,11)) + Target = Some return + AppliesToGetterAndSetter = false + Range = (9,2--9,11) }] + Range = (9,0--9,13) }; + { Attributes = [{ TypeName = SynLongIdent ([A], [], [None]) + ArgExpr = Const (Unit, (9,23--9,24)) + Target = Some return + AppliesToGetterAndSetter = false + Range = (9,15--9,24) }] + Range = (9,13--9,26) }], + PreXmlDoc ((9,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([[]], SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([f], [], [None]), None, None, + Pats [Paren (Const (Unit, (10,6--10,8)), (10,6--10,8))], + None, (10,4--10,8)), None, Const (Unit, (10,11--10,13)), + (9,0--10,8), NoneAtLet, { LeadingKeyword = Let (10,0--10,3) + InlineKeyword = None + EqualsRange = Some (10,9--10,10) })], + (9,0--10,13), { InKeyword = None }); + Let + (false, + [SynBinding + (None, Normal, false, false, + [{ Attributes = + [{ TypeName = SynLongIdent ([A], [], [None]) + ArgExpr = Const (Unit, (12,10--12,11)) + Target = Some return + AppliesToGetterAndSetter = false + Range = (12,2--12,11) }; + { TypeName = SynLongIdent ([A], [], [None]) + ArgExpr = Const (Unit, (12,21--12,22)) + Target = Some return + AppliesToGetterAndSetter = false + Range = (12,13--12,22) }] + Range = (12,0--12,24) }], + PreXmlDoc ((12,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([[]], SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([g], [], [None]), None, None, + Pats [Paren (Const (Unit, (13,6--13,8)), (13,6--13,8))], + None, (13,4--13,8)), None, Const (Unit, (13,11--13,13)), + (12,0--13,8), NoneAtLet, { LeadingKeyword = Let (13,0--13,3) + InlineKeyword = None + EqualsRange = Some (13,9--13,10) })], + (12,0--13,13), { InKeyword = None })], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--13,13), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeStaysOnBinding.fs b/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeStaysOnBinding.fs new file mode 100644 index 00000000000..b3d775d2087 --- /dev/null +++ b/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeStaysOnBinding.fs @@ -0,0 +1,4 @@ +module M + +[] +let (|Foo|_|) (x: int) = ValueNone diff --git a/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeStaysOnBinding.fs.bsl b/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeStaysOnBinding.fs.bsl new file mode 100644 index 00000000000..1972cd1be30 --- /dev/null +++ b/tests/service/data/SyntaxTree/Attribute/ReturnTargetedAttributeStaysOnBinding.fs.bsl @@ -0,0 +1,45 @@ +ImplFile + (ParsedImplFileInput + ("/root/Attribute/ReturnTargetedAttributeStaysOnBinding.fs", false, + QualifiedNameOfFile M, [], + [SynModuleOrNamespace + ([M], false, NamedModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, + [{ Attributes = + [{ TypeName = SynLongIdent ([Struct], [], [None]) + ArgExpr = Const (Unit, (3,10--3,16)) + Target = Some return + AppliesToGetterAndSetter = false + Range = (3,2--3,16) }] + Range = (3,0--3,18) }], + PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, Some x)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent + ([|Foo|_|], [], + [Some (HasParenthesis ((4,4--4,5), (4,12--4,13)))]), + None, None, + Pats + [Paren + (Typed + (Named + (SynIdent (x, None), false, None, (4,15--4,16)), + LongIdent (SynLongIdent ([int], [], [None])), + (4,15--4,21)), (4,14--4,22))], None, (4,4--4,22)), + None, Ident ValueNone, (3,0--4,22), NoneAtLet, + { LeadingKeyword = Let (4,0--4,3) + InlineKeyword = None + EqualsRange = Some (4,23--4,24) })], (3,0--4,34), + { InKeyword = None })], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, + (1,0--4,34), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + { ConditionalDirectives = [] + WarnDirectives = [] + CodeComments = [] }, set [])) From bceab8a91b80df72eb78a60f6e17d8ae8bedf192 Mon Sep 17 00:00:00 2001 From: nojaf Date: Tue, 25 Aug 2026 20:15:53 +0200 Subject: [PATCH 2/8] Add release note --- docs/release-notes/.FSharp.Compiler.Service/11.0.100.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index 3c823881ec1..7865d14ca8e 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -197,6 +197,7 @@ * Stabilized several `preview` language features into F# 11.0 (`--langversion:11.0`, enabled by default with a .NET 11 SDK): `MethodOverloadsCache`, `ErrorOnMissingSignatureAttribute`, `DirectDelegateConstruction`, `AccessProtectedBaseFieldFromClosure`, and `RecordSpreads`. `FromEndSlicing` intentionally remains in `preview`. ([PR #20199](https://github.com/dotnet/fsharp/pull/20199)) * Interpolated string holes (e.g. `$"{x}"`) are now formatted with invariant culture (via the `string` operator) instead of the current thread culture. ([PR #19971](https://github.com/dotnet/fsharp/pull/19971)) * Lines starting with `#:` are now ignored ([Language suggestion 1440](https://github.com/fsharp/fslang-suggestions/issues/1440), [RFC FS-1337](https://github.com/fsharp/fslang-design/pull/830), [PR #20212](https://github.com/dotnet/fsharp/pull/20212)) +* `[]` attributes written in front of a binding are again reported by `SynBinding.attributes` in the untyped syntax tree, with their original grouping and `[< >]` ranges. The rotation into `SynValInfo.retInfo` added by [PR #19738](https://github.com/dotnet/fsharp/pull/19738) now happens while normalizing a binding for checking instead of in the parser, so both fixes from that PR are unchanged while tools reading the parse tree (formatters, analyzers, source generators) again see what was written. ([PR #20356](https://github.com/dotnet/fsharp/pull/20356)) ### Breaking Changes * Add `ExtendedLayoutAttribute` support for future .NET runtime interop. `ILTypeDefLayout` has a new `Extended` case. ([Issue #19190](https://github.com/dotnet/fsharp/issues/19190), [PR #19194](https://github.com/dotnet/fsharp/pull/19194)) From a2484b866d4763f55fde01457c266654845e277e Mon Sep 17 00:00:00 2001 From: Eugene Auduchinok Date: Wed, 26 Aug 2026 16:01:04 +0200 Subject: [PATCH 3/8] Calculate Entity.PublicPath instead of storing (#20285) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * IL: derive an entity's public path from its compilation path instead of storing it entity_pubpath duplicated data the entity already had: every construction site set it to exactly the enclosing compilation path plus the entity's own logical name, as the REVIEW comment on the field had noted. Storing it cost an option, a PubPath and a fresh string[] per entity — about 100 bytes each, 2.6 MB on a 489-reference project — and the pickled form was read back into a field nothing needed. PublicPath becomes a struct over the enclosing CompilationPath and the name, so Entity.PublicPath can produce one without allocating, and the field is gone. The struct carries custom equality over the mangled path and the name only: derived equality would also compare the enclosing path's ILScopeRef and SyntaxAccess, which is stricter than the flat string[] comparison it replaces. Accessors return voption so a struct payload does not force an allocation per lookup. The pickle format is unchanged: writers derive the flat path, readers consume the index and discard it, so the pubpath table no longer builds PublicPath values. Derivation is exact at all four construction sites, and the only writes to entity_cpath and entity_logical_name after construction are in Link, which copies both from one source entity, so a derived path cannot drift from a stored one. Retained memory after ParseAndCheckProject drops 0.12-2.62 MB per project (-0.18% to -0.84%) across the measurement suite. Co-Authored-By: Claude Opus 5 (1M context) * Release notes * Release notes * Review * Compare public paths with a function, not a struct member pubPathEq ended in a call to PublicPath.Equals, and fslibRefEq in one to EqualsFullPath. A body ending in a struct member call is not inferred to make no critical tailcalls, and that inference propagates to callers: primEntityRefEq gained a .tail prefix, and from there so did tyconRefEq, tcrefAEquiv, HasHeadType and the TypeTesters predicates. A tail-prefixed call is never inlined, which cost 12% checking a two-project graph. Comparing the access paths in a plain function keeps the inference, and builds neither a MangledPath list nor a FullPath array. PublicPath no longer carries equality at all. Its only comparison was an implicit = on a PublicPath voption in Exprs.fs, which boxed both sides; that now calls pubPathEq, so structural equality on a PublicPath is a compile error rather than a silently boxing comparison. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01SSWUAYfpj82BHvzpkUCy8Z * Fantomas --------- Co-authored-by: Claude Opus 5 (1M context) Co-authored-by: Tomas Grosup --- .../.FSharp.Compiler.Service/11.0.100.md | 1 + src/Compiler/Checking/NameResolution.fs | 6 +- .../Checking/OverloadResolutionRules.fs | 2 +- src/Compiler/Service/FSharpCheckerResults.fs | 4 +- .../Service/ServiceDeclarationLists.fs | 21 +++--- src/Compiler/Symbols/Exprs.fs | 8 ++- src/Compiler/TypedTree/TypedTree.fs | 68 ++++++++++--------- src/Compiler/TypedTree/TypedTree.fsi | 34 ++++++---- src/Compiler/TypedTree/TypedTreeBasics.fs | 30 +++++--- .../TypedTree/TypedTreeOps.Attributes.fs | 4 +- .../TypedTreeOps.ExprConstruction.fs | 4 +- .../TypedTree/TypedTreeOps.FreeVars.fs | 34 +++++----- src/Compiler/TypedTree/TypedTreePickle.fs | 17 +++-- 13 files changed, 131 insertions(+), 102 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index 7865d14ca8e..bbeb2d24352 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -198,6 +198,7 @@ * Interpolated string holes (e.g. `$"{x}"`) are now formatted with invariant culture (via the `string` operator) instead of the current thread culture. ([PR #19971](https://github.com/dotnet/fsharp/pull/19971)) * Lines starting with `#:` are now ignored ([Language suggestion 1440](https://github.com/fsharp/fslang-suggestions/issues/1440), [RFC FS-1337](https://github.com/fsharp/fslang-design/pull/830), [PR #20212](https://github.com/dotnet/fsharp/pull/20212)) * `[]` attributes written in front of a binding are again reported by `SynBinding.attributes` in the untyped syntax tree, with their original grouping and `[< >]` ranges. The rotation into `SynValInfo.retInfo` added by [PR #19738](https://github.com/dotnet/fsharp/pull/19738) now happens while normalizing a binding for checking instead of in the parser, so both fixes from that PR are unchanged while tools reading the parse tree (formatters, analyzers, source generators) again see what was written. ([PR #20356](https://github.com/dotnet/fsharp/pull/20356)) +* Calculate Entity.PublicPath instead of storing ([PR #20285](https://github.com/dotnet/fsharp/pull/20285)) ### Breaking Changes * Add `ExtendedLayoutAttribute` support for future .NET runtime interop. `ILTypeDefLayout` has a new `Extended` case. ([Issue #19190](https://github.com/dotnet/fsharp/issues/19190), [PR #19194](https://github.com/dotnet/fsharp/pull/19194)) diff --git a/src/Compiler/Checking/NameResolution.fs b/src/Compiler/Checking/NameResolution.fs index 1ce55448a7f..e520c6235f6 100644 --- a/src/Compiler/Checking/NameResolution.fs +++ b/src/Compiler/Checking/NameResolution.fs @@ -1174,11 +1174,11 @@ let ResolveProvidedTypeNameInEntity (amap, m, typeName, modref: ModuleOrNamespac match modref.TypeReprInfo with | TProvidedNamespaceRepr(resolutionEnvironment, resolvers) -> match modref.Deref.PublicPath with - | Some(PubPath path) -> + | ValueSome pubpath -> resolvers - |> List.choose (fun r-> TryResolveProvidedType(r, m, path, typeName)) + |> List.choose (fun r -> TryResolveProvidedType(r, m, pubpath.FullPath, typeName)) |> List.map (fun st -> AddEntityForProvidedType (amap, modref, resolutionEnvironment, st, m)) - | None -> [] + | ValueNone -> [] // We have a provided type, look up its nested types (populating them on-demand if necessary) | TProvidedTypeRepr info -> diff --git a/src/Compiler/Checking/OverloadResolutionRules.fs b/src/Compiler/Checking/OverloadResolutionRules.fs index d099c936883..62a08c57ec8 100644 --- a/src/Compiler/Checking/OverloadResolutionRules.fs +++ b/src/Compiler/Checking/OverloadResolutionRules.fs @@ -309,7 +309,7 @@ let private compareArg (ctx: OverloadResolutionContext) (calledArg1: CalledArg) | ValueSome tcref1 when tcref1.DisplayName = "Func" && (match tcref1.PublicPath with - | Some p -> p.EnclosingPath = [| "System" |] + | ValueSome p -> p.EnclosingPath = [| "System" |] | _ -> false) && isDelegateTy g ty1 && isDelegateTy g ty2 diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs index a125c74a783..155d1b5f702 100644 --- a/src/Compiler/Service/FSharpCheckerResults.fs +++ b/src/Compiler/Service/FSharpCheckerResults.fs @@ -2741,8 +2741,8 @@ type internal TypeCheckInfo None else match tr.TypeReprInfo, tr.PublicPath with - | TILObjectRepr(TILObjectReprData(ILScopeRef.Assembly assemblyRef, _, _)), Some(PubPath parts) -> - let fullName = parts |> String.concat "." + | TILObjectRepr(TILObjectReprData(ILScopeRef.Assembly assemblyRef, _, _)), ValueSome pubpath -> + let fullName = pubpath.FullPath |> String.concat "." Some(FindDeclResult.ExternalDecl(assemblyRef.Name, FindDeclExternalSymbol.Type fullName)) | _ -> None | _ -> None diff --git a/src/Compiler/Service/ServiceDeclarationLists.fs b/src/Compiler/Service/ServiceDeclarationLists.fs index e5d76901a02..6142e72cf3c 100644 --- a/src/Compiler/Service/ServiceDeclarationLists.fs +++ b/src/Compiler/Service/ServiceDeclarationLists.fs @@ -143,17 +143,16 @@ module DeclarationListHelpers = member x.Equals(item1, item2) = nullSafeEquality item1 item2 (fun item1 item2 -> fullDisplayTextOfModRef item1 = fullDisplayTextOfModRef item2) member x.GetHashCode item = hash item.Stamp } - let OutputFullName displayFullName ppF fnF r = + let OutputFullName displayFullName hasPubPath fnF r = // Only display full names in quick info, not declaration lists or method lists - if not displayFullName then - match ppF r with - | None -> emptyL - | Some _ -> wordL (tagText (FSComp.SR.typeInfoFullName())) ^^ RightL.colon ^^ (fnF r) + if not displayFullName then + if hasPubPath r then wordL (tagText (FSComp.SR.typeInfoFullName())) ^^ RightL.colon ^^ (fnF r) + else emptyL else emptyL - let pubpathOfValRef (v: ValRef) = v.PublicPath + let hasPubPathValRef (v: ValRef) = v.PublicPath.IsSome - let pubpathOfTyconRef (x: TyconRef) = x.PublicPath + let hasPubPathTyconRef (x: TyconRef) = x.PublicPath.IsSome /// Output the quick info information of a language item let rec FormatItemDescriptionToToolTipElement displayFullName (infoReader: InfoReader) ad m denv (item: ItemWithInst) symbol (width: int option) = @@ -169,7 +168,7 @@ module DeclarationListHelpers = | Item.Value vref | Item.CustomBuilder (_, vref) -> let prettyTyparInst, resL = layoutQualifiedValOrMember denv infoReader item.TyparInstantiation vref - let remarks = OutputFullName displayFullName pubpathOfValRef fullDisplayTextOfValRefAsLayout vref + let remarks = OutputFullName displayFullName hasPubPathValRef fullDisplayTextOfValRefAsLayout vref let tpsL = FormatTyparMapping denv prettyTyparInst let typeMapping = List.map toRichText tpsL let resL = PrintUtilities.squashToWidth width resL @@ -212,7 +211,7 @@ module DeclarationListHelpers = let vTauTy = v.TauType // REVIEW: use _cxs here let (prettyTyparInst, prettyTy), _cxs = PrettyTypes.PrettifyInstAndType denv.g (item.TyparInstantiation, vTauTy) - let remarks = OutputFullName displayFullName pubpathOfValRef fullDisplayTextOfValRefAsLayout v + let remarks = OutputFullName displayFullName hasPubPathValRef fullDisplayTextOfValRefAsLayout v let layout = wordL (tagText (FSComp.SR.typeInfoActiveRecognizer())) ^^ wordL (tagActivePatternCase apref.DisplayName |> mkNav v.DefinitionRange) ^^ @@ -231,7 +230,7 @@ module DeclarationListHelpers = | Item.ExnCase ecref -> let layout = layoutExnDef denv infoReader ecref let layout = PrintUtilities.squashToWidth width layout - let remarks = OutputFullName displayFullName pubpathOfTyconRef fullDisplayTextOfExnRefAsLayout ecref + let remarks = OutputFullName displayFullName hasPubPathTyconRef fullDisplayTextOfExnRefAsLayout ecref let mainDescription = toRichText layout let remarks = toRichText remarks ToolTipElement.Single (mainDescription, xml, remarks=remarks, ?symbol = symbol) @@ -388,7 +387,7 @@ module DeclarationListHelpers = showDocumentation = false } let layout = layoutTyconDefn denv infoReader ad m (* width *) tcref.Deref let layout = PrintUtilities.squashToWidth width layout - let remarks = OutputFullName displayFullName pubpathOfTyconRef fullDisplayTextOfTyconRefAsLayout tcref + let remarks = OutputFullName displayFullName hasPubPathTyconRef fullDisplayTextOfTyconRefAsLayout tcref let mainDescription = toRichText layout let remarks = toRichText remarks ToolTipElement.Single (mainDescription, xml, remarks=remarks, ?symbol = symbol) diff --git a/src/Compiler/Symbols/Exprs.fs b/src/Compiler/Symbols/Exprs.fs index 4b6ecbec6db..caaf9cfb577 100644 --- a/src/Compiler/Symbols/Exprs.fs +++ b/src/Compiler/Symbols/Exprs.fs @@ -1065,7 +1065,11 @@ module FSharpExprConvert = |> Seq.filter (fun v -> (v.CompiledName g.CompilerGlobalState) = vName && match v.TryDeclaringEntity with - | Parent p -> p.PublicPath = enclosingEntity.PublicPath + | Parent p -> + (match p.PublicPath, enclosingEntity.PublicPath with + | ValueSome pp1, ValueSome pp2 -> pubPathEq pp1 pp2 + | ValueNone, ValueNone -> true + | _ -> false) | _ -> false ) |> List.ofSeq match findModuleMemberByName with @@ -1205,7 +1209,7 @@ module FSharpExprConvert = let argCount = (List.sumBy List.length argTys) + (if isStatic then 0 else 1) let key = ValLinkageFullKey({ MemberParentMangledName=memberParentName; MemberIsOverride=false; LogicalName=logicalName; TotalArgCount= argCount }, Some linkageType) - let (PubPath p) = tcref.PublicPath.Value + let p = tcref.PublicPath.Value.FullPath let enclosingNonLocalRef = mkNonLocalEntityRef tcref.nlr.Ccu p let vref = mkNonLocalValRef enclosingNonLocalRef key makeFSExpr isMember vref diff --git a/src/Compiler/TypedTree/TypedTree.fs b/src/Compiler/TypedTree/TypedTree.fs index 1c053557cf1..5030f59334d 100644 --- a/src/Compiler/TypedTree/TypedTree.fs +++ b/src/Compiler/TypedTree/TypedTree.fs @@ -556,15 +556,6 @@ type ModuleOrNamespaceKind = | ModuleOrType -> 1 | Namespace _ -> 2 -/// A public path records where a construct lives within the global namespace -/// of a CCU. -type PublicPath = - | PubPath of string[] - member x.EnclosingPath = - let (PubPath pp) = x - assert (pp.Length >= 1) - pp[0..pp.Length-2] - /// Represents the specified visibility of the accessibility -- used to ensure IL visibility [] type SyntaxAccess = @@ -583,9 +574,7 @@ type CompilationPath = member x.MangledPath = List.map fst x.AccessPath - member x.NestedPublicPath (id: Ident) = PubPath(Array.append (Array.ofList x.MangledPath) [| id.idText |]) - - member x.ParentCompPath = + member x.ParentCompPath = let a, _ = List.frontAndBack x.AccessPath CompPath(x.ILScopeRef, x.SyntaxAccess, a) @@ -603,6 +592,31 @@ type CompilationPath = member x.SyntaxAccess = let (CompPath(_, access, _)) = x in access +[] +type PublicPath = + | PubPath of enclosing: CompilationPath * name: string + + member x.EnclosingCompilationPath = let (PubPath(cp, _)) = x in cp + + member x.Name = let (PubPath(_, nm)) = x in nm + + member x.EnclosingPath: string[] = Array.ofList x.EnclosingCompilationPath.MangledPath + + member x.FullPath: string[] = + let enclosing = x.EnclosingCompilationPath.MangledPath + let res = Array.zeroCreate (List.length enclosing + 1) + let mutable i = 0 + + for nm in enclosing do + res[i] <- nm + i <- i + 1 + + res[i] <- x.Name + res + + member x.HasEmptyEnclosingPath = List.isEmpty x.EnclosingCompilationPath.AccessPath + + [] type EntityOptionalData = { @@ -693,12 +707,7 @@ type Entity = // when compiling fslib to fixup compiler forward references to internal items mutable entity_modul_type: MaybeLazy - /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 - // REVIEW: it looks like entity_cpath subsumes this - // MUTABILITY: only for unpickle linkage - mutable entity_pubpath: PublicPath option - - /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 + /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 // MUTABILITY: only for unpickle linkage mutable entity_cpath: CompilationPath option @@ -960,7 +969,10 @@ type Entity = | c -> c /// Get a blob of data indicating how this type is nested in other namespaces, modules or types. - member x.PublicPath = x.entity_pubpath + member x.PublicPath: PublicPath voption = + match x.entity_cpath with + | Some cpath -> ValueSome(PubPath(cpath, x.entity_logical_name)) + | None -> ValueNone /// Get the value representing the accessibility of an F# type definition or module. member x.Accessibility = @@ -1106,7 +1118,6 @@ type Entity = entity_tycon_repr= Unchecked.defaultof<_> entity_tycon_tcaug= Unchecked.defaultof<_> entity_modul_type= Unchecked.defaultof<_> - entity_pubpath = Unchecked.defaultof<_> entity_cpath = Unchecked.defaultof<_> entity_il_repr_cache = Unchecked.defaultof<_> entity_opt_data = Unchecked.defaultof<_>} @@ -1125,8 +1136,7 @@ type Entity = x.entity_tycon_repr <- tg.entity_tycon_repr x.entity_tycon_tcaug <- tg.entity_tycon_tcaug x.entity_modul_type <- tg.entity_modul_type - x.entity_pubpath <- tg.entity_pubpath - x.entity_cpath <- tg.entity_cpath + x.entity_cpath <- tg.entity_cpath x.entity_il_repr_cache <- tg.entity_il_repr_cache match tg.entity_opt_data with | Some tg -> @@ -3287,9 +3297,9 @@ type Val = member x.PublicPath = match x.TryDeclaringEntity with | Parent eref -> - match eref.PublicPath with - | None -> None - | Some p -> Some(ValPubPath(p, x.GetLinkageFullKey())) + match eref.PublicPath with + | ValueNone -> None + | ValueSome p -> Some(ValPubPath(p, x.GetLinkageFullKey())) | ParentNone -> None @@ -3946,7 +3956,7 @@ type EntityRef = member x.CompiledReprCache = x.Deref.CompiledReprCache /// Get a blob of data indicating how this type is nested in other namespaces, modules or types. - member x.PublicPath: PublicPath option = x.Deref.PublicPath + member x.PublicPath: PublicPath voption = x.Deref.PublicPath /// Get the value representing the accessibility of an F# type definition or module. member x.Accessibility = x.Deref.Accessibility @@ -6324,7 +6334,6 @@ type Construct() = static member NewProvidedTycon(resolutionEnvironment, st: Tainted, importProvidedType, isSuppressRelocate, m, ?access, ?cpath) = let stamp = newStamp() let name = st.PUntaint((fun st -> st.Name), m) - let id = ident (name, m) let kind = let isMeasure = st.PApplyWithProvider((fun (st, provider) -> @@ -6344,7 +6353,6 @@ type Construct() = let enclosingName = GetFSharpPathToProvidedType(st, m) CompPath(ilScopeRef, SyntaxAccess.Unknown, enclosingName |> List.map(fun id->id, ModuleOrNamespaceKind.Namespace true)) | Some p -> p - let pubpath = cpath.NestedPublicPath id let repr = Construct.NewProvidedTyconRepr(resolutionEnvironment, st, importProvidedType, isSuppressRelocate, m) @@ -6359,7 +6367,6 @@ type Construct() = entity_tycon_tcaug=TyconAugmentation.Create() entity_modul_type = MaybeLazy.Lazy(InterruptibleLazy(fun _ -> ModuleOrNamespaceType(Namespace true, QueueList.ofList [], QueueList.ofList []))) // Generated types get internal accessibility - entity_pubpath = Some pubpath entity_cpath = Some cpath entity_il_repr_cache = null entity_opt_data = @@ -6383,7 +6390,6 @@ type Construct() = entity_typars=LazyWithContext.NotLazy [] entity_tycon_repr = TNoRepr entity_tycon_tcaug=TyconAugmentation.Create() - entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath id) entity_cpath=cpath entity_attribs=WellKnownEntityAttribs.Create(attribs) entity_il_repr_cache = null @@ -6458,7 +6464,6 @@ type Construct() = entity_logical_name = id.idText entity_range = id.idRange entity_tycon_tcaug = TyconAugmentation.Create() - entity_pubpath = cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath id) entity_modul_type = MaybeLazy.Strict (Construct.NewEmptyModuleOrNamespaceType ModuleOrType) entity_cpath = cpath entity_typars = LazyWithContext.NotLazy [] @@ -6501,7 +6506,6 @@ type Construct() = entity_tycon_repr = TNoRepr entity_tycon_tcaug=TyconAugmentation.Create() entity_modul_type = mtyp - entity_pubpath=cpath |> Option.map (fun (cp: CompilationPath) -> cp.NestedPublicPath (mkSynId m nm)) entity_cpath = cpath entity_il_repr_cache = null entity_opt_data = diff --git a/src/Compiler/TypedTree/TypedTree.fsi b/src/Compiler/TypedTree/TypedTree.fsi index d97811bdd6c..d706237e468 100644 --- a/src/Compiler/TypedTree/TypedTree.fsi +++ b/src/Compiler/TypedTree/TypedTree.fsi @@ -340,13 +340,6 @@ type ModuleOrNamespaceKind = /// If false, this namespace was implicitly constructed during type checking. isExplicit: bool -/// A public path records where a construct lives within the global namespace -/// of a CCU. -type PublicPath = - | PubPath of string[] - - member EnclosingPath: string[] - /// Represents the specified visibility of the accessibility -- used to ensure IL visibility [] type SyntaxAccess = @@ -364,8 +357,6 @@ type CompilationPath = member NestedCompPath: n: string -> moduleKind: ModuleOrNamespaceKind -> CompilationPath - member NestedPublicPath: id: Ident -> PublicPath - member AccessPath: (string * ModuleOrNamespaceKind) list member DemangledPath: string list @@ -378,6 +369,24 @@ type CompilationPath = member SyntaxAccess: SyntaxAccess +/// A public path records where a construct lives within the global namespace of a CCU. +/// +/// Comparison goes through pubPathEq: derived equality would also compare the enclosing path's +/// ILScopeRef and SyntaxAccess, besides boxing this struct. +[] +type PublicPath = + | PubPath of enclosing: CompilationPath * name: string + + member EnclosingCompilationPath: CompilationPath + + member Name: string + + member EnclosingPath: string[] + + member FullPath: string[] + + member HasEmptyEnclosingPath: bool + [] type EntityOptionalData = { @@ -449,9 +458,6 @@ type Entity = /// This field is used when the 'tycon' is really a module definition. It holds statically nested type definitions type nested modules mutable entity_modul_type: MaybeLazy - /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 - mutable entity_pubpath: PublicPath option - /// The stable path to the type, e.g. Microsoft.FSharp.Core.FSharpFunc`2 mutable entity_cpath: CompilationPath option @@ -768,7 +774,7 @@ type Entity = member PreEstablishedHasDefaultConstructor: bool /// Get a blob of data indicating how this type is nested in other namespaces, modules or types. - member PublicPath: PublicPath option + member PublicPath: PublicPath voption /// The code location where the module, namespace or type is defined. member Range: range @@ -2750,7 +2756,7 @@ type EntityRef = member PreEstablishedHasDefaultConstructor: bool /// Get a blob of data indicating how this type is nested in other namespaces, modules or types. - member PublicPath: PublicPath option + member PublicPath: PublicPath voption /// The code location where the module, namespace or type is defined. member Range: range diff --git a/src/Compiler/TypedTree/TypedTreeBasics.fs b/src/Compiler/TypedTree/TypedTreeBasics.fs index 6c14530109a..ee55156caca 100644 --- a/src/Compiler/TypedTree/TypedTreeBasics.fs +++ b/src/Compiler/TypedTree/TypedTreeBasics.fs @@ -366,10 +366,10 @@ let mkNestedValRef (cref: EntityRef) (v: Val) : ValRef = mkNonLocalValRefPreResolved v nlr key /// From Ref_private to Ref_nonlocal when exporting data. -let rescopePubPathToParent viewedCcu (PubPath p) = NonLocalEntityRef(viewedCcu, p[0..p.Length-2]) +let rescopePubPathToParent viewedCcu (pp: PublicPath) = NonLocalEntityRef(viewedCcu, pp.EnclosingPath) /// From Ref_private to Ref_nonlocal when exporting data. -let rescopePubPath viewedCcu (PubPath p) = NonLocalEntityRef(viewedCcu, p) +let rescopePubPath viewedCcu (pp: PublicPath) = NonLocalEntityRef(viewedCcu, pp.FullPath) //--------------------------------------------------------------------------- // Equality between TAST items. @@ -414,10 +414,20 @@ let nonLocalRefEq (NonLocalEntityRef(x1, y1) as smr1) (NonLocalEntityRef(x2, y2) let nonLocalRefDefinitelyNotEq (NonLocalEntityRef(_, y1)) (NonLocalEntityRef(_, y2)) = not (arrayPathEq y1 y2) -let pubPathEq (PubPath path1) (PubPath path2) = arrayPathEq path1 path2 +// A function rather than a member on PublicPath: the optimizer does not see through a struct member +// call when inferring MightMakeCriticalTailcall, and this runs in tail position from fslibEntityRefEq. +let pubPathEq (path1: PublicPath) (path2: PublicPath) = + let rec loop p1 p2 = + match p1, p2 with + | [], [] -> true + | (nm1, _) :: rest1, (nm2, _) :: rest2 -> nm1 = nm2 && loop rest1 rest2 + | _ -> false + + path1.Name = path2.Name + && loop path1.EnclosingCompilationPath.AccessPath path2.EnclosingCompilationPath.AccessPath -let fslibRefEq (nlr1: NonLocalEntityRef) (PubPath path2) = - arrayPathEq nlr1.Path path2 +let fslibRefEq (nlr1: NonLocalEntityRef) (path2: PublicPath) = + arrayPathEq nlr1.Path path2.FullPath // Compare two EntityRef's for equality when compiling fslib (FSharp.Core.dll) // @@ -430,12 +440,12 @@ let fslibEntityRefEq fslibCcu (eref1: EntityRef) (eref2: EntityRef) = | ERefNonLocal nlr1, ERefLocal x2 | ERefLocal x2, ERefNonLocal nlr1 -> ccuEq nlr1.Ccu fslibCcu && - match x2.PublicPath with - | Some pp2 -> fslibRefEq nlr1 pp2 - | None -> false + match x2.PublicPath with + | ValueSome pp2 -> fslibRefEq nlr1 pp2 + | ValueNone -> false | ERefLocal e1, ERefLocal e2 -> - match e1.PublicPath, e2.PublicPath with - | Some pp1, Some pp2 -> pubPathEq pp1 pp2 + match e1.PublicPath, e2.PublicPath with + | ValueSome pp1, ValueSome pp2 -> pubPathEq pp1 pp2 | _ -> false | _ -> false diff --git a/src/Compiler/TypedTree/TypedTreeOps.Attributes.fs b/src/Compiler/TypedTree/TypedTreeOps.Attributes.fs index 771f6036e25..3210c1714e2 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.Attributes.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.Attributes.fs @@ -255,8 +255,8 @@ module internal AttributeHelpers = struct (ValueSome nlr.Path, ValueNone) elif g.compilingFSharpCore then match tcref.Deref.PublicPath with - | Some(PubPath pp) -> struct (ValueNone, ValueSome pp) - | None -> struct (ValueNone, ValueNone) + | ValueSome pubpath -> struct (ValueNone, ValueSome pubpath.FullPath) + | ValueNone -> struct (ValueNone, ValueNone) else struct (ValueNone, ValueNone) diff --git a/src/Compiler/TypedTree/TypedTreeOps.ExprConstruction.fs b/src/Compiler/TypedTree/TypedTreeOps.ExprConstruction.fs index 7cd2846f7ca..5c0763f2216 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.ExprConstruction.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.ExprConstruction.fs @@ -596,8 +596,8 @@ module internal TypeTesters = /// Try to create a EntityRef suitable for accessing the given Entity from another assembly let tryRescopeEntity viewedCcu (entity: Entity) : EntityRef voption = match entity.PublicPath with - | Some pubpath -> ValueSome(ERefNonLocal(rescopePubPath viewedCcu pubpath)) - | None -> ValueNone + | ValueSome pubpath -> ValueSome(ERefNonLocal(rescopePubPath viewedCcu pubpath)) + | ValueNone -> ValueNone /// Try to create a ValRef suitable for accessing the given Val from another assembly let tryRescopeVal viewedCcu (entityRemap: Remap) (vspec: Val) : ValRef voption = diff --git a/src/Compiler/TypedTree/TypedTreeOps.FreeVars.fs b/src/Compiler/TypedTree/TypedTreeOps.FreeVars.fs index 50f7af9014b..975ff6cfb3a 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.FreeVars.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.FreeVars.fs @@ -1313,18 +1313,20 @@ module internal MemberRepresentation = let layoutOfPath p = sepListL SepL.dot (List.map (tagNamespace >> wordL) p) - let fullNameOfParentOfPubPath pp = - match pp with - | PubPath([| _ |]) -> ValueNone - | pp -> ValueSome(textOfPath pp.EnclosingPath) + let fullNameOfParentOfPubPath (pp: PublicPath) = + if pp.HasEmptyEnclosingPath then + ValueNone + else + ValueSome(textOfPath pp.EnclosingPath) - let fullNameOfParentOfPubPathAsLayout pp = - match pp with - | PubPath([| _ |]) -> ValueNone - | pp -> ValueSome(layoutOfPath (Array.toList pp.EnclosingPath)) + let fullNameOfParentOfPubPathAsLayout (pp: PublicPath) = + if pp.HasEmptyEnclosingPath then + ValueNone + else + ValueSome(layoutOfPath pp.EnclosingCompilationPath.MangledPath) - let fullNameOfPubPath (PubPath p) = textOfPath p - let fullNameOfPubPathAsLayout (PubPath p) = layoutOfPath (Array.toList p) + let fullNameOfPubPath (pp: PublicPath) = textOfPath pp.FullPath + let fullNameOfPubPathAsLayout (pp: PublicPath) = layoutOfPath (Array.toList pp.FullPath) let fullNameOfParentOfNonLocalEntityRef (nlr: NonLocalEntityRef) = if nlr.Path.Length < 2 then @@ -1342,16 +1344,16 @@ module internal MemberRepresentation = match eref with | ERefLocal x -> match x.PublicPath with - | None -> ValueNone - | Some ppath -> fullNameOfParentOfPubPath ppath + | ValueNone -> ValueNone + | ValueSome ppath -> fullNameOfParentOfPubPath ppath | ERefNonLocal nlr -> fullNameOfParentOfNonLocalEntityRef nlr let fullNameOfParentOfEntityRefAsLayout eref = match eref with | ERefLocal x -> match x.PublicPath with - | None -> ValueNone - | Some ppath -> fullNameOfParentOfPubPathAsLayout ppath + | ValueNone -> ValueNone + | ValueSome ppath -> fullNameOfParentOfPubPathAsLayout ppath | ERefNonLocal nlr -> fullNameOfParentOfNonLocalEntityRefAsLayout nlr let fullNameOfEntityRef nmF xref = @@ -1529,8 +1531,8 @@ module internal MemberRepresentation = match tcref with | ERefLocal _ -> (match tcref.PublicPath with - | None -> [||] - | Some pp -> pp.EnclosingPath) + | ValueNone -> [||] + | ValueSome pp -> pp.EnclosingPath) | ERefNonLocal nlr -> nlr.EnclosingMangledPath /// generates a name like 'System.IComparable.Get' diff --git a/src/Compiler/TypedTree/TypedTreePickle.fs b/src/Compiler/TypedTree/TypedTreePickle.fs index 90bb7e9482f..921f194ce34 100644 --- a/src/Compiler/TypedTree/TypedTreePickle.fs +++ b/src/Compiler/TypedTree/TypedTreePickle.fs @@ -200,7 +200,7 @@ type ReaderState = ivals: NodeInTable ianoninfos: NodeInTable istrings: InputTable - ipubpaths: InputTable + ipubpaths: InputTable inlerefs: InputTable isimpletys: InputTable ifile: string @@ -869,12 +869,12 @@ let p_ccuref s st = p_int (encode_ccuref st.occus s) st // References to public items in this module // A huge number of these occur in pickled F# data, so make them unique let decode_pubpath st stringTab a = - PubPath(Array.map (lookup_string st stringTab) a) + Array.map (lookup_string st stringTab) a let u_encoded_pubpath = u_array u_int let u_pubpath st = lookup_uniq st st.ipubpaths (u_int st) -let encode_pubpath stringTab pubpathTab (PubPath a) = +let encode_pubpath stringTab pubpathTab (a: string[]) = encode_uniq pubpathTab (Array.map (encode_string stringTab) a) let p_encoded_pubpath = p_array p_int @@ -897,7 +897,7 @@ let encode_nleref ccuTab stringTab nlerefTab thisCcu (nleref: NonLocalEntityRef) // References to these nodes _do_ appear in F# assembly metadata, because they may be public. let nleref = match nleref.Deref.PublicPath with - | Some pubpath when nleref.Deref.IsProvidedGeneratedTycon -> + | ValueSome pubpath when nleref.Deref.IsProvidedGeneratedTycon -> if verbose then dprintfn "remapping pickled reference to provider-generated type %s" nleref.Deref.DisplayNameWithStaticParameters @@ -2818,7 +2818,11 @@ and p_entity_spec_data (x: Entity) st = p_string x.entity_logical_name st p_option p_string x.EntityCompiledName st p_range x.entity_range st - p_option p_pubpath x.entity_pubpath st + let pubPathOpt = + match x.PublicPath with + | ValueSome pubpath -> Some pubpath.FullPath + | ValueNone -> None + p_option p_pubpath pubPathOpt st p_access x.Accessibility st p_access x.TypeReprAccessibility st p_attribs (x.entity_attribs.AsList()) st @@ -3147,7 +3151,7 @@ and u_rfield_table st = Construct.MakeRecdFieldsTable(u_list u_recdfield_spec st) and u_entity_spec_data st : Entity = - let x1, x2a, x2b, x2c, x3, (x4a, x4b), x6, x7f, x8, x9, _x10, x10b, x11, x12, x13, x14, x15 = + let x1, x2a, x2b, x2c, _x3, (x4a, x4b), x6, x7f, x8, x9, _x10, x10b, x11, x12, x13, x14, x15 = u_tup17 u_tyar_specs u_string @@ -3176,7 +3180,6 @@ and u_entity_spec_data st : Entity = entity_stamp = newStamp () entity_logical_name = x2a entity_range = x2c - entity_pubpath = x3 entity_attribs = WellKnownEntityAttribs.Create(x6) entity_tycon_repr = x7 entity_tycon_tcaug = x9 From 65c286f04562194b78a05fa7f5c6305cfac7f2d5 Mon Sep 17 00:00:00 2001 From: Andrii Chebukin Date: Wed, 26 Aug 2026 16:09:41 +0200 Subject: [PATCH 4/8] Cleanup: use `FindByNameAndArity` guard in `CheckILBaseCall` to avoid exception-based control flow for inherited IL methods (#20272) * Fix inherited IL base-call crash and add release notes * Address review: inherit the IL method in the 20264 test, resolve via FindByNameAndArity, and keep a try/with around signature matching. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * PR review fix * Clarify IL base-call check notes, split #20264 test Release notes now specify skipping `resolveILMethodRefWithRescope` only when the method isn't on the immediate IL type, not via exception flow. The `SimpleInteropTests.fs` test for #20264 is split: one test checks inherited non-abstract IL base method calls on generics succeed, the other checks abstract base method calls on generics fail with FS1201. Test names and code are now clearer and more targeted. --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .../.FSharp.Compiler.Service/11.0.100.md | 1 + src/Compiler/AbstractIL/il.fsi | 2 + src/Compiler/Checking/PostInferenceChecks.fs | 20 ++++--- .../Interop/SimpleInteropTests.fs | 55 +++++++++++++++++++ 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index bbeb2d24352..ce58fd2188d 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -99,6 +99,7 @@ * Fix Debug-mode compilation when mixing resumable and standard computation expressions. ([Issue #19625](https://github.com/dotnet/fsharp/issues/19625), [PR #19630](https://github.com/dotnet/fsharp/pull/19630)) * IlxGen: fix missing CompilationMapping attribute for generic values ([PR #19643](https://github.com/dotnet/fsharp/pull/19643)) * Fix internal error `FS0192: encodeCustomAttrElemType` when using arrays of user-defined types as custom attribute arguments. Empty arrays (e.g. `[]`) now compile successfully; non-empty arrays of unencodable types report a proper diagnostic (FS3887) instead of an internal error. ([Issue #12796](https://github.com/dotnet/fsharp/issues/12796), [PR #19472](https://github.com/dotnet/fsharp/pull/19472)) +* Cleanup in IL base-call checking: skip `resolveILMethodRefWithRescope` when the method is not declared on the immediate IL type, instead of relying on the `try/with` around a `failwith`. `FS1201` still applies when the abstract member is declared on the immediate IL base. ([Issue #20264](https://github.com/dotnet/fsharp/issues/20264), [PR #20272](https://github.com/dotnet/fsharp/pull/20272)) * Fix internal compiler error in `use` bindings when a C#-style `Dispose` extension method is in scope alongside `IDisposable.Dispose`. ([Issue #19552](https://github.com/dotnet/fsharp/issues/19552), [PR #19568](https://github.com/dotnet/fsharp/pull/19568)) * Fix signature generation: single-case struct DU gets spurious bar causing FS0300. ([Issue #19597](https://github.com/dotnet/fsharp/issues/19597), [PR #19609](https://github.com/dotnet/fsharp/pull/19609)) * Fix signature generation: backticked active pattern case names lose escaping. ([Issue #19592](https://github.com/dotnet/fsharp/issues/19592), [PR #19609](https://github.com/dotnet/fsharp/pull/19609)) diff --git a/src/Compiler/AbstractIL/il.fsi b/src/Compiler/AbstractIL/il.fsi index 1aeac5f861b..f6ed7d039de 100644 --- a/src/Compiler/AbstractIL/il.fsi +++ b/src/Compiler/AbstractIL/il.fsi @@ -1262,6 +1262,8 @@ type ILMethodDefs = member FindByName: string -> ILMethodDef list + member internal FindByNameAndArity: string * int -> ILMethodDef list + member TryFindInstanceByNameAndCallingSignature: string * ILCallingSignature -> ILMethodDef option /// Field definitions. diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs index 6e0b46c8fa4..6437d4d151c 100644 --- a/src/Compiler/Checking/PostInferenceChecks.fs +++ b/src/Compiler/Checking/PostInferenceChecks.fs @@ -1358,15 +1358,17 @@ and CheckILBaseCall cenv env (ilMethRef, enclTypeInst, methInst, retTypes, tyarg // Disallow calls to abstract base methods on IL types. match tryTcrefOfAppTy g baseVal.Type with | ValueSome tcref when tcref.IsILTycon -> - try - let mdef = - match tcref.ILTyconInfo with - | TILObjectReprData(scoref, _, _) -> - resolveILMethodRefWithRescope (rescopeILType scoref) tcref.ILTyconRawMetadata ilMethRef - - if mdef.IsAbstract then - errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(RichText.mkMethod mdef.Name), m)) - with _ -> () + match tcref.ILTyconInfo with + | TILObjectReprData(scoref, _, _) -> + if not (isNil (tcref.ILTyconRawMetadata.Methods.FindByNameAndArity(ilMethRef.Name, ilMethRef.ArgTypes.Length))) then + try + let mdef = + resolveILMethodRefWithRescope (rescopeILType scoref) tcref.ILTyconRawMetadata ilMethRef + + if mdef.IsAbstract then + errorR(Error(FSComp.SR.tcCannotCallAbstractBaseMember(RichText.mkMethod mdef.Name), m)) + with _ -> + () | _ -> () CheckTypeInstNoByrefs cenv env m tyargs diff --git a/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs b/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs index 00a5781553f..b53bd01458f 100644 --- a/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Interop/SimpleInteropTests.fs @@ -223,3 +223,58 @@ let main _ = |> asExe |> compileExeAndRun |> shouldSucceed + + // https://github.com/dotnet/fsharp/issues/20264 + [] + let ``Issue 20264 - inherited non-abstract IL base method on generic type`` () = + let csLib = + CSharp + """ +namespace External +{ + public abstract class BehaviorBase { + public virtual void OnDetaching() { } + } + public class Behavior : BehaviorBase { } +} + """ + |> withName "ExternalBehavior" + + FSharp + """ +module TestIssue20264 +open External +type MyBehavior() = + inherit Behavior() + member _.Test() = base.OnDetaching() + """ + |> withReferences [ csLib ] + |> compile + |> shouldSucceed + + [] + let ``Issue 20264 - abstract IL base method on immediate generic type`` () = + let csLib = + CSharp + """ +namespace External +{ + public abstract class Behavior { + public abstract void AbstractDetaching(); + } +} + """ + |> withName "ExternalBehaviorAbstract" + + FSharp + """ +module TestIssue20264Abstract +open External +type MyBehavior() = + inherit Behavior() + override _.AbstractDetaching() = base.AbstractDetaching() + """ + |> withReferences [ csLib ] + |> compile + |> shouldFail + |> withErrorCode 1201 From be2f84a68fb4752df317a54278221644fc9ebfae Mon Sep 17 00:00:00 2001 From: Edgar Gonzalez Date: Wed, 26 Aug 2026 16:11:34 +0200 Subject: [PATCH 5/8] Reject bitwise operators on char-backed enums (#11785) (#20322) --- .../.FSharp.Compiler.Service/11.0.100.md | 1 + docs/release-notes/.Language/preview.md | 2 + src/Compiler/Checking/ConstraintSolver.fs | 10 ++++- src/Compiler/FSComp.txt | 1 + src/Compiler/Facilities/LanguageFeatures.fs | 3 ++ src/Compiler/Facilities/LanguageFeatures.fsi | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 +++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 +++ .../EnumTypes/E_BitwiseOpsOnCharEnum.fs | 8 ++++ .../EnumTypes/EnumTypes.fs | 42 +++++++++++++++++++ .../EnumTypes/ExtensionBitwiseOrOnCharEnum.fs | 20 +++++++++ 22 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/E_BitwiseOpsOnCharEnum.fs create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/ExtensionBitwiseOrOnCharEnum.fs diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index ce58fd2188d..c622916be07 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -43,6 +43,7 @@ * Fix FS0421 "The address of the variable cannot be used at this point" incorrectly raised for the discard pattern `let _ = &expr` when `let x = &expr` compiles. ([Issue #18841](https://github.com/dotnet/fsharp/issues/18841), [PR #19811](https://github.com/dotnet/fsharp/pull/19811)) * Fix double `Dispose` call when a `use` binding aliases its value via an `as` pattern or rebinds an existing `use`-bound value. ([Issue #12300](https://github.com/dotnet/fsharp/issues/12300), [PR #19858](https://github.com/dotnet/fsharp/pull/19858)) * Honor `--nowarn` and `--warnaserror` for warnings emitted during command-line option parsing ([Issue #19576](https://github.com/dotnet/fsharp/issues/19576), [PR #19776](https://github.com/dotnet/fsharp/pull/19776)) +* Bitwise operators (`|||`, `&&&`, `^^^`) applied to enums with a non-integral underlying type (e.g. `char`) are now rejected at compile time with FS0001 instead of compiling and failing at runtime with `NotSupportedException`. Gated behind the `ErrorOnBitwiseOpsOnNonIntegralEnums` language feature (F# 11.0). ([Issue #11785](https://github.com/dotnet/fsharp/issues/11785), [PR #20322](https://github.com/dotnet/fsharp/pull/20322)) * Fix `[]` prefix attributes being silently dropped on class members, and fix false-positive `AllowMultiple=false` errors when `[]` and `[]` are applied to the same binding. ([Issue #17904](https://github.com/dotnet/fsharp/issues/17904), [Issue #19020](https://github.com/dotnet/fsharp/issues/19020), [PR #19738](https://github.com/dotnet/fsharp/pull/19738)) * Fix `=` adjacent to an interpolated string (e.g. `C(Name=$"value")`) being lexed as the invalid operator `=$` instead of an assignment followed by an interpolated string. ([Issue #16696](https://github.com/dotnet/fsharp/issues/16696)) * Extend the `=` adjacent to an interpolated string fix to the verbatim (`=$@"…"`, `=@$"…"`) and extended multi-dollar (`=$$"""…"""`) interpolated-string forms. ([Issue #16696](https://github.com/dotnet/fsharp/issues/16696), [PR #19984](https://github.com/dotnet/fsharp/pull/19984)) diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md index b2048b549af..d15ec5177c9 100644 --- a/docs/release-notes/.Language/preview.md +++ b/docs/release-notes/.Language/preview.md @@ -35,6 +35,8 @@ ### Fixed +* Bitwise operators (`|||`, `&&&`, `^^^`) on enums whose underlying type is not an integer type (e.g. `char`) are now a compile-time error (FS0001, consistent with `~~~`, `<<<`, `>>>`) instead of a runtime `NotSupportedException`. ([Issue #11785](https://github.com/dotnet/fsharp/issues/11785), [PR #20322](https://github.com/dotnet/fsharp/pull/20322)) + ### Changed * Inline functions now keep SRTP constraints generic instead of eagerly resolving through weak resolution. This changes inferred types for some inline code — see [RFC FS-1043 compatibility section](https://github.com/fsharp/fslang-design/blob/main/RFCs/FS-1043-extension-members-for-operators-and-srtp-constraints.md) for details and workarounds. diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index aec5c02e758..838a534f2a2 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -452,8 +452,14 @@ let IsCharOrStringType g ty = isCharTy g ty || isStringTy g ty /// Checks the argument type for a built-in solution to an op_Addition, op_Subtraction or op_Modulus constraint. let IsAddSubModType nm g ty = IsNumericOrIntegralEnumType g ty || (nm = "op_Addition" && IsCharOrStringType g ty) || (nm = "op_Subtraction" && isCharTy g ty) -/// Checks the argument type for a built-in solution to a bitwise operator constraint -let IsBitwiseOpType g ty = IsIntegerOrIntegerEnumTy g ty || (isEnumTy g ty) +/// Checks the argument type for a built-in solution to a bitwise operator constraint. +/// +/// Enums whose underlying type is not an integer type (e.g. 'char') have no runtime +/// implementation of the bitwise operators (see issue #11785) and so are only accepted +/// for compatibility with language versions predating the ErrorOnBitwiseOpsOnNonIntegralEnums feature. +let IsBitwiseOpType (g: TcGlobals) ty = + IsIntegerOrIntegerEnumTy g ty + || (isEnumTy g ty && not (g.langVersion.SupportsFeature LanguageFeature.ErrorOnBitwiseOpsOnNonIntegralEnums)) /// Check the other type in a built-in solution for a binary operator. /// For weak resolution, require a relevant primitive on one side. diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index f357d733f74..531ae517fd0 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1797,6 +1797,7 @@ featureMethodOverloadsCache,"Support for caching method overload resolution resu featureImplicitDIMCoverage,"Implicit dispatch slot coverage for default interface member implementations" featurePreprocessorElif,"#elif preprocessor directive" featureExtensionConstraintSolutions,"Allow extension members to participate in SRTP constraint resolution" +featureErrorOnBitwiseOpsOnNonIntegralEnums,"Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char)." 3880,optsLangVersionOutOfSupport,"Language version '%s' is out of support. The last .NET SDK supporting it is available at https://dotnet.microsoft.com/en-us/download/dotnet/%s" 3881,optsUnrecognizedLanguageFeature,"Unrecognized language feature name: '%s'. Use a valid feature name such as 'NameOf' or 'StringInterpolation'." 3882,lexHashElifMustBeFirst,"#elif directive must appear as the first non-whitespace character on a line" diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index ab6ace19aae..df7cc294aa4 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -98,6 +98,7 @@ type LanguageFeature = | AccessProtectedBaseFieldFromClosure | ImprovedImpliedArgumentNamesPartTwo | RecordSpreads + | ErrorOnBitwiseOpsOnNonIntegralEnums /// LanguageVersion management type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array) = @@ -220,6 +221,7 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array) // Put stabilized features here for F# 11.0 previews via .NET SDK preview channels LanguageFeature.WarnWhenFunctionValueUsedAsInterpolatedStringArg, languageVersion110 LanguageFeature.PreprocessorElif, languageVersion110 + LanguageFeature.ErrorOnBitwiseOpsOnNonIntegralEnums, languageVersion110 LanguageFeature.ExceptionFieldSerializationSupport, languageVersion110 LanguageFeature.NotNullIfNotNull, languageVersion110 LanguageFeature.ImprovedImpliedArgumentNamesPartTwo, languageVersion110 @@ -421,6 +423,7 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array) | LanguageFeature.AccessProtectedBaseFieldFromClosure -> FSComp.SR.featureAccessProtectedBaseFieldFromClosure () | LanguageFeature.ImprovedImpliedArgumentNamesPartTwo -> FSComp.SR.featureImprovedImpliedArgumentNamesPartTwo () | LanguageFeature.RecordSpreads -> FSComp.SR.featureRecordSpreads () + | LanguageFeature.ErrorOnBitwiseOpsOnNonIntegralEnums -> FSComp.SR.featureErrorOnBitwiseOpsOnNonIntegralEnums () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index f19abbb861e..9db6bee529e 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -89,6 +89,7 @@ type LanguageFeature = | AccessProtectedBaseFieldFromClosure | ImprovedImpliedArgumentNamesPartTwo | RecordSpreads + | ErrorOnBitwiseOpsOnNonIntegralEnums /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index dc4782c9ed4..61211b419b4 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -402,6 +402,11 @@ Vyvolá chyby pro přepsání jiných než virtuálních členů + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute chyba při zastaralém přístupu konstruktoru s atributem RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 4cb29a257b1..28019bbdaf3 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -402,6 +402,11 @@ Löst Fehler für Außerkraftsetzungen nicht virtueller Member aus. + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute Beim veralteten Zugriff auf das Konstrukt mit dem RequireQualifiedAccess-Attribut wird ein Fehler ausgegeben. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 3c9a547190c..0d5158ff312 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -402,6 +402,11 @@ Genera errores para invalidaciones de miembros no virtuales + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute error en el acceso en desuso de la construcción con el atributo RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 4fa634e0bf4..b1222d679d8 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -402,6 +402,11 @@ Déclenche des erreurs pour les remplacements de membres non virtuels + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute donner une erreur sur l’accès déconseillé de la construction avec l’attribut RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 847a812bca6..748229772c3 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -402,6 +402,11 @@ Genera errori per gli override dei membri non virtuali + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute errore durante l'accesso deprecato del costrutto con l'attributo RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 1984f24be07..e413d95f6d4 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -402,6 +402,11 @@ 仮想メンバー以外のオーバーライドに対してエラーを発生させます + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute RequireQualifiedAccess 属性を持つコンストラクトの非推奨アクセスでエラーが発生しました diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 1c926d2f636..26f6ef4e6ed 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -402,6 +402,11 @@ 비가상 멤버 재정의에 대한 오류 발생 + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute RequireQualifiedAccess 특성을 사용하여 사용되지 않는 구문 액세스에 대한 오류 제공 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 184e743f9ab..623fb303116 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -402,6 +402,11 @@ Zgłasza błędy w przypadku przesłonięć elementów innych niż wirtualne + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute wskazywanie błędu w przypadku przestarzałego dostępu do konstrukcji z atrybutem RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index d45561696cc..c11f600ad14 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -402,6 +402,11 @@ Gera erros para substituições de membros não virtuais + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute fornecer erro no acesso preterido do constructo com o atributo RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index a354c753312..a877af1b88c 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -402,6 +402,11 @@ Вызывает ошибки при переопределениях невиртуальных элементов + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute выдать ошибку при устаревшем доступе к конструкции с атрибутом RequireQualifiedAccess diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 8eee8e0f00b..bced047f177 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -402,6 +402,11 @@ Sanal olmayan üyelerde geçersiz kılmalar için hatalar oluştur + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute RequireQualifiedAccess özniteliğine sahip yapının kullanım dışı erişiminde hata diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 8b416bf6648..1193d6bfcfe 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -402,6 +402,11 @@ 引发非虚拟成员替代的错误 + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute 对具有 RequireQualifiedAccess 属性的构造进行弃用的访问时出错 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index c8848815e00..f1a7a9b02aa 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -402,6 +402,11 @@ 引發非虛擬成員覆寫的錯誤 + + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + Error when bitwise operators are used on enums whose underlying type is not an integer type (e.g. char). + + give error on deprecated access of construct with RequireQualifiedAccess attribute 對具有 RequireQualifiedAccess 屬性的建構的已取代存取發出錯誤 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/E_BitwiseOpsOnCharEnum.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/E_BitwiseOpsOnCharEnum.fs new file mode 100644 index 00000000000..7f715a88168 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/E_BitwiseOpsOnCharEnum.fs @@ -0,0 +1,8 @@ +// #Regression #Conformance #ObjectOrientedTypes #Enums +// Regression test for https://github.com/dotnet/fsharp/issues/11785 + +type CharEnum = A = 'A' | B = 'B' + +let bitwiseOr = CharEnum.A ||| CharEnum.B +let bitwiseAnd = CharEnum.A &&& CharEnum.B +let exclusiveOr = CharEnum.A ^^^ CharEnum.B diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/EnumTypes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/EnumTypes.fs index e8b43ce72c0..b896c6b1696 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/EnumTypes.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/EnumTypes.fs @@ -10,6 +10,48 @@ module EnumTypes = // Error tests - should fail with expected error codes + [] + let ``E_BitwiseOpsOnCharEnum_fs`` compilation = + compilation + |> getCompilation + |> asExe + |> withOptions ["--test:ErrorRanges"] + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 1, Line 6, Col 17, Line 6, Col 27, "The type 'CharEnum' does not support the operator '|||'") + (Error 1, Line 7, Col 18, Line 7, Col 28, "The type 'CharEnum' does not support the operator '&&&'") + (Error 1, Line 8, Col 19, Line 8, Col 29, "The type 'CharEnum' does not support the operator '^^^'") + ] + + [] + let ``E_BitwiseOpsOnCharEnum_fs - compat with langversion 10`` compilation = + compilation + |> getCompilation + |> asExe + |> withLangVersion10 + |> typecheck + |> shouldSucceed + + [] + let ``ExtensionBitwiseOrOnCharEnum_fs - ExtensionConstraintSolutions`` compilation = + compilation + |> getCompilation + |> asExe + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + + [] + let ``ExtensionBitwiseOrOnCharEnum_fs - error without ExtensionConstraintSolutions`` compilation = + compilation + |> getCompilation + |> asExe + |> typecheck + |> shouldFail + |> withErrorCode 1 + |> withDiagnosticMessageMatches "The type 'E' does not support the operator '\\|\\|\\|'" + [] let ``E_BoolUnderlyingType_fs`` compilation = compilation diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/ExtensionBitwiseOrOnCharEnum.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/ExtensionBitwiseOrOnCharEnum.fs new file mode 100644 index 00000000000..d3bb04aa669 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/ObjectOrientedTypeDefinitions/EnumTypes/ExtensionBitwiseOrOnCharEnum.fs @@ -0,0 +1,20 @@ +// #Conformance #ObjectOrientedTypes #Enums +// Regression test for https://github.com/dotnet/fsharp/issues/11785 + +module M = + type E = A = 'A' | B = 'B' + +[] +module Ext = + type M.E with + static member (|||) (a: M.E, b: M.E) = M.E.B + +open M + +[] +let main _ = + let r = E.A ||| E.B + if r <> E.B then + failwith "expected the extension (|||) to be used" + + 0 From 980242595d89534d96daec3d380135797d61a64e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 26 Aug 2026 17:16:19 +0200 Subject: [PATCH 6/8] Remove always-on IndexerNotationWithoutDot language feature flag (#20319) * Flatten always-on IndexerNotationWithoutDot: remove flag and collapse enforcement sites Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove orphaned IndexerNotationWithoutDot diagnostic strings and regenerate xlf Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Sync xlf files: remove trans-units for FSComp keys deleted in this PR --------- Co-authored-by: Copilot Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: T-Gro --- .../Checking/Expressions/CheckExpressions.fs | 77 +++++-------------- .../Checking/Expressions/CheckExpressions.fsi | 2 +- src/Compiler/Driver/CompilerDiagnostics.fs | 15 ++-- src/Compiler/FSComp.txt | 11 --- src/Compiler/Facilities/LanguageFeatures.fs | 8 -- src/Compiler/Facilities/LanguageFeatures.fsi | 4 - src/Compiler/SyntaxTree/LexFilter.fs | 1 - src/Compiler/xlf/FSComp.txt.cs.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.de.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.es.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.fr.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.it.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.ja.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.ko.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.pl.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.ru.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.tr.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 55 ------------- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 55 ------------- 20 files changed, 26 insertions(+), 807 deletions(-) diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index eb1e66817a6..ff34ea0ae34 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -59,7 +59,7 @@ exception FunctionExpected of DisplayEnv * TType * range exception NotAFunction of DisplayEnv * TType * range * range -exception NotAFunctionButIndexer of DisplayEnv * TType * string option * range * range * bool +exception NotAFunctionButIndexer of DisplayEnv * TType * string option * range * range exception Recursion of DisplayEnv * Ident * TType * TType * range @@ -4118,13 +4118,10 @@ let GetInstanceMemberThisVariable (vspec: Val, expr) = None /// c.atomicLeftMethExpr[idx] and atomicLeftExpr[idx] as applications give warnings -let checkHighPrecedenceFunctionApplicationToList (g: TcGlobals) args atomicFlag exprRange = +let checkHighPrecedenceFunctionApplicationToList args atomicFlag exprRange = match args, atomicFlag with | ([SynExpr.ArrayOrList (false, _, _)] | [SynExpr.ArrayOrListComputed (false, _, _)]), ExprAtomicFlag.Atomic -> - if g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then - informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListDeprecated(), exprRange)) - elif not (g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then - informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListReserved(), exprRange)) + informationalWarning(Error(FSComp.SR.tcHighPrecedenceFunctionApplicationToListDeprecated(), exprRange)) | _ -> () /// Indicates whether a syntactic type is allowed to include new type variables @@ -5616,8 +5613,7 @@ and TryTcStmt (cenv: cenv) env tpenv synExpr = let hasTypeUnit = TryUnifyUnitTypeWithoutWarning cenv env m ty hasTypeUnit, ty, expr, tpenv -and CheckForAdjacentListExpression (cenv: cenv) synExpr hpa isInfix delayed (arg: SynExpr) = - let g = cenv.g +and CheckForAdjacentListExpression synExpr hpa isInfix delayed (arg: SynExpr) = // func (arg)[arg2] gives warning that .[ must be used. match delayed with | DelayedApp (hpa2, isSugar2, _, arg2, _) :: _ when not isInfix && (hpa = ExprAtomicFlag.NonAtomic) && isAdjacentListExpr isSugar2 hpa2 (Some synExpr) arg2 -> @@ -5625,23 +5621,14 @@ and CheckForAdjacentListExpression (cenv: cenv) synExpr hpa isInfix delayed (arg match arg with | SynExpr.Paren _ -> - if g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then - warning(Error(FSComp.SR.tcParenThenAdjacentListArgumentNeedsAdjustment(), mWarning)) - elif not (g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then - informationalWarning(Error(FSComp.SR.tcParenThenAdjacentListArgumentReserved(), mWarning)) + warning(Error(FSComp.SR.tcParenThenAdjacentListArgumentNeedsAdjustment(), mWarning)) | SynExpr.ArrayOrListComputed _ | SynExpr.ArrayOrList _ -> - if g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then - warning(Error(FSComp.SR.tcListThenAdjacentListArgumentNeedsAdjustment(), mWarning)) - elif not (g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then - informationalWarning(Error(FSComp.SR.tcListThenAdjacentListArgumentReserved(), mWarning)) + warning(Error(FSComp.SR.tcListThenAdjacentListArgumentNeedsAdjustment(), mWarning)) | _ -> - if g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then - warning(Error(FSComp.SR.tcOtherThenAdjacentListArgumentNeedsAdjustment(), mWarning)) - elif not (g.langVersion.IsExplicitlySpecifiedAs50OrBefore()) then - informationalWarning(Error(FSComp.SR.tcOtherThenAdjacentListArgumentReserved(), mWarning)) + warning(Error(FSComp.SR.tcOtherThenAdjacentListArgumentNeedsAdjustment(), mWarning)) | _ -> () @@ -5649,8 +5636,6 @@ and CheckForAdjacentListExpression (cenv: cenv) synExpr hpa isInfix delayed (arg /// keep a stack of things on the right. This lets us recognize /// method applications and other item-based syntax. and TcExprThen (cenv: cenv) overallTy env tpenv isArg synExpr delayed = - let g = cenv.g - let cachedExpression = env.eCachedImplicitYieldExpressions.FindAll synExpr.Range |> List.tryPick (fun (se, ty, e) -> @@ -5700,7 +5685,7 @@ and TcExprThen (cenv: cenv) overallTy env tpenv isArg synExpr delayed = TcNonControlFlowExpr env <| fun env -> - CheckForAdjacentListExpression cenv synExpr hpa isInfix delayed arg + CheckForAdjacentListExpression synExpr hpa isInfix delayed arg TcExprThen cenv overallTy env tpenv false func ((DelayedApp (hpa, isInfix, Some func, arg, mFuncAndArg)) :: delayed) @@ -5724,7 +5709,7 @@ and TcExprThen (cenv: cenv) overallTy env tpenv isArg synExpr delayed = // etc. | SynExpr.DotIndexedGet (expr1, IndexerArgs indexArgs, mDot, mWholeExpr) -> TcNonControlFlowExpr env <| fun env -> - if not isArg && g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + if not isArg then informationalWarning(Error(FSComp.SR.tcIndexNotationDeprecated(), mDot)) TcIndexerThen cenv env overallTy mWholeExpr mDot tpenv None expr1 indexArgs delayed @@ -5733,8 +5718,7 @@ and TcExprThen (cenv: cenv) overallTy env tpenv isArg synExpr delayed = // etc. | SynExpr.DotIndexedSet (expr1, IndexerArgs indexArgs, expr3, mOfLeftOfSet, mDot, mWholeExpr) -> TcNonControlFlowExpr env <| fun env -> - if g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then - warning(Error(FSComp.SR.tcIndexNotationDeprecated(), mDot)) + warning(Error(FSComp.SR.tcIndexNotationDeprecated(), mDot)) // Wrap in extra parens: like MakeDelayedSet, // but we don't actually want to delay it here. let setInfo = SynExpr.Paren (expr3, range0, None, expr3.Range), mOfLeftOfSet @@ -8737,41 +8721,22 @@ and Propagate (cenv: cenv) (overallTy: OverallTy) (env: TcEnv) tpenv (expr: Appl // expr[idx1..idx2] | SynExpr.ArrayOrListComputed(false, _, _) -> let isAdjacent = isAdjacentListExpr isSugar atomicFlag synLeftExprOpt synArg - if isAdjacent && g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot then + if isAdjacent then // This is the non-error path () else - // This is the error path. The error we give depends on what's enabled. - // - // First, 'delayed' is about to be dropped on the floor, do rudimentary checking to get name resolutions in its body + // 'delayed' is about to be dropped on the floor, do rudimentary checking to get name resolutions in its body RecordNameAndTypeResolutionsDelayed cenv env tpenv delayed let vName = match expr.Expr with | Expr.Val (d, _, _) -> Some d.DisplayName | _ -> None - if isAdjacent then - if IsIndexerType g cenv.amap expr.Type then - if g.langVersion.IsExplicitlySpecifiedAs50OrBefore() then - error (NotAFunctionButIndexer(denv, overallTy.Commit, vName, mExpr, mArg, false)) - match vName with - | Some nm -> - error(Error(FSComp.SR.tcNotAFunctionButIndexerNamedIndexingNotYetEnabled(RichText.mkMember nm, RichText.mkMember nm), mExprAndArg)) - | _ -> - error(Error(FSComp.SR.tcNotAFunctionButIndexerIndexingNotYetEnabled(), mExprAndArg)) - else - match vName with - | Some nm -> - error(Error(FSComp.SR.tcNotAnIndexerNamedIndexingNotYetEnabled(RichText.mkMember nm), mExprAndArg)) - | _ -> - error(Error(FSComp.SR.tcNotAnIndexerIndexingNotYetEnabled(), mExprAndArg)) + if IsIndexerType g cenv.amap expr.Type then + // NotAFunctionButIndexer uses overallTy (expected type) for the indexer suggestion message. + error (NotAFunctionButIndexer(denv, overallTy.Commit, vName, mExpr, mArg)) else - if IsIndexerType g cenv.amap expr.Type then - let old = not (g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot) - // NotAFunctionButIndexer uses overallTy (expected type) for the indexer suggestion message. - error (NotAFunctionButIndexer(denv, overallTy.Commit, vName, mExpr, mArg, old)) - else - // NotAFunction uses exprTy (actual type) to show "has type X, which does not accept arguments". - error (NotAFunction(denv, exprTy, mExpr, mArg)) + // NotAFunction uses exprTy (actual type) to show "has type X, which does not accept arguments". + error (NotAFunction(denv, exprTy, mExpr, mArg)) // f x (where 'f' is not a function) | _ -> @@ -9022,7 +8987,7 @@ and TcApplicationThen (cenv: cenv) (overallTy: OverallTy) env tpenv mExprAndArg // atomicLeftExpr[idx] unifying as application gives a warning if not isSugar then - checkHighPrecedenceFunctionApplicationToList g [synArg] atomicFlag mExprAndArg + checkHighPrecedenceFunctionApplicationToList [synArg] atomicFlag mExprAndArg match leftExpr with | ApplicableExpr(expr=NameOfExpr g _) when g.langVersion.SupportsFeature LanguageFeature.NameOf -> @@ -9091,9 +9056,7 @@ and TcApplicationThen (cenv: cenv) (overallTy: OverallTy) env tpenv mExprAndArg // leftExpr[idx] // leftExpr[idx] <- expr2 | SynExpr.ArrayOrListComputed(false, IndexerArgs indexArgs, m) - when - isAdjacentListExpr isSugar atomicFlag synLeftExprOpt synArg && - g.langVersion.SupportsFeature LanguageFeature.IndexerNotationWithoutDot -> + when isAdjacentListExpr isSugar atomicFlag synLeftExprOpt synArg -> let expandedIndexArgs = ExpandIndexArgs cenv synLeftExprOpt indexArgs let setInfo, delayed = @@ -10248,7 +10211,7 @@ and TcMethodApplicationThen let mWholeExpr = (m, args) ||> List.fold (fun m arg -> unionRanges m arg.Range) // c.atomicLeftMethExpr[idx] as application gives a warning - checkHighPrecedenceFunctionApplicationToList g args atomicFlag mWholeExpr + checkHighPrecedenceFunctionApplicationToList args atomicFlag mWholeExpr // Work out if we know anything about the return type of the overall expression. If there are any delayed // lookups then we don't know anything. diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fsi b/src/Compiler/Checking/Expressions/CheckExpressions.fsi index 03eb0416921..5e4ef62aedd 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fsi +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fsi @@ -37,7 +37,7 @@ exception FunctionExpected of DisplayEnv * TType * range exception NotAFunction of DisplayEnv * TType * range * range -exception NotAFunctionButIndexer of DisplayEnv * TType * string option * range * range * bool +exception NotAFunctionButIndexer of DisplayEnv * TType * string option * range * range exception Recursion of DisplayEnv * Ident * TType * TType * range diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 61fa12e7f62..3b46c9b64c4 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -179,7 +179,7 @@ type Exception with | NotAFunction(_, _, mfun, _) -> Some mfun - | NotAFunctionButIndexer(_, _, _, mfun, _, _) -> Some mfun + | NotAFunctionButIndexer(_, _, _, mfun, _) -> Some mfun | IllegalFileNameChar _ -> Some rangeCmdArgs @@ -1092,15 +1092,10 @@ type Exception with | InterfaceNotRevealed(denv, intfTy, _) -> os.Append(InterfaceNotRevealedE(), NicePrint.minimalRichTextOfType denv intfTy) - | NotAFunctionButIndexer(_, _, name, _, _, old) -> - if old then - match name with - | Some name -> os.Append(FSComp.SR.notAFunctionButMaybeIndexerWithName (RichText.mkLocal name)) - | _ -> os.Append(FSComp.SR.notAFunctionButMaybeIndexer ()) - else - match name with - | Some name -> os.Append(FSComp.SR.notAFunctionButMaybeIndexerWithName2 (RichText.mkLocal name)) - | _ -> os.Append(FSComp.SR.notAFunctionButMaybeIndexer2 ()) + | NotAFunctionButIndexer(_, _, name, _, _) -> + match name with + | Some name -> os.Append(FSComp.SR.notAFunctionButMaybeIndexerWithName2 (RichText.mkLocal name)) + | _ -> os.Append(FSComp.SR.notAFunctionButMaybeIndexer2 ()) | NotAFunction(denv, ty, _, marg) -> if marg.StartColumn = 0 then diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 531ae517fd0..29d13df0cd0 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1248,7 +1248,6 @@ invalidFullNameForProvidedType,"invalid full name for provided type" 3087,tcCustomOperationMayNotBeOverloaded,"The custom operation '%s' refers to a method which is overloaded. The implementations of custom operations may not be overloaded." featureOverloadsForCustomOperations,"overloads for custom operations" featureExpandedMeasurables,"more types support units of measure" -featureIndexerNotationWithoutDot,"expr[idx] notation for indexing and slicing" featureRefCellNotationInformationals,"informational messages related to reference cells" featureNonVariablePatternsToRightOfAsPatterns,"non-variable patterns to the right of 'as' patterns" featureAttributesToRightOfModuleKeyword,"attributes to the right of the 'module' keyword" @@ -1484,8 +1483,6 @@ keywordDescriptionUntypedQuotation,"Delimits a untyped code quotation." descriptionWordIs,"is" notAFunction,"This value is not a function and cannot be applied." notAFunctionWithType,"This value is not a function and cannot be applied. It has type '%s', which does not accept arguments." -notAFunctionButMaybeIndexerWithName,"This value is not a function and cannot be applied. Did you intend to access the indexer via '%s.[index]'?" -notAFunctionButMaybeIndexer,"This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'?" notAFunctionButMaybeIndexerWithName2,"This value is not a function and cannot be applied. Did you intend to access the indexer via '%s[index]'?" notAFunctionButMaybeIndexer2,"This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr[index]'?" 3217,notAFunctionButMaybeIndexerErrorCode,"" @@ -1603,10 +1600,6 @@ featureEnforceAttributeTargets,"Enforce AttributeTargets" featureLowerInterpolatedStringToConcat,"Optimizes interpolated strings in certain cases, by lowering to concatenation" featureLowerIntegralRangesToFastLoops,"Optimizes certain uses of the integral range (..) and range-step (.. ..) operators to fast while-loops." featureLowerSimpleMappingsInComprehensionsToFastLoops,"Lowers [for x in xs -> f x] and [|for x in xs -> f x|] to fast loops when xs is a list or an array, respectively." -3354,tcNotAFunctionButIndexerNamedIndexingNotYetEnabled,"This value supports indexing, e.g. '%s.[index]'. The syntax '%s[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." -3354,tcNotAFunctionButIndexerIndexingNotYetEnabled,"This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation." -3355,tcNotAnIndexerNamedIndexingNotYetEnabled,"The value '%s' is not a function and does not support index notation." -3355,tcNotAnIndexerIndexingNotYetEnabled,"This expression is not a function and does not support index notation." 3356,tcDuplicateExtensionMemberNames,"Extension members extending types with the same simple name '%s' but different fully qualified names cannot be defined in the same module. Consider defining these extensions in separate modules." 3360,typrelInterfaceWithConcreteAndVariable,"'%s' cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify." 3361,typrelInterfaceWithConcreteAndVariableObjectExpression,"You cannot implement the interface '%s' with the two instantiations '%s' and '%s' because they may unify." @@ -1615,10 +1608,6 @@ featureLowerSimpleMappingsInComprehensionsToFastLoops,"Lowers [for x in xs -> f 3364,tcInvalidUseOfReverseIndex,"Invalid use of reverse index in list expression." 3365,tcHighPrecedenceFunctionApplicationToListDeprecated,"The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'." 3366,tcIndexNotationDeprecated,"The syntax 'arr.[idx]' is now revised to 'arr[idx]'. Please update your code." -3367,tcHighPrecedenceFunctionApplicationToListReserved,"The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'." -3368,tcParenThenAdjacentListArgumentReserved,"The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'." -3368,tcListThenAdjacentListArgumentReserved,"The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'." -3368,tcOtherThenAdjacentListArgumentReserved,"The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'." 3369,tcParenThenAdjacentListArgumentNeedsAdjustment,"The syntax '(expr1)[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'." 3369,tcListThenAdjacentListArgumentNeedsAdjustment,"The syntax '[expr1][expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use '(expr1).[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'." 3369,tcOtherThenAdjacentListArgumentNeedsAdjustment,"The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'." diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index df7cc294aa4..97239a6a940 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -29,7 +29,6 @@ type LanguageFeature = | OverloadsForCustomOperations | ExpandedMeasurables | NullnessChecking - | IndexerNotationWithoutDot | RefCellNotationInformationals | UnionIsPropertiesVisible | NonVariablePatternsToRightOfAsPatterns @@ -151,7 +150,6 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array) LanguageFeature.OverloadsForCustomOperations, languageVersion60 LanguageFeature.ExpandedMeasurables, languageVersion60 LanguageFeature.ResumableStateMachines, languageVersion60 - LanguageFeature.IndexerNotationWithoutDot, languageVersion60 LanguageFeature.RefCellNotationInformationals, languageVersion60 LanguageFeature.NonVariablePatternsToRightOfAsPatterns, languageVersion60 LanguageFeature.AttributesToRightOfModuleKeyword, languageVersion60 @@ -294,11 +292,6 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array) /// Create a new LanguageVersion with updated disabled features member _.WithDisabledFeatures(disabled: LanguageFeature array) = LanguageVersion(versionText, disabled) - /// Has preview been explicitly specified - member _.IsExplicitlySpecifiedAs50OrBefore() = - let v = getVersionFromString versionText - v <> 0.0m && v <= 5.0m - /// Has preview been explicitly specified member _.IsPreviewEnabled = specified = previewVersion @@ -348,7 +341,6 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array) | LanguageFeature.StringInterpolation -> FSComp.SR.featureStringInterpolation () | LanguageFeature.OverloadsForCustomOperations -> FSComp.SR.featureOverloadsForCustomOperations () | LanguageFeature.ExpandedMeasurables -> FSComp.SR.featureExpandedMeasurables () - | LanguageFeature.IndexerNotationWithoutDot -> FSComp.SR.featureIndexerNotationWithoutDot () | LanguageFeature.RefCellNotationInformationals -> FSComp.SR.featureRefCellNotationInformationals () | LanguageFeature.UnionIsPropertiesVisible -> FSComp.SR.featureUnionIsPropertiesVisible () | LanguageFeature.NonVariablePatternsToRightOfAsPatterns -> FSComp.SR.featureNonVariablePatternsToRightOfAsPatterns () diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index 9db6bee529e..931629eebcd 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -19,7 +19,6 @@ type LanguageFeature = | OverloadsForCustomOperations | ExpandedMeasurables | NullnessChecking - | IndexerNotationWithoutDot | RefCellNotationInformationals | UnionIsPropertiesVisible | NonVariablePatternsToRightOfAsPatterns @@ -106,9 +105,6 @@ type LanguageVersion = /// Has preview been explicitly specified member IsPreviewEnabled: bool - /// Has been explicitly specified as 4.6, 4.7 or 5.0 - member IsExplicitlySpecifiedAs50OrBefore: unit -> bool - /// Does the selected LanguageVersion support the specified feature member SupportsFeature: LanguageFeature -> bool diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index d45b1cf520c..e7d0f357d91 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -774,7 +774,6 @@ type LexFilterImpl ( // Undentation rules //-------------------------------------------------------------------------- - //let indexerNotationWithoutDot = lexbuf.SupportsFeature LanguageFeature.IndexerNotationWithoutDot let tryPushCtxt strict ignoreIndent tokenTup (newCtxt: Context) = let rec undentationLimit strict stack = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 61211b419b4..7758bfff93f 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - Notace expr[idx] pro indexování a vytváření řezů - - static abstract interface members statičtí abstraktní členové rozhraní @@ -1517,11 +1512,6 @@ Syntaxe expr1[expr2] se používá pro indexování. Pokud chcete povolit indexování, zvažte možnost přidat anotaci typu, nebo pokud voláte funkci, přidejte mezeru, třeba expr1 [expr2]. - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - Syntaxe expr1[expr2] je teď vyhrazena pro indexování. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci, přidejte mezi funkci a argument mezeru, třeba someFunction [expr]. - - Byref types are not allowed in an open type declaration. Typy Byref nejsou v deklaraci otevřeného typu povolené. @@ -1622,11 +1612,6 @@ Syntaxe [expr1][expr2] je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud plánujete indexování nebo vytváření řezů, musíte použít (expr1).[expr2] na pozici argumentu. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction [expr1] [expr2]. - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - Syntaxe [expr1][expr2] je teď vyhrazena pro indexování a je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction [expr1] [expr2]. - - A [<Literal>] declaration cannot use an active pattern for its identifier Deklarace [<Literal>] nemůže používat aktivní vzor jako svůj identifikátor. @@ -1677,26 +1662,6 @@ Nenašla se žádná statická abstraktní vlastnost, která by odpovídala tomuto přepsání. - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Tento výraz podporuje indexování, třeba expr.[index]. Syntaxe expr[index] vyžaduje /langversion:preview. Více informací: https://aka.ms/fsharp-index-notation - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Tato hodnota podporuje indexování, třeba {0}.[index]. Syntaxe {1}[index] vyžaduje /langversion:preview. Více informací: https://aka.ms/fsharp-index-notation - - - - This expression is not a function and does not support index notation. - Tento výraz není funkce a nepodporuje zápis indexu. - - - - The value '{0}' is not a function and does not support index notation. - Hodnota {0} není funkce a nepodporuje zápis indexu. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ Syntaxe expr1[expr2] je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud plánujete indexování nebo vytváření řezů, musíte použít expr1.[expr2] na pozici argumentu. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction expr1 [expr2]. - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - Syntaxe expr1[expr2] je teď vyhrazena pro indexování a je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction expr1 [expr2]. - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ Syntaxe (expr1)[expr2] je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud plánujete indexování nebo vytváření řezů, musíte použít (expr1).[expr2] na pozici argumentu. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction (expr1) [expr2]. - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - Syntaxe (expr1)[expr2] je teď pro indexování vyhrazená a je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction (expr1) [expr2]. - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - Tato hodnota není funkcí a nedá se použít. Nechtěli jste získat k indexeru přístup přes {0}.[index]? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - Tento výraz není funkcí a nedá se použít. Nechtěli jste získat k indexeru přístup přes expr.[index]? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? Tato hodnota není funkce a nedá se použít. Nezapomněli jste ukončit deklaraci? diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 28019bbdaf3..08ca8cb9ebd 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - expr[idx]-Notation zum Indizieren und Aufteilen - - static abstract interface members statische abstrakte Schnittstellenmitglieder @@ -1517,11 +1512,6 @@ Die Syntax "expr1[expr2]" wird für die Indizierung verwendet. Fügen Sie ggf. eine Typanmerkung hinzu, um die Indizierung zu aktivieren, oder fügen Sie beim Aufrufen einer Funktion ein Leerzeichen hinzu, z. B. "expr1 [expr2]". - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - Die Syntax "expr1[expr2]" ist jetzt für die Indizierung reserviert. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion aufrufen, fügen Sie ein Leerzeichen zwischen der Funktion und dem Argument hinzu, z. B. "someFunction [expr]". - - Byref types are not allowed in an open type declaration. Byref-Typen sind in einer Deklaration für offene Typen nicht zulässig. @@ -1622,11 +1612,6 @@ Die Syntax "[expr1][expr2]" ist mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie indizieren oder aufteilen möchten, müssen Sie "(expr1).[expr2]' in Argumentposition verwenden. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction [expr1] [expr2]". - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - Die Syntax "[expr1][expr2]" ist jetzt für die Indizierung reserviert und mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction [expr1] [expr2]". - - A [<Literal>] declaration cannot use an active pattern for its identifier Eine [<Literal>]-Deklaration kann kein aktives Muster für ihren Bezeichner verwenden. @@ -1677,26 +1662,6 @@ Es wurde keine statische abstrakte Eigenschaft gefunden, die dieser Überschreibung entspricht. - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Dieser Ausdruck unterstützt die Indizierung, z. B. "expr.[index]". Die Syntax "expr[index]" erfordert /langversion:preview. Siehe https://aka.ms/fsharp-index-notation. - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Dieser Wert unterstützt die Indizierung, z. B. "{0}.[index]". Die Syntax "{1}[index]" erfordert /langversion:preview. Siehe https://aka.ms/fsharp-index-notation. - - - - This expression is not a function and does not support index notation. - Dieser Ausdruck ist keine Funktion und unterstützt keine Indexnotation. - - - - The value '{0}' is not a function and does not support index notation. - Der Wert "{0}" ist keine Funktion und unterstützt keine Indexnotation. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ Die Syntax "expr1[expr2]" ist mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie indizieren oder aufteilen möchten, müssen Sie "expr1.[expr2]' in Argumentposition verwenden. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction expr1 [expr2]". - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - Die Syntax "expr1[expr2]" ist jetzt für die Indizierung reserviert und mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction expr1 [expr2]". - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ Die Syntax "(expr1)[expr2]" ist mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie indizieren oder aufteilen möchten, müssen Sie "(expr1).[expr2]' in Argumentposition verwenden. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction (expr1) [expr2]". - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - Die Syntax "(expr1)[expr2]" ist jetzt für die Indizierung reserviert und mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction (expr1) [expr2]". - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - Dieser Wert ist keine Funktion und kann nicht angewendet werden. Wollten Sie auf den Indexer über "{0}.[index]" zugreifen? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - Dieser Ausdruck ist keine Funktion und kann nicht angewendet werden. Wollten Sie auf den Indexer über "expr.[index]" zugreifen? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? Dieser Wert ist keine Funktion und kann nicht angewendet werden. Wurde möglicherweise eine Deklaration nicht abgeschlossen? diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 0d5158ff312..71a3e2db55c 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - Notación para indexación y segmentación expr[idx] - - static abstract interface members miembros de interfaz abstracta estática @@ -1517,11 +1512,6 @@ La sintaxis "expr1[expr2]" se usa para la indexación. Considere la posibilidad de agregar una anotación de tipo para habilitar la indexación, si se llama a una función, agregue un espacio, por ejemplo, "expr1 [expr2]". - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - La sintaxis "expr1[expr2]" está ahora reservada para la indexación. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función, agregue un espacio entre la función y el argumento; por ejemplo, "unaFunción [expr]". - - Byref types are not allowed in an open type declaration. No se permiten tipos byref en una declaración de tipo abierto. @@ -1622,11 +1612,6 @@ La sintaxis "[expr1][expr2]" es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si piensa indexar o segmentar, debe usar "(expr1).[expr2]" en la posición del argumento. Si se llama a una función con varios argumentos currificados, se agregará un espacio entre ellos, por ejemplo, "unaFunción [expr1] [expr2]". - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - La sintaxis "[expr1][expr2]" está reservada ahora para la indexación y es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función con varios argumentos currificados, agregue un espacio entre ellos, por ejemplo, "unaFunción expr1 [expr2]". - - A [<Literal>] declaration cannot use an active pattern for its identifier Una declaración [<Literal>] no puede usar un modelo activo para su identificador @@ -1677,26 +1662,6 @@ No se encontró ninguna propiedad abstracta estática que corresponda a esta invalidación. - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Esta expresión admite indexación, por ejemplo "expr.[index]". La sintaxis "expr[index]" requiere /langversion:preview. Ver https://aka.ms/fsharp-index-notation. - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Este valor admite indexación, por ejemplo "{0}.[index]". La sintaxis "{1}[index]" requiere /langversion:preview. Ver https://aka.ms/fsharp-index-notation. - - - - This expression is not a function and does not support index notation. - Esta expresión no es una función y no admite la notación de índices. - - - - The value '{0}' is not a function and does not support index notation. - El valor "{0}" no es una función y no admite la notación de índices. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ La sintaxis "expr1[expr2]" es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si piensa indexar o segmentar, debe usar "expr1.[expr2]" en la posición del argumento. Si se llama a una función con varios argumentos currificados, se agregará un espacio entre ellos, por ejemplo, "unaFunción expr1 [expr2]". - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - La sintaxis "expr1[expr2]" está reservada ahora para la indexación y es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función con varios argumentos currificados, agregue un espacio entre ellos, por ejemplo, "unaFunción expr1 [expr2]". - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ La sintaxis "(expr1)[expr2]" es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si piensa indexar o segmentar, debe usar "(expr1).[expr2]" en la posición del argumento. Si se llama a una función con varios argumentos currificados, se agregará un espacio entre ellos, por ejemplo, "unaFunción (expr1) [expr2]". - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - La sintaxis "(expr1)[expr2]" está reservada ahora para la indexación y es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si se llama a una función con varios argumentos currificados, agregue un espacio entre ellos, por ejemplo, "unaFunción (expr1) [expr2]". - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - Este valor no es una función y no se puede aplicar. ¿Quería tener acceso al indexador a través de "{0}.[index]"? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - Esta expresión no es una función y no se puede aplicar. ¿Quería acceder al indexador a través de "expr.[index]"? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? Este valor no es una función y no se puede aplicar. ¿Olvidó terminar una declaración? diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index b1222d679d8..d88803dec60 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - Notation expr[idx] pour l’indexation et le découpage - - static abstract interface members membres d’interface abstraite statiques @@ -1517,11 +1512,6 @@ La syntaxe « expr1[expr2] » est utilisée pour l’indexation. Envisagez d’ajouter une annotation de type pour activer l’indexation, ou si vous appelez une fonction, ajoutez un espace, par exemple « expr1 [expr2] ». - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - La syntaxe « expr1[expr2] » est désormais réservée à l’indexation. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction, ajoutez un espace entre la fonction et l’argument, par exemple « someFunction [expr] ». - - Byref types are not allowed in an open type declaration. Les types Byref ne sont pas autorisés dans une déclaration de type ouverte. @@ -1622,11 +1612,6 @@ La syntaxe « [expr1][expr2] » est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous avez l’intention d’indexer ou de découper, vous devez utiliser « (expr1).[expr2] » en position d’argument. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction [expr1] [expr2] ». - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - La syntaxe « [expr1][expr2] » est désormais réservée à l’indexation et est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction [expr1] [expr2] ». - - A [<Literal>] declaration cannot use an active pattern for its identifier Une déclaration [<Literal>] ne peut pas utiliser un modèle actif en tant qu'identificateur @@ -1677,26 +1662,6 @@ Désolé, nous n’avons pas pu trouver une propriété abstraite statique qui corresponde à cette substitution - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Cette expression prend en charge l’indexation, par exemple « expr.[index] ». La syntaxe « expr[index] » requiert /langversion:preview. Voir https://aka.ms/fsharp-index-notation. - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Cette valeur prend en charge l’indexation, par exemple « {0}.[index] ». La syntaxe « {1}[index] » nécessite /langversion:preview. Voir https://aka.ms/fsharp-index-notation. - - - - This expression is not a function and does not support index notation. - Cette expression n’est pas une fonction et ne prend pas en charge la notation d’index. - - - - The value '{0}' is not a function and does not support index notation. - La valeur « {0} » n’est pas une fonction et ne prend pas en charge la notation d’index. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ La syntaxe « expr1[expr2] » est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous avez l’intention d’indexer ou de découper, vous devez utiliser « expr1.[expr2] » en position d’argument. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction expr1 [expr2] ». - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - La syntaxe « expr1[expr2] » est désormais réservée à l’indexation et est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction expr1 [expr2] ». - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ La syntaxe « (expr1)[expr2] » est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous avez l’intention d’indexer ou de découper, vous devez utiliser « (expr1).[expr2] » en position d’argument. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction (expr1) [expr2] ». - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - La syntaxe « (expr1)[expr2] » est désormais réservée à l’indexation et est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction (expr1) [expr2] ». - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - Cette valeur n'est pas une fonction et ne peut pas être appliquée. Souhaitiez-vous accéder à l'indexeur via « {0}.[index] » ? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - Cette expression n'est pas une fonction et ne peut pas être appliquée. Souhaitiez-vous accéder à l'indexeur via « expr.[index] » ? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? Cette valeur n'est pas une fonction et ne peut pas être appliquée. Avez-vous oublié de terminer une déclaration ? diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 748229772c3..6e206a88f36 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - Notazione expr[idx] per l'indicizzazione e il sezionamento - - static abstract interface members membri dell'interfaccia astratta statica @@ -1517,11 +1512,6 @@ La sintassi 'expr1[expr2]' viene usata per l'indicizzazione. Provare ad aggiungere un'annotazione di tipo per abilitare l'indicizzazione oppure se la chiamata a una funzione aggiunge uno spazio, ad esempio 'expr1 [expr2]'. - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - La sintassi 'expr1[expr2]' è ora riservata per l'indicizzazione. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione, aggiungere uno spazio tra la funzione e l'argomento, ad esempio 'someFunction [expr]'. - - Byref types are not allowed in an open type declaration. I tipi byref non sono consentiti in una dichiarazione di tipo aperto. @@ -1622,11 +1612,6 @@ La sintassi '[expr1][expr2]' è ambigua se usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si intende eseguire l'indicizzazione o il sezionamento, è necessario usare '(expr1). [expr2]' nella posizione dell'argomento. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction [expr1] [expr2]'. - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - La sintassi '[expr1][expr2]' è ora riservata per l'indicizzazione ed è ambigua quando usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction [expr1] [expr2]'. - - A [<Literal>] declaration cannot use an active pattern for its identifier Una dichiarazione [<Literal>] non può usare un criterio attivo per il relativo identificatore @@ -1677,26 +1662,6 @@ Nessuna proprietà astratta statica trovata corrispondente all'override - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Questa espressione supporta l'indicizzazione, ad esempio 'expr.[index]'. La sintassi 'expr[index]' richiede/langversion:preview. Vedere https://aka.ms/fsharp-index-notation.. - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Questo valore supporta l'indicizzazione, ad esempio '{0}.[index]'. La sintassi '{1}[index]' richiede/langversion:preview. Vedere https://aka.ms/fsharp-index-notation. - - - - This expression is not a function and does not support index notation. - Questa espressione non è una funzione e non supporta la notazione degli indici. - - - - The value '{0}' is not a function and does not support index notation. - Questo valore '{0}' non è una funzione e non supporta la notazione degli indici. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ La sintassi 'expr1[expr2]' è ambigua se usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si intende eseguire l'indicizzazione o il sezionamento, è necessario usare 'expr1.[expr2]' nella posizione dell'argomento. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction expr1 [expr2]'. - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - La sintassi 'expr1[expr2]' è ora riservata per l'indicizzazione ed è ambigua quando usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction expr1 [expr2]'. - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ La sintassi '(expr1)[expr2]' è ambigua se usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si intende eseguire l'indicizzazione o il sezionamento, è necessario usare '(expr1).[expr2]' nella posizione dell'argomento. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction (expr1) [expr2]'. - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - La sintassi '(expr1)[expr2]' è ora riservata per l'indicizzazione ed è ambigua quando usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction (expr1) [expr2]'. - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - Questo valore non è una funzione e non può essere applicato. Si intendeva accedere all'indicizzatore tramite la sintassi '{0}.[index]'? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - Questa espressione non è una funzione e non può essere applicata. Si intendeva accedere all'indicizzatore tramite la sintassi 'expr.[index]'? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? Questo valore non è una funzione e non può essere applicato. Potrebbe essere presente una dichiarazione non terminata. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index e413d95f6d4..3baa0fd6e17 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - インデックス作成とスライス用の expr[idx] 表記 - - static abstract interface members 静的抽象インターフェイス メンバー @@ -1517,11 +1512,6 @@ 構文 'expr1[expr2]' はインデックス作成に使用されます。インデックスを有効にするために型の注釈を追加するか、関数を呼び出す場合には、'expr1 [expr2]' のようにスペースを入れます。 - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - 構文 'expr1[expr2]' はインデックス作成用に予約されています。https://aka.ms/fsharp-index-notation を参照してください。関数を呼び出す場合は、'someFunction [expr]' のように関数と引数の間にスペースを追加します。 - - Byref types are not allowed in an open type declaration. Byref 型は、オープン型宣言では使用できません。 @@ -1622,11 +1612,6 @@ 構文 '[expr1][expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。インデックス作成またはスライスを行う場合は、'(expr1).[expr2]' を引数の位置に使用する必要があります。複数のカリー化された引数を持つ関数を呼び出す場合は、'[expr1] [expr2]' のように間にスペースを追加します。 - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - 構文 '[expr1][expr2]' はインデックス作成用に予約され、引数として使用するとあいまいになります。https://aka.ms/fsharp-index-notation を参照してください。複数のカリー化された引数を持つ関数を呼び出す場合は、それらの間にスペースを追加します (例: 'someFunction [expr1] [expr2]')。 - - A [<Literal>] declaration cannot use an active pattern for its identifier [<Literal>] 宣言では、その識別子に対してアクティブ パターンを使用することはできません @@ -1677,26 +1662,6 @@ このオーバーライドに対応する抽象プロパティが見つかりませんでした - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - この式は、'expr. [index]' などのインデックスをサポートしています。構文 'expr[index]' には /langversion:preview が必要です。https://aka.ms/fsharp-index-notation を参照してください。 - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - この式は、 '{0}.[index]' などのインデックスをサポートしています。構文 '{1}[index]' には /langversion:preview が必要です。https://aka.ms/fsharp-index-notation を参照してください。 - - - - This expression is not a function and does not support index notation. - この式は関数ではなく、インデックス表記をサポートしていません。 - - - - The value '{0}' is not a function and does not support index notation. - 値 '{0}' は関数ではなく、インデックス表記をサポートしていません。 - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ 構文 'expr1[expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。インデックス作成またはスライスを行う場合は、'expr1.[expr2]' を引数の位置に使用する必要があります。複数のカリー化された引数を持つ関数を呼び出す場合は、'expr1 [expr2]' のように間にスペースを追加します。 - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - 構文 'expr1[expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。複数のカリー化された引数を持つ関数を呼び出す場合には、'someFunction expr1 [expr2]' のように間にスペースを追加します。 - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ 構文 '(expr1)[expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。インデックス作成またはスライスを行う場合は、'(expr1).[expr2]' を引数の位置に使用する必要があります。複数のカリー化された引数を持つ関数を呼び出す場合は、'someFunction (expr1) [expr2]' のように間にスペースを追加します。 - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - 構文 '(expr1)[expr2]' はインデックス作成に予約されているので、引数として使うとあいまいです。https://aka.ms/fsharp-index-notation を参照してください。複数のカリー化された引数を持つ関数を呼び出す場合には、'someFunction (expr1) [expr2]' のように間にスペースを追加します。 - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - この値は関数ではないため、適用できません。{0}.[index] によってインデクサーにアクセスしようとしましたか? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - この式は関数ではないため、適用できません。expr.[index] によってインデクサーにアクセスしようとしましたか? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? この値は関数ではないため、適用できません。宣言を終結しましたか? diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 26f6ef4e6ed..bf2b4a248e7 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - 인덱싱 및 슬라이싱을 위한 expr[idx] 표기법 - - static abstract interface members 고정적인 추상 인터페이스 멤버 @@ -1517,11 +1512,6 @@ 인덱싱에는 'expr1[expr2]' 구문이 사용됩니다. 인덱싱을 사용하도록 설정하기 위해 형식 주석을 추가하는 것을 고려하거나 함수를 호출하는 경우 공백을 추가하세요(예: 'expr1 [expr2]'). - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - 'expr1[expr2]' 구문은 이제 인덱싱용으로 예약되어 있습니다. https://aka.ms/fsharp-index-notation을 참조하세요. 함수를 호출하는 경우 함수와 인수 사이에 공백을 추가하세요(예: 'someFunction [expr]'). - - Byref types are not allowed in an open type declaration. Byref 형식은 개방형 형식 선언에서 허용되지 않습니다. @@ -1622,11 +1612,6 @@ '[expr1][expr2]' 구문은 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 인덱싱이나 슬라이싱을 하려면 인수 위치에 '(expr1).[expr2]'를 사용해야 합니다. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction [expr1] [expr2]'). - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - 구문 '[expr1][expr2]'는 이제 인덱싱을 위해 예약되었으며 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction [expr1] [expr2]'). - - A [<Literal>] declaration cannot use an active pattern for its identifier [<Literal>] 선언은 해당 식별자에 대한 활성 패턴을 사용할 수 없습니다. @@ -1677,26 +1662,6 @@ 이 재정의에 해당하는 정적 추상 속성을 찾을 수 없습니다. - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - 이 식은 인덱싱을 지원합니다. 'expr.[index]'. 'expr[index]' 구문에는 /langversion:preview가 필요합니다. https://aka.ms/fsharp-index-notation을 참조하세요. - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - 이 값은 인덱싱을 지원합니다. '{0}.[index]'. 구문 '{1}[index]'에는 /langversion:preview가 필요합니다. https://aka.ms/fsharp-index-notation을 참조하세요. - - - - This expression is not a function and does not support index notation. - 이 식은 함수가 아니며 인덱스 표기법을 지원하지 않습니다. - - - - The value '{0}' is not a function and does not support index notation. - '{0}' 값은 함수가 아니며 인덱스 표기법을 지원하지 않습니다. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ 'expr1[expr2]' 구문은 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 인덱싱이나 슬라이싱을 하려면 인수 위치에 'expr1.[expr2]'를 사용해야 합니다. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction expr1 [expr2]'). - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - 구문 'expr1[expr2]'은 이제 인덱싱용으로 예약되어 있으며 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction expr1 [expr2]'). - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ '(expr1)[expr2]' 구문은 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 인덱싱이나 슬라이싱을 하려면 인수 위치에 '(expr1).[expr2]'를 사용해야 합니다. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction (expr1) [expr2]'). - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - 구문 '(expr1)[expr2]'는 이제 인덱싱을 위해 예약되었으며 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction (expr1) [expr2]'). - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - 이 값은 함수가 아니며 적용할 수 없습니다. '{0}.[index]'를 통해 인덱서에 액세스하려고 했습니까? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - 이 표현식은 함수가 아니며 적용할 수 없습니다. 'expr.[index]'를 통해 인덱서에 액세스하려고 했습니까? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? 이 값은 함수가 아니며 적용할 수 없습니다. 선언을 종료해야 합니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 623fb303116..76542364493 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - notacja wyrażenia expr[idx] do indeksowania i fragmentowania - - static abstract interface members statyczne abstrakcyjne elementy członkowskie interfejsu @@ -1517,11 +1512,6 @@ Do indeksowania używana jest składnia „expr1[expr2]”. Rozważ dodanie adnotacji typu, aby umożliwić indeksowanie, lub jeśli wywołujesz funkcję dodaj spację, np. „expr1 [expr2]”. - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - Składnia wyrażenia „expr1[expr2]” jest teraz zarezerwowana dla indeksowania. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję, dodaj spację między funkcją a argumentem, np. „someFunction [expr]”. - - Byref types are not allowed in an open type declaration. Typy ByRef są niedozwolone w deklaracji typu otwartego. @@ -1622,11 +1612,6 @@ Składnia wyrażenia „[expr1][expr2]” jest niejednoznaczna, gdy jest używana jako argument. Zobacz https://aka.ms/fsharp-index-notation. Jeśli zamierzasz indeksować lub fragmentować, to w pozycji argumentu musi być użyte wyrażenie „(expr1).[expr2]”. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction [expr1] [expr2]”. - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - Składnia wyrażenia „[expr1][expr2]” jest teraz zarezerwowana do indeksowania i jest niejednoznaczna, gdy jest używana jako argument. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction [expr1] [expr2]”. - - A [<Literal>] declaration cannot use an active pattern for its identifier Deklaracja [<Literal>] nie może używać aktywnego wzorca dla swojego identyfikatora @@ -1677,26 +1662,6 @@ Nie odnaleziono żadnej statycznej właściwości abstrakcyjnej odpowiadającej temu przesłonięciu - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - To wyrażenie obsługuje indeksowanie, np. „expr.[index]”. Składnia wyrażenia „expr[index]” wymaga parametru /langversion:preview. Zobacz: https://aka.ms/fsharp-index-notation. - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Ta wartość obsługuje indeksowanie, m.in. „{0}.[index]”. Składnia wyrażenia „{1}[index]” wymaga parametru /langversion:preview. Zobacz: https://aka.ms/fsharp-index-notation. - - - - This expression is not a function and does not support index notation. - To wyrażenie nie jest funkcją i nie obsługuje notacji indeksowej. - - - - The value '{0}' is not a function and does not support index notation. - Wartość elementu „{0}” nie jest funkcją i nie obsługuje notacji indeksowej. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ Składnia wyrażenia „expr1[expr2]” jest niejednoznaczna, gdy jest używana jako argument. Zobacz https://aka.ms/fsharp-index-notation. Jeśli zamierzasz indeksować lub fragmentować, to w pozycji argumentu musi być użyte wyrażenie „expr1.[expr2]”. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction expr1 [expr2]”. - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - Składnia wyrażenia „expr1[expr2]” jest teraz zarezerwowana do indeksowania i jest niejednoznaczna, gdy jest używana jako argument. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction expr1 [expr2]”. - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ Składnia wyrażenia „(expr1)[expr2]” jest niejednoznaczna, gdy jest używana jako argument. Zobacz https://aka.ms/fsharp-index-notation. Jeśli zamierzasz indeksować lub fragmentować, to w pozycji argumentu musi być użyte wyrażenie „(expr1).[expr2]”. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction (expr1) [expr2]”. - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - Składnia wyrażenia „(expr1)[expr2]” jest teraz zarezerwowana do indeksowania i jest niejednoznaczna, gdy jest używana jako argument. Zobacz: https://aka.ms/fsharp-index-notation. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction (expr1) [expr2]”. - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - To wyrażenie nie jest funkcją i nie można go zastosować. Spróbuj uzyskać dostęp do indeksatora za pośrednictwem wyrażenia „{0}.[index]”? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - To wyrażenie nie jest funkcją i nie można go zastosować. Spróbuj uzyskać dostęp do indeksatora za pośrednictwem wyrażenia „expr.[index]”? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? Ta wartość nie jest funkcją i nie można jej zastosować. Czy deklaracja została zakończona? diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index c11f600ad14..1f1f5391694 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - notação expr[idx] para indexação e fatia - - static abstract interface members membros de interface abstrata estática @@ -1517,11 +1512,6 @@ A sintaxe 'expr1[expr2]' é usada para indexação. Considere adicionar uma anotação de tipo para habilitar a indexação ou, se chamar uma função, adicione um espaço, por exemplo, 'expr1 [expr2]'. - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - A sintaxe ' expr1[expr2] ' agora está reservada para indexação. Consulte https://aka.ms/fsharp-index-notation. Se estiver chamando uma função, adicione um espaço entre a função e o argumento, por exemplo, 'someFunction [expr]'. - - Byref types are not allowed in an open type declaration. Os tipos Byref não são permitidos em uma declaração de tipo aberto. @@ -1622,11 +1612,6 @@ A sintaxe ' [expr1][expr2] ' é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. se você pretende indexar ou colocar em fatias e, em seguida, deve usar '(expr1). [expr2]' na posição do argumento. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction [expr1] [expr2]'. - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - A sintaxe 'expr1[expr2]' agora está reservada para indexação e é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction expr1 [expr2]'. - - A [<Literal>] declaration cannot use an active pattern for its identifier Uma declaração [<Literal>] não pode usar um padrão ativo para seu identificador @@ -1677,26 +1662,6 @@ Nenhuma propriedade abstrata que corresponde a esta substituição foi encontrada - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Essa expressão oferece suporte à indexação, por exemplo, 'expr. [index]'. A sintaxe 'expr[index]' requer /langversion:preview. Consulte https://aka.ms/fsharp-index-notation. - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Esse valor dá suporte à indexação, por exemplo, '{0}.[index]'. A sintaxe '{1}[index]' requer /langversion:preview. Consulte https://aka.ms/fsharp-index-notation. - - - - This expression is not a function and does not support index notation. - Essa expressão não é uma função e não dá suporte à notação de índice. - - - - The value '{0}' is not a function and does not support index notation. - O valor '{0}' não é uma função e não dá suporte à notação de índice. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ A sintaxe '[expr1][expr2]' é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se você pretende indexar ou colocar em fatias, deve usar '(expr1).[expr2]' na posição do argumento. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction [expr1] [expr2]'. - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - A sintaxe 'expr1[expr2]' agora está reservada para indexação e é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction expr1 [expr2]'. - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ A sintaxe '[expr1][expr2]' é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se você pretende indexar ou colocar em fatias, deve usar '(expr1).[expr2]' na posição do argumento. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction [expr1] [expr2]'. - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - A sintaxe 'expr1[expr2]' agora está reservada para indexação e é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction expr1 [expr2]'. - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - Esse valor não é uma função e não pode ser aplicado. Você pretendia acessar o indexador por meio do '{0}.[index]'? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - Essa expressão não é uma função e não pode ser aplicada. Você pretendia acessar o indexador por meio do 'expr.[index]'? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? Este valor não é uma função e não pode ser aplicado. Você esqueceu de finalizar a declaração? diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index a877af1b88c..43fdc52908d 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - expr[idx] для индексации и среза - - static abstract interface members статические абстрактные элементы интерфейса @@ -1517,11 +1512,6 @@ Для индексирования используется синтаксис "expr1[expr2]". Рассмотрите возможность добавления аннотации типа для включения индексации или при вызове функции добавьте пробел, например "expr1 [expr2]". - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - Синтаксис "expr1[expr2]" сейчас зарезервирован для индексирования. См. https://aka.ms/fsharp-index-notation. При вызове функции добавьте пробел между функцией и аргументом, например "someFunction [expr]". - - Byref types are not allowed in an open type declaration. Типы ByRef запрещены в объявлении открытого типа. @@ -1622,11 +1612,6 @@ Синтаксис "[expr1][expr2]" неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. Если вы намереваетесь индексировать или разрезать, необходимо использовать "(expr1).[expr2]" в позиции аргумента. При вызове функции с несколькими каррированными аргументами добавьте пробел между ними, например "someFunction [expr1] [expr2]". - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - Синтаксис "[expr1][expr2]" теперь зарезервирован для индексирования и неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. При вызове функции с несколькими каррированными аргументами добавьте между ними пробел, например "someFunction [expr1] [expr2]". - - A [<Literal>] declaration cannot use an active pattern for its identifier Объявление [<Literal>] не может использовать активный шаблон для своего идентификатора @@ -1677,26 +1662,6 @@ Не найдено статическое абстрактное свойство, соответствующее этому переопределению. - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Это выражение поддерживает индексирование, например, "expr. [index]". Для синтаксиса "expr[index]" требуется /langversion:preview. См. https://aka.ms/fsharp-index-notation. - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Это значение поддерживает индексирование, например, "{0}.[index]". Для синтаксиса "{1}[index]" требуется /langversion:preview. См. https://aka.ms/fsharp-index-notation. - - - - This expression is not a function and does not support index notation. - Это выражение не является функцией и не поддерживает нотацию индекса. - - - - The value '{0}' is not a function and does not support index notation. - Значение {0} не является функцией и не поддерживает нотацию индекса. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ Синтаксис "expr1[expr2]" неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. Если вы намереваетесь индексировать или разрезать, необходимо использовать "expr1.[expr2]" в позиции аргумента. При вызове функции с несколькими каррированными аргументами добавьте пробел между ними, например "someFunction expr1 [expr2]". - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - Синтаксис "expr1[expr2]" теперь зарезервирован для индексирования и неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. При вызове функции с несколькими каррированными аргументами добавьте между ними пробел, например "someFunction expr1 [expr2]". - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ Синтаксис "(expr1)[expr2]" неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. Если вы намереваетесь индексировать или разрезать, необходимо использовать "(expr1).[expr2]" в позиции аргумента. При вызове функции с несколькими каррированными аргументами добавьте пробел между ними, например "someFunction (expr1) [expr2]". - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - Синтаксис "(expr1)[expr2]" теперь зарезервирован для индексирования и неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. При вызове функции с несколькими каррированными аргументами добавьте между ними пробел, например "someFunction (expr1) [expr2]". - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - Это значение не является функцией, и применить его невозможно. Вы хотели обратиться к индексатору с помощью "{0}.[index]"? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - Это выражение не является функцией, и применить его невозможно. Вы хотели обратиться к индексатору с помощью "expr.[index]"? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? Данное значение не является функцией и не может быть применено. Забыли завершить объявление? diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index bced047f177..969330f4833 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - Dizin oluşturma ve dilimleme için expr[idx] gösterimi - - static abstract interface members statik soyut arabirim üyeleri @@ -1517,11 +1512,6 @@ Söz dizimi “expr1[expr2]” dizin oluşturma için kullanılıyor. Dizin oluşturmayı etkinleştirmek için bir tür ek açıklama eklemeyi düşünün veya bir işlev çağırıyorsanız bir boşluk ekleyin, örn. “expr1 [expr2]”. - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - Söz dizimi “expr1[expr2]” artık dizin oluşturmak için ayrılmıştır. https://aka.ms/fsharp-index-notation'a bakın. Bir işlev çağırıyorsanız, işlev ile bağımsız değişken arasına bir boşluk ekleyin, örn. “someFunction [expr]”. - - Byref types are not allowed in an open type declaration. Açık tür bildiriminde Byref türlerine izin verilmez. @@ -1622,11 +1612,6 @@ Söz dizimi “[expr1][expr2]”, bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Dizin oluşturmayı veya dilimlemeyi düşünüyorsanız, bağımsız değişken konumunda “(expr1).[expr2]” kullanmanız gerekir. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction [expr1] [expr2]” gibi bir boşluk ekleyin. - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - Söz dizimi “[expr1][expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction [expr1] [expr2]”. - - A [<Literal>] declaration cannot use an active pattern for its identifier Bir [<Literal>] bildirimi, tanımlayıcısı için aktif bir kalıp kullanamaz @@ -1677,26 +1662,6 @@ Bu geçersiz kılmaya karşılık gelen hiçbir statik soyut özellik bulunamadı - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Bu ifade dizin oluşturmayı destekler, örn. “expr.[index]”. Söz dizimi “expr.[index]” /langversion:preview gerektirir. https://aka.ms/fsharp-index-notation'a bakın. - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - Bu değer dizin oluşturmayı destekler, örn. “{0}.[index]”. Söz dizimi “{1}[index]” /langversion:preview gerektirir. https://aka.ms/fsharp-index-notation'a bakın. - - - - This expression is not a function and does not support index notation. - Bu ifade bir işlev değildir ve dizin gösterimini desteklemez. - - - - The value '{0}' is not a function and does not support index notation. - “{0}” değeri bir işlev değildir ve dizin gösterimini desteklemez. - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ Söz dizimi “expr1[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Dizin oluşturmayı veya dilimlemeyi düşünüyorsanız, bağımsız değişken konumunda “expr1.[expr2]” kullanmalısınız. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction expr1 [expr2]”. - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - Söz dizimi “expr1[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction expr1 [expr2]”. - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ Söz dizimi “(expr1)[expr2]” bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Dizin oluşturmayı veya dilimlemeyi düşünüyorsanız, bağımsız değişken konumunda “(expr1).[expr2]” kullanmalısınız. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction (expr1) [expr2]”. - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - Söz dizimi “(expr1)[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction (expr1) [expr2]”. - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - Bu değer, bir işlev değil ve uygulanamaz. Dizin oluşturucuya bunun yerine “{0}.[index]” üzerinden erişmeye mi çalışıyordunuz? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - Bu ifade bir fonksiyon değildir ve uygulanamaz. Dizin oluşturucuya “expr.[index]” aracılığıyla mı erişmeyi düşündünüz? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? Bu değer bir işlev değil ve uygulanamaz. Bir bildirimi sonlandırmayı mı unuttunuz? diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 1193d6bfcfe..d846fb3af03 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - 用于索引和切片的 expr[idx] 表示法 - - static abstract interface members 静态抽象接口成员 @@ -1517,11 +1512,6 @@ 语法“expr1[expr2]”用于索引。考虑添加类型批注来启用索引,或者在调用函数添加空格,例如“expr1 [expr2]”。 - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - 语法“expr1[expr2]”现在保留用于索引。请参阅 https://aka.ms/fsharp-index-notation。如果调用函数,请在函数和参数之间添加空格,例如“someFunction [expr]”。 - - Byref types are not allowed in an open type declaration. 在开放类型声明中不允许使用 Byref 类型。 @@ -1622,11 +1612,6 @@ 语法“[expr1][expr2]”用作参数时不明确。请参阅 https://aka.ms/fsharp-index-notation。如果要索引或切片,则必须在参数位置使用“(expr1).[expr2]”。如果使用多个扩充参数调用函数,请在它们之间添加空格,例如“someFunction [expr1] [expr2]”。 - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - 语法“[expr1][expr2]”现在保留用于索引,用作参数时不明确。请参见 https://aka.ms/fsharp-index-notation。如果使用多个扩充参数调用函数, 请在它们之间添加空格,例如“someFunction [expr1] [expr2]”。 - - A [<Literal>] declaration cannot use an active pattern for its identifier [<Literal>] 声明不能对其标识符使用活动模式 @@ -1677,26 +1662,6 @@ 未找到与此重写对应的静态抽象属性 - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - 此表达式支持索引,例如“expr.[index]”。语法“expr[index]”需要 /langversion:preview。请参阅 https://aka.ms/fsharp-index-notation。 - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - 此值支持索引,例如“{0}.[index]”。语法“{1}[index]”需要 /langversion:preview。请参阅 https://aka.ms/fsharp-index-notation。 - - - - This expression is not a function and does not support index notation. - 此表达式不是函数,不支持索引表示法。 - - - - The value '{0}' is not a function and does not support index notation. - 值 '{0}' 不是函数,不支持索引表示法。 - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ 语法“expr1[expr2]”用作参数时不明确。请参阅 https://aka.ms/fsharp-index-notation。如果要索引或切片,则必须在参数位置使用“expr1.[expr2]”。如果使用多个扩充参数调用函数,请在它们之间添加空格,例如“someFunction expr1 [expr2]”。 - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - 语法“expr1[expr2]”现在保留用于索引,用作参数时不明确。请参见 https://aka.ms/fsharp-index-notation。如果使用多个扩充参数调用函数, 请在它们之间添加空格,例如“someFunction expr1 [expr2]”。 - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ 语法“(expr1)[expr2]”用作参数时不明确。请参阅 https://aka.ms/fsharp-index-notation。如果要索引或切片,则必须在参数位置使用“(expr1)[expr2]”。如果使用多个扩充参数调用函数,请在它们之间添加空格,例如“someFunction (expr1)[expr2]”。 - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - 语法“(expr1)[expr2]”现在保留用于索引,用作参数时不明确。请参见 https://aka.ms/fsharp-index-notation。如果使用多个扩充参数调用函数, 请在它们之间添加空格,例如“someFunction (expr1) [expr2]”。 - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - 此值不是一个函数,无法应用。是否曾打算通过 '{0}.[index]' 访问索引器? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - 此表达式不是函数,无法应用。是否曾打算通过 expr.[index] 访问索引器? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? 此值不是一个函数,无法应用。您是否忘记结束某个声明? diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index f1a7a9b02aa..273d94dcc27 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -472,11 +472,6 @@ Improved implied argument names with partial application - - expr[idx] notation for indexing and slicing - 用於編製索引和分割的 expr[idx] 註釋 - - static abstract interface members 靜態抽象介面成員 @@ -1517,11 +1512,6 @@ 語法 'expr1[expr2]' 已用於編製索引。請考慮新增類型註釋來啟用編製索引,或是呼叫函式並新增空格,例如 'expr1 [expr2]'。 - - The syntax 'expr1[expr2]' is now reserved for indexing. See https://aka.ms/fsharp-index-notation. If calling a function, add a space between the function and argument, e.g. 'someFunction [expr]'. - 語法 'expr1[expr2]' 現已為編製索引保留。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫函式,請在函式與引數之間新增空格,例如 'someFunction [expr]'。 - - Byref types are not allowed in an open type declaration. 開放式類型宣告中不允許 Byref 類型。 @@ -1622,11 +1612,6 @@ 語法 '[expr1][expr2]' 用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果您要編製索引或切割,則必須在引數位置使用 '(expr1).[expr2]'。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction [expr1] [expr2]'。 - - The syntax '[expr1][expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction [expr1] [expr2]'. - 語法 '[expr1][expr2]' 現已為編製索引保留,但用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction [expr1] [expr2]'。 - - A [<Literal>] declaration cannot use an active pattern for its identifier [<Literal>] 宣告不能對其識別碼使用現用模式 @@ -1677,26 +1662,6 @@ 找不到對應到這個覆寫的靜態抽象屬性 - - This expression supports indexing, e.g. 'expr.[index]'. The syntax 'expr[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - 此運算式支援編製索引,例如 'expr.[index]'。語法 'expr[index]' 需要 /langversion:preview。請參閱 https://aka.ms/fsharp-index-notation。 - - - - This value supports indexing, e.g. '{0}.[index]'. The syntax '{1}[index]' requires /langversion:preview. See https://aka.ms/fsharp-index-notation. - 此值支援編製索引,例如 '{0}.[index]'。語法 '{1}[index]' 需要 /langversion:preview。請參閱 https://aka.ms/fsharp-index-notation。 - - - - This expression is not a function and does not support index notation. - 此運算式並非函式,不支援索引標記法。 - - - - The value '{0}' is not a function and does not support index notation. - 值 '{0}' 並非函式,不支援索引標記法。 - - With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. With nullness checking enabled, overrides of .ToString() method must return a non-nullable string. You can handle potential nulls via the built-in string function. @@ -1717,11 +1682,6 @@ 語法 'expr1[expr2]' 用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果您要編製索引或切割,則必須在引數位置使用 'expr1.[expr2]'。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction expr1 [expr2]'。 - - The syntax 'expr1[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. - 語法 'expr1[expr2]' 現已為編製索引保留,但用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction expr1 [expr2]'。 - - The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. The 'OverloadResolutionPriorityAttribute' cannot be applied to an override member. Apply it to the original declaration instead. @@ -1737,11 +1697,6 @@ 語法 '(expr1)[expr2]' 用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果您要編製索引或切割,則必須在引數位置使用 '(expr1).[expr2]'。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction (expr1) [expr2]'。 - - The syntax '(expr1)[expr2]' is now reserved for indexing and is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction (expr1) [expr2]'. - 語法 '(expr1)[expr2]' 現已為編製索引保留,但用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction (expr1) [expr2]'。 - - Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern. @@ -8822,16 +8777,6 @@ This value is not a function and cannot be applied. It has type '{0}', which does not accept arguments. - - This value is not a function and cannot be applied. Did you intend to access the indexer via '{0}.[index]'? - 此值並非函式,因而無法套用。您要用 '{0}.[index]' 存取索引子嗎? - - - - This expression is not a function and cannot be applied. Did you intend to access the indexer via 'expr.[index]'? - 此運算式並非函式,因而無法套用。您要用 'expr.[index]' 存取索引子嗎? - - This value is not a function and cannot be applied. Did you forget to terminate a declaration? 這個值不是函式,無法套用。您是不是忘記終止宣告了? From c327f8908d38461b52742d58878660fc77053685 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 26 Aug 2026 17:19:12 +0200 Subject: [PATCH 7/8] Replace the stringified pattern-match memo key with a typed one (#20337) * Replace the stringified pattern-match memo key with a typed one The memo added in #20244 keyed residual match states by concatenating paths, pattern node ids and bound expressions into a string, then compared those strings. Replace it with structural keys: - PathKey / BoundExprKey / FrontierKey / MemoKey instead of string concatenation, so equality is structural rather than textual. - Record field and union case keys now carry the declaring tycon stamp, so same-named fields of different types can no longer fuse. - MemoEntry replaces the (int ref * Lazy * Lazy<_>) tuple. - The diagnostics/codegen distinction is a JoinPromotion argument rather than being inferred from warnOnIncomplete, which happened to coincide. Behaviour preserving: emitted assembly size and full IL fingerprint are identical to main for the issue #18425 repro at N=8..40. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 86c47998-fe39-4b68-8b80-c72b72fc9efb * Add release note Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 86c47998-fe39-4b68-8b80-c72b72fc9efb * Keep the memo machinery private and drop a redundant pass CompilePatternBasic is only called from CompilePattern in this file and is not in the signature file, so it and JoinPromotion can be private like the key types already are. Also name the pattern node id in FrontierKey (matching the existing ClauseNumber alias) and build the bound-expression key list in one pass instead of Map.toList followed by List.map. Map enumerates in ascending key order, so the key is unchanged; verified IL-identical. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 86c47998-fe39-4b68-8b80-c72b72fc9efb * Document the key types State the safety invariant on the path key directly (equal keys imply pathEq, so being finer only costs memo misses), and give FrontierKey and MemoEntry the same brief purpose comments the neighbouring types have. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 86c47998-fe39-4b68-8b80-c72b72fc9efb * Record what the size guard actually catches Red-green checked by disabling promotion: the N=32 input then runs for 383s and is OOM-killed rather than emitting something slightly over the bound, so the exact constant does not matter. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 86c47998-fe39-4b68-8b80-c72b72fc9efb * Drop the release note This is an internal refactoring with no observable behaviour change, and the latent over-fusion it fixes was introduced by #20244 in this same release, so no shipped compiler could exhibit it. Labelled NO_RELEASE_NOTES. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 86c47998-fe39-4b68-8b80-c72b72fc9efb --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 86c47998-fe39-4b68-8b80-c72b72fc9efb --- .../Checking/PatternMatchCompilation.fs | 154 +++++++++++------- .../GuardedOrPatternComplexity.fs | 12 ++ 2 files changed, 110 insertions(+), 56 deletions(-) diff --git a/src/Compiler/Checking/PatternMatchCompilation.fs b/src/Compiler/Checking/PatternMatchCompilation.fs index dd7243ba1fb..e1b2afc7c90 100644 --- a/src/Compiler/Checking/PatternMatchCompilation.fs +++ b/src/Compiler/Checking/PatternMatchCompilation.fs @@ -396,17 +396,6 @@ type Actives = Active list /// Represents an unresolved portion of pattern matching within a clause type Frontier = Frontier of ClauseNumber * Actives * ValMap -// Keep in sync with pathEq: equal keys may share one compiled residual state. -let rec private frontierPathKey p = - match p with - | PathQuery(p, n) -> "Q" + string n + frontierPathKey p - | PathTuple(p, _, n) -> "T" + string n + frontierPathKey p - | PathRecd(p, _, _, n) -> "R" + string n + frontierPathKey p - | PathUnionConstr(p, _, _, n) -> "U" + string n + frontierPathKey p - | PathArray(p, _, i1, i2) -> "A" + string i1 + "_" + string i2 + frontierPathKey p - | PathExnConstr(p, _, n) -> "E" + string n + frontierPathKey p - | PathEmpty _ -> "." - type InvestigationPoint = Investigation of ClauseNumber * DecisionTreeTest * Path // Note: actives must be a SortedDictionary @@ -994,10 +983,70 @@ let rec isPatternDisjunctive inpPat = // The algorithm //--------------------------------------------------------------------------- -let CompilePatternBasic +/// Equal keys imply pathEq. Keeping the array length (as the string key did) makes this finer +/// than pathEq, which only costs memo misses. +[] +type private PathKey = + | Query of Unique + | Tuple of int + | Recd of int + | UnionConstr of int + | Array of length: int * index: int + | ExnConstr of int + +let rec private pathKey p = + match p with + | PathQuery(p, n) -> PathKey.Query n :: pathKey p + | PathTuple(p, _, n) -> PathKey.Tuple n :: pathKey p + | PathRecd(p, _, _, n) -> PathKey.Recd n :: pathKey p + | PathUnionConstr(p, _, _, n) -> PathKey.UnionConstr n :: pathKey p + | PathArray(p, _, len, n) -> PathKey.Array(len, n) :: pathKey p + | PathExnConstr(p, _, n) -> PathKey.ExnConstr n :: pathKey p + | PathEmpty _ -> [] + +/// Field keys include the declaring tycon, so same-named fields of different types never fuse. +[] +type private BoundExprKey = + | Local of Stamp + | TupleField of index: int * BoundExprKey + | RecdField of tycon: Stamp * field: string * BoundExprKey + | UnionField of tycon: Stamp * case: string * index: int * BoundExprKey + | Coerce of BoundExprKey + | Opaque of nodeId: int + +type private PatternNodeId = int + +/// One clause's outstanding work: sub-terms still to be tested, plus what it has already bound. +[] +type private FrontierKey = + { Clause: ClauseNumber + Actives: (PathKey list * PatternNodeId) list + Bound: (Stamp * BoundExprKey) list } + +/// Residual match states with equal keys compile to the same tree. +[] +type private MemoKey = + { Frontiers: FrontierKey list + Captured: Stamp list } + +/// Hits counts visits to one state; the thunk is built only once it is visited past the threshold. +[] +type private MemoEntry = + { mutable Hits: int + IsPromotable: Lazy + JoinThunk: Lazy } + +/// Off for the throwaway diagnostics pass and for matches that cannot blow up in the first place. +[] +type private JoinPromotion = + | Disabled + | Enabled + +let private CompilePatternBasic (g: TcGlobals) denv amap tcVal infoReader mExpr mMatch warnOnUnused warnOnIncomplete + (joinPromotion: JoinPromotion) actionOnFailure (origInputVal, origInputValTypars, _origInputExprOpt: Expr option) (clauses: MatchClause list) @@ -1144,8 +1193,11 @@ let CompilePatternBasic let stackGuard = StackGuard("InvestigateFrontiers") let joinPromotionThreshold = 32 let isThunkableTy ty = not (isByrefLikeTy g mExpr ty) && not (isByrefTy g ty) + + // Promoted states are let-bound thunks, not shared TTargets: re-entering a TTarget embeds a + // copy of the target array, so nested promotions compound (measured: 167MB vs 1.4MB at N=48). let joinBindings = ResizeArray() - let frontierMemo = Dictionary * Lazy>() + let frontierMemo = Dictionary() // The full body includes clause targets, which may contain constructs that cannot move into a lambda. let isLiftableJoinBody body = @@ -1173,9 +1225,6 @@ let CompilePatternBasic ids[pat] <- v v - let frontierActiveKey (Active(path, _, pat)) = - frontierPathKey path + "#" + string (patternNodeId pat) - let boundExprNodeId = let ids = System.Collections.Generic.Dictionary(HashIdentity.Reference) fun (e: Expr) -> @@ -1188,27 +1237,21 @@ let CompilePatternBasic let rec boundExprKey (e: Expr) = match stripDebugPoints e with - | Expr.Val(vref, _, _) -> "v" + string vref.Stamp - | Expr.Op(TOp.TupleFieldGet(_, j), _, [ arg ], _) -> "t" + string j + "(" + boundExprKey arg + ")" - | Expr.Op(TOp.ValFieldGet rfref, _, args, _) -> "r" + rfref.FieldName + "(" + String.concat "," (List.map boundExprKey args) + ")" - | Expr.Op(TOp.UnionCaseFieldGet(ucref, j), _, args, _) -> "u" + ucref.CaseName + "_" + string j + "(" + String.concat "," (List.map boundExprKey args) + ")" - | Expr.Op(TOp.Coerce, _, [ arg ], _) -> "c(" + boundExprKey arg + ")" - | _ -> "?" + string (boundExprNodeId e) - - let frontierValMapKey (valMap: ValMap) = - if valMap.IsEmpty then - "" - else - valMap.Contents - |> Seq.map (fun (KeyValue (stamp, boundExpr)) -> string stamp + "=" + boundExprKey boundExpr) - |> Seq.sort - |> String.concat ";" - - let frontiersStateKey frontiers = - frontiers - |> List.map (fun (Frontier(i, actives, valMap)) -> - string i + ":" + String.concat "," (List.map frontierActiveKey actives) + "{" + frontierValMapKey valMap + "}") - |> String.concat "|" + | Expr.Val(vref, _, _) -> BoundExprKey.Local vref.Stamp + | Expr.Op(TOp.TupleFieldGet(_, j), _, [ arg ], _) -> BoundExprKey.TupleField(j, boundExprKey arg) + | Expr.Op(TOp.ValFieldGet(RecdFieldRef(tcref, nm)), _, [ arg ], _) -> BoundExprKey.RecdField(tcref.Stamp, nm, boundExprKey arg) + | Expr.Op(TOp.UnionCaseFieldGet(UnionCaseRef(tcref, nm), j), _, [ arg ], _) -> BoundExprKey.UnionField(tcref.Stamp, nm, j, boundExprKey arg) + | Expr.Op(TOp.Coerce, _, [ arg ], _) -> BoundExprKey.Coerce(boundExprKey arg) + | _ -> BoundExprKey.Opaque(boundExprNodeId e) + + let memoKeyOf frontiers capturedVals = + { Frontiers = + frontiers + |> List.map (fun (Frontier(i, actives, valMap)) -> + { Clause = i + Actives = actives |> List.map (fun (Active(path, _, pat)) -> pathKey path, patternNodeId pat) + Bound = [ for KeyValue(stamp, e) in valMap.Contents -> stamp, boundExprKey e ] }) + Captured = capturedVals |> List.map (fun (v: Val) -> v.Stamp) } // The match input stays in scope at the outer join binding; only tree-bound locals need parameters. let capturedValsOfFrontiers frontiers = @@ -1290,34 +1333,33 @@ let CompilePatternBasic | None -> successTree and investigateMemoized refuted frontiers = - if warnOnIncomplete then + if joinPromotion = JoinPromotion.Disabled then InvestigateFrontiers refuted frontiers else - let caps = capturedValsOfFrontiers frontiers - let key = - frontiersStateKey frontiers + "|CAP:" + (caps |> List.map (fun v -> string v.Stamp) |> String.concat ",") + let capturedVals = capturedValsOfFrontiers frontiers + let key = memoKeyOf frontiers capturedVals match frontierMemo.TryGetValue key with - | true, (count, promotable, shared) -> - count.Value <- count.Value + 1 - if (shared.IsValueCreated || count.Value > joinPromotionThreshold) && promotable.Value then - let joinE, joinThunkTy = shared.Value - callJoinThunk joinE joinThunkTy caps + | true, state -> + state.Hits <- state.Hits + 1 + if state.Hits > joinPromotionThreshold && state.IsPromotable.Value then + let joinE, joinThunkTy = state.JoinThunk.Value + callJoinThunk joinE joinThunkTy capturedVals else InvestigateFrontiers refuted frontiers | _ -> let subtree = InvestigateFrontiers refuted frontiers let joinBody = lazy (mkAndSimplifyMatch DebugPointAtBinding.NoneAtInvisible mExpr mMatch resultTy subtree (matchBuilder.CloseTargets())) - let promotable = + let isPromotable = lazy - (match subtree with TDSuccess _ -> false | _ -> true) + (match subtree with TDSuccess _ -> false | TDSwitch _ | TDBind _ -> true) && isLiftableJoinBody joinBody.Value - let shared = + let joinThunk = lazy - let paramVals = caps |> List.map (fun v -> fst (mkCompGenLocal mMatch "joinCap" v.Type)) + let paramVals = capturedVals |> List.map (fun v -> fst (mkCompGenLocal mMatch "joinCap" v.Type)) let remap = { Remap.Empty with - valRemap = ValMap.OfList (List.map2 (fun (c: Val) (p: Val) -> c, mkLocalValRef p) caps paramVals) } + valRemap = ValMap.OfList (List.map2 (fun (c: Val) (p: Val) -> c, mkLocalValRef p) capturedVals paramVals) } let body = remapExpr g CloneAll remap joinBody.Value let unitV, _ = mkCompGenLocal mMatch "unitArg" g.unit_ty let joinThunkTy = List.foldBack (fun (p: Val) acc -> mkFunTy g p.Type acc) paramVals (mkFunTy g g.unit_ty resultTy) @@ -1325,7 +1367,7 @@ let CompilePatternBasic let joinV, joinE = mkCompGenLocal mMatch "joinThunk" joinThunkTy joinBindings.Add(mkInvisibleBind joinV joinLam) (joinE, joinThunkTy) - frontierMemo[key] <- ref 1, promotable, shared + frontierMemo[key] <- { Hits = 1; IsPromotable = isPromotable; JoinThunk = joinThunk } subtree /// Select the set of discriminators which we can handle in one test, or as a series of iterated tests, @@ -1855,7 +1897,7 @@ let rec CompilePattern g denv amap tcVal infoReader mExpr mMatch warnOnUnused a let warnOnUnused = false // we can't turn this on since we're pretending all partials fail in order to control the complexity of this. let warnOnIncomplete = true let clausesPretendAllPartialFail = clausesL |> List.collect (fun (MatchClause(p, whenOpt, tg, m)) -> [MatchClause(erasePartialPatterns p, whenOpt, tg, m)]) - let _ = CompilePatternBasic g denv amap tcVal infoReader mExpr mMatch warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) clausesPretendAllPartialFail inputTy resultTy + let _ = CompilePatternBasic g denv amap tcVal infoReader mExpr mMatch warnOnUnused warnOnIncomplete JoinPromotion.Disabled actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) clausesPretendAllPartialFail inputTy resultTy let warnOnIncomplete = false // Partial and when clauses cause major code explosion if treated naively @@ -1863,7 +1905,7 @@ let rec CompilePattern g denv amap tcVal infoReader mExpr mMatch warnOnUnused a let rec atMostOneProblematicClauseAtATime clauses = match List.takeUntil isProblematicClause clauses with | l, [] -> - CompilePatternBasic g denv amap tcVal infoReader mExpr mMatch warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) l inputTy resultTy + CompilePatternBasic g denv amap tcVal infoReader mExpr mMatch warnOnUnused warnOnIncomplete JoinPromotion.Enabled actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) l inputTy resultTy | l, h :: t -> // Add the problematic clause. doGroupWithAtMostOneProblematic (l @ [h]) t @@ -1878,10 +1920,10 @@ let rec CompilePattern g denv amap tcVal infoReader mExpr mMatch warnOnUnused a // Make the clause that represents the remaining cases of the pattern match let clauseForRestOfMatch = MatchClause(TPat_wild mMatch, None, TTarget(List.empty, expr, None), mMatch) - CompilePatternBasic g denv amap tcVal infoReader mExpr mMatch warnOnUnused warnOnIncomplete actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) (group @ [clauseForRestOfMatch]) inputTy resultTy + CompilePatternBasic g denv amap tcVal infoReader mExpr mMatch warnOnUnused warnOnIncomplete JoinPromotion.Enabled actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) (group @ [clauseForRestOfMatch]) inputTy resultTy atMostOneProblematicClauseAtATime clausesL | _ -> - CompilePatternBasic g denv amap tcVal infoReader mExpr mMatch warnOnUnused true actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) clausesL inputTy resultTy + CompilePatternBasic g denv amap tcVal infoReader mExpr mMatch warnOnUnused true JoinPromotion.Disabled actionOnFailure (origInputVal, origInputValTypars, origInputExprOpt) clausesL inputTy resultTy diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/GuardedOrPatternComplexity.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/GuardedOrPatternComplexity.fs index 2b6f7db32cd..720b23b0ed5 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/GuardedOrPatternComplexity.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/PatternMatching/GuardedOrPatternComplexity.fs @@ -47,6 +47,18 @@ let main _ = guardedOrSource 24 |> runsWith "r1=-1 r2=2000" + // Emits ~506KB today. Without promotion this input does not merely exceed the bound, it OOMs + // the compiler, so the exact constant is not load-bearing; the refuted shared-target design emitted ~3MB. + [] + let ``Issue 18425 - promoted subtrees are shared by name, not copied`` () = + guardedOrSource 32 + |> FSharp + |> asExe + |> compile + |> shouldSucceed + |> withPeReader (fun pe -> pe.GetEntireImage().Length) + |> fun emitted -> Assert.True(emitted < 1_000_000, $"emitted assembly is {emitted} bytes") + [] let ``Issue 18425 - shared guard binding a variable at different positions is not over-fused`` () = """module Test From 57e48828c26dfed12ff259d4f54248ff9a6d5b6f Mon Sep 17 00:00:00 2001 From: nojaf Date: Wed, 26 Aug 2026 19:28:56 +0200 Subject: [PATCH 8/8] Add postmortem --- .../instructions/SyntaxTree.instructions.md | 24 ++++++ docs/postmortems/README.md | 1 + ...n-parse-tree-fidelity-return-attributes.md | 78 +++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 docs/postmortems/regression-parse-tree-fidelity-return-attributes.md diff --git a/.github/instructions/SyntaxTree.instructions.md b/.github/instructions/SyntaxTree.instructions.md index 666713e1b8b..0e92a9e8d2e 100644 --- a/.github/instructions/SyntaxTree.instructions.md +++ b/.github/instructions/SyntaxTree.instructions.md @@ -1,7 +1,31 @@ --- applyTo: - "src/Compiler/SyntaxTree/SyntaxTree.{fs,fsi}" + - "src/Compiler/SyntaxTree/SyntaxTreeOps.{fs,fsi}" + - "src/Compiler/SyntaxTree/ParseHelpers.{fs,fsi}" - "src/Compiler/pars.fsy" --- +# The Untyped Syntax Tree + Read `docs/changing-the-ast.md`. + +## The parse tree describes the source, not the semantics + +`SynBinding`, `SynExpr`, `SynPat` and friends answer one question: **what did the user write, and where?** They are not a private staging area for the type checker — they are the public output of `FSharpParseFileResults`, and for formatters, analyzers, source generators and refactoring tooling they are the *only* view of the file. + +The parser is the last stage that sees the source. Anything it discards or rewrites is gone: no downstream consumer can recover it. + +So do not move, merge, synthesize or drop nodes in the parser to suit a downstream consumer, even when the relocation is semantically correct. Lower it in `BindingNormalization`, in the checker, or wherever the consumer actually reads — those stages can rewrite freely because the parse tree survives them intact. + +Watch for the lossy variants specifically. Narrowing a range (an attribute's own span instead of the `[< >]` that encloses it) and flattening a grouping (splicing several `SynAttributeList`s into one) both destroy information that no later stage can reconstruct. + +If a checker-side fix tempts you to edit `mkSynBinding` or a `pars.fsy` action, ask what the untyped tree now claims about source it can no longer describe. + +## Changing tree shape requires baseline coverage + +`tests/service/data/SyntaxTree` pretty-prints parse trees to `.bsl` files, so a shape change surfaces as a baseline diff a reviewer has to accept. That safety net only works for syntax the corpus actually contains — an uncovered case produces no diff, which reads exactly like a change that broke nothing. + +When you change what the parser produces, add a `.fs`/`.bsl` pair for the syntax you touched before relying on a green run. Typed-tree tests (`AttributeCheckingTests.fs`, `Symbols.fs`, component tests) cannot substitute: they observe the tree *after* lowering, and will pass while the parse tree is wrong. + +See `docs/postmortems/regression-parse-tree-fidelity-return-attributes.md` for what this cost when it was ignored. diff --git a/docs/postmortems/README.md b/docs/postmortems/README.md index 8d3bc9a6166..0da4a4bd8e3 100644 --- a/docs/postmortems/README.md +++ b/docs/postmortems/README.md @@ -9,3 +9,4 @@ These are referenced from [agentic instructions](../../.github/instructions/) an - [`regression-fs0229-bstream-misalignment.md`](regression-fs0229-bstream-misalignment.md) — a conditional write with an unconditional read shifted the pickle B-stream, producing `FS0229` when reading older metadata. - [`regression-legacy-inline-metadata-dynamic-invocation.md`](regression-legacy-inline-metadata-dynamic-invocation.md) — a new inline-flag case reused a serialized bit pattern that already meant "required inline" in F# 5 binaries, breaking cross-assembly SRTP at runtime. - [`regression-sourcebuild-cpm-runtime-version-floor.md`](regression-sourcebuild-cpm-runtime-version-floor.md) — renaming the CPM runtime-package pins to computed `$(System*CentralVersion)` aliases with a floor defeated source-build's `$(System*Version)` override, causing prebuilt/`NU1109` failures in the VMR that fsharp CI could not see. +- [`regression-parse-tree-fidelity-return-attributes.md`](regression-parse-tree-fidelity-return-attributes.md) — a semantic lowering moved into the parser made `SynBinding.attributes` drop `[]`, so tools reading the untyped tree silently deleted attributes the source visibly had. diff --git a/docs/postmortems/regression-parse-tree-fidelity-return-attributes.md b/docs/postmortems/regression-parse-tree-fidelity-return-attributes.md new file mode 100644 index 00000000000..fc5daa92179 --- /dev/null +++ b/docs/postmortems/regression-parse-tree-fidelity-return-attributes.md @@ -0,0 +1,78 @@ +# Regression: `[]` Attributes Disappeared From the Untyped Syntax Tree + +## Summary + +A semantic lowering that had always run in the type checker was moved into the parser, so `SynBinding.attributes` stopped reporting `[]` attributes that were visibly present in the source. Tools that read the untyped tree — formatters, analyzers, source generators — were handed a tree that no longer matched the file it came from. Fantomas silently deleted every `[]` partial active pattern it formatted. + +## Error Manifestation + +No error. No warning. No diagnostic anywhere. + +Given source that visibly carries an attribute: + +```fsharp +[] +let (|Foo|_|) x = ValueNone +``` + +`SynBinding.attributes` was `[]`. A round-tripping tool read the binding, found nothing to print, and wrote the file back without the attribute: + +```fsharp +let (|Foo|_|) x = ValueNone // attribute gone, file still compiles, meaning changed +``` + +The failure is silent by construction: the consumer cannot detect an absence it was never told about. Fantomas' own code base contains 34 such active patterns, and self-formatting would have stripped all of them. + +## Root Cause + +`[]` on a binding is written in front of the binding but targets the method's return value. Routing it to `SynValInfo.retInfo` is correct for the type checker, IL emit and the Symbols API. The mistake was *where* the routing happened. + +[PR #19738](https://github.com/dotnet/fsharp/pull/19738) moved the rotation into `mkSynBinding` in `SyntaxTreeOps.fs`, a parser-stage constructor. Before that, the rotation lived in `TcNormalizedBinding` and patched a *local* `valSynData`; the `SynBinding` itself was never touched, so the parse tree stayed faithful to the source. + +The violated invariant: + +> **The untyped syntax tree describes where the user wrote things. Semantic relocation belongs downstream of it.** + +`SynBinding` has exactly one contract — report the source. It is not a type checker input in disguise; it is the public output of `FSharpParseFileResults`, and it is the *only* view some consumers have. Once the parser rewrites a node, no consumer can recover the original, because the parser is the last stage that saw the source. + +The rotation was lossy in two ways that made recovery impossible even for a consumer that knew about it: + +- The attribute list's range narrowed from the `[< >]` span to the attribute alone, so the brackets the user typed were no longer represented anywhere in the tree. +- Every return attribute was collected into one synthesized `SynAttributeList`, so `[]` and `[][]` produced identical trees. Neither can be printed back to its original form. + +## Why It Escaped + +The change was reviewed as a type-checker fix, and as a type-checker fix it was correct — both reported bugs (#17904, #19020) were genuinely fixed, and the tests added with it all passed: + +- `AttributeCheckingTests.fs` — diagnostics +- `Symbols.fs` — `mfv.ReturnParameter.Attributes` via the FCS Symbols API + +All of them observe the *typed* tree. None observes the parse tree. The blast radius of editing `mkSynBinding` — every untyped-tree consumer in the ecosystem — was never in view. + +The `tests/service/data/SyntaxTree` baseline corpus is exactly the mechanism that catches this: it pretty-prints the parse tree to a `.bsl` file, so any change to tree shape shows up as a baseline diff a reviewer must accept. At the time of #19738, **not one file in that corpus contained a `return:` attribute**. The corpus was silent because the case did not exist in it, and a silent corpus reads the same as a passing one. + +It shipped to nuget.org in `FSharp.Compiler.Service 43.13.101-preview7.26381.103` (2026-08-11). It was found downstream by [fsprojects/fantomas#3400](https://github.com/fsprojects/fantomas/pull/3400) while bumping vendored compiler sources — caught before any Fantomas release carried it, but only because that bump walked one upstream commit at a time. Fantomas' own suite stayed green throughout: its tests covered the return *type annotation* form (`let f x : [] int = x`), which never went through this rotation, and not the prefix form, which did. + +## Fix + +[PR #20356](https://github.com/dotnet/fsharp/pull/20356) moves the rotation to `BindingNormalization.NormalizeBinding` in `CheckExpressions.fs` — the single funnel from `SynBinding` to `NormalizedBinding`, and already a lowering step. Every consumer of the rotated form (`TcNormalizedBinding`, `AnalyzeAndMakeAndPublishRecursiveValue`, the object-expression paths) reads `NormalizeBinding`'s output, so both fixes from #19738 are unchanged and `retInfo` remains the single source of truth for the checker. + +`NormalizedBinding` holds a flat `SynAttribute list`, so `RotateReturnAttributes` now takes and returns that instead of `SynAttributes`. The list-splicing that flattened attribute grouping is gone with it — there is no grouping left to destroy at that layer. + +`SynBinding` again carries the attribute with its full `[< >]` range, and `retInfo` is empty at parse time. + +## Timeline + +| Date | PR | Change | +|---|---|---| +| 2026-05-20 | [#19738](https://github.com/dotnet/fsharp/pull/19738) | Rotation moved from `TcNormalizedBinding` (local `valSynData` patch) into `mkSynBinding`. Fixes #17904 and #19020; parse tree starts diverging from source. | +| 2026-08-11 | — | Ships to nuget.org in `FSharp.Compiler.Service 43.13.101-preview7.26381.103`. | +| 2026-08-21 | [fantomas#3400](https://github.com/fsprojects/fantomas/pull/3400) | Fantomas bumps vendored compiler sources, finds `[]` silently deleted, works around it with `restoreRotatedReturnAttributes`, and raises the layering question upstream. | +| 2026-08-25 | [#20356](https://github.com/dotnet/fsharp/pull/20356) | Rotation moved to `BindingNormalization.NormalizeBinding`. Parse tree faithful again; grouping and ranges preserved. | + +## Prevention + +- **Rule encoded** in [`.github/instructions/SyntaxTree.instructions.md`](../../.github/instructions/SyntaxTree.instructions.md): the parser must not perform semantic relocation, and any change to parse-tree shape needs `tests/service/data/SyntaxTree` coverage. +- **Baseline coverage added** in `tests/service/data/SyntaxTree/Attribute/`: `ReturnTargetedAttributeStaysOnBinding.fs` pins the attribute to `SynBinding.attributes` with its `[< >]` range, and `ReturnTargetedAttributeGroupingIsPreserved.fs` pins `[][]` and `[]` to distinct trees. + +The generalizable lesson is about *which* tests a change needs, not about attributes. A fix that is correct in the type checker can still be wrong in the parser, and only a parse-tree baseline will say so.