Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix: Warn when upcast drops nullness via FindUniqueFeasibleSupertype #18261

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/Compiler/Checking/TypeRelations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -341,5 +341,13 @@ let IteratedAdjustLambdaToMatchValReprInfo g amap valReprInfo lambdaExpr =
/// "Single Feasible Type" inference
/// Look for the unique supertype of ty2 for which ty2 :> ty1 might feasibly hold
let FindUniqueFeasibleSupertype g amap m ty1 ty2 =
let supertypes = Option.toList (GetSuperTypeOfType g amap m ty2) @ (GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m ty2)
supertypes |> List.tryFind (TypeFeasiblySubsumesType 0 g amap m ty1 NoCoerce)
let n2 = nullnessOfTy g ty2
let nullify t = addNullnessToTy n2 t

let supertypes =
Option.toList (GetSuperTypeOfType g amap m ty2) @
(GetImmediateInterfacesOfType SkipUnrefInterfaces.Yes g amap m ty2)

supertypes
|> List.tryFind (TypeFeasiblySubsumesType 0 g amap m ty1 NoCoerce)
|> Option.map nullify
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,20 @@ let typeCheckWithStrictNullness cu =
|> withNullnessOptions
|> typecheck

[<Fact>]
let ``Warning on nullness hidden behind interface upcast`` () =
FSharp """module Test

open System.IO
open System

// This is bad - input is nullable, output is not = must warn
let whatisThis (s:Stream|null) : IDisposable =
s"""
|> asLibrary
|> typeCheckWithStrictNullness
|> shouldFail
|> withDiagnostics [Error 3261, Line 8, Col 5, Line 8, Col 6, "Nullness warning: The types 'IDisposable' and 'IDisposable | null' do not have compatible nullability."]

[<FSharp.Test.FactForNETCOREAPPAttribute>]
let ``Report warning when applying anon record to a nullable generic return value`` () =
Expand Down
Loading