Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into scoped-nowarn
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin521 committed Feb 25, 2025
2 parents 7e3cb94 + c281bd0 commit 991bb3d
Show file tree
Hide file tree
Showing 42 changed files with 357 additions and 65 deletions.
3 changes: 3 additions & 0 deletions docs/release-notes/.FSharp.Compiler.Service/9.0.300.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Cancellable: set token in more places ([PR #18283](https://github.com/dotnet/fsharp/pull/18283))
* Cancellable: fix leaking cancellation token ([PR #18295](https://github.com/dotnet/fsharp/pull/18295))
* Fix NRE when accessing nullable fields of types within their equals/hash/compare methods ([PR #18296](https://github.com/dotnet/fsharp/pull/18296))
* Fix nullness warning for overrides of generic code with nullable type instance ([Issue #17988](https://github.com/dotnet/fsharp/issues/17988), [PR #18337](https://github.com/dotnet/fsharp/pull/18337))

### Added
* Added missing type constraints in FCS. ([PR #18241](https://github.com/dotnet/fsharp/pull/18241))
Expand All @@ -27,6 +28,8 @@
* Update `Obsolete` attribute checking to account for `DiagnosticId` and `UrlFormat` properties. ([PR #18224](https://github.com/dotnet/fsharp/pull/18224))
* Remove `Cancellable.UsingToken` from tests ([PR #18276](https://github.com/dotnet/fsharp/pull/18276))
* Added nullability annotations to `.Using` builder method for `async`, `task` and compiler-internal builders ([PR #18292](https://github.com/dotnet/fsharp/pull/18292))
* Warn when `unit` is passed to an `obj`-typed argument ([PR #18330](https://github.com/dotnet/fsharp/pull/18330))
* Warning for "useless null handling" works with piped syntax constructs now ([PR #18331](https://github.com/dotnet/fsharp/pull/18331))

### Breaking Changes
* 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))
17 changes: 17 additions & 0 deletions docs/release-notes/.FSharp.Core/9.0.101.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## FSharp.Core 9.0.101 did not change compared to version 9.0.100. Below are the changes for FSharp.Core 9.0.100

### Fixed
* Struct UnionCase doesn't seem to be a valid target for the DefaultAugmentationAttribute ([Issue #17499](https://github.com/dotnet/fsharp/issues/17499), [PR #17502](https://github.com/dotnet/fsharp/pull/17502))

### Added

* Enable C# collection expression support for F# lists & sets. ([Language suggestion #1355](https://github.com/fsharp/fslang-suggestions/issues/1355), [RFC FS-1145 (PR#776)](https://github.com/fsharp/fslang-design/pull/776), [PR #17359](https://github.com/dotnet/fsharp/pull/17359))
* Add module functions for converting between `'T option` and `'T voption`. ([PR #17436](https://github.com/dotnet/fsharp/pull/17436))

### Changed
* Change compiler default setting realsig+ when building assemblies ([Issue #17384](https://github.com/dotnet/fsharp/issues/17384), [PR #17378](https://github.com/dotnet/fsharp/pull/17385))
* Change compiler default setting for compressedMetadata ([Issue #17379](https://github.com/dotnet/fsharp/issues/17379), [PR #17383](https://github.com/dotnet/fsharp/pull/17383))
* Enable FSharp 9.0 Language Version ([Issue #17497](https://github.com/dotnet/fsharp/issues/17438)), [PR](https://github.com/dotnet/fsharp/pull/17500)))
* Struct UnionCase doesn't seem to be a valid target for the DefaultAugmentationAttribute ([Issue #17499](https://github.com/dotnet/fsharp/issues/17499), [PR #17502](https://github.com/dotnet/fsharp/pull/17502))
### Breaking Changes

1 change: 1 addition & 0 deletions docs/release-notes/.Language/preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Deprecate places where `seq` can be omitted. ([Language suggestion #1033](https://github.com/fsharp/fslang-suggestions/issues/1033), [PR #17772](https://github.com/dotnet/fsharp/pull/17772))
* Added type conversions cache, only enabled for compiler runs ([PR#17668](https://github.com/dotnet/fsharp/pull/17668))
* 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))
* Warn when `unit` is passed to an `obj`-typed argument ([PR #18330](https://github.com/dotnet/fsharp/pull/18330))
* 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))

### Fixed
Expand Down
7 changes: 5 additions & 2 deletions src/Compiler/Checking/ConstraintSolver.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3177,6 +3177,7 @@ and ArgsMustSubsumeOrConvert
trackErrors {
let g = csenv.g
let m = callerArg.Range
let callerTy = callerArg.CallerArgumentType
let calledArgTy, usesTDC, eqn = AdjustCalledArgType csenv.InfoReader ad isConstraint enforceNullableOptionalsKnownTypes calledArg callerArg

match eqn with
Expand All @@ -3188,8 +3189,10 @@ and ArgsMustSubsumeOrConvert
match usesTDC with
| TypeDirectedConversionUsed.Yes(warn, _, _) -> do! WarnD(warn csenv.DisplayEnv)
| TypeDirectedConversionUsed.No -> ()
do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln (Some calledArg.CalledArgumentType) calledArgTy callerArg.CallerArgumentType
if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerArg.CallerArgumentType) then
do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln (Some calledArg.CalledArgumentType) calledArgTy callerTy
if g.langVersion.SupportsFeature(LanguageFeature.WarnWhenUnitPassedToObjArg) && isUnitTy g callerTy && isObjTyAnyNullness g calledArgTy then
do! WarnD(Error(FSComp.SR.tcUnitToObjSubsumption(), m))
if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerTy) then
return! ErrorD(Error(FSComp.SR.csMethodExpectsParams(), m))
else
return usesTDC
Expand Down
56 changes: 38 additions & 18 deletions src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1890,7 +1890,11 @@ let FreshenAbstractSlot g amap m synTyparDecls absMethInfo =

// Work out the required type of the member
let argTysFromAbsSlot = argTys |> List.mapSquared (instType typarInstFromAbsSlot)
let retTyFromAbsSlot = retTy |> GetFSharpViewOfReturnType g |> instType typarInstFromAbsSlot

let retTyFromAbsSlot =
retTy
|> GetFSharpViewOfReturnType g
|> instType typarInstFromAbsSlot
typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot

let CheckRecdExprDuplicateFields (elems: Ident list) =
Expand Down Expand Up @@ -8568,29 +8572,21 @@ and TcApplicationThen (cenv: cenv) (overallTy: OverallTy) env tpenv mExprAndArg

| _ -> synArg

let (arg, tpenv), cenv =
let (arg, tpenv) =
// treat left and right of '||' and '&&' as control flow, so for example
// f expr1 && g expr2
// will have debug points on "f expr1" and "g expr2"
let env,cenv =
let env =
match leftExpr with
| ApplicableExpr(expr=Expr.Val (vref, _, _))
| ApplicableExpr(expr=Expr.App (Expr.Val (vref, _, _), _, _, [_], _))
when valRefEq g vref g.and_vref
|| valRefEq g vref g.and2_vref
|| valRefEq g vref g.or_vref
|| valRefEq g vref g.or2_vref ->
{ env with eIsControlFlow = true },cenv
| ApplicableExpr(expr=Expr.Val (valRef=vref))
| ApplicableExpr(expr=Expr.App (funcExpr=Expr.Val (valRef=vref))) ->
match TryFindLocalizedFSharpStringAttribute g g.attrib_WarnOnWithoutNullArgumentAttribute vref.Attribs with
| Some _ as msg -> env,{ cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = msg}
| None when cenv.css.WarnWhenUsingWithoutNullOnAWithNullTarget <> None ->
env, { cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = None}
| None -> env,cenv
| _ -> env,cenv

TcExprFlex2 cenv domainTy env false tpenv synArg, cenv
|| valRefEq g vref g.or2_vref -> { env with eIsControlFlow = true }
| _ -> env

TcExprFlex2 cenv domainTy env false tpenv synArg

let exprAndArg, resultTy = buildApp cenv leftExpr resultTy arg mExprAndArg
TcDelayed cenv overallTy env tpenv mExprAndArg exprAndArg resultTy atomicFlag delayed
Expand Down Expand Up @@ -9289,6 +9285,7 @@ and TcValueItemThen cenv overallTy env vref tpenv mItem afterResolution delayed
PropagateThenTcDelayed cenv overallTy env tpenv mExprAndTypeArgs vexpFlex vexpFlex.Type ExprAtomicFlag.Atomic otherDelayed

// Value get

| _ ->
let _, vExpr, isSpecial, _, _, tpenv = TcVal cenv env tpenv vref None (Some afterResolution) mItem

Expand All @@ -9297,6 +9294,19 @@ and TcValueItemThen cenv overallTy env vref tpenv mItem afterResolution delayed
| Expr.Const (Const.String value, _, _) -> TcConstStringExpr cenv overallTy env mItem tpenv value LiteralArgumentType.StaticField
| _ -> vExpr, tpenv

let getCenvForVref cenv (vref:ValRef) =
match TryFindLocalizedFSharpStringAttribute g g.attrib_WarnOnWithoutNullArgumentAttribute vref.Attribs with
| Some _ as msg -> { cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = msg}
| None when cenv.css.WarnWhenUsingWithoutNullOnAWithNullTarget <> None ->
// We need to reset the warning back to default once in a nested call, to prevent false warnings e.g. in `Option.ofObj (Path.GetDirectoryName "")`
{ cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = None}
| None -> cenv

let cenv =
match vExpr with
| Expr.App (funcExpr=Expr.Val (valRef=vref)) -> getCenvForVref cenv vref
| _ -> cenv

let vexpFlex = if isSpecial then MakeApplicableExprNoFlex cenv vExpr else MakeApplicableExprWithFlex cenv env vExpr

PropagateThenTcDelayed cenv overallTy env tpenv mItem vexpFlex vexpFlex.Type ExprAtomicFlag.Atomic delayed
Expand Down Expand Up @@ -11768,16 +11778,26 @@ and ApplyAbstractSlotInference (cenv: cenv) (envinner: TcEnv) (_: Val option) (a
match uniqueAbstractMethSigs with
| uniqueAbstractMeth :: _ ->

// Overrides can narrow the retTy from nullable to not-null.
// By changing nullness to be variable we do not get in the way of eliminating nullness (=good).
// We only keep a WithNull nullness if it was part of an explicit type instantiation
let canChangeNullableRetTy =
match g.checkNullness, renaming with
| false, _ -> false
| true, [] -> true
| true, _ -> not(uniqueAbstractMeth.HasGenericRetTy())

let uniqueAbstractMeth = uniqueAbstractMeth.Instantiate(cenv.amap, m, renaming)

let typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot =
FreshenAbstractSlot g cenv.amap m synTyparDecls uniqueAbstractMeth

let declaredTypars = (if typarsFromAbsSlotAreRigid then typarsFromAbsSlot else declaredTypars)

// Overrides can narrow the retTy from nullable to not-null.
// By changing nullness to be variable we do not get in the way of eliminating nullness (=good).
let retTyFromAbsSlot = retTyFromAbsSlot |> changeWithNullReqTyToVariable g
let retTyFromAbsSlot =
if canChangeNullableRetTy then
retTyFromAbsSlot |> changeWithNullReqTyToVariable g
else retTyFromAbsSlot

let absSlotTy = mkMethodTy g argTysFromAbsSlot retTyFromAbsSlot

Expand Down
14 changes: 14 additions & 0 deletions src/Compiler/Checking/infos.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,20 @@ type MethInfo =
let (ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, reflArgInfo)) = info
ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, nmOpt, reflArgInfo, pty)))

member x.HasGenericRetTy() =
match x with
| ILMeth(_g, ilminfo, _) -> ilminfo.RawMetadata.Return.Type.IsTypeVar
| FSMeth(g, _, vref, _) ->
let _, _, _, retTy, _ = GetTypeOfMemberInMemberForm g vref
match retTy with
| Some retTy -> isTyparTy g retTy
| None -> false
| MethInfoWithModifiedReturnType(_,retTy) -> false
| DefaultStructCtor _ -> false
#if !NO_TYPEPROVIDERS
| ProvidedMeth(amap, mi, _, m) -> false
#endif

/// Get the ParamData objects for the parameters of a MethInfo
member x.HasParamArrayArg(amap, m, minst) =
x.GetParamDatas(amap, m, minst) |> List.existsSquared (fun (ParamData(isParamArrayArg, _, _, _, _, _, _, _)) -> isParamArrayArg)
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Checking/infos.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,8 @@ type MethInfo =
/// Get the signature of an abstract method slot.
member GetSlotSig: amap: ImportMap * m: range -> SlotSig

member HasGenericRetTy: unit -> bool

/// Get the ParamData objects for the parameters of a MethInfo
member HasParamArrayArg: amap: ImportMap * m: range * minst: TType list -> bool

Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,7 @@ forFormatInvalidForInterpolated4,"Interpolated strings used as type IFormattable
3394,parsNewExprMemberAccess,"This member access is ambiguous. Please use parentheses around the object creation, e.g. '(new SomeType(args)).MemberName'"
3395,tcImplicitConversionUsedForMethodArg,"This expression uses the implicit conversion '%s' to convert type '%s' to type '%s'."
3396,tcLiteralAttributeCannotUseActivePattern,"A [<Literal>] declaration cannot use an active pattern for its identifier"
3397,tcUnitToObjSubsumption,"This expression uses 'unit' for an 'obj'-typed argument. This will lead to passing 'null' at runtime. This warning may be disabled using '#nowarn \"3397\"."
3401,ilxgenInvalidConstructInStateMachineDuringCodegen,"The resumable code construct '%s' may only be used in inlined code protected by 'if __useResumableCode then ...' and the overall composition must form valid resumable code."
3402,tcInvalidResumableConstruct,"The construct '%s' may only be used in valid resumable code."
3501,tcResumableCodeFunctionMustBeInline,"Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'"
Expand Down Expand Up @@ -1794,6 +1795,7 @@ featureDontWarnOnUppercaseIdentifiersInBindingPatterns,"Don't warn on uppercase
3874,tcExpectedTypeParamMarkedWithUnitOfMeasureAttribute,"Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute."
featureDeprecatePlacesWhereSeqCanBeOmitted,"Deprecate places where 'seq' can be omitted"
featureSupportValueOptionsAsOptionalParameters,"Support ValueOption as valid type for optional member parameters"
featureSupportWarnWhenUnitPassedToObjArg,"Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`."
featureScopedNowarn,"Support for scoped enabling / disabling of warnings by #warn and #nowarn directives, also inside modules"
3874,lexWarnDirectiveMustBeFirst,"#nowarn/#warnon directives must appear as the first non-whitespace characters on a line"
3875,lexWarnDirectiveMustHaveArgs,"Warn directives must have warning number(s) as argument(s)"
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/Facilities/LanguageFeatures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ type LanguageFeature =
| UseTypeSubsumptionCache
| DeprecatePlacesWhereSeqCanBeOmitted
| SupportValueOptionsAsOptionalParameters
| WarnWhenUnitPassedToObjArg
| ScopedNowarn

/// LanguageVersion management
Expand Down Expand Up @@ -228,6 +229,7 @@ type LanguageVersion(versionText) =
LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns, previewVersion
LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted, previewVersion
LanguageFeature.SupportValueOptionsAsOptionalParameters, previewVersion
LanguageFeature.WarnWhenUnitPassedToObjArg, previewVersion
LanguageFeature.ScopedNowarn, previewVersion
]

Expand Down Expand Up @@ -390,6 +392,7 @@ type LanguageVersion(versionText) =
| LanguageFeature.UseTypeSubsumptionCache -> FSComp.SR.featureUseTypeSubsumptionCache ()
| LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted -> FSComp.SR.featureDeprecatePlacesWhereSeqCanBeOmitted ()
| LanguageFeature.SupportValueOptionsAsOptionalParameters -> FSComp.SR.featureSupportValueOptionsAsOptionalParameters ()
| LanguageFeature.WarnWhenUnitPassedToObjArg -> FSComp.SR.featureSupportWarnWhenUnitPassedToObjArg ()
| LanguageFeature.ScopedNowarn -> FSComp.SR.featureScopedNowarn ()

/// Get a version string associated with the given feature.
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Facilities/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ type LanguageFeature =
| UseTypeSubsumptionCache
| DeprecatePlacesWhereSeqCanBeOmitted
| SupportValueOptionsAsOptionalParameters
| WarnWhenUnitPassedToObjArg
| ScopedNowarn

/// LanguageVersion management
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Interactive/ControlledExecution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// because we continue to support older coreclrs and the windows desktop framework through netstandard2.0
// we access the features using reflection

#nowarn "3262" // The `Option.ofObj (Type.GetType..) construct warns in ns20, because Type.GetType is not annotated as nullable

namespace FSharp.Compiler.Interactive

open System
Expand Down
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.

Loading

0 comments on commit 991bb3d

Please sign in to comment.