Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -2037,3 +2037,42 @@ if r <> 1 then failwith $"Expected 1 but got {r}"
|> asExe
|> compileAndRun
|> shouldSucceed

// The domain-order fix keeps the SRTP typar as the unification representative, so a nullable
// argument annotation survives the recursive specialization and nullness inference stays intact
// under --checknulls+ (no lost or spurious warning, no internal error).
[<Fact>]
let ``Recursive inline SRTP memoization preserves nullable argument inference under checknulls`` () =
FSharp """
module Test
open System.Collections.Concurrent

type Default1 = class end

[<Struct>]
type MemoizationKeyWrapper<'a> = MemoizationKeyWrapper of 'a

type MemoizeN =
inherit Default1
static member getOrAdd (cd: ConcurrentDictionary<MemoizationKeyWrapper<'a>,'b>) (f: 'a -> 'b) k =
cd.GetOrAdd (MemoizationKeyWrapper k, (fun (MemoizationKeyWrapper x) -> x) >> f)

let inline memoizeN (f: ^F) : ^F =
let inline call_2 (a: ^MemoizeN, b: ^b) = ((^MemoizeN or ^b) : (static member MemoizeN : ^MemoizeN * 'b -> _ ) (a, b))
call_2 (Unchecked.defaultof<MemoizeN>, Unchecked.defaultof< ^F >) f

type MemoizeN with
static member MemoizeN (_: Default1, _: 'a -> 'b) = MemoizeN.getOrAdd (ConcurrentDictionary ())
static member inline MemoizeN (_: MemoizeN, _:'t -> 'a -> 'b) = MemoizeN.getOrAdd (ConcurrentDictionary ()) << (<<) memoizeN

let lookup (prefix: int) (index: int) (s: string | null) = s.Length + prefix + index
let mlookup = memoizeN lookup
mlookup 1 2 "abc" |> ignore
"""
|> withLangVersion "preview"
|> withCheckNulls
|> withWarnOn 3261
|> compile
|> withDiagnostics [
Warning 3261, Line 23, Col 60, Line 23, Col 61, "Nullness warning: Possible dereference of a null value when accessing member 'Length' on the nullable value 's' of type 'string | null'."
]
Loading