Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* Add FSharpCodeCompletionOptions ([PR #19030](https://github.com/dotnet/fsharp/pull/19030))
* Type checker: recover on checking binding parameter constraints ([#19046](https://github.com/dotnet/fsharp/pull/19046))
* Debugger: provide breakpoint ranges for short lambdas ([#19067](https://github.com/dotnet/fsharp/pull/19067))
* Add `--disableLanguageFeature` command line switch to selectively disable specific F# language features ([PR #NNNNN](https://github.com/dotnet/fsharp/pull/NNNNN))

### Changed

Expand Down
6 changes: 6 additions & 0 deletions src/Compiler/Driver/CompilerConfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,8 @@ type TcConfigBuilder =

mutable langVersion: LanguageVersion

mutable disabledLanguageFeatures: Set<LanguageFeature>

mutable xmlDocInfoLoader: IXmlDocumentationInfoLoader option

mutable exiter: Exiter
Expand Down Expand Up @@ -836,6 +838,7 @@ type TcConfigBuilder =
pathMap = PathMap.empty
applyLineDirectives = true
langVersion = LanguageVersion.Default
disabledLanguageFeatures = Set.empty
implicitIncludeDir = implicitIncludeDir
defaultFSharpBinariesDir = defaultFSharpBinariesDir
reduceMemoryUsage = reduceMemoryUsage
Expand Down Expand Up @@ -984,6 +987,9 @@ type TcConfigBuilder =
WarnOn = ListSet.insert (=) n tcConfigB.diagnosticsOptions.WarnOn
}

member tcConfigB.SupportsFeature(feature: LanguageFeature) =
tcConfigB.langVersion.SupportsFeature(feature)

member tcConfigB.AddIncludePath(m, path, pathIncludedFrom) =
let absolutePath = ComputeMakePathAbsolute pathIncludedFrom path

Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/Driver/CompilerConfig.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,8 @@ type TcConfigBuilder =

mutable langVersion: LanguageVersion

mutable disabledLanguageFeatures: Set<LanguageFeature>

mutable xmlDocInfoLoader: IXmlDocumentationInfoLoader option

mutable exiter: Exiter
Expand Down Expand Up @@ -548,6 +550,8 @@ type TcConfigBuilder =

member TurnWarningOn: range * string -> unit

member SupportsFeature: LanguageFeature -> bool

member AddIncludePath: range * string * string -> unit

member AddCompilerToolsByPath: string -> unit
Expand Down
18 changes: 17 additions & 1 deletion src/Compiler/Driver/CompilerOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1177,11 +1177,27 @@ let languageFlags tcConfigB =
CompilerOption(
"langversion",
tagLangVersionValues,
OptionString(fun switch -> tcConfigB.langVersion <- setLanguageVersion switch),
OptionString(fun switch ->
tcConfigB.langVersion <- setLanguageVersion switch
tcConfigB.langVersion.SetDisabledFeatures(tcConfigB.disabledLanguageFeatures)),
None,
Some(FSComp.SR.optsSetLangVersion ())
)

// -disableLanguageFeature:<string> Disable a specific language feature by name (repeatable)
CompilerOption(
"disableLanguageFeature",
tagString,
OptionStringList(fun featureName ->
match LanguageVersion.TryParseFeature(featureName) with
| Some feature ->
tcConfigB.disabledLanguageFeatures <- tcConfigB.disabledLanguageFeatures.Add(feature)
tcConfigB.langVersion.SetDisabledFeatures(tcConfigB.disabledLanguageFeatures)
| None -> error (Error(FSComp.SR.optsUnrecognizedLanguageFeature featureName, rangeCmdArgs))),
None,
Some(FSComp.SR.optsDisableLanguageFeature ())
)

CompilerOption(
"checked",
tagNone,
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1570,6 +1570,8 @@ optsCheckNulls,"Enable nullness declarations and checks (%s by default)"
fSharpBannerVersion,"%s for F# %s"
optsGetLangVersions,"Display the allowed values for language version."
optsSetLangVersion,"Specify language version such as 'latest' or 'preview'."
optsDisableLanguageFeature,"Disable a specific language feature by name."
3879,optsUnrecognizedLanguageFeature,"Unrecognized language feature name: '%s'. Use a valid feature name such as 'NameOf' or 'StringInterpolation'."
optsSupportedLangVersions,"Supported language versions:"
optsStrictIndentation,"Override indentation rules implied by the language version (%s by default)"
nativeResourceFormatError,"Stream does not begin with a null resource and is not in '.RES' format."
Expand Down
112 changes: 109 additions & 3 deletions src/Compiler/Facilities/LanguageFeatures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,19 @@ type LanguageVersion(versionText) =

let specifiedString = versionToString specified

let mutable disabledFeatures: Set<LanguageFeature> = Set.empty

/// Check if this feature is supported by the selected langversion
member _.SupportsFeature featureId =
match features.TryGetValue featureId with
| true, v -> v <= specified
| false, _ -> false
if disabledFeatures.Contains featureId then
false
else
match features.TryGetValue featureId with
| true, v -> v <= specified
| false, _ -> false

/// Set the disabled features for this language version
member _.SetDisabledFeatures(disabled: Set<LanguageFeature>) = disabledFeatures <- disabled

/// Has preview been explicitly specified
member _.IsExplicitlySpecifiedAs50OrBefore() =
Expand Down Expand Up @@ -422,6 +430,104 @@ type LanguageVersion(versionText) =
| true, v -> versionToString v
| _ -> invalidArg "feature" "Internal error: Unable to find feature."

/// Try to parse a feature name string to a LanguageFeature option
static member TryParseFeature(featureName: string) =
let normalized = featureName.Trim().ToLowerInvariant()

match normalized with
| "singleunderscorepattern" -> Some LanguageFeature.SingleUnderscorePattern
| "wildcardinforloop" -> Some LanguageFeature.WildCardInForLoop
| "relaxwhitespace" -> Some LanguageFeature.RelaxWhitespace
| "relaxwhitespace2" -> Some LanguageFeature.RelaxWhitespace2
| "strictindentation" -> Some LanguageFeature.StrictIndentation
| "nameof" -> Some LanguageFeature.NameOf
| "implicityield" -> Some LanguageFeature.ImplicitYield
| "opentypedeclaration" -> Some LanguageFeature.OpenTypeDeclaration
| "dotlessfloat32literal" -> Some LanguageFeature.DotlessFloat32Literal
| "packagemanagement" -> Some LanguageFeature.PackageManagement
| "fromendslicing" -> Some LanguageFeature.FromEndSlicing
| "fixedindexslice3d4d" -> Some LanguageFeature.FixedIndexSlice3d4d
| "andbang" -> Some LanguageFeature.AndBang
| "resumablestatemachines" -> Some LanguageFeature.ResumableStateMachines
| "nullableoptionalinterop" -> Some LanguageFeature.NullableOptionalInterop
| "defaultinterfacememberconsumption" -> Some LanguageFeature.DefaultInterfaceMemberConsumption
| "witnesspassing" -> Some LanguageFeature.WitnessPassing
| "additionaltypedirectedconversions" -> Some LanguageFeature.AdditionalTypeDirectedConversions
| "interfaceswithmultiplegenericinstantiation" -> Some LanguageFeature.InterfacesWithMultipleGenericInstantiation
| "stringinterpolation" -> Some LanguageFeature.StringInterpolation
| "overloadsforcustomoperations" -> Some LanguageFeature.OverloadsForCustomOperations
| "expandedmeasurables" -> Some LanguageFeature.ExpandedMeasurables
| "nullnesschecking" -> Some LanguageFeature.NullnessChecking
| "structactivepattern" -> Some LanguageFeature.StructActivePattern
| "printfbinaryformat" -> Some LanguageFeature.PrintfBinaryFormat
| "indexernotationwithoutdot" -> Some LanguageFeature.IndexerNotationWithoutDot
| "refcellnotationinformationals" -> Some LanguageFeature.RefCellNotationInformationals
| "usebindingvaluediscard" -> Some LanguageFeature.UseBindingValueDiscard
| "unionispropertiesvisible" -> Some LanguageFeature.UnionIsPropertiesVisible
| "nonvariablepatternstorightofaspatterns" -> Some LanguageFeature.NonVariablePatternsToRightOfAsPatterns
| "attributestorightofmodulekeyword" -> Some LanguageFeature.AttributesToRightOfModuleKeyword
| "mlcompatrevisions" -> Some LanguageFeature.MLCompatRevisions
| "betterexceptionprinting" -> Some LanguageFeature.BetterExceptionPrinting
| "delegatetypenameresolutionfix" -> Some LanguageFeature.DelegateTypeNameResolutionFix
| "reallylonglists" -> Some LanguageFeature.ReallyLongLists
| "errorondeprecatedrequirequalifiedaccess" -> Some LanguageFeature.ErrorOnDeprecatedRequireQualifiedAccess
| "requiredpropertiessupport" -> Some LanguageFeature.RequiredPropertiesSupport
| "initpropertiessupport" -> Some LanguageFeature.InitPropertiesSupport
| "lowercaseduwhenrequirequalifiedaccess" -> Some LanguageFeature.LowercaseDUWhenRequireQualifiedAccess
| "interfaceswithabstractstaticmembers" -> Some LanguageFeature.InterfacesWithAbstractStaticMembers
| "selftypeconstraints" -> Some LanguageFeature.SelfTypeConstraints
| "accessorfunctionshorthand" -> Some LanguageFeature.AccessorFunctionShorthand
| "matchnotallowedforunioncasewithnodata" -> Some LanguageFeature.MatchNotAllowedForUnionCaseWithNoData
| "csharpextensionattributenotrequired" -> Some LanguageFeature.CSharpExtensionAttributeNotRequired
| "errorfornonvirtualmembersoverrides" -> Some LanguageFeature.ErrorForNonVirtualMembersOverrides
| "warningwheninliningmethodimplnoinlinemarkedfunction" -> Some LanguageFeature.WarningWhenInliningMethodImplNoInlineMarkedFunction
| "escapedotnetformattablestrings" -> Some LanguageFeature.EscapeDotnetFormattableStrings
| "arithmeticinliterals" -> Some LanguageFeature.ArithmeticInLiterals
| "errorreportingonstaticclasses" -> Some LanguageFeature.ErrorReportingOnStaticClasses
| "trywithinseqexpression" -> Some LanguageFeature.TryWithInSeqExpression
| "warningwhencopyandupdaterecordchangesallfields" -> Some LanguageFeature.WarningWhenCopyAndUpdateRecordChangesAllFields
| "staticmembersininterfaces" -> Some LanguageFeature.StaticMembersInInterfaces
| "noninlineliteralsasprintfformat" -> Some LanguageFeature.NonInlineLiteralsAsPrintfFormat
| "nestedcopyandupdate" -> Some LanguageFeature.NestedCopyAndUpdate
| "extendedstringinterpolation" -> Some LanguageFeature.ExtendedStringInterpolation
| "warningwhenmultiplerecdtypechoice" -> Some LanguageFeature.WarningWhenMultipleRecdTypeChoice
| "improvedimpliedargumentnames" -> Some LanguageFeature.ImprovedImpliedArgumentNames
| "diagnosticforobjinference" -> Some LanguageFeature.DiagnosticForObjInference
| "constraintintersectiononflexibletypes" -> Some LanguageFeature.ConstraintIntersectionOnFlexibleTypes
| "staticletinrecordsdustemptypes" -> Some LanguageFeature.StaticLetInRecordsDusEmptyTypes
| "warningwhentailrecattributebutnontailrecusage" -> Some LanguageFeature.WarningWhenTailRecAttributeButNonTailRecUsage
| "unmanagedconstraintcsharpinterop" -> Some LanguageFeature.UnmanagedConstraintCsharpInterop
| "whilebang" -> Some LanguageFeature.WhileBang
| "reusesamefieldssinstructunions" -> Some LanguageFeature.ReuseSameFieldsInStructUnions
| "extendedfixedbindings" -> Some LanguageFeature.ExtendedFixedBindings
| "preferstringgetpinnablereference" -> Some LanguageFeature.PreferStringGetPinnableReference
| "preferextensionmethodoverplainproperty" -> Some LanguageFeature.PreferExtensionMethodOverPlainProperty
| "warningindexedpropertiesgetsetsametype" -> Some LanguageFeature.WarningIndexedPropertiesGetSetSameType
| "warningwhentailcallattrononrec" -> Some LanguageFeature.WarningWhenTailCallAttrOnNonRec
| "booleanreturningandreturntypedirectedpartialactivepattern" ->
Some LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern
| "enforceattributetargets" -> Some LanguageFeature.EnforceAttributeTargets
| "lowerinterpolatedstringtoconcat" -> Some LanguageFeature.LowerInterpolatedStringToConcat
| "lowerintegralrangestofastloops" -> Some LanguageFeature.LowerIntegralRangesToFastLoops
| "allowaccessmodifierstautopropertiesgettersandsetters" ->
Some LanguageFeature.AllowAccessModifiersToAutoPropertiesGettersAndSetters
| "lowersimplemappingsincomprehensionstofastloops" -> Some LanguageFeature.LowerSimpleMappingsInComprehensionsToFastLoops
| "parsedhashdirectiveargumentnonquotes" -> Some LanguageFeature.ParsedHashDirectiveArgumentNonQuotes
| "emptybodiedcomputationexpressions" -> Some LanguageFeature.EmptyBodiedComputationExpressions
| "allowobjectexpressionwithoutoverrides" -> Some LanguageFeature.AllowObjectExpressionWithoutOverrides
| "dontwarnunuppercaseidentifiersinbindingpatterns" -> Some LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns
| "usetypesubsumptioncache" -> Some LanguageFeature.UseTypeSubsumptionCache
| "deprecateplaceswheresecanbemitted" -> Some LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted
| "supportvalueoptionsasoptionalparameters" -> Some LanguageFeature.SupportValueOptionsAsOptionalParameters
| "warnwhenunitpassedtoobjarg" -> Some LanguageFeature.WarnWhenUnitPassedToObjArg
| "usebangbindingvaluediscard" -> Some LanguageFeature.UseBangBindingValueDiscard
| "betteranonymousrecordparsing" -> Some LanguageFeature.BetterAnonymousRecordParsing
| "scopednowarn" -> Some LanguageFeature.ScopedNowarn
| "erroroninvaliddeclsintypedefinitions" -> Some LanguageFeature.ErrorOnInvalidDeclsInTypeDefinitions
| "allowtypedletuseandbang" -> Some LanguageFeature.AllowTypedLetUseAndBang
| "returnfromfinal" -> Some LanguageFeature.ReturnFromFinal
| _ -> None

override x.Equals(yobj: obj) =
match yobj with
| :? LanguageVersion as y -> x.SpecifiedVersion = y.SpecifiedVersion
Expand Down
6 changes: 6 additions & 0 deletions src/Compiler/Facilities/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ type LanguageVersion =
/// Does the selected LanguageVersion support the specified feature
member SupportsFeature: LanguageFeature -> bool

/// Set the disabled features for this language version
member SetDisabledFeatures: Set<LanguageFeature> -> unit

/// Get the list of valid versions
static member ValidVersions: string[]

Expand All @@ -136,4 +139,7 @@ type LanguageVersion =
/// Get a version string associated with the given feature.
static member GetFeatureVersionString: feature: LanguageFeature -> string

/// Try to parse a feature name string to a LanguageFeature option
static member TryParseFeature: featureName: string -> LanguageFeature option

static member Default: LanguageVersion
10 changes: 10 additions & 0 deletions src/Compiler/xlf/FSComp.txt.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Compiler/xlf/FSComp.txt.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions src/Compiler/xlf/FSComp.txt.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading