Skip to content

Commit 14a7822

Browse files
authored
Merge branch 'main' into cache-2
2 parents d3dbcd1 + 24b393c commit 14a7822

File tree

17 files changed

+346
-292
lines changed

17 files changed

+346
-292
lines changed

docs/release-notes/.FSharp.Compiler.Service/10.0.100.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Add support for tail calls in computation expressions ([PR #18804](https://github.com/dotnet/fsharp/pull/18804))
55
* Add `--typecheck-only` flag support for F# Interactive (FSI) scripts to type-check without execution. ([Issue #18686](https://github.com/dotnet/fsharp/issues/18686))
66
* Diagnostics: add extended data for 'No constructors' error ([PR #18863](https://github.com/dotnet/fsharp/pull/18863))
7+
* FSharpType.Format: support top-level prefix generic types style. ([PR #18897](https://github.com/dotnet/fsharp/pull/18897))
78
* FCS: allow getting captured types ([PR $18878](https://github.com/dotnet/fsharp/pull/18878))
89

910
### Fixed
@@ -25,6 +26,7 @@
2526
* 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))
2627
* Fix nullable types formatting in `FSharpType.Format` and tooltips to include parentheses. ([PR #18842](https://github.com/dotnet/fsharp/pull/18842))
2728
* TypeMismatchDiagnosticExtendedData: fix expected and actual types calculation. ([Issue ](https://github.com/dotnet/fsharp/pull/18851))
29+
* 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))
2830
* Parser: fix range for computed binding expressions ([PR #18903](https://github.com/dotnet/fsharp/pull/18903))
2931

3032
### Changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
### Fixed
2+
* Split package init into foreground+background, fix background analysis setting ([Issue #18623](https://github.com/dotnet/fsharp/issues/18623), [Issue #18904](https://github.com/dotnet/fsharp/issues/18904), [PR #18646](https://github.com/dotnet/fsharp/pull/18646))
3+
4+
### Added
5+
6+
### Changed
7+
8+
### Breaking Changes

src/Compiler/Checking/NicePrint.fs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,10 @@ module internal PrintUtilities =
169169

170170
let usePrefix (denv: DisplayEnv) (tcref: TyconRef) =
171171
match denv.genericParameterStyle with
172-
| GenericParameterStyle.Implicit -> tcref.IsPrefixDisplay
173-
| GenericParameterStyle.Prefix -> true
174-
| GenericParameterStyle.Suffix -> false
172+
| GenericParameterStyle.Implicit -> tcref.IsPrefixDisplay, denv
173+
| GenericParameterStyle.Prefix -> true, denv
174+
| GenericParameterStyle.Suffix -> false, denv
175+
| GenericParameterStyle.TopLevelPrefix nested -> true, denv.UseGenericParameterStyle(nested)
175176

176177
/// <summary>
177178
/// Creates a layout for TyconRef.
@@ -187,7 +188,7 @@ module internal PrintUtilities =
187188
/// </param>
188189
let layoutTyconRefImpl isAttribute (denv: DisplayEnv) (tcref: TyconRef) (demangledPath: string list option) =
189190

190-
let prefix = usePrefix denv tcref
191+
let prefix, denv = usePrefix denv tcref
191192
let isArray = not prefix && isArrayTyconRef denv.g tcref
192193
let demangled =
193194
if isArray then
@@ -744,12 +745,8 @@ module PrintTypes =
744745
| Some typarConstraintTy ->
745746
if Zset.contains typar env.singletons then
746747
let tyLayout =
747-
match typarConstraintTy with
748-
| TType_app (tyconRef = tc; typeInstantiation = ti)
749-
when ti.Length > 0 && not (usePrefix denv tc) ->
750-
layoutTypeWithInfo denv env typarConstraintTy
751-
|> bracketL
752-
| _ -> layoutTypeWithInfo denv env typarConstraintTy
748+
let denv = denv.UseTopLevelPrefixGenericParameterStyle()
749+
layoutTypeWithInfo denv env typarConstraintTy
753750

754751
leftL (tagPunctuation "#") ^^ tyLayout
755752
else
@@ -975,10 +972,10 @@ module PrintTypes =
975972

976973
// Layout a type application
977974
| TType_ucase (UnionCaseRef(tc, _), args) ->
978-
let prefix = usePrefix denv tc
975+
let prefix, denv = usePrefix denv tc
979976
layoutTypeAppWithInfoAndPrec denv env (layoutTyconRefImpl false denv tc None) prec prefix args
980977
| TType_app (tc, args, nullness) ->
981-
let prefix = usePrefix denv tc
978+
let prefix, denv = usePrefix denv tc
982979
let demangledCompilationPathOpt, args =
983980
if not denv.includeStaticParametersInTypeNames then
984981
None, args
@@ -2047,6 +2044,7 @@ module TastDefinitionPrinting =
20472044
GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m ty
20482045

20492046
let iimplsLs =
2047+
let denv = denv.UseTopLevelPrefixGenericParameterStyle()
20502048
iimpls
20512049
|> List.map (fun intfTy -> (if isInterfaceTy g ty then WordL.keywordInherit else WordL.keywordInterface) -* layoutType denv intfTy)
20522050

@@ -2181,7 +2179,8 @@ module TastDefinitionPrinting =
21812179
| _ -> ()
21822180
]
21832181

2184-
let inheritsL =
2182+
let inheritsL =
2183+
let denv = denv.UseTopLevelPrefixGenericParameterStyle()
21852184
inherits
21862185
|> List.map (fun super -> WordL.keywordInherit ^^ (layoutType denv super))
21872186

src/Compiler/Symbols/Symbols.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ type FSharpDisplayContext(denv: TcGlobals -> DisplayEnv) =
216216
member _.WithSuffixGenericParameters () =
217217
FSharpDisplayContext(fun g -> { denv g with genericParameterStyle = GenericParameterStyle.Suffix } )
218218

219+
member x.WithTopLevelPrefixGenericParameters () =
220+
FSharpDisplayContext(fun g -> (denv g).UseTopLevelPrefixGenericParameterStyle())
221+
219222
// delay the realization of 'item' in case it is unresolved
220223
type FSharpSymbol(cenv: SymbolEnv, item: unit -> Item, access: FSharpSymbol -> CcuThunk -> AccessorDomain -> bool) =
221224

src/Compiler/Symbols/Symbols.fsi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ type FSharpDisplayContext =
7474
/// for example `int list`
7575
member WithSuffixGenericParameters: unit -> FSharpDisplayContext
7676

77+
/// Causes type signatures to be formatted with prefix-style generic parameters for a top level type
78+
/// while nested types inherit generic parameters style from the current `FSharpDisplayContext` instance,
79+
/// for example, `int list seq` becomes `seq<int list>`
80+
member WithTopLevelPrefixGenericParameters: unit -> FSharpDisplayContext
81+
7782
/// Represents a symbol in checked F# source code or a compiled .NET component.
7883
///
7984
/// The subtype of the symbol may reveal further information and can be one of FSharpEntity, FSharpUnionCase

src/Compiler/TypedTree/TypedTreeOps.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3171,6 +3171,7 @@ type GenericParameterStyle =
31713171
| Implicit
31723172
| Prefix
31733173
| Suffix
3174+
| TopLevelPrefix of nested: GenericParameterStyle
31743175

31753176
[<NoEquality; NoComparison>]
31763177
type DisplayEnv =
@@ -3255,6 +3256,14 @@ type DisplayEnv =
32553256

32563257
member denv.UseGenericParameterStyle style =
32573258
{ denv with genericParameterStyle = style }
3259+
3260+
member denv.UseTopLevelPrefixGenericParameterStyle() =
3261+
let nestedStyle =
3262+
match denv.genericParameterStyle with
3263+
| TopLevelPrefix(nested) -> nested
3264+
| style -> style
3265+
3266+
{ denv with genericParameterStyle = TopLevelPrefix(nestedStyle) }
32583267

32593268
static member InitialForSigFileGeneration g =
32603269
let denv =

src/Compiler/TypedTree/TypedTreeOps.fsi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,9 @@ type GenericParameterStyle =
10611061
| Prefix
10621062
/// Force the suffix style: int List
10631063
| Suffix
1064+
/// Force the prefix style for a top-level type,
1065+
/// for example, `seq<int list>` instead of `int list seq`
1066+
| TopLevelPrefix of nested: GenericParameterStyle
10641067

10651068
[<NoEquality; NoComparison>]
10661069
type DisplayEnv =
@@ -1111,6 +1114,8 @@ type DisplayEnv =
11111114

11121115
member UseGenericParameterStyle: GenericParameterStyle -> DisplayEnv
11131116

1117+
member UseTopLevelPrefixGenericParameterStyle: unit -> DisplayEnv
1118+
11141119
static member InitialForSigFileGeneration: TcGlobals -> DisplayEnv
11151120

11161121
val tagEntityRefName: xref: EntityRef -> name: string -> TaggedText

tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.bsl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5166,6 +5166,7 @@ FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisp
51665166
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithPrefixGenericParameters()
51675167
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithShortTypeNames(Boolean)
51685168
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithSuffixGenericParameters()
5169+
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext WithTopLevelPrefixGenericParameters()
51695170
FSharp.Compiler.Symbols.FSharpDisplayContext: FSharp.Compiler.Symbols.FSharpDisplayContext get_Empty()
51705171
FSharp.Compiler.Symbols.FSharpEntity: Boolean Equals(System.Object)
51715172
FSharp.Compiler.Symbols.FSharpEntity: Boolean HasAssemblyCodeRepresentation

tests/FSharp.Compiler.Service.Tests/Symbols.fs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,34 @@ let tester2: int Group = []
449449

450450
| other -> failwithf "myArr was supposed to be a value, but is %A" other
451451

452+
[<Fact>]
453+
let ``FSharpType.Format with top-level prefix generic parameters style`` () =
454+
let _, checkResults = getParseAndCheckResults """
455+
let f (x: int list seq) = ()
456+
"""
457+
let symbolUse = findSymbolUseByName "x" checkResults
458+
let symbol = symbolUse.Symbol :?> FSharpMemberOrFunctionOrValue
459+
let typeArg = symbol.FullType
460+
let displayContext = symbolUse.DisplayContext
461+
462+
let topLevelPrefixStyle =
463+
displayContext.WithTopLevelPrefixGenericParameters()
464+
465+
let topLevelPrefixWithNestedPrefixStyle1 =
466+
displayContext.WithPrefixGenericParameters().WithTopLevelPrefixGenericParameters()
467+
468+
// Should be idempotent
469+
let topLevelPrefixWithNestedPrefixStyle2 =
470+
topLevelPrefixWithNestedPrefixStyle1.WithTopLevelPrefixGenericParameters()
471+
472+
[ typeArg.Format(topLevelPrefixStyle)
473+
typeArg.Format(topLevelPrefixWithNestedPrefixStyle1)
474+
typeArg.Format(topLevelPrefixWithNestedPrefixStyle2) ]
475+
|> shouldBe [
476+
"seq<int list>"
477+
"seq<list<int>>"
478+
"seq<list<int>>" ]
479+
452480
[<Fact>]
453481
let ``Unfinished long ident type `` () =
454482
let _, checkResults = getParseAndCheckResults """

tests/FSharp.Compiler.Service.Tests/TooltipTests.fs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,4 +535,36 @@ open System
535535
let doIt(myAction : Action<int>) = myAc{caret}tion.Invoke(42)
536536
"""
537537
|> assertAndGetSingleToolTipText
538-
|> Assert.shouldBeEquivalentTo ("""val myAction: Action<int>""" |> normalize)
538+
|> Assert.shouldBeEquivalentTo ("""val myAction: Action<int>""" |> normalize)
539+
540+
[<Fact>]
541+
let ``Super type should be formatted in the prefix style`` () =
542+
Checker.getTooltip """
543+
namespace Foo
544+
545+
type A{caret} =
546+
inherit seq<int list>
547+
"""
548+
|> assertAndGetSingleToolTipText
549+
|> Assert.shouldBeEquivalentTo "type A =\n inherit seq<int list>"
550+
551+
[<Fact>]
552+
let ``Interface impl should be formatted in the prefix style`` () =
553+
Checker.getTooltip """
554+
namespace Foo
555+
556+
type A{caret} =
557+
interface seq<int list> with
558+
"""
559+
|> assertAndGetSingleToolTipText
560+
|> Assert.shouldBeEquivalentTo "type A =\n interface seq<int list>"
561+
562+
[<Fact>]
563+
let ``Flexible generic type should be formatted in the prefix style`` () =
564+
Checker.getTooltip """
565+
module Foo
566+
567+
let f (x{caret}: #seq<int list>) = ()
568+
"""
569+
|> assertAndGetSingleToolTipText
570+
|> Assert.shouldBeEquivalentTo "val x: #seq<int list>"

0 commit comments

Comments
 (0)