Skip to content

Commit 43babe7

Browse files
Update src/Compiler/Checking/Expressions/CheckExpressionsOps.fs
Co-authored-by: Brian Rourke Boll <brianrourkeboll@users.noreply.github.com>
1 parent d881686 commit 43babe7

File tree

2 files changed

+54
-54
lines changed

2 files changed

+54
-54
lines changed

src/Compiler/Checking/Expressions/CheckArrayOrListComputedExpressions.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ let TcArrayOrListComputedExpression (cenv: TcFileState) env (overallTy: OverallT
199199
| e -> List.rev (e :: acc)
200200

201201
let elems = getElems comp []
202-
transformMixedListWithExplicitYields elems m
202+
insertImplicitYieldsAndYieldBangs elems m
203203
| _ -> comp
204204
else if containsRangeMixedWithYields then
205205
checkLanguageFeatureAndRecover g.langVersion LanguageFeature.AllowMixedRangesAndValuesInSeqExpressions m

src/Compiler/Checking/Expressions/CheckExpressionsOps.fs

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -395,11 +395,17 @@ let inline mkOptionalParamTyBasedOnAttribute (g: TcGlobals.TcGlobals) tyarg attr
395395
else
396396
mkOptionTy g tyarg
397397

398-
/// Adds implicit `yield!` before ranges in a mixed list/array comprehension.
399-
/// E.g., [-3; 1..10; 19] becomes [yield -3; yield! seq { 1..10 }; yield 19]
398+
/// Adds implicit `yield!` before ranges in a mixed list/array/seq comprehension if necessary.
399+
/// E.g., [-3; 1..10; 19] becomes [yield -3; yield! (..) 1 10; yield 19]
400400
let insertImplicitYieldsAndYieldBangs elems m =
401401
let (|RangeExpr|_|) = RewriteRangeExpr
402402

403+
let (|IfThenElseExpr|_|) expr =
404+
match expr with
405+
| SynExpr.IfThenElse(ifExpr, thenExpr, elseExpr, spIfToThen, isFromErrorRecovery, range, trivia) ->
406+
ValueSome(thenExpr, elseExpr, (ifExpr, spIfToThen, isFromErrorRecovery, range, trivia))
407+
| _ -> ValueNone
408+
403409
let ``yield!`` rewritten (orig: SynExpr) =
404410
SynExpr.YieldOrReturnFrom(
405411
(true, false),
@@ -413,68 +419,62 @@ let insertImplicitYieldsAndYieldBangs elems m =
413419
let ``yield`` (orig: SynExpr) =
414420
SynExpr.YieldOrReturn((true, false), orig, orig.Range, { YieldOrReturnKeyword = orig.Range })
415421

422+
let ``if then`` (ifExpr, spIfToThen, isFromErrorRecovery, m, trivia) thenExpr =
423+
SynExpr.IfThenElse(ifExpr, thenExpr, None, spIfToThen, isFromErrorRecovery, m, trivia)
424+
425+
let ``if then else`` (ifExpr, spIfToThen, isFromErrorRecovery, m, trivia) thenExpr elseExpr =
426+
SynExpr.IfThenElse(ifExpr, thenExpr, Some elseExpr, spIfToThen, isFromErrorRecovery, m, trivia)
427+
428+
let ``match`` (dbg, expr, m, trivia) clauses =
429+
SynExpr.Match(dbg, expr, clauses, m, trivia)
430+
431+
let ``match!`` (dbg, expr, m, trivia) clauses =
432+
SynExpr.MatchBang(dbg, expr, clauses, m, trivia)
433+
416434
let ``;`` expr1 expr2 =
417435
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, true, expr1, expr2, m, SynExprSequentialTrivia.Zero)
418436

419-
let rec loop elems cont =
437+
let rec loopElems elems cont =
420438
match elems with
421439
| [] -> cont (SynExpr.Const(SynConst.Unit, m))
440+
422441
| [ elem & RangeExpr rangeExpr ] -> cont (``yield!`` rangeExpr elem)
442+
443+
| [ elem & SynExpr.YieldOrReturn _ ]
444+
| [ elem & SynExpr.YieldOrReturnFrom _ ] -> cont elem
445+
446+
| [ IfThenElseExpr(thenExpr, None, info) ] -> loopElems [ thenExpr ] (cont << ``if then`` info)
447+
| [ IfThenElseExpr(thenExpr, Some elseExpr, info) ] ->
448+
loopElems [ thenExpr ] (fun thenExpr -> loopElems [ elseExpr ] (cont << ``if then else`` info thenExpr))
449+
450+
| [ SynExpr.Match(dbg, expr, clauses, m, trivia) ] -> loopMatchClauses [] clauses (cont << ``match`` (dbg, expr, m, trivia))
451+
| [ SynExpr.MatchBang(dbg, expr, clauses, m, trivia) ] -> loopMatchClauses [] clauses (cont << ``match!`` (dbg, expr, m, trivia))
452+
423453
| [ elem ] -> cont (``yield`` elem)
424-
| (elem & RangeExpr rangeExpr) :: elems -> loop elems (cont << ``;`` (``yield!`` rangeExpr elem))
425-
| elem :: elems -> loop elems (cont << ``;`` (``yield`` elem))
426454

427-
loop elems id
455+
| (elem & RangeExpr rangeExpr) :: elems -> loopElems elems (cont << ``;`` (``yield!`` rangeExpr elem))
428456

429-
/// Transforms mixed lists/arrays that contain explicit yield! expressions.
430-
/// E.g., [1..10; 19; yield! 20..30] becomes [yield! 1..10; yield 19; yield! 20..30]
431-
let transformMixedListWithExplicitYields elems m =
432-
let (|RangeExpr|_|) = RewriteRangeExpr
457+
| (elem & SynExpr.YieldOrReturn _) :: elems
458+
| (elem & SynExpr.YieldOrReturnFrom _) :: elems -> loopElems elems (cont << ``;`` elem)
433459

434-
let ``yield!`` rewritten (orig: SynExpr) =
435-
SynExpr.YieldOrReturnFrom(
436-
(true, false),
437-
rewritten,
438-
orig.Range,
439-
{
440-
YieldOrReturnFromKeyword = orig.Range
441-
}
442-
)
460+
| IfThenElseExpr(thenExpr, None, info) :: elems ->
461+
loopElems [ thenExpr ] (fun thenExpr -> loopElems elems (cont << ``;`` (``if then`` info thenExpr)))
462+
| IfThenElseExpr(thenExpr, Some elseExpr, info) :: elems ->
463+
loopElems [ thenExpr ] (fun thenExpr ->
464+
loopElems [ elseExpr ] (fun elseExpr -> loopElems elems (cont << ``;`` (``if then else`` info thenExpr elseExpr))))
443465

444-
let ``yield`` (orig: SynExpr) =
445-
SynExpr.YieldOrReturn((true, false), orig, orig.Range, { YieldOrReturnKeyword = orig.Range })
466+
| SynExpr.Match(dbg, expr, clauses, m, trivia) :: elems ->
467+
loopMatchClauses [] clauses (fun clauses -> loopElems elems (cont << ``;`` (``match`` (dbg, expr, m, trivia) clauses)))
468+
| SynExpr.MatchBang(dbg, expr, clauses, m, trivia) :: elems ->
469+
loopMatchClauses [] clauses (fun clauses -> loopElems elems (cont << ``;`` (``match!`` (dbg, expr, m, trivia) clauses)))
446470

447-
let ``;`` expr1 expr2 =
448-
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, true, expr1, expr2, m, SynExprSequentialTrivia.Zero)
471+
| elem :: elems -> loopElems elems (cont << ``;`` (``yield`` elem))
449472

