diff --git a/Directory.Build.props b/Directory.Build.props
index 719838f0a0d..7f5b362cb34 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -7,7 +7,7 @@
$(MSBuildThisFileDirectory)
true
net9.0
- $(DotNetBuildFromSource)
+ $(DotNetBuildSourceOnly)
-
+
$(NetCurrent)
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 52109a82ee6..c43425cc369 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -26,7 +26,7 @@
When .NET gets built from source, make the SDK aware there are bootstrap packages
for Microsoft.NETCore.App.Runtime. and Microsoft.NETCore.App.Crossgen2..
-->
-
+
%(RuntimePackRuntimeIdentifiers);$(NETCoreSdkRuntimeIdentifier)
@@ -51,30 +51,4 @@
RemoveProperties="TargetFramework"
StopOnFirstFailure="True" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/FSharpBuild.Directory.Build.props b/FSharpBuild.Directory.Build.props
index b2b9ae303cb..148d9c95116 100644
--- a/FSharpBuild.Directory.Build.props
+++ b/FSharpBuild.Directory.Build.props
@@ -73,8 +73,8 @@
false
-
-
+
+
false
diff --git a/buildtools/fsyacc/fsyaccdriver.fs b/buildtools/fsyacc/fsyaccdriver.fs
index f46e607f93a..c9ca12e4710 100644
--- a/buildtools/fsyacc/fsyaccdriver.fs
+++ b/buildtools/fsyacc/fsyaccdriver.fs
@@ -199,8 +199,6 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
writer.WriteLineInterface "module %s" s;
writer.WriteLine "#nowarn \"64\";; // turn off warnings that type variables used in production annotations are instantiated to concrete type";
- writer.WriteLine "#nowarn \"1182\" // the generated code often has unused variable 'parseState'"
- writer.WriteLine "#nowarn \"3261\" // the generated code would need to properly annotate nulls, e.g. changing System.Object to `obj|null`";
for s in generatorState.opens do
writer.WriteLine "open %s" s;
diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
index 24ce8c5a07b..b98195c81d7 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
@@ -1,6 +1,5 @@
### Fixed
-* Fix a bug in the interaction between ``#line` and `#nowarn` directives ([PR #17649](https://github.com/dotnet/fsharp/pull/17649))
* Fix wrong TailCall warning ([Issue #17604](https://github.com/dotnet/fsharp/issues/17604), [PR #17637](https://github.com/dotnet/fsharp/pull/17637))
* Compiler hangs when compiling inline recursive invocation ([Issue #17376](https://github.com/dotnet/fsharp/issues/17376), [PR #17394](https://github.com/dotnet/fsharp/pull/17394))
* Fix reporting IsFromComputationExpression only for CE builder type constructors and let bindings. ([PR #17375](https://github.com/dotnet/fsharp/pull/17375))
@@ -16,8 +15,12 @@
* Add missing byte chars notations, enforce limits in decimal notation in byte char & string (Issues [#15867](https://github.com/dotnet/fsharp/issues/15867), [#15868](https://github.com/dotnet/fsharp/issues/15868), [#15869](https://github.com/dotnet/fsharp/issues/15869), [PR #15898](https://github.com/dotnet/fsharp/pull/15898))
* Parentheses analysis: keep extra parentheses around unit & tuples in method definitions. ([PR #17618](https://github.com/dotnet/fsharp/pull/17618))
* Fix IsUnionCaseTester throwing for non-methods/properties [#17301](https://github.com/dotnet/fsharp/pull/17634)
+* Fix xmlc doc tooltip display for nullable types [#17741](https://github.com/dotnet/fsharp/pull/17741)
* Consider `open type` used when the type is an enum and any of the enum cases is used unqualified. ([PR #17628](https://github.com/dotnet/fsharp/pull/17628))
* Guard for possible StackOverflowException when typechecking non recursive modules and namespaces ([PR #17654](https://github.com/dotnet/fsharp/pull/17654))
+* Nullable - fix for processing System.Nullable types with nesting ([PR #17736](https://github.com/dotnet/fsharp/pull/17736))
+* Fixes for the optimization of simple mappings in array and list comprehensions. ([Issue #17708](https://github.com/dotnet/fsharp/issues/17708), [PR #17711](https://github.com/dotnet/fsharp/pull/17711))
+
### Added
@@ -33,6 +36,8 @@
* Enable LanguageFeature.EnforceAttributeTargets in F# 9.0. ([Issue #17514](https://github.com/dotnet/fsharp/issues/17558), [PR #17516](https://github.com/dotnet/fsharp/pull/17558))
* Parser: better recovery for unfinished patterns ([PR #17231](https://github.com/dotnet/fsharp/pull/17231), [PR #17232](https://github.com/dotnet/fsharp/pull/17232)))
* Enable consuming generic arguments defined as `allows ref struct` in C# ([Issue #17597](https://github.com/dotnet/fsharp/issues/17597)
+* Trivia for SynTypeConstraint.WhereTyparNotSupportsNull. ([Issue #17721](https://github.com/dotnet/fsharp/issues/17721), [PR #17745](https://github.com/dotnet/fsharp/pull/17745))
+* Trivia for SynType.WithNull. ([Issue #17720](https://github.com/dotnet/fsharp/issues/17720), [PR #17745](https://github.com/dotnet/fsharp/pull/17745))
### Changed
@@ -47,7 +52,8 @@
* Better CE error reporting when using `use!` with `and!` ([PR #17671](https://github.com/dotnet/fsharp/pull/17671))
* Better error reporting for let bindings. ([PR #17601](https://github.com/dotnet/fsharp/pull/17601))
* Optimize ILTypeDef interface impls reading from metadata. ([PR #17382](https://github.com/dotnet/fsharp/pull/17382))
+* Make ILTypeDef interface impls calculation lazy. ([PR #17392](https://github.com/dotnet/fsharp/pull/17392))
* Better error reporting for active patterns. ([PR #17666](https://github.com/dotnet/fsharp/pull/17666))
-
+* Multiple fsi sessions use separate temporary directories ([PR #17760](https://github.com/dotnet/fsharp/pull/17760))
### Breaking Changes
diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
new file mode 100644
index 00000000000..a2a0f964f7f
--- /dev/null
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
@@ -0,0 +1,11 @@
+### Fixed
+
+
+### Added
+
+
+### Changed
+
+* Make ILTypeDef interface impls calculation lazy. ([PR #17392](https://github.com/dotnet/fsharp/pull/17392))
+
+### Breaking Changes
diff --git a/docs/release-notes/About.md b/docs/release-notes/About.md
index 20e5138533c..5a8434709d3 100644
--- a/docs/release-notes/About.md
+++ b/docs/release-notes/About.md
@@ -7,7 +7,7 @@ title: About
# About
-The release notes for the [F\# language](./Language.md), [FSharp.Core](./FSharp.Core.md) and [FSharp.Compiler.Service](./FSharp.Compiler.Service.md) are based on the [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format.
+The release notes for the [F\# language](./Language.html), [FSharp.Core](./FSharp.Core.html) and [FSharp.Compiler.Service](./FSharp.Compiler.Service.html) are based on the [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format.
The target audience of these release notes are the respective end-users.
## Writing a changelog entry
diff --git a/docs/release-notes/Language.fsx b/docs/release-notes/Language.fsx
index 73c173e7774..3bcd6f14c3d 100644
--- a/docs/release-notes/Language.fsx
+++ b/docs/release-notes/Language.fsx
@@ -25,7 +25,11 @@ Directory.EnumerateFiles(path, "*.md")
| "preview", "preview" -> 0
| "preview", _ -> -1
| _, "preview" -> 1
- | _, _ -> compare (int b) (int a))
+ | _, _ ->
+ match System.Decimal.TryParse(b), System.Decimal.TryParse(b) with
+ | (true, a) , ( true, b) -> compare (int b) (int a)
+ | _ -> failwithf "Cannot compare %s with %s" b a
+ )
|> Seq.map (fun file ->
let version = Path.GetFileNameWithoutExtension(file)
let version = if version = "preview" then "Preview" else version
diff --git a/eng/Build.ps1 b/eng/Build.ps1
index a6bda85ef6b..6305083d0df 100644
--- a/eng/Build.ps1
+++ b/eng/Build.ps1
@@ -292,6 +292,8 @@ function BuildSolution([string] $solutionName, $nopack) {
# Do not set the property to true explicitly, since that would override value projects might set.
$suppressExtensionDeployment = if (!$deployExtensions) { "/p:DeployExtension=false" } else { "" }
+ $sourceBuildArgs = if ($sourceBuild) { "/p:DotNetBuildSourceOnly=true /p:DotNetBuildRepo=true" } else { "" }
+
$BUILDING_USING_DOTNET_ORIG = $env:BUILDING_USING_DOTNET
$env:BUILDING_USING_DOTNET="false"
@@ -314,10 +316,10 @@ function BuildSolution([string] $solutionName, $nopack) {
/p:QuietRestore=$quietRestore `
/p:QuietRestoreBinaryLog=$binaryLog `
/p:TestTargetFrameworks=$testTargetFrameworks `
- /p:DotNetBuildFromSource=$sourceBuild `
/p:CompressAllMetadata=$CompressAllMetadata `
/p:BuildNoRealsig=$buildnorealsig `
/v:$verbosity `
+ $sourceBuildArgs `
$suppressExtensionDeployment `
@properties
diff --git a/eng/SourceBuild.props b/eng/DotNetBuild.props
similarity index 87%
rename from eng/SourceBuild.props
rename to eng/DotNetBuild.props
index c1759d53260..c7bc688ba3e 100644
--- a/eng/SourceBuild.props
+++ b/eng/DotNetBuild.props
@@ -13,7 +13,7 @@
-->
+ Condition="'$(DotNetBuildSourceOnly)' == 'true'">
$(InnerBuildArgs) /p:Projects="$(InnerSourceBuildRepoRoot)\Microsoft.FSharp.Compiler.sln"
@@ -26,7 +26,7 @@
+ Condition="'$(DotNetBuildSourceOnly)' == 'true'">
--tfm $(SourceBuildBootstrapTfm)
@@ -41,9 +41,9 @@
-bl enables the binlogs for the tools and Proto builds, which make debugging failures here easier
-->
+ EnvironmentVariables="@(InnerBuildEnv)" />
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 76c5d53d8d6..a6fe9dd9339 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -42,14 +42,14 @@
-
+
https://github.com/dotnet/arcade
- 65260b148c869ada772a5843863c54737cd2361e
+ 91b9734abbad751d575c002b30778c88d978993c
-
+
https://github.com/dotnet/arcade
- 65260b148c869ada772a5843863c54737cd2361e
+ 91b9734abbad751d575c002b30778c88d978993c
diff --git a/eng/Versions.props b/eng/Versions.props
index c56fb4a3cd0..24e8f6f6790 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -14,7 +14,7 @@
9
0
- 100
+ 200
0
diff --git a/eng/build.sh b/eng/build.sh
index 8544de1e72e..90260cbfa4f 100755
--- a/eng/build.sh
+++ b/eng/build.sh
@@ -241,6 +241,11 @@ function BuildSolution {
if [[ "$UNAME" == "Darwin" ]]; then
enable_analyzers=false
fi
+
+ local source_build_args=""
+ if [[ "$source_build" == true ]]; then
+ source_build_args="/p:DotNetBuildRepo=true /p:DotNetBuildSourceOnly=true"
+ fi
# NuGet often exceeds the limit of open files on Mac and Linux
# https://github.com/NuGet/Home/issues/2163
@@ -274,7 +279,7 @@ function BuildSolution {
fi
BuildMessage="Error building tools"
- local args=" publish $repo_root/proto.proj $blrestore $bltools /p:Configuration=Proto /p:ArcadeBuildFromSource=$source_build $properties"
+ local args=" publish $repo_root/proto.proj $blrestore $bltools /p:Configuration=Proto $source_build_args $properties"
echo $args
"$DOTNET_INSTALL_DIR/dotnet" $args #$args || exit $?
fi
@@ -296,8 +301,8 @@ function BuildSolution {
/p:ContinuousIntegrationBuild=$ci \
/p:QuietRestore=$quiet_restore \
/p:QuietRestoreBinaryLog="$binary_log" \
- /p:ArcadeBuildFromSource=$source_build \
/p:BuildNoRealsig=$buildnorealsig \
+ $source_build_args \
$properties
fi
}
diff --git a/eng/common/internal/Tools.csproj b/eng/common/internal/Tools.csproj
index 32f79dfb340..db46d5582eb 100644
--- a/eng/common/internal/Tools.csproj
+++ b/eng/common/internal/Tools.csproj
@@ -6,6 +6,31 @@
false
false
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/test-determinism.ps1 b/eng/test-determinism.ps1
index fcb5495f434..8056de2b371 100644
--- a/eng/test-determinism.ps1
+++ b/eng/test-determinism.ps1
@@ -78,7 +78,7 @@ function Run-Build([string]$rootDir, [string]$increment) {
/p:ContinuousIntegrationBuild=false `
/p:OfficialBuildId="" `
/p:QuietRestore=false `
- /p:DotNetBuildFromSource=false `
+ /p:DotNetBuildSourceOnly=false `
/p:Deterministic=true `
/p:DebugDeterminism=true `
/p:Features="debug-determinism" `
diff --git a/global.json b/global.json
index bce954435c7..b66eed16d21 100644
--- a/global.json
+++ b/global.json
@@ -17,7 +17,7 @@
"perl": "5.38.2.2"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24459.6",
+ "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24462.3",
"Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.23255.2"
}
}
diff --git a/proto.proj b/proto.proj
index 2d07b389fa6..eb0814976ea 100644
--- a/proto.proj
+++ b/proto.proj
@@ -4,8 +4,10 @@
Bootstrap
-
-
+
+
diff --git a/setup/Directory.Build.props b/setup/Directory.Build.props
index cca2c04ebcf..47bbe960ea3 100644
--- a/setup/Directory.Build.props
+++ b/setup/Directory.Build.props
@@ -12,7 +12,7 @@
$(ArtifactsDir)\VSSetup.obj\$(Configuration)\$(MSBuildProjectName)
$(SetupRootFolder)..\artifacts\VSSetup\$(Configuration)
$(SetupRootFolder)..\artifacts\VSSetup\$(Configuration)\Insertion
- true
+ true
Neutral
diff --git a/setup/Swix/Directory.Build.targets b/setup/Swix/Directory.Build.targets
index 5e826e8da63..85048309295 100644
--- a/setup/Swix/Directory.Build.targets
+++ b/setup/Swix/Directory.Build.targets
@@ -15,7 +15,7 @@
+ Condition="'$(DotNetBuildSourceOnly)' != 'true'">
diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs
index 9ed1822676b..b10a119fced 100644
--- a/src/Compiler/AbstractIL/il.fs
+++ b/src/Compiler/AbstractIL/il.fs
@@ -1909,6 +1909,23 @@ let inline conditionalAdd condition flagToAdd source =
let NoMetadataIdx = -1
+type InterfaceImpl =
+ { Idx: int; Type: ILType; mutable CustomAttrsStored: ILAttributesStored }
+
+ member x.CustomAttrs =
+ match x.CustomAttrsStored with
+ | ILAttributesStored.Reader f ->
+ let res = ILAttributes(f x.Idx)
+ x.CustomAttrsStored <- ILAttributesStored.Given res
+ res
+ | ILAttributesStored.Given attrs -> attrs
+
+ static member Create(ilType: ILType, customAttrsStored: ILAttributesStored) =
+ { Idx = NoMetadataIdx; Type = ilType; CustomAttrsStored = customAttrsStored }
+
+ static member Create(ilType: ILType) = InterfaceImpl.Create(ilType, emptyILCustomAttrsStored)
+
+
[]
type ILMethodDef
(
@@ -2635,8 +2652,7 @@ type ILTypeDef
name: string,
attributes: TypeAttributes,
layout: ILTypeDefLayout,
- implements: ILTypes,
- implementsCustomAttrs: (ILAttributesStored * int) list option,
+ implements: InterruptibleLazy,
genericParams: ILGenericParameterDefs,
extends: ILType option,
methods: ILMethodDefs,
@@ -2659,7 +2675,6 @@ type ILTypeDef
attributes,
layout,
implements,
- implementsCustomAttrs,
genericParams,
extends,
methods,
@@ -2676,7 +2691,6 @@ type ILTypeDef
attributes,
layout,
implements,
- implementsCustomAttrs,
genericParams,
extends,
methods,
@@ -2703,8 +2717,6 @@ type ILTypeDef
member _.Implements = implements
- member _.ImplementsCustomAttrs = implementsCustomAttrs
-
member _.Extends = extends
member _.Methods = methods
@@ -2744,8 +2756,7 @@ type ILTypeDef
?properties,
?newAdditionalFlags,
?customAttrs,
- ?securityDecls,
- ?implementsCustomAttrs
+ ?securityDecls
) =
ILTypeDef(
name = defaultArg name x.Name,
@@ -2754,7 +2765,6 @@ type ILTypeDef
genericParams = defaultArg genericParams x.GenericParams,
nestedTypes = defaultArg nestedTypes x.NestedTypes,
implements = defaultArg implements x.Implements,
- implementsCustomAttrs = defaultArg implementsCustomAttrs x.ImplementsCustomAttrs,
extends = defaultArg extends x.Extends,
methods = defaultArg methods x.Methods,
securityDecls = defaultArg securityDecls x.SecurityDecls,
@@ -3333,6 +3343,8 @@ let mkILTypeDefs l = mkILTypeDefsFromArray (Array.ofList l)
let mkILTypeDefsComputed f = ILTypeDefs f
let emptyILTypeDefs = mkILTypeDefsFromArray [||]
+let emptyILInterfaceImpls = InterruptibleLazy.FromValue([])
+
// --------------------------------------------------------------------
// Operations on method tables.
// --------------------------------------------------------------------
@@ -4240,7 +4252,7 @@ let mkILSimpleStorageCtor (baseTySpec, ty, extraParams, flds, access, tag, impor
let mkILStorageCtor (preblock, ty, flds, access, tag, imports) =
mkILStorageCtorWithParamNames (preblock, ty, [], addParamNames flds, access, tag, imports)
-let mkILGenericClass (nm, access, genparams, extends, impl, methods, fields, nestedTypes, props, events, attrs, init) =
+let mkILGenericClass (nm, access, genparams, extends, impls, methods, fields, nestedTypes, props, events, attrs, init) =
let attributes =
convertTypeAccessFlags access
||| TypeAttributes.AutoLayout
@@ -4254,8 +4266,7 @@ let mkILGenericClass (nm, access, genparams, extends, impl, methods, fields, nes
name = nm,
attributes = attributes,
genericParams = genparams,
- implements = impl,
- implementsCustomAttrs = None,
+ implements = InterruptibleLazy.FromValue(impls),
layout = ILTypeDefLayout.Auto,
extends = Some extends,
methods = methods,
@@ -4279,8 +4290,7 @@ let mkRawDataValueTypeDef (iltyp_ValueType: ILType) (nm, size, pack) =
||| TypeAttributes.ExplicitLayout
||| TypeAttributes.BeforeFieldInit
||| TypeAttributes.AnsiClass),
- implements = [],
- implementsCustomAttrs = None,
+ implements = emptyILInterfaceImpls,
extends = Some iltyp_ValueType,
layout = ILTypeDefLayout.Explicit { Size = Some size; Pack = Some pack },
methods = emptyILMethods,
@@ -5586,7 +5596,7 @@ and refsOfILMethodImpl s m =
and refsOfILTypeDef s (td: ILTypeDef) =
refsOfILTypeDefs s td.NestedTypes
refsOfILGenericParams s td.GenericParams
- refsOfILTypes s td.Implements
+ refsOfILTypes s (td.Implements.Value |> List.map _.Type)
Option.iter (refsOfILType s) td.Extends
refsOfILMethodDefs s td.Methods
refsOfILFieldDefs s (td.Fields.AsList())
diff --git a/src/Compiler/AbstractIL/il.fsi b/src/Compiler/AbstractIL/il.fsi
index e3ec95a40d7..1487830e8f0 100644
--- a/src/Compiler/AbstractIL/il.fsi
+++ b/src/Compiler/AbstractIL/il.fsi
@@ -327,6 +327,15 @@ type ILCallingSignature =
ArgTypes: ILTypes
ReturnType: ILType }
+type InterfaceImpl =
+ { Idx: int
+ Type: ILType
+ mutable CustomAttrsStored: ILAttributesStored }
+
+ member CustomAttrs: ILAttributes
+ static member Create: ilType: ILType * customAttrsStored: ILAttributesStored -> InterfaceImpl
+ static member Create: ilType: ILType -> InterfaceImpl
+
/// Actual generic parameters are always types.
type ILGenericArgs = ILType list
@@ -1518,8 +1527,7 @@ type ILTypeDef =
name: string *
attributes: TypeAttributes *
layout: ILTypeDefLayout *
- implements: ILTypes *
- implementsCustomAttrs: (ILAttributesStored * int) list option *
+ implements: InterruptibleLazy *
genericParams: ILGenericParameterDefs *
extends: ILType option *
methods: ILMethodDefs *
@@ -1539,8 +1547,7 @@ type ILTypeDef =
name: string *
attributes: TypeAttributes *
layout: ILTypeDefLayout *
- implements: ILTypes *
- implementsCustomAttrs: (ILAttributesStored * int) list option *
+ implements: InterruptibleLazy *
genericParams: ILGenericParameterDefs *
extends: ILType option *
methods: ILMethodDefs *
@@ -1559,8 +1566,7 @@ type ILTypeDef =
member GenericParams: ILGenericParameterDefs
member Layout: ILTypeDefLayout
member NestedTypes: ILTypeDefs
- member Implements: ILTypes
- member ImplementsCustomAttrs: (ILAttributesStored * int) list option
+ member Implements: InterruptibleLazy
member Extends: ILType option
member Methods: ILMethodDefs
member SecurityDecls: ILSecurityDecls
@@ -1609,7 +1615,7 @@ type ILTypeDef =
?name: string *
?attributes: TypeAttributes *
?layout: ILTypeDefLayout *
- ?implements: ILTypes *
+ ?implements: InterruptibleLazy *
?genericParams: ILGenericParameterDefs *
?extends: ILType option *
?methods: ILMethodDefs *
@@ -1620,8 +1626,7 @@ type ILTypeDef =
?properties: ILPropertyDefs *
?newAdditionalFlags: ILTypeDefAdditionalFlags *
?customAttrs: ILAttributesStored *
- ?securityDecls: ILSecurityDecls *
- ?implementsCustomAttrs: (ILAttributesStored * int) list option ->
+ ?securityDecls: ILSecurityDecls ->
ILTypeDef
/// Represents a prefix of information for ILTypeDef.
@@ -2161,7 +2166,7 @@ val internal mkILGenericClass:
ILTypeDefAccess *
ILGenericParameterDefs *
ILType *
- ILType list *
+ InterfaceImpl list *
ILMethodDefs *
ILFieldDefs *
ILTypeDefs *
@@ -2245,6 +2250,8 @@ val internal mkCtorMethSpecForDelegate: ILGlobals -> ILType * bool -> ILMethodSp
/// The toplevel "class" for a module or assembly.
val internal mkILTypeForGlobalFunctions: ILScopeRef -> ILType
+val emptyILInterfaceImpls: InterruptibleLazy
+
/// Making tables of custom attributes, etc.
val mkILCustomAttrs: ILAttribute list -> ILAttributes
val mkILCustomAttrsFromArray: ILAttribute[] -> ILAttributes
diff --git a/src/Compiler/AbstractIL/ilmorph.fs b/src/Compiler/AbstractIL/ilmorph.fs
index 334ed93d212..9f2f3d0582f 100644
--- a/src/Compiler/AbstractIL/ilmorph.fs
+++ b/src/Compiler/AbstractIL/ilmorph.fs
@@ -368,8 +368,13 @@ let rec tdef_ty2ty_ilmbody2ilmbody_mdefs2mdefs isInKnownSet enc fs (tdef: ILType
let mdefsR = fMethodDefs (enc, tdef) tdef.Methods
let fdefsR = fdefs_ty2ty fTyInCtxtR tdef.Fields
+ let implements =
+ tdef.Implements.Value
+ |> List.map (fun x -> { x with Type = fTyInCtxtR x.Type })
+ |> InterruptibleLazy.FromValue
+
tdef.With(
- implements = List.map fTyInCtxtR tdef.Implements,
+ implements = implements,
genericParams = gparams_ty2ty fTyInCtxtR tdef.GenericParams,
extends = Option.map fTyInCtxtR tdef.Extends,
methods = mdefsR,
diff --git a/src/Compiler/AbstractIL/ilpars.fsy b/src/Compiler/AbstractIL/ilpars.fsy
index b8380364f6b..ca06f6570be 100644
--- a/src/Compiler/AbstractIL/ilpars.fsy
+++ b/src/Compiler/AbstractIL/ilpars.fsy
@@ -2,7 +2,6 @@
%{
-#nowarn "64" // turn off warnings that type variables used in production annotations are instantiated to concrete type
#nowarn "1182" // the generated code often has unused variable "parseState"
#nowarn "3261" // the generated code would need to properly annotate nulls, e.g. changing System.Object to `obj|null`
diff --git a/src/Compiler/AbstractIL/ilprint.fs b/src/Compiler/AbstractIL/ilprint.fs
index 9d278dbe317..6ed8aec9286 100644
--- a/src/Compiler/AbstractIL/ilprint.fs
+++ b/src/Compiler/AbstractIL/ilprint.fs
@@ -752,8 +752,9 @@ let goutput_superclass env os =
output_string os "extends "
(goutput_typ_with_shortened_class_syntax env) os typ
-let goutput_implements env os (imp: ILTypes) =
+let goutput_implements env os (imp: InterfaceImpl list) =
if not (List.isEmpty imp) then
+ let imp = imp |> Seq.map _.Type
output_string os "implements "
output_seq ", " (goutput_typ_with_shortened_class_syntax env) os imp
@@ -836,7 +837,7 @@ let rec goutput_tdef enc env contents os (cd: ILTypeDef) =
output_string os "\n\t"
goutput_superclass env os cd.Extends
output_string os "\n\t"
- goutput_implements env os cd.Implements
+ goutput_implements env os cd.Implements.Value
output_string os "\n{\n "
if contents then
diff --git a/src/Compiler/AbstractIL/ilread.fs b/src/Compiler/AbstractIL/ilread.fs
index 02696c53f0e..7ffa71feeee 100644
--- a/src/Compiler/AbstractIL/ilread.fs
+++ b/src/Compiler/AbstractIL/ilread.fs
@@ -2192,8 +2192,7 @@ and typeDefReader ctxtH : ILTypeDefStored =
let fdefs = seekReadFields ctxt (numTypars, hasLayout) fieldsIdx endFieldsIdx
let nested = seekReadNestedTypeDefs ctxt idx
- let impls, intImplsAttrs =
- seekReadInterfaceImpls ctxt mdv numTypars idx |> List.unzip
+ let impls = seekReadInterfaceImpls ctxt mdv numTypars idx
let mimpls = seekReadMethodImpls ctxt numTypars idx
let props = seekReadProperties ctxt numTypars idx
@@ -2206,7 +2205,6 @@ and typeDefReader ctxtH : ILTypeDefStored =
layout = layout,
nestedTypes = nested,
implements = impls,
- implementsCustomAttrs = Some intImplsAttrs,
extends = super,
methods = mdefs,
securityDeclsStored = ctxt.securityDeclsReader_TypeDef,
@@ -2240,19 +2238,26 @@ and seekReadNestedTypeDefs (ctxt: ILMetadataReader) tidx =
|])
and seekReadInterfaceImpls (ctxt: ILMetadataReader) mdv numTypars tidx =
- seekReadIndexedRows (
- ctxt.getNumRows TableNames.InterfaceImpl,
- id,
- id,
- (fun idx ->
- let mutable addr = ctxt.rowAddr TableNames.InterfaceImpl idx
- let _tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
- simpleIndexCompare tidx _tidx),
- isSorted ctxt TableNames.InterfaceImpl,
- (fun idx ->
- let intfIdx = seekReadInterfaceIdx ctxt mdv idx
- seekReadTypeDefOrRef ctxt numTypars AsObject [] intfIdx, (ctxt.customAttrsReader_InterfaceImpl, idx))
- )
+ InterruptibleLazy(fun () ->
+ seekReadIndexedRows (
+ ctxt.getNumRows TableNames.InterfaceImpl,
+ id,
+ id,
+ (fun idx ->
+ let mutable addr = ctxt.rowAddr TableNames.InterfaceImpl idx
+ let _tidx = seekReadUntaggedIdx TableNames.TypeDef ctxt mdv &addr
+ simpleIndexCompare tidx _tidx),
+ isSorted ctxt TableNames.InterfaceImpl,
+ (fun idx ->
+ let intfIdx = seekReadInterfaceIdx ctxt mdv idx
+ let ilType = seekReadTypeDefOrRef ctxt numTypars AsObject [] intfIdx
+
+ {
+ Idx = idx
+ Type = ilType
+ CustomAttrsStored = ctxt.customAttrsReader_InterfaceImpl
+ })
+ ))
and seekReadGenericParams ctxt numTypars (a, b) : ILGenericParameterDefs =
ctxt.seekReadGenericParams (GenericParamsIdx(numTypars, a, b))
diff --git a/src/Compiler/AbstractIL/ilreflect.fs b/src/Compiler/AbstractIL/ilreflect.fs
index 9b0b7eddb9e..2a65eb8679b 100644
--- a/src/Compiler/AbstractIL/ilreflect.fs
+++ b/src/Compiler/AbstractIL/ilreflect.fs
@@ -2178,7 +2178,8 @@ let rec buildTypeDefPass2 cenv nesting emEnv (tdef: ILTypeDef) =
let typB = envGetTypB emEnv tref
let emEnv = envPushTyvars emEnv (getGenericArgumentsOfType typB)
// add interface impls
- tdef.Implements
+ tdef.Implements.Value
+ |> List.map _.Type
|> convTypes cenv emEnv
|> List.iter (fun implT -> typB.AddInterfaceImplementationAndLog implT)
// add methods, properties
@@ -2339,7 +2340,8 @@ let createTypeRef (visited: Dictionary<_, _>, created: Dictionary<_, _>) emEnv t
if verbose2 then
dprintf "buildTypeDefPass4: Creating Interface Chain of %s\n" tdef.Name
- tdef.Implements |> List.iter (traverseType CollectTypes.All)
+ tdef.Implements.Value
+ |> List.iter (fun x -> traverseType CollectTypes.All x.Type)
if verbose2 then
dprintf "buildTypeDefPass4: Do value types in fields of %s\n" tdef.Name
diff --git a/src/Compiler/AbstractIL/ilwrite.fs b/src/Compiler/AbstractIL/ilwrite.fs
index 832aa1c2810..3cbdd3c752b 100644
--- a/src/Compiler/AbstractIL/ilwrite.fs
+++ b/src/Compiler/AbstractIL/ilwrite.fs
@@ -1323,7 +1323,7 @@ and GenTypeDefPass2 pidx enc cenv (tdef: ILTypeDef) =
// Now generate or assign index numbers for tables referenced by the maps.
// Don't yet generate contents of these tables - leave that to pass3, as
// code may need to embed these entries.
- cenv.implementsIdxs[tidx] <- tdef.Implements |> List.map (GenImplementsPass2 cenv env tidx)
+ cenv.implementsIdxs[tidx] <- tdef.Implements.Value |> List.map (fun x -> GenImplementsPass2 cenv env tidx x.Type)
tdef.Fields.AsList() |> List.iter (GenFieldDefPass2 tdef cenv tidx)
tdef.Methods |> Seq.iter (GenMethodDefPass2 tdef cenv tidx)
@@ -2875,12 +2875,9 @@ let rec GenTypeDefPass3 enc cenv (tdef: ILTypeDef) =
let env = envForTypeDef tdef
let tidx = GetIdxForTypeDef cenv (TdKey(enc, tdef.Name))
- match tdef.ImplementsCustomAttrs with
- | None -> ()
- | Some attrList ->
- attrList
- |> List.zip cenv.implementsIdxs[tidx]
- |> List.iter (fun (impIdx,(attrs,metadataIdx)) -> GenCustomAttrsPass3Or4 cenv (hca_InterfaceImpl,impIdx) (attrs.GetCustomAttrs metadataIdx))
+ tdef.Implements.Value
+ |> List.zip cenv.implementsIdxs[tidx]
+ |> List.iter (fun (impIdx, impl) -> GenCustomAttrsPass3Or4 cenv (hca_InterfaceImpl,impIdx) impl.CustomAttrs)
tdef.Properties.AsList() |> List.iter (GenPropertyPass3 cenv env)
tdef.Events.AsList() |> List.iter (GenEventPass3 cenv env)
diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs
index 96d3bb2b28d..e739169ea9c 100644
--- a/src/Compiler/Checking/CheckDeclarations.fs
+++ b/src/Compiler/Checking/CheckDeclarations.fs
@@ -431,7 +431,7 @@ module TcRecdUnionAndEnumDeclarations =
let TcFieldDecl (cenv: cenv) env parent isIncrClass tpenv (isStatic, synAttrs, id: Ident, nameGenerated, ty, isMutable, xmldoc, vis) =
let g = cenv.g
let m = id.idRange
- let attrs, _ = TcAttributesWithPossibleTargets false cenv env AttributeTargets.FieldDecl synAttrs
+ let attrs, _ = TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv env AttributeTargets.FieldDecl synAttrs
let attrsForProperty, attrsForField = attrs |> List.partition (fun (attrTargets, _) -> (attrTargets &&& AttributeTargets.Property) <> enum 0)
let attrsForProperty = (List.map snd attrsForProperty)
@@ -455,7 +455,7 @@ module TcRecdUnionAndEnumDeclarations =
match parent with
| Parent tcref when useGenuineField tcref.Deref rfspec ->
// Recheck the attributes for errors if the definition only generates a field
- TcAttributesWithPossibleTargets false cenv env AttributeTargets.FieldDeclRestricted synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv env AttributeTargets.FieldDeclRestricted synAttrs |> ignore
| _ -> ()
rfspec
@@ -2909,9 +2909,9 @@ module EstablishTypeDefinitionCores =
if reportAttributeTargetsErrors then
if hasStructAttr then
- TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Struct synAttrs |> ignore
else
- TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Class synAttrs |> ignore
// Note: the table of union cases is initially empty
Construct.MakeUnionRepr []
@@ -2934,9 +2934,9 @@ module EstablishTypeDefinitionCores =
if reportAttributeTargetsErrors then
if hasStructAttr then
- TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Struct synAttrs |> ignore
else
- TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Class synAttrs |> ignore
// Note: the table of record fields is initially empty
TFSharpTyconRepr (Construct.NewEmptyFSharpTyconData TFSharpRecord)
@@ -2952,19 +2952,19 @@ module EstablishTypeDefinitionCores =
match kind with
| SynTypeDefnKind.Class ->
if reportAttributeTargetsErrors then
- TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Class synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Class synAttrs |> ignore
TFSharpClass
| SynTypeDefnKind.Interface ->
if reportAttributeTargetsErrors then
- TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Interface synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Interface synAttrs |> ignore
TFSharpInterface
| SynTypeDefnKind.Delegate _ ->
if reportAttributeTargetsErrors then
- TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Delegate synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Delegate synAttrs |> ignore
TFSharpDelegate (MakeSlotSig("Invoke", g.unit_ty, [], [], [], None))
| SynTypeDefnKind.Struct ->
if reportAttributeTargetsErrors then
- TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Struct synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Struct synAttrs |> ignore
TFSharpStruct
| _ -> error(InternalError("should have inferred tycon kind", m))
@@ -2973,7 +2973,7 @@ module EstablishTypeDefinitionCores =
| SynTypeDefnSimpleRepr.Enum _ ->
noCLIMutableAttributeCheck()
if reportAttributeTargetsErrors then
- TcAttributesWithPossibleTargets false cenv envinner AttributeTargets.Enum synAttrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.IgnoreMemberResoutionError cenv envinner AttributeTargets.Enum synAttrs |> ignore
TFSharpTyconRepr (Construct.NewEmptyFSharpTyconData TFSharpEnum)
// OK, now fill in the (partially computed) type representation
@@ -4035,7 +4035,7 @@ module EstablishTypeDefinitionCores =
// Phase 1B. Establish the kind of each type constructor
// Here we run InferTyconKind and record partial information about the kind of the type constructor.
// This means FSharpTyconKind is set, which means isSealedTy, isInterfaceTy etc. give accurate results.
- let withAttrs =
+ let withAttrs =
(envMutRecPrelim, withEnvs) ||> MutRecShapes.mapTyconsWithEnv (fun envForDecls (origInfo, tyconOpt) ->
let res =
match origInfo, tyconOpt with
@@ -5202,7 +5202,7 @@ let TcModuleOrNamespaceElementsMutRec (cenv: cenv) parent typeNames m envInitial
let mutRecDefnsChecked, envAfter = TcDeclarations.TcMutRecDefinitions cenv envInitial parent typeNames tpenv m scopem mutRecNSInfo mutRecDefns true
// Check the assembly attributes
- let attrs, _ = TcAttributesWithPossibleTargets false cenv envAfter AttributeTargets.Top synAttrs
+ let attrs, _ = TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv envAfter AttributeTargets.Top synAttrs
// Check the non-escaping condition as we build the list of module expressions on the way back up
let moduleContents = TcMutRecDefsFinish cenv mutRecDefnsChecked m
@@ -5279,7 +5279,7 @@ let rec TcModuleOrNamespaceElementNonMutRec (cenv: cenv) parent typeNames scopem
return! failwith "unreachable"
| SynModuleDecl.Attributes (Attributes synAttrs, _) ->
- let attrs, _ = TcAttributesWithPossibleTargets false cenv env AttributeTargets.Top synAttrs
+ let attrs, _ = TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv env AttributeTargets.Top synAttrs
return ([], [], attrs), env, env
| SynModuleDecl.HashDirective _ ->
diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs
index 98ae7580eba..615e4251893 100644
--- a/src/Compiler/Checking/Expressions/CheckExpressions.fs
+++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs
@@ -1010,6 +1010,13 @@ let TranslatePartialValReprInfo tps (PrelimValReprInfo (argsData, retData)) =
// Members
//-------------------------------------------------------------------------
+
+[]
+type TcCanFail =
+ | IgnoreMemberResoutionError
+ | IgnoreAllErrors
+ | ReportAllErrors
+
let TcAddNullnessToType (warn: bool) (cenv: cenv) (env: TcEnv) nullness innerTyC m =
let g = cenv.g
if g.langFeatureNullness then
@@ -4028,7 +4035,7 @@ let rec TcTyparConstraint ridx (cenv: cenv) newOk checkConstraints occ (env: TcE
| SynTypeConstraint.WhereTyparSupportsNull(tp, m) ->
TcSimpleTyparConstraint cenv env newOk tpenv tp m AddCxTypeUseSupportsNull
- | SynTypeConstraint.WhereTyparNotSupportsNull(tp, m) ->
+ | SynTypeConstraint.WhereTyparNotSupportsNull(tp, m, _) ->
if g.langFeatureNullness then
TcSimpleTyparConstraint cenv env newOk tpenv tp m AddCxTypeDefnNotSupportsNull
else
@@ -4472,7 +4479,7 @@ and TcTypeOrMeasure kindOpt (cenv: cenv) newOk checkConstraints occ (iwsam: Warn
errorR(Error(FSComp.SR.parsInvalidLiteralInType(), m))
NewErrorType (), tpenv
- | SynType.WithNull(innerTy, ambivalent, m) ->
+ | SynType.WithNull(innerTy, ambivalent, m, _) ->
let innerTyC, tpenv = TcTypeAndRecover cenv newOk checkConstraints occ WarnOnIWSAM.Yes env tpenv innerTy
let nullness = if ambivalent then KnownAmbivalentToNull else KnownWithNull
let tyWithNull = TcAddNullnessToType false cenv env nullness innerTyC m
@@ -7530,9 +7537,9 @@ and TcInterpolatedStringExpr cenv (overallTy: OverallTy) env m tpenv (parts: Syn
let concatenableExprs = if canLower then concatenable [] fillExprs parts else []
match concatenableExprs with
- | [p1; p2; p3; p4] -> mkStaticCall_String_Concat4 g m p1 p2 p3 p4, tpenv
- | [p1; p2; p3] -> mkStaticCall_String_Concat3 g m p1 p2 p3, tpenv
- | [p1; p2] -> mkStaticCall_String_Concat2 g m p1 p2, tpenv
+ | [p1; p2; p3; p4] -> TcPropagatingExprLeafThenConvert cenv overallTy g.string_ty env m (fun () -> mkStaticCall_String_Concat4 g m p1 p2 p3 p4, tpenv)
+ | [p1; p2; p3] -> TcPropagatingExprLeafThenConvert cenv overallTy g.string_ty env m (fun () -> mkStaticCall_String_Concat3 g m p1 p2 p3, tpenv)
+ | [p1; p2] -> TcPropagatingExprLeafThenConvert cenv overallTy g.string_ty env m (fun () -> mkStaticCall_String_Concat2 g m p1 p2, tpenv)
| [p1] -> p1, tpenv
| _ ->
@@ -10869,7 +10876,7 @@ and TcNormalizedBinding declKind (cenv: cenv) env tpenv overallTy safeThisValOpt
// For all but attributes positioned at the return value, disallow implicitly
// targeting the return value.
let tgtEx = if isRet then enum 0 else AttributeTargets.ReturnValue
- let attrs, _ = TcAttributesMaybeFailEx false cenv envinner tgt tgtEx attrs
+ let attrs, _ = TcAttributesMaybeFailEx TcCanFail.ReportAllErrors cenv envinner tgt tgtEx attrs
let attrs: Attrib list = attrs
if attrTgt = enum 0 && not (isNil attrs) then
for attr in attrs do
@@ -11131,7 +11138,7 @@ and TcAttributeTargetsOnLetBindings (cenv: cenv) env attrs overallPatTy overallE
else
AttributeTargets.ReturnValue ||| AttributeTargets.Field ||| AttributeTargets.Property
- TcAttributesWithPossibleTargets false cenv env attrTgt attrs |> ignore
+ TcAttributesWithPossibleTargets TcCanFail.ReportAllErrors cenv env attrTgt attrs |> ignore
and TcLiteral (cenv: cenv) overallTy env tpenv (attrs, synLiteralValExpr) =
@@ -11291,7 +11298,7 @@ and TcAttributeEx canFail (cenv: cenv) (env: TcEnv) attrTgt attrEx (synAttr: Syn
error(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElement(), mAttr))
match ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mAttr ad ty with
- | Exception _ when canFail -> [ ], true
+ | Exception _ when canFail = TcCanFail.IgnoreAllErrors || canFail = TcCanFail.IgnoreMemberResoutionError -> [ ], true
| res ->
let item = ForceRaise res
@@ -11396,11 +11403,11 @@ and TcAttributesMaybeFail canFail cenv env attrTgt synAttribs =
TcAttributesMaybeFailEx canFail cenv env attrTgt (enum 0) synAttribs
and TcAttributesCanFail cenv env attrTgt synAttribs =
- let attrs, didFail = TcAttributesMaybeFail true cenv env attrTgt synAttribs
+ let attrs, didFail = TcAttributesMaybeFail TcCanFail.IgnoreAllErrors cenv env attrTgt synAttribs
attrs, (fun () -> if didFail then TcAttributes cenv env attrTgt synAttribs else attrs)
and TcAttributes cenv env attrTgt synAttribs =
- TcAttributesMaybeFail false cenv env attrTgt synAttribs |> fst
+ TcAttributesMaybeFail TcCanFail.ReportAllErrors cenv env attrTgt synAttribs |> fst
//-------------------------------------------------------------------------
// TcLetBinding
diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fsi b/src/Compiler/Checking/Expressions/CheckExpressions.fsi
index 6612194d1a5..cccb19f8abf 100644
--- a/src/Compiler/Checking/Expressions/CheckExpressions.fsi
+++ b/src/Compiler/Checking/Expressions/CheckExpressions.fsi
@@ -345,6 +345,12 @@ type PostSpecialValsRecursiveBinding =
{ ValScheme: ValScheme
Binding: Binding }
+[]
+type TcCanFail =
+ | IgnoreMemberResoutionError
+ | IgnoreAllErrors
+ | ReportAllErrors
+
/// Represents a recursive binding after it has been both checked and generalized, but
/// before initialization recursion has been rewritten
type PreInitializationGraphEliminationBinding =
@@ -598,7 +604,7 @@ val TcAttributesCanFail:
/// Check a set of attributes which can only target specific elements
val TcAttributesWithPossibleTargets:
- canFail: bool ->
+ canFail: TcCanFail ->
cenv: TcFileState ->
env: TcEnv ->
attrTgt: AttributeTargets ->
diff --git a/src/Compiler/Checking/TypeHierarchy.fs b/src/Compiler/Checking/TypeHierarchy.fs
index 102f36908fe..0805fcaf09b 100644
--- a/src/Compiler/Checking/TypeHierarchy.fs
+++ b/src/Compiler/Checking/TypeHierarchy.fs
@@ -117,17 +117,16 @@ let GetImmediateInterfacesOfMetadataType g amap m skipUnref ty (tcref: TyconRef)
// succeeded with more reported. There are pathological corner cases where this
// doesn't apply: e.g. for mscorlib interfaces like IComparable, but we can always
// assume those are present.
- match tdef.ImplementsCustomAttrs with
- | Some attrsList when g.langFeatureNullness && g.checkNullness ->
- for (attrs,attrsIdx),intfTy in tdef.Implements |> List.zip attrsList do
- if skipUnref = SkipUnrefInterfaces.No || CanRescopeAndImportILType scoref amap m intfTy then
+ let checkNullness = g.langFeatureNullness && g.checkNullness
+ for {Idx = attrsIdx; Type = intfTy; CustomAttrsStored = attrs} in tdef.Implements.Value do
+ if skipUnref = SkipUnrefInterfaces.No || CanRescopeAndImportILType scoref amap m intfTy then
+ if checkNullness then
let typeAttrs = AttributesFromIL(attrsIdx,attrs)
let nullness = {DirectAttributes = typeAttrs; Fallback = FromClass typeAttrs}
RescopeAndImportILType scoref amap m tinst nullness intfTy
- | _ ->
- for intfTy in tdef.Implements do
- if skipUnref = SkipUnrefInterfaces.No || CanRescopeAndImportILType scoref amap m intfTy then
+ else
RescopeAndImportILTypeSkipNullness scoref amap m tinst intfTy
+
| FSharpOrArrayOrByrefOrTupleOrExnTypeMetadata ->
for intfTy in tcref.ImmediateInterfaceTypesOfFSharpTycon do
instType (mkInstForAppTy g ty) intfTy ]
diff --git a/src/Compiler/Checking/import.fs b/src/Compiler/Checking/import.fs
index 0f800e7bbd6..68e3512864b 100644
--- a/src/Compiler/Checking/import.fs
+++ b/src/Compiler/Checking/import.fs
@@ -273,12 +273,18 @@ For value types, a value is passed even though it is always 0
member this.Advance() = {Data = this.Data; Idx = this.Idx + 1}
+ let inline isSystemNullable (tspec:ILTypeSpec) =
+ match tspec.Name,tspec.Enclosing with
+ | "Nullable`1",["System"] -> true
+ | "System.Nullable`1",[] -> true
+ | _ -> false
+
let inline evaluateFirstOrderNullnessAndAdvance (ilt:ILType) (flags:NullableFlags) =
match ilt with
| ILType.Value tspec when tspec.GenericArgs.IsEmpty -> KnownWithoutNull, flags
// System.Nullable is special-cased in C# spec for nullness metadata.
// You CAN assign 'null' to it, and when boxed, it CAN be boxed to 'null'.
- | ILType.Value tspec when tspec.Name = "Nullable`1" && tspec.Enclosing = ["System"] -> KnownWithoutNull, flags
+ | ILType.Value tspec when isSystemNullable tspec -> KnownWithoutNull, flags
| ILType.Value _ -> KnownWithoutNull, flags.Advance()
| _ -> flags.GetNullness(), flags.Advance()
diff --git a/src/Compiler/CodeGen/EraseClosures.fs b/src/Compiler/CodeGen/EraseClosures.fs
index ed32d83b369..df2604717ed 100644
--- a/src/Compiler/CodeGen/EraseClosures.fs
+++ b/src/Compiler/CodeGen/EraseClosures.fs
@@ -572,8 +572,7 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo =
name = td.Name,
genericParams = td.GenericParams,
attributes = td.Attributes,
- implements = [],
- implementsCustomAttrs = None,
+ implements = emptyILInterfaceImpls,
nestedTypes = emptyILTypeDefs,
layout = ILTypeDefLayout.Auto,
extends = Some cenv.mkILTyFuncTy,
@@ -707,8 +706,7 @@ let rec convIlxClosureDef cenv encl (td: ILTypeDef) clo =
name = td.Name,
genericParams = td.GenericParams,
attributes = td.Attributes,
- implements = [],
- implementsCustomAttrs = None,
+ implements = emptyILInterfaceImpls,
layout = ILTypeDefLayout.Auto,
nestedTypes = emptyILTypeDefs,
extends = Some nowEnvParentClass,
diff --git a/src/Compiler/CodeGen/EraseUnions.fs b/src/Compiler/CodeGen/EraseUnions.fs
index 88336c057b2..79788107475 100644
--- a/src/Compiler/CodeGen/EraseUnions.fs
+++ b/src/Compiler/CodeGen/EraseUnions.fs
@@ -1571,8 +1571,7 @@ let mkClassUnionDef
genericParams = td.GenericParams,
attributes = enum 0,
layout = ILTypeDefLayout.Auto,
- implements = [],
- implementsCustomAttrs = None,
+ implements = emptyILInterfaceImpls,
extends = Some g.ilg.typ_Object,
methods = emptyILMethods,
securityDecls = emptyILSecurityDecls,
diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs
index 6758b6dcd94..82572ea888a 100644
--- a/src/Compiler/CodeGen/IlxGen.fs
+++ b/src/Compiler/CodeGen/IlxGen.fs
@@ -2227,7 +2227,8 @@ type AnonTypeGenerationTable() =
let ilInterfaceTys =
[
- for intfTy, _, _ in tcaug.tcaug_interfaces -> GenType cenv m (TypeReprEnv.Empty.ForTypars tps) intfTy
+ for intfTy, _, _ in tcaug.tcaug_interfaces ->
+ GenType cenv m (TypeReprEnv.Empty.ForTypars tps) intfTy |> InterfaceImpl.Create
]
let ilTypeDef =
@@ -6023,7 +6024,8 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel
let interfaceTys =
GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g cenv.amap m templateStructTy
- let ilInterfaceTys = List.map (GenType cenv m eenvinner.tyenv) interfaceTys
+ let ilInterfaceTys =
+ List.map (GenType cenv m eenvinner.tyenv >> InterfaceImpl.Create) interfaceTys
let super = g.iltyp_ValueType
@@ -6254,8 +6256,7 @@ and GenStructStateMachine cenv cgbuf eenvouter (res: LoweredStateMachine) sequel
methods = mkILMethods mdefs,
methodImpls = mkILMethodImpls mimpls,
nestedTypes = emptyILTypeDefs,
- implements = ilInterfaceTys,
- implementsCustomAttrs = None,
+ implements = InterruptibleLazy.FromValue(ilInterfaceTys),
extends = Some super,
additionalFlags = ILTypeDefAdditionalFlags.None,
securityDecls = emptyILSecurityDecls
@@ -6381,7 +6382,8 @@ and GenObjectExpr cenv cgbuf eenvouter objExpr (baseType, baseValOpt, basecall,
let mimpls = mimpls |> List.choose id // choose the ones that actually have method impls
let interfaceTys =
- interfaceImpls |> List.map (fst >> GenType cenv m eenvinner.tyenv)
+ interfaceImpls
+ |> List.map (fst >> GenType cenv m eenvinner.tyenv >> InterfaceImpl.Create)
let super =
(if isInterfaceTy g baseType then
@@ -6390,7 +6392,11 @@ and GenObjectExpr cenv cgbuf eenvouter objExpr (baseType, baseValOpt, basecall,
ilCloRetTy)
let interfaceTys =
- interfaceTys @ (if isInterfaceTy g baseType then [ ilCloRetTy ] else [])
+ interfaceTys
+ @ (if isInterfaceTy g baseType then
+ [ InterfaceImpl.Create(ilCloRetTy) ]
+ else
+ [])
let cloTypeDefs =
GenClosureTypeDefs
@@ -6688,8 +6694,7 @@ and GenClosureTypeDefs
methods = mkILMethods mdefs,
methodImpls = mkILMethodImpls mimpls,
nestedTypes = emptyILTypeDefs,
- implements = ilIntfTys,
- implementsCustomAttrs = None,
+ implements = InterruptibleLazy.FromValue(ilIntfTys),
extends = Some ext,
additionalFlags = ILTypeDefAdditionalFlags.None,
securityDecls = emptyILSecurityDecls
@@ -10770,23 +10775,20 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option
let ilThisTy = GenType cenv m eenvinner.tyenv thisTy
let tref = ilThisTy.TypeRef
let ilGenParams = GenGenericParams cenv eenvinner tycon.TyparsNoRange
+ let checkNullness = g.langFeatureNullness && g.checkNullness
let ilIntfTys =
tycon.ImmediateInterfaceTypesOfFSharpTycon
- |> List.map (GenType cenv m eenvinner.tyenv)
-
- let ilIntCustomAttrs =
- if g.langFeatureNullness && g.checkNullness && not (isNil ilIntfTys) then
- tycon.ImmediateInterfaceTypesOfFSharpTycon
- |> List.map (
- GenAdditionalAttributesForTy g
- >> mkILCustomAttrs
- >> ILAttributesStored.Given
- >> (fun x -> x, 0)
- )
- |> Some
- else
- None
+ |> List.map (fun x ->
+ let ilType = GenType cenv m eenvinner.tyenv x
+
+ let customAttrs =
+ if checkNullness then
+ GenAdditionalAttributesForTy g x |> mkILCustomAttrs |> ILAttributesStored.Given
+ else
+ emptyILCustomAttrsStored
+
+ InterfaceImpl.Create(ilType, customAttrs))
let ilTypeName = tref.Name
@@ -11447,11 +11449,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option
.WithSerializable(isSerializable)
.WithAbstract(isAbstract)
.WithImport(isComInteropTy g thisTy)
- .With(
- methodImpls = mkILMethodImpls methodImpls,
- newAdditionalFlags = additionalFlags,
- implementsCustomAttrs = ilIntCustomAttrs
- )
+ .With(methodImpls = mkILMethodImpls methodImpls, newAdditionalFlags = additionalFlags)
let tdLayout, tdEncoding =
match TryFindFSharpAttribute g g.attrib_StructLayoutAttribute tycon.Attribs with
@@ -11613,8 +11611,7 @@ and GenTypeDef cenv mgbuf lazyInitInfo eenv m (tycon: Tycon) : ILTypeRef option
methods = mkILMethods ilMethods,
methodImpls = mkILMethodImpls methodImpls,
nestedTypes = emptyILTypeDefs,
- implements = ilIntfTys,
- implementsCustomAttrs = None,
+ implements = InterruptibleLazy.FromValue(ilIntfTys),
extends =
Some(
if tycon.IsStructOrEnumTycon then
@@ -11837,7 +11834,7 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) : ILTypeRef option =
let interfaces =
exnc.ImmediateInterfaceTypesOfFSharpTycon
- |> List.map (GenType cenv m eenv.tyenv)
+ |> List.map (GenType cenv m eenv.tyenv >> InterfaceImpl.Create)
let tdef =
mkILGenericClass (
diff --git a/src/Compiler/CodeGen/IlxGenSupport.fs b/src/Compiler/CodeGen/IlxGenSupport.fs
index 073b4473ea9..0e163db4069 100644
--- a/src/Compiler/CodeGen/IlxGenSupport.fs
+++ b/src/Compiler/CodeGen/IlxGenSupport.fs
@@ -46,7 +46,7 @@ let mkLocalPrivateAttributeWithDefaultConstructor (g: TcGlobals, name: string) =
ILTypeDefAccess.Private,
ILGenericParameterDefs.Empty,
g.ilg.typ_Attribute,
- ILTypes.Empty,
+ [],
ilMethods,
emptyILFields,
emptyILTypeDefs,
@@ -140,7 +140,7 @@ let mkLocalPrivateAttributeWithPropertyConstructors
ILTypeDefAccess.Private,
ILGenericParameterDefs.Empty,
g.ilg.typ_Attribute,
- ILTypes.Empty,
+ [],
mkILMethods (
ilCtorDef
:: (ilElements |> List.fold (fun acc (_, getter, _, _) -> getter @ acc) [])
@@ -205,7 +205,7 @@ let mkLocalPrivateAttributeWithByteAndByteArrayConstructors (g: TcGlobals, name:
ILTypeDefAccess.Private,
ILGenericParameterDefs.Empty,
g.ilg.typ_Attribute,
- ILTypes.Empty,
+ [],
mkILMethods ([ ilScalarCtorDef; ilArrayCtorDef ]),
mkILFields [ fieldDef ],
emptyILTypeDefs,
@@ -233,7 +233,7 @@ let mkLocalPrivateInt32Enum (g: TcGlobals, tref: ILTypeRef, values: (string * in
ILTypeDefAccess.Private,
ILGenericParameterDefs.Empty,
g.ilg.typ_Enum,
- ILTypes.Empty,
+ [],
mkILMethods [],
mkILFields enumFields,
emptyILTypeDefs,
diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs
index c73b8e5d197..1c50ca26781 100644
--- a/src/Compiler/Driver/CompilerDiagnostics.fs
+++ b/src/Compiler/Driver/CompilerDiagnostics.fs
@@ -24,7 +24,6 @@ open FSharp.Compiler.ConstraintSolver
open FSharp.Compiler.DiagnosticMessage
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.DiagnosticsLogger
-open FSharp.Compiler.Features
open FSharp.Compiler.Infos
open FSharp.Compiler.IO
open FSharp.Compiler.Lexhelp
@@ -2300,13 +2299,17 @@ type PhasedDiagnostic with
// Scoped #nowarn pragmas
/// Build an DiagnosticsLogger that delegates to another DiagnosticsLogger but filters warnings turned off by the given pragma declarations
+//
+// NOTE: we allow a flag to turn of strict file checking. This is because file names sometimes don't match due to use of
+// #line directives, e.g. for pars.fs/pars.fsy. In this case we just test by line number - in most cases this is sufficient
+// because we install a filtering error handler on a file-by-file basis for parsing and type-checking.
+// However this is indicative of a more systematic problem where source-line
+// sensitive operations (lexfilter and warning filtering) do not always
+// interact well with #line directives.
type DiagnosticsLoggerFilteringByScopedPragmas
- (langVersion: LanguageVersion, scopedPragmas, diagnosticOptions: FSharpDiagnosticOptions, diagnosticsLogger: DiagnosticsLogger) =
+ (checkFile, scopedPragmas, diagnosticOptions: FSharpDiagnosticOptions, diagnosticsLogger: DiagnosticsLogger) =
inherit DiagnosticsLogger("DiagnosticsLoggerFilteringByScopedPragmas")
- let needCompatibilityWithEarlierInconsistentInteraction =
- not (langVersion.SupportsFeature LanguageFeature.ConsistentNowarnLineDirectiveInteraction)
-
let mutable realErrorPresent = false
override _.DiagnosticSink(diagnostic: PhasedDiagnostic, severity) =
@@ -2320,10 +2323,12 @@ type DiagnosticsLoggerFilteringByScopedPragmas
match diagnostic.Range with
| Some m ->
scopedPragmas
- |> List.exists (fun (ScopedPragma.WarningOff(pragmaRange, warningNumFromPragma)) ->
+ |> List.exists (fun pragma ->
+ let (ScopedPragma.WarningOff(pragmaRange, warningNumFromPragma)) = pragma
+
warningNum = warningNumFromPragma
- && (needCompatibilityWithEarlierInconsistentInteraction
- || m.FileIndex = pragmaRange.FileIndex && posGeq m.Start pragmaRange.Start))
+ && (not checkFile || m.FileIndex = pragmaRange.FileIndex)
+ && posGeq m.Start pragmaRange.Start)
|> not
| None -> true
@@ -2339,5 +2344,5 @@ type DiagnosticsLoggerFilteringByScopedPragmas
override _.CheckForRealErrorsIgnoringWarnings = realErrorPresent
-let GetDiagnosticsLoggerFilteringByScopedPragmas (langVersion, scopedPragmas, diagnosticOptions, diagnosticsLogger) =
- DiagnosticsLoggerFilteringByScopedPragmas(langVersion, scopedPragmas, diagnosticOptions, diagnosticsLogger) :> DiagnosticsLogger
+let GetDiagnosticsLoggerFilteringByScopedPragmas (checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) =
+ DiagnosticsLoggerFilteringByScopedPragmas(checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) :> DiagnosticsLogger
diff --git a/src/Compiler/Driver/CompilerDiagnostics.fsi b/src/Compiler/Driver/CompilerDiagnostics.fsi
index 7c5acef17d4..6139da434cf 100644
--- a/src/Compiler/Driver/CompilerDiagnostics.fsi
+++ b/src/Compiler/Driver/CompilerDiagnostics.fsi
@@ -7,7 +7,6 @@ open System.Text
open FSharp.Compiler.CompilerConfig
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.DiagnosticsLogger
-open FSharp.Compiler.Features
open FSharp.Compiler.Syntax
open FSharp.Compiler.Text
@@ -85,7 +84,7 @@ type PhasedDiagnostic with
/// Get a diagnostics logger that filters the reporting of warnings based on scoped pragma information
val GetDiagnosticsLoggerFilteringByScopedPragmas:
- langVersion: LanguageVersion *
+ checkFile: bool *
scopedPragmas: ScopedPragma list *
diagnosticOptions: FSharpDiagnosticOptions *
diagnosticsLogger: DiagnosticsLogger ->
diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs
index d5d18d79651..a6804bfe746 100644
--- a/src/Compiler/Driver/ParseAndCheckInputs.fs
+++ b/src/Compiler/Driver/ParseAndCheckInputs.fs
@@ -511,7 +511,7 @@ let ParseInput
finally
// OK, now commit the errors, since the ScopedPragmas will (hopefully) have been scraped
let filteringDiagnosticsLogger =
- GetDiagnosticsLoggerFilteringByScopedPragmas(lexbuf.LanguageVersion, scopedPragmas, diagnosticOptions, diagnosticsLogger)
+ GetDiagnosticsLoggerFilteringByScopedPragmas(false, scopedPragmas, diagnosticOptions, diagnosticsLogger)
delayLogger.CommitDelayedDiagnostics filteringDiagnosticsLogger
@@ -1429,7 +1429,7 @@ let CheckOneInput
// Within a file, equip loggers to locally filter w.r.t. scope pragmas in each input
let DiagnosticsLoggerForInput (tcConfig: TcConfig, input: ParsedInput, oldLogger) =
- GetDiagnosticsLoggerFilteringByScopedPragmas(tcConfig.langVersion, input.ScopedPragmas, tcConfig.diagnosticsOptions, oldLogger)
+ GetDiagnosticsLoggerFilteringByScopedPragmas(false, input.ScopedPragmas, tcConfig.diagnosticsOptions, oldLogger)
/// Typecheck a single file (or interactive entry into F# Interactive)
let CheckOneInputEntry (ctok, checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt) tcState input =
diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs
index 9dccdec826d..ac4ee179538 100644
--- a/src/Compiler/Driver/fsc.fs
+++ b/src/Compiler/Driver/fsc.fs
@@ -745,7 +745,7 @@ let main2
yield! pragmas
]
- GetDiagnosticsLoggerFilteringByScopedPragmas(tcConfig.langVersion, scopedPragmas, tcConfig.diagnosticsOptions, oldLogger)
+ GetDiagnosticsLoggerFilteringByScopedPragmas(true, scopedPragmas, tcConfig.diagnosticsOptions, oldLogger)
SetThreadDiagnosticsLoggerNoUnwind diagnosticsLogger
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index 2e391fa5515..b5a50afc7c0 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -1783,5 +1783,4 @@ featureEmptyBodiedComputationExpressions,"Support for computation expressions wi
featureAllowAccessModifiersToAutoPropertiesGettersAndSetters,"Allow access modifiers to auto properties getters and setters"
3871,tcAccessModifiersNotAllowedInSRTPConstraint,"Access modifiers cannot be applied to an SRTP constraint."
featureAllowObjectExpressionWithoutOverrides,"Allow object expressions without overrides"
-3872,tcPartialActivePattern,"Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."
-featureConsistentNowarnLineDirectiveInteraction,"The interaction between #nowarn and #line is now consistent."
+3872,tcPartialActivePattern,"Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."
\ No newline at end of file
diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs
index 530d0e5f2ba..5c311237594 100644
--- a/src/Compiler/Facilities/LanguageFeatures.fs
+++ b/src/Compiler/Facilities/LanguageFeatures.fs
@@ -94,7 +94,6 @@ type LanguageFeature =
| ParsedHashDirectiveArgumentNonQuotes
| EmptyBodiedComputationExpressions
| AllowObjectExpressionWithoutOverrides
- | ConsistentNowarnLineDirectiveInteraction
/// LanguageVersion management
type LanguageVersion(versionText) =
@@ -214,7 +213,6 @@ type LanguageVersion(versionText) =
LanguageFeature.ParsedHashDirectiveArgumentNonQuotes, languageVersion90
LanguageFeature.EmptyBodiedComputationExpressions, languageVersion90
LanguageFeature.EnforceAttributeTargets, languageVersion90
- LanguageFeature.ConsistentNowarnLineDirectiveInteraction, languageVersion90
// F# preview
LanguageFeature.UnmanagedConstraintCsharpInterop, previewVersion // not enabled because: https://github.com/dotnet/fsharp/issues/17509
@@ -377,7 +375,6 @@ type LanguageVersion(versionText) =
| LanguageFeature.ParsedHashDirectiveArgumentNonQuotes -> FSComp.SR.featureParsedHashDirectiveArgumentNonString ()
| LanguageFeature.EmptyBodiedComputationExpressions -> FSComp.SR.featureEmptyBodiedComputationExpressions ()
| LanguageFeature.AllowObjectExpressionWithoutOverrides -> FSComp.SR.featureAllowObjectExpressionWithoutOverrides ()
- | LanguageFeature.ConsistentNowarnLineDirectiveInteraction -> FSComp.SR.featureConsistentNowarnLineDirectiveInteraction ()
/// Get a version string associated with the given feature.
static member GetFeatureVersionString feature =
diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi
index 4ae722c7f60..7408300b943 100644
--- a/src/Compiler/Facilities/LanguageFeatures.fsi
+++ b/src/Compiler/Facilities/LanguageFeatures.fsi
@@ -85,7 +85,6 @@ type LanguageFeature =
| ParsedHashDirectiveArgumentNonQuotes
| EmptyBodiedComputationExpressions
| AllowObjectExpressionWithoutOverrides
- | ConsistentNowarnLineDirectiveInteraction
/// LanguageVersion management
type LanguageVersion =
diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs
index 832327656d9..10991bb59f7 100644
--- a/src/Compiler/Interactive/fsi.fs
+++ b/src/Compiler/Interactive/fsi.fs
@@ -1675,34 +1675,6 @@ let internal mkBoundValueTypedImpl tcGlobals m moduleName name ty =
let qname = QualifiedNameOfFile.QualifiedNameOfFile(Ident(moduleName, m))
entity, v, CheckedImplFile.CheckedImplFile(qname, [], mty, contents, false, false, StampMap.Empty, Map.empty)
-let scriptingSymbolsPath =
- let createDirectory (path: string) =
- lazy
- try
- if not (Directory.Exists(path)) then
- Directory.CreateDirectory(path) |> ignore
-
- path
- with _ ->
- path
-
- createDirectory (Path.Combine(Path.GetTempPath(), $"{DateTime.Now:s}-{Guid.NewGuid():n}".Replace(':', '-')))
-
-let deleteScriptingSymbols () =
- try
-#if !DEBUG
- if scriptingSymbolsPath.IsValueCreated then
- if Directory.Exists(scriptingSymbolsPath.Value) then
- Directory.Delete(scriptingSymbolsPath.Value, true)
-#else
- ()
-#endif
- with _ ->
- ()
-
-AppDomain.CurrentDomain.ProcessExit
-|> Event.add (fun _ -> deleteScriptingSymbols ())
-
let dynamicCcuName = "FSI-ASSEMBLY"
/// Encapsulates the coordination of the typechecking, optimization and code generation
@@ -1764,6 +1736,33 @@ type internal FsiDynamicCompiler
let reportedAssemblies = Dictionary()
+ let scriptingSymbolsPath =
+ let createDirectory (path: string) =
+ try
+ if not (Directory.Exists(path)) then
+ Directory.CreateDirectory(path) |> ignore
+
+ path
+ with _ ->
+ path
+
+ createDirectory (Path.Combine(Path.GetTempPath(), $"{DateTime.Now:s}-{Guid.NewGuid():n}".Replace(':', '-')))
+
+ let deleteScriptingSymbols () =
+ try
+#if !DEBUG
+ if Directory.Exists(scriptingSymbolsPath) then
+ Directory.Delete(scriptingSymbolsPath, true)
+#else
+ ()
+#endif
+ with _ ->
+ ()
+
+ do
+ AppDomain.CurrentDomain.ProcessExit
+ |> Event.add (fun _ -> deleteScriptingSymbols ())
+
/// Add attributes
let CreateModuleFragment (tcConfigB: TcConfigBuilder, dynamicCcuName, codegenResults) =
if progress then
@@ -1841,7 +1840,7 @@ type internal FsiDynamicCompiler
{
ilg = tcGlobals.ilg
outfile = $"{multiAssemblyName}-{dynamicAssemblyId}.dll"
- pdbfile = Some(Path.Combine(scriptingSymbolsPath.Value, $"{multiAssemblyName}-{dynamicAssemblyId}.pdb"))
+ pdbfile = Some(Path.Combine(scriptingSymbolsPath, $"{multiAssemblyName}-{dynamicAssemblyId}.pdb"))
emitTailcalls = tcConfig.emitTailcalls
deterministic = tcConfig.deterministic
portablePDB = true
diff --git a/src/Compiler/Optimize/LowerComputedCollections.fs b/src/Compiler/Optimize/LowerComputedCollections.fs
index 98b01086cc6..98101af36fe 100644
--- a/src/Compiler/Optimize/LowerComputedCollections.fs
+++ b/src/Compiler/Optimize/LowerComputedCollections.fs
@@ -373,60 +373,70 @@ module Array =
else any ilTy
/// Makes the equivalent of an inlined call to Array.map.
- let mkMap g m (mBody, _spFor, _spIn, mFor, mIn, spInWhile) srcArray srcIlTy destIlTy overallElemTy loopVal body =
- let len = mkLdlen g mIn srcArray
- let arrayTy = mkArrayType g overallElemTy
-
- /// (# "newarr !0" type ('T) count : 'T array #)
- let array =
- mkAsmExpr
- (
- [I_newarr (ILArrayShape.SingleDimensional, destIlTy)],
- [],
- [len],
- [arrayTy],
- m
- )
-
- let ldelem = mkIlInstr g I_ldelem (fun ilTy -> I_ldelem_any (ILArrayShape.SingleDimensional, ilTy)) srcIlTy
- let stelem = mkIlInstr g I_stelem (fun ilTy -> I_stelem_any (ILArrayShape.SingleDimensional, ilTy)) destIlTy
-
- let mapping =
- mkCompGenLetIn m (nameof array) arrayTy array (fun (_, array) ->
- mkCompGenLetMutableIn mFor "i" g.int32_ty (mkTypedZero g mIn g.int32_ty) (fun (iVal, i) ->
- let body =
- // Rebind the loop val to pull directly from the source array.
- let body = mkInvisibleLet mBody loopVal (mkAsmExpr ([ldelem], [], [srcArray; i], [loopVal.val_type], mBody)) body
-
- // destArray[i] <- body srcArray[i]
- let setArrSubI = mkAsmExpr ([stelem], [], [array; i; body], [], mIn)
-
- // i <- i + 1
- let incrI = mkValSet mIn (mkLocalValRef iVal) (mkAsmExpr ([AI_add], [], [i; mkTypedOne g mIn g.int32_ty], [g.int32_ty], mIn))
-
- mkSequential mIn setArrSubI incrI
-
- let guard = mkILAsmClt g mFor i (mkLdlen g mFor array)
+ let mkMap g m (mBody, _spFor, _spIn, mFor, mIn, spInWhile) srcArray srcIlTy destIlTy overallElemTy (loopVal: Val) body =
+ mkCompGenLetIn m (nameof srcArray) (tyOfExpr g srcArray) srcArray (fun (_, srcArray) ->
+ let len = mkLdlen g mIn srcArray
+ let arrayTy = mkArrayType g overallElemTy
+
+ /// (# "newarr !0" type ('T) count : 'T array #)
+ let array =
+ mkAsmExpr
+ (
+ [I_newarr (ILArrayShape.SingleDimensional, destIlTy)],
+ [],
+ [len],
+ [arrayTy],
+ m
+ )
- let loop =
- mkWhile
- g
- (
- spInWhile,
- NoSpecialWhileLoopMarker,
- guard,
- body,
- mIn
- )
+ let ldelem = mkIlInstr g I_ldelem (fun ilTy -> I_ldelem_any (ILArrayShape.SingleDimensional, ilTy)) srcIlTy
+ let stelem = mkIlInstr g I_stelem (fun ilTy -> I_stelem_any (ILArrayShape.SingleDimensional, ilTy)) destIlTy
- // while i < array.Length do done
- // array
- mkSequential m loop array
+ let mapping =
+ mkCompGenLetIn m (nameof array) arrayTy array (fun (_, array) ->
+ mkCompGenLetMutableIn mFor "i" g.int32_ty (mkTypedZero g mIn g.int32_ty) (fun (iVal, i) ->
+ let body =
+ // If the loop val is used in the loop body,
+ // rebind it to pull directly from the source array.
+ // Otherwise, don't bother reading from the source array at all.
+ let body =
+ let freeLocals = (freeInExpr CollectLocals body).FreeLocals
+
+ if freeLocals.Contains loopVal then
+ mkInvisibleLet mBody loopVal (mkAsmExpr ([ldelem], [], [srcArray; i], [loopVal.val_type], mBody)) body
+ else
+ body
+
+ // destArray[i] <- body srcArray[i]
+ let setArrSubI = mkAsmExpr ([stelem], [], [array; i; body], [], mIn)
+
+ // i <- i + 1
+ let incrI = mkValSet mIn (mkLocalValRef iVal) (mkAsmExpr ([AI_add], [], [i; mkTypedOne g mIn g.int32_ty], [g.int32_ty], mIn))
+
+ mkSequential mIn setArrSubI incrI
+
+ let guard = mkILAsmClt g mFor i (mkLdlen g mFor array)
+
+ let loop =
+ mkWhile
+ g
+ (
+ spInWhile,
+ NoSpecialWhileLoopMarker,
+ guard,
+ body,
+ mIn
+ )
+
+ // while i < array.Length do done
+ // array
+ mkSequential m loop array
+ )
)
- )
- // Add a debug point at the `for`, before anything gets evaluated.
- Expr.DebugPoint (DebugPointAtLeafExpr.Yes mFor, mapping)
+ // Add a debug point at the `for`, before anything gets evaluated.
+ Expr.DebugPoint (DebugPointAtLeafExpr.Yes mFor, mapping)
+ )
/// Whether to check for overflow when converting a value to a native int.
[]
@@ -558,6 +568,9 @@ let (|SingleYield|_|) g expr : Expr voption =
| Expr.Sequential (expr1, DebugPoints (body, debug), kind, m) ->
loop body (cont << fun body -> Expr.Sequential (expr1, debug body, kind, m))
+ | Expr.Match (debugPoint, mInput, decision, [|TTarget (boundVals, DebugPoints (SeqSingleton g body, debug), isStateVarFlags)|], mFull, exprType) ->
+ ValueSome (cont (Expr.Match (debugPoint, mInput, decision, [|TTarget (boundVals, debug body, isStateVarFlags)|], mFull, exprType)))
+
| SeqSingleton g body ->
ValueSome (cont body)
diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs
index 7951f3c9328..b7560b222c2 100644
--- a/src/Compiler/Service/IncrementalBuild.fs
+++ b/src/Compiler/Service/IncrementalBuild.fs
@@ -259,7 +259,7 @@ type BoundModel private (
IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBETypechecked fileName)
let capturingDiagnosticsLogger = CapturingDiagnosticsLogger("TypeCheck")
- let diagnosticsLogger = GetDiagnosticsLoggerFilteringByScopedPragmas(tcConfig.langVersion, input.ScopedPragmas, tcConfig.diagnosticsOptions, capturingDiagnosticsLogger)
+ let diagnosticsLogger = GetDiagnosticsLoggerFilteringByScopedPragmas(false, input.ScopedPragmas, tcConfig.diagnosticsOptions, capturingDiagnosticsLogger)
use _ = new CompilationGlobalsScope(diagnosticsLogger, BuildPhase.TypeCheck)
beforeFileChecked.Trigger fileName
diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs
index 621d89e4cca..e0957fe0140 100644
--- a/src/Compiler/Service/ServiceParseTreeWalk.fs
+++ b/src/Compiler/Service/ServiceParseTreeWalk.fs
@@ -838,7 +838,7 @@ module SyntaxTraversal =
| SynType.Fun(argType = ty1; returnType = ty2) -> [ ty1; ty2 ] |> List.tryPick (traverseSynType path)
| SynType.MeasurePower(ty, _, _)
| SynType.HashConstraint(ty, _)
- | SynType.WithNull(ty, _, _)
+ | SynType.WithNull(innerType = ty)
| SynType.WithGlobalConstraints(ty, _, _)
| SynType.Array(_, ty, _) -> traverseSynType path ty
| SynType.StaticConstantNamed(ty1, ty2, _)
diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs
index 64e7f282b33..0b3f0134545 100644
--- a/src/Compiler/Service/ServiceParsedInputOps.fs
+++ b/src/Compiler/Service/ServiceParsedInputOps.fs
@@ -647,7 +647,7 @@ module ParsedInput =
| SynTypeConstraint.WhereTyparIsReferenceType(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparIsUnmanaged(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparSupportsNull(t, _) -> walkTypar t
- | SynTypeConstraint.WhereTyparNotSupportsNull(t, _) -> walkTypar t
+ | SynTypeConstraint.WhereTyparNotSupportsNull(genericName = t) -> walkTypar t
| SynTypeConstraint.WhereTyparIsComparable(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparIsEquatable(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparSubtypeOfType(t, ty, _) -> walkTypar t |> Option.orElseWith (fun () -> walkType ty)
@@ -711,7 +711,7 @@ module ParsedInput =
| SynType.Array(_, t, _) -> walkType t
| SynType.Fun(argType = t1; returnType = t2) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
| SynType.WithGlobalConstraints(t, _, _) -> walkType t
- | SynType.WithNull(t, _, _)
+ | SynType.WithNull(innerType = t)
| SynType.HashConstraint(t, _) -> walkType t
| SynType.Or(t1, t2, _, _) -> walkType t1 |> Option.orElseWith (fun () -> walkType t2)
| SynType.MeasurePower(t, _, _) -> walkType t
@@ -1914,7 +1914,7 @@ module ParsedInput =
| SynTypeConstraint.WhereTyparIsReferenceType(t, _)
| SynTypeConstraint.WhereTyparIsUnmanaged(t, _)
| SynTypeConstraint.WhereTyparSupportsNull(t, _)
- | SynTypeConstraint.WhereTyparNotSupportsNull(t, _)
+ | SynTypeConstraint.WhereTyparNotSupportsNull(genericName = t)
| SynTypeConstraint.WhereTyparIsComparable(t, _)
| SynTypeConstraint.WhereTyparIsEquatable(t, _) -> walkTypar t
| SynTypeConstraint.WhereTyparDefaultsToType(t, ty, _)
@@ -1976,7 +1976,7 @@ module ParsedInput =
| SynType.Array(_, t, _)
| SynType.HashConstraint(t, _)
| SynType.MeasurePower(t, _, _)
- | SynType.WithNull(t, _, _)
+ | SynType.WithNull(innerType = t)
| SynType.Paren(t, _)
| SynType.SignatureParameter(usedType = t) -> walkType t
| SynType.Fun(argType = t1; returnType = t2)
diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs
index 735a6b241f1..e3acd1d4c6c 100644
--- a/src/Compiler/Service/TransparentCompiler.fs
+++ b/src/Compiler/Service/TransparentCompiler.fs
@@ -1303,12 +1303,7 @@ type internal TransparentCompiler
let diagnosticsLogger = errHandler.DiagnosticsLogger
let diagnosticsLogger =
- GetDiagnosticsLoggerFilteringByScopedPragmas(
- tcConfig.langVersion,
- input.ScopedPragmas,
- tcConfig.diagnosticsOptions,
- diagnosticsLogger
- )
+ GetDiagnosticsLoggerFilteringByScopedPragmas(false, input.ScopedPragmas, tcConfig.diagnosticsOptions, diagnosticsLogger)
use _ = new CompilationGlobalsScope(diagnosticsLogger, BuildPhase.TypeCheck)
diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs
index 50c81fdcc58..962188c2f21 100644
--- a/src/Compiler/SyntaxTree/SyntaxTree.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTree.fs
@@ -332,7 +332,7 @@ type SynTypeConstraint =
| WhereTyparSupportsNull of typar: SynTypar * range: range
- | WhereTyparNotSupportsNull of genericName: SynTypar * range: range
+ | WhereTyparNotSupportsNull of genericName: SynTypar * range: range * trivia: SynTypeConstraintWhereTyparNotSupportsNullTrivia
| WhereTyparIsComparable of typar: SynTypar * range: range
@@ -465,7 +465,7 @@ type SynType =
| StaticConstantNamed of ident: SynType * value: SynType * range: range
- | WithNull of innerType: SynType * ambivalent: bool * range: range
+ | WithNull of innerType: SynType * ambivalent: bool * range: range * trivia: SynTypeWithNullTrivia
| Paren of innerType: SynType * range: range
diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi
index 2cc6b14947a..f2c75d8dfac 100644
--- a/src/Compiler/SyntaxTree/SyntaxTree.fsi
+++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi
@@ -409,7 +409,10 @@ type SynTypeConstraint =
| WhereTyparSupportsNull of typar: SynTypar * range: range
/// F# syntax is 'typar : null
- | WhereTyparNotSupportsNull of genericName: SynTypar * range: range
+ | WhereTyparNotSupportsNull of
+ genericName: SynTypar *
+ range: range *
+ trivia: SynTypeConstraintWhereTyparNotSupportsNullTrivia
/// F# syntax is 'typar: comparison
| WhereTyparIsComparable of typar: SynTypar * range: range
@@ -527,7 +530,7 @@ type SynType =
/// F# syntax: ident=1 etc., used in static parameters to type providers
| StaticConstantNamed of ident: SynType * value: SynType * range: range
- | WithNull of innerType: SynType * ambivalent: bool * range: range
+ | WithNull of innerType: SynType * ambivalent: bool * range: range * trivia: SynTypeWithNullTrivia
| Paren of innerType: SynType * range: range
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
index f259746cfff..0932befd7c1 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs
@@ -404,6 +404,9 @@ type SynFieldTrivia =
[]
type SynTypeOrTrivia = { OrKeyword: range }
+[]
+type SynTypeWithNullTrivia = { BarRange: range }
+
[]
type SynBindingReturnInfoTrivia = { ColonRange: range option }
@@ -429,3 +432,6 @@ type SynMeasureConstantTrivia =
LessRange: range
GreaterRange: range
}
+
+[]
+type SynTypeConstraintWhereTyparNotSupportsNullTrivia = { ColonRange: range; NotRange: range }
diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
index 567586081f2..24bfc1b7a52 100644
--- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
+++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi
@@ -512,6 +512,14 @@ type SynTypeOrTrivia =
OrKeyword: range
}
+/// Represents additional information for SynType.WithNull
+[]
+type SynTypeWithNullTrivia =
+ {
+ /// The syntax range of the `|` token
+ BarRange: range
+ }
+
/// Represents additional information for SynBindingReturnInfo
[]
type SynBindingReturnInfoTrivia =
@@ -545,3 +553,14 @@ type SynTyparDeclTrivia =
type SynMeasureConstantTrivia =
{ LessRange: range
GreaterRange: range }
+
+/// Represents additional information for SynTypeConstraint.WhereTyparNotSupportsNull
+[]
+type SynTypeConstraintWhereTyparNotSupportsNullTrivia =
+ {
+ /// The syntax range of `:`
+ ColonRange: range
+
+ /// The syntax range of `not`
+ NotRange: range
+ }
diff --git a/src/Compiler/TypedTree/TcGlobals.fs b/src/Compiler/TypedTree/TcGlobals.fs
index c78933864be..2c065437f2b 100644
--- a/src/Compiler/TypedTree/TcGlobals.fs
+++ b/src/Compiler/TypedTree/TcGlobals.fs
@@ -193,9 +193,7 @@ type TcGlobals(
realsig: bool) =
let v_langFeatureNullness = langVersion.SupportsFeature LanguageFeature.NullnessChecking
-
- let v_renderNullness = checkNullness && v_langFeatureNullness
-
+
let v_knownWithNull =
if v_langFeatureNullness then KnownWithNull else KnownAmbivalentToNull
@@ -1113,8 +1111,6 @@ type TcGlobals(
member _.langFeatureNullness = v_langFeatureNullness
- member _.renderNullnessAnnotations = v_renderNullness
-
member _.knownWithNull = v_knownWithNull
member _.knownWithoutNull = v_knownWithoutNull
diff --git a/src/Compiler/TypedTree/TcGlobals.fsi b/src/Compiler/TypedTree/TcGlobals.fsi
index 83b390e299e..950d5217500 100644
--- a/src/Compiler/TypedTree/TcGlobals.fsi
+++ b/src/Compiler/TypedTree/TcGlobals.fsi
@@ -1055,8 +1055,6 @@ type internal TcGlobals =
member reference_equality_inner_vref: FSharp.Compiler.TypedTree.ValRef
- member renderNullnessAnnotations: bool
-
member reraise_info: IntrinsicValRef
member reraise_vref: FSharp.Compiler.TypedTree.ValRef
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs
index 60ab98e8c5f..333b29cd78f 100644
--- a/src/Compiler/TypedTree/TypedTreeOps.fs
+++ b/src/Compiler/TypedTree/TypedTreeOps.fs
@@ -8926,10 +8926,7 @@ let typarEnc _g (gtpsType, gtpsMethod) typar =
warning(InternalError("Typar not found during XmlDoc generation", typar.Range))
"``0"
-let nullnessEnc (g:TcGlobals) (nullness:Nullness) =
- if g.renderNullnessAnnotations then nullness.ToFsharpCodeString() else ""
-
-let rec typeEnc g (gtpsType, gtpsMethod) ty =
+let rec typeEnc g (gtpsType, gtpsMethod) ty =
let stripped = stripTyEqnsAndMeasureEqns g ty
match stripped with
| TType_forall _ ->
@@ -8943,26 +8940,26 @@ let rec typeEnc g (gtpsType, gtpsMethod) ty =
let ety = destNativePtrTy g ty
typeEnc g (gtpsType, gtpsMethod) ety + "*"
- | TType_app (_, _, nullness) when isArrayTy g ty ->
+ | TType_app (_, _, _nullness) when isArrayTy g ty ->
let tcref, tinst = destAppTy g ty
let rank = rankOfArrayTyconRef g tcref
let arraySuffix = "[" + String.concat ", " (List.replicate (rank-1) "0:") + "]"
- typeEnc g (gtpsType, gtpsMethod) (List.head tinst) + arraySuffix + nullnessEnc g nullness
+ typeEnc g (gtpsType, gtpsMethod) (List.head tinst) + arraySuffix
| TType_ucase (_, tinst)
| TType_app (_, tinst, _) ->
- let tyName,nullness =
+ let tyName =
let ty = stripTyEqnsAndMeasureEqns g ty
match ty with
- | TType_app (tcref, _tinst, nullness) ->
+ | TType_app (tcref, _tinst, _nullness) ->
// Generic type names are (name + "`" + digits) where name does not contain "`".
// In XML doc, when used in type instances, these do not use the ticks.
let path = Array.toList (fullMangledPathToTyconRef tcref) @ [tcref.CompiledName]
- textOfPath (List.map DemangleGenericTypeName path),nullness
+ textOfPath (List.map DemangleGenericTypeName path)
| _ ->
assert false
failwith "impossible"
- tyName + tyargsEnc g (gtpsType, gtpsMethod) tinst + nullnessEnc g nullness
+ tyName + tyargsEnc g (gtpsType, gtpsMethod) tinst
| TType_anon (anonInfo, tinst) ->
sprintf "%s%s" anonInfo.ILTypeRef.FullName (tyargsEnc g (gtpsType, gtpsMethod) tinst)
@@ -8973,11 +8970,11 @@ let rec typeEnc g (gtpsType, gtpsMethod) ty =
else
sprintf "System.Tuple%s"(tyargsEnc g (gtpsType, gtpsMethod) tys)
- | TType_fun (domainTy, rangeTy, nullness) ->
- "Microsoft.FSharp.Core.FSharpFunc" + tyargsEnc g (gtpsType, gtpsMethod) [domainTy; rangeTy] + nullnessEnc g nullness
+ | TType_fun (domainTy, rangeTy, _nullness) ->
+ "Microsoft.FSharp.Core.FSharpFunc" + tyargsEnc g (gtpsType, gtpsMethod) [domainTy; rangeTy]
- | TType_var (typar, nullness) ->
- typarEnc g (gtpsType, gtpsMethod) typar + nullnessEnc g nullness
+ | TType_var (typar, _nullness) ->
+ typarEnc g (gtpsType, gtpsMethod) typar
| TType_measure _ -> "?"
diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy
index 2588f9d128b..2794edf560e 100644
--- a/src/Compiler/pars.fsy
+++ b/src/Compiler/pars.fsy
@@ -2,7 +2,6 @@
%{
-#nowarn "64" // turn off warnings that type variables used in production annotations are instantiated to concrete type
#nowarn "1182" // generated code has lots of unused "parseState"
#nowarn "3261" // the generated code would need to properly annotate nulls, e.g. changing System.Object to `obj|null`
@@ -2652,8 +2651,9 @@ typeConstraint:
{ SynTypeConstraint.WhereTyparSupportsNull($1, lhs parseState) }
| typar COLON IDENT NULL
- { if $3 <> "not" then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier($3 + " (2)"))
- SynTypeConstraint.WhereTyparNotSupportsNull($1, lhs parseState) }
+ { if $3 <> "not" then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier($3 + " (2)"))
+ let trivia : SynTypeConstraintWhereTyparNotSupportsNullTrivia = { ColonRange = rhs parseState 2; NotRange = rhs parseState 3 }
+ SynTypeConstraint.WhereTyparNotSupportsNull($1, lhs parseState, trivia) }
| typar COLON LPAREN classMemberSpfn rparen
{ let tp = $1
@@ -3241,7 +3241,7 @@ cType:
SynType.App(SynType.LongIdent(SynLongIdent([ident("nativeptr", m)], [], [ Some(IdentTrivia.OriginalNotation "*") ])), None, [$1], [], None, true, m) }
| cType BAR_JUST_BEFORE_NULL NULL
- { SynType.WithNull($1, false, lhs parseState) }
+ { SynType.WithNull($1, false, lhs parseState, { BarRange = rhs parseState 2 }) }
| cType AMP
{ let m = lhs parseState
@@ -6193,7 +6193,7 @@ appTypeConPower:
appTypeCanBeNullable:
| appTypeWithoutNull BAR_JUST_BEFORE_NULL NULL
- { SynType.WithNull($1, false, lhs parseState) }
+ { SynType.WithNull($1, false, lhs parseState, { BarRange = rhs parseState 2 }) }
| appTypeWithoutNull
{ $1 }
diff --git a/src/Compiler/pppars.fsy b/src/Compiler/pppars.fsy
index 41cb41ff38a..cd27722a254 100644
--- a/src/Compiler/pppars.fsy
+++ b/src/Compiler/pppars.fsy
@@ -3,7 +3,6 @@
%{
open FSharp.Compiler.DiagnosticsLogger
-#nowarn "64" // turn off warnings that type variables used in production annotations are instantiated to concrete type
#nowarn "3261" // the generated code would need to properly annotate nulls, e.g. changing System.Object to `obj|null`
let dummy = IfdefId("DUMMY")
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index 39b41f3b382..2b1a9483def 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -307,11 +307,6 @@
Vyvolá upozornění, pokud je atribut TailCall použit u nerekurzivních funkcí.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
Průnik omezení u flexibilních typů
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index 402571c8a5a..a1b2532e4db 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -307,11 +307,6 @@
Löst Warnungen aus, wenn das Attribut "TailCall" für nicht rekursive Funktionen verwendet wird.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
Einschränkungsüberschneidung für flexible Typen
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index d3267a7425c..dd9cbb7fec6 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -307,11 +307,6 @@
Genera advertencias si el atributo 'TailCall' se usa en funciones no recursivas.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
Intersección de restricciones en tipos flexibles
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index f74bc4e3196..2cc92e5f4d5 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -307,11 +307,6 @@
Émet des avertissements si l’attribut « TailCall » est utilisé sur des fonctions non récursives.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
Intersection de contraintes sur les types flexibles
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index 3495d0c1659..5b5793c4841 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -307,11 +307,6 @@
Genera avvisi se l'attributo 'TailCall' viene utilizzato in funzioni non ricorsive.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
Intersezione di vincoli su tipi flessibili
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index a87915633be..d30efc74724 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -307,11 +307,6 @@
'TailCall' 属性が再帰関数以外で使用されている場合、警告が発せられます。
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
フレキシブル型の制約積集合
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index 70a64e75a53..c9359c56807 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -307,11 +307,6 @@
'TailCall' 특성이 비 재귀 함수에 사용되는 경우 경고를 발생합니다.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
유연한 형식의 제약 조건 교집합
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index 31b8d2a6215..933379b9f7b 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -307,11 +307,6 @@
Zgłasza ostrzeżenia, jeśli atrybut „TailCall” jest używany w funkcjach niekursywnych.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
Przecięcie ograniczenia dla typów elastycznych
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index c49d815ca06..e6480e13025 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -307,11 +307,6 @@
Gera avisos se o atributo "TailCall" for usado em funções não recursivas.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
Interseção de restrição em tipos flexíveis
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index 495089d8c53..61c03885917 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -307,11 +307,6 @@
Выдает предупреждения, если атрибут TailCall используется в нерекурсивных функциях.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
Пересечение ограничений на гибких типах
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index 93dfdedb2bd..09c113ee3f1 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -307,11 +307,6 @@
'TailCall' özniteliği özyinelemeli olmayan işlevlerde kullanılıyorsa uyarılar oluşturur.
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
Esnek türlerde kısıtlama kesişimi
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index 54f6b088094..d9573b5bed2 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -307,11 +307,6 @@
如果在非递归函数上使用“TailCall”属性,则引发警告。
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
灵活类型的约束交集
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index df3a706ae28..1a6c3de6ccf 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -307,11 +307,6 @@
如果 'TailCall' 屬性用於非遞迴函數,則引發警告。
-
-
- The interaction between #nowarn and #line is now consistent.
-
-
彈性類型上的條件約束交集
diff --git a/src/fsc/fscAnyCpuProject/fscAnyCpu.fsproj b/src/fsc/fscAnyCpuProject/fscAnyCpu.fsproj
index 3fac5305cae..a813df67d88 100644
--- a/src/fsc/fscAnyCpuProject/fscAnyCpu.fsproj
+++ b/src/fsc/fscAnyCpuProject/fscAnyCpu.fsproj
@@ -5,7 +5,7 @@
net472
anycpu
- true
+ true
diff --git a/src/fsc/fscArm64Project/fscArm64.fsproj b/src/fsc/fscArm64Project/fscArm64.fsproj
index c7c42ca1adf..bcc20db5d6a 100644
--- a/src/fsc/fscArm64Project/fscArm64.fsproj
+++ b/src/fsc/fscArm64Project/fscArm64.fsproj
@@ -5,7 +5,7 @@
net472
arm64
- true
+ true
diff --git a/src/fsi/fsiAnyCpuProject/fsiAnyCpu.fsproj b/src/fsi/fsiAnyCpuProject/fsiAnyCpu.fsproj
index f11e2783e44..ae7238e556a 100644
--- a/src/fsi/fsiAnyCpuProject/fsiAnyCpu.fsproj
+++ b/src/fsi/fsiAnyCpuProject/fsiAnyCpu.fsproj
@@ -5,7 +5,7 @@
net472
anycpu
- true
+ true
$(DefineConstants);FSI_SHADOW_COPY_REFERENCES;FSI_SERVER
diff --git a/src/fsi/fsiArm64Project/fsiArm64.fsproj b/src/fsi/fsiArm64Project/fsiArm64.fsproj
index 07e19f49d5e..acb66346e8a 100644
--- a/src/fsi/fsiArm64Project/fsiArm64.fsproj
+++ b/src/fsi/fsiArm64Project/fsiArm64.fsproj
@@ -5,7 +5,7 @@
net472
arm64
- true
+ true
$(DefineConstants);FSI_SHADOW_COPY_REFERENCES;FSI_SERVER
diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props
index 06697bc35ed..80708062652 100644
--- a/tests/Directory.Build.props
+++ b/tests/Directory.Build.props
@@ -3,7 +3,7 @@
- true
+ true
portable
diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Nowarn.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Nowarn.fs
deleted file mode 100644
index 78067aa8c32..00000000000
--- a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Nowarn.fs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
-namespace CompilerDirectives
-
-open Xunit
-open FSharp.Test.Compiler
-
-module Nowarn =
-
- let warn20Text = "The result of this expression has type 'string' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'."
-
- let checkFileBugSource = """
-module A
-#nowarn "20"
-#line 1 "xyz.fs"
-""
- """
-
- let checkFileBugSource2 = """
-module A
-#line 1 "xyz.fs"
-#nowarn "20"
-""
- """
-
-
- []
- let ``checkFile bug simulation for compatibility`` () =
-
- FSharp checkFileBugSource
- |> withLangVersion80
- |> compile
- |> shouldSucceed
-
- []
- let ``checkFile bug fixed leads to new warning`` () =
-
- FSharp checkFileBugSource
- |> withLangVersion90
- |> compile
- |> shouldFail
- |> withDiagnostics [
- (Warning 20, Line 1, Col 1, Line 1, Col 3, warn20Text)
- ]
-
- []
- let ``checkFile bug fixed, no warning if nowarn is correctly used`` () =
-
- FSharp checkFileBugSource2
- |> withLangVersion90
- |> compile
- |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
index adfe0e3cfcb..f6d8a0cc530 100644
--- a/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
+++ b/tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/CustomAttributes/AttributeUsage/AttributeUsage.fs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace Conformance.BasicGrammarElements
@@ -98,7 +98,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargets01_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -134,7 +134,7 @@ module CustomAttributes_AttributeUsage =
let ``E_AttributeTargetIsField01_fs`` compilation =
compilation
|> withOptions ["--nowarn:25"]
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -187,7 +187,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetIsMethod02_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> withOptions ["--nowarn:25"]
|> verifyCompile
|> shouldFail
@@ -218,7 +218,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetIsMethod03_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> withOptions ["--nowarn:25"]
|> verifyCompile
|> shouldFail
@@ -336,7 +336,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetIsStruct_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -366,7 +366,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetIsClass_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -387,7 +387,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetIsClass01_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -485,7 +485,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetIsField03_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -505,7 +505,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetIsProperty01_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -525,7 +525,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetIsCtor01_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -562,7 +562,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetIsEnum01_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -599,7 +599,7 @@ module CustomAttributes_AttributeUsage =
[]
let ``E_AttributeTargetsIsDelegate01_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -648,7 +648,7 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
[]
let ``E_AttributeTargetIsInterface_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -670,7 +670,7 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
[]
let ``E_AttributeTargetIsClass02_fs`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -698,9 +698,9 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
// SOURCE=CLIMutableAttribute01.fs # CLIMutableAttribute01.fs
[]
- let ``CLIMutableAttribute01 preview`` compilation =
+ let ``CLIMutableAttribute01 90`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldSucceed
@@ -724,9 +724,9 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
// SOURCE=E_CLIMutableAttribute.fs # E_CLIMutableAttribute.fs
[]
- let ``E_CLIMutableAttribute preview`` compilation =
+ let ``E_CLIMutableAttribute 90`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -761,9 +761,9 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
// SOURCE=E_AllowNullLiteral.fs # E_AllowNullLiteral.fs
[]
- let ``E_AllowNullLiteral preview`` compilation =
+ let ``E_AllowNullLiteral 90`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -788,9 +788,9 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
// SOURCE=AllowNullLiteral01.fs # AllowNullLiteral01.fs
[]
- let ``AllowNullLiteral01 preview`` compilation =
+ let ``AllowNullLiteral01 90`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldSucceed
@@ -816,9 +816,9 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
// SOURCE=E_VolatileField.fs # E_VolatileField.fs
[]
- let ``E_VolatileField preview`` compilation =
+ let ``E_VolatileField 90`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -844,9 +844,9 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
// SOURCE=VolatileField01.fs # VolatileField01.fs
[]
- let ``VolatileField01 preview`` compilation =
+ let ``VolatileField01 90`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldSucceed
@@ -865,9 +865,9 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
// SOURCE=E_SealedAttribute01.fs # E_SealedAttribute01.fs
[]
- let ``E_SealedAttribute01 preview`` compilation =
+ let ``E_SealedAttribute01 90`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -875,7 +875,7 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
(Error 948, Line 8, Col 6, Line 8, Col 24, "Interface types cannot be sealed")
(Error 942, Line 14, Col 6, Line 14, Col 33, "Delegate types are always sealed")
]
-
+
// SOURCE= E_StructLayout01.fs # E_StructLayout01.fs
[]
let ``E_StructLayout01 9.0`` compilation =
@@ -890,12 +890,12 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
(Error 937, Line 14, Col 6, Line 14, Col 8, "Only structs and classes without primary constructors may be given the 'StructLayout' attribute")
(Error 937, Line 17, Col 6, Line 17, Col 8, "Only structs and classes without primary constructors may be given the 'StructLayout' attribute")
]
-
+
// SOURCE=E_StructLayout01.fs # E_StructLayout01.fs
[]
- let ``E_StructLayout01 preview`` compilation =
+ let ``E_StructLayout01 90`` compilation =
compilation
- |> withLangVersionPreview
+ |> withLangVersion90
|> verifyCompile
|> shouldFail
|> withDiagnostics [
@@ -904,4 +904,32 @@ type InterruptibleLazy<'T> private (valueFactory: unit -> 'T) =
(Error 937, Line 11, Col 6, Line 11, Col 8, "Only structs and classes without primary constructors may be given the 'StructLayout' attribute")
(Error 937, Line 14, Col 6, Line 14, Col 8, "Only structs and classes without primary constructors may be given the 'StructLayout' attribute")
(Error 937, Line 17, Col 6, Line 17, Col 8, "Only structs and classes without primary constructors may be given the 'StructLayout' attribute")
- ]
\ No newline at end of file
+ ]
+
+#if NETCOREAPP
+ let missingConstructorRepro =
+ """
+open System.Text.Json.Serialization
+
+type internal ApplicationTenantJsonDerivedTypeAttribute () =
+ inherit JsonDerivedTypeAttribute (typeof, "a")
+
+// --------------------------------------------------------------------------
+// IMPORTANT: Read ReadMe before modifying this сlass and any referenced types
+// --------------------------------------------------------------------------
+and []
+ ApplicationTenant
+ [] (id, name, loginProvider, allowedDomains, authorizedTenants, properties) =
+
+ member _.Id = ""
+ """
+
+ []
+ []
+ []
+ let ``Regression for - F# 9 compiler cannot find constructor for attribute`` langVersion =
+ FSharp missingConstructorRepro
+ |> withLangVersion langVersion
+ |> verifyCompile
+ |> shouldSucceed
+#endif
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs
index 6b074654e45..1f55bc40d91 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs
@@ -21,3 +21,17 @@ let f8 f g (array: int array) = [|let y = f () in let z = g () in for x in array
let f9 f g (array: int array) = [|let y = f () in g (); for x in array -> x + y|]
let f10 f g (array: int array) = [|f (); g (); for x in array -> x|]
let f11 f g (array: int array) = [|f (); let y = g () in for x in array -> x + y|]
+let f12 (f: unit -> int array) y = [|for x in f () -> x + y|]
+
+// https://github.com/dotnet/fsharp/issues/17708
+// Don't read or rebind the loop variable when it is not in scope in the body.
+let ``for _ in Array.groupBy id [||] do ...`` () = [|for _ in Array.groupBy id [||] do 0|]
+let ``for _ | _ in Array.groupBy id [||] do ...`` () = [|for _ | _ in Array.groupBy id [||] do 0|]
+let ``for _ & _ in Array.groupBy id [||] do ...`` () = [|for _ & _ in Array.groupBy id [||] do 0|]
+let ``for _, _group in Array.groupBy id [||] do ...`` () = [|for _, _group in Array.groupBy id [||] do 0|]
+let ``for _, group in Array.groupBy id [||] do ...`` () = [|for _, group in Array.groupBy id [||] do group.Length|]
+let ``for 1 | 2 | _ in ...`` () = [|for 1 | 2 | _ in [||] do 0|]
+let ``for Failure _ | _ in ...`` () = [|for Failure _ | _ in [||] do 0|]
+let ``for true | false in ...`` () = [|for true | false in [||] do 0|]
+let ``for true | _ in ...`` () = [|for true | _ in [||] do 0|]
+let ``for _ | true in ...`` () = [|for _ | true in [||] do 0|]
diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl
index 4839243ebdb..2e1eeb67e45 100644
--- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl
+++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/ComputedCollections/ForXInArray_ToArray.fs.il.bsl
@@ -43,164 +43,342 @@
extends [runtime]System.Object
{
.custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 )
- .method public static int32[] f0(int32[] 'array') cil managed
+ .class auto ansi serializable sealed nested assembly beforefieldinit 'for _ in Array-groupBy id -||- do ---@28'
+ extends class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2