Skip to content

Commit 5f947fa

Browse files
committed
Move transformMixedListWithRangesToSeqExpr to CheckExpressionsOps
1 parent 8ceb9f6 commit 5f947fa

File tree

4 files changed

+50
-90
lines changed

4 files changed

+50
-90
lines changed

src/Compiler/Checking/Expressions/CheckArrayOrListComputedExpressions.fs

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,8 @@ open FSharp.Compiler.TypedTreeOps
1313
open FSharp.Compiler.Features
1414
open FSharp.Compiler.DiagnosticsLogger
1515
open FSharp.Compiler.Syntax
16-
open FSharp.Compiler.SyntaxTrivia
17-
18-
/// Adds implicit `yield!` before ranges in a mixed list/array comprehension.
19-
/// E.g., [-3; 1..10; 19] becomes [yield -3; yield! seq { 1..10 }; yield 19]
20-
let private transformMixedListWithRangesToSeqExpr elems m =
21-
let (|RangeExpr|_|) = RewriteRangeExpr
22-
23-
let ``yield!`` rewritten (orig: SynExpr) =
24-
SynExpr.YieldOrReturnFrom(
25-
(true, false),
26-
rewritten,
27-
orig.Range,
28-
{
29-
YieldOrReturnFromKeyword = orig.Range
30-
}
31-
)
32-
33-
let ``yield`` (orig: SynExpr) =
34-
SynExpr.YieldOrReturn((true, false), orig, orig.Range, { YieldOrReturnKeyword = orig.Range })
35-
36-
let ``;`` expr1 expr2 =
37-
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, true, expr1, expr2, m, SynExprSequentialTrivia.Zero)
38-
39-
let rec loop elems cont =
40-
match elems with
41-
| [] -> cont (SynExpr.Const(SynConst.Unit, m))
42-
| [ elem & RangeExpr rangeExpr ] -> cont (``yield!`` rangeExpr elem)
43-
| [ elem ] -> cont (``yield`` elem)
44-
| (elem & RangeExpr rangeExpr) :: elems -> loop elems (cont << ``;`` (``yield!`` rangeExpr elem))
45-
| elem :: elems -> loop elems (cont << ``;`` (``yield`` elem))
46-
47-
loop elems id
48-
49-
let private TcMixedSequencesWithRanges (cenv: TcFileState) env overallTy tpenv isArray elems m =
16+
17+
let private tcMixedSequencesWithRanges (cenv: TcFileState) env overallTy tpenv isArray elems m =
5018
let g = cenv.g
5119
let transformedBody = transformMixedListWithRangesToSeqExpr elems m
5220

