Skip to content

Commit 71788e5

Browse files
authored
Merge branch 'main' into fix-10697
2 parents 2669c9b + 29bcaf1 commit 71788e5

File tree

999 files changed

+3683
-1870
lines changed

Some content is hidden

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

999 files changed

+3683
-1870
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
* Add a switch to determine whether to generate a default implementation body for overridden method when completing. [PR #18341](https://github.com/dotnet/fsharp/pull/18341)
4545
* Use a more accurate range for CE Combine methods. [PR #18394](https://github.com/dotnet/fsharp/pull/18394)
4646
* Enable TypeSubsumptionCache for IDE use. [PR #18499](https://github.com/dotnet/fsharp/pull/18499)
47-
47+
* Scoped Nowarn: Add the #warnon compiler directive ([Language suggestion #278](https://github.com/fsharp/fslang-suggestions/issues/278), [RFC FS-1146 PR](https://github.com/fsharp/fslang-design/pull/782), [PR #18049](https://github.com/dotnet/fsharp/pull/18049))
4848

4949
### Changed
5050
* FSharpCheckFileResults.ProjectContext.ProjectOptions will not be available when using the experimental Transparent Compiler feature. ([PR #18205](https://github.com/dotnet/fsharp/pull/18205))
@@ -55,6 +55,7 @@
5555
* Warning for "useless null handling" works with piped syntax constructs now ([PR #18331](https://github.com/dotnet/fsharp/pull/18331))
5656
* Make indent in generated overridden member code depend on the context, not fix to 4. ([PR #18341](https://github.com/dotnet/fsharp/pull/18341))
5757
* Adjust caller info attribute error message range ([PR #18388](https://github.com/dotnet/fsharp/pull/18388))
58+
* Make attribute targets mismatch a warning and not an error ([PR #18492](https://github.com/dotnet/fsharp/pull/18492))
5859

5960
### Breaking Changes
6061
* Struct unions with overlapping fields now generate mappings needed for reading via reflection ([Issue #18121](https://github.com/dotnet/fsharp/issues/17797), [PR #18274](https://github.com/dotnet/fsharp/pull/17877))

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Support ValueOption + Struct attribute as optional parameter for methods ([Language suggestion #1136](https://github.com/fsharp/fslang-suggestions/issues/1136), [PR #18098](https://github.com/dotnet/fsharp/pull/18098))
77
* Allow `_` in `use!` bindings values (lift FS1228 restriction) ([PR #18487](https://github.com/dotnet/fsharp/pull/18487))
88
* Warn when `unit` is passed to an `obj`-typed argument ([PR #18330](https://github.com/dotnet/fsharp/pull/18330))
9+
* Scoped Nowarn: added the #warnon compiler directive ([Language suggestion #278](https://github.com/fsharp/fslang-suggestions/issues/278), [RFC FS-1146 PR](https://github.com/fsharp/fslang-design/pull/782), [PR #18049](https://github.com/dotnet/fsharp/pull/18049))
910

1011
### Fixed
1112

src/Compiler/Checking/CheckDeclarations.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5752,7 +5752,7 @@ let CheckOneImplFile
57525752
synImplFile,
57535753
diagnosticOptions) =
57545754

5755-
let (ParsedImplFileInput (fileName, isScript, qualNameOfFile, scopedPragmas, _, implFileFrags, isLastCompiland, _, _)) = synImplFile
5755+
let (ParsedImplFileInput (fileName, isScript, qualNameOfFile, _, implFileFrags, isLastCompiland, _, _)) = synImplFile
57565756
let infoReader = InfoReader(g, amap)
57575757

57585758
cancellable {
@@ -5891,7 +5891,7 @@ let CheckOneImplFile
58915891
|> Array.map (fun (KeyValue(k,v)) -> (k,v))
58925892
|> Map
58935893

5894-
let implFile = CheckedImplFile (qualNameOfFile, scopedPragmas, implFileTy, implFileContents, hasExplicitEntryPoint, isScript, anonRecdTypes, namedDebugPointsForInlinedCode)
5894+
let implFile = CheckedImplFile (qualNameOfFile, implFileTy, implFileContents, hasExplicitEntryPoint, isScript, anonRecdTypes, namedDebugPointsForInlinedCode)
58955895

58965896
return (topAttrs, implFile, envAtEnd, cenv.createsGeneratedProvidedTypes)
58975897
}

src/Compiler/Checking/Expressions/CheckExpressions.fs

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3187,6 +3187,24 @@ let BuildRecdFieldSet g m objExpr (rfinfo: RecdFieldInfo) argExpr =
31873187
let wrap, objExpr, _readonly, _writeonly = mkExprAddrOfExpr g boxity false DefinitelyMutates objExpr None m
31883188
wrap (mkRecdFieldSetViaExprAddr (objExpr, rfinfo.RecdFieldRef, rfinfo.TypeInst, argExpr, m) )
31893189

3190+
// This is used to check the target of an attribute with the form of
3191+
// Long Form: [<target:attribute-name(arguments)>]
3192+
// Short Form: [<attribute-name(arguments)>]
3193+
let (|LongFormAttrTarget|UnrecognizedLongAttrTarget|ShortFormAttributeTarget|) (targetIndicator: Ident option) =
3194+
match targetIndicator with
3195+
| Some id when id.idText = "assembly" -> LongFormAttrTarget AttributeTargets.Assembly
3196+
| Some id when id.idText = "module" -> LongFormAttrTarget AttributeTargets.Module
3197+
| Some id when id.idText = "return" -> LongFormAttrTarget AttributeTargets.ReturnValue
3198+
| Some id when id.idText = "field" -> LongFormAttrTarget AttributeTargets.Field
3199+
| Some id when id.idText = "property" -> LongFormAttrTarget AttributeTargets.Property
3200+
| Some id when id.idText = "method" -> LongFormAttrTarget AttributeTargets.Method
3201+
| Some id when id.idText = "param" -> LongFormAttrTarget AttributeTargets.Parameter
3202+
| Some id when id.idText = "type" -> LongFormAttrTarget AttributeTargets.TyconDecl
3203+
| Some id when id.idText = "constructor" -> LongFormAttrTarget AttributeTargets.Constructor
3204+
| Some id when id.idText = "event" -> LongFormAttrTarget AttributeTargets.Event
3205+
| Some id -> UnrecognizedLongAttrTarget id
3206+
| None -> ShortFormAttributeTarget
3207+
31903208
//-------------------------------------------------------------------------
31913209
// Helpers dealing with named and optional args at callsites
31923210
//-------------------------------------------------------------------------
@@ -11344,30 +11362,21 @@ and TcAttributeEx canFail (cenv: cenv) (env: TcEnv) attrTgt attrEx (synAttr: Syn
1134411362
(validOnDefault, inheritedDefault)
1134511363
| _ ->
1134611364
(validOnDefault, inheritedDefault)
11347-
let possibleTgts = enum validOn &&& attrTgt
11348-
let directedTgts =
11365+
let attributeTargets = enum validOn &&& attrTgt
11366+
let directedTargets =
1134911367
match targetIndicator with
11350-
| Some id when id.idText = "assembly" -> AttributeTargets.Assembly
11351-
| Some id when id.idText = "module" -> AttributeTargets.Module
11352-
| Some id when id.idText = "return" -> AttributeTargets.ReturnValue
11353-
| Some id when id.idText = "field" -> AttributeTargets.Field
11354-
| Some id when id.idText = "property" -> AttributeTargets.Property
11355-
| Some id when id.idText = "method" -> AttributeTargets.Method
11356-
| Some id when id.idText = "param" -> AttributeTargets.Parameter
11357-
| Some id when id.idText = "type" -> AttributeTargets.TyconDecl
11358-
| Some id when id.idText = "constructor" -> AttributeTargets.Constructor
11359-
| Some id when id.idText = "event" -> AttributeTargets.Event
11360-
| Some id ->
11361-
errorR(Error(FSComp.SR.tcUnrecognizedAttributeTarget(), id.idRange))
11362-
possibleTgts
11363-
// mask explicit targets
11364-
| _ -> possibleTgts &&& ~~~ attrEx
11365-
let constrainedTgts = possibleTgts &&& directedTgts
11366-
if constrainedTgts = enum 0 then
11367-
if (directedTgts = AttributeTargets.Assembly || directedTgts = AttributeTargets.Module) then
11368+
| LongFormAttrTarget attrTarget -> attrTarget
11369+
| UnrecognizedLongAttrTarget attrTarget ->
11370+
errorR(Error(FSComp.SR.tcUnrecognizedAttributeTarget(), attrTarget.idRange))
11371+
attributeTargets
11372+
| ShortFormAttributeTarget -> attributeTargets &&& ~~~ attrEx
11373+
11374+
let constrainedTargets = attributeTargets &&& directedTargets
11375+
if constrainedTargets = enum 0 then
11376+
if (directedTargets = AttributeTargets.Assembly || directedTargets = AttributeTargets.Module) then
1136811377
error(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElementUseDo(), mAttr))
1136911378
else
11370-
error(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElement(), mAttr))
11379+
warning(Error(FSComp.SR.tcAttributeIsNotValidForLanguageElement(), mAttr))
1137111380

1137211381
match ResolveObjectConstructor cenv.nameResolver env.DisplayEnv mAttr ad ty with
1137311382
| Exception _ when canFail = TcCanFail.IgnoreAllErrors || canFail = TcCanFail.IgnoreMemberResoutionError -> [ ], true
@@ -11428,19 +11437,19 @@ and TcAttributeEx canFail (cenv: cenv) (env: TcEnv) attrTgt attrEx (synAttr: Syn
1142811437
if isStruct then error (Error(FSComp.SR.tcCustomAttributeMustBeReferenceType(), m))
1142911438
if args.Length <> ilMethRef.ArgTypes.Length then error (Error(FSComp.SR.tcCustomAttributeArgumentMismatch(), m))
1143011439
let args = args |> List.map mkAttribExpr
11431-
Attrib(tcref, ILAttrib ilMethRef, args, namedAttribArgMap, isAppliedToGetterOrSetter, Some constrainedTgts, m)
11440+
Attrib(tcref, ILAttrib ilMethRef, args, namedAttribArgMap, isAppliedToGetterOrSetter, Some constrainedTargets, m)
1143211441

1143311442
| Expr.App (InnerExprPat(ExprValWithPossibleTypeInst(vref, _, _, _)), _, _, args, _) ->
1143411443
let args = args |> List.collect (function Expr.Const (Const.Unit, _, _) -> [] | expr -> tryDestRefTupleExpr expr) |> List.map mkAttribExpr
11435-
Attrib(tcref, FSAttrib vref, args, namedAttribArgMap, isAppliedToGetterOrSetter, Some constrainedTgts, mAttr)
11444+
Attrib(tcref, FSAttrib vref, args, namedAttribArgMap, isAppliedToGetterOrSetter, Some constrainedTargets, mAttr)
1143611445

1143711446
| _ ->
1143811447
error (Error(FSComp.SR.tcCustomAttributeMustInvokeConstructor(), mAttr))
1143911448

1144011449
| _ ->
1144111450
error(Error(FSComp.SR.tcAttributeExpressionsMustBeConstructorCalls(), mAttr))
1144211451

11443-
[ (constrainedTgts, attrib) ], false
11452+
[ (constrainedTargets, attrib) ], false
1144411453

1144511454
and TcAttributesWithPossibleTargetsEx canFail (cenv: cenv) env attrTgt attrEx synAttribs =
1144611455

src/Compiler/CodeGen/IlxGen.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10391,7 +10391,7 @@ and GenModuleBinding cenv (cgbuf: CodeGenBuffer) (qname: QualifiedNameOfFile) la
1039110391

1039210392
/// Generate the namespace fragments in a single file
1039310393
and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: CheckedImplFileAfterOptimization) =
10394-
let (CheckedImplFile(qname, _, signature, contents, hasExplicitEntryPoint, isScript, anonRecdTypes, _)) =
10394+
let (CheckedImplFile(qname, signature, contents, hasExplicitEntryPoint, isScript, anonRecdTypes, _)) =
1039510395
implFile.ImplFile
1039610396

1039710397
let optimizeDuringCodeGen = implFile.OptimizeDuringCodeGen

src/Compiler/Driver/CompilerDiagnostics.fs

Lines changed: 19 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ type PhasedDiagnostic with
379379
// Level 2
380380
| _ -> 2
381381

382-
member x.IsEnabled(severity, options) =
382+
member private x.IsEnabled(severity, options) =
383383
let level = options.WarnLevel
384384
let specificWarnOn = options.WarnOn
385385
let n = x.Number
@@ -412,19 +412,25 @@ type PhasedDiagnostic with
412412
member x.AdjustSeverity(options, severity) =
413413
let n = x.Number
414414

415-
let warnOff () = List.contains n options.WarnOff
415+
let localWarnon () = WarnScopes.IsWarnon options n x.Range
416+
417+
let localNowarn () = WarnScopes.IsNowarn options n x.Range
418+
419+
let warnOff () =
420+
List.contains n options.WarnOff && not (localWarnon ()) || localNowarn ()
416421

417422
match severity with
418423
| FSharpDiagnosticSeverity.Error -> FSharpDiagnosticSeverity.Error
419424
| FSharpDiagnosticSeverity.Warning when
420425
x.IsEnabled(severity, options)
421426
&& ((options.GlobalWarnAsError && not (warnOff ()))
422-
|| List.contains n options.WarnAsError)
427+
|| List.contains n options.WarnAsError && not (localNowarn ()))
423428
&& not (List.contains n options.WarnAsWarn)
424429
->
425430
FSharpDiagnosticSeverity.Error
431+
| FSharpDiagnosticSeverity.Info when List.contains n options.WarnAsError && not (localNowarn ()) -> FSharpDiagnosticSeverity.Error
426432
| FSharpDiagnosticSeverity.Warning when x.IsEnabled(severity, options) && not (warnOff ()) -> FSharpDiagnosticSeverity.Warning
427-
| FSharpDiagnosticSeverity.Info when List.contains n options.WarnAsError -> FSharpDiagnosticSeverity.Error
433+
| FSharpDiagnosticSeverity.Warning when localWarnon () -> FSharpDiagnosticSeverity.Warning
428434
| FSharpDiagnosticSeverity.Info when List.contains n options.WarnOn && not (warnOff ()) -> FSharpDiagnosticSeverity.Warning
429435
| FSharpDiagnosticSeverity.Info when x.IsEnabled(severity, options) && not (warnOff ()) -> FSharpDiagnosticSeverity.Info
430436
| _ -> FSharpDiagnosticSeverity.Hidden
@@ -2274,51 +2280,25 @@ type PhasedDiagnostic with
22742280
diagnostic.OutputContext(buf, prefix, fileLineFunction)
22752281
diagnostic.Output(buf, tcConfig, severity))
22762282

2277-
//----------------------------------------------------------------------------
2278-
// Scoped #nowarn pragmas
2279-
2280-
/// Build an DiagnosticsLogger that delegates to another DiagnosticsLogger but filters warnings turned off by the given pragma declarations
2281-
//
2282-
// NOTE: we allow a flag to turn of strict file checking. This is because file names sometimes don't match due to use of
2283-
// #line directives, e.g. for pars.fs/pars.fsy. In this case we just test by line number - in most cases this is sufficient
2284-
// because we install a filtering error handler on a file-by-file basis for parsing and type-checking.
2285-
// However this is indicative of a more systematic problem where source-line
2286-
// sensitive operations (lexfilter and warning filtering) do not always
2287-
// interact well with #line directives.
2288-
type DiagnosticsLoggerFilteringByScopedPragmas
2289-
(checkFile, scopedPragmas, diagnosticOptions: FSharpDiagnosticOptions, diagnosticsLogger: DiagnosticsLogger) =
2290-
inherit DiagnosticsLogger("DiagnosticsLoggerFilteringByScopedPragmas")
2283+
/// Build an DiagnosticsLogger that delegates to another DiagnosticsLogger but filters warnings
2284+
type DiagnosticsLoggerFilteringByScopedNowarn(diagnosticOptions: FSharpDiagnosticOptions, diagnosticsLogger: DiagnosticsLogger) =
2285+
inherit DiagnosticsLogger("DiagnosticsLoggerFilteringByScopedNowarn")
22912286

22922287
let mutable realErrorPresent = false
22932288

22942289
override _.DiagnosticSink(diagnostic: PhasedDiagnostic, severity) =
2290+
22952291
if severity = FSharpDiagnosticSeverity.Error then
22962292
realErrorPresent <- true
22972293
diagnosticsLogger.DiagnosticSink(diagnostic, severity)
22982294
else
2299-
let report =
2300-
let warningNum = diagnostic.Number
2301-
2302-
match diagnostic.Range with
2303-
| Some m ->
2304-
scopedPragmas
2305-
|> List.exists (fun pragma ->
2306-
let (ScopedPragma.WarningOff(pragmaRange, warningNumFromPragma)) = pragma
2307-
2308-
warningNum = warningNumFromPragma
2309-
&& (not checkFile || m.FileIndex = pragmaRange.FileIndex)
2310-
&& posGeq m.Start pragmaRange.Start)
2311-
|> not
2312-
| None -> true
2313-
2314-
if report then
2315-
match diagnostic.AdjustSeverity(diagnosticOptions, severity) with
2316-
| FSharpDiagnosticSeverity.Hidden -> ()
2317-
| s -> diagnosticsLogger.DiagnosticSink(diagnostic, s)
2295+
match diagnostic.AdjustSeverity(diagnosticOptions, severity) with
2296+
| FSharpDiagnosticSeverity.Hidden -> ()
2297+
| s -> diagnosticsLogger.DiagnosticSink(diagnostic, s)
23182298

23192299
override _.ErrorCount = diagnosticsLogger.ErrorCount
23202300

23212301
override _.CheckForRealErrorsIgnoringWarnings = realErrorPresent
23222302

2323-
let GetDiagnosticsLoggerFilteringByScopedPragmas (checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) =
2324-
DiagnosticsLoggerFilteringByScopedPragmas(checkFile, scopedPragmas, diagnosticOptions, diagnosticsLogger) :> DiagnosticsLogger
2303+
let GetDiagnosticsLoggerFilteringByScopedNowarn (diagnosticOptions, diagnosticsLogger) =
2304+
DiagnosticsLoggerFilteringByScopedNowarn(diagnosticOptions, diagnosticsLogger) :> DiagnosticsLogger

src/Compiler/Driver/CompilerDiagnostics.fsi

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,8 @@ type PhasedDiagnostic with
7777
unit
7878

7979
/// Get a diagnostics logger that filters the reporting of warnings based on scoped pragma information
80-
val GetDiagnosticsLoggerFilteringByScopedPragmas:
81-
checkFile: bool *
82-
scopedPragmas: ScopedPragma list *
83-
diagnosticOptions: FSharpDiagnosticOptions *
84-
diagnosticsLogger: DiagnosticsLogger ->
85-
DiagnosticsLogger
80+
val GetDiagnosticsLoggerFilteringByScopedNowarn:
81+
diagnosticOptions: FSharpDiagnosticOptions * diagnosticsLogger: DiagnosticsLogger -> DiagnosticsLogger
8682

8783
/// Remove 'implicitIncludeDir' from a file name before output
8884
val SanitizeFileName: fileName: string -> implicitIncludeDir: string -> string

0 commit comments

Comments
 (0)