diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index bbae4ecb698..6e0c412215d 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -1,12 +1,12 @@
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
{
"name": "F#",
- "image": "mcr.microsoft.com/dotnet/sdk:9.0.100",
+ "image": "mcr.microsoft.com/dotnet/sdk:9.0.102",
"features": {
- "ghcr.io/devcontainers/features/common-utils:2.5.1": {},
+ "ghcr.io/devcontainers/features/common-utils:2.5.2": {},
"ghcr.io/devcontainers/features/git:1.3.2": {},
"ghcr.io/devcontainers/features/github-cli:1.0.13": {},
- "ghcr.io/devcontainers/features/dotnet:2.1.3": {}
+ "ghcr.io/devcontainers/features/dotnet:2.2.0": {}
},
"hostRequirements": {
"cpus": 2,
diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
index 66888c7cebe..52b92207001 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
@@ -1,13 +1,14 @@
### Fixed
-
* Fix Realsig+ generates nested closures with incorrect Generic ([Issue #17797](https://github.com/dotnet/fsharp/issues/17797), [PR #17877](https://github.com/dotnet/fsharp/pull/17877))
+* Fix internal error when missing measure attribute in an unsolved measure typar. ([Issue #7491](https://github.com/dotnet/fsharp/issues/7491), [PR #18234](https://github.com/dotnet/fsharp/pull/18234)==
* Set `Cancellable.token` from async computation ([Issue #18235](https://github.com/dotnet/fsharp/issues/18235), [PR #18238](https://github.com/dotnet/fsharp/pull/18238))
### Added
-
+* Added missing type constraints in FCS. ([PR #18241](https://github.com/dotnet/fsharp/pull/18241))
### Changed
+* FSharpCheckFileResults.ProjectContext.ProjectOptions will not be available when using the experimental Transparent Compiler feature. ([PR #18205](https://github.com/dotnet/fsharp/pull/18205))
+* Update `Obsolete` attribute checking to account for `DiagnosticId` and `UrlFormat` properties. ([PR #18224](https://github.com/dotnet/fsharp/pull/18224))
### Breaking Changes
-
diff --git a/eng/DotNetBuild.props b/eng/DotNetBuild.props
index d1681803391..b44b8bae3b4 100644
--- a/eng/DotNetBuild.props
+++ b/eng/DotNetBuild.props
@@ -31,6 +31,7 @@
--tfm $(SourceBuildBootstrapTfm)
false
+ /p:RestoreConfigFile=$(RestoreConfigFile)
diff --git a/eng/Versions.props b/eng/Versions.props
index 59f0f6e7cb9..3b36ad6a716 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -37,7 +37,7 @@
$(FSMajorVersion).$(FSMinorVersion).$(FSBuildVersion)
- 9.0.100
+ 9.0.101
$(FSCorePackageVersionValue)-$(PreReleaseVersionLabel).*
diff --git a/src/Compiler/Checking/AttributeChecking.fs b/src/Compiler/Checking/AttributeChecking.fs
old mode 100644
new mode 100755
index 563af942829..8c317ad5f31
--- a/src/Compiler/Checking/AttributeChecking.fs
+++ b/src/Compiler/Checking/AttributeChecking.fs
@@ -24,8 +24,12 @@ open FSharp.Compiler.TypeProviders
open FSharp.Core.CompilerServices
#endif
-exception ObsoleteWarning of string * range
-exception ObsoleteError of string * range
+exception ObsoleteDiagnostic of
+ isError: bool *
+ diagnosticId: string *
+ message: string *
+ urlFormat: string *
+ range: range
let fail() = failwith "This custom attribute has an argument that cannot yet be converted using this API"
@@ -234,7 +238,6 @@ let MethInfoHasAttribute g m attribSpec minfo =
(fun _ -> Some ())
|> Option.isSome
-
let private CheckCompilerFeatureRequiredAttribute (g: TcGlobals) cattrs msg m =
// In some cases C# will generate both ObsoleteAttribute and CompilerFeatureRequiredAttribute.
// Specifically, when default constructor is generated for class with any required members in them.
@@ -244,87 +247,160 @@ let private CheckCompilerFeatureRequiredAttribute (g: TcGlobals) cattrs msg m =
| Some([ILAttribElem.String (Some featureName) ], _) when featureName = "RequiredMembers" ->
CompleteD
| _ ->
- ErrorD (ObsoleteError(msg, m))
+ ErrorD (ObsoleteDiagnostic(true, "", msg, "", m))
+
+let private extractILObsoleteAttributeInfo namedArgs =
+ let extractILAttribValueFrom name namedArgs =
+ match namedArgs with
+ | ExtractILAttributeNamedArg name (AttribElemStringArg v) -> v
+ | _ -> ""
+ let diagnosticId = extractILAttribValueFrom "DiagnosticId" namedArgs
+ let urlFormat = extractILAttribValueFrom "UrlFormat" namedArgs
+ (diagnosticId, urlFormat)
+
+let private CheckILObsoleteAttributes (g: TcGlobals) isByrefLikeTyconRef cattrs m =
+ if isByrefLikeTyconRef then
+ CompleteD
+ else
+ let (AttribInfo(tref,_)) = g.attrib_SystemObsolete
+ match TryDecodeILAttribute tref cattrs with
+ // []
+ // []
+ // []
+ // []
+ // []
+ // []
+ // []
+ // []
+ // []
+ // Constructors deciding on IsError and Message properties.
+ | Some ([ attribElement ], namedArgs) ->
+ let diagnosticId, urlFormat = extractILObsoleteAttributeInfo namedArgs
+ let msg =
+ match attribElement with
+ | ILAttribElem.String (Some msg) -> msg
+ | ILAttribElem.String None
+ | _ -> ""
+
+ WarnD (ObsoleteDiagnostic(false, diagnosticId, msg, urlFormat, m))
+ | Some ([ILAttribElem.String (Some msg); ILAttribElem.Bool isError ], namedArgs) ->
+ let diagnosticId, urlFormat = extractILObsoleteAttributeInfo namedArgs
+ if isError then
+ if g.langVersion.SupportsFeature(LanguageFeature.RequiredPropertiesSupport) then
+ CheckCompilerFeatureRequiredAttribute g cattrs msg m
+ else
+ ErrorD (ObsoleteDiagnostic(true, diagnosticId, msg, urlFormat, m))
+ else
+ WarnD (ObsoleteDiagnostic(false, diagnosticId, msg, urlFormat, m))
+ // Only DiagnosticId, UrlFormat
+ | Some (_, namedArgs) ->
+ let diagnosticId, urlFormat = extractILObsoleteAttributeInfo namedArgs
+ WarnD(ObsoleteDiagnostic(false, diagnosticId, "", urlFormat, m))
+ // No arguments
+ | None -> CompleteD
/// Check IL attributes for 'ObsoleteAttribute', returning errors and warnings as data
let private CheckILAttributes (g: TcGlobals) isByrefLikeTyconRef cattrs m =
- let (AttribInfo(tref,_)) = g.attrib_SystemObsolete
- match TryDecodeILAttribute tref cattrs with
- | Some ([ILAttribElem.String (Some msg) ], _) when not isByrefLikeTyconRef ->
- WarnD(ObsoleteWarning(msg, m))
- | Some ([ILAttribElem.String (Some msg); ILAttribElem.Bool isError ], _) when not isByrefLikeTyconRef ->
- if isError then
- if g.langVersion.SupportsFeature(LanguageFeature.RequiredPropertiesSupport) then
- CheckCompilerFeatureRequiredAttribute g cattrs msg m
- else
- ErrorD (ObsoleteError(msg, m))
- else
- WarnD (ObsoleteWarning(msg, m))
- | Some ([ILAttribElem.String None ], _) when not isByrefLikeTyconRef ->
- WarnD(ObsoleteWarning("", m))
- | Some _ when not isByrefLikeTyconRef ->
- WarnD(ObsoleteWarning("", m))
- | _ ->
- CompleteD
+ trackErrors {
+ do! CheckILObsoleteAttributes g isByrefLikeTyconRef cattrs m
+ }
let langVersionPrefix = "--langversion:preview"
+let private extractObsoleteAttributeInfo namedArgs =
+ let extractILAttribValueFrom name namedArgs =
+ match namedArgs with
+ | ExtractAttribNamedArg name (AttribStringArg v) -> v
+ | _ -> ""
+ let diagnosticId = extractILAttribValueFrom "DiagnosticId" namedArgs
+ let urlFormat = extractILAttribValueFrom "UrlFormat" namedArgs
+ (diagnosticId, urlFormat)
+
+let private CheckObsoleteAttributes g attribs m =
+ trackErrors {
+ match TryFindFSharpAttribute g g.attrib_SystemObsolete attribs with
+ // []
+ // []
+ // []
+ // []
+ // []
+ // []
+ // []
+ // []
+ // []
+ // Constructors deciding on IsError and Message properties.
+ | Some(Attrib(unnamedArgs= [ AttribStringArg s ]; propVal= namedArgs)) ->
+ let diagnosticId, urlFormat = extractObsoleteAttributeInfo namedArgs
+ do! WarnD(ObsoleteDiagnostic(false, diagnosticId, s, urlFormat, m))
+ | Some(Attrib(unnamedArgs= [ AttribStringArg s; AttribBoolArg(isError) ]; propVal= namedArgs)) ->
+ let diagnosticId, urlFormat = extractObsoleteAttributeInfo namedArgs
+ if isError then
+ do! ErrorD (ObsoleteDiagnostic(true, diagnosticId, s, urlFormat, m))
+ else
+ do! WarnD (ObsoleteDiagnostic(false, diagnosticId, s, urlFormat, m))
+ // Only DiagnosticId, UrlFormat
+ | Some(Attrib(propVal= namedArgs)) ->
+ let diagnosticId, urlFormat = extractObsoleteAttributeInfo namedArgs
+ do! WarnD(ObsoleteDiagnostic(false, diagnosticId, "", urlFormat, m))
+ | None -> ()
+ }
+
+let private CheckCompilerMessageAttribute g attribs m =
+ trackErrors {
+ match TryFindFSharpAttribute g g.attrib_CompilerMessageAttribute attribs with
+ | Some(Attrib(unnamedArgs= [ AttribStringArg s ; AttribInt32Arg n ]; propVal= namedArgs)) ->
+ let msg = UserCompilerMessage(s, n, m)
+ let isError =
+ match namedArgs with
+ | ExtractAttribNamedArg "IsError" (AttribBoolArg v) -> v
+ | _ -> false
+ // If we are using a compiler that supports nameof then error 3501 is always suppressed.
+ // See attribute on FSharp.Core 'nameof'
+ if n = 3501 then
+ ()
+ elif isError && (not g.compilingFSharpCore || n <> 1204) then
+ do! ErrorD msg
+ else
+ do! WarnD msg
+ | _ ->
+ ()
+ }
+
+let private CheckExperimentalAttribute g attribs m =
+ trackErrors {
+ match TryFindFSharpAttribute g g.attrib_ExperimentalAttribute attribs with
+ | Some(Attrib(unnamedArgs= [ AttribStringArg(s) ])) ->
+ let isExperimentalAttributeDisabled (s:string) =
+ if g.compilingFSharpCore then
+ true
+ else
+ g.langVersion.IsPreviewEnabled && (s.IndexOf(langVersionPrefix, StringComparison.OrdinalIgnoreCase) >= 0)
+ if not (isExperimentalAttributeDisabled s) then
+ do! WarnD(Experimental(s, m))
+ | Some _ ->
+ do! WarnD(Experimental(FSComp.SR.experimentalConstruct (), m))
+ | _ ->
+ ()
+ }
+
+let private CheckUnverifiableAttribute g attribs m =
+ trackErrors {
+ match TryFindFSharpAttribute g g.attrib_UnverifiableAttribute attribs with
+ | Some _ ->
+ do! WarnD(PossibleUnverifiableCode(m))
+ | _ -> ()
+ }
+
/// Check F# attributes for 'ObsoleteAttribute', 'CompilerMessageAttribute' and 'ExperimentalAttribute',
/// returning errors and warnings as data
let CheckFSharpAttributes (g:TcGlobals) attribs m =
if isNil attribs then CompleteD
else
trackErrors {
- match TryFindFSharpAttribute g g.attrib_SystemObsolete attribs with
- | Some(Attrib(_, _, [ AttribStringArg s ], _, _, _, _)) ->
- do! WarnD(ObsoleteWarning(s, m))
- | Some(Attrib(_, _, [ AttribStringArg s; AttribBoolArg(isError) ], _, _, _, _)) ->
- if isError then
- do! ErrorD (ObsoleteError(s, m))
- else
- do! WarnD (ObsoleteWarning(s, m))
- | Some _ ->
- do! WarnD(ObsoleteWarning("", m))
- | None ->
- ()
-
- match TryFindFSharpAttribute g g.attrib_CompilerMessageAttribute attribs with
- | Some(Attrib(_, _, [ AttribStringArg s ; AttribInt32Arg n ], namedArgs, _, _, _)) ->
- let msg = UserCompilerMessage(s, n, m)
- let isError =
- match namedArgs with
- | ExtractAttribNamedArg "IsError" (AttribBoolArg v) -> v
- | _ -> false
- // If we are using a compiler that supports nameof then error 3501 is always suppressed.
- // See attribute on FSharp.Core 'nameof'
- if n = 3501 then
- ()
- elif isError && (not g.compilingFSharpCore || n <> 1204) then
- do! ErrorD msg
- else
- do! WarnD msg
- | _ ->
- ()
-
- match TryFindFSharpAttribute g g.attrib_ExperimentalAttribute attribs with
- | Some(Attrib(_, _, [ AttribStringArg(s) ], _, _, _, _)) ->
- let isExperimentalAttributeDisabled (s:string) =
- if g.compilingFSharpCore then
- true
- else
- g.langVersion.IsPreviewEnabled && (s.IndexOf(langVersionPrefix, StringComparison.OrdinalIgnoreCase) >= 0)
- if not (isExperimentalAttributeDisabled s) then
- do! WarnD(Experimental(s, m))
- | Some _ ->
- do! WarnD(Experimental(FSComp.SR.experimentalConstruct (), m))
- | _ ->
- ()
-
- match TryFindFSharpAttribute g g.attrib_UnverifiableAttribute attribs with
- | Some _ ->
- do! WarnD(PossibleUnverifiableCode(m))
- | _ ->
- ()
+ do! CheckObsoleteAttributes g attribs m
+ do! CheckCompilerMessageAttribute g attribs m
+ do! CheckExperimentalAttribute g attribs m
+ do! CheckUnverifiableAttribute g attribs m
}
#if !NO_TYPEPROVIDERS
@@ -332,16 +408,16 @@ let CheckFSharpAttributes (g:TcGlobals) attribs m =
let private CheckProvidedAttributes (g: TcGlobals) m (provAttribs: Tainted) =
let (AttribInfo(tref, _)) = g.attrib_SystemObsolete
match provAttribs.PUntaint((fun a -> a.GetAttributeConstructorArgs(provAttribs.TypeProvider.PUntaintNoFailure(id), tref.FullName)), m) with
- | Some ([ Some (:? string as msg) ], _) -> WarnD(ObsoleteWarning(msg, m))
+ | Some ([ Some (:? string as msg) ], _) -> WarnD(ObsoleteDiagnostic(false, "", msg, "", m))
| Some ([ Some (:? string as msg); Some (:?bool as isError) ], _) ->
if isError then
- ErrorD (ObsoleteError(msg, m))
+ ErrorD (ObsoleteDiagnostic(true, "", msg, "", m))
else
- WarnD (ObsoleteWarning(msg, m))
+ WarnD (ObsoleteDiagnostic(false, "", msg, "", m))
| Some ([ None ], _) ->
- WarnD(ObsoleteWarning("", m))
+ WarnD(ObsoleteDiagnostic(false, "", "", "", m))
| Some _ ->
- WarnD(ObsoleteWarning("", m))
+ WarnD(ObsoleteDiagnostic(false, "", "", "", m))
| None ->
CompleteD
#endif
diff --git a/src/Compiler/Checking/AttributeChecking.fsi b/src/Compiler/Checking/AttributeChecking.fsi
index 663198f9247..5885c1b39e9 100644
--- a/src/Compiler/Checking/AttributeChecking.fsi
+++ b/src/Compiler/Checking/AttributeChecking.fsi
@@ -13,9 +13,12 @@ open FSharp.Compiler.TcGlobals
open FSharp.Compiler.Text
open FSharp.Compiler.TypedTree
-exception ObsoleteWarning of string * range
-
-exception ObsoleteError of string * range
+exception ObsoleteDiagnostic of
+ isError: bool *
+ diagnosticId: string *
+ message: string *
+ urlFormat: string *
+ range: range
type AttribInfo =
| FSAttribInfo of TcGlobals * Attrib
diff --git a/src/Compiler/Checking/PostInferenceChecks.fs b/src/Compiler/Checking/PostInferenceChecks.fs
index 645f43fe3cb..e8d6f5a5af0 100644
--- a/src/Compiler/Checking/PostInferenceChecks.fs
+++ b/src/Compiler/Checking/PostInferenceChecks.fs
@@ -551,7 +551,7 @@ let WarnOnWrongTypeForAccess (cenv: cenv) env objName valAcc m ty =
if isLessAccessible tyconAcc valAcc then
let errorText = FSComp.SR.chkTypeLessAccessibleThanType(tcref.DisplayName, (objName())) |> snd
let warningText = errorText + Environment.NewLine + FSComp.SR.tcTypeAbbreviationsCheckedAtCompileTime()
- warning(AttributeChecking.ObsoleteWarning(warningText, m))
+ warning(AttributeChecking.ObsoleteDiagnostic(false, "", warningText, "", m))
CheckTypeDeep cenv (visitType, None, None, None, None) cenv.g env NoInfo ty
diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs
index 9dcf0b72ea3..019226f46e4 100644
--- a/src/Compiler/Driver/CompilerDiagnostics.fs
+++ b/src/Compiler/Driver/CompilerDiagnostics.fs
@@ -148,8 +148,7 @@ type Exception with
| IntfImplInExtrinsicAugmentation m
| ValueRestriction(_, _, _, _, m)
| LetRecUnsound(_, _, m)
- | ObsoleteError(_, m)
- | ObsoleteWarning(_, m)
+ | ObsoleteDiagnostic(_, _, _, _, m)
| Experimental(_, m)
| PossibleUnverifiableCode m
| UserCompilerMessage(_, _, m)
@@ -266,7 +265,7 @@ type Exception with
| UnresolvedOverloading _ -> 41
| LibraryUseOnly _ -> 42
| ErrorFromAddingConstraint _ -> 43
- | ObsoleteWarning _ -> 44
+ | ObsoleteDiagnostic(isError = false) -> 44
| ReservedKeyword _ -> 46
| SelfRefObjCtor _ -> 47
| VirtualAugmentationOnNullValuedType _ -> 48
@@ -327,7 +326,7 @@ type Exception with
| UnresolvedConversionOperator _ -> 93
// avoid 94-100 for safety
- | ObsoleteError _ -> 101
+ | ObsoleteDiagnostic(isError = true) -> 101
#if !NO_TYPEPROVIDERS
| TypeProviders.ProvidedTypeResolutionNoRange _
| TypeProviders.ProvidedTypeResolution _ -> 103
@@ -1790,9 +1789,7 @@ type Exception with
| ValNotLocal _ -> os.AppendString(ValNotLocalE().Format)
- | ObsoleteError(s, _)
-
- | ObsoleteWarning(s, _) ->
+ | ObsoleteDiagnostic(message = s) ->
os.AppendString(Obsolete1E().Format)
if s <> "" then
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index 8cb0e76548d..75ddfba7382 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -1789,6 +1789,7 @@ featureUseTypeSubsumptionCache,"Use type conversion cache during compilation"
3872,tcPartialActivePattern,"Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."
featureDontWarnOnUppercaseIdentifiersInBindingPatterns,"Don't warn on uppercase identifiers in binding patterns"
3873,chkDeprecatePlacesWhereSeqCanBeOmitted,"This construct is deprecated. Sequence expressions should be of the form 'seq {{ ... }}'"
+3874,tcExpectedTypeParamMarkedWithUnitOfMeasureAttribute,"Expected unit-of-measure type parameter must be marked with the [] attribute."
featureDeprecatePlacesWhereSeqCanBeOmitted,"Deprecate places where 'seq' can be omitted"
featureSupportValueOptionsAsOptionalParameters,"Support ValueOption as valid type for optional member parameters"
featureUseBangBindingValueDiscard,"Use 'use!' binding for value discard"
diff --git a/src/Compiler/Service/BackgroundCompiler.fs b/src/Compiler/Service/BackgroundCompiler.fs
index 63d147d005b..8f119f2fd60 100644
--- a/src/Compiler/Service/BackgroundCompiler.fs
+++ b/src/Compiler/Service/BackgroundCompiler.fs
@@ -1066,7 +1066,7 @@ type internal BackgroundCompiler
tcProj.TcGlobals,
options.IsIncompleteTypeCheckEnvironment,
Some builder,
- options,
+ Some options,
Array.ofList tcDependencyFiles,
creationDiags,
parseResults.Diagnostics,
@@ -1248,7 +1248,7 @@ type internal BackgroundCompiler
tcEnvAtEnd.AccessRights,
tcAssemblyExprOpt,
Array.ofList tcDependencyFiles,
- options)
+ Some options)
let results =
FSharpCheckProjectResults(
diff --git a/src/Compiler/Service/FSharpCheckerResults.fs b/src/Compiler/Service/FSharpCheckerResults.fs
index 1c7878c6df8..0d6e83a61c2 100644
--- a/src/Compiler/Service/FSharpCheckerResults.fs
+++ b/src/Compiler/Service/FSharpCheckerResults.fs
@@ -348,7 +348,7 @@ type internal TypeCheckInfo
tcAccessRights: AccessorDomain,
projectFileName: string,
mainInputFileName: string,
- projectOptions: FSharpProjectOptions,
+ projectOptions: FSharpProjectOptions option,
sResolutions: TcResolutions,
sSymbolUses: TcSymbolUses,
sFallback: NameResolutionEnv,
@@ -3289,7 +3289,7 @@ module internal ParseAndCheckFile =
tcEnvAtEnd.AccessRights,
projectFileName,
mainInputFileName,
- projectOptions,
+ Some projectOptions,
sink.GetResolutions(),
sink.GetSymbolUses(),
tcEnvAtEnd.NameEnv,
@@ -3302,9 +3302,14 @@ module internal ParseAndCheckFile =
}
[]
-type FSharpProjectContext(thisCcu: CcuThunk, assemblies: FSharpAssembly list, ad: AccessorDomain, projectOptions: FSharpProjectOptions) =
+type FSharpProjectContext
+ (thisCcu: CcuThunk, assemblies: FSharpAssembly list, ad: AccessorDomain, projectOptions: FSharpProjectOptions option) =
- member _.ProjectOptions = projectOptions
+ // TODO: Once API around Transparent Compiler is stabilized we should probably remove this.
+ member _.ProjectOptions =
+ projectOptions
+ |> Option.defaultWith (fun () ->
+ failwith "ProjectOptions are not available. This is expected when using FSharpChecker with useTransparentCompiler=true.")
member _.GetReferencedAssemblies() = assemblies
@@ -3713,7 +3718,7 @@ type FSharpCheckProjectResults
AccessorDomain *
CheckedImplFile list option *
string[] *
- FSharpProjectOptions) option
+ FSharpProjectOptions option) option
) =
let getDetails () =
@@ -4009,7 +4014,7 @@ type FsiInteractiveChecker(legacyReferenceResolver, tcConfig: TcConfig, tcGlobal
tcState.TcEnvFromImpls.AccessRights,
None,
dependencyFiles,
- projectOptions)
+ Some projectOptions)
let projectResults =
FSharpCheckProjectResults(fileName, Some tcConfig, keepAssemblyContents, errors, Some details)
diff --git a/src/Compiler/Service/FSharpCheckerResults.fsi b/src/Compiler/Service/FSharpCheckerResults.fsi
index 6b0a7f49135..607232f3c92 100644
--- a/src/Compiler/Service/FSharpCheckerResults.fsi
+++ b/src/Compiler/Service/FSharpCheckerResults.fsi
@@ -454,7 +454,7 @@ type public FSharpCheckFileResults =
tcGlobals: TcGlobals *
isIncompleteTypeCheckEnvironment: bool *
builder: IncrementalBuilder option *
- projectOptions: FSharpProjectOptions *
+ projectOptions: FSharpProjectOptions option *
dependencyFiles: string[] *
creationErrors: FSharpDiagnostic[] *
parseErrors: FSharpDiagnostic[] *
@@ -554,7 +554,7 @@ type public FSharpCheckProjectResults =
AccessorDomain *
CheckedImplFile list option *
string[] *
- FSharpProjectOptions) option ->
+ FSharpProjectOptions option) option ->
FSharpCheckProjectResults
module internal ParseAndCheckFile =
diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs
index f25b75fe99d..9f35b4f2835 100644
--- a/src/Compiler/Service/TransparentCompiler.fs
+++ b/src/Compiler/Service/TransparentCompiler.fs
@@ -1696,7 +1696,7 @@ type internal TransparentCompiler
bootstrapInfo.TcGlobals,
projectSnapshot.IsIncompleteTypeCheckEnvironment,
None,
- projectSnapshot.ToOptions(),
+ None,
Array.ofList tcInfo.tcDependencyFiles,
creationDiags,
parseResults.Diagnostics,
@@ -1963,7 +1963,7 @@ type internal TransparentCompiler
tcEnvAtEnd.AccessRights,
Some checkedImplFiles,
Array.ofList tcDependencyFiles,
- projectSnapshot.ToOptions())
+ None)
let results =
FSharpCheckProjectResults(
diff --git a/src/Compiler/Symbols/FSharpDiagnostic.fs b/src/Compiler/Symbols/FSharpDiagnostic.fs
index 31ec0536c3e..581b51ab8c7 100644
--- a/src/Compiler/Symbols/FSharpDiagnostic.fs
+++ b/src/Compiler/Symbols/FSharpDiagnostic.fs
@@ -9,6 +9,7 @@ namespace FSharp.Compiler.Diagnostics
open System
+open FSharp.Compiler.AttributeChecking
open FSharp.Compiler.CheckExpressions
open FSharp.Compiler.ConstraintSolver
open FSharp.Compiler.SignatureConformance
@@ -18,7 +19,6 @@ open FSharp.Compiler.TypedTree
open FSharp.Compiler.TypedTreeBasics
open FSharp.Compiler.TypedTreeOps
open Internal.Utilities.Library
-open Internal.Utilities.Library.Extras
open FSharp.Core.Printf
open FSharp.Compiler
@@ -67,6 +67,17 @@ module ExtendedData =
[]
type IFSharpDiagnosticExtendedData = interface end
+ /// Additional data for diagnostics about obsolete attributes.
+ []
+ type ObsoleteDiagnosticExtendedData
+ internal (diagnosticId: string, urlFormat: string) =
+ interface IFSharpDiagnosticExtendedData
+ /// Represents the DiagnosticId of the diagnostic
+ member this.DiagnosticId: string = diagnosticId
+
+ /// Represents the URL format of the diagnostic
+ member this.UrlFormat: string = urlFormat
+
[]
type TypeMismatchDiagnosticExtendedData
internal (symbolEnv: SymbolEnv, dispEnv: DisplayEnv, expectedType: TType, actualType: TType, context: DiagnosticContextInfo) =
@@ -201,6 +212,8 @@ type FSharpDiagnostic(m: range, severity: FSharpDiagnosticSeverity, message: str
| DefinitionsInSigAndImplNotCompatibleAbbreviationsDiffer(implTycon = implTycon; sigTycon = sigTycon) ->
Some(DefinitionsInSigAndImplNotCompatibleAbbreviationsDifferExtendedData(sigTycon, implTycon))
+ | ObsoleteDiagnostic(diagnosticId= diagnosticId; urlFormat= urlFormat) ->
+ Some(ObsoleteDiagnosticExtendedData(diagnosticId, urlFormat))
| _ -> None
let msg =
diff --git a/src/Compiler/Symbols/FSharpDiagnostic.fsi b/src/Compiler/Symbols/FSharpDiagnostic.fsi
index 6c941bdd84d..ecee4c0540b 100644
--- a/src/Compiler/Symbols/FSharpDiagnostic.fsi
+++ b/src/Compiler/Symbols/FSharpDiagnostic.fsi
@@ -50,6 +50,17 @@ module public ExtendedData =
interface
end
+ /// Additional data for diagnostics about obsolete attributes.
+ []
+ type public ObsoleteDiagnosticExtendedData =
+ interface IFSharpDiagnosticExtendedData
+
+ /// Represents the DiagnosticId of the diagnostic
+ member DiagnosticId: string
+
+ /// Represents the URL format of the diagnostic
+ member UrlFormat: string
+
/// Additional data for type-mismatch-like (usually with ErrorNumber = 1) diagnostics
[]
type public TypeMismatchDiagnosticExtendedData =
diff --git a/src/Compiler/Symbols/Symbols.fs b/src/Compiler/Symbols/Symbols.fs
index 36823f65dc0..470327f59cd 100644
--- a/src/Compiler/Symbols/Symbols.fs
+++ b/src/Compiler/Symbols/Symbols.fs
@@ -1596,6 +1596,11 @@ type FSharpGenericParameterConstraint(cenv, cx: TyparConstraint) =
| TyparConstraint.IsDelegate(ty1, ty2, _) -> FSharpGenericParameterDelegateConstraint(cenv, ty1, ty2)
| _ -> invalidOp "not a delegate constraint"
+ member _.IsAllowsRefStructConstraint =
+ match cx with
+ | TyparConstraint.AllowsRefStruct _ -> true
+ | _ -> false
+
override x.ToString() = ""
type FSharpInlineAnnotation =
diff --git a/src/Compiler/Symbols/Symbols.fsi b/src/Compiler/Symbols/Symbols.fsi
index 5c26d2d42ea..49742673d58 100644
--- a/src/Compiler/Symbols/Symbols.fsi
+++ b/src/Compiler/Symbols/Symbols.fsi
@@ -708,6 +708,9 @@ type FSharpGenericParameterConstraint =
/// Indicates a constraint that a type has a 'null' value
member IsSupportsNullConstraint: bool
+ /// Indicates a constraint that a type doesn't support nullness
+ member IsNotSupportsNullConstraint: bool
+
/// Indicates a constraint that a type supports F# generic comparison
member IsComparisonConstraint: bool
@@ -750,6 +753,9 @@ type FSharpGenericParameterConstraint =
/// Gets further information about a delegate constraint
member DelegateConstraintData: FSharpGenericParameterDelegateConstraint
+ /// An anti-constraint indicating that ref structs (e.g. Span<>) are allowed here
+ member IsAllowsRefStructConstraint: bool
+
[]
type FSharpInlineAnnotation =
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs
index e2bc362c784..d4f58881b19 100644
--- a/src/Compiler/TypedTree/TypedTreeOps.fs
+++ b/src/Compiler/TypedTree/TypedTreeOps.fs
@@ -243,6 +243,9 @@ and remapMeasureAux tyenv unt =
| Some tpTy ->
match tpTy with
| TType_measure unt -> unt
+ | TType_var(typar= typar) when tp.Kind = TyparKind.Measure ->
+ // This is a measure typar that is not yet solved, so we can't remap it
+ error(Error(FSComp.SR.tcExpectedTypeParamMarkedWithUnitOfMeasureAttribute(), typar.Range))
| _ -> failwith "remapMeasureAux: incorrect kinds"
| None -> unt
| Some (TType_measure unt) -> remapMeasureAux tyenv unt
@@ -3524,6 +3527,10 @@ let IsMatchingFSharpAttributeOpt g attrOpt (Attrib(tcref2, _, _, _, _, _, _)) =
[]
let (|ExtractAttribNamedArg|_|) nm args =
args |> List.tryPick (function AttribNamedArg(nm2, _, _, v) when nm = nm2 -> Some v | _ -> None) |> ValueOptionInternal.ofOption
+
+[]
+let (|ExtractILAttributeNamedArg|_|) nm (args: ILAttributeNamedArg list) =
+ args |> List.tryPick (function nm2, _, _, v when nm = nm2 -> Some v | _ -> None) |> ValueOptionInternal.ofOption
[]
let (|StringExpr|_|) = function Expr.Const (Const.String n, _, _) -> ValueSome n | _ -> ValueNone
@@ -3540,6 +3547,8 @@ let (|AttribBoolArg|_|) = function AttribExpr(_, Expr.Const (Const.Bool n, _, _)
[]
let (|AttribStringArg|_|) = function AttribExpr(_, Expr.Const (Const.String n, _, _)) -> ValueSome n | _ -> ValueNone
+let (|AttribElemStringArg|_|) = function ILAttribElem.String(n) -> n | _ -> None
+
let TryFindFSharpBoolAttributeWithDefault dflt g nm attrs =
match TryFindFSharpAttribute g nm attrs with
| Some(Attrib(_, _, [ ], _, _, _, _)) -> Some dflt
diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi
index 10f66bf63bf..3bca5cdb21e 100755
--- a/src/Compiler/TypedTree/TypedTreeOps.fsi
+++ b/src/Compiler/TypedTree/TypedTreeOps.fsi
@@ -2601,6 +2601,9 @@ val (|ConstToILFieldInit|_|): Const -> ILFieldInit voption
[]
val (|ExtractAttribNamedArg|_|): string -> AttribNamedArg list -> AttribExpr voption
+[]
+val (|ExtractILAttributeNamedArg|_|): string -> ILAttributeNamedArg list -> ILAttribElem voption
+
[]
val (|AttribInt32Arg|_|): (AttribExpr -> int32 voption)
@@ -2613,6 +2616,8 @@ val (|AttribBoolArg|_|): (AttribExpr -> bool voption)
[]
val (|AttribStringArg|_|): (AttribExpr -> string voption)
+val (|AttribElemStringArg|_|): (ILAttribElem -> string option)
+
[]
val (|Int32Expr|_|): Expr -> int32 voption
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index d0dd8088d0d..cc5e0129f32 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
Syntaxe expr1[expr2] se používá pro indexování. Pokud chcete povolit indexování, zvažte možnost přidat anotaci typu, nebo pokud voláte funkci, přidejte mezeru, třeba expr1 [expr2].
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index 1e8cfe71fea..20e20cf70b9 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
Die Syntax "expr1[expr2]" wird für die Indizierung verwendet. Fügen Sie ggf. eine Typanmerkung hinzu, um die Indizierung zu aktivieren, oder fügen Sie beim Aufrufen einer Funktion ein Leerzeichen hinzu, z. B. "expr1 [expr2]".
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index 3124b130426..530d664bf39 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
La sintaxis "expr1[expr2]" se usa para la indexación. Considere la posibilidad de agregar una anotación de tipo para habilitar la indexación, si se llama a una función, agregue un espacio, por ejemplo, "expr1 [expr2]".
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index 98442392f67..7abad9be212 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
La syntaxe « expr1[expr2] » est utilisée pour l’indexation. Envisagez d’ajouter une annotation de type pour activer l’indexation, ou si vous appelez une fonction, ajoutez un espace, par exemple « expr1 [expr2] ».
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index 0ad02dcab33..573943ab292 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
La sintassi 'expr1[expr2]' viene usata per l'indicizzazione. Provare ad aggiungere un'annotazione di tipo per abilitare l'indicizzazione oppure se la chiamata a una funzione aggiunge uno spazio, ad esempio 'expr1 [expr2]'.
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index 76014c5f081..5f5414025a0 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
構文 'expr1[expr2]' はインデックス作成に使用されます。インデックスを有効にするために型の注釈を追加するか、関数を呼び出す場合には、'expr1 [expr2]' のようにスペースを入れます。
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index 26519b8c7a3..6b5922783b6 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
인덱싱에는 'expr1[expr2]' 구문이 사용됩니다. 인덱싱을 사용하도록 설정하기 위해 형식 주석을 추가하는 것을 고려하거나 함수를 호출하는 경우 공백을 추가하세요(예: 'expr1 [expr2]').
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index 0d80733a2dc..2048f0b47c3 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
Do indeksowania używana jest składnia „expr1[expr2]”. Rozważ dodanie adnotacji typu, aby umożliwić indeksowanie, lub jeśli wywołujesz funkcję dodaj spację, np. „expr1 [expr2]”.
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index edb38fc356a..70fd0f1b333 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
A sintaxe 'expr1[expr2]' é usada para indexação. Considere adicionar uma anotação de tipo para habilitar a indexação ou, se chamar uma função, adicione um espaço, por exemplo, 'expr1 [expr2]'.
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index 6e54d232187..564d99f2835 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
Для индексирования используется синтаксис "expr1[expr2]". Рассмотрите возможность добавления аннотации типа для включения индексации или при вызове функции добавьте пробел, например "expr1 [expr2]".
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index 2df10343769..77c8cdd9948 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
Söz dizimi “expr1[expr2]” dizin oluşturma için kullanılıyor. Dizin oluşturmayı etkinleştirmek için bir tür ek açıklama eklemeyi düşünün veya bir işlev çağırıyorsanız bir boşluk ekleyin, örn. “expr1 [expr2]”.
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index eb03cbcaac8..4f13728960d 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
语法“expr1[expr2]”用于索引。考虑添加类型批注来启用索引,或者在调用函数添加空格,例如“expr1 [expr2]”。
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index f8820624484..5da35fdf95a 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -1367,6 +1367,11 @@
An empty body may only be used if the computation expression builder defines a 'Zero' method.
+
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+ Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute.
+
+
The syntax 'expr1[expr2]' is used for indexing. Consider adding a type annotation to enable indexing, or if calling a function add a space, e.g. 'expr1 [expr2]'.
語法 'expr1[expr2]' 已用於編製索引。請考慮新增類型註釋來啟用編製索引,或是呼叫函式並新增空格,例如 'expr1 [expr2]'。
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ExtendedDiagnosticDataTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ExtendedDiagnosticDataTests.fs
index 65a1cceb43d..23e4a9b9440 100644
--- a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ExtendedDiagnosticDataTests.fs
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ExtendedDiagnosticDataTests.fs
@@ -241,3 +241,304 @@ type Foo = {| bar: int; x: int |}
(fun (fieldsData: DefinitionsInSigAndImplNotCompatibleAbbreviationsDifferExtendedData) ->
assertRange (4,5) (4,8) fieldsData.SignatureRange
assertRange (4,6) (4,9) fieldsData.ImplementationRange)
+
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 01`` () =
+ FSharp """
+open System
+[]
+type MyClass() = class end
+
+let x = MyClass()
+"""
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated. Message")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("FS222", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("https://example.com", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 02`` () =
+ FSharp """
+open System
+[]
+type MyClass() = class end
+
+let x = MyClass()
+"""
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated. Message")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("FS222", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 03`` () =
+ FSharp """
+open System
+[]
+type MyClass() = class end
+
+let x = MyClass()
+"""
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated. Message")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 04`` () =
+ FSharp """
+open System
+[]
+type MyClass() = class end
+
+let x = MyClass()
+"""
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("FS222", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("https://example.com", obsoleteDiagnostic.UrlFormat))
+
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 05`` () =
+ let CSLib =
+ CSharp """
+using System;
+[Obsolete("Use something else", false, DiagnosticId = "FS222")]
+public static class Class1
+{
+ public static string Test()
+ {
+ return "Hello";
+ }
+}
+ """
+ |> withName "CSLib"
+
+ let app =
+ FSharp """
+open MyLib
+
+let text = Class1.Test();
+ """ |> withReferences [CSLib]
+
+ app
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated. Use something else")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("FS222", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 06`` () =
+ let CSLib =
+ CSharp """
+using System;
+[Obsolete("Use something else", false, DiagnosticId = "FS222", UrlFormat = "https://example.com")]
+public static class Class1
+{
+ public static string Test()
+ {
+ return "Hello";
+ }
+}
+ """
+ |> withName "CSLib"
+
+ let app =
+ FSharp """
+open MyLib
+
+let text = Class1.Test();
+ """ |> withReferences [CSLib]
+
+ app
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated. Use something else")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("FS222", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("https://example.com", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 07`` () =
+ let CSLib =
+ CSharp """
+using System;
+[Obsolete("Use something else", false)]
+public static class Class1
+{
+ public static string Test()
+ {
+ return "Hello";
+ }
+}
+ """
+ |> withName "CSLib"
+
+ let app =
+ FSharp """
+open MyLib
+
+let text = Class1.Test();
+ """ |> withReferences [CSLib]
+
+ app
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated. Use something else")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 08`` () =
+ let CSLib =
+ CSharp """
+using System;
+[Obsolete(DiagnosticId = "FS222", UrlFormat = "https://example.com")]
+public static class Class1
+{
+ public static string Test()
+ {
+ return "Hello";
+ }
+}
+ """
+ |> withName "CSLib"
+
+ let app =
+ FSharp """
+open MyLib
+
+let text = Class1.Test();
+ """ |> withReferences [CSLib]
+
+ app
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("FS222", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("https://example.com", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 09`` () =
+ FSharp """
+open System
+[]
+type MyClass() = class end
+
+let x = MyClass()
+"""
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Warning - ObsoleteDiagnosticExtendedData 10`` () =
+ let CSLib =
+ CSharp """
+using System;
+[Obsolete]
+public static class Class1
+{
+ public static string Test()
+ {
+ return "Hello";
+ }
+}
+ """
+ |> withName "CSLib"
+
+ let app =
+ FSharp """
+open MyLib
+
+let text = Class1.Test();
+ """ |> withReferences [CSLib]
+
+ app
+ |> typecheckResults
+ |> checkDiagnostic
+ (44, "This construct is deprecated")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Error - ObsoleteDiagnosticExtendedData 01`` () =
+ FSharp """
+open System
+[]
+type MyClass() = class end
+
+let x = MyClass()
+"""
+ |> typecheckResults
+ |> checkDiagnostic
+ (101, "This construct is deprecated. Message")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("FS222", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("https://example.com", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Error - ObsoleteDiagnosticExtendedData 02`` () =
+ FSharp """
+open System
+[]
+type MyClass() = class end
+
+let x = MyClass()
+"""
+ |> typecheckResults
+ |> checkDiagnostic
+ (101, "This construct is deprecated. Message")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("FS222", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Error - ObsoleteDiagnosticExtendedData 03`` () =
+ FSharp """
+open System
+[]
+type MyClass() = class end
+
+let x = MyClass()
+"""
+ |> typecheckResults
+ |> checkDiagnostic
+ (101, "This construct is deprecated. Message")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("", obsoleteDiagnostic.UrlFormat))
+
+[]
+let ``Error - ObsoleteDiagnosticExtendedData 04`` () =
+ FSharp """
+open System
+[]
+type MyClass() = class end
+
+let x = MyClass()
+"""
+ |> typecheckResults
+ |> checkDiagnostic
+ (101, "This construct is deprecated")
+ (fun (obsoleteDiagnostic: ObsoleteDiagnosticExtendedData) ->
+ Assert.Equal("FS222", obsoleteDiagnostic.DiagnosticId)
+ Assert.Equal("https://example.com", obsoleteDiagnostic.UrlFormat))
\ No newline at end of file
diff --git a/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs
new file mode 100644
index 00000000000..36ef76e772d
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/UnitOfMeasureTests.fs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+
+module ErrorMessages.UnitOfMeasureTests
+
+open Xunit
+open FSharp.Test.Compiler
+
+[]
+let ``Error - Expected unit-of-measure type parameter must be marked with the [] attribute.`` () =
+ Fsx """
+type A<[]'u>(x : int<'u>) =
+ member this.X = x
+
+type B<'u>(x: 'u) =
+ member this.X = x
+
+module M =
+ type A<'u> with // Note the missing Measure attribute
+ member this.Y = this.X
+
+ type B<'u> with
+ member this.Y = this.X
+
+open System.Runtime.CompilerServices
+type FooExt =
+ []
+ static member Bar(this: A<'u>, value: A<'u>) = this
+ """
+ |> typecheck
+ |> shouldFail
+ |> withDiagnostics [
+ (Error 3874, Line 9, Col 12, Line 9, Col 14, "Expected unit-of-measure type parameter must be marked with the [] attribute.")
+ ]
+
+[]
+let ``Expected unit-of-measure type parameter must be marked with the [] attribute.`` () =
+ Fsx """
+type A<[]'u>(x : int<'u>) =
+ member this.X = x
+
+module M =
+ type A<[] 'u> with // Note the Measure attribute
+ member this.Y = this.X
+
+open System.Runtime.CompilerServices
+type FooExt =
+ []
+ static member Bar(this: A<'u>, value: A<'u>) = this
+ """
+ |> typecheck
+ |> shouldSucceed
+
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index b96aba6777b..9eb31c35e0d 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -218,6 +218,7 @@
+
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl
index 6004f3fb62d..e85b3022c96 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl
@@ -2856,6 +2856,11 @@ FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedDa
FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+IFSharpDiagnosticExtendedData
FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData
FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String DiagnosticId
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String UrlFormat
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String get_DiagnosticId()
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String get_UrlFormat()
+FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData
FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnostic Create(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity, System.String, Int32, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Severity
FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Severity()
@@ -5398,6 +5403,8 @@ FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsRequiresDefa
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsSimpleChoiceConstraint
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsSupportsNullConstraint
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsUnmanagedConstraint
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsNotSupportsNullConstraint
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsAllowsRefStructConstraint
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsCoercesToConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsComparisonConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsDefaultsToConstraint()
@@ -5411,6 +5418,8 @@ FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsRequires
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsSimpleChoiceConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsSupportsNullConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsUnmanagedConstraint()
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsNotSupportsNullConstraint()
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsAllowsRefStructConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint DefaultsToConstraintData
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint get_DefaultsToConstraintData()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint DelegateConstraintData
diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
index 6004f3fb62d..e85b3022c96 100644
--- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
+++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl
@@ -2856,6 +2856,11 @@ FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedDa
FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+IFSharpDiagnosticExtendedData
FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+TypeMismatchDiagnosticExtendedData
FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ValueNotContainedDiagnosticExtendedData
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String DiagnosticId
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String UrlFormat
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String get_DiagnosticId()
+FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData: System.String get_UrlFormat()
+FSharp.Compiler.Diagnostics.ExtendedData: FSharp.Compiler.Diagnostics.ExtendedData+ObsoleteDiagnosticExtendedData
FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnostic Create(FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity, System.String, Int32, FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.String])
FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity Severity
FSharp.Compiler.Diagnostics.FSharpDiagnostic: FSharp.Compiler.Diagnostics.FSharpDiagnosticSeverity get_Severity()
@@ -5398,6 +5403,8 @@ FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsRequiresDefa
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsSimpleChoiceConstraint
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsSupportsNullConstraint
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsUnmanagedConstraint
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsNotSupportsNullConstraint
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean IsAllowsRefStructConstraint
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsCoercesToConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsComparisonConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsDefaultsToConstraint()
@@ -5411,6 +5418,8 @@ FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsRequires
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsSimpleChoiceConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsSupportsNullConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsUnmanagedConstraint()
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsNotSupportsNullConstraint()
+FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: Boolean get_IsAllowsRefStructConstraint()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint DefaultsToConstraintData
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDefaultsToConstraint get_DefaultsToConstraintData()
FSharp.Compiler.Symbols.FSharpGenericParameterConstraint: FSharp.Compiler.Symbols.FSharpGenericParameterDelegateConstraint DelegateConstraintData
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
index 1a5e3d85c4a..81cc143b139 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Debug_netstandard2.0.bsl
@@ -40,7 +40,7 @@
[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000082][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000008B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-508::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000094][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$Symbols+fullName@2490-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000015][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$Symbols+fullName@2495-1::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000015][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CreateILModule+MainModuleBuilder::ConvertProductVersionToILVersionInfo(string)][offset 0x00000011][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.StaticLinking+TypeForwarding::followTypeForwardForILTypeRef([FSharp.Compiler.Service]FSharp.Compiler.AbstractIL.IL+ILTypeRef)][offset 0x00000010][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CompilerOptions::getCompilerOption([FSharp.Compiler.Service]FSharp.Compiler.CompilerOptions+CompilerOption, [FSharp.Core]Microsoft.FSharp.Core.FSharpOption`1)][offset 0x000000E6][found Char] Unexpected type on the stack.
diff --git a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
index 77ba0d7133e..588f29f5a96 100644
--- a/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
+++ b/tests/ILVerify/ilverify_FSharp.Compiler.Service_Release_netstandard2.0.bsl
@@ -39,7 +39,7 @@
[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000064][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x0000006D][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : .$ServiceLexing+clo@921-529::Invoke([FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Core.Unit>)][offset 0x00000076][found Char] Unexpected type on the stack.
-[IL]: Error [StackUnexpected]: : .$Symbols+fullName@2490-3::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000030][found Char] Unexpected type on the stack.
+[IL]: Error [StackUnexpected]: : .$Symbols+fullName@2495-3::Invoke([FSharp.Core]Microsoft.FSharp.Core.Unit)][offset 0x00000030][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x0000000B][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.Driver+ProcessCommandLineFlags@301-1::Invoke(string)][offset 0x00000014][found Char] Unexpected type on the stack.
[IL]: Error [StackUnexpected]: : FSharp.Compiler.CreateILModule+MainModuleBuilder::ConvertProductVersionToILVersionInfo(string)][offset 0x00000010][found Char] Unexpected type on the stack.
diff --git a/tests/service/data/TestTP/ProvidedTypes.fs b/tests/service/data/TestTP/ProvidedTypes.fs
index 747455e271f..50dd53a55a4 100644
--- a/tests/service/data/TestTP/ProvidedTypes.fs
+++ b/tests/service/data/TestTP/ProvidedTypes.fs
@@ -613,7 +613,7 @@ type ProvidedTypeSymbol(kind: ProvidedTypeSymbolKind, typeArgs: Type list, typeB
| ProvidedTypeSymbolKind.ByRef, [| arg |] -> arg.Name + "&"
| ProvidedTypeSymbolKind.Generic gty, _typeArgs -> gty.Name
| ProvidedTypeSymbolKind.FSharpTypeAbbreviation (_, _, path), _ -> path[path.Length-1]
- | _ -> failwith "unreachable"
+ | c -> failwithf "unreachable %O" c
override __.BaseType =
match kind with
@@ -669,7 +669,7 @@ type ProvidedTypeSymbol(kind: ProvidedTypeSymbolKind, typeArgs: Type list, typeB
| ProvidedTypeSymbolKind.ByRef, [| arg |] -> 43904 + hash arg
| ProvidedTypeSymbolKind.Generic gty, _ -> 9797 + hash gty + Array.sumBy hash typeArgs
| ProvidedTypeSymbolKind.FSharpTypeAbbreviation _, _ -> 3092
- | _ -> failwith "unreachable"
+ | c -> failwithf "unreachable %O" c
override this.Equals(other: obj) = eqTypeObj this other
@@ -1313,16 +1313,17 @@ and ProvidedMeasureBuilder() =
// there seems to be no way to check if a type abbreviation exists
static let unitNamesTypeAbbreviations =
[
- "meter"; "hertz"; "newton"; "pascal"; "joule"; "watt"; "coulomb";
- "volt"; "farad"; "ohm"; "siemens"; "weber"; "tesla"; "henry"
- "lumen"; "lux"; "becquerel"; "gray"; "sievert"; "katal"
+ "metre"; "meter"; "kilogram"; "second"; "ampere"; "kelvin"; "mole"; "candela"
+ "hertz"; "newton"; "pascal"; "joule"; "watt"; "coulomb"; "volt"; "farad"
+ "ohm"; "siemens"; "weber"; "tesla"; "henry"; "lumen"; "lux"; "becquerel"
+ "gray"; "sievert"; "katal"
]
|> Set.ofList
static let unitSymbolsTypeAbbreviations =
[
"m"; "kg"; "s"; "A"; "K"; "mol"; "cd"; "Hz"; "N"; "Pa"; "J"; "W"; "C"
- "V"; "F"; "S"; "Wb"; "T"; "lm"; "lx"; "Bq"; "Gy"; "Sv"; "kat"; "H"
+ "V"; "F"; "S"; "ohm"; "Wb"; "T"; "lm"; "lx"; "Bq"; "Gy"; "Sv"; "kat"; "H"
]
|> Set.ofList
@@ -1448,7 +1449,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri
let save (key: BindingFlags) f : 'T =
let key = int key
- if bindings = null then
+ if isNull bindings then
bindings <- Dictionary<_, _>(HashIdentity.Structural)
if not (moreMembers()) && bindings.ContainsKey(key) then
@@ -1557,13 +1558,13 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri
(//save ("methods", bindingFlags, None) (fun () ->
getMembers()
|> Array.choose (function :? MethodInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None)
- |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetMethods(bindingFlags)))))
+ |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetMethods(bindingFlags)))))
override this.GetFields bindingFlags =
(//save ("fields", bindingFlags, None) (fun () ->
getMembers()
|> Array.choose (function :? FieldInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None)
- |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetFields(bindingFlags)))))
+ |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetFields(bindingFlags)))))
override this.GetProperties bindingFlags =
(//save ("props", bindingFlags, None) (fun () ->
@@ -1571,7 +1572,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri
getMembers()
|> Array.choose (function :? PropertyInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None)
staticOrPublic
- |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null
+ |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType
then id
else (fun mems -> Array.append mems (this.ErasedBaseType.GetProperties(bindingFlags)))))
@@ -1579,13 +1580,13 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri
(//save ("events", bindingFlags, None) (fun () ->
getMembers()
|> Array.choose (function :? EventInfo as m when memberBinds false bindingFlags m.IsStatic m.IsPublic -> Some m | _ -> None)
- |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetEvents(bindingFlags)))))
+ |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetEvents(bindingFlags)))))
override __.GetNestedTypes bindingFlags =
(//save ("nested", bindingFlags, None) (fun () ->
getMembers()
|> Array.choose (function :? Type as m when memberBinds true bindingFlags false m.IsPublic || m.IsNestedPublic -> Some m | _ -> None)
- |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || this.BaseType = null then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetNestedTypes(bindingFlags)))))
+ |> (if hasFlag bindingFlags BindingFlags.DeclaredOnly || isNull this.BaseType then id else (fun mems -> Array.append mems (this.ErasedBaseType.GetNestedTypes(bindingFlags)))))
override this.GetConstructorImpl(bindingFlags, _binder, _callConventions, _types, _modifiers) =
let xs = this.GetConstructors bindingFlags |> Array.filter (fun m -> m.Name = ".ctor")
@@ -1601,7 +1602,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri
let methods = this.GetMethods bindingFlags
methods |> Seq.groupBy (fun m -> m.Name) |> Seq.map (fun (k, v) -> k, Seq.toArray v) |> dict)
- let xs = if table.ContainsKey name then table[name] else [| |]
+ let xs = match table.TryGetValue name with | true, tn -> tn | false, _ -> [| |]
//let xs = this.GetMethods bindingFlags |> Array.filter (fun m -> m.Name = name)
if xs.Length > 1 then failwithf "GetMethodImpl. not support overloads, name = '%s', methods - '%A', callstack = '%A'" name xs Environment.StackTrace
if xs.Length > 0 then xs[0] else null)
@@ -1617,7 +1618,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri
save (bindingFlags ||| BindingFlags.GetProperty) (fun () ->
let methods = this.GetProperties bindingFlags
methods |> Seq.groupBy (fun m -> m.Name) |> Seq.map (fun (k, v) -> k, Seq.toArray v) |> dict)
- let xs = if table.ContainsKey name then table[name] else [| |]
+ let xs = match table.TryGetValue name with | true, tn -> tn | false, _ -> [| |]
//let xs = this.GetProperties bindingFlags |> Array.filter (fun m -> m.Name = name)
if xs.Length > 0 then xs[0] else null)
@@ -1804,7 +1805,7 @@ and ProvidedTypeDefinition(isTgt: bool, container:TypeContainer, className: stri
match keylist with
| [] -> ()
| key::rest ->
- buckets[key] <- (rest, v) :: (if buckets.ContainsKey key then buckets[key] else []);
+ buckets.[key] <- (rest, v) :: (match buckets.TryGetValue key with |true, bucket -> bucket | false, _ -> []);
[ for (KeyValue(key, items)) in buckets -> nodef key items ]
@@ -2209,7 +2210,7 @@ module internal AssemblyReader =
override x.ToString() = x.QualifiedName
- type ILArrayBound = int32 option
+ type ILArrayBound = int32 uoption
type ILArrayBounds = ILArrayBound * ILArrayBound
[]
@@ -2217,11 +2218,11 @@ module internal AssemblyReader =
| ILArrayShape of ILArrayBounds[] (* lobound/size pairs *)
member x.Rank = (let (ILArrayShape l) = x in l.Length)
static member SingleDimensional = ILArrayShapeStatics.SingleDimensional
- static member FromRank n = if n = 1 then ILArrayShape.SingleDimensional else ILArrayShape(List.replicate n (Some 0, None) |> List.toArray)
+ static member FromRank n = if n = 1 then ILArrayShape.SingleDimensional else ILArrayShape(List.replicate n (USome 0, UNone) |> List.toArray)
and ILArrayShapeStatics() =
- static let singleDimensional = ILArrayShape [| (Some 0, None) |]
+ static let singleDimensional = ILArrayShape [| (USome 0, UNone) |]
static member SingleDimensional = singleDimensional
/// Calling conventions. These are used in method pointer types.
@@ -2259,6 +2260,7 @@ module internal AssemblyReader =
static member Instance = instanceCallConv
static member Static = staticCallConv
+ []
type ILBoxity =
| AsObject
| AsValue
@@ -2360,9 +2362,9 @@ module internal AssemblyReader =
| ILType.Array (ILArrayShape(s), ty) -> ty.BasicQualifiedName + "[" + System.String(',', s.Length-1) + "]"
| ILType.Value tr | ILType.Boxed tr -> tr.BasicQualifiedName
| ILType.Void -> "void"
- | ILType.Ptr _ty -> failwith "unexpected pointer type"
- | ILType.Byref _ty -> failwith "unexpected byref type"
- | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type"
+ | ILType.Ptr _ty -> failwithf "unexpected pointer type %O" _ty
+ | ILType.Byref _ty -> failwithf "unexpected byref type %O" _ty
+ | ILType.FunctionPointer _mref -> failwithf "unexpected function pointer type %O" _mref
member x.QualifiedNameExtension =
match x with
@@ -2371,9 +2373,9 @@ module internal AssemblyReader =
| ILType.Array (ILArrayShape(_s), ty) -> ty.QualifiedNameExtension
| ILType.Value tr | ILType.Boxed tr -> tr.QualifiedNameExtension
| ILType.Void -> failwith "void"
- | ILType.Ptr _ty -> failwith "unexpected pointer type"
- | ILType.Byref _ty -> failwith "unexpected byref type"
- | ILType.FunctionPointer _mref -> failwith "unexpected function pointer type"
+ | ILType.Ptr _ty -> failwithf "unexpected pointer type %O" _ty
+ | ILType.Byref _ty -> failwithf "unexpected byref type %O" _ty
+ | ILType.FunctionPointer _mref -> failwithf "unexpected function pointer type %O" _mref
member x.QualifiedName =
x.BasicQualifiedName + x.QualifiedNameExtension
@@ -2381,18 +2383,18 @@ module internal AssemblyReader =
member x.TypeSpec =
match x with
| ILType.Boxed tr | ILType.Value tr -> tr
- | _ -> failwithf "not a nominal type"
+ | c -> failwithf "not a nominal type %O" c
member x.Boxity =
match x with
| ILType.Boxed _ -> AsObject
| ILType.Value _ -> AsValue
- | _ -> failwithf "not a nominal type"
+ | c -> failwithf "not a nominal type %O" c
member x.TypeRef =
match x with
| ILType.Boxed tspec | ILType.Value tspec -> tspec.TypeRef
- | _ -> failwithf "not a nominal type"
+ | c -> failwithf "not a nominal type %O" c
member x.IsNominal =
match x with
@@ -2843,14 +2845,13 @@ module internal AssemblyReader =
let mutable lmap = null
let getmap() =
- if lmap = null then
+ if isNull lmap then
lmap <- Dictionary()
for y in larr.Force() do
let key = y.Name
- if lmap.ContainsKey key then
- lmap[key] <- Array.append [| y |] lmap[key]
- else
- lmap[key] <- [| y |]
+ match lmap.TryGetValue key with
+ | true, lmpak -> lmap.[key] <- Array.append [| y |] lmpak
+ | false, _ -> lmap.[key] <- [| y |]
lmap
member __.Entries = larr.Force()
@@ -3061,7 +3062,7 @@ module internal AssemblyReader =
let mutable lmap = null
let getmap() =
- if lmap = null then
+ if isNull lmap then
lmap <- Dictionary()
for (nsp, nm, ltd) in larr.Force() do
let key = nsp, nm
@@ -3074,9 +3075,10 @@ module internal AssemblyReader =
member __.TryFindByName (nsp, nm) =
let tdefs = getmap()
let key = (nsp, nm)
- if tdefs.ContainsKey key then
- Some (tdefs[key].Force())
- else
+ match tdefs.TryGetValue key with
+ | true, tdefFal ->
+ Some (tdefFal.Force())
+ | false, _ ->
None
type ILNestedExportedType =
@@ -3105,7 +3107,7 @@ module internal AssemblyReader =
and ILExportedTypesAndForwarders(larr:Lazy) =
let mutable lmap = null
let getmap() =
- if lmap = null then
+ if isNull lmap then
lmap <- Dictionary()
for ltd in larr.Force() do
let key = ltd.Namespace, ltd.Name
@@ -4565,8 +4567,9 @@ module internal AssemblyReader =
| null -> cache := new Dictionary<_, _>(11 (* sz:int *) )
| _ -> ()
!cache
- if cache.ContainsKey idx then cache[idx]
- else let res = f idx in cache[idx] <- res; res
+ match cache.TryGetValue idx with
+ | true, cached -> cached
+ | false, _ -> let res = f idx in cache.[idx] <- res; res
let seekFindRow numRows rowChooser =
let mutable i = 1
@@ -5108,18 +5111,18 @@ module internal AssemblyReader =
seekReadIdx tableBigness[tab.Index] &addr
- let seekReadResolutionScopeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> ResolutionScopeTag idx) 2 rsBigness &addr
- let seekReadTypeDefOrRefOrSpecIdx (addr: byref) = seekReadTaggedIdx (fun idx -> TypeDefOrRefOrSpecTag idx) 2 tdorBigness &addr
- let seekReadTypeOrMethodDefIdx (addr: byref) = seekReadTaggedIdx (fun idx -> TypeOrMethodDefTag idx) 1 tomdBigness &addr
- let seekReadHasConstantIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasConstantTag idx) 2 hcBigness &addr
- let seekReadHasCustomAttributeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasCustomAttributeTag idx) 5 hcaBigness &addr
- //let seekReadHasFieldMarshalIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasFieldMarshalTag idx) 1 hfmBigness &addr
- //let seekReadHasDeclSecurityIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasDeclSecurityTag idx) 2 hdsBigness &addr
- let seekReadMemberRefParentIdx (addr: byref) = seekReadTaggedIdx (fun idx -> MemberRefParentTag idx) 3 mrpBigness &addr
- let seekReadHasSemanticsIdx (addr: byref) = seekReadTaggedIdx (fun idx -> HasSemanticsTag idx) 1 hsBigness &addr
- let seekReadMethodDefOrRefIdx (addr: byref) = seekReadTaggedIdx (fun idx -> MethodDefOrRefTag idx) 1 mdorBigness &addr
- let seekReadImplementationIdx (addr: byref) = seekReadTaggedIdx (fun idx -> ImplementationTag idx) 2 iBigness &addr
- let seekReadCustomAttributeTypeIdx (addr: byref) = seekReadTaggedIdx (fun idx -> CustomAttributeTypeTag idx) 3 catBigness &addr
+ let seekReadResolutionScopeIdx (addr: byref) = seekReadTaggedIdx ResolutionScopeTag 2 rsBigness &addr
+ let seekReadTypeDefOrRefOrSpecIdx (addr: byref) = seekReadTaggedIdx TypeDefOrRefOrSpecTag 2 tdorBigness &addr
+ let seekReadTypeOrMethodDefIdx (addr: byref) = seekReadTaggedIdx TypeOrMethodDefTag 1 tomdBigness &addr
+ let seekReadHasConstantIdx (addr: byref) = seekReadTaggedIdx HasConstantTag 2 hcBigness &addr
+ let seekReadHasCustomAttributeIdx (addr: byref) = seekReadTaggedIdx HasCustomAttributeTag 5 hcaBigness &addr
+ //let seekReadHasFieldMarshalIdx (addr: byref) = seekReadTaggedIdx HasFieldMarshalTag 1 hfmBigness &addr
+ //let seekReadHasDeclSecurityIdx (addr: byref) = seekReadTaggedIdx HasDeclSecurityTag 2 hdsBigness &addr
+ let seekReadMemberRefParentIdx (addr: byref) = seekReadTaggedIdx MemberRefParentTag 3 mrpBigness &addr
+ let seekReadHasSemanticsIdx (addr: byref) = seekReadTaggedIdx HasSemanticsTag 1 hsBigness &addr
+ let seekReadMethodDefOrRefIdx (addr: byref) = seekReadTaggedIdx MethodDefOrRefTag 1 mdorBigness &addr
+ let seekReadImplementationIdx (addr: byref) = seekReadTaggedIdx ImplementationTag 2 iBigness &addr
+ let seekReadCustomAttributeTypeIdx (addr: byref) = seekReadTaggedIdx CustomAttributeTypeTag 3 catBigness &addr
let seekReadStringIdx (addr: byref) = seekReadIdx stringsBigness &addr
let seekReadGuidIdx (addr: byref) = seekReadIdx guidsBigness &addr
let seekReadBlobIdx (addr: byref) = seekReadIdx blobsBigness &addr
@@ -5692,7 +5695,7 @@ module internal AssemblyReader =
| tag when tag = ImplementationTag.File -> ILScopeRef.Module (seekReadFile idx)
| tag when tag = ImplementationTag.AssemblyRef -> ILScopeRef.Assembly (seekReadAssemblyRef idx)
| tag when tag = ImplementationTag.ExportedType -> failwith "seekReadImplAsScopeRef"
- | _ -> failwith "seekReadImplAsScopeRef"
+ | c -> failwithf "seekReadImplAsScopeRef %O" c
and seekReadTypeRefScope (TaggedIndex(tag, idx) ): ILTypeRefScope =
match tag with
@@ -5700,7 +5703,7 @@ module internal AssemblyReader =
| tag when tag = ResolutionScopeTag.ModuleRef -> ILTypeRefScope.Top(ILScopeRef.Module (seekReadModuleRef idx))
| tag when tag = ResolutionScopeTag.AssemblyRef -> ILTypeRefScope.Top(ILScopeRef.Assembly (seekReadAssemblyRef idx))
| tag when tag = ResolutionScopeTag.TypeRef -> ILTypeRefScope.Nested (seekReadTypeRef idx)
- | _ -> failwith "seekReadTypeRefScope"
+ | c -> failwithf "seekReadTypeRefScope %O" c
and seekReadOptionalTypeDefOrRef numtypars boxity idx =
if idx = TaggedIndex(TypeDefOrRefOrSpecTag.TypeDef, 0) then None
@@ -5808,8 +5811,8 @@ module internal AssemblyReader =
let lobounds, sigptr = sigptrFold sigptrGetZInt32 numLoBounded bytes sigptr
let shape =
let dim i =
- (if i < numLoBounded then Some lobounds[i] else None),
- (if i < numSized then Some sizes[i] else None)
+ (if i < numLoBounded then USome lobounds[i] else UNone),
+ (if i < numSized then USome sizes[i] else UNone)
ILArrayShape (Array.init rank dim)
ILType.Array (shape, typ), sigptr
@@ -6420,7 +6423,7 @@ module internal AssemblyReader =
| :? Type as ty -> encodeCustomAttrString ty.FullName
| :? (obj[]) as elems ->
[| yield! i32AsBytes elems.Length; for elem in elems do yield! encodeCustomAttrPrimValue elem |]
- | _ -> failwith "unexpected value in custom attribute"
+ | c -> failwithf "unexpected value in custom attribute (%O)" c
and encodeCustomAttrValue ty (c: obj) =
match ty, c with
@@ -6561,7 +6564,7 @@ module internal AssemblyReader =
step()
drop()
- Some(ILArrayShape(Array.create rank (Some 0, None)))
+ Some(ILArrayShape(Array.create rank (USome 0, UNone)))
else
None
@@ -6688,7 +6691,7 @@ module internal AssemblyReader =
(argty, box (char n)), sigptr
| ILType.Value tspec when tspec.Namespace = USome "System" && tspec.Name = "Boolean" ->
let n, sigptr = sigptr_get_byte bytes sigptr
- (argty, box (not (n = 0))), sigptr
+ (argty, box (n <> 0)), sigptr
| ILType.Boxed tspec when tspec.Namespace = USome "System" && tspec.Name = "String" ->
//printfn "parsing string, sigptr = %d" sigptr
let n, sigptr = sigptr_get_serstring_possibly_null bytes sigptr
@@ -6805,7 +6808,7 @@ module internal AssemblyReader =
// Auto-clear the cache every 30.0 seconds.
// We would use System.Runtime.Caching but some version constraints make this difficult.
- let enableAutoClear = try Environment.GetEnvironmentVariable("FSHARP_TPREADER_AUTOCLEAR_OFF") = null with _ -> true
+ let enableAutoClear = try isNull (Environment.GetEnvironmentVariable "FSHARP_TPREADER_AUTOCLEAR_OFF") with _ -> true
let clearSpanDefault = 30000
let clearSpan = try (match Environment.GetEnvironmentVariable("FSHARP_TPREADER_AUTOCLEAR_SPAN") with null -> clearSpanDefault | s -> int32 s) with _ -> clearSpanDefault
let lastAccessLock = obj()
@@ -6954,9 +6957,9 @@ namespace ProviderImplementation.ProvidedTypes
type TxTable<'T2>() =
let tab = Dictionary()
member __.Get inp f =
- if tab.ContainsKey inp then
- tab[inp]
- else
+ match tab.TryGetValue inp with
+ | true, tabVal -> tabVal
+ | false, _ ->
let res = f()
tab[inp] <- res
res
@@ -7525,7 +7528,7 @@ namespace ProviderImplementation.ProvidedTypes
// See bug https://github.com/fsprojects/FSharp.TypeProviders.SDK/issues/236
override __.IsSZArray =
match kind with
- | TypeSymbolKind.SDArray _ -> true
+ | TypeSymbolKind.SDArray -> true
| _ -> false
#endif
override this.GetMember(_name, _mt, _bindingFlags) = notRequired this "GetMember" this.Name
@@ -8028,7 +8031,7 @@ namespace ProviderImplementation.ProvidedTypes
override __.GetEnumUnderlyingType() =
if this.IsEnum then
txILType ([| |], [| |]) ilGlobals.typ_Int32 // TODO: in theory the assumption of "Int32" is not accurate for all enums, however in practice .NET only uses enums with backing field Int32
- else failwithf "not enum type"
+ else failwithf "not enum type %O" this
override __.IsArrayImpl() = false
override __.IsByRefImpl() = false
@@ -8099,6 +8102,9 @@ namespace ProviderImplementation.ProvidedTypes
txTable.Get inp.Token (fun () ->
// We never create target types for the types of primitive values that are accepted by the F# compiler as Expr.Value nodes,
// which fortunately also correspond to element types. We just use the design-time types instead.
+ // See convertConstExpr in the compiler, e.g.
+ // https://github.com/Microsoft/visualfsharp/blob/44fa027b308681a1b78a089e44fa1ab35ff77b41/src/fsharp/MethodCalls.fs#L842
+ // for the accepted types.
match inp.Namespace, inp.Name with
//| USome "System", "Void"-> typeof
(*
@@ -8987,7 +8993,7 @@ namespace ProviderImplementation.ProvidedTypes
if i < 0 then
let msg =
if toTgt then sprintf "The design-time type '%O' utilized by a type provider was not found in the target reference assembly set '%A'. You may be referencing a profile which contains fewer types than those needed by the type provider you are using." t (getTargetAssemblies() |> Seq.toList)
- elif getSourceAssemblies() |> Seq.length = 0 then sprintf "A failure occurred while determining compilation references"
+ elif getSourceAssemblies() |> Seq.isEmpty then sprintf "A failure occurred while determining compilation references"
else sprintf "The target type '%O' utilized by a type provider was not found in the design-time assembly set '%A'. Please report this problem to the project site for the type provider." t (getSourceAssemblies() |> Seq.toList)
failwith msg
else
@@ -9552,10 +9558,10 @@ namespace ProviderImplementation.ProvidedTypes
/// Check that the data held at a fixup is some special magic value, as a sanity check
/// to ensure the fixup is being placed at a ood location.
let checkFixup32 (data: byte[]) offset exp =
- if data[offset + 3] <> b3 exp then failwith "fixup sanity check failed"
- if data[offset + 2] <> b2 exp then failwith "fixup sanity check failed"
- if data[offset + 1] <> b1 exp then failwith "fixup sanity check failed"
- if data[offset] <> b0 exp then failwith "fixup sanity check failed"
+ if data.[offset + 3] <> b3 exp then failwithf "fixup sanity check failed at %O" offset
+ if data.[offset + 2] <> b2 exp then failwithf "fixup sanity check failed at %O" offset
+ if data.[offset + 1] <> b1 exp then failwithf "fixup sanity check failed at %O" offset
+ if data.[offset] <> b0 exp then failwithf "fixup sanity check failed at %O" offset
let applyFixup32 (data:byte[]) offset v =
data[offset] <- b0 v
@@ -9983,9 +9989,9 @@ namespace ProviderImplementation.ProvidedTypes
let splitNameAt (nm:string) idx =
- if idx < 0 then failwith "splitNameAt: idx < 0";
+ if idx < 0 then failwithf "splitNameAt: idx < 0: %O" idx;
let last = nm.Length - 1
- if idx > last then failwith "splitNameAt: idx > last";
+ if idx > last then failwithf "splitNameAt: idx > last: %O %O" idx last;
(nm.Substring(0, idx)),
(if idx < last then nm.Substring (idx+1, last - idx) else "")
@@ -10157,13 +10163,13 @@ namespace ProviderImplementation.ProvidedTypes
// REVIEW: write into an accumulating buffer
let EmitArrayShape (bb: ByteBuffer) (ILArrayShape shape) =
- let sized = Array.filter (function (_, Some _) -> true | _ -> false) shape
- let lobounded = Array.filter (function (Some _, _) -> true | _ -> false) shape
+ let sized = Array.filter (function (_, USome _) -> true | _ -> false) shape
+ let lobounded = Array.filter (function (USome _, _) -> true | _ -> false) shape
bb.EmitZ32 shape.Length
bb.EmitZ32 sized.Length
- sized |> Array.iter (function (_, Some sz) -> bb.EmitZ32 sz | _ -> failwith "?")
+ sized |> Array.iter (function (_, USome sz) -> bb.EmitZ32 sz | c -> failwithf "%O ?" c)
bb.EmitZ32 lobounded.Length
- lobounded |> Array.iter (function (Some low, _) -> bb.EmitZ32 low | _ -> failwith "?")
+ lobounded |> Array.iter (function (USome low, _) -> bb.EmitZ32 low | c -> failwithf "%O ?" c)
let hasthisToByte hasthis =
match hasthis with
@@ -10672,8 +10678,8 @@ namespace ProviderImplementation.ProvidedTypes
| _ -> ()
UnsharedRow
- [| HasCustomAttribute (fst hca, snd hca)
- CustomAttributeType (fst cat, snd cat)
+ [| HasCustomAttribute hca
+ CustomAttributeType cat
Blob (GetCustomAttrDataAsBlobIdx cenv attr.Data)
|]
@@ -10937,8 +10943,9 @@ namespace ProviderImplementation.ProvidedTypes
if not (origAvailBrFixups.ContainsKey tg) then
printfn "%s" ("branch target " + formatCodeLabel tg + " not found in code")
let origDest =
- if origAvailBrFixups.ContainsKey tg then origAvailBrFixups[tg]
- else 666666
+ match origAvailBrFixups.TryGetValue tg with
+ | true, oaVal -> oaVal
+ | false, _ -> 666666
let origRelOffset = origDest - origEndOfInstr
-128 <= origRelOffset && origRelOffset <= 127
end
@@ -11246,7 +11253,7 @@ namespace ProviderImplementation.ProvidedTypes
| DT_R4 -> i_stind_r4
| DT_R8 -> i_stind_r8
| DT_REF -> i_stind_ref
- | _ -> failwith "stelem")
+ | x -> failwithf "stelem %O" x)
| I_switch labs -> codebuf.RecordReqdBrFixups (i_switch, None) labs
@@ -11278,12 +11285,12 @@ namespace ProviderImplementation.ProvidedTypes
| (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeDef -> getUncodedToken ILTableNames.TypeDef idx
| (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeRef -> getUncodedToken ILTableNames.TypeRef idx
| (tag, idx) when tag = TypeDefOrRefOrSpecTag.TypeSpec -> getUncodedToken ILTableNames.TypeSpec idx
- | _ -> failwith "?"
+ | x -> failwithf "%O ?" x
| ILToken.ILMethod mspec ->
match GetMethodSpecAsMethodDefOrRef cenv env (mspec, None) with
| (tag, idx) when tag = MethodDefOrRefTag.MethodDef -> getUncodedToken ILTableNames.Method idx
| (tag, idx) when tag = MethodDefOrRefTag.MemberRef -> getUncodedToken ILTableNames.MemberRef idx
- | _ -> failwith "?"
+ | x -> failwithf "%O ?" x
| ILToken.ILField fspec ->
match GetFieldSpecAsFieldDefOrRef cenv env fspec with
@@ -11466,7 +11473,7 @@ namespace ProviderImplementation.ProvidedTypes
let pc2pos = Array.zeroCreate (instrs.Length+1)
let pc2labs = Dictionary()
for (KeyValue(lab, pc)) in code.Labels do
- if pc2labs.ContainsKey pc then pc2labs[pc] <- lab :: pc2labs[pc] else pc2labs[pc] <- [lab]
+ match pc2labs.TryGetValue pc with | true, pcVal -> pc2labs.[pc] <- lab :: pcVal | false, _ -> pc2labs.[pc] <- [lab]
// Emit the instructions
for pc = 0 to instrs.Length do
@@ -11690,14 +11697,14 @@ namespace ProviderImplementation.ProvidedTypes
SharedRow
[| UShort (uint16 idx)
UShort (uint16 flags)
- TypeOrMethodDef (fst owner, snd owner)
+ TypeOrMethodDef owner
StringE (GetStringHeapIdx cenv gp.Name)
TypeDefOrRefOrSpec (TypeDefOrRefOrSpecTag.TypeDef, 0) (* empty kind field in deprecated metadata *) |]
else
SharedRow
[| UShort (uint16 idx)
UShort (uint16 flags)
- TypeOrMethodDef (fst owner, snd owner)
+ TypeOrMethodDef owner
StringE (GetStringHeapIdx cenv gp.Name) |]
and GenTypeAsGenericParamConstraintRow cenv env gpidx ty =
@@ -12026,7 +12033,7 @@ namespace ProviderImplementation.ProvidedTypes
[| data
ULong (match r.Access with ILResourceAccess.Public -> 0x01 | ILResourceAccess.Private -> 0x02)
StringE (GetStringHeapIdx cenv r.Name)
- Implementation (fst impl, snd impl) |]
+ Implementation impl |]
and GenResourcePass3 cenv r =
let idx = AddUnsharedRow cenv ILTableNames.ManifestResource (GetResourceAsManifestResourceRow cenv r)
@@ -12124,7 +12131,7 @@ namespace ProviderImplementation.ProvidedTypes
ULong 0x0
nelem
nselem
- Implementation (fst impl, snd impl) |])
+ Implementation impl |])
GenCustomAttrsPass3Or4 cenv (HasCustomAttributeTag.ExportedType, cidx) ce.CustomAttrs
GenNestedExportedTypesPass3 cenv cidx ce.Nested
@@ -12168,8 +12175,9 @@ namespace ProviderImplementation.ProvidedTypes
// Record the entrypoint decl if needed.
match m.EntrypointElsewhere with
| Some mref ->
- if cenv.entrypoint <> None then failwith "duplicate entrypoint"
- else cenv.entrypoint <- Some (false, GetModuleRefAsIdx cenv mref)
+ match cenv.entrypoint with
+ | Some e -> failwithf "duplicate entrypoint %O" e
+ | None -> cenv.entrypoint <- Some (false, GetModuleRefAsIdx cenv mref)
| None -> ()
and newGuid (modul: ILModuleDef) =
@@ -13928,7 +13936,7 @@ namespace ProviderImplementation.ProvidedTypes
|> Array.tryFind
(fun x ->
x.Name = name
- && x.ReturnType = returnType
+ && Type.(=)(x.ReturnType, returnType)
&& (x.GetParameters() |> Array.map (fun i -> i.ParameterType)) = tps)
@@ -14174,13 +14182,13 @@ namespace ProviderImplementation.ProvidedTypes
let pop () = ilg.Emit(I_pop)
let popIfEmptyExpected s = if isEmpty s then pop()
let emitConvIfNecessary t1 =
- if t1 = typeof then
+ if Type.(=)(t1, typeof) then
ilg.Emit(I_conv DT_I2)
- elif t1 = typeof then
+ elif Type.(=)(t1, typeof) then
ilg.Emit(I_conv DT_U2)
- elif t1 = typeof then
+ elif Type.(=)(t1, typeof) then
ilg.Emit(I_conv DT_I1)
- elif t1 = typeof then
+ elif Type.(=)(t1, typeof) then
ilg.Emit(I_conv DT_U1)
// emits given expression to corresponding IL
match expr with
@@ -14854,7 +14862,7 @@ namespace ProviderImplementation.ProvidedTypes
|> Array.tryFind
(fun x ->
x.Name = "op_Explicit"
- && x.ReturnType = rtTgt
+ && Type.(=)(x.ReturnType, rtTgt)
&& (x.GetParameters() |> Array.map (fun i -> i.ParameterType)) = [|t1|])
match m with
| None ->
@@ -15086,7 +15094,7 @@ namespace ProviderImplementation.ProvidedTypes
| false, true ->
// method produced something, but we don't need it
pop()
- | true, false when expr.Type = typeof ->
+ | true, false when Type.(=)(expr.Type, typeof) ->
// if we need result and method produce void and result should be unit - push null as unit value on stack
ilg.Emit(I_ldnull)
| _ -> ()
@@ -15122,7 +15130,7 @@ namespace ProviderImplementation.ProvidedTypes
| :? float32 as x -> ilg.Emit(I_ldc (DT_R4, ILConst.R4 x))
| :? float as x -> ilg.Emit(I_ldc(DT_R8, ILConst.R8 x))
#if !FX_NO_GET_ENUM_UNDERLYING_TYPE
- | :? Enum as x when x.GetType().GetEnumUnderlyingType() = typeof -> ilg.Emit(mk_ldc (unbox v))
+ | :? Enum as x when Type.(=) (x.GetType().GetEnumUnderlyingType(), typeof) -> ilg.Emit(mk_ldc (unbox v))
#endif
| :? Type as ty ->
ilg.Emit(I_ldtoken (ILToken.ILType (transType ty)))
@@ -15319,7 +15327,7 @@ namespace ProviderImplementation.ProvidedTypes
and transTypeRefScope (ty: Type): ILTypeRefScope =
match ty.DeclaringType with
| null ->
- if ty.Assembly = null then failwithf "null assembly for type %s" ty.FullName
+ if isNull ty.Assembly then failwithf "null assembly for type %s" ty.FullName
ILTypeRefScope.Top (transScopeRef ty.Assembly)
| dt -> ILTypeRefScope.Nested (transTypeRef dt)
@@ -15439,7 +15447,7 @@ namespace ProviderImplementation.ProvidedTypes
let otb, _ =
((None, ""), ns) ||> List.fold (fun (otb:ILTypeBuilder option, fullName) n ->
let fullName = if fullName = "" then n else fullName + "." + n
- let priorType = if typeMapExtra.ContainsKey(fullName) then Some typeMapExtra[fullName] else None
+ let priorType = match typeMapExtra.TryGetValue fullName with | true, typeVal -> Some typeVal | false, _ -> None
let tb =
match priorType with
| Some tbb -> tbb
@@ -15512,21 +15520,23 @@ namespace ProviderImplementation.ProvidedTypes
| :? ProvidedMethod as pminfo when not (methMap.ContainsKey pminfo) ->
let mb = tb.DefineMethod(minfo.Name, minfo.Attributes, transType minfo.ReturnType, [| for p in minfo.GetParameters() -> transType p.ParameterType |])
+ let ctorTy1 = typeof
+ let ctor1 = ctorTy1.GetConstructor([|typeof|])
+ let ctorTgt1 = context.ConvertSourceConstructorRefToTarget ctor1
+
+ let ctorTy2 = typeof
+ let ctor2 = ctorTy2.GetConstructor([||])
+ let ctorTgt2 = context.ConvertSourceConstructorRefToTarget ctor2
+
for (i, p) in minfo.GetParameters() |> Seq.mapi (fun i x -> (i, x :?> ProvidedParameter)) do
let pb = mb.DefineParameter(i+1, p.Attributes, p.Name)
if p.HasDefaultParameterValue then
- let ctorTy = typeof
- let ctor = ctorTy.GetConstructor([|typeof|])
- let ctorTgt = context.ConvertSourceConstructorRefToTarget ctor
- let ca = mkILCustomAttribMethRef (transCtorSpec ctorTgt, [p.RawDefaultValue], [], [])
+ let ca = mkILCustomAttribMethRef (transCtorSpec ctorTgt1, [p.RawDefaultValue], [], [])
pb.SetCustomAttribute ca
- let ctorTy = typeof
- let ctor = ctorTy.GetConstructor([||])
- let ctorTgt = context.ConvertSourceConstructorRefToTarget ctor
- let ca = mkILCustomAttribMethRef (transCtorSpec ctorTgt, [], [], [])
+ let ca = mkILCustomAttribMethRef (transCtorSpec ctorTgt2, [], [], [])
pb.SetCustomAttribute ca
pb.SetConstant p.RawDefaultValue
@@ -15766,7 +15776,7 @@ namespace ProviderImplementation.ProvidedTypes
failwithf "expected identical assembly name keys '%s' and '%s'" origAssemblyName newAssemblyName
// check the type really exists
- if t.Assembly.GetType(tyName) = null then
+ if isNull (t.Assembly.GetType tyName) then
failwithf "couldn't find type '%s' in assembly '%O'" tyName t.Assembly
t
@@ -15903,7 +15913,7 @@ namespace ProviderImplementation.ProvidedTypes
| :? ProvidedMethod as mT when (match methodBaseT.DeclaringType with :? ProvidedTypeDefinition as pt -> pt.IsErased | _ -> true) ->
match mT.GetInvokeCode with
| Some _ when methodBaseT.DeclaringType.IsInterface ->
- failwith "The provided type definition is an interface; therefore, it should not define an implementation for its members."
+ failwithf "The provided type definition is an interface; therefore, it should not define an implementation for its members. %O" methodBaseT.DeclaringType
(* NOTE: These checks appear to fail for generative abstract and virtual methods.
| Some _ when mT.IsAbstract ->
failwith "The provided method is defined as abstract; therefore, it should not define an implementation."