@@ -141,7 +109,7 @@ let TcArrayOrListComputedExpression (cenv: TcFileState) env (overallTy: OverallT
141109
containsRangeExpressions
142110
&& g.langVersion.SupportsFeature LanguageFeature.AllowMixedRangesAndValuesInSeqExpressions
143111
then
144-
TcMixedSequencesWithRanges cenv env overallTy tpenv isArray elems m
112+
tcMixedSequencesWithRanges cenv env overallTy tpenv isArray elems m
145113
else
146114
if containsRangeExpressions then
147115
checkLanguageFeatureAndRecover cenv.g.langVersion LanguageFeature.AllowMixedRangesAndValuesInSeqExpressions m

src/Compiler/Checking/Expressions/CheckComputationExpressions.fs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,14 +1581,25 @@ let rec TryTranslateComputationExpression
15811581
&& hasBuilderMethod "Delay" ceenv.cenv ceenv.env ceenv.ad ceenv.builderTy m
15821582

15831583
if builderSupportsMixedRanges ceenv m then
1584-
let transformed = TransformSequenceWithRanges ceenv comp
1584+
let rec transformSequenceWithRanges ceenv expr =
1585+
match expr with
1586+
| SynExpr.Sequential(sp, true, e1, e2, m, trivia) ->
1587+
// Transform each part to yield/yieldFrom
1588+
let e1Transformed = TransformExprToYieldOrYieldFrom ceenv e1
1589+
let e2Transformed = transformSequenceWithRanges ceenv e2
1590+
// Create a new sequential expression with the transformed parts
1591+
SynExpr.Sequential(sp, true, e1Transformed, e2Transformed, m, trivia)
1592+
| e -> TransformExprToYieldOrYieldFrom ceenv e
1593+
1594+
let transformed = transformSequenceWithRanges ceenv comp
15851595
Some(TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace transformed translatedCtxt)
15861596
else
15871597
None
15881598
// Check for 'where x > y' and other mis-applications of infix operators. If detected, give a good error message, and just ignore innerComp1
15891599
elif ceenv.isQuery && checkForBinaryApp ceenv innerComp1 then
1590-
// if containsRangeExpressions then
1591-
// reportRangeExpressionsNotSupported ceenv comp
1600+
if containsRangeExpressions then
1601+
reportRangeExpressionsNotSupported ceenv comp
1602+
15921603
Some(TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace innerComp2 translatedCtxt)
15931604

15941605
else
@@ -2722,18 +2733,6 @@ and TransformExprToYieldOrYieldFrom ceenv expr =
27222733
SynExpr.YieldOrReturn((true, false), expr, expr.Range, { YieldOrReturnKeyword = expr.Range })
27232734
| e -> SynExpr.YieldOrReturn((true, false), e, e.Range, { YieldOrReturnKeyword = e.Range })
27242735

2725-
/// Transform a sequential expression with ranges into yields and yieldFroms
2726-
and TransformSequenceWithRanges ceenv expr =
2727-
match expr with
2728-
| SynExpr.Sequential(sp, true, e1, e2, m, trivia) ->
2729-
// Transform each part to yield/yieldFrom
2730-
let e1Transformed = TransformExprToYieldOrYieldFrom ceenv e1
2731-
let e2Transformed = TransformSequenceWithRanges ceenv e2
2732-
2733-
// Create a new sequential expression with the transformed parts
2734-
SynExpr.Sequential(sp, true, e1Transformed, e2Transformed, m, trivia)
2735-
| e -> TransformExprToYieldOrYieldFrom ceenv e
2736-
27372736
and TranslateComputationExpression (ceenv: ComputationExpressionContext<'a>) firstTry q varSpace comp translatedCtxt =
27382737

27392738
ceenv.cenv.stackGuard.Guard

src/Compiler/Checking/Expressions/CheckExpressionsOps.fs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ open FSharp.Compiler.TypedTree
1717
open FSharp.Compiler.TypedTreeBasics
1818
open FSharp.Compiler.TypedTreeOps
1919
open FSharp.Compiler.SyntaxTreeOps
20+
open FSharp.Compiler.SyntaxTrivia
2021

2122
let TryAllowFlexibleNullnessInControlFlow isFirst (g: TcGlobals.TcGlobals) ty =
2223
match isFirst, g.checkNullness, GetTyparTyIfSupportsNull g ty with
@@ -393,3 +394,34 @@ let inline mkOptionalParamTyBasedOnAttribute (g: TcGlobals.TcGlobals) tyarg attr
393394
mkValueOptionTy g tyarg
394395
else
395396
mkOptionTy g tyarg
397+
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]
400+
let transformMixedListWithRangesToSeqExpr elems m =
401+
let (|RangeExpr|_|) = RewriteRangeExpr
402+
403+
let ``yield!`` rewritten (orig: SynExpr) =
404+
SynExpr.YieldOrReturnFrom(
405+
(true, false),
406+
rewritten,
407+
orig.Range,
408+
{
409+
YieldOrReturnFromKeyword = orig.Range
410+
}
411+
)
412+
413+
let ``yield`` (orig: SynExpr) =
414+
SynExpr.YieldOrReturn((true, false), orig, orig.Range, { YieldOrReturnKeyword = orig.Range })
415+
416+
let ``;`` expr1 expr2 =
417+
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, true, expr1, expr2, m, SynExprSequentialTrivia.Zero)
418+
419+
let rec loop elems cont =
420+
match elems with
421+
| [] -> cont (SynExpr.Const(SynConst.Unit, m))
422+
| [ elem & RangeExpr rangeExpr ] -> cont (``yield!`` rangeExpr elem)
423+
| [ elem ] -> cont (``yield`` elem)
424+
| (elem & RangeExpr rangeExpr) :: elems -> loop elems (cont << ``;`` (``yield!`` rangeExpr elem))
425+
| elem :: elems -> loop elems (cont << ``;`` (``yield`` elem))
426+
427+
loop elems id

src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -451,46 +451,7 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
451451
delayedExpr, tpenv
452452

453453
let private TcMixedSequencesWithRanges cenv env tpenv overallTy elems m =
454-
let rec buildSeqBody elems =
455-
match elems with
456-
| [] -> SynExpr.Const(SynConst.Unit, m)
457-
| [ elem ] ->
458-
match elem with
459-
| SynExpr.IndexRange _ ->
460-
match RewriteRangeExpr elem with
461-
| Some rewrittenRange ->
462-
SynExpr.YieldOrReturnFrom(
463-
(true, false),
464-
rewrittenRange,
465-
elem.Range,
466-
{
467-
YieldOrReturnFromKeyword = elem.Range
468-
}
469-
)
470-
| None -> SynExpr.YieldOrReturn((true, false), elem, elem.Range, { YieldOrReturnKeyword = elem.Range })
471-
| _ -> SynExpr.YieldOrReturn((true, false), elem, elem.Range, { YieldOrReturnKeyword = elem.Range })
472-
| elem :: rest ->
473-
let headExpr =
474-
match elem with
475-
| SynExpr.IndexRange _ ->
476-
match RewriteRangeExpr elem with
477-
| Some rewrittenRange ->
478-
SynExpr.YieldOrReturnFrom(
479-
(true, false),
480-
rewrittenRange,
481-
elem.Range,
482-
{
483-
YieldOrReturnFromKeyword = elem.Range
484-
}
485-
)
486-
| None -> SynExpr.YieldOrReturn((true, false), elem, elem.Range, { YieldOrReturnKeyword = elem.Range })
487-
| _ -> SynExpr.YieldOrReturn((true, false), elem, elem.Range, { YieldOrReturnKeyword = elem.Range })
488-
489-
let tailExpr = buildSeqBody rest
490-
491-
SynExpr.Sequential(DebugPointAtSequential.SuppressNeither, true, headExpr, tailExpr, m, SynExprSequentialTrivia.Zero)
492-
493-
let transformedBody = buildSeqBody elems
454+
let transformedBody = transformMixedListWithRangesToSeqExpr elems m
494455
TcSequenceExpression cenv env tpenv transformedBody overallTy m
495456

496457
let TcSequenceExpressionEntry (cenv: TcFileState) env (overallTy: OverallTy) tpenv (hasBuilder, comp) m =

0 commit comments

Comments
 (0)