@@ -191,11 +191,13 @@ let AdjustCalledArgTypeForOptionals (g: TcGlobals) enforceNullableOptionalsKnown
191191 calledArgTy
192192 else
193193 match calledArg.OptArgInfo with
194- | NotOptional ->
194+ // CSharpMethod(x = arg), non-optional C#-style argument, may have type Nullable<ty>.
195+ | NotOptional when not ( g.langVersion.SupportsFeature LanguageFeature.NullableOptionalInterop) ->
195196 calledArgTy
196197
197- // CSharpMethod(x = arg), optional C#-style argument, may have type Nullable<ty>.
198198 // The arg should have type ty. However for backwards compat, we also allow arg to have type Nullable<ty>
199+ | NotOptional
200+ // CSharpMethod(x = arg), optional C#-style argument, may have type Nullable<ty>.
199201 | CallerSide _ ->
200202 if isNullableTy g calledArgTy && g.langVersion.SupportsFeature LanguageFeature.NullableOptionalInterop then
201203 // If inference has worked out it's a nullable then use this
@@ -1148,21 +1150,40 @@ let GetDefaultExpressionForOptionalArg tcFieldInit g (calledArg: CalledArg) eCal
11481150 let callerArg = CallerArg( calledArgTy, mMethExpr, false , expr)
11491151 preBinder, { NamedArgIdOpt = None; CalledArg = calledArg; CallerArg = callerArg }
11501152
1153+ let MakeNullableExprIfNeeded ( infoReader : InfoReader ) calledArgTy callerArgTy callerArgExpr m =
1154+ let g = infoReader.g
1155+ let amap = infoReader.amap
1156+ if isNullableTy g callerArgTy then
1157+ callerArgExpr
1158+ else
1159+ let calledNonOptTy = destNullableTy g calledArgTy
1160+ let minfo = GetIntrinsicConstructorInfosOfType infoReader m calledArgTy |> List.head
1161+ let callerArgExprCoerced = mkCoerceIfNeeded g calledNonOptTy callerArgTy callerArgExpr
1162+ MakeMethInfoCall amap m minfo [] [ callerArgExprCoerced]
1163+
11511164// Adjust all the optional arguments, filling in values for defaults,
11521165let AdjustCallerArgForOptional tcFieldInit eCallerMemberName ( infoReader : InfoReader ) ( assignedArg : AssignedCalledArg < _ >) =
11531166 let g = infoReader.g
1154- let amap = infoReader.amap
11551167 let callerArg = assignedArg.CallerArg
11561168 let ( CallerArg ( callerArgTy , m , isOptCallerArg , callerArgExpr )) = callerArg
11571169 let calledArg = assignedArg.CalledArg
1158- match calledArg.OptArgInfo with
1159- | NotOptional ->
1170+ let calledArgTy = calledArg.CalledArgumentType
1171+ match calledArg.OptArgInfo with
1172+ | NotOptional when not ( g.langVersion.SupportsFeature LanguageFeature.NullableOptionalInterop) ->
11601173 if isOptCallerArg then errorR( Error( FSComp.SR.tcFormalArgumentIsNotOptional(), m))
11611174 assignedArg
1162- | _ ->
1175+
1176+ | _ ->
1177+
11631178 let callerArgExpr2 =
11641179 match calledArg.OptArgInfo with
1165- | NotOptional -> failwith " unreachable"
1180+ | NotOptional ->
1181+ // T --> Nullable<T> widening at callsites
1182+ if isOptCallerArg then errorR( Error( FSComp.SR.tcFormalArgumentIsNotOptional(), m))
1183+ if isNullableTy g calledArgTy then
1184+ MakeNullableExprIfNeeded infoReader calledArgTy callerArgTy callerArgExpr m
1185+ else
1186+ callerArgExpr
11661187
11671188 | CallerSide dfltVal ->
11681189 let calledArgTy = calledArg.CalledArgumentType
@@ -1184,15 +1205,9 @@ let AdjustCallerArgForOptional tcFieldInit eCallerMemberName (infoReader: InfoRe
11841205 else
11851206 if isNullableTy g calledArgTy then
11861207 // CSharpMethod(x=b) when 'x' has nullable type
1187- if isNullableTy g callerArgTy then
1188- // CSharpMethod(x=b) when both 'x' and 'b' have nullable type --> CSharpMethod(x=b)
1189- callerArgExpr
1190- else
1191- // CSharpMethod(x=b) when 'x' has nullable type and 'b' does not --> CSharpMethod(x=Nullable(b))
1192- let calledNonOptTy = destNullableTy g calledArgTy
1193- let minfo = GetIntrinsicConstructorInfosOfType infoReader m calledArgTy |> List.head
1194- let callerArgExprCoerced = mkCoerceIfNeeded g calledNonOptTy callerArgTy callerArgExpr
1195- MakeMethInfoCall amap m minfo [] [ callerArgExprCoerced]
1208+ // CSharpMethod(x=b) when both 'x' and 'b' have nullable type --> CSharpMethod(x=b)
1209+ // CSharpMethod(x=b) when 'x' has nullable type and 'b' does not --> CSharpMethod(x=Nullable(b))
1210+ MakeNullableExprIfNeeded infoReader calledArgTy callerArgTy callerArgExpr m
11961211 else
11971212 // CSharpMethod(x=b) --> CSharpMethod(?x=b)
11981213 callerArgExpr
@@ -1203,7 +1218,6 @@ let AdjustCallerArgForOptional tcFieldInit eCallerMemberName (infoReader: InfoRe
12031218 callerArgExpr
12041219 else
12051220 // CSharpMethod(x=b) when CSharpMethod(A) --> CSharpMethod(?x=Some(b :> A))
1206- let calledArgTy = assignedArg.CalledArg.CalledArgumentType
12071221 if isOptionTy g calledArgTy then
12081222 let calledNonOptTy = destOptionTy g calledArgTy
12091223 let callerArgExprCoerced = mkCoerceIfNeeded g calledNonOptTy callerArgTy callerArgExpr
0 commit comments