diff --git a/src/fsharp/MethodCalls.fs b/src/fsharp/MethodCalls.fs index 07bd84c44f5..94fbd7ff60f 100644 --- a/src/fsharp/MethodCalls.fs +++ b/src/fsharp/MethodCalls.fs @@ -214,11 +214,10 @@ let AdjustCalledArgTypeForOptionals (g: TcGlobals) enforceNullableOptionalsKnown calledArgTy // If at the beginning of inference then use a type variable. else - let destTy = destNullableTy g calledArgTy match calledArg.OptArgInfo with - // Use the type variable from the Nullable if called arg is not optional. - | NotOptional when isTyparTy g destTy -> - destTy + // If inference has not solved the kind of Nullable on the called arg and is not optional then use this. + | NotOptional when isTyparTy g (destNullableTy g calledArgTy) -> + calledArgTy | _ -> let compgenId = mkSynId range0 unassignedTyparName mkTyparTy (Construct.NewTypar (TyparKind.Type, TyparRigidity.Flexible, SynTypar(compgenId, TyparStaticReq.None, true), false, TyparDynamicReq.No, [], false, false)) diff --git a/tests/fsharp/Compiler/Language/OptionalInteropTests.fs b/tests/fsharp/Compiler/Language/OptionalInteropTests.fs index cffba65c156..19d32334850 100644 --- a/tests/fsharp/Compiler/Language/OptionalInteropTests.fs +++ b/tests/fsharp/Compiler/Language/OptionalInteropTests.fs @@ -6,6 +6,7 @@ open System.Collections.Immutable open NUnit.Framework open FSharp.Test.Utilities open FSharp.Test.Utilities.Utilities +open FSharp.Test.Utilities.Compiler open FSharp.Compiler.Diagnostics open Microsoft.CodeAnalysis diff --git a/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs b/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs index 93970223ce5..26391ffa1c3 100644 --- a/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs +++ b/tests/fsharp/Compiler/Regressions/NullableOptionalRegressionTests.fs @@ -33,3 +33,66 @@ let test () = |> typecheck |> shouldSucceed |> ignore + + [] + let ``Method should infer 'z' correctly``() = + let fsSrc = + """ +namespace FSharpTest + +open System + +type Test() = class end + +type Test with + + static member nullableE (encoder, x: Nullable<'a>) = if x.HasValue then encoder x.Value else Test() + static member nullable codec z = Test.nullableE(codec, z) + """ + FSharp fsSrc + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``Method should infer correctly``() = + let fsSrc = + """ +namespace FSharpTest + +open System + +type Test() = class end + +type Test with + + static member nullableE encoder (x: Nullable<'a>) = if x.HasValue then encoder x.Value else Test() + static member nullable codec = Test.nullableE codec + """ + FSharp fsSrc + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + |> ignore + + [] + let ``Method should infer correctly 2``() = + let fsSrc = + """ +namespace FSharpTest + +open System + +type Test() = class end + +type Test with + + static member nullableE encoder (x: Nullable) = if x.HasValue then encoder x.Value else Test() + static member nullable codec = Test.nullableE codec + """ + FSharp fsSrc + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + |> ignore