From 7a47c78dcbcc3a1858aeeb4d7e26686855b23587 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Thu, 11 Sep 2025 17:56:06 +0300 Subject: [PATCH 1/8] wip --- src/Compiler/Checking/NicePrint.fs | 22 ++++++++++------- src/Compiler/TypedTree/TypedTreeOps.fs | 1 + src/Compiler/TypedTree/TypedTreeOps.fsi | 5 ++++ .../TooltipTests.fs | 24 ++++++++++++++++++- 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index 00b6f4c0b55..d2aca827887 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -124,6 +124,9 @@ module internal PrintUtilities = |> fun reversedArgs -> (true, retTyL) :: reversedArgs |> List.fold (fun acc (shouldBreak, layout) -> (if shouldBreak then (---) else (++)) layout acc) emptyL + let getSuperTypeDenv (denv: DisplayEnv) = + denv.UseGenericParameterStyle(PrefixForTopLevel(denv.genericParameterStyle)) + let tagNavArbValRef (valRefOpt: ValRef option) tag = match valRefOpt with | Some vref -> @@ -169,9 +172,10 @@ module internal PrintUtilities = let usePrefix (denv: DisplayEnv) (tcref: TyconRef) = match denv.genericParameterStyle with - | GenericParameterStyle.Implicit -> tcref.IsPrefixDisplay - | GenericParameterStyle.Prefix -> true - | GenericParameterStyle.Suffix -> false + | GenericParameterStyle.Implicit -> tcref.IsPrefixDisplay, denv + | GenericParameterStyle.Prefix -> true, denv + | GenericParameterStyle.Suffix -> false, denv + | GenericParameterStyle.PrefixForTopLevel nested -> true, denv.UseGenericParameterStyle(nested) /// /// Creates a layout for TyconRef. @@ -187,7 +191,7 @@ module internal PrintUtilities = /// let layoutTyconRefImpl isAttribute (denv: DisplayEnv) (tcref: TyconRef) (demangledPath: string list option) = - let prefix = usePrefix denv tcref + let prefix, denv = usePrefix denv tcref let isArray = not prefix && isArrayTyconRef denv.g tcref let demangled = if isArray then @@ -746,7 +750,7 @@ module PrintTypes = let tyLayout = match typarConstraintTy with | TType_app (tyconRef = tc; typeInstantiation = ti) - when ti.Length > 0 && not (usePrefix denv tc) -> + when ti.Length > 0 && not (usePrefix denv tc |> fst) -> layoutTypeWithInfo denv env typarConstraintTy |> bracketL | _ -> layoutTypeWithInfo denv env typarConstraintTy @@ -975,10 +979,10 @@ module PrintTypes = // Layout a type application | TType_ucase (UnionCaseRef(tc, _), args) -> - let prefix = usePrefix denv tc + let prefix, denv = usePrefix denv tc layoutTypeAppWithInfoAndPrec denv env (layoutTyconRefImpl false denv tc None) prec prefix args | TType_app (tc, args, nullness) -> - let prefix = usePrefix denv tc + let prefix, denv = usePrefix denv tc let demangledCompilationPathOpt, args = if not denv.includeStaticParametersInTypeNames then None, args @@ -2047,6 +2051,7 @@ module TastDefinitionPrinting = GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m ty let iimplsLs = + let denv = getSuperTypeDenv denv iimpls |> List.map (fun intfTy -> (if isInterfaceTy g ty then WordL.keywordInherit else WordL.keywordInterface) -* layoutType denv intfTy) @@ -2181,7 +2186,8 @@ module TastDefinitionPrinting = | _ -> () ] - let inheritsL = + let inheritsL = + let denv = getSuperTypeDenv denv inherits |> List.map (fun super -> WordL.keywordInherit ^^ (layoutType denv super)) diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index 368dd9a99ce..3d4aee1e2b2 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -3171,6 +3171,7 @@ type GenericParameterStyle = | Implicit | Prefix | Suffix + | PrefixForTopLevel of nested: GenericParameterStyle [] type DisplayEnv = diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi index 06200be47f7..c0e2a7848bb 100755 --- a/src/Compiler/TypedTree/TypedTreeOps.fsi +++ b/src/Compiler/TypedTree/TypedTreeOps.fsi @@ -1061,6 +1061,11 @@ type GenericParameterStyle = | Prefix /// Force the suffix style: int List | Suffix + /// Force the prefix style for top-level types in interface/inherit declarations: + /// inherit seq + /// instead of + /// inherit int list seq + | PrefixForTopLevel of nested: GenericParameterStyle [] type DisplayEnv = diff --git a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs index 92d30a3e4cd..fe4806ddd3a 100644 --- a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs @@ -535,4 +535,26 @@ open System let doIt(myAction : Action) = myAc{caret}tion.Invoke(42) """ |> assertAndGetSingleToolTipText - |> Assert.shouldBeEquivalentTo ("""val myAction: Action""" |> normalize) \ No newline at end of file + |> Assert.shouldBeEquivalentTo ("""val myAction: Action""" |> normalize) + +[] +let ``Super type should be formatted in the prefix style`` () = + Checker.getTooltip """ +namespace Foo + +type A{caret} = + inherit seq +""" + |> assertAndGetSingleToolTipText + |> Assert.shouldBeEquivalentTo "type A =\n inherit seq" + +[] +let ``Interface impl should be formatted in the prefix style`` () = + Checker.getTooltip """ +namespace Foo + +type A{caret} = + interface seq with +""" + |> assertAndGetSingleToolTipText + |> Assert.shouldBeEquivalentTo "type A =\n interface seq" From 8e4200e42464e43066a4d52143a806463f1dc943 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Thu, 11 Sep 2025 22:22:33 +0300 Subject: [PATCH 2/8] release notes --- docs/release-notes/.FSharp.Compiler.Service/10.0.100.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md index 06b39cc019d..a707b87e14f 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md @@ -24,6 +24,7 @@ * Fix Show XML doc for enum fields in external metadata ([Issue #17939](https://github.com/dotnet/fsharp/issues/17939#issuecomment-3137410105), [PR #18800](https://github.com/dotnet/fsharp/pull/18800)) * Fix nullable types formatting in `FSharpType.Format` and tooltips to include parentheses. ([PR #18842](https://github.com/dotnet/fsharp/pull/18842)) * TypeMismatchDiagnosticExtendedData: fix expected and actual types calculation. ([Issue ](https://github.com/dotnet/fsharp/pull/18851)) +* Nice print: format generic types in inherit/interface declarations using a prefix style. ([PR #18897](https://github.com/dotnet/fsharp/pull/18897)) ### Changed * Use `errorR` instead of `error` in `CheckDeclarations.fs` when possible. ([PR #18645](https://github.com/dotnet/fsharp/pull/18645)) From 968bf9fcb3211c1025c51e79ec0c049d35d7e4f4 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Thu, 11 Sep 2025 22:55:06 +0300 Subject: [PATCH 3/8] ilverify --- .../ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl | 2 +- .../ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl index 6a676b52c7a..42cf5fbfe1d 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl @@ -60,7 +60,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000634][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000065][found Byte] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x00000015][found Boolean] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2078-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000BE][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2083-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000BE][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+PrintUtilities::layoutXmlDoc([FSharp.Compiler.Service]FSharp.Compiler.TypedTreeOps+DisplayEnv, bool, [FSharp.Compiler.Service]FSharp.Compiler.Xml.XmlDoc, [FSharp.Compiler.Service]FSharp.Compiler.Text.Layout)][offset 0x00000033][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateNamespaceName(string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string)][offset 0x00000063][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateExpectedName([FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string[], string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1)][offset 0x000000AD][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl index 3a9313580a0..fc0562112ea 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl @@ -65,7 +65,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.IlxGen::HashRangeSorted([S.P.CoreLib]System.Collections.Generic.IDictionary`2>)][offset 0x00000012][found ref '[FSharp.Compiler.Service]FSharp.Compiler.IlxGen+HashRangeSorted@1875'][expected ref '[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,T0>'] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000040][found Byte] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x0000000B][found Boolean] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2078-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000B3][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2083-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000B3][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+PrintUtilities::layoutXmlDoc([FSharp.Compiler.Service]FSharp.Compiler.TypedTreeOps+DisplayEnv, bool, [FSharp.Compiler.Service]FSharp.Compiler.Xml.XmlDoc, [FSharp.Compiler.Service]FSharp.Compiler.Text.Layout)][offset 0x00000034][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateNamespaceName(string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string)][offset 0x00000074][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateExpectedName([FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string[], string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1)][offset 0x000000A8][found Char] Unexpected type on the stack. From b669abb975241ad246902353db45f37b17b3e075 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Mon, 15 Sep 2025 20:00:30 +0300 Subject: [PATCH 4/8] wip --- src/Compiler/Checking/NicePrint.fs | 17 ++++------- src/Compiler/Symbols/Symbols.fs | 3 ++ src/Compiler/Symbols/Symbols.fsi | 5 ++++ src/Compiler/TypedTree/TypedTreeOps.fs | 10 ++++++- src/Compiler/TypedTree/TypedTreeOps.fsi | 4 ++- .../FSharp.Compiler.Service.Tests/Symbols.fs | 28 +++++++++++++++++++ .../TooltipTests.fs | 10 +++++++ ....Compiler.Service_Debug_netstandard2.0.bsl | 4 +-- ...ompiler.Service_Release_netstandard2.0.bsl | 4 +-- 9 files changed, 67 insertions(+), 18 deletions(-) diff --git a/src/Compiler/Checking/NicePrint.fs b/src/Compiler/Checking/NicePrint.fs index d2aca827887..94a239da048 100644 --- a/src/Compiler/Checking/NicePrint.fs +++ b/src/Compiler/Checking/NicePrint.fs @@ -124,9 +124,6 @@ module internal PrintUtilities = |> fun reversedArgs -> (true, retTyL) :: reversedArgs |> List.fold (fun acc (shouldBreak, layout) -> (if shouldBreak then (---) else (++)) layout acc) emptyL - let getSuperTypeDenv (denv: DisplayEnv) = - denv.UseGenericParameterStyle(PrefixForTopLevel(denv.genericParameterStyle)) - let tagNavArbValRef (valRefOpt: ValRef option) tag = match valRefOpt with | Some vref -> @@ -175,7 +172,7 @@ module internal PrintUtilities = | GenericParameterStyle.Implicit -> tcref.IsPrefixDisplay, denv | GenericParameterStyle.Prefix -> true, denv | GenericParameterStyle.Suffix -> false, denv - | GenericParameterStyle.PrefixForTopLevel nested -> true, denv.UseGenericParameterStyle(nested) + | GenericParameterStyle.TopLevelPrefix nested -> true, denv.UseGenericParameterStyle(nested) /// /// Creates a layout for TyconRef. @@ -748,12 +745,8 @@ module PrintTypes = | Some typarConstraintTy -> if Zset.contains typar env.singletons then let tyLayout = - match typarConstraintTy with - | TType_app (tyconRef = tc; typeInstantiation = ti) - when ti.Length > 0 && not (usePrefix denv tc |> fst) -> - layoutTypeWithInfo denv env typarConstraintTy - |> bracketL - | _ -> layoutTypeWithInfo denv env typarConstraintTy + let denv = denv.UseTopLevelPrefixGenericParameterStyle() + layoutTypeWithInfo denv env typarConstraintTy leftL (tagPunctuation "#") ^^ tyLayout else @@ -2051,7 +2044,7 @@ module TastDefinitionPrinting = GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m ty let iimplsLs = - let denv = getSuperTypeDenv denv + let denv = denv.UseTopLevelPrefixGenericParameterStyle() iimpls |> List.map (fun intfTy -> (if isInterfaceTy g ty then WordL.keywordInherit else WordL.keywordInterface) -* layoutType denv intfTy) @@ -2187,7 +2180,7 @@ module TastDefinitionPrinting = ] let inheritsL = - let denv = getSuperTypeDenv denv + let denv = denv.UseTopLevelPrefixGenericParameterStyle() inherits |> List.map (fun super -> WordL.keywordInherit ^^ (layoutType denv super)) diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs index fb413eccea7..28045551725 100644 --- a/src/Compiler/Symbols/Symbols.fs +++ b/src/Compiler/Symbols/Symbols.fs @@ -216,6 +216,9 @@ type FSharpDisplayContext(denv: TcGlobals -> DisplayEnv) = member _.WithSuffixGenericParameters () = FSharpDisplayContext(fun g -> { denv g with genericParameterStyle = GenericParameterStyle.Suffix } ) + member x.WithTopLevelPrefixGenericParameters () = + FSharpDisplayContext(fun g -> (denv g).UseTopLevelPrefixGenericParameterStyle()) + // delay the realization of 'item' in case it is unresolved type FSharpSymbol(cenv: SymbolEnv, item: unit -> Item, access: FSharpSymbol -> CcuThunk -> AccessorDomain -> bool) = diff --git a/src/Compiler/Symbols/Symbols.fsi b/src/Compiler/Symbols/Symbols.fsi index 701e9a8fe3c..0fec9922171 100644 --- a/src/Compiler/Symbols/Symbols.fsi +++ b/src/Compiler/Symbols/Symbols.fsi @@ -74,6 +74,11 @@ type FSharpDisplayContext = /// for example `int list` member WithSuffixGenericParameters: unit -> FSharpDisplayContext + /// Causes type signatures to be formatted with prefix-style generic parameters for a top level type + /// while nested types inherit generic parameters style from the current `FSharpDisplayContext` instance, + /// for example, `int list seq` becomes `seq` + member WithTopLevelPrefixGenericParameters: unit -> FSharpDisplayContext + /// Represents a symbol in checked F# source code or a compiled .NET component. /// /// The subtype of the symbol may reveal further information and can be one of FSharpEntity, FSharpUnionCase diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index 3d4aee1e2b2..3c5d2dcd20b 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -3171,7 +3171,7 @@ type GenericParameterStyle = | Implicit | Prefix | Suffix - | PrefixForTopLevel of nested: GenericParameterStyle + | TopLevelPrefix of nested: GenericParameterStyle [] type DisplayEnv = @@ -3256,6 +3256,14 @@ type DisplayEnv = member denv.UseGenericParameterStyle style = { denv with genericParameterStyle = style } + + member denv.UseTopLevelPrefixGenericParameterStyle() = + let nestedStyle = + match denv.genericParameterStyle with + | TopLevelPrefix(nested) -> nested + | style -> style + + { denv with genericParameterStyle = TopLevelPrefix(nestedStyle) } static member InitialForSigFileGeneration g = let denv = diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi index c0e2a7848bb..128ae33dddd 100755 --- a/src/Compiler/TypedTree/TypedTreeOps.fsi +++ b/src/Compiler/TypedTree/TypedTreeOps.fsi @@ -1065,7 +1065,7 @@ type GenericParameterStyle = /// inherit seq /// instead of /// inherit int list seq - | PrefixForTopLevel of nested: GenericParameterStyle + | TopLevelPrefix of nested: GenericParameterStyle [] type DisplayEnv = @@ -1116,6 +1116,8 @@ type DisplayEnv = member UseGenericParameterStyle: GenericParameterStyle -> DisplayEnv + member UseTopLevelPrefixGenericParameterStyle: unit -> DisplayEnv + static member InitialForSigFileGeneration: TcGlobals -> DisplayEnv val tagEntityRefName: xref: EntityRef -> name: string -> TaggedText diff --git a/tests/FSharp.Compiler.Service.Tests/Symbols.fs b/tests/FSharp.Compiler.Service.Tests/Symbols.fs index b5126bf1ca6..f27033ee4d2 100644 --- a/tests/FSharp.Compiler.Service.Tests/Symbols.fs +++ b/tests/FSharp.Compiler.Service.Tests/Symbols.fs @@ -449,6 +449,34 @@ let tester2: int Group = [] | other -> failwithf "myArr was supposed to be a value, but is %A" other + [] + let ``FSharpType.Format with top-level prefix generic parameters style`` () = + let _, checkResults = getParseAndCheckResults """ +let f (x: int list seq) = () +""" + let symbolUse = findSymbolUseByName "x" checkResults + let symbol = symbolUse.Symbol :?> FSharpMemberOrFunctionOrValue + let typeArg = symbol.FullType + let displayContext = symbolUse.DisplayContext + + let topLevelPrefixStyle = + displayContext.WithTopLevelPrefixGenericParameters() + + let topLevelPrefixWithNestedSuffixStyle1 = + displayContext.WithPrefixGenericParameters().WithTopLevelPrefixGenericParameters() + + // Idempotent + let topLevelPrefixWithNestedSuffixStyle2 = + topLevelPrefixWithNestedSuffixStyle1.WithTopLevelPrefixGenericParameters() + + [ typeArg.Format(topLevelPrefixStyle) + typeArg.Format(topLevelPrefixWithNestedSuffixStyle1) + typeArg.Format(topLevelPrefixWithNestedSuffixStyle2) ] + |> shouldBe [ + "seq" + "seq>" + "seq>" ] + [] let ``Unfinished long ident type `` () = let _, checkResults = getParseAndCheckResults """ diff --git a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs index fe4806ddd3a..517e4a8b59d 100644 --- a/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs +++ b/tests/FSharp.Compiler.Service.Tests/TooltipTests.fs @@ -558,3 +558,13 @@ type A{caret} = """ |> assertAndGetSingleToolTipText |> Assert.shouldBeEquivalentTo "type A =\n interface seq" + +[] +let ``Flexible generic type should be formatted in the prefix style`` () = + Checker.getTooltip """ +module Foo + +let f (x{caret}: #seq) = () +""" + |> assertAndGetSingleToolTipText + |> Assert.shouldBeEquivalentTo "val x: #seq" diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl index 42cf5fbfe1d..3eefca84aee 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl @@ -40,7 +40,7 @@ [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@924-516::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@924-516::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@924-516::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$Symbols+fullName@2498-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000015][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$Symbols+fullName@2501-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000015][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CreateILModule+MainModuleBuilder::ConvertProductVersionToILVersionInfo(string)][offset 0x00000011][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::getCompilerOption([FSharp.Compiler.Service]FSharp.Compiler.CompilerOptions+CompilerOption, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1)][offset 0x000000E6][found Char] Unexpected type on the stack. @@ -60,7 +60,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerConfig+TcConfig::.ctor([FSharp.Compiler.Service]FSharp.Compiler.CompilerConfig+TcConfigBuilder, bool)][offset 0x00000634][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000065][found Byte] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x00000015][found Boolean] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2083-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000BE][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2076-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000BE][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+PrintUtilities::layoutXmlDoc([FSharp.Compiler.Service]FSharp.Compiler.TypedTreeOps+DisplayEnv, bool, [FSharp.Compiler.Service]FSharp.Compiler.Xml.XmlDoc, [FSharp.Compiler.Service]FSharp.Compiler.Text.Layout)][offset 0x00000033][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateNamespaceName(string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string)][offset 0x00000063][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateExpectedName([FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string[], string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1)][offset 0x000000AD][found Char] Unexpected type on the stack. diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl index fc0562112ea..bbf9187b1a7 100644 --- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl +++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl @@ -39,7 +39,7 @@ [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@924-531::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@924-531::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@924-531::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : .$Symbols+fullName@2498-3::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000030][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : .$Symbols+fullName@2501-3::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000030][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@286-1::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@286-1::Invoke(string)][offset 0x00000014][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.CreateILModule+MainModuleBuilder::ConvertProductVersionToILVersionInfo(string)][offset 0x00000010][found Char] Unexpected type on the stack. @@ -65,7 +65,7 @@ [IL]: Error [StackUnexpected]: : FSharp.Compiler.IlxGen::HashRangeSorted([S.P.CoreLib]System.Collections.Generic.IDictionary`2>)][offset 0x00000012][found ref '[FSharp.Compiler.Service]FSharp.Compiler.IlxGen+HashRangeSorted@1875'][expected ref '[FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,T0>'] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.PatternMatchCompilation::isProblematicClause([FSharp.Compiler.Service]FSharp.Compiler.PatternMatchCompilation+MatchClause)][offset 0x00000040][found Byte] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : .$FSharp.Compiler.PatternMatchCompilation::.cctor()][offset 0x0000000B][found Boolean] Unexpected type on the stack. -[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2083-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000B3][found Char] Unexpected type on the stack. +[IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+TastDefinitionPrinting+meths@2076-3::Invoke([FSharp.Compiler.Service]FSharp.Compiler.Infos+MethInfo)][offset 0x000000B3][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.NicePrint+PrintUtilities::layoutXmlDoc([FSharp.Compiler.Service]FSharp.Compiler.TypedTreeOps+DisplayEnv, bool, [FSharp.Compiler.Service]FSharp.Compiler.Xml.XmlDoc, [FSharp.Compiler.Service]FSharp.Compiler.Text.Layout)][offset 0x00000034][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateNamespaceName(string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1, [FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string)][offset 0x00000074][found Char] Unexpected type on the stack. [IL]: Error [StackUnexpected]: : FSharp.Compiler.TypeProviders::ValidateExpectedName([FSharp.Compiler.Service]FSharp.Compiler.Text.Range, string[], string, [FSharp.Compiler.Service]FSharp.Compiler.Tainted`1)][offset 0x000000A8][found Char] Unexpected type on the stack. From 0d489b9ea1f0ac29b67fbc518b6a67a19f138cae Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Mon, 15 Sep 2025 20:09:36 +0300 Subject: [PATCH 5/8] fix --- src/Compiler/TypedTree/TypedTreeOps.fsi | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi index 128ae33dddd..ed847cc5839 100755 --- a/src/Compiler/TypedTree/TypedTreeOps.fsi +++ b/src/Compiler/TypedTree/TypedTreeOps.fsi @@ -1061,10 +1061,8 @@ type GenericParameterStyle = | Prefix /// Force the suffix style: int List | Suffix - /// Force the prefix style for top-level types in interface/inherit declarations: - /// inherit seq - /// instead of - /// inherit int list seq + /// Force the prefix style for a top-level type, + /// for example, `seq` instead of `int list seq` | TopLevelPrefix of nested: GenericParameterStyle [] From 46b330d93b1611fa84eb2c7d54f6243113cbfabb Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Mon, 15 Sep 2025 20:57:30 +0300 Subject: [PATCH 6/8] surface area --- .../FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl index 31ecae647c8..cf2c03ce7df 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl @@ -5164,6 +5164,7 @@ FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisp FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithPrefixGenericParameters() FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithShortTypeNames(Boolean) FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithSuffixGenericParameters() +FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithTopLevelPrefixGenericParameters() FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext get_Empty() FSharp.Compiler.Symbols.FSharpEntity: Boolean Equals(System.Object) FSharp.Compiler.Symbols.FSharpEntity: Boolean HasAssemblyCodeRepresentation From 074938645bff029b2eb742d82c25b67cf33d2aaf Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Mon, 15 Sep 2025 22:10:10 +0300 Subject: [PATCH 7/8] update release notes --- docs/release-notes/.FSharp.Compiler.Service/10.0.100.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md index a707b87e14f..638ccefdb23 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/10.0.100.md @@ -4,6 +4,7 @@ * Add support for tail calls in computation expressions ([PR #18804](https://github.com/dotnet/fsharp/pull/18804)) * Add `--typecheck-only` flag support for F# Interactive (FSI) scripts to type-check without execution. ([Issue #18686](https://github.com/dotnet/fsharp/issues/18686)) * Diagnostics: add extended data for 'No constructors' error ([PR #18863](https://github.com/dotnet/fsharp/pull/18863)) +* FSharpType.Format: support top-level prefix generic types style. ([PR #18897](https://github.com/dotnet/fsharp/pull/18897)) ### Fixed @@ -24,7 +25,7 @@ * Fix Show XML doc for enum fields in external metadata ([Issue #17939](https://github.com/dotnet/fsharp/issues/17939#issuecomment-3137410105), [PR #18800](https://github.com/dotnet/fsharp/pull/18800)) * Fix nullable types formatting in `FSharpType.Format` and tooltips to include parentheses. ([PR #18842](https://github.com/dotnet/fsharp/pull/18842)) * TypeMismatchDiagnosticExtendedData: fix expected and actual types calculation. ([Issue ](https://github.com/dotnet/fsharp/pull/18851)) -* Nice print: format generic types in inherit/interface declarations using a prefix style. ([PR #18897](https://github.com/dotnet/fsharp/pull/18897)) +* Format top-level generic types using a prefix style in inherit/interface declarations and flexible type annotations. ([PR #18897](https://github.com/dotnet/fsharp/pull/18897)) ### Changed * Use `errorR` instead of `error` in `CheckDeclarations.fs` when possible. ([PR #18645](https://github.com/dotnet/fsharp/pull/18645)) From 0ed71838859c37fcc439b2889531cf90275a24bd Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Mon, 15 Sep 2025 23:08:53 +0300 Subject: [PATCH 8/8] fixes --- tests/FSharp.Compiler.Service.Tests/Symbols.fs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/Symbols.fs b/tests/FSharp.Compiler.Service.Tests/Symbols.fs index f27033ee4d2..dc39cc6f7f7 100644 --- a/tests/FSharp.Compiler.Service.Tests/Symbols.fs +++ b/tests/FSharp.Compiler.Service.Tests/Symbols.fs @@ -462,16 +462,16 @@ let f (x: int list seq) = () let topLevelPrefixStyle = displayContext.WithTopLevelPrefixGenericParameters() - let topLevelPrefixWithNestedSuffixStyle1 = + let topLevelPrefixWithNestedPrefixStyle1 = displayContext.WithPrefixGenericParameters().WithTopLevelPrefixGenericParameters() - // Idempotent - let topLevelPrefixWithNestedSuffixStyle2 = - topLevelPrefixWithNestedSuffixStyle1.WithTopLevelPrefixGenericParameters() + // Should be idempotent + let topLevelPrefixWithNestedPrefixStyle2 = + topLevelPrefixWithNestedPrefixStyle1.WithTopLevelPrefixGenericParameters() [ typeArg.Format(topLevelPrefixStyle) - typeArg.Format(topLevelPrefixWithNestedSuffixStyle1) - typeArg.Format(topLevelPrefixWithNestedSuffixStyle2) ] + typeArg.Format(topLevelPrefixWithNestedPrefixStyle1) + typeArg.Format(topLevelPrefixWithNestedPrefixStyle2) ] |> shouldBe [ "seq" "seq>"