Skip to content

Commit ccd0de1

Browse files
authored
[RFC FS-1060] Nullness checking (applied to codebase) (#15310)
- apply nullness to codebase - build F.C.S also againts net9 to get best annotations (multi targetting) - bootstrap FSharp.Build in proto build
1 parent 14f4369 commit ccd0de1

File tree

100 files changed

+910
-650
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+910
-650
lines changed

.fantomasignore

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ vsintegration/*
1212
!vsintegration/tests/FSharp.Editor.Tests
1313
artifacts/
1414

15-
# For some reason, it tries to format files from remotes (Processing .\.git\refs\remotes\<remote>\FSComp.fsi)
15+
# For some reason, it tries to format files from remotes (Processing ./.git/refs/remotes/<remote>/FSComp.fsi)
1616
.git/
1717

1818
# Explicitly unformatted implementation
@@ -101,10 +101,22 @@ src/FSharp.Core/option.fsi
101101
src/FSharp.Core/option.fs
102102
src/fsi/console.fs
103103
src/FSharp.Build/FSharpCommandLineBuilder.fs
104+
105+
src/Compiler/Utilities/Activity.fs
104106
src/Compiler/Utilities/sformat.fs
105107
src/Compiler/Utilities/illib.fsi
106108
src/Compiler/Utilities/illib.fs
107109

110+
111+
src/Compiler/Utilities/NullnessShims.fs
112+
src/Compiler/Utilities/LruCache.fsi
113+
src/Compiler/Utilities/LruCache.fs
114+
src/Compiler/Utilities/HashMultiMap.fsi
115+
src/Compiler/Utilities/HashMultiMap.fs
116+
src/Compiler/Facilities/AsyncMemoize.fsi
117+
src/Compiler/Facilities/AsyncMemoize.fs
118+
src/Compiler/AbstractIL/il.fs
119+
108120
# Fantomas limitations on implementation files (to investigate)
109121

110122
src/Compiler/AbstractIL/ilwrite.fs

FSharpBuild.Directory.Build.targets

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@
8888
</ItemGroup>
8989
</Target>
9090

91+
<!-- SDK targets override -->
92+
<PropertyGroup Condition="'$(Configuration)' != 'Proto' AND '$(DisableCompilerRedirection)'!='true' AND Exists('$(ProtoOutputPath)')">
93+
<FSharpBuildAssemblyFileOverride>$(ProtoOutputPath)\fsc\FSharp.Build.dll</FSharpBuildAssemblyFileOverride>
94+
</PropertyGroup>
95+
<UsingTask TaskName="FSharpEmbedResourceText" AssemblyFile="$(FSharpBuildAssemblyFileOverride)" Override="true" Condition="'$(Configuration)' != 'Proto' AND '$(DisableCompilerRedirection)'!='true' AND Exists('$(ProtoOutputPath)')" />
96+
<UsingTask TaskName="FSharpEmbedResXSource" AssemblyFile="$(FSharpBuildAssemblyFileOverride)" Override="true" Condition="'$(Configuration)' != 'Proto' AND '$(DisableCompilerRedirection)'!='true' AND Exists('$(ProtoOutputPath)')" />
97+
98+
9199
<Target Name="BeforeResGen"
92100
Inputs="@(EmbeddedResource->'$(IntermediateOutputPath)%(Filename)%(Extension)')"
93101
Outputs="@(EmbeddedResource->'$(IntermediateOutputPath)resources\%(Filename)%(Extension)')"

azure-pipelines-PR.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,8 @@ stages:
553553
- checkout: self
554554
clean: true
555555
- script: ./eng/cibuild.sh --configuration $(_BuildConfig) --testcoreclr
556+
env:
557+
SKIP_NETCURRENT_FSC_BUILD: true
556558
displayName: Build / Test
557559
- task: PublishTestResults@2
558560
displayName: Publish Test Results
@@ -595,6 +597,7 @@ stages:
595597
- script: ./eng/cibuild.sh --configuration $(_BuildConfig) --testcoreclr
596598
env:
597599
COMPlus_DefaultStackSize: 1000000
600+
SKIP_NETCURRENT_FSC_BUILD: true
598601
displayName: Build / Test
599602
- task: PublishTestResults@2
600603
displayName: Publish Test Results

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
* Treat `{ new Foo() }` as `SynExpr.ObjExpr` ([PR #17388](https://github.com/dotnet/fsharp/pull/17388))
2626
* Optimize metadata reading for type members and custom attributes. ([PR #17364](https://github.com/dotnet/fsharp/pull/17364))
2727
* Enforce `AttributeTargets` on unions. ([PR #17389](https://github.com/dotnet/fsharp/pull/17389))
28+
* Applied nullable reference types to FSharp.Compiler.Service itself ([PR #15310](https://github.com/dotnet/fsharp/pull/15310))
2829
* Ensure that isinteractive multi-emit backing fields are not public. ([Issue #17439](https://github.com/dotnet/fsharp/issues/17438)), ([PR #17439](https://github.com/dotnet/fsharp/pull/17439))
2930
* Enable FSharp 9.0 Language Version ([Issue #17497](https://github.com/dotnet/fsharp/issues/17438)), [PR](https://github.com/dotnet/fsharp/pull/17500)))
3031
* Better error reporting for unions with duplicated fields. ([PR #17521](https://github.com/dotnet/fsharp/pull/17521))

src/Compiler/AbstractIL/il.fs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,11 @@ let splitTypeNameRight nm =
170170
// --------------------------------------------------------------------
171171

172172
/// This is used to store event, property and field maps.
173-
type LazyOrderedMultiMap<'Key, 'Data when 'Key: equality>(keyf: 'Data -> 'Key, lazyItems: InterruptibleLazy<'Data list>) =
173+
type LazyOrderedMultiMap<'Key, 'Data when 'Key: equality
174+
#if !NO_CHECKNULLS
175+
and 'Key:not null
176+
#endif
177+
>(keyf: 'Data -> 'Key, lazyItems: InterruptibleLazy<'Data list>) =
174178

175179
let quickMap =
176180
lazyItems
@@ -515,7 +519,8 @@ type ILAssemblyRef(data) =
515519

516520
let retargetable = aname.Flags = AssemblyNameFlags.Retargetable
517521

518-
ILAssemblyRef.Create(aname.Name, None, publicKey, retargetable, version, locale)
522+
let name = match aname.Name with | null -> aname.FullName | name -> name
523+
ILAssemblyRef.Create(name, None, publicKey, retargetable, version, locale)
519524

520525
member aref.QualifiedName =
521526
let b = StringBuilder(100)
@@ -823,7 +828,7 @@ type ILTypeRef =
823828
member x.DebugText = x.ToString()
824829

825830
/// For debugging
826-
override x.ToString() = x.FullName
831+
override x.ToString() : string = x.FullName
827832

828833
and [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>] ILTypeSpec =
829834
{
@@ -875,7 +880,7 @@ and [<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugT
875880
&& (x.GenericArgs = y.GenericArgs)
876881

877882
override x.ToString() =
878-
x.TypeRef.ToString() + if isNil x.GenericArgs then "" else "<...>"
883+
x.TypeRef.FullName + if isNil x.GenericArgs then "" else "<...>"
879884

880885
and [<RequireQualifiedAccess; StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>] ILType =
881886
| Void
@@ -1017,8 +1022,9 @@ type ILMethodRef =
10171022
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
10181023
member x.DebugText = x.ToString()
10191024

1020-
override x.ToString() =
1021-
x.DeclaringTypeRef.ToString() + "::" + x.Name + "(...)"
1025+
member x.FullName = x.DeclaringTypeRef.FullName + "::" + x.Name + "(...)"
1026+
1027+
override x.ToString() = x.FullName
10221028

10231029
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
10241030
type ILFieldRef =
@@ -1033,7 +1039,7 @@ type ILFieldRef =
10331039
member x.DebugText = x.ToString()
10341040

10351041
override x.ToString() =
1036-
x.DeclaringTypeRef.ToString() + "::" + x.Name
1042+
x.DeclaringTypeRef.FullName + "::" + x.Name
10371043

10381044
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
10391045
type ILMethodSpec =
@@ -1072,7 +1078,7 @@ type ILMethodSpec =
10721078
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
10731079
member x.DebugText = x.ToString()
10741080

1075-
override x.ToString() = x.MethodRef.ToString() + "(...)"
1081+
override x.ToString() = x.MethodRef.FullName + "(...)"
10761082

10771083
[<StructuralEquality; StructuralComparison; StructuredFormatDisplay("{DebugText}")>]
10781084
type ILFieldSpec =
@@ -1213,7 +1219,7 @@ type ILAttribute =
12131219
[<DebuggerBrowsable(DebuggerBrowsableState.Never)>]
12141220
member x.DebugText = x.ToString()
12151221

1216-
override x.ToString() = x.Method.ToString() + "(...)"
1222+
override x.ToString() = x.Method.MethodRef.FullName
12171223

12181224
[<NoEquality; NoComparison; Struct>]
12191225
type ILAttributes(array: ILAttribute[]) =
@@ -1571,7 +1577,7 @@ type ILFieldInit =
15711577
| ILFieldInit.UInt64 u64 -> box u64
15721578
| ILFieldInit.Single ieee32 -> box ieee32
15731579
| ILFieldInit.Double ieee64 -> box ieee64
1574-
| ILFieldInit.Null -> (null :> Object)
1580+
| ILFieldInit.Null -> (null :> objnull)
15751581

15761582
// --------------------------------------------------------------------
15771583
// Native Types, for marshalling to the native C interface.

src/Compiler/AbstractIL/il.fsi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ type ILTypeRef =
237237

238238
member internal EqualsWithPrimaryScopeRef: ILScopeRef * obj -> bool
239239

240+
override ToString: unit -> string
241+
240242
interface System.IComparable
241243

242244
/// Type specs and types.
@@ -664,7 +666,7 @@ type ILFieldInit =
664666
| Double of double
665667
| Null
666668

667-
member AsObject: unit -> obj
669+
member AsObject: unit -> objnull
668670

669671
[<RequireQualifiedAccess; StructuralEquality; StructuralComparison>]
670672
type internal ILNativeVariant =

src/Compiler/AbstractIL/ilnativeres.fs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ type Directory(name, id) =
10001000
member val ID = id
10011001
member val NumberOfNamedEntries = Unchecked.defaultof<uint16> with get, set
10021002
member val NumberOfIdEntries = Unchecked.defaultof<uint16> with get, set
1003-
member val Entries = List<obj>()
1003+
member val Entries = List<objnull>()
10041004

10051005
type NativeResourceWriter() =
10061006
static member private CompareResources (left: Win32Resource) (right: Win32Resource) =
@@ -1149,7 +1149,12 @@ type NativeResourceWriter() =
11491149
dataWriter.WriteByte 0uy
11501150

11511151
false
1152-
| e -> failwithf "Unknown entry %s" (if isNull e then "<NULL>" else e.GetType().FullName)
1152+
| e ->
1153+
failwithf
1154+
"Unknown entry %s"
1155+
(match e with
1156+
| null -> "<NULL>"
1157+
| e -> e.GetType().FullName)
11531158

11541159
if id >= 0 then
11551160
writer.WriteInt32 id

src/Compiler/AbstractIL/ilpars.fsy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
%{
44

55
#nowarn "1182" // the generated code often has unused variable "parseState"
6+
#nowarn "3261" // the generated code would need to properly annotate nulls, e.g. changing System.Object to `obj|null`
67

78
open Internal.Utilities.Library
89

src/Compiler/AbstractIL/ilread.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -941,11 +941,11 @@ let mkCacheGeneric lowMem _inbase _nm (sz: int) =
941941
fun f (idx: 'T) ->
942942
let cache =
943943
match cache with
944-
| Null ->
944+
| null ->
945945
let v = ConcurrentDictionary<_, _>(Environment.ProcessorCount, sz)
946946
cache <- v
947947
v
948-
| NonNull v -> v
948+
| v -> v
949949

950950
match cache.TryGetValue idx with
951951
| true, v ->

0 commit comments

Comments
 (0)