Skip to content

Commit f386188

Browse files
authored
Merge pull request #18348 from dotnet/merge/main-to-feature/lsp
[automated] Merge branch 'main' => 'feature/lsp'
2 parents f5e190c + 9c6e560 commit f386188

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
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))
1414
* 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))
15+
* Unsafe downcast from `obj` to generic `T` no longer requires `not null` constraint on `T`([Issue #18275](https://github.com/dotnet/fsharp/issues/18275), [PR #18343](https://github.com/dotnet/fsharp/pull/18343))
1516

1617
### Added
1718
* Added missing type constraints in FCS. ([PR #18241](https://github.com/dotnet/fsharp/pull/18241))

src/Compiler/Checking/Expressions/CheckExpressions.fs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2976,11 +2976,9 @@ let TcRuntimeTypeTest isCast isOperator (cenv: cenv) denv m tgtTy srcTy =
29762976
if isSealedTy g srcTy then
29772977
error(RuntimeCoercionSourceSealed(denv, srcTy, m))
29782978

2979-
if isSealedTy g tgtTy || isTyparTy g tgtTy || not (isInterfaceTy g srcTy) then
2980-
if isCast then
2981-
AddCxTypeMustSubsumeType (ContextInfo.RuntimeTypeTest isOperator) denv cenv.css m NoTrace srcTy tgtTy
2982-
else
2983-
AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css m NoTrace srcTy tgtTy
2979+
if (isSealedTy g tgtTy || isTyparTy g tgtTy || not (isInterfaceTy g srcTy)) && not (isObjTyAnyNullness g srcTy) then
2980+
let context = if isCast then ContextInfo.RuntimeTypeTest isOperator else ContextInfo.NoContext
2981+
AddCxTypeMustSubsumeType context denv cenv.css m NoTrace srcTy tgtTy
29842982

29852983
if isErasedType g tgtTy then
29862984
if isCast then

tests/FSharp.Compiler.ComponentTests/Language/Nullness/NullableReferenceTypesTests.fs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,8 @@ let doNotWarnOnDowncastRepeatedNestedNullable(o:objnull) = o :? list<((AB | null
150150
|> shouldFail
151151
|> withDiagnostics
152152
[ Error 3264, Line 4, Col 39, Line 4, Col 47, "Nullness warning: Downcasting from 'objnull' into 'AB' can introduce unexpected null values. Cast to 'AB|null' instead or handle the null before downcasting."
153-
Error 3261, Line 5, Col 42, Line 5, Col 59, "Nullness warning: The types 'obj' and 'AB | null' do not have compatible nullability."
154153
Error 3060, Line 5, Col 42, Line 5, Col 59, "This type test or downcast will erase the provided type 'AB | null' to the type 'AB'"
155154
Error 3060, Line 6, Col 41, Line 6, Col 55, "This type test or downcast will erase the provided type 'AB | null' to the type 'AB'"
156-
Error 3261, Line 7, Col 51, Line 7, Col 97, "Nullness warning: The types 'obj' and 'AB | null array | null list | null' do not have compatible nullability."
157155
Error 3060, Line 7, Col 51, Line 7, Col 97, "This type test or downcast will erase the provided type 'List<AB | null array | null> | null' to the type 'List<AB array>'"]
158156

159157

@@ -1381,6 +1379,20 @@ dict["ok"] <- 42
13811379
|> typeCheckWithStrictNullness
13821380
|> shouldSucceed
13831381

1382+
[<InlineData("t :?> 'T")>]
1383+
[<InlineData("(downcast t) : 'T")>]
1384+
[<InlineData("t |> unbox<'T>")>]
1385+
[<InlineData("(t : objnull) :?> 'T")>]
1386+
[<Theory>]
1387+
let ``Unsafe cast should not insist on not null constraint``(castOp:string) =
1388+
1389+
FSharp $"""module MyLibrary
1390+
let test<'T> () =
1391+
let t = obj()
1392+
{castOp}"""
1393+
|> asLibrary
1394+
|> typeCheckWithStrictNullness
1395+
|> shouldSucceed
13841396

13851397

13861398
[<InlineData("null")>]

0 commit comments

Comments
 (0)