@@ -45,6 +45,8 @@ type Pattern =
45
45
| TPat_ range of char * char * range
46
46
| TPat_ null of range
47
47
| TPat_ isinst of TType * TType * PatternValBinding option * range
48
+ | TPat_ error of range
49
+
48
50
member this.Range =
49
51
match this with
50
52
| TPat_ const(_, m) -> m
@@ -61,6 +63,7 @@ type Pattern =
61
63
| TPat_ range(_, _, m) -> m
62
64
| TPat_ null m -> m
63
65
| TPat_ isinst(_, _, _, m) -> m
66
+ | TPat_ error m -> m
64
67
65
68
and PatternValBinding = PBind of Val * TypeScheme
66
69
@@ -419,7 +422,11 @@ let getDiscrimOfPattern (g: TcGlobals) tpinst t =
419
422
| TPat_ array ( args, ty, _ m) ->
420
423
Some( DecisionTreeTest.ArrayLength ( args.Length, ty))
421
424
| TPat_ query (( activePatExpr, resTys, apatVrefOpt, idx, apinfo), _, _ m) ->
422
- Some( DecisionTreeTest.ActivePatternCase ( activePatExpr, instTypes tpinst resTys, apatVrefOpt, idx, apinfo))
425
+ Some ( DecisionTreeTest.ActivePatternCase ( activePatExpr, instTypes tpinst resTys, apatVrefOpt, idx, apinfo))
426
+
427
+ | TPat_ error range ->
428
+ Some ( DecisionTreeTest.Error range)
429
+
423
430
| _ -> None
424
431
425
432
let constOfDiscrim discrim =
@@ -459,10 +466,10 @@ let rec chooseSimultaneousEdgeSet prevOpt f l =
459
466
| [] -> [], []
460
467
| h :: t ->
461
468
match f prevOpt h with
462
- | Some x, _ ->
469
+ | Some x ->
463
470
let l , r = chooseSimultaneousEdgeSet ( Some x) f t
464
471
x :: l, r
465
- | None, _ cont ->
472
+ | None ->
466
473
let l , r = chooseSimultaneousEdgeSet prevOpt f t
467
474
l, h :: r
468
475
@@ -490,6 +497,11 @@ let discrimsHaveSameSimultaneousClass g d1 d2 =
490
497
491
498
| _ -> false
492
499
500
+ let canInvestigate ( pat : Pattern ) =
501
+ match pat with
502
+ | TPat_ null _ | TPat_ isinst _ | TPat_ exnconstr _ | TPat_ unioncase _
503
+ | TPat_ array _ | TPat_ const _ | TPat_ query _ | TPat_ range _ | TPat_ error _ -> true
504
+ | _ -> false
493
505
494
506
/// Decide the next pattern to investigate
495
507
let ChooseInvestigationPointLeftToRight frontiers =
@@ -498,8 +510,7 @@ let ChooseInvestigationPointLeftToRight frontiers =
498
510
let rec choose l =
499
511
match l with
500
512
| [] -> failwith " ChooseInvestigationPointLeftToRight: no non-immediate patterns in first rule"
501
- | ( Active(_, _, ( TPat_ null _ | TPat_ isinst _ | TPat_ exnconstr _ | TPat_ unioncase _ | TPat_ array _ | TPat_ const _ | TPat_ query _ | TPat_ range _)) as active)
502
- :: _ -> active
513
+ | Active (_, _, pat) as active :: _ when canInvestigate pat -> active
503
514
| _ :: t -> choose t
504
515
choose actives
505
516
| [] -> failwith " ChooseInvestigationPointLeftToRight: no frontiers!"
@@ -698,6 +709,7 @@ let rec isPatternPartial p =
698
709
| TPat_ range _ -> false
699
710
| TPat_ null _ -> false
700
711
| TPat_ isinst _ -> false
712
+ | TPat_ error _ -> false
701
713
702
714
let rec erasePartialPatterns inpp =
703
715
match inpp with
@@ -716,7 +728,8 @@ let rec erasePartialPatterns inpp =
716
728
| TPat_ wild _
717
729
| TPat_ range _
718
730
| TPat_ null _
719
- | TPat_ isinst _ -> inpp
731
+ | TPat_ isinst _
732
+ | TPat_ error _ -> inpp
720
733
721
734
and erasePartials inps =
722
735
List.map erasePartialPatterns inps
@@ -736,14 +749,14 @@ let CompilePatternBasic
736
749
warnOnIncomplete
737
750
actionOnFailure
738
751
( origInputVal , origInputValTypars , _origInputExprOpt : Expr option )
739
- ( clausesL : TypedMatchClause list )
752
+ ( typedClauses : TypedMatchClause list )
740
753
inputTy
741
754
resultTy =
742
755
// Add the targets to a match builder.
743
756
// Note the input expression has already been evaluated and saved into a variable,
744
757
// hence no need for a new sequence point.
745
758
let matchBuilder = MatchBuilder ( NoSequencePointAtInvisibleBinding, exprm)
746
- clausesL |> List.iter ( fun c -> matchBuilder.AddTarget c.Target |> ignore)
759
+ typedClauses |> List.iter ( fun c -> matchBuilder.AddTarget c.Target |> ignore)
747
760
748
761
// Add the incomplete or rethrow match clause on demand,
749
762
// printing a warning if necessary (only if it is ever exercised).
@@ -807,8 +820,8 @@ let CompilePatternBasic
807
820
| Some c -> c
808
821
809
822
// Helpers to get the variables bound at a target.
810
- // We conceptually add a dummy clause that will always succeed with a "throw"
811
- let clausesA = Array.ofList clausesL
823
+ // We conceptually add a dummy clause that will always succeed with a "throw".
824
+ let clausesA = Array.ofList typedClauses
812
825
let nClauses = clausesA.Length
813
826
let GetClause i refuted =
814
827
if i < nClauses then
@@ -842,14 +855,10 @@ let CompilePatternBasic
842
855
| _ ->
843
856
// Otherwise choose a point (i.e. a path) to investigate.
844
857
let ( Active ( path , subexpr , pat )) = ChooseInvestigationPointLeftToRight frontiers
845
- match pat with
846
- // All these constructs should have been eliminated in BindProjectionPattern
847
- | TPat_ as _ | TPat_ tuple _ | TPat_ wild _ | TPat_ disjs _ | TPat_ conjs _ | TPat_ recd _ ->
858
+ if not ( canInvestigate pat) then
859
+ // All these constructs should have been eliminated in BindProjectionPattern
848
860
failwith " Unexpected pattern"
849
-
850
- // Leaving the ones where we have real work to do.
851
- | _ ->
852
-
861
+ else
853
862
let simulSetOfEdgeDiscrims , fallthroughPathFrontiers = ChooseSimultaneousEdges frontiers path
854
863
855
864
let inpExprOpt , bindOpt = ChoosePreBinder simulSetOfEdgeDiscrims subexpr
@@ -861,8 +870,7 @@ let CompilePatternBasic
861
870
862
871
// Work out what the default/fall-through tree looks like, is any
863
872
// Check if match is complete, if so optimize the default case away.
864
-
865
- let defaultTreeOpt : DecisionTree option = CompileFallThroughTree fallthroughPathFrontiers path refuted simulSetOfCases
873
+ let defaultTreeOpt = CompileFallThroughTree fallthroughPathFrontiers path refuted simulSetOfCases
866
874
867
875
// OK, build the whole tree and whack on the binding if any
868
876
let finalDecisionTree =
@@ -879,7 +887,7 @@ let CompilePatternBasic
879
887
let es2 =
880
888
vs2 |> List.map ( fun v ->
881
889
match valMap.TryFind v with
882
- | None -> error ( Error ( FSComp.SR.patcMissingVariable ( v.DisplayName ), v.Range))
890
+ | None -> mkUnit g v.Range
883
891
| Some res -> res)
884
892
let rhs ' = TDSuccess( es2, i)
885
893
match GetWhenGuardOfClause i refuted with
@@ -913,14 +921,14 @@ let CompilePatternBasic
913
921
match getDiscrimOfPattern p with
914
922
| Some discrim ->
915
923
if ( match prevOpt with None -> true | Some ( EdgeDiscrim(_, discrimPrev, _)) -> discrimsHaveSameSimultaneousClass g discrim discrimPrev) then
916
- Some ( EdgeDiscrim( i', discrim, p.Range)), true
924
+ Some ( EdgeDiscrim( i', discrim, p.Range))
917
925
else
918
- None, false
926
+ None
919
927
920
928
| None ->
921
- None, true
929
+ None
922
930
else
923
- None, true )
931
+ None)
924
932
925
933
and IsCopyableInputExpr origInputExpr =
926
934
match origInputExpr with
@@ -1235,8 +1243,17 @@ let CompilePatternBasic
1235
1243
| _ ->
1236
1244
[ frontier]
1237
1245
1246
+ | TPat_ error range ->
1247
+ match discrim with
1248
+ | DecisionTreeTest.Error testRange when range = testRange ->
1249
+ [ Frontier ( i, active', valMap)]
1250
+ | _ ->
1251
+ [ frontier]
1252
+
1238
1253
| _ -> failwith " pattern compilation: GenerateNewFrontiersAfterSuccessfulInvestigation"
1239
- else [ frontier]
1254
+
1255
+ else
1256
+ [ frontier]
1240
1257
1241
1258
and BindProjectionPattern ( Active ( path , subExpr , p ) as inp ) (( accActive , accValMap ) as s ) =
1242
1259
let ( SubExpr ( accessf , ve )) = subExpr
@@ -1286,11 +1303,11 @@ let CompilePatternBasic
1286
1303
and BindProjectionPatterns ps s =
1287
1304
List.foldBack ( fun p sofar -> List.collect ( BindProjectionPattern p) sofar) ps [ s]
1288
1305
1289
- (* The setup routine of the match compiler *)
1306
+ // The setup routine of the match compiler.
1290
1307
let frontiers =
1291
- (( clausesL
1308
+ (( typedClauses
1292
1309
|> List.mapi ( fun i c ->
1293
- let initialSubExpr = SubExpr(( fun _tpinst x -> x), ( exprForVal origInputVal.Range origInputVal, origInputVal))
1310
+ let initialSubExpr = SubExpr(( fun _ x -> x), ( exprForVal origInputVal.Range origInputVal, origInputVal))
1294
1311
let investigations = BindProjectionPattern ( Active( PathEmpty inputTy, initialSubExpr, c.Pattern)) ([], ValMap<_>. Empty)
1295
1312
mkFrontiers investigations i)
1296
1313
|> List.concat)
@@ -1308,7 +1325,7 @@ let CompilePatternBasic
1308
1325
if warnOnUnused then
1309
1326
let used = HashSet<_>( accTargetsOfDecisionTree dtree [], HashIdentity.Structural)
1310
1327
1311
- clausesL |> List.iteri ( fun i c ->
1328
+ typedClauses |> List.iteri ( fun i c ->
1312
1329
if not ( used.Contains i) then warning ( RuleNeverMatched c.Range))
1313
1330
1314
1331
dtree, targets
0 commit comments