@@ -23,6 +23,7 @@ open FSharp.Compiler.TypedTreeBasics
2323open FSharp.Compiler .TypedTreeOps
2424open FSharp.Compiler .TypedTreeOps .DebugPrint
2525open FSharp.Compiler .TypeRelations
26+ open type System.MemoryExtensions
2627
2728exception MatchIncomplete of bool * ( string * bool ) option * range
2829exception RuleNeverMatched of range
@@ -48,7 +49,6 @@ type Pattern =
4849 | TPat_ tuple of TupInfo * Pattern list * TType list * range
4950 | TPat_ array of Pattern list * TType * range
5051 | TPat_ recd of TyconRef * TypeInst * Pattern list * range
51- | TPat_ range of char * char * range
5252 | TPat_ null of range
5353 | TPat_ isinst of TType * TType * Pattern option * range
5454 | TPat_ error of range
@@ -66,7 +66,6 @@ type Pattern =
6666 | TPat_ tuple(_, _, _, m) -> m
6767 | TPat_ array(_, _, m) -> m
6868 | TPat_ recd(_, _, _, m) -> m
69- | TPat_ range(_, _, m) -> m
7069 | TPat_ null m -> m
7170 | TPat_ isinst(_, _, _, m) -> m
7271 | TPat_ error m -> m
@@ -720,7 +719,7 @@ let discrimWithinSimultaneousClass g amap m discrim prev =
720719let canInvestigate ( pat : Pattern ) =
721720 match pat with
722721 | TPat_ null _ | TPat_ isinst _ | TPat_ exnconstr _ | TPat_ unioncase _
723- | TPat_ array _ | TPat_ const _ | TPat_ query _ | TPat _ range _ | TPat_ error _ -> true
722+ | TPat_ array _ | TPat_ const _ | TPat_ query _ | TPat_ error _ -> true
724723 | _ -> false
725724
726725/// Decide the next pattern to investigate
@@ -905,43 +904,37 @@ let rec layoutPat pat =
905904let mkFrontiers investigations clauseNumber =
906905 investigations |> List.map ( fun ( actives , valMap ) -> Frontier( clauseNumber, actives, valMap))
907906
907+ let singleFalseInvestigationPoint = [| false |]
908+
908909// Search for pattern decision points that are decided "one at a time" - i.e. where there is no
909910// multi-way switching. For example partial active patterns
910911let rec investigationPoints inpPat =
911- seq {
912- match inpPat with
913- | TPat_ query ((_, _, _, _, _, apinfo), subPat, _) ->
914- yield not apinfo.IsTotal
915- yield ! investigationPoints subPat
916- | TPat_ isinst (_, _ tgtTy, subPatOpt, _) ->
917- yield false
918- match subPatOpt with
919- | None -> ()
920- | Some subPat ->
921- yield ! investigationPoints subPat
922- | TPat_ as ( subPat, _, _) ->
923- yield ! investigationPoints subPat
924- | TPat_ disjs ( subPats, _)
925- | TPat_ conjs( subPats, _)
926- | TPat_ tuple (_, subPats, _, _)
927- | TPat_ recd (_, _, subPats, _) ->
928- for subPat in subPats do
929- yield ! investigationPoints subPat
930- | TPat_ exnconstr(_, subPats, _) ->
931- for subPat in subPats do
932- yield ! investigationPoints subPat
933- | TPat_ array ( subPats, _, _)
934- | TPat_ unioncase (_, _, subPats, _) ->
935- yield false
936- for subPat in subPats do
937- yield ! investigationPoints subPat
938- | TPat_ range _
939- | TPat_ null _
940- | TPat_ const _ ->
941- yield false
942- | TPat_ wild _
943- | TPat_ error _ -> ()
944- }
912+ match inpPat with
913+ | TPat_ query((_, _, _, _, _, apinfo), subPat, _) ->
914+ Array.prepend ( not apinfo.IsTotal) ( investigationPoints subPat)
915+ | TPat_ isinst(_, _ tgtTy, subPatOpt, _) ->
916+ match subPatOpt with
917+ | None -> singleFalseInvestigationPoint
918+ | Some subPat -> Array.prepend false ( investigationPoints subPat)
919+ | TPat_ as( subPat, _, _) -> investigationPoints subPat
920+ | TPat_ disjs( subPats, _)
921+ | TPat_ conjs( subPats, _)
922+ | TPat_ tuple(_, subPats, _, _)
923+ | TPat_ exnconstr(_, subPats, _)
924+ | TPat_ recd(_, _, subPats, _) ->
925+ subPats
926+ |> Seq.collect investigationPoints
927+ |> Seq.toArray
928+ | TPat_ array ( subPats, _, _)
929+ | TPat_ unioncase (_, _, subPats, _) ->
930+ subPats
931+ |> Seq.collect investigationPoints
932+ |> Seq.toArray
933+ |> Array.prepend false
934+ | TPat_ null _
935+ | TPat_ const _ -> singleFalseInvestigationPoint
936+ | TPat_ wild _
937+ | TPat_ error _ -> [||]
945938
946939let rec erasePartialPatterns inpPat =
947940 match inpPat with
@@ -959,7 +952,6 @@ let rec erasePartialPatterns inpPat =
959952 | TPat_ isinst ( x, y, subPatOpt, m) -> TPat_ isinst ( x, y, Option.map erasePartialPatterns subPatOpt, m)
960953 | TPat_ const _
961954 | TPat_ wild _
962- | TPat_ range _
963955 | TPat_ null _
964956 | TPat_ error _ -> inpPat
965957
@@ -1002,7 +994,6 @@ let rec isPatternDisjunctive inpPat =
1002994 | TPat_ isinst (_, _, subPatOpt, _) -> Option.exists isPatternDisjunctive subPatOpt
1003995 | TPat_ const _ -> false
1004996 | TPat_ wild _ -> false
1005- | TPat_ range _ -> false
1006997 | TPat_ null _ -> false
1007998 | TPat_ error _ -> false
1008999
@@ -1605,8 +1596,6 @@ let CompilePatternBasic
16051596 | _ ->
16061597 [ frontier]
16071598
1608- | _ -> failwith " pattern compilation: GenerateNewFrontiersAfterSuccessfulInvestigation"
1609-
16101599 else
16111600 [ frontier]
16121601
@@ -1646,12 +1635,6 @@ let CompilePatternBasic
16461635 let newActives = List.mapi ( mkSubActive ( fun path _j -> path) ( fun _j -> inpAccess)) subPats
16471636 BindProjectionPatterns newActives activeState
16481637
1649- | TPat_ range ( c1, c2, m) ->
1650- let mutable res = []
1651- for i = int c1 to int c2 do
1652- res <- BindProjectionPattern ( Active( inpPath, inpExpr, TPat_ const( Const.Char( char i), m))) activeState @ res
1653- res
1654-
16551638 // Assign an identifier to each TPat_query based on our knowledge of the 'identity' of the active pattern, if any
16561639 | TPat_ query ((_, _, _, apatVrefOpt, _, _), _, _) ->
16571640 let uniqId =
@@ -1740,16 +1723,13 @@ let CompilePatternBasic
17401723// So disjunction alone isn't considered problematic, but in combination with 'when' patterns
17411724
17421725let isProblematicClause ( clause : MatchClause ) =
1743- let ips =
1744- seq {
1745- yield ! investigationPoints clause.Pattern
1746- if clause.GuardExpr.IsSome then
1747- yield true
1748- } |> Seq.toArray
1749- let ips = if isPatternDisjunctive clause.Pattern then Array.append ips ips else ips
1750- // Look for multiple decision points.
1751- // We don't mind about the last logical decision point
1752- ips.Length > 0 && Array.exists id ips[ 0 .. ips.Length-2 ]
1726+ if clause.GuardExpr.IsSome then
1727+ isPatternDisjunctive clause.Pattern || Array.exists id ( investigationPoints clause.Pattern)
1728+ else
1729+ // Look for multiple decision points.
1730+ // We don't mind about the last logical decision point
1731+ let ips = investigationPoints clause.Pattern
1732+ ips.Length > 0 && Span.exists id ( ips.AsSpan ( 0 , ips.Length - 1 ))
17531733
17541734let rec CompilePattern g denv amap tcVal infoReader mExpr mMatch warnOnUnused actionOnFailure ( origInputVal , origInputValTypars , origInputExprOpt ) ( clausesL : MatchClause list ) inputTy resultTy =
17551735 match clausesL with
0 commit comments