Skip to content

Commit 345742d

Browse files
authored
Merge pull request #18339 from dotnet/merge/main-to-release/dev17.14
[automated] Merge branch 'main' => 'release/dev17.14'
2 parents e4889bb + 25edc45 commit 345742d

39 files changed

+339
-35
lines changed

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:
22
{
33
"name": "F#",
4-
"image": "mcr.microsoft.com/dotnet/sdk:9.0.102",
4+
"image": "mcr.microsoft.com/dotnet/sdk:9.0.200",
55
"features": {
66
"ghcr.io/devcontainers/features/common-utils:2.5.2": {},
77
"ghcr.io/devcontainers/features/git:1.3.2": {},

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
* Cancellable: set token in more places ([PR #18283](https://github.com/dotnet/fsharp/pull/18283))
1212
* Cancellable: fix leaking cancellation token ([PR #18295](https://github.com/dotnet/fsharp/pull/18295))
1313
* Fix NRE when accessing nullable fields of types within their equals/hash/compare methods ([PR #18296](https://github.com/dotnet/fsharp/pull/18296))
14+
* 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))
1415

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

3033
### Breaking Changes
3134
* 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))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
## FSharp.Core 9.0.101 did not change compared to version 9.0.100. Below are the changes for FSharp.Core 9.0.100
2+
3+
### Fixed
4+
* 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))
5+
6+
### Added
7+
8+
* 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))
9+
* Add module functions for converting between `'T option` and `'T voption`. ([PR #17436](https://github.com/dotnet/fsharp/pull/17436))
10+
11+
### Changed
12+
* 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))
13+
* Change compiler default setting for compressedMetadata ([Issue #17379](https://github.com/dotnet/fsharp/issues/17379), [PR #17383](https://github.com/dotnet/fsharp/pull/17383))
14+
* Enable FSharp 9.0 Language Version ([Issue #17497](https://github.com/dotnet/fsharp/issues/17438)), [PR](https://github.com/dotnet/fsharp/pull/17500)))
15+
* 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))
16+
### Breaking Changes
17+

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* 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))
55
* Added type conversions cache, only enabled for compiler runs ([PR#17668](https://github.com/dotnet/fsharp/pull/17668))
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))
7+
* Warn when `unit` is passed to an `obj`-typed argument ([PR #18330](https://github.com/dotnet/fsharp/pull/18330))
78

89
### Fixed
910

eng/Versions.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
<FSharpLibrariesChangelogVersion>$(FSMajorVersion).$(FSMinorVersion).$(FSBuildVersion)</FSharpLibrariesChangelogVersion>
3838
<!-- -->
3939
<!-- The current published nuget package -->
40-
<FSharpCoreShippedPackageVersionValue>9.0.101</FSharpCoreShippedPackageVersionValue>
40+
<FSharpCoreShippedPackageVersionValue>9.0.201</FSharpCoreShippedPackageVersionValue>
4141
<!-- -->
4242
<!-- The pattern for specifying the preview package -->
4343
<FSharpCorePreviewPackageVersionValue>$(FSCorePackageVersionValue)-$(PreReleaseVersionLabel).*</FSharpCorePreviewPackageVersionValue>

global.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"sdk": {
3-
"version": "9.0.103",
3+
"version": "9.0.200",
44
"allowPrerelease": true
55
},
66
"tools": {
7-
"dotnet": "9.0.103",
7+
"dotnet": "9.0.200",
88
"vs": {
99
"version": "17.8",
1010
"components": [

src/Compiler/Checking/ConstraintSolver.fs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3177,6 +3177,7 @@ and ArgsMustSubsumeOrConvert
31773177
trackErrors {
31783178
let g = csenv.g
31793179
let m = callerArg.Range
3180+
let callerTy = callerArg.CallerArgumentType
31803181
let calledArgTy, usesTDC, eqn = AdjustCalledArgType csenv.InfoReader ad isConstraint enforceNullableOptionalsKnownTypes calledArg callerArg
31813182

31823183
match eqn with
@@ -3188,8 +3189,10 @@ and ArgsMustSubsumeOrConvert
31883189
match usesTDC with
31893190
| TypeDirectedConversionUsed.Yes(warn, _, _) -> do! WarnD(warn csenv.DisplayEnv)
31903191
| TypeDirectedConversionUsed.No -> ()
3191-
do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln (Some calledArg.CalledArgumentType) calledArgTy callerArg.CallerArgumentType
3192-
if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerArg.CallerArgumentType) then
3192+
do! SolveTypeSubsumesTypeWithReport csenv ndeep m trace cxsln (Some calledArg.CalledArgumentType) calledArgTy callerTy
3193+
if g.langVersion.SupportsFeature(LanguageFeature.WarnWhenUnitPassedToObjArg) && isUnitTy g callerTy && isObjTyAnyNullness g calledArgTy then
3194+
do! WarnD(Error(FSComp.SR.tcUnitToObjSubsumption(), m))
3195+
if calledArg.IsParamArray && isArray1DTy g calledArgTy && not (isArray1DTy g callerTy) then
31933196
return! ErrorD(Error(FSComp.SR.csMethodExpectsParams(), m))
31943197
else
31953198
return usesTDC

src/Compiler/Checking/Expressions/CheckExpressions.fs

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,11 @@ let FreshenAbstractSlot g amap m synTyparDecls absMethInfo =
18901890

18911891
// Work out the required type of the member
18921892
let argTysFromAbsSlot = argTys |> List.mapSquared (instType typarInstFromAbsSlot)
1893-
let retTyFromAbsSlot = retTy |> GetFSharpViewOfReturnType g |> instType typarInstFromAbsSlot
1893+
1894+
let retTyFromAbsSlot =
1895+
retTy
1896+
|> GetFSharpViewOfReturnType g
1897+
|> instType typarInstFromAbsSlot
18941898
typarsFromAbsSlotAreRigid, typarsFromAbsSlot, argTysFromAbsSlot, retTyFromAbsSlot
18951899

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

85698573
| _ -> synArg
85708574

8571-
let (arg, tpenv), cenv =
8575+
let (arg, tpenv) =
85728576
// treat left and right of '||' and '&&' as control flow, so for example
85738577
// f expr1 && g expr2
85748578
// will have debug points on "f expr1" and "g expr2"
8575-
let env,cenv =
8579+
let env =
85768580
match leftExpr with
85778581
| ApplicableExpr(expr=Expr.Val (vref, _, _))
85788582
| ApplicableExpr(expr=Expr.App (Expr.Val (vref, _, _), _, _, [_], _))
85798583
when valRefEq g vref g.and_vref
85808584
|| valRefEq g vref g.and2_vref
85818585
|| valRefEq g vref g.or_vref
8582-
|| valRefEq g vref g.or2_vref ->
8583-
{ env with eIsControlFlow = true },cenv
8584-
| ApplicableExpr(expr=Expr.Val (valRef=vref))
8585-
| ApplicableExpr(expr=Expr.App (funcExpr=Expr.Val (valRef=vref))) ->
8586-
match TryFindLocalizedFSharpStringAttribute g g.attrib_WarnOnWithoutNullArgumentAttribute vref.Attribs with
8587-
| Some _ as msg -> env,{ cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = msg}
8588-
| None when cenv.css.WarnWhenUsingWithoutNullOnAWithNullTarget <> None ->
8589-
env, { cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = None}
8590-
| None -> env,cenv
8591-
| _ -> env,cenv
8592-
8593-
TcExprFlex2 cenv domainTy env false tpenv synArg, cenv
8586+
|| valRefEq g vref g.or2_vref -> { env with eIsControlFlow = true }
8587+
| _ -> env
8588+
8589+
TcExprFlex2 cenv domainTy env false tpenv synArg
85948590

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

92919287
// Value get
9288+
92929289
| _ ->
92939290
let _, vExpr, isSpecial, _, _, tpenv = TcVal cenv env tpenv vref None (Some afterResolution) mItem
92949291

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

9297+
let getCenvForVref cenv (vref:ValRef) =
9298+
match TryFindLocalizedFSharpStringAttribute g g.attrib_WarnOnWithoutNullArgumentAttribute vref.Attribs with
9299+
| Some _ as msg -> { cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = msg}
9300+
| None when cenv.css.WarnWhenUsingWithoutNullOnAWithNullTarget <> None ->
9301+
// 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 "")`
9302+
{ cenv with css.WarnWhenUsingWithoutNullOnAWithNullTarget = None}
9303+
| None -> cenv
9304+
9305+
let cenv =
9306+
match vExpr with
9307+
| Expr.App (funcExpr=Expr.Val (valRef=vref)) -> getCenvForVref cenv vref
9308+
| _ -> cenv
9309+
93009310
let vexpFlex = if isSpecial then MakeApplicableExprNoFlex cenv vExpr else MakeApplicableExprWithFlex cenv env vExpr
93019311

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

11781+
// Overrides can narrow the retTy from nullable to not-null.
11782+
// By changing nullness to be variable we do not get in the way of eliminating nullness (=good).
11783+
// We only keep a WithNull nullness if it was part of an explicit type instantiation
11784+
let canChangeNullableRetTy =
11785+
match g.checkNullness, renaming with
11786+
| false, _ -> false
11787+
| true, [] -> true
11788+
| true, _ -> not(uniqueAbstractMeth.HasGenericRetTy())
11789+
1177111790
let uniqueAbstractMeth = uniqueAbstractMeth.Instantiate(cenv.amap, m, renaming)
1177211791

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

1177611795
let declaredTypars = (if typarsFromAbsSlotAreRigid then typarsFromAbsSlot else declaredTypars)
1177711796

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

1178211802
let absSlotTy = mkMethodTy g argTysFromAbsSlot retTyFromAbsSlot
1178311803

src/Compiler/Checking/infos.fs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,20 @@ type MethInfo =
14301430
let (ParamAttribs(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, reflArgInfo)) = info
14311431
ParamData(isParamArrayArg, isInArg, isOutArg, optArgInfo, callerInfo, nmOpt, reflArgInfo, pty)))
14321432

1433+
member x.HasGenericRetTy() =
1434+
match x with
1435+
| ILMeth(_g, ilminfo, _) -> ilminfo.RawMetadata.Return.Type.IsTypeVar
1436+
| FSMeth(g, _, vref, _) ->
1437+
let _, _, _, retTy, _ = GetTypeOfMemberInMemberForm g vref
1438+
match retTy with
1439+
| Some retTy -> isTyparTy g retTy
1440+
| None -> false
1441+
| MethInfoWithModifiedReturnType(_,retTy) -> false
1442+
| DefaultStructCtor _ -> false
1443+
#if !NO_TYPEPROVIDERS
1444+
| ProvidedMeth(amap, mi, _, m) -> false
1445+
#endif
1446+
14331447
/// Get the ParamData objects for the parameters of a MethInfo
14341448
member x.HasParamArrayArg(amap, m, minst) =
14351449
x.GetParamDatas(amap, m, minst) |> List.existsSquared (fun (ParamData(isParamArrayArg, _, _, _, _, _, _, _)) -> isParamArrayArg)

src/Compiler/Checking/infos.fsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,8 @@ type MethInfo =
538538
/// Get the signature of an abstract method slot.
539539
member GetSlotSig: amap: ImportMap * m: range -> SlotSig
540540

541+
member HasGenericRetTy: unit -> bool
542+
541543
/// Get the ParamData objects for the parameters of a MethInfo
542544
member HasParamArrayArg: amap: ImportMap * m: range * minst: TType list -> bool
543545

src/Compiler/FSComp.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,6 +1683,7 @@ forFormatInvalidForInterpolated4,"Interpolated strings used as type IFormattable
16831683
3394,parsNewExprMemberAccess,"This member access is ambiguous. Please use parentheses around the object creation, e.g. '(new SomeType(args)).MemberName'"
16841684
3395,tcImplicitConversionUsedForMethodArg,"This expression uses the implicit conversion '%s' to convert type '%s' to type '%s'."
16851685
3396,tcLiteralAttributeCannotUseActivePattern,"A [<Literal>] declaration cannot use an active pattern for its identifier"
1686+
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\"."
16861687
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."
16871688
3402,tcInvalidResumableConstruct,"The construct '%s' may only be used in valid resumable code."
16881689
3501,tcResumableCodeFunctionMustBeInline,"Invalid resumable code. Any method of function accepting or returning resumable code must be marked 'inline'"
@@ -1794,3 +1795,4 @@ featureDontWarnOnUppercaseIdentifiersInBindingPatterns,"Don't warn on uppercase
17941795
3874,tcExpectedTypeParamMarkedWithUnitOfMeasureAttribute,"Expected unit-of-measure type parameter must be marked with the [<Measure>] attribute."
17951796
featureDeprecatePlacesWhereSeqCanBeOmitted,"Deprecate places where 'seq' can be omitted"
17961797
featureSupportValueOptionsAsOptionalParameters,"Support ValueOption as valid type for optional member parameters"
1798+
featureSupportWarnWhenUnitPassedToObjArg,"Warn when unit is passed to a member accepting `obj` argument, e.g. `Method(o:obj)` will warn if called via `Method()`."

src/Compiler/Facilities/LanguageFeatures.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ type LanguageFeature =
9898
| UseTypeSubsumptionCache
9999
| DeprecatePlacesWhereSeqCanBeOmitted
100100
| SupportValueOptionsAsOptionalParameters
101+
| WarnWhenUnitPassedToObjArg
101102

102103
/// LanguageVersion management
103104
type LanguageVersion(versionText) =
@@ -227,6 +228,7 @@ type LanguageVersion(versionText) =
227228
LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns, previewVersion
228229
LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted, previewVersion
229230
LanguageFeature.SupportValueOptionsAsOptionalParameters, previewVersion
231+
LanguageFeature.WarnWhenUnitPassedToObjArg, previewVersion
230232
]
231233

232234
static let defaultLanguageVersion = LanguageVersion("default")
@@ -388,6 +390,7 @@ type LanguageVersion(versionText) =
388390
| LanguageFeature.UseTypeSubsumptionCache -> FSComp.SR.featureUseTypeSubsumptionCache ()
389391
| LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted -> FSComp.SR.featureDeprecatePlacesWhereSeqCanBeOmitted ()
390392
| LanguageFeature.SupportValueOptionsAsOptionalParameters -> FSComp.SR.featureSupportValueOptionsAsOptionalParameters ()
393+
| LanguageFeature.WarnWhenUnitPassedToObjArg -> FSComp.SR.featureSupportWarnWhenUnitPassedToObjArg ()
391394

392395
/// Get a version string associated with the given feature.
393396
static member GetFeatureVersionString feature =

src/Compiler/Facilities/LanguageFeatures.fsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ type LanguageFeature =
8989
| UseTypeSubsumptionCache
9090
| DeprecatePlacesWhereSeqCanBeOmitted
9191
| SupportValueOptionsAsOptionalParameters
92+
| WarnWhenUnitPassedToObjArg
9293

9394
/// LanguageVersion management
9495
type LanguageVersion =

src/Compiler/Interactive/ControlledExecution.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
// because we continue to support older coreclrs and the windows desktop framework through netstandard2.0
77
// we access the features using reflection
88

9+
#nowarn "3262" // The `Option.ofObj (Type.GetType..) construct warns in ns20, because Type.GetType is not annotated as nullable
10+
911
namespace FSharp.Compiler.Interactive
1012

1113
open System

src/Compiler/xlf/FSComp.txt.cs.xlf

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)