From 123e9649246e98b8b05be2c5f571b59ffd73db56 Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 2 Jun 2026 14:46:06 +0200 Subject: [PATCH 1/7] Add failing tests for signature-enforced attributes (issue #19560) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Signatures/SignatureEnforcedAttributes.fs | 110 ++++++++++++++++++ .../FSharp.Compiler.ComponentTests.fsproj | 1 + 2 files changed, 111 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/Signatures/SignatureEnforcedAttributes.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Signatures/SignatureEnforcedAttributes.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Signatures/SignatureEnforcedAttributes.fs new file mode 100644 index 00000000000..358845dd409 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Signatures/SignatureEnforcedAttributes.fs @@ -0,0 +1,110 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace Conformance.Signatures + +open Xunit +open FSharp.Test +open FSharp.Test.Compiler + +module SignatureEnforcedAttributes = + + let private fsi src = SourceCodeFileKind.Create("Library.fsi", src) + let private fs src = SourceCodeFileKind.Create("Library.fs", src) + + let private compileSigImpl (sigSrc: string) (implSrc: string) = + fsFromString (fsi sigSrc) + |> FS + |> withAdditionalSourceFile (fs implSrc) + |> asLibrary + |> compile + + [] + let ``NoDynamicInvocation in impl but not sig raises error`` () = + let sigSrc = """ +module M +val f: x: int -> int +""" + let implSrc = """ +module M +[] +let inline f (x: int) = x + 1 +""" + compileSigImpl sigSrc implSrc + |> shouldFail + |> withDiagnosticMessageMatches "NoDynamicInvocation" + + [] + let ``NoDynamicInvocation in both impl and sig compiles clean`` () = + let sigSrc = """ +module M +[] +val inline f: x: int -> int +""" + let implSrc = """ +module M +[] +let inline f (x: int) = x + 1 +""" + compileSigImpl sigSrc implSrc + |> shouldSucceed + + [] + let ``Regular attribute in impl but not sig does NOT raise enforcement error`` () = + let sigSrc = """ +module M +val f: x: int -> int +""" + let implSrc = """ +module M +[] +let f (x: int) = x + 1 +""" + // Obsolete is NOT in the enforced list - compilation must succeed. + compileSigImpl sigSrc implSrc + |> shouldSucceed + + [] + let ``InlineIfLambda in sig but not impl still raises (existing behavior preserved)`` () = + let sigSrc = """ +module M +val run: f: (int -> int) -> int +""" + let implSrc = """ +module M +let run ([] f: int -> int) = f 42 +""" + // Pre-existing FS3518 path. Must still fire. + compileSigImpl sigSrc implSrc + |> shouldFail + |> withDiagnosticMessageMatches "InlineIfLambda" + + [] + let ``Attribute absent from both impl and sig is fine`` () = + let sigSrc = """ +module M +val f: x: int -> int +""" + let implSrc = """ +module M +let f (x: int) = x + 1 +""" + compileSigImpl sigSrc implSrc + |> shouldSucceed + + [] + let ``NoDynamicInvocation on type member in impl but not sig raises error`` () = + let sigSrc = """ +module M +type T = + new: unit -> T + member F: x: int -> int +""" + let implSrc = """ +module M +type T() = + [] + member inline _.F(x: int) = x + 1 +""" + compileSigImpl sigSrc implSrc + |> shouldFail + |> withDiagnosticMessageMatches "NoDynamicInvocation" diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index acfeca79f35..4a6c86c355a 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -211,6 +211,7 @@ + From 48bb025117b468c886db6615121180ab649bb759 Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 2 Jun 2026 15:03:14 +0200 Subject: [PATCH 2/7] Enforce signature presence of compiler-semantic attributes from impl (issue #19560) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Compiler/Checking/SignatureConformance.fs | 22 ++++++++++++ src/Compiler/FSComp.txt | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.de.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.es.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.fr.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.it.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.ja.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.ko.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.pl.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.ru.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.tr.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 35 +++++++++++-------- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 35 +++++++++++-------- 15 files changed, 283 insertions(+), 195 deletions(-) diff --git a/src/Compiler/Checking/SignatureConformance.fs b/src/Compiler/Checking/SignatureConformance.fs index 0f3d5ec13fe..c7e297bc8f2 100644 --- a/src/Compiler/Checking/SignatureConformance.fs +++ b/src/Compiler/Checking/SignatureConformance.fs @@ -16,6 +16,7 @@ open FSharp.Compiler.InfoReader open FSharp.Compiler.Syntax open FSharp.Compiler.SyntaxTreeOps open FSharp.Compiler.Text +open FSharp.Compiler.TcGlobals open FSharp.Compiler.TypedTree open FSharp.Compiler.TypedTreeBasics open FSharp.Compiler.TypedTreeOps @@ -41,6 +42,20 @@ exception InterfaceNotRevealed of DisplayEnv * TType * range exception ArgumentsInSigAndImplMismatch of sigArg: Ident * implArg: Ident +/// The set of well-known Val-level attributes whose presence on an implementation +/// must be matched in the signature. These attributes change the contract observed +/// by consumers of a value/member (inlining behaviour, dynamic dispatch, codegen), +/// and tooling does not consult the implementation when a signature file is present +/// (so attributes only on the impl are silently lost). Adding a new attribute here +/// is the ONE PLACE required to enforce its presence in the signature. +let private signatureEnforcedAttributes (g: TcGlobals) : (string * (Val -> bool)) list = + [ + "NoDynamicInvocation", + (fun (v: Val) -> + ValHasWellKnownAttribute g WellKnownValAttributes.NoDynamicInvocationAttribute_True v + || ValHasWellKnownAttribute g WellKnownValAttributes.NoDynamicInvocationAttribute_False v) + ] + exception DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer of denv: DisplayEnv * implTycon:Tycon * @@ -368,6 +383,13 @@ type Checker(g, amap, denv, remapInfo: SignatureRepackageInfo, checkingSig) = let mk_err kind denv f = ValueNotContained(kind,denv, infoReader, implModRef, implVal, sigVal, f) let err denv f = errorR(mk_err RegularMismatch denv f); false let m = implVal.Range + + // Enforce that compiler-semantic attributes present on the implementation + // are also present on the signature. See `signatureEnforcedAttributes` for + // the list and rationale. + for (attrName, hasAttr) in signatureEnforcedAttributes g do + if hasAttr implVal && not (hasAttr sigVal) then + errorR(Error (FSComp.SR.implAttributeMissingFromSignature(attrName, implVal.DisplayName), m)) if implVal.IsMutable <> sigVal.IsMutable then (err denv FSComp.SR.ValueNotContainedMutabilityAttributesDiffer) elif implVal.LogicalName <> sigVal.LogicalName then (err denv FSComp.SR.ValueNotContainedMutabilityNamesDiffer) elif (implVal.CompiledName g.CompilerGlobalState) <> (sigVal.CompiledName g.CompilerGlobalState) then (err denv FSComp.SR.ValueNotContainedMutabilityCompiledNamesDiffer) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index f9765bdbd6e..79c64488b9f 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1705,6 +1705,7 @@ reprResumableCodeDefinitionWasGeneric,"A delegate or function producing resumabl reprStateMachineInvalidForm,"The state machine has an unexpected form" 3517,optFailedToInlineSuggestedValue,"The value '%s' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only." 3518,implMissingInlineIfLambda,"The 'InlineIfLambda' attribute is present in the signature but not the implementation." +3888,implAttributeMissingFromSignature,"The attribute '%s' is present on '%s' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present." 3519,tcInlineIfLambdaUsedOnNonInlineFunctionOrMethod,"The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type." 3520,invalidXmlDocPosition,"XML comment is not placed on a valid language element." 3521,tcInvalidMemberDeclNameMissingOrHasParen,"Invalid member declaration. The name of the member is missing or has parentheses." diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 10fe84e6ab1..0247d7d30c3 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -802,6 +802,11 @@ Konstruktor obnovitelného kódu {0} se dá použít jenom ve vloženém kódu chráněném příkazem if __useResumableCode then ... a celkové složení musí tvořit platný obnovitelný kód. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. Atribut InlineIfLambda se nachází v signatuře, ale ne v implementaci. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 17f93260936..341bdc5257d 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -802,6 +802,11 @@ Das fortsetzbare Codekonstrukt "{0}" darf nur in Inlinecode verwendet werden, der durch "if __useResumableCode then..." geschützt wird. Die Gesamtkomposition muss einen gültigen fortsetzbaren Code bilden. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. Das Attribut "InlineIfLambda" ist in der Signatur vorhanden, jedoch nicht in der Implementierung. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index ecc7e4a3f27..b7f8a1a95e5 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -802,6 +802,11 @@ La construcción de código reanudable "{0}" solo se puede usar en el código insertado protegido por "if __useResumableCode then ..." y la composición general debe formar un código reanudable válido. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. El atributo "InlineIfLambda" está presente en la firma, pero no en la implementación. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 3e0ab156a68..8443f26e848 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -802,6 +802,11 @@ La construction de code pouvant être repris «{0}» ne peut être utilisée que dans du code inlined protégé par «if __useResumableCode then ...» et la composition globale doit former un code pouvant être repris valide. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. L’attribut « InlineIfLambda » est présent dans la signature, mais pas dans l’implémentation. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 424a8e0310b..91529c59733 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -802,6 +802,11 @@ Il costrutto di codice ripristinabile '{0}' può essere usato solo nel codice impostato come inline e protetto da 'if __useResumableCode then...' e l'intera composizione deve formare codice ripristinabile valido. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. L'attributo 'InlineIfLambda' è presente nella firma, ma non nell'implementazione. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index d588b1908d7..9358e3ebdb4 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -802,6 +802,11 @@ 再開可能なコード コンストラクト '{0}' は、 'if __useResumableCode then ...' によって保護されているインライン コードでのみ使用でき、コンポジション全体は有効な再開可能コードを形成する必要があります。 + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. 'InlineIfLambda' 属性はシグネチャに存在しますが、実装はありません。 @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index ec0d939e7b2..1ae2f6c33f2 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -802,6 +802,11 @@ 다시 시작 가능한 코드 구문 '{0}'은 'if __useResumableCode then ...'로 보호되는 인라인 코드에서만 사용할 수 있습니다. 전반적인 구성은 유효한 다시 시작 가능한 코드를 형성해야 합니다. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. 'InlineIfLambda' 특성이 서명에 있지만 구현에는 없습니다. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index ae93051caa0..6deaccb8494 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -802,6 +802,11 @@ Konstrukcja kodu z możliwością wznowienia "{0}" może być używana tylko w nieliniowym kodzie chronionym przez "If __useResumableCode then..." i ogólna kompozycja musi być w formacie prawidłowego kodu z możliwością wznowienia. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. Atrybut "InlineIfLambda" jest obecny w sygnaturze, ale nie w implementacji. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 0e0c2367513..40fa335b5a9 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -802,6 +802,11 @@ A construção de código retomável '{0}' só pode ser usada em código delimitado protegido por 'se __useResumableCode então ...' e a composição geral deve formar um código retomável válido. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. O atributo 'InlineIfLambda' está presente na assinatura, mas não na implementação. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index e25503d865e..700b441ca84 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -802,6 +802,11 @@ Конструкцию возобновляемого кода "{0}" можно использовать только во встроенном коде, защищенном с помощью "if __useResumableCode then ...", а общая композиция должна представлять собой допустимый возобновляемый код. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. Атрибут "InlineIfLambda" присутствует в сигнатуре, но отсутствует в реализации. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index a296c02e44c..1cf99711192 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -802,6 +802,11 @@ Sürdürülebilir kod yapısı '{0}' yalnızca 'if__useResumableCode then ...' tarafından korunan satır içine alınmış kodda kullanılabilir ve genel birleştirme geçerli sürdürülebilir kod biçiminde olmalıdır. + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. 'InlineIfLambda' özniteliği imzada var ama uygulamada yok. @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index aa66fa326f6..7de9c275415 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -802,6 +802,11 @@ 可恢复的代码构造 "{0}" 只能用于受 "if __useResumableCode then..." 保护的内联代码,且整体组合必须构成有效的可恢复代码。 + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. "InlineIfLambda" 属性存在于签名中,但实现中不存在。 @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index d8517bff3ff..ef0484dc5ee 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -802,6 +802,11 @@ 可繼續的程式碼構造 '{0}' 只能用於 'if __useResumableCode then ...' 所保護的內嵌程式碼中,且整體組合必須形成有效的可繼續程式碼。 + + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + The attribute '{0}' is present on '{1}' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present. + + The 'InlineIfLambda' attribute is present in the signature but not the implementation. 'InlineIfLambda' 屬性存在於簽章中,但不存在於實作中。 @@ -8972,21 +8977,21 @@ This expression is a function value. When used in an interpolated string it will be formatted using its 'ToString' method, which is likely not the intended behavior. Consider applying the function to its arguments. - - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. - - - - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? - - - - emit GetObjectData and field-restoring deserialization constructor for exception types - emit GetObjectData and field-restoring deserialization constructor for exception types - - + + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + '{0}' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression. + + + + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements? + + + + emit GetObjectData and field-restoring deserialization constructor for exception types + emit GetObjectData and field-restoring deserialization constructor for exception types + + \ No newline at end of file From 32964ad2f01414185b5b6123e28a70f9201e6a9b Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 2 Jun 2026 15:36:28 +0200 Subject: [PATCH 3/7] Mirror NoDynamicInvocation into FSharp.Core .fsi files (issue #19560) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/FSharp.Core/nativeptr.fsi | 19 ++++++++++++++++ src/FSharp.Core/prim-types.fsi | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/src/FSharp.Core/nativeptr.fsi b/src/FSharp.Core/nativeptr.fsi index 2f380f85dae..798290f1d4e 100644 --- a/src/FSharp.Core/nativeptr.fsi +++ b/src/FSharp.Core/nativeptr.fsi @@ -25,6 +25,7 @@ module NativePtr = /// [] [] + [] val inline ofNativeInt: address: nativeint -> nativeptr<'T> /// Returns a machine address for a given typed native pointer. @@ -36,6 +37,7 @@ module NativePtr = /// [] [] + [] val inline toNativeInt: address: nativeptr<'T> -> nativeint /// Returns a typed native pointer for a untyped native pointer. @@ -47,6 +49,7 @@ module NativePtr = /// [] [] + [] val inline ofVoidPtr: address: voidptr -> nativeptr<'T> /// Returns an untyped native pointer for a given typed native pointer. @@ -58,6 +61,7 @@ module NativePtr = /// [] [] + [] val inline toVoidPtr: address: nativeptr<'T> -> voidptr /// Returns a typed native pointer for a Common IL (Intermediate Language) signature pointer. @@ -69,6 +73,7 @@ module NativePtr = /// [] [] + [] val inline ofILSigPtr: address: ilsigptr<'T> -> nativeptr<'T> /// Returns a Common IL (Intermediate Language) signature pointer for a given typed native pointer. @@ -80,6 +85,7 @@ module NativePtr = /// [] [] + [] val inline toILSigPtr: address: nativeptr<'T> -> ilsigptr<'T> /// Converts a given typed native pointer to a managed pointer. @@ -91,6 +97,7 @@ module NativePtr = /// [] [] + [] val inline toByRef: address: nativeptr<'T> -> byref<'T> /// Returns a typed native pointer by adding index * sizeof<'T> to the @@ -104,6 +111,7 @@ module NativePtr = /// [] [] + [] val inline add: address: nativeptr<'T> -> index: int -> nativeptr<'T> /// Dereferences the typed native pointer computed by adding index * sizeof<'T> to the @@ -117,6 +125,7 @@ module NativePtr = /// [] [] + [] val inline get: address: nativeptr<'T> -> index: int -> 'T /// Dereferences the given typed native pointer. @@ -128,6 +137,7 @@ module NativePtr = /// [] [] + [] val inline read: address: nativeptr<'T> -> 'T /// Assigns the value into the memory location referenced by the given typed native pointer. @@ -138,6 +148,7 @@ module NativePtr = /// [] [] + [] val inline write: address: nativeptr<'T> -> value: 'T -> unit /// Assigns the value into the memory location referenced by the typed native @@ -150,6 +161,7 @@ module NativePtr = /// [] [] + [] val inline set: address: nativeptr<'T> -> index: int -> value: 'T -> unit /// Allocates a region of memory on the stack. @@ -161,6 +173,7 @@ module NativePtr = /// [] [] + [] val inline stackalloc: count: int -> nativeptr<'T> /// Gets the null native pointer. @@ -171,6 +184,7 @@ module NativePtr = [] [] [] + [] val inline nullPtr<'T when 'T: unmanaged> : nativeptr<'T> /// Tests whether the given native pointer is null. @@ -182,6 +196,7 @@ module NativePtr = /// [] [] + [] val inline isNullPtr: address: nativeptr<'T> -> bool /// Clears the value stored at the location of a given native pointer. @@ -191,6 +206,7 @@ module NativePtr = /// [] [] + [] val inline clear: address: nativeptr<'T> -> unit /// Initializes a specified block of memory starting at a specific address to a given byte count and initial byte value. @@ -202,6 +218,7 @@ module NativePtr = /// [] [] + [] val inline initBlock: address: nativeptr<'T> -> value: byte -> count: uint32 -> unit /// Copies a value to a specified destination address from a specified source address. @@ -212,6 +229,7 @@ module NativePtr = /// [] [] + [] val inline copy: destination: nativeptr<'T> -> source: nativeptr<'T> -> unit /// Copies a block of memory to a specified destination address starting from a specified source address until a specified byte count of (count * sizeof<'T>). @@ -223,4 +241,5 @@ module NativePtr = /// [] [] + [] val inline copyBlock: destination: nativeptr<'T> -> source: nativeptr<'T> -> count: int -> unit diff --git a/src/FSharp.Core/prim-types.fsi b/src/FSharp.Core/prim-types.fsi index fb03e49d201..90f68893105 100644 --- a/src/FSharp.Core/prim-types.fsi +++ b/src/FSharp.Core/prim-types.fsi @@ -1745,6 +1745,7 @@ namespace Microsoft.FSharp.Core /// The input object. /// /// The managed pointer. + [] val inline (~&): obj: 'T -> byref<'T> /// Address-of. Uses of this value may result in the generation of unverifiable code. @@ -1752,6 +1753,7 @@ namespace Microsoft.FSharp.Core /// The input object. /// /// The unmanaged pointer. + [] val inline (~&&): obj: 'T -> nativeptr<'T> //------------------------------------------------------------------------- @@ -2773,6 +2775,7 @@ namespace Microsoft.FSharp.Core /// /// /// + [] val inline (~-): n: ^T -> ^T when ^T: (static member ( ~- ): ^T -> ^T) and default ^T: int /// Overloaded addition operator @@ -2803,6 +2806,7 @@ namespace Microsoft.FSharp.Core /// 10 - 2 // Evaluates to 8 /// /// + [] val inline (-): x: ^T1 -> y: ^T2 -> ^T3 when (^T1 or ^T2): (static member (-): ^T1 * ^T2 -> ^T3) and default ^T2: ^T3 and default ^T3: ^T1 and default ^T3: ^T2 and default ^T1: ^T3 and default ^T1: ^T2 and default ^T1: int /// Overloaded multiplication operator @@ -2831,6 +2835,7 @@ namespace Microsoft.FSharp.Core /// 16 / 2 // Evaluates to 8 /// /// + [] val inline (/): x: ^T1 -> y: ^T2 -> ^T3 when (^T1 or ^T2): (static member (/): ^T1 * ^T2 -> ^T3) and default ^T2: ^T3 and default ^T3: ^T1 and default ^T3: ^T2 and default ^T1: ^T3 and default ^T1: ^T2 and default ^T1: int /// Overloaded modulo operator @@ -2845,6 +2850,7 @@ namespace Microsoft.FSharp.Core /// 29 % 5 // Evaluates to 4 /// /// + [] val inline (%): x: ^T1 -> y: ^T2 -> ^T3 when (^T1 or ^T2): (static member (%): ^T1 * ^T2 -> ^T3) and default ^T2: ^T3 and default ^T3: ^T1 and default ^T3: ^T2 and default ^T1: ^T3 and default ^T1: ^T2 and default ^T1: int /// Overloaded bitwise-AND operator @@ -2862,6 +2868,7 @@ namespace Microsoft.FSharp.Core /// /// Evaluates to 9 /// + [] val inline (&&&): x: ^T -> y: ^T -> ^T when ^T: (static member (&&&): ^T * ^T -> ^T) and default ^T: int /// Overloaded bitwise-OR operator @@ -2879,6 +2886,7 @@ namespace Microsoft.FSharp.Core /// /// Evaluates to 15 /// + [] val inline (|||): x: ^T -> y: ^T -> ^T when ^T: (static member (|||): ^T * ^T -> ^T) and default ^T: int /// Overloaded bitwise-XOR operator @@ -2896,6 +2904,7 @@ namespace Microsoft.FSharp.Core /// /// Evaluates to 6 /// + [] val inline (^^^): x: ^T -> y: ^T -> ^T when ^T: (static member (^^^): ^T * ^T -> ^T) and default ^T: int /// Overloaded byte-shift left operator by a specified number of bits @@ -2912,6 +2921,7 @@ namespace Microsoft.FSharp.Core /// /// Evaluates to 208 /// + [] val inline (<<<): value: ^T -> shift: int32 -> ^T when ^T : (static member (<<<) : ^T * int32 -> ^T) and default ^T : int /// Overloaded byte-shift right operator by a specified number of bits @@ -2930,6 +2940,7 @@ namespace Microsoft.FSharp.Core /// Evaluates to 3 /// /// + [] val inline (>>>): value: ^T -> shift: int32 -> ^T when ^T: (static member (>>>): ^T * int32 -> ^T) and default ^T: int /// Overloaded bitwise-NOT operator @@ -2946,6 +2957,7 @@ namespace Microsoft.FSharp.Core /// Evaluates to 195 /// /// + [] val inline (~~~): value: ^T -> ^T when ^T: (static member (~~~): ^T -> ^T) and default ^T: int /// Overloaded prefix-plus operator @@ -2956,6 +2968,7 @@ namespace Microsoft.FSharp.Core /// /// /// + [] val inline (~+): value: ^T -> ^T when ^T: (static member (~+): ^T -> ^T) and default ^T: int /// Structural less-than comparison @@ -3289,6 +3302,7 @@ namespace Microsoft.FSharp.Core /// The result value. [] [] + [] val inline rethrow: unit -> 'T /// Rethrows an exception. This should only be used when handling an exception @@ -3310,6 +3324,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline reraise: unit -> 'T /// Builds a object. @@ -4493,6 +4508,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline byte: value: ^T -> byte when ^T: (static member op_Explicit: ^T -> byte) and default ^T: int /// Converts the argument to signed byte. This is a direct conversion for all @@ -4513,6 +4529,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline sbyte: value:^T -> sbyte when ^T: (static member op_Explicit: ^T -> sbyte) and default ^T: int /// Converts the argument to signed 16-bit integer. This is a direct conversion for all @@ -4533,6 +4550,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline int16: value: ^T -> int16 when ^T: (static member op_Explicit: ^T -> int16) and default ^T: int /// Converts the argument to unsigned 16-bit integer. This is a direct conversion for all @@ -4553,6 +4571,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline uint16: value: ^T -> uint16 when ^T: (static member op_Explicit: ^T -> uint16) and default ^T: int /// Converts the argument to signed 32-bit integer. This is a direct conversion for all @@ -4632,6 +4651,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline int32: value: ^T -> int32 when ^T: (static member op_Explicit: ^T -> int32) and default ^T: int /// Converts the argument to unsigned 32-bit integer. This is a direct conversion for all @@ -4652,6 +4672,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline uint32: value: ^T -> uint32 when ^T: (static member op_Explicit: ^T -> uint32) and default ^T: int /// Converts the argument to signed 64-bit integer. This is a direct conversion for all @@ -4672,6 +4693,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline int64: value: ^T -> int64 when ^T : (static member op_Explicit : ^T -> int64) and default ^T : int /// Converts the argument to unsigned 64-bit integer. This is a direct conversion for all @@ -4692,6 +4714,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline uint64: value: ^T -> uint64 when ^T: (static member op_Explicit: ^T -> uint64) and default ^T: int /// Converts the argument to 32-bit float. This is a direct conversion for all @@ -4712,6 +4735,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline float32: value: ^T -> float32 when ^T: (static member op_Explicit: ^T -> float32) and default ^T: int /// Converts the argument to 64-bit float. This is a direct conversion for all @@ -4732,6 +4756,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline float: value: ^T -> float when ^T: (static member op_Explicit: ^T -> float) and default ^T: int /// Converts the argument to signed native integer. This is a direct conversion for all @@ -4751,6 +4776,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline nativeint: value: ^T -> nativeint when ^T: (static member op_Explicit: ^T -> nativeint) and default ^T: int /// Converts the argument to unsigned native integer using a direct conversion for all @@ -4770,6 +4796,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline unativeint: value: ^T -> unativeint when ^T: (static member op_Explicit: ^T -> unativeint) and default ^T: int /// Converts the argument to a string using ToString. @@ -4809,6 +4836,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline decimal: value: ^T -> decimal when ^T: (static member op_Explicit: ^T -> decimal) and default ^T: int /// Converts the argument to character. Numeric inputs are converted according to the UTF-16 @@ -4828,6 +4856,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline char: value: ^T -> char when ^T: (static member op_Explicit: ^T -> char) and default ^T: int /// An active pattern to match values of type @@ -5929,6 +5958,7 @@ namespace Microsoft.FSharp.Core /// /// /// + [] val inline (~-): value: ^T -> ^T when ^T: (static member (~-): ^T -> ^T) and default ^T: int /// Overloaded subtraction operator (checks for overflow) @@ -5976,6 +6006,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline byte: value: ^T -> byte when ^T: (static member op_Explicit: ^T -> byte) and default ^T: int /// Converts the argument to sbyte. This is a direct, checked conversion for all @@ -5990,6 +6021,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline sbyte: value: ^T -> sbyte when ^T: (static member op_Explicit: ^T -> sbyte) and default ^T: int /// Converts the argument to int16. This is a direct, checked conversion for all @@ -6004,6 +6036,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline int16: value: ^T -> int16 when ^T: (static member op_Explicit: ^T -> int16) and default ^T: int /// Converts the argument to uint16. This is a direct, checked conversion for all @@ -6018,6 +6051,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline uint16: value: ^T -> uint16 when ^T: (static member op_Explicit: ^T -> uint16) and default ^T: int /// Converts the argument to int. This is a direct, checked conversion for all @@ -6046,6 +6080,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline int32: value: ^T -> int32 when ^T: (static member op_Explicit: ^T -> int32) and default ^T: int /// Converts the argument to uint32. This is a direct, checked conversion for all @@ -6060,6 +6095,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline uint32: value: ^T -> uint32 when ^T: (static member op_Explicit: ^T -> uint32) and default ^T: int /// Converts the argument to int64. This is a direct, checked conversion for all @@ -6074,6 +6110,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline int64: value: ^T -> int64 when ^T: (static member op_Explicit: ^T -> int64) and default ^T: int /// Converts the argument to uint64. This is a direct, checked conversion for all @@ -6088,6 +6125,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline uint64: value: ^T -> uint64 when ^T: (static member op_Explicit: ^T -> uint64) and default ^T: int /// Converts the argument to . This is a direct, checked conversion for all @@ -6101,6 +6139,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline nativeint: value: ^T -> nativeint when ^T: (static member op_Explicit: ^T -> nativeint) and default ^T: int /// Converts the argument to unativeint. This is a direct, checked conversion for all @@ -6114,6 +6153,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline unativeint: value: ^T -> unativeint when ^T: (static member op_Explicit: ^T -> unativeint) and default ^T: int /// Converts the argument to char. Numeric inputs are converted using a checked @@ -6128,6 +6168,7 @@ namespace Microsoft.FSharp.Core /// /// [] + [] val inline char: value: ^T -> char when ^T: (static member op_Explicit: ^T -> char) and default ^T: int namespace Microsoft.FSharp.Control From 63252b8c76826b7be24221cb490bc1a25bc8791e Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 2 Jun 2026 16:14:37 +0200 Subject: [PATCH 4/7] Polish: fantomas, release notes, surface-area baselines for issue #19560 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- 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 ff1c9aae2dd..a6c1c0f37d3 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -68,6 +68,7 @@ * Reference assembly MVIDs are now deterministic across compiler invocations. Previously, `--refout` / `true` produced a different MVID every build because the implied signature hash used .NET's randomized `String.GetHashCode()`. ([Issue #19751](https://github.com/dotnet/fsharp/issues/19751), [PR #19801](https://github.com/dotnet/fsharp/pull/19801)) * Parser: recover on unfinished if and binary expressions ([PR #19724](https://github.com/dotnet/fsharp/pull/19724)) +* Enforce that compiler-semantic attributes (`NoDynamicInvocation`) present on a value in a `.fs` implementation file are also declared in the corresponding `.fsi` signature file. Previously such attributes were silently dropped because tooling skips implementations when a signature is present. ([Issue #19560](https://github.com/dotnet/fsharp/issues/19560)) ### Added From b89994935a12e55a9d86cac6acf7fff6e9a78613 Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 2 Jun 2026 16:53:50 +0200 Subject: [PATCH 5/7] Add PR link to release notes for #19560 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/release-notes/.FSharp.Compiler.Service/11.0.100.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a6c1c0f37d3..d9cb8c44533 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -68,7 +68,7 @@ * Reference assembly MVIDs are now deterministic across compiler invocations. Previously, `--refout` / `true` produced a different MVID every build because the implied signature hash used .NET's randomized `String.GetHashCode()`. ([Issue #19751](https://github.com/dotnet/fsharp/issues/19751), [PR #19801](https://github.com/dotnet/fsharp/pull/19801)) * Parser: recover on unfinished if and binary expressions ([PR #19724](https://github.com/dotnet/fsharp/pull/19724)) -* Enforce that compiler-semantic attributes (`NoDynamicInvocation`) present on a value in a `.fs` implementation file are also declared in the corresponding `.fsi` signature file. Previously such attributes were silently dropped because tooling skips implementations when a signature is present. ([Issue #19560](https://github.com/dotnet/fsharp/issues/19560)) +* Enforce that compiler-semantic attributes (`NoDynamicInvocation`) present on a value in a `.fs` implementation file are also declared in the corresponding `.fsi` signature file. Previously such attributes were silently dropped because tooling skips implementations when a signature is present. ([Issue #19560](https://github.com/dotnet/fsharp/issues/19560), [PR #19880](https://github.com/dotnet/fsharp/pull/19880)) ### Added From 2efd19839193b62330f393f7ed8876b72beae353 Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 2 Jun 2026 18:30:04 +0200 Subject: [PATCH 6/7] Fix FSComp.txt error-code sort order for 3888 (issue #19560) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Compiler/FSComp.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 79c64488b9f..86e4422c96f 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1705,7 +1705,6 @@ reprResumableCodeDefinitionWasGeneric,"A delegate or function producing resumabl reprStateMachineInvalidForm,"The state machine has an unexpected form" 3517,optFailedToInlineSuggestedValue,"The value '%s' was marked 'InlineIfLambda' but was not determined to have a lambda value. This warning is for informational purposes only." 3518,implMissingInlineIfLambda,"The 'InlineIfLambda' attribute is present in the signature but not the implementation." -3888,implAttributeMissingFromSignature,"The attribute '%s' is present on '%s' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present." 3519,tcInlineIfLambdaUsedOnNonInlineFunctionOrMethod,"The 'InlineIfLambda' attribute may only be used on parameters of inlined functions of methods whose type is a function or F# delegate type." 3520,invalidXmlDocPosition,"XML comment is not placed on a valid language element." 3521,tcInvalidMemberDeclNameMissingOrHasParen,"Invalid member declaration. The name of the member is missing or has parentheses." @@ -1819,4 +1818,5 @@ featurePreprocessorElif,"#elif preprocessor directive" 3885,parsLetBangCannotBeLastInCE,"'%s' cannot be the final expression in a computation expression. Finish with 'return', 'return!', or a simple expression." 3886,tcListLiteralWithSingleTupleElement,"This list expression contains a single tuple element. Did you mean to use ';' instead of ',' to separate list elements?" 3887,ilCustomAttrInvalidArrayElemType,"The type '%s' is not a valid custom attribute argument type. Custom attribute arrays must have elements of primitive types, enums, string, System.Type, or System.Object." +3888,implAttributeMissingFromSignature,"The attribute '%s' is present on '%s' in the implementation but not in the signature. Add the attribute to the signature, because tooling skips the implementation when a signature file is present." featureExceptionFieldSerializationSupport,"emit GetObjectData and field-restoring deserialization constructor for exception types" From bf5c732746f07cdf09404e1a52517d9a5c506611 Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 2 Jun 2026 18:30:05 +0200 Subject: [PATCH 7/7] Add FSharp.Core release notes for #19560 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- docs/release-notes/.FSharp.Core/11.0.100.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Core/11.0.100.md b/docs/release-notes/.FSharp.Core/11.0.100.md index 7d0385e3b89..22f013ae729 100644 --- a/docs/release-notes/.FSharp.Core/11.0.100.md +++ b/docs/release-notes/.FSharp.Core/11.0.100.md @@ -3,3 +3,4 @@ * Fix `Array.exists2` documentation examples to use equal-length arrays; the previous examples would throw `ArgumentException` at runtime instead of returning the documented `false`/`true` values. ([PR #19672](https://github.com/dotnet/fsharp/pull/19672)) * Move `Async.StartChild` to the "Starting Async Computations" docs category alongside `Async.StartChildAsTask`. ([Issue #19667](https://github.com/dotnet/fsharp/issues/19667)) * Add `InlineIfLambda` to `Array.init` ([PR #19869](https://github.com/dotnet/fsharp/pull/19869)) +* Mirror `[]` from FSharp.Core implementation files into the matching `.fsi` signature files (in `nativeptr.fsi` and `prim-types.fsi`) so the attribute reaches consumers and tooling. Required by the new signature-enforced-attributes check. ([Issue #19560](https://github.com/dotnet/fsharp/issues/19560), [PR #19880](https://github.com/dotnet/fsharp/pull/19880))