Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
24 changes: 14 additions & 10 deletions src/Compiler/Checking/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9535,7 +9535,7 @@ and TcMethodApplication_CheckArguments
let denv = env.DisplayEnv
match curriedCallerArgsOpt with
| None ->
let curriedArgTys, returnTy =
let curriedArgTys, curriedArgs, returnTy =
match candidates with
// "single named item" rule. This is where we have a single accessible method
// member x.M(arg1, ..., argN)
Expand All @@ -9547,19 +9547,23 @@ and TcMethodApplication_CheckArguments
// to their default values (for optionals) and be part of the return tuple (for out args).
| [calledMeth] ->
let curriedArgTys, returnTy = UnifyMatchingSimpleArgumentTypes cenv env exprTy.Commit calledMeth mMethExpr mItem
curriedArgTys, MustEqual returnTy
curriedArgTys, calledMeth.GetParamNames(), MustEqual returnTy
| _ ->
let domainTy, returnTy = UnifyFunctionType None cenv denv mMethExpr exprTy.Commit
let argTys = if isUnitTy g domainTy then [] else tryDestRefTupleTy g domainTy
// Only apply this rule if a candidate method exists with this number of arguments
let argTys =
if candidates |> List.exists (CalledMethHasSingleArgumentGroupOfThisLength argTys.Length) then
argTys
else
[domainTy]
[argTys], MustEqual returnTy

let lambdaVarsAndExprs = curriedArgTys |> List.mapiSquared (fun i j ty -> mkCompGenLocal mMethExpr ("arg"+string i+string j) ty)
let argTys, argNames =
match candidates |> List.tryFind (CalledMethHasSingleArgumentGroupOfThisLength argTys.Length) with
| Some meth -> argTys, meth.GetParamNames()
| None -> [domainTy], [[None]]
[argTys], argNames, MustEqual returnTy

let lambdaVarsAndExprs =
curriedArgTys
|> List.mapiSquared (fun i j ty ->
let argName = curriedArgs |> List.tryItem i |> Option.bind (List.tryItem j) |> Option.flatten |> Option.defaultWith (fun () -> "arg" + string i + string j)
mkCompGenLocal mMethExpr argName ty)

let unnamedCurriedCallerArgs = lambdaVarsAndExprs |> List.mapSquared (fun (_, e) -> CallerArg(tyOfExpr g e, e.Range, false, e))
let namedCurriedCallerArgs = lambdaVarsAndExprs |> List.map (fun _ -> [])
let lambdaVars = List.mapSquared fst lambdaVarsAndExprs
Expand Down
14 changes: 13 additions & 1 deletion src/Compiler/Checking/MethodCalls.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,8 +1266,20 @@ let BuildNewDelegateExpr (eventInfoOpt: EventInfo option, g, amap, delegateTy, d
if List.exists (isByrefTy g) delArgTys then
error(Error(FSComp.SR.tcFunctionRequiresExplicitLambda(delArgTys.Length), m))

let delFuncArgNames =
match delFuncExpr with
| Expr.Val (valRef = vref) -> vref.ValReprInfo |> Option.map (fun repr -> repr.ArgNames)
| _ -> None

let delArgVals =
delArgTys |> List.mapi (fun i argTy -> fst (mkCompGenLocal m ("delegateArg" + string i) argTy))
delArgTys
|> List.mapi (fun i argTy ->
let argName =
match delFuncArgNames with
| Some argNames -> argNames[i]
| None -> "delegateArg" + string i

fst (mkCompGenLocal m argName argTy))

let expr =
let args =
Expand Down
15 changes: 15 additions & 0 deletions src/Compiler/Checking/infos.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,21 @@ type MethInfo =
member x.GetFSharpReturnType(amap, m, minst) =
x.GetCompiledReturnType(amap, m, minst) |> GetFSharpViewOfReturnType amap.g

member x.GetParamNames() =
match x with
| FSMeth (g, _, vref, _) ->
ParamNameAndType.FromMember x.IsCSharpStyleExtensionMember g vref |> List.mapSquared (fun (ParamNameAndType (name, _)) -> name |> Option.map (fun x -> x.idText))
| ILMeth (ilMethInfo = ilminfo) ->
// A single group of tupled arguments
[ ilminfo.ParamMetadata |> List.map (fun x -> x.Name) ]
#if !NO_TYPEPROVIDERS
| ProvidedMeth (_, mi, _, m) ->
// A single group of tupled arguments
[ [ for p in mi.PApplyArray((fun mi -> mi.GetParameters()), "GetParameters", m) do
yield p.PUntaint((fun p -> Some p.Name), m) ] ]
#endif
| _ -> []

/// Get the parameter types of a method info
member x.GetParamTypes(amap, m, minst) =
match x with
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/Checking/infos.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,9 @@ type MethInfo =
/// Get the ParamData objects for the parameters of a MethInfo
member GetParamDatas: amap: ImportMap * m: range * minst: TType list -> ParamData list list

/// Get the parameter names of a MethInfo
member GetParamNames: unit -> string option list list

/// Get the parameter types of a method info
member GetParamTypes: amap: ImportMap * m: range * minst: TType list -> TType list list

Expand Down