450-
let rec transformExpr expr cont =
451-
match expr with
452-
| RangeExpr rangeExpr -> cont (``yield!`` rangeExpr expr)
453-
| SynExpr.YieldOrReturnFrom _ -> cont expr
454-
| SynExpr.YieldOrReturn _ -> cont expr
455-
| SynExpr.IfThenElse(ifExpr, thenExpr, elseExprOpt, spIfToThen, isFromErrorRecovery, range, trivia) ->
456-
transformExpr thenExpr (fun transformedThen ->
457-
match elseExprOpt with
458-
| Some elseExpr ->
459-
transformExpr elseExpr (fun transformedElse ->
460-
cont (
461-
SynExpr.IfThenElse(
462-
ifExpr,
463-
transformedThen,
464-
Some transformedElse,
465-
spIfToThen,
466-
isFromErrorRecovery,
467-
range,
468-
trivia
469-
)
470-
))
471-
| None -> cont (SynExpr.IfThenElse(ifExpr, transformedThen, None, spIfToThen, isFromErrorRecovery, range, trivia)))
472-
| _ -> cont (``yield`` expr)
473-
474-
let rec loop elems cont =
475-
match elems with
476-
| [] -> cont (SynExpr.Const(SynConst.Unit, m))
477-
| [ elem ] -> transformExpr elem cont
478-
| elem :: elems -> transformExpr elem (fun transformedElem -> loop elems (fun restExpr -> cont (``;`` transformedElem restExpr)))
473+
and loopMatchClauses acc clauses cont =
474+
match clauses with
475+
| [] -> cont (List.rev acc)
476+
| SynMatchClause(pat, whenExpr, resultExpr, m, dbg, trivia) :: clauses ->
477+
loopElems [ resultExpr ] (fun resultExpr ->
478+
loopMatchClauses (SynMatchClause(pat, whenExpr, resultExpr, m, dbg, trivia) :: acc) clauses cont)
479479

480-
loop elems id
480+
loopElems elems id

0 commit comments

Comments
 (0)