Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/10.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* Fix find all references for F# exceptions ([PR #18565](https://github.com/dotnet/fsharp/pull/18565))
* Shorthand lambda: fix completion for chained calls and analysis for unfinished expression ([PR #18560](https://github.com/dotnet/fsharp/pull/18560))
* Completion: fix previous namespace considered opened [PR #18609](https://github.com/dotnet/fsharp/pull/18609)
* Fix active pattern typechecking regression. ([Issue #18638](https://github.com/dotnet/fsharp/issues/18638), [PR #18642](https://github.com/dotnet/fsharp/pull/18642))

### Added

Expand Down
5 changes: 4 additions & 1 deletion src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5259,6 +5259,8 @@ and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags
| _, _ -> FSComp.SR.tcActivePatternArgsCountNotMatchArgsAndPat(paramCount, caseName, fmtExprArgs paramCount)
error(Error(msg, m))

let isUnsolvedTyparTy g ty = tryDestTyparTy g ty |> ValueOption.exists (fun typar -> not typar.IsSolved)

// partial active pattern (returning bool) doesn't have output arg
if (not apinfo.IsTotal && isBoolTy g retTy) then
checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern m
Expand All @@ -5281,7 +5283,8 @@ and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags
showErrMsg 1

// active pattern in function param (e.g. let f (|P|_|) = ...)
elif tryDestTyparTy g vExprTy |> ValueOption.exists (fun typar -> not typar.IsSolved) then
// or in mutual recursion with a lambda: `and (|P|) x = fun y -> …`
elif isUnsolvedTyparTy g vExprTy || tryDestFunTy g vExprTy |> ValueOption.exists (fun (_, rangeTy) -> isUnsolvedTyparTy g rangeTy) then
List.frontAndBack args

// args count should equal to AP function params count
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,26 @@ match 1 with P expr2 pat -> ()
|> typecheck
|> shouldSucceed

module ``Recursive active pattern definition with and`` =
/// See https://github.com/dotnet/fsharp/issues/18638
[<Fact>]
let ``match expr1 with P expr2 pat -> …`` () =
FSharp """
let rec parse p =
function
| IsSomething p v -> Some v
| _ -> None

and (|IsSomething|_|) p =
function
| "nested" -> parse p "42"
| "42" -> Some 42
| _ -> None
"""
|> withNoWarn IncompletePatternMatches
|> typecheck
|> shouldSucceed

module ``int → int → int voption`` =
// Normal usage; pat is int.
[<Fact>]
Expand Down
Loading