Skip to content

Commit 5dab0a0

Browse files
dsymeDon Syme
andauthored
fix 10472 (#11349)
* fix 10472 * fix generated signature * simplify local type functions to use only an implementation class * fix comment * fix tests * simplify initial display environment code * fix test * simplify initial display environment code * fix fsi display code Co-authored-by: Don Syme <donsyme@fastmail.com>
1 parent 0794281 commit 5dab0a0

File tree

11 files changed

+334
-278
lines changed

11 files changed

+334
-278
lines changed

src/fsharp/IlxGen.fs

Lines changed: 233 additions & 210 deletions
Large diffs are not rendered by default.

src/fsharp/NicePrint.fs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,12 @@ module private PrintTypes =
946946
module private PrintTastMemberOrVals =
947947
open PrintTypes
948948

949+
let mkInlineL denv (v: Val) nameL =
950+
if v.MustInline && not denv.suppressInlineKeyword then
951+
wordL (tagKeyword "inline") ++ nameL
952+
else
953+
nameL
954+
949955
let private prettyLayoutOfMemberShortOption denv typarInst (v:Val) short =
950956
let v = mkLocalValRef v
951957
let membInfo = Option.get v.MemberInfo
@@ -978,6 +984,7 @@ module private PrintTastMemberOrVals =
978984
if short then tauL
979985
else
980986
let nameL = mkNameL niceMethodTypars tagMember v.LogicalName
987+
let nameL = if short then nameL else mkInlineL denv v.Deref nameL
981988
stat --- (nameL ^^ WordL.colon ^^ tauL)
982989
prettyTyparInst, resL
983990

@@ -1096,11 +1103,7 @@ module private PrintTastMemberOrVals =
10961103
wordL (tagKeyword "mutable") ++ nameL
10971104
else
10981105
nameL
1099-
let nameL =
1100-
if v.MustInline && not denv.suppressInlineKeyword then
1101-
wordL (tagKeyword "inline") ++ nameL
1102-
else
1103-
nameL
1106+
let nameL = mkInlineL denv v nameL
11041107

11051108
let isOverGeneric = List.length (Zset.elements (freeInType CollectTyparsNoCaching tau).FreeTypars) < List.length tps // Bug: 1143
11061109
let isTyFunction = v.IsTypeFunction // Bug: 1143, and innerpoly tests

src/fsharp/TypedTreeOps.fs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2782,7 +2782,7 @@ type DisplayEnv =
27822782
showHiddenMembers = false
27832783
showTyparBinding = false
27842784
showImperativeTyparAnnotations = false
2785-
suppressInlineKeyword = false
2785+
suppressInlineKeyword = true
27862786
suppressMutableKeyword = false
27872787
showMemberContainers = false
27882788
showAttributes = false
@@ -2813,6 +2813,24 @@ type DisplayEnv =
28132813
member denv.UseGenericParameterStyle style =
28142814
{ denv with genericParameterStyle = style }
28152815

2816+
static member InitialForSigFileGeneration g =
2817+
let denv =
2818+
{ DisplayEnv.Empty g with
2819+
showImperativeTyparAnnotations = true
2820+
showHiddenMembers = true
2821+
showObsoleteMembers = true
2822+
showAttributes = true
2823+
suppressInlineKeyword = false
2824+
showDocumentation = true
2825+
shrinkOverloads = false
2826+
}
2827+
denv.SetOpenPaths
2828+
[ FSharpLib.RootPath
2829+
FSharpLib.CorePath
2830+
FSharpLib.CollectionsPath
2831+
FSharpLib.ControlPath
2832+
(IL.splitNamespace FSharpLib.ExtraTopLevelOperatorsName) ]
2833+
28162834
let (+.+) s1 s2 = if s1 = "" then s2 else s1+"."+s2
28172835

28182836
let layoutOfPath p =
@@ -8794,21 +8812,23 @@ and remapValToNonLocal g tmenv inp =
87948812
let ApplyExportRemappingToEntity g tmenv x = remapTyconToNonLocal g tmenv x
87958813

87968814
(* Which constraints actually get compiled to .NET constraints? *)
8797-
let isCompiledConstraint cx =
8815+
let isCompiledOrWitnessPassingConstraint (g: TcGlobals) cx =
87988816
match cx with
87998817
| TyparConstraint.SupportsNull _ // this implies the 'class' constraint
88008818
| TyparConstraint.IsReferenceType _ // this is the 'class' constraint
88018819
| TyparConstraint.IsNonNullableStruct _
88028820
| TyparConstraint.IsReferenceType _
88038821
| TyparConstraint.RequiresDefaultConstructor _
88048822
| TyparConstraint.CoercesTo _ -> true
8823+
| TyparConstraint.MayResolveMember _ when g.langVersion.SupportsFeature LanguageFeature.WitnessPassing -> true
88058824
| _ -> false
88068825

8807-
// Is a value a first-class polymorphic value with .NET constraints?
8808-
// Used to turn off TLR and method splitting
8826+
// Is a value a first-class polymorphic value with .NET constraints, or witness-passing constraints?
8827+
// Used to turn off TLR and method splitting and do not compile to
8828+
// FSharpTypeFunc, but rather bake a "local type function" for each TyLambda abstraction.
88098829
let IsGenericValWithGenericConstraints g (v: Val) =
88108830
isForallTy g v.Type &&
8811-
v.Type |> destForallTy g |> fst |> List.exists (fun tp -> List.exists isCompiledConstraint tp.Constraints)
8831+
v.Type |> destForallTy g |> fst |> List.exists (fun tp -> List.exists (isCompiledOrWitnessPassingConstraint g) tp.Constraints)
88128832

88138833
// Does a type support a given interface?
88148834
type Entity with

src/fsharp/TypedTreeOps.fsi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,8 @@ type DisplayEnv =
10081008

10091009
member UseGenericParameterStyle: GenericParameterStyle -> DisplayEnv
10101010

1011+
static member InitialForSigFileGeneration: TcGlobals -> DisplayEnv
1012+
10111013
val tagEntityRefName: xref: EntityRef -> name: string -> TaggedText
10121014

10131015
/// Return the full text for an item as we want it displayed to the user as a fully qualified entity
@@ -1563,6 +1565,8 @@ val normalizeEnumTy: TcGlobals -> TType -> TType
15631565
/// Determine if a type is a struct type
15641566
val isStructTy: TcGlobals -> TType -> bool
15651567

1568+
val isStructOrEnumTyconTy: TcGlobals -> TType -> bool
1569+
15661570
/// Determine if a type is a variable type with the ': struct' constraint.
15671571
///
15681572
/// Note, isStructTy does not include type parameters with the ': struct' constraint

src/fsharp/fsc.fs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -309,21 +309,6 @@ let ProcessCommandLineFlags (tcConfigB: TcConfigBuilder, lcidFromCodePage, argv)
309309
/// Write a .fsi file for the --sig option
310310
module InterfaceFileWriter =
311311

312-
let BuildInitialDisplayEnvForSigFileGeneration tcGlobals =
313-
let denv =
314-
{ DisplayEnv.Empty tcGlobals with
315-
showImperativeTyparAnnotations = true
316-
showHiddenMembers = true
317-
showObsoleteMembers = true
318-
showAttributes = true
319-
showDocumentation = true }
320-
denv.SetOpenPaths
321-
[ FSharpLib.RootPath
322-
FSharpLib.CorePath
323-
FSharpLib.CollectionsPath
324-
FSharpLib.ControlPath
325-
(IL.splitNamespace FSharpLib.ExtraTopLevelOperatorsName) ]
326-
327312
let WriteInterfaceFile (tcGlobals, tcConfig: TcConfig, infoReader, declaredImpls) =
328313

329314
/// Use a UTF-8 Encoding with no Byte Order Mark
@@ -336,9 +321,9 @@ module InterfaceFileWriter =
336321
fprintfn os ""
337322

338323
for (TImplFile (_, _, mexpr, _, _, _)) in declaredImpls do
339-
let denv = BuildInitialDisplayEnvForSigFileGeneration tcGlobals
324+
let denv = DisplayEnv.InitialForSigFileGeneration tcGlobals
340325
writeViaBuffer os (fun os s -> Printf.bprintf os "%s\n\n" s)
341-
(NicePrint.layoutInferredSigOfModuleExpr true { denv with shrinkOverloads = false; printVerboseSignatures = true } infoReader AccessibleFromSomewhere range0 mexpr |> Display.squashTo 80 |> LayoutRender.showL)
326+
(NicePrint.layoutInferredSigOfModuleExpr true { denv with printVerboseSignatures = true } infoReader AccessibleFromSomewhere range0 mexpr |> Display.squashTo 80 |> LayoutRender.showL)
342327

343328
if tcConfig.printSignatureFile <> "" then os.Dispose()
344329

src/fsharp/fsi/fsi.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ type internal FsiValuePrinter(fsi: FsiEvaluationSessionHostConfig, tcConfigB: Tc
480480
let lay = valuePrinter.PrintValue (FsiValuePrinterMode.PrintExpr, opts, obj, objTy)
481481
if isEmptyL lay then None else Some lay // suppress empty layout
482482
let denv = { denv with suppressMutableKeyword = true } // suppress 'mutable' in 'val mutable it = ...'
483+
let denv = { denv with suppressInlineKeyword = false } // dont' suppress 'inline' in 'val inline f = ...'
483484
let fullL =
484485
if Option.isNone rhsL || isEmptyL rhsL.Value then
485486
NicePrint.prettyLayoutOfValOrMemberNoInst denv vref (* the rhs was suppressed by the printer, so no value to print *)
@@ -1200,6 +1201,7 @@ type internal FsiDynamicCompiler
12001201
else
12011202
// With #load items, the vals in the inferred signature do not tie up with those generated. Disable printing.
12021203
denv
1204+
let denv = { denv with suppressInlineKeyword = false } // dont' suppress 'inline' in 'val inline f = ...'
12031205

12041206
// 'Open' the path for the fragment we just compiled for any future printing.
12051207
let denv = denv.AddOpenPath (pathOfLid prefixPath)

src/fsharp/service/FSharpCheckerResults.fs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,22 +1974,7 @@ type FSharpCheckFileResults
19741974
threadSafeOp (fun () -> None) (fun scope ->
19751975
scope.ImplementationFile
19761976
|> Option.map (fun implFile ->
1977-
// this logic copied from fsc's InterfaceFileWriter.BuildInitialDisplayEnvForSigFileGeneration,
1978-
// should/can it be consolidated?
1979-
let denv =
1980-
{ DisplayEnv.Empty scope.TcGlobals with
1981-
showImperativeTyparAnnotations = true
1982-
showHiddenMembers = true
1983-
showObsoleteMembers = true
1984-
showAttributes = true
1985-
showDocumentation = true }
1986-
let denv =
1987-
denv.SetOpenPaths
1988-
[ FSharpLib.RootPath
1989-
FSharpLib.CorePath
1990-
FSharpLib.CollectionsPath
1991-
FSharpLib.ControlPath
1992-
(IL.splitNamespace FSharpLib.ExtraTopLevelOperatorsName) ]
1977+
let denv = DisplayEnv.InitialForSigFileGeneration scope.TcGlobals
19931978
let infoReader = InfoReader(scope.TcGlobals, scope.TcImports.GetImportMap())
19941979
let (TImplFile (_, _, mexpr, _, _, _)) = implFile
19951980
let layout = NicePrint.layoutInferredSigOfModuleExpr true denv infoReader AccessibleFromSomewhere range0 mexpr

src/fsharp/symbols/SymbolHelpers.fs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -763,8 +763,7 @@ module internal SymbolHelpers =
763763
items |> List.filter (fun item -> not (IsExplicitlySuppressed g item.Item))
764764

765765
let SimplerDisplayEnv denv =
766-
{ denv with suppressInlineKeyword=true
767-
shortConstraints=true
766+
{ denv with shortConstraints=true
768767
showConstraintTyparAnnotations=false
769768
abbreviateAdditionalConstraints=false
770769
suppressNestedTypes=true

src/fsharp/symbols/Symbols.fs

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -814,16 +814,7 @@ type FSharpEntity(cenv: SymbolEnv, entity:EntityRef) =
814814
if entity.IsNamespace then None
815815
else
816816

817-
let denv = DisplayEnv.Empty cenv.g
818-
let denv =
819-
{ denv with
820-
showImperativeTyparAnnotations=true
821-
showHiddenMembers=true
822-
showObsoleteMembers=true
823-
showAttributes=true
824-
shrinkOverloads=false
825-
printVerboseSignatures=false
826-
showDocumentation=true }
817+
let denv = DisplayEnv.InitialForSigFileGeneration cenv.g
827818

828819
let extraOpenPath =
829820
match entity.CompilationPathOpt with
@@ -855,15 +846,7 @@ type FSharpEntity(cenv: SymbolEnv, entity:EntityRef) =
855846
| _ ->
856847
false
857848

858-
let denv =
859-
denv.SetOpenPaths
860-
([ FSharpLib.RootPath
861-
FSharpLib.CorePath
862-
FSharpLib.CollectionsPath
863-
FSharpLib.ControlPath
864-
(IL.splitNamespace FSharpLib.ExtraTopLevelOperatorsName)
865-
extraOpenPath
866-
])
849+
let denv = denv.AddOpenPath extraOpenPath
867850

868851
let infoReader = cenv.infoReader
869852

tests/fsharp/Compiler/Service/SignatureGenerationTests.fs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ exception MyEx of reason: string
4040
/// module-level docs
4141
module Inner =
4242
/// type-level docs
43-
type Farts
43+
type Facts
4444
/// primary ctor docs
4545
(name: string) =
4646
/// constructor-level docs
47-
new() = Farts("default name")
47+
new() = Facts("default name")
4848
/// member-level docs
4949
member x.blah() = [1;2;3]
5050
/// auto-property-level docs
@@ -77,9 +77,11 @@ module Inner =
7777
/// module-level docs
7878
module Inner = begin
7979
/// type-level docs
80-
type Farts =
80+
type Facts =
8181
/// constructor-level docs
82-
new : unit -> Farts + 1 overload
82+
new : unit -> Facts
83+
/// primary ctor docs
84+
new : name:string -> Facts
8385
/// member-level docs
8486
member blah : unit -> int list
8587
/// auto-property-level docs

0 commit comments

Comments
 (0)