diff --git a/buildtools/fsyacc/fsyaccdriver.fs b/buildtools/fsyacc/fsyaccdriver.fs
index c9ca12e4710..f46e607f93a 100644
--- a/buildtools/fsyacc/fsyaccdriver.fs
+++ b/buildtools/fsyacc/fsyaccdriver.fs
@@ -199,6 +199,8 @@ let writeSpecToFile (generatorState: GeneratorState) (spec: ParserSpec) (compile
writer.WriteLineInterface "module %s" s;
writer.WriteLine "#nowarn \"64\";; // turn off warnings that type variables used in production annotations are instantiated to concrete type";
+ writer.WriteLine "#nowarn \"1182\" // the generated code often has unused variable 'parseState'"
+ writer.WriteLine "#nowarn \"3261\" // the generated code would need to properly annotate nulls, e.g. changing System.Object to `obj|null`";
for s in generatorState.opens do
writer.WriteLine "open %s" s;
diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
index 2f370f86aef..8185ef22b43 100644
--- a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
+++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md
@@ -1,5 +1,6 @@
### Fixed
+* Fix a bug in the interaction between ``#line` and `#nowarn` directives ([PR #17649](https://github.com/dotnet/fsharp/pull/17649))
* Fix wrong TailCall warning ([Issue #17604](https://github.com/dotnet/fsharp/issues/17604), [PR #17637](https://github.com/dotnet/fsharp/pull/17637))
* Compiler hangs when compiling inline recursive invocation ([Issue #17376](https://github.com/dotnet/fsharp/issues/17376), [PR #17394](https://github.com/dotnet/fsharp/pull/17394))
* Fix reporting IsFromComputationExpression only for CE builder type constructors and let bindings. ([PR #17375](https://github.com/dotnet/fsharp/pull/17375))
diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md
index dc79bbfe7e1..d57025fb5c3 100644
--- a/docs/release-notes/.Language/preview.md
+++ b/docs/release-notes/.Language/preview.md
@@ -21,6 +21,7 @@
* Enforce AttributeTargets on union case declarations. ([PR #16764](https://github.com/dotnet/fsharp/pull/16764))
* Enforce AttributeTargets on implicit constructors. ([PR #16845](https://github.com/dotnet/fsharp/pull/16845/))
* Enforce AttributeTargets on structs and classes ([PR #16790](https://github.com/dotnet/fsharp/pull/16790))
+* Ensure consistent interaction between ``#line` and `#nowarn` directives ([PR #17649](https://github.com/dotnet/fsharp/pull/17649))
### Changed
diff --git a/src/Compiler/AbstractIL/ilpars.fsy b/src/Compiler/AbstractIL/ilpars.fsy
index ca06f6570be..b8380364f6b 100644
--- a/src/Compiler/AbstractIL/ilpars.fsy
+++ b/src/Compiler/AbstractIL/ilpars.fsy
@@ -2,6 +2,7 @@
%{
+#nowarn "64" // turn off warnings that type variables used in production annotations are instantiated to concrete type
#nowarn "1182" // the generated code often has unused variable "parseState"
#nowarn "3261" // the generated code would need to properly annotate nulls, e.g. changing System.Object to `obj|null`
diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs
index 1c50ca26781..c73b8e5d197 100644
--- a/src/Compiler/Driver/CompilerDiagnostics.fs
+++ b/src/Compiler/Driver/CompilerDiagnostics.fs
@@ -24,6 +24,7 @@ open FSharp.Compiler.ConstraintSolver
open FSharp.Compiler.DiagnosticMessage
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.DiagnosticsLogger
+open FSharp.Compiler.Features
open FSharp.Compiler.Infos
open FSharp.Compiler.IO
open FSharp.Compiler.Lexhelp
@@ -2299,17 +2300,13 @@ type PhasedDiagnostic with
// Scoped #nowarn pragmas
/// Build an DiagnosticsLogger that delegates to another DiagnosticsLogger but filters warnings turned off by the given pragma declarations
-//
-// NOTE: we allow a flag to turn of strict file checking. This is because file names sometimes don't match due to use of
-// #line directives, e.g. for pars.fs/pars.fsy. In this case we just test by line number - in most cases this is sufficient
-// because we install a filtering error handler on a file-by-file basis for parsing and type-checking.
-// However this is indicative of a more systematic problem where source-line
-// sensitive operations (lexfilter and warning filtering) do not always
-// interact well with #line directives.
type DiagnosticsLoggerFilteringByScopedPragmas
- (checkFile, scopedPragmas, diagnosticOptions: FSharpDiagnosticOptions, diagnosticsLogger: DiagnosticsLogger) =
+ (langVersion: LanguageVersion, scopedPragmas, diagnosticOptions: FSharpDiagnosticOptions, diagnosticsLogger: DiagnosticsLogger) =
inherit DiagnosticsLogger("DiagnosticsLoggerFilteringByScopedPragmas")
+ let needCompatibilityWithEarlierInconsistentInteraction =
+ not (langVersion.SupportsFeature LanguageFeature.ConsistentNowarnLineDirectiveInteraction)
+
let mutable realErrorPresent = false
override _.DiagnosticSink(diagnostic: PhasedDiagnostic, severity) =
@@ -2323,12 +2320,10 @@ type DiagnosticsLoggerFilteringByScopedPragmas
match diagnostic.Range with
| Some m ->
scopedPragmas
- |> List.exists (fun pragma ->
- let (ScopedPragma.WarningOff(pragmaRange, warningNumFromPragma)) = pragma
-
+ |> List.exists (fun (ScopedPragma.WarningOff(pragmaRange, warningNumFromPragma)) ->
warningNum = warningNumFromPragma
- && (not checkFile || m.FileIndex = pragmaRange.FileIndex)
- && posGeq m.Start pragmaRange.Start)
+ && (needCompatibilityWithEarlierInconsistentInteraction
+ || m.FileIndex = pragmaRange.FileIndex && posGeq m.Start pragmaRange.Start))
|> not
| None -> true
@@ -2344,5 +2339,5 @@ type DiagnosticsLoggerFilteringByScopedPragmas
override _.CheckForRealErrorsIgnoringWarnings = realErrorPresent
-let GetDiagnosticsLoggerFilteringByScopedPragmas (checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) =
- DiagnosticsLoggerFilteringByScopedPragmas(checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) :> DiagnosticsLogger
+let GetDiagnosticsLoggerFilteringByScopedPragmas (langVersion, scopedPragmas, diagnosticOptions, diagnosticsLogger) =
+ DiagnosticsLoggerFilteringByScopedPragmas(langVersion, scopedPragmas, diagnosticOptions, diagnosticsLogger) :> DiagnosticsLogger
diff --git a/src/Compiler/Driver/CompilerDiagnostics.fsi b/src/Compiler/Driver/CompilerDiagnostics.fsi
index 6139da434cf..7c5acef17d4 100644
--- a/src/Compiler/Driver/CompilerDiagnostics.fsi
+++ b/src/Compiler/Driver/CompilerDiagnostics.fsi
@@ -7,6 +7,7 @@ open System.Text
open FSharp.Compiler.CompilerConfig
open FSharp.Compiler.Diagnostics
open FSharp.Compiler.DiagnosticsLogger
+open FSharp.Compiler.Features
open FSharp.Compiler.Syntax
open FSharp.Compiler.Text
@@ -84,7 +85,7 @@ type PhasedDiagnostic with
/// Get a diagnostics logger that filters the reporting of warnings based on scoped pragma information
val GetDiagnosticsLoggerFilteringByScopedPragmas:
- checkFile: bool *
+ langVersion: LanguageVersion *
scopedPragmas: ScopedPragma list *
diagnosticOptions: FSharpDiagnosticOptions *
diagnosticsLogger: DiagnosticsLogger ->
diff --git a/src/Compiler/Driver/ParseAndCheckInputs.fs b/src/Compiler/Driver/ParseAndCheckInputs.fs
index a6804bfe746..d5d18d79651 100644
--- a/src/Compiler/Driver/ParseAndCheckInputs.fs
+++ b/src/Compiler/Driver/ParseAndCheckInputs.fs
@@ -511,7 +511,7 @@ let ParseInput
finally
// OK, now commit the errors, since the ScopedPragmas will (hopefully) have been scraped
let filteringDiagnosticsLogger =
- GetDiagnosticsLoggerFilteringByScopedPragmas(false, scopedPragmas, diagnosticOptions, diagnosticsLogger)
+ GetDiagnosticsLoggerFilteringByScopedPragmas(lexbuf.LanguageVersion, scopedPragmas, diagnosticOptions, diagnosticsLogger)
delayLogger.CommitDelayedDiagnostics filteringDiagnosticsLogger
@@ -1429,7 +1429,7 @@ let CheckOneInput
// Within a file, equip loggers to locally filter w.r.t. scope pragmas in each input
let DiagnosticsLoggerForInput (tcConfig: TcConfig, input: ParsedInput, oldLogger) =
- GetDiagnosticsLoggerFilteringByScopedPragmas(false, input.ScopedPragmas, tcConfig.diagnosticsOptions, oldLogger)
+ GetDiagnosticsLoggerFilteringByScopedPragmas(tcConfig.langVersion, input.ScopedPragmas, tcConfig.diagnosticsOptions, oldLogger)
/// Typecheck a single file (or interactive entry into F# Interactive)
let CheckOneInputEntry (ctok, checkForErrors, tcConfig: TcConfig, tcImports, tcGlobals, prefixPathOpt) tcState input =
diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs
index ac4ee179538..9dccdec826d 100644
--- a/src/Compiler/Driver/fsc.fs
+++ b/src/Compiler/Driver/fsc.fs
@@ -745,7 +745,7 @@ let main2
yield! pragmas
]
- GetDiagnosticsLoggerFilteringByScopedPragmas(true, scopedPragmas, tcConfig.diagnosticsOptions, oldLogger)
+ GetDiagnosticsLoggerFilteringByScopedPragmas(tcConfig.langVersion, scopedPragmas, tcConfig.diagnosticsOptions, oldLogger)
SetThreadDiagnosticsLoggerNoUnwind diagnosticsLogger
diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt
index b5a50afc7c0..2e391fa5515 100644
--- a/src/Compiler/FSComp.txt
+++ b/src/Compiler/FSComp.txt
@@ -1783,4 +1783,5 @@ featureEmptyBodiedComputationExpressions,"Support for computation expressions wi
featureAllowAccessModifiersToAutoPropertiesGettersAndSetters,"Allow access modifiers to auto properties getters and setters"
3871,tcAccessModifiersNotAllowedInSRTPConstraint,"Access modifiers cannot be applied to an SRTP constraint."
featureAllowObjectExpressionWithoutOverrides,"Allow object expressions without overrides"
-3872,tcPartialActivePattern,"Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."
\ No newline at end of file
+3872,tcPartialActivePattern,"Multi-case partial active patterns are not supported. Consider using a single-case partial active pattern or a full active pattern."
+featureConsistentNowarnLineDirectiveInteraction,"The interaction between #nowarn and #line is now consistent."
diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs
index 5c311237594..530d0e5f2ba 100644
--- a/src/Compiler/Facilities/LanguageFeatures.fs
+++ b/src/Compiler/Facilities/LanguageFeatures.fs
@@ -94,6 +94,7 @@ type LanguageFeature =
| ParsedHashDirectiveArgumentNonQuotes
| EmptyBodiedComputationExpressions
| AllowObjectExpressionWithoutOverrides
+ | ConsistentNowarnLineDirectiveInteraction
/// LanguageVersion management
type LanguageVersion(versionText) =
@@ -213,6 +214,7 @@ type LanguageVersion(versionText) =
LanguageFeature.ParsedHashDirectiveArgumentNonQuotes, languageVersion90
LanguageFeature.EmptyBodiedComputationExpressions, languageVersion90
LanguageFeature.EnforceAttributeTargets, languageVersion90
+ LanguageFeature.ConsistentNowarnLineDirectiveInteraction, languageVersion90
// F# preview
LanguageFeature.UnmanagedConstraintCsharpInterop, previewVersion // not enabled because: https://github.com/dotnet/fsharp/issues/17509
@@ -375,6 +377,7 @@ type LanguageVersion(versionText) =
| LanguageFeature.ParsedHashDirectiveArgumentNonQuotes -> FSComp.SR.featureParsedHashDirectiveArgumentNonString ()
| LanguageFeature.EmptyBodiedComputationExpressions -> FSComp.SR.featureEmptyBodiedComputationExpressions ()
| LanguageFeature.AllowObjectExpressionWithoutOverrides -> FSComp.SR.featureAllowObjectExpressionWithoutOverrides ()
+ | LanguageFeature.ConsistentNowarnLineDirectiveInteraction -> FSComp.SR.featureConsistentNowarnLineDirectiveInteraction ()
/// Get a version string associated with the given feature.
static member GetFeatureVersionString feature =
diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi
index 7408300b943..4ae722c7f60 100644
--- a/src/Compiler/Facilities/LanguageFeatures.fsi
+++ b/src/Compiler/Facilities/LanguageFeatures.fsi
@@ -85,6 +85,7 @@ type LanguageFeature =
| ParsedHashDirectiveArgumentNonQuotes
| EmptyBodiedComputationExpressions
| AllowObjectExpressionWithoutOverrides
+ | ConsistentNowarnLineDirectiveInteraction
/// LanguageVersion management
type LanguageVersion =
diff --git a/src/Compiler/Service/IncrementalBuild.fs b/src/Compiler/Service/IncrementalBuild.fs
index 6b0c3f36c46..89f23605c79 100644
--- a/src/Compiler/Service/IncrementalBuild.fs
+++ b/src/Compiler/Service/IncrementalBuild.fs
@@ -259,7 +259,7 @@ type BoundModel private (
IncrementalBuilderEventTesting.MRU.Add(IncrementalBuilderEventTesting.IBETypechecked fileName)
let capturingDiagnosticsLogger = CapturingDiagnosticsLogger("TypeCheck")
- let diagnosticsLogger = GetDiagnosticsLoggerFilteringByScopedPragmas(false, input.ScopedPragmas, tcConfig.diagnosticsOptions, capturingDiagnosticsLogger)
+ let diagnosticsLogger = GetDiagnosticsLoggerFilteringByScopedPragmas(tcConfig.langVersion, input.ScopedPragmas, tcConfig.diagnosticsOptions, capturingDiagnosticsLogger)
use _ = new CompilationGlobalsScope(diagnosticsLogger, BuildPhase.TypeCheck)
beforeFileChecked.Trigger fileName
diff --git a/src/Compiler/Service/TransparentCompiler.fs b/src/Compiler/Service/TransparentCompiler.fs
index a2bc0beaf4b..908e2893124 100644
--- a/src/Compiler/Service/TransparentCompiler.fs
+++ b/src/Compiler/Service/TransparentCompiler.fs
@@ -1299,7 +1299,12 @@ type internal TransparentCompiler
let diagnosticsLogger = errHandler.DiagnosticsLogger
let diagnosticsLogger =
- GetDiagnosticsLoggerFilteringByScopedPragmas(false, input.ScopedPragmas, tcConfig.diagnosticsOptions, diagnosticsLogger)
+ GetDiagnosticsLoggerFilteringByScopedPragmas(
+ tcConfig.langVersion,
+ input.ScopedPragmas,
+ tcConfig.diagnosticsOptions,
+ diagnosticsLogger
+ )
use _ = new CompilationGlobalsScope(diagnosticsLogger, BuildPhase.TypeCheck)
diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy
index e355a31e2f3..762af2b709e 100644
--- a/src/Compiler/pars.fsy
+++ b/src/Compiler/pars.fsy
@@ -2,6 +2,7 @@
%{
+#nowarn "64" // turn off warnings that type variables used in production annotations are instantiated to concrete type
#nowarn "1182" // generated code has lots of unused "parseState"
#nowarn "3261" // the generated code would need to properly annotate nulls, e.g. changing System.Object to `obj|null`
diff --git a/src/Compiler/pppars.fsy b/src/Compiler/pppars.fsy
index cd27722a254..41cb41ff38a 100644
--- a/src/Compiler/pppars.fsy
+++ b/src/Compiler/pppars.fsy
@@ -3,6 +3,7 @@
%{
open FSharp.Compiler.DiagnosticsLogger
+#nowarn "64" // turn off warnings that type variables used in production annotations are instantiated to concrete type
#nowarn "3261" // the generated code would need to properly annotate nulls, e.g. changing System.Object to `obj|null`
let dummy = IfdefId("DUMMY")
diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf
index 2b1a9483def..39b41f3b382 100644
--- a/src/Compiler/xlf/FSComp.txt.cs.xlf
+++ b/src/Compiler/xlf/FSComp.txt.cs.xlf
@@ -307,6 +307,11 @@
Vyvolá upozornění, pokud je atribut TailCall použit u nerekurzivních funkcí.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesPrůnik omezení u flexibilních typů
diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf
index a1b2532e4db..402571c8a5a 100644
--- a/src/Compiler/xlf/FSComp.txt.de.xlf
+++ b/src/Compiler/xlf/FSComp.txt.de.xlf
@@ -307,6 +307,11 @@
Löst Warnungen aus, wenn das Attribut "TailCall" für nicht rekursive Funktionen verwendet wird.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesEinschränkungsüberschneidung für flexible Typen
diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf
index dd9cbb7fec6..d3267a7425c 100644
--- a/src/Compiler/xlf/FSComp.txt.es.xlf
+++ b/src/Compiler/xlf/FSComp.txt.es.xlf
@@ -307,6 +307,11 @@
Genera advertencias si el atributo 'TailCall' se usa en funciones no recursivas.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesIntersección de restricciones en tipos flexibles
diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf
index 2cc92e5f4d5..f74bc4e3196 100644
--- a/src/Compiler/xlf/FSComp.txt.fr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.fr.xlf
@@ -307,6 +307,11 @@
Émet des avertissements si l’attribut « TailCall » est utilisé sur des fonctions non récursives.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesIntersection de contraintes sur les types flexibles
diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf
index 5b5793c4841..3495d0c1659 100644
--- a/src/Compiler/xlf/FSComp.txt.it.xlf
+++ b/src/Compiler/xlf/FSComp.txt.it.xlf
@@ -307,6 +307,11 @@
Genera avvisi se l'attributo 'TailCall' viene utilizzato in funzioni non ricorsive.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesIntersezione di vincoli su tipi flessibili
diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf
index d30efc74724..a87915633be 100644
--- a/src/Compiler/xlf/FSComp.txt.ja.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ja.xlf
@@ -307,6 +307,11 @@
'TailCall' 属性が再帰関数以外で使用されている場合、警告が発せられます。
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesフレキシブル型の制約積集合
diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf
index c9359c56807..70a64e75a53 100644
--- a/src/Compiler/xlf/FSComp.txt.ko.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ko.xlf
@@ -307,6 +307,11 @@
'TailCall' 특성이 비 재귀 함수에 사용되는 경우 경고를 발생합니다.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible types유연한 형식의 제약 조건 교집합
diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf
index 933379b9f7b..31b8d2a6215 100644
--- a/src/Compiler/xlf/FSComp.txt.pl.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pl.xlf
@@ -307,6 +307,11 @@
Zgłasza ostrzeżenia, jeśli atrybut „TailCall” jest używany w funkcjach niekursywnych.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesPrzecięcie ograniczenia dla typów elastycznych
diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
index e6480e13025..c49d815ca06 100644
--- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
+++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf
@@ -307,6 +307,11 @@
Gera avisos se o atributo "TailCall" for usado em funções não recursivas.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesInterseção de restrição em tipos flexíveis
diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf
index 61c03885917..495089d8c53 100644
--- a/src/Compiler/xlf/FSComp.txt.ru.xlf
+++ b/src/Compiler/xlf/FSComp.txt.ru.xlf
@@ -307,6 +307,11 @@
Выдает предупреждения, если атрибут TailCall используется в нерекурсивных функциях.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesПересечение ограничений на гибких типах
diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf
index 09c113ee3f1..93dfdedb2bd 100644
--- a/src/Compiler/xlf/FSComp.txt.tr.xlf
+++ b/src/Compiler/xlf/FSComp.txt.tr.xlf
@@ -307,6 +307,11 @@
'TailCall' özniteliği özyinelemeli olmayan işlevlerde kullanılıyorsa uyarılar oluşturur.
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible typesEsnek türlerde kısıtlama kesişimi
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
index d9573b5bed2..54f6b088094 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf
@@ -307,6 +307,11 @@
如果在非递归函数上使用“TailCall”属性,则引发警告。
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible types灵活类型的约束交集
diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
index 1a6c3de6ccf..df3a706ae28 100644
--- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
+++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf
@@ -307,6 +307,11 @@
如果 'TailCall' 屬性用於非遞迴函數,則引發警告。
+
+ The interaction between #nowarn and #line is now consistent.
+ The interaction between #nowarn and #line is now consistent.
+
+ Constraint intersection on flexible types彈性類型上的條件約束交集
diff --git a/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Nowarn.fs b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Nowarn.fs
new file mode 100644
index 00000000000..78067aa8c32
--- /dev/null
+++ b/tests/FSharp.Compiler.ComponentTests/CompilerDirectives/Nowarn.fs
@@ -0,0 +1,51 @@
+// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
+namespace CompilerDirectives
+
+open Xunit
+open FSharp.Test.Compiler
+
+module Nowarn =
+
+ let warn20Text = "The result of this expression has type 'string' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'."
+
+ let checkFileBugSource = """
+module A
+#nowarn "20"
+#line 1 "xyz.fs"
+""
+ """
+
+ let checkFileBugSource2 = """
+module A
+#line 1 "xyz.fs"
+#nowarn "20"
+""
+ """
+
+
+ []
+ let ``checkFile bug simulation for compatibility`` () =
+
+ FSharp checkFileBugSource
+ |> withLangVersion80
+ |> compile
+ |> shouldSucceed
+
+ []
+ let ``checkFile bug fixed leads to new warning`` () =
+
+ FSharp checkFileBugSource
+ |> withLangVersion90
+ |> compile
+ |> shouldFail
+ |> withDiagnostics [
+ (Warning 20, Line 1, Col 1, Line 1, Col 3, warn20Text)
+ ]
+
+ []
+ let ``checkFile bug fixed, no warning if nowarn is correctly used`` () =
+
+ FSharp checkFileBugSource2
+ |> withLangVersion90
+ |> compile
+ |> shouldSucceed
diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
index 5f352a315ee..f7e63b79621 100644
--- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
+++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj
@@ -33,6 +33,7 @@
+