Skip to content

Commit a0f1e31

Browse files
authored
function implicit conversion the same way as fun x (#17487)
1 parent 182dd57 commit a0f1e31

File tree

4 files changed

+79
-16
lines changed

4 files changed

+79
-16
lines changed

docs/release-notes/.FSharp.Compiler.Service/9.0.100.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Optimize simple mappings in comprehensions when the body of the mapping has `let`-bindings and/or sequential expressions before a single yield. ([PR #17419](https://github.com/dotnet/fsharp/pull/17419))
66
* C# protected property can be assigned in F# inherit constructor call. ([Issue #13299](https://github.com/dotnet/fsharp/issues/13299), [PR #17391](https://github.com/dotnet/fsharp/pull/17391))
77
* MethodAccessException on equality comparison of a record with private fields. ([Issue #17447](https://github.com/dotnet/fsharp/issues/17447), [PR #17391](https://github.com/dotnet/fsharp/pull/17467))
8+
* Fix `function` implicit conversion. ([Issue #7401](https://github.com/dotnet/fsharp/issues/7401), [PR #17487](https://github.com/dotnet/fsharp/pull/17487))
89
* Compiler fails to recognise namespace in FQN with enabled GraphBasedChecking. ([Issue #17508](https://github.com/dotnet/fsharp/issues/17508), [PR #17510](https://github.com/dotnet/fsharp/pull/17510))
910
* Fix missing message for type error (FS0001). ([Issue #17373](https://github.com/dotnet/fsharp/issues/17373), [PR #17516](https://github.com/dotnet/fsharp/pull/17516))
1011

src/Compiler/Checking/Expressions/CheckExpressions.fs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9672,22 +9672,36 @@ and TcMethodApplicationThen
96729672
PropagateThenTcDelayed cenv overallTy env tpenv mWholeExpr (MakeApplicableExprNoFlex cenv expr) exprTy atomicFlag delayed
96739673

96749674
/// Infer initial type information at the callsite from the syntax of an argument, prior to overload resolution.
9675-
and GetNewInferenceTypeForMethodArg (cenv: cenv) env tpenv x =
9675+
and GetNewInferenceTypeForMethodArg (cenv: cenv) x =
96769676

96779677
let g = cenv.g
96789678

9679-
match x with
9680-
| SynExprParen(a, _, _, _) ->
9681-
GetNewInferenceTypeForMethodArg cenv env tpenv a
9682-
| SynExpr.AddressOf (true, a, _, m) ->
9683-
mkByrefTyWithInference g (GetNewInferenceTypeForMethodArg cenv env tpenv a) (NewByRefKindInferenceType g m)
9684-
| SynExpr.Lambda (body = a)
9685-
| SynExpr.DotLambda (expr = a) ->
9686-
mkFunTy g (NewInferenceType g) (GetNewInferenceTypeForMethodArg cenv env tpenv a)
9687-
| SynExpr.Quote (_, raw, a, _, _) ->
9688-
if raw then mkRawQuotedExprTy g
9689-
else mkQuotedExprTy g (GetNewInferenceTypeForMethodArg cenv env tpenv a)
9690-
| _ -> NewInferenceType g
9679+
let rec loopExpr expr cont : struct (_ * _) =
9680+
match expr with
9681+
| SynExprParen (a, _, _, _) ->
9682+
loopExpr a cont
9683+
| SynExpr.AddressOf (true, a, _, m) ->
9684+
loopExpr a (cont << fun struct (depth, ty) -> depth + 1, mkByrefTyWithInference g ty (NewByRefKindInferenceType g m))
9685+
| SynExpr.Lambda (body = a)
9686+
| SynExpr.DotLambda (expr = a) ->
9687+
loopExpr a (cont << fun struct (depth, ty) -> depth + 1, mkFunTy g (NewInferenceType g) ty)
9688+
| SynExpr.MatchLambda (matchClauses = SynMatchClause (resultExpr = a) :: clauses) ->
9689+
let loopClause a = loopExpr a (cont << fun struct (depth, ty) -> depth + 1, mkFunTy g (NewInferenceType g) ty)
9690+
9691+
// Look at all branches, keeping the one
9692+
// that gives us the most syntactic information.
9693+
(loopClause a, clauses)
9694+
||> List.fold (fun ((maxClauseDepth, _) as acc) (SynMatchClause (resultExpr = a)) ->
9695+
match loopClause a with
9696+
| clauseDepth, ty when clauseDepth > maxClauseDepth -> clauseDepth, ty
9697+
| _ -> acc)
9698+
| SynExpr.Quote (_, raw, a, _, _) ->
9699+
if raw then cont (0, mkRawQuotedExprTy g)
9700+
else loopExpr a (cont << fun struct (depth, ty) -> depth + 1, mkQuotedExprTy g ty)
9701+
| _ -> cont (0, NewInferenceType g)
9702+
9703+
let struct (_depth, ty) = loopExpr x id
9704+
ty
96919705

96929706
and CalledMethHasSingleArgumentGroupOfThisLength n (calledMeth: MethInfo) =
96939707
match calledMeth.NumArgs with
@@ -9722,7 +9736,7 @@ and UnifyMatchingSimpleArgumentTypes (cenv: cenv) (env: TcEnv) exprTy (calledMet
97229736
and TcMethodApplication_SplitSynArguments
97239737
(cenv: cenv)
97249738
(env: TcEnv)
9725-
tpenv
9739+
_tpenv
97269740
isProp
97279741
(candidates: MethInfo list)
97289742
(exprTy: OverallTy)
@@ -9750,7 +9764,7 @@ and TcMethodApplication_SplitSynArguments
97509764
else
97519765
unnamedCurriedCallerArgs, namedCurriedCallerArgs
97529766

9753-
let MakeUnnamedCallerArgInfo x = (x, GetNewInferenceTypeForMethodArg cenv env tpenv x, x.Range)
9767+
let MakeUnnamedCallerArgInfo x = (x, GetNewInferenceTypeForMethodArg cenv x, x.Range)
97549768

97559769
let singleMethodCurriedArgs =
97569770
match candidates with
@@ -9789,7 +9803,7 @@ and TcMethodApplication_SplitSynArguments
97899803
| _ ->
97909804
let unnamedCurriedCallerArgs = unnamedCurriedCallerArgs |> List.mapSquared MakeUnnamedCallerArgInfo
97919805
let namedCurriedCallerArgs = namedCurriedCallerArgs |> List.mapSquared (fun (isOpt, nm, x) ->
9792-
let ty = GetNewInferenceTypeForMethodArg cenv env tpenv x
9806+
let ty = GetNewInferenceTypeForMethodArg cenv x
97939807
// #435263: compiler crash with .net optional parameters and F# optional syntax
97949808
// named optional arguments should always have option type
97959809
// STRUCT OPTIONS: if we allow struct options as optional arguments then we should relax this and rely
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
open System
2+
let ae = new AggregateException()
3+
4+
ae.Handle(fun e ->
5+
match e with
6+
| :? OperationCanceledException -> true
7+
| _ -> false
8+
)
9+
10+
ae.Handle(function
11+
| :? OperationCanceledException -> true
12+
| _ -> false
13+
)
14+
15+
ae.Handle(
16+
Func<exn,bool>(
17+
function
18+
| :? OperationCanceledException -> true
19+
| _ -> false
20+
))
21+
22+
module M1 =
23+
type T =
24+
static member M (_ : Func<int, exn, int>) = ()
25+
26+
T.M (function _ -> function :? ArgumentException -> 3 | _ -> 4)
27+
T.M (function 0 -> (function _ -> 3) | _ -> function :? ArgumentException -> 3 | _ -> 4)
28+
29+
module M2 =
30+
type T =
31+
static member M (_ : Func<int, int, int>) = ()
32+
33+
T.M (function 0 -> (function _ -> 1) | _ -> (function 0 -> 3 | _ -> 4))
34+
T.M (function 0 -> id | _ -> (function 0 -> 3 | _ -> 4))
35+
T.M (function 0 -> (function 0 -> 3 | _ -> 4) | _ -> id)
36+
37+
module M3 =
38+
type T =
39+
static member M (_ : Func<int, int, int, int>) = ()
40+
41+
T.M (function 0 -> (function 0 -> (function 0 -> 1 | _ -> 0) | _ -> (function 0 -> 2 | _ -> 3)) | _ -> (function 0 -> (function _ -> 3) | _ -> (function 3 -> 4 | _ -> 5)))
42+
T.M (function 0 -> (function 0 -> id | _ -> (function 0 -> 2 | _ -> 3)) | _ -> (function 0 -> (function _ -> 3) | _ -> (function 3 -> 4 | _ -> 5)))

tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/MemberDefinitions/OverloadingMembers/OverloadingMembers.fs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,9 @@ module MemberDefinitions_OverloadingMembers =
229229
|> withDefines ["TOO_GENERIC"]
230230
|> verifyCompileAndRun
231231
|> shouldSucceed
232+
233+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"OverloadResolutionUsingFunction.fs"|])>]
234+
let ``OverloadResolutionUsingFunction_fs`` compilation =
235+
compilation
236+
|> verifyCompileAndRun
237+
|> shouldSucceed

0 commit comments

Comments
 (0)