Skip to content

Commit 8bf3841

Browse files
authored
Merge pull request #17319 from dotnet/merges/main-to-release/dev17.11
Merge main to release/dev17.11
2 parents c07c8eb + 40797b0 commit 8bf3841

Some content is hidden

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

52 files changed

+955
-311
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
### Added
2222

2323
* Generate new `Equals` overload to avoid boxing for structural comparison ([PR #16857](https://github.com/dotnet/fsharp/pull/16857))
24+
* Allow #nowarn to support the FS prefix on error codes to disable warnings ([Issue #17206](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))
25+
* Allow ParsedHashDirectives to have argument types other than strings ([Issue #17240](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))
2426
* Parser: better recovery for unfinished patterns ([PR #17231](https://github.com/dotnet/fsharp/pull/17231))
2527
* Parser: recover on empty match clause ([PR #17233](https://github.com/dotnet/fsharp/pull/17233))
2628

docs/release-notes/.Language/preview.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Bidirectional F#/C# interop for 'unmanaged' constraint. ([PR #12154](https://github.com/dotnet/fsharp/pull/12154))
77
* Make `.Is*` discriminated union properties visible. ([Language suggestion #222](https://github.com/fsharp/fslang-suggestions/issues/222), [PR #16341](https://github.com/dotnet/fsharp/pull/16341))
88
* Allow returning bool instead of unit option for partial active patterns. ([Language suggestion #1041](https://github.com/fsharp/fslang-suggestions/issues/1041), [PR #16473](https://github.com/dotnet/fsharp/pull/16473))
9+
* Allow #nowarn to support the FS prefix on error codes to disable warnings ([Issue #17206](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))
10+
* Allow ParsedHashDirectives to have argument types other than strings ([Issue #17240](https://github.com/dotnet/fsharp/issues/16447), [PR #17209](https://github.com/dotnet/fsharp/pull/17209))
911

1012
### Fixed
1113

src/Compiler/Driver/CompilerConfig.fs

+12-9
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,19 @@ let ResolveFileUsingPaths (paths, m, fileName) =
9191
let searchMessage = String.concat "\n " paths
9292
raise (FileNameNotResolved(fileName, searchMessage, m))
9393

94-
let GetWarningNumber (m, warningNumber: string) =
94+
let GetWarningNumber (m, warningNumber: string, prefixSupported) =
9595
try
96-
// Okay so ...
97-
// #pragma strips FS of the #pragma "FS0004" and validates the warning number
98-
// therefore if we have warning id that starts with a numeric digit we convert it to Some (int32)
99-
// anything else is ignored None
96+
let warningNumber =
97+
if warningNumber.StartsWithOrdinal "FS" then
98+
if prefixSupported then
99+
warningNumber.Substring 2
100+
else
101+
raise (new ArgumentException())
102+
else
103+
warningNumber
104+
100105
if Char.IsDigit(warningNumber[0]) then
101106
Some(int32 warningNumber)
102-
elif warningNumber.StartsWithOrdinal "FS" then
103-
raise (ArgumentException())
104107
else
105108
None
106109
with _ ->
@@ -918,7 +921,7 @@ type TcConfigBuilder =
918921
member tcConfigB.TurnWarningOff(m, s: string) =
919922
use _ = UseBuildPhase BuildPhase.Parameter
920923

921-
match GetWarningNumber(m, s) with
924+
match GetWarningNumber(m, s, tcConfigB.langVersion.SupportsFeature(LanguageFeature.ParsedHashDirectiveArgumentNonQuotes)) with
922925
| None -> ()
923926
| Some n ->
924927
// nowarn:62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus
@@ -933,7 +936,7 @@ type TcConfigBuilder =
933936
member tcConfigB.TurnWarningOn(m, s: string) =
934937
use _ = UseBuildPhase BuildPhase.Parameter
935938

936-
match GetWarningNumber(m, s) with
939+
match GetWarningNumber(m, s, tcConfigB.langVersion.SupportsFeature(LanguageFeature.ParsedHashDirectiveArgumentNonQuotes)) with
937940
| None -> ()
938941
| Some n ->
939942
// warnon 62 turns on mlCompatibility, e.g. shows ML compat items in intellisense menus

src/Compiler/Driver/CompilerConfig.fsi

+1-1
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ val TryResolveFileUsingPaths: paths: string seq * m: range * fileName: string ->
916916

917917
val ResolveFileUsingPaths: paths: string seq * m: range * fileName: string -> string
918918

919-
val GetWarningNumber: m: range * warningNumber: string -> int option
919+
val GetWarningNumber: m: range * warningNumber: string * prefixSupported: bool -> int option
920920

921921
/// Get the name used for FSharp.Core
922922
val GetFSharpCoreLibraryName: unit -> string

src/Compiler/Driver/ParseAndCheckInputs.fs

+83-39
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,26 @@ let PostParseModuleSpec (_i, defaultNamespace, isLastCompiland, fileName, intf)
216216

217217
SynModuleOrNamespaceSig(lid, isRecursive, kind, decls, xmlDoc, attributes, None, range, trivia)
218218

219-
let GetScopedPragmasForHashDirective hd =
219+
let GetScopedPragmasForHashDirective hd (langVersion: LanguageVersion) =
220+
let supportsNonStringArguments =
221+
langVersion.SupportsFeature(LanguageFeature.ParsedHashDirectiveArgumentNonQuotes)
222+
220223
[
221224
match hd with
222225
| ParsedHashDirective("nowarn", numbers, m) ->
223226
for s in numbers do
224-
match s with
225-
| ParsedHashDirectiveArgument.SourceIdentifier _ -> ()
226-
| ParsedHashDirectiveArgument.String(s, _, _) ->
227-
match GetWarningNumber(m, s) with
228-
| None -> ()
229-
| Some n -> ScopedPragma.WarningOff(m, n)
227+
let warningNumber =
228+
match supportsNonStringArguments, s with
229+
| _, ParsedHashDirectiveArgument.SourceIdentifier _ -> None
230+
| true, ParsedHashDirectiveArgument.LongIdent _ -> None
231+
| true, ParsedHashDirectiveArgument.Int32(n, _) -> GetWarningNumber(m, string n, true)
232+
| true, ParsedHashDirectiveArgument.Ident(s, _) -> GetWarningNumber(m, s.idText, true)
233+
| _, ParsedHashDirectiveArgument.String(s, _, _) -> GetWarningNumber(m, s, true)
234+
| _ -> None
235+
236+
match warningNumber with
237+
| None -> ()
238+
| Some n -> ScopedPragma.WarningOff(m, n)
230239
| _ -> ()
231240
]
232241

@@ -272,10 +281,10 @@ let PostParseModuleImpls
272281
for SynModuleOrNamespace(decls = decls) in impls do
273282
for d in decls do
274283
match d with
275-
| SynModuleDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd
284+
| SynModuleDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
276285
| _ -> ()
277286
for hd in hashDirectives do
278-
yield! GetScopedPragmasForHashDirective hd
287+
yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
279288
]
280289

281290
let conditionalDirectives = LexbufIfdefStore.GetTrivia(lexbuf)
@@ -323,10 +332,10 @@ let PostParseModuleSpecs
323332
for SynModuleOrNamespaceSig(decls = decls) in specs do
324333
for d in decls do
325334
match d with
326-
| SynModuleSigDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd
335+
| SynModuleSigDecl.HashDirective(hd, _) -> yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
327336
| _ -> ()
328337
for hd in hashDirectives do
329-
yield! GetScopedPragmasForHashDirective hd
338+
yield! GetScopedPragmasForHashDirective hd lexbuf.LanguageVersion
330339
]
331340

332341
let conditionalDirectives = LexbufIfdefStore.GetTrivia(lexbuf)
@@ -888,55 +897,90 @@ let ProcessMetaCommandsFromInput
888897

889898
try
890899
match hash with
891-
| ParsedHashDirective("I", ParsedHashDirectiveArguments args, m) ->
900+
| ParsedHashDirective("I", [ path ], m) ->
892901
if not canHaveScriptMetaCommands then
893902
errorR (HashIncludeNotAllowedInNonScript m)
903+
else
904+
let arguments = parsedHashDirectiveStringArguments [ path ] tcConfig.langVersion
894905

895-
match args with
896-
| [ path ] ->
897-
matchedm <- m
898-
tcConfig.AddIncludePath(m, path, pathOfMetaCommandSource)
899-
state
900-
| _ ->
901-
errorR (Error(FSComp.SR.buildInvalidHashIDirective (), m))
902-
state
903-
| ParsedHashDirective("nowarn", ParsedHashDirectiveArguments numbers, m) ->
904-
List.fold (fun state d -> nowarnF state (m, d)) state numbers
906+
match arguments with
907+
| [ path ] ->
908+
matchedm <- m
909+
tcConfig.AddIncludePath(m, path, pathOfMetaCommandSource)
910+
| _ -> errorR (Error(FSComp.SR.buildInvalidHashIDirective (), m))
905911

906-
| ParsedHashDirective(("reference" | "r"), ParsedHashDirectiveArguments args, m) ->
907-
matchedm <- m
908-
ProcessDependencyManagerDirective Directive.Resolution args m state
912+
state
909913

910-
| ParsedHashDirective("i", ParsedHashDirectiveArguments args, m) ->
911-
matchedm <- m
912-
ProcessDependencyManagerDirective Directive.Include args m state
914+
| ParsedHashDirective("nowarn", hashArguments, m) ->
915+
let arguments = parsedHashDirectiveArguments hashArguments tcConfig.langVersion
916+
List.fold (fun state d -> nowarnF state (m, d)) state arguments
913917

914-
| ParsedHashDirective("load", ParsedHashDirectiveArguments args, m) ->
918+
| ParsedHashDirective(("reference" | "r") as c, [], m) ->
915919
if not canHaveScriptMetaCommands then
916920
errorR (HashDirectiveNotAllowedInNonScript m)
921+
else
922+
let arg = (parsedHashDirectiveArguments [] tcConfig.langVersion)
923+
warning (Error((FSComp.SR.fsiInvalidDirective (c, String.concat " " arg)), m))
924+
925+
state
926+
927+
| ParsedHashDirective(("reference" | "r"), [ reference ], m) ->
928+
if not canHaveScriptMetaCommands then
929+
errorR (HashDirectiveNotAllowedInNonScript m)
930+
state
931+
else
932+
let arguments =
933+
parsedHashDirectiveStringArguments [ reference ] tcConfig.langVersion
934+
935+
match arguments with
936+
| [ reference ] ->
937+
matchedm <- m
938+
ProcessDependencyManagerDirective Directive.Resolution [ reference ] m state
939+
| _ -> state
917940

918-
match args with
919-
| _ :: _ ->
941+
| ParsedHashDirective("i", [ path ], m) ->
942+
if not canHaveScriptMetaCommands then
943+
errorR (HashDirectiveNotAllowedInNonScript m)
944+
state
945+
else
920946
matchedm <- m
921-
args |> List.iter (fun path -> loadSourceF state (m, path))
922-
| _ -> errorR (Error(FSComp.SR.buildInvalidHashloadDirective (), m))
947+
let arguments = parsedHashDirectiveStringArguments [ path ] tcConfig.langVersion
948+
949+
match arguments with
950+
| [ path ] -> ProcessDependencyManagerDirective Directive.Include [ path ] m state
951+
| _ -> state
952+
953+
| ParsedHashDirective("load", paths, m) ->
954+
if not canHaveScriptMetaCommands then
955+
errorR (HashDirectiveNotAllowedInNonScript m)
956+
else
957+
let arguments = parsedHashDirectiveArguments paths tcConfig.langVersion
958+
959+
match arguments with
960+
| _ :: _ ->
961+
matchedm <- m
962+
arguments |> List.iter (fun path -> loadSourceF state (m, path))
963+
| _ -> errorR (Error(FSComp.SR.buildInvalidHashloadDirective (), m))
923964

924965
state
925-
| ParsedHashDirective("time", ParsedHashDirectiveArguments args, m) ->
966+
967+
| ParsedHashDirective("time", switch, m) ->
926968
if not canHaveScriptMetaCommands then
927969
errorR (HashDirectiveNotAllowedInNonScript m)
970+
else
971+
let arguments = parsedHashDirectiveArguments switch tcConfig.langVersion
928972

929-
match args with
930-
| [] -> ()
931-
| [ "on" | "off" ] -> ()
932-
| _ -> errorR (Error(FSComp.SR.buildInvalidHashtimeDirective (), m))
973+
match arguments with
974+
| [] -> matchedm <- m
975+
| [ "on" | "off" ] -> matchedm <- m
976+
| _ -> errorR (Error(FSComp.SR.buildInvalidHashtimeDirective (), m))
933977

934978
state
935979

936980
| _ ->
937-
938981
(* warning(Error("This meta-command has been ignored", m)) *)
939982
state
983+
940984
with RecoverableException e ->
941985
errorRecovery e matchedm
942986
state

src/Compiler/FSComp.txt

+3
Original file line numberDiff line numberDiff line change
@@ -1752,3 +1752,6 @@ featureReuseSameFieldsInStructUnions,"Share underlying fields in a [<Struct>] di
17521752
3868,tcActivePatternArgsCountNotMatchOnlyPat,"This active pattern expects exactly one pattern argument, e.g., '%s pat'."
17531753
3868,tcActivePatternArgsCountNotMatchArgs,"This active pattern expects %d expression argument(s), e.g., '%s%s'."
17541754
3868,tcActivePatternArgsCountNotMatchArgsAndPat,"This active pattern expects %d expression argument(s) and a pattern argument, e.g., '%s%s pat'."
1755+
featureParsedHashDirectiveArgumentNonString,"# directives with non-quoted string arguments"
1756+
3869,featureParsedHashDirectiveUnexpectedInteger,"Unexpected integer literal '%d'."
1757+
3869,featureParsedHashDirectiveUnexpectedIdentifier,"Unexpected identifier '%s'."

src/Compiler/FSStrings.resx

+3-3
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@
10511051
<value>Override implementations should be given as part of the initial declaration of a type.</value>
10521052
</data>
10531053
<data name="IntfImplInIntrinsicAugmentation" xml:space="preserve">
1054-
<value>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using #nowarn "69" if you have checked this is not the case.</value>
1054+
<value>Interface implementations should normally be given on the initial declaration of a type. Interface implementations in augmentations may lead to accessing static bindings before they are initialized, though only if the interface implementation is invoked during initialization of the static data, and in turn access the static data. You may remove this warning using '#nowarn "69"' if you have checked this is not the case.</value>
10551055
</data>
10561056
<data name="IntfImplInExtrinsicAugmentation" xml:space="preserve">
10571057
<value>Interface implementations should be given on the initial declaration of a type.</value>
@@ -1063,10 +1063,10 @@
10631063
<value>The type referenced through '{0}' is defined in an assembly that is not referenced. You must add a reference to assembly '{1}'.</value>
10641064
</data>
10651065
<data name="HashIncludeNotAllowedInNonScript" xml:space="preserve">
1066-
<value>#I directives may only occur in F# script files (extensions .fsx or .fsscript). Either move this code to a script file, add a '-I' compiler option for this reference or delimit the directive with delimit it with '#if INTERACTIVE'/'#endif'.</value>
1066+
<value>#I directives may only be used in F# script files (extensions .fsx or .fsscript). Either move this code to a script file, add a '-I' compiler option for this reference or delimit the directive with delimit it with '#if INTERACTIVE'/'#endif'.</value>
10671067
</data>
10681068
<data name="HashReferenceNotAllowedInNonScript" xml:space="preserve">
1069-
<value>#r directives may only occur in F# script files (extensions .fsx or .fsscript). Either move this code to a script file or replace this reference with the '-r' compiler option. If this directive is being executed as user input, you may delimit it with '#if INTERACTIVE'/'#endif'.</value>
1069+
<value>#r directives may only be used in F# script files (extensions .fsx or .fsscript). Either move this code to a script file or replace this reference with the '-r' compiler option. If this directive is being executed as user input, you may delimit it with '#if INTERACTIVE'/'#endif'.</value>
10701070
</data>
10711071
<data name="HashDirectiveNotAllowedInNonScript" xml:space="preserve">
10721072
<value>This directive may only be used in F# script files (extensions .fsx or .fsscript). Either remove the directive, move this code to a script file or delimit the directive with '#if INTERACTIVE'/'#endif'.</value>

src/Compiler/Facilities/DiagnosticsLogger.fs

+10-8
Original file line numberDiff line numberDiff line change
@@ -832,24 +832,26 @@ let internal languageFeatureError (langVersion: LanguageVersion) (langFeature: L
832832
let suggestedVersionStr = LanguageVersion.GetFeatureVersionString langFeature
833833
Error(FSComp.SR.chkFeatureNotLanguageSupported (featureStr, currentVersionStr, suggestedVersionStr), m)
834834

835-
let private tryLanguageFeatureErrorAux (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) =
835+
let internal tryLanguageFeatureErrorOption (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) =
836836
if not (langVersion.SupportsFeature langFeature) then
837837
Some(languageFeatureError langVersion langFeature m)
838838
else
839839
None
840840

841841
let internal checkLanguageFeatureError langVersion langFeature m =
842-
match tryLanguageFeatureErrorAux langVersion langFeature m with
842+
match tryLanguageFeatureErrorOption langVersion langFeature m with
843843
| Some e -> error e
844844
| None -> ()
845845

846-
let internal checkLanguageFeatureAndRecover langVersion langFeature m =
847-
match tryLanguageFeatureErrorAux langVersion langFeature m with
848-
| Some e -> errorR e
849-
| None -> ()
846+
let internal tryCheckLanguageFeatureAndRecover langVersion langFeature m =
847+
match tryLanguageFeatureErrorOption langVersion langFeature m with
848+
| Some e ->
849+
errorR e
850+
false
851+
| None -> true
850852

851-
let internal tryLanguageFeatureErrorOption langVersion langFeature m =
852-
tryLanguageFeatureErrorAux langVersion langFeature m
853+
let internal checkLanguageFeatureAndRecover langVersion langFeature m =
854+
tryCheckLanguageFeatureAndRecover langVersion langFeature m |> ignore
853855

854856
let internal languageFeatureNotSupportedInLibraryError (langFeature: LanguageFeature) (m: range) =
855857
let featureStr = LanguageVersion.GetFeatureString langFeature

src/Compiler/Facilities/DiagnosticsLogger.fsi

+2
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,8 @@ val languageFeatureError: langVersion: LanguageVersion -> langFeature: LanguageF
438438

439439
val checkLanguageFeatureError: langVersion: LanguageVersion -> langFeature: LanguageFeature -> m: range -> unit
440440

441+
val tryCheckLanguageFeatureAndRecover: langVersion: LanguageVersion -> langFeature: LanguageFeature -> m: range -> bool
442+
441443
val checkLanguageFeatureAndRecover: langVersion: LanguageVersion -> langFeature: LanguageFeature -> m: range -> unit
442444

443445
val tryLanguageFeatureErrorOption:

src/Compiler/Facilities/LanguageFeatures.fs

+3
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ type LanguageFeature =
8989
| LowerInterpolatedStringToConcat
9090
| LowerIntegralRangesToFastLoops
9191
| LowerSimpleMappingsInComprehensionsToDirectCallsToMap
92+
| ParsedHashDirectiveArgumentNonQuotes
9293

9394
/// LanguageVersion management
9495
type LanguageVersion(versionText) =
@@ -205,6 +206,7 @@ type LanguageVersion(versionText) =
205206
LanguageFeature.LowerInterpolatedStringToConcat, previewVersion
206207
LanguageFeature.LowerIntegralRangesToFastLoops, previewVersion
207208
LanguageFeature.LowerSimpleMappingsInComprehensionsToDirectCallsToMap, previewVersion
209+
LanguageFeature.ParsedHashDirectiveArgumentNonQuotes, previewVersion
208210
]
209211

210212
static let defaultLanguageVersion = LanguageVersion("default")
@@ -353,6 +355,7 @@ type LanguageVersion(versionText) =
353355
| LanguageFeature.LowerIntegralRangesToFastLoops -> FSComp.SR.featureLowerIntegralRangesToFastLoops ()
354356
| LanguageFeature.LowerSimpleMappingsInComprehensionsToDirectCallsToMap ->
355357
FSComp.SR.featureLowerSimpleMappingsInComprehensionsToDirectCallsToMap ()
358+
| LanguageFeature.ParsedHashDirectiveArgumentNonQuotes -> FSComp.SR.featureParsedHashDirectiveArgumentNonString ()
356359

357360
/// Get a version string associated with the given feature.
358361
static member GetFeatureVersionString feature =

0 commit comments

Comments
 (0)