Skip to content

Commit b3e463e

Browse files
committed
Merge branch 'mixed-ranges-prototype' of github.com:edgarfgp/fsharp into mixed-ranges-prototype
2 parents ba9f733 + bc8a8f1 commit b3e463e

File tree

4 files changed

+55
-65
lines changed

4 files changed

+55
-65
lines changed

src/Compiler/Checking/Expressions/CheckArrayOrListComputedExpressions.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ open FSharp.Compiler.Syntax
1616

1717
let private tcMixedSequencesWithRanges (cenv: TcFileState) env overallTy tpenv isArray elems m =
1818
let g = cenv.g
19-
let transformedBody = transformMixedListWithRangesToSeqExpr elems m
19+
let transformedBody = insertImplicitYieldsAndYieldBangs elems m
2020

2121
let genCollElemTy = NewInferenceType g
2222
let genCollTy = (if isArray then mkArrayType else mkListTy) g genCollElemTy

src/Compiler/Checking/Expressions/CheckComputationExpressions.fs

Lines changed: 52 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,14 +1563,30 @@ let rec TryTranslateComputationExpression
15631563
Some(ConsumeCustomOpClauses ceenv comp q varSpace dataCompPriorToOp comp false mClause)
15641564

15651565
| SynExpr.Sequential(sp, true, innerComp1, innerComp2, m, _) ->
1566-
let rec containsRangeExpressions expr =
1567-
match expr with
1568-
| SynExpr.IndexRange _ -> true
1569-
| SynExpr.Sequential(_, true, e1, e2, _, _) -> containsRangeExpressions e1 || containsRangeExpressions e2
1570-
| _ -> false
1566+
let containsRangeExpressions expr =
1567+
let rec loop exprs =
1568+
match exprs with
1569+
| SynExpr.IndexRange _ :: _ -> true
1570+
| SynExpr.Sequential(_, true, e1, e2, _, _) :: exprs -> loop (e1 :: e2 :: exprs)
1571+
| _ -> false
1572+
1573+
loop [ expr ]
15711574

15721575
let containsRangeExpressions = containsRangeExpressions comp
15731576

1577+
/// Report language feature error for each range expression in a sequence
1578+
let reportRangeExpressionsNotSupported ceenv expr =
1579+
let rec loop exprs =
1580+
match exprs with
1581+
| [] -> ()
1582+
| SynExpr.IndexRange(_, _, _, _, _, m) :: exprs ->
1583+
checkLanguageFeatureAndRecover ceenv.cenv.g.langVersion LanguageFeature.AllowMixedRangesAndValuesInSeqExpressions m
1584+
loop exprs
1585+
| SynExpr.Sequential(_, true, e1, e2, _, _) :: exprs -> loop (e1 :: e2 :: exprs)
1586+
| _ :: exprs -> loop exprs
1587+
1588+
loop [ expr ]
1589+
15741590
if
15751591
ceenv.cenv.g.langVersion.SupportsFeature LanguageFeature.AllowMixedRangesAndValuesInSeqExpressions
15761592
&& containsRangeExpressions
@@ -1581,15 +1597,20 @@ let rec TryTranslateComputationExpression
15811597
&& hasBuilderMethod "Delay" ceenv.cenv ceenv.env ceenv.ad ceenv.builderTy m
15821598

15831599
if builderSupportsMixedRanges ceenv m then
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
1600+
let transformSequenceWithRanges ceenv expr =
1601+
let rec loop expr cont =
1602+
match expr with
1603+
| SynExpr.Sequential(sp, true, e1, e2, m, trivia) ->
1604+
// Transform each part to yield/yieldFrom
1605+
let e1Transformed = TransformExprToYieldOrYieldFrom ceenv e1
1606+
// Create a new sequential expression with the transformed parts
1607+
loop
1608+
e2
1609+
(cont
1610+
<< fun e2Transformed -> SynExpr.Sequential(sp, true, e1Transformed, e2Transformed, m, trivia))
1611+
| e -> cont (TransformExprToYieldOrYieldFrom ceenv e)
1612+
1613+
loop expr id
15931614

15941615
let transformed = transformSequenceWithRanges ceenv comp
15951616
Some(TranslateComputationExpression ceenv CompExprTranslationPass.Initial q varSpace transformed translatedCtxt)
@@ -2702,56 +2723,25 @@ and isSimpleExpr ceenv comp =
27022723
| SynExpr.DoBang _ -> false
27032724
| _ -> true
27042725

2705-
/// Report language feature error for each range expression in a sequence
2706-
and reportRangeExpressionsNotSupported ceenv expr =
2707-
match expr with
2708-
| SynExpr.IndexRange(_, _, _, _, _, m) ->
2709-
checkLanguageFeatureAndRecover ceenv.cenv.g.langVersion LanguageFeature.AllowMixedRangesAndValuesInSeqExpressions m
2710-
| SynExpr.Sequential(_, true, e1, e2, _, _) ->
2711-
reportRangeExpressionsNotSupported ceenv e1
2712-
reportRangeExpressionsNotSupported ceenv e2
2713-
| _ -> ()
2714-
2715-
/// Check if this is a simple semicolon sequence (potentially with ranges)
2716-
and isSimpleSemicolonSequence ceenv expr =
2717-
match expr with
2718-
| SynExpr.Sequential(_, true, e1, e2, _, _) -> isSimpleExpr ceenv e1 && isSimpleSemicolonSequence ceenv e2
2719-
| e -> isSimpleExpr ceenv e
2720-
27212726
/// Transform a single expression to Yield or YieldFrom based on whether it's a range
27222727
and TransformExprToYieldOrYieldFrom ceenv expr =
2723-
match expr with
2724-
| SynExpr.IndexRange _ ->
2725-
match RewriteRangeExpr expr with
2726-
| Some rewrittenRange ->
2727-
// Check if YieldFrom is available
2728-
match
2729-
TryFindIntrinsicOrExtensionMethInfo
2730-
ResultCollectionSettings.AllResults
2731-
ceenv.cenv
2732-
ceenv.env
2733-
expr.Range
2734-
ceenv.ad
2735-
"YieldFrom"
2736-
ceenv.builderTy
2737-
with
2738-
| [] ->
2739-
// No YieldFrom, use Yield
2740-
// Create a YieldOrReturn expression and let the CE machinery handle it
2741-
SynExpr.YieldOrReturn((true, false), rewrittenRange, expr.Range, { YieldOrReturnKeyword = expr.Range })
2742-
| _ ->
2743-
SynExpr.YieldOrReturnFrom(
2744-
(true, false),
2745-
rewrittenRange,
2746-
expr.Range,
2747-
{
2748-
YieldOrReturnFromKeyword = expr.Range
2749-
}
2750-
)
2751-
| None ->
2752-
// If we can't rewrite range, yield the expression
2753-
SynExpr.YieldOrReturn((true, false), expr, expr.Range, { YieldOrReturnKeyword = expr.Range })
2754-
| e -> SynExpr.YieldOrReturn((true, false), e, e.Range, { YieldOrReturnKeyword = e.Range })
2728+
let m = expr.Range
2729+
2730+
let ``yield!`` rewrittenRange =
2731+
SynExpr.YieldOrReturnFrom((true, false), rewrittenRange, m, { YieldOrReturnFromKeyword = m })
2732+
2733+
let ``yield`` rewrittenRange =
2734+
SynExpr.YieldOrReturn((true, false), rewrittenRange, m, { YieldOrReturnKeyword = m })
2735+
2736+
// If there is no YieldFrom defined on the builder, use Yield;
2737+
// create a YieldOrReturn expression and let the CE machinery handle it.
2738+
match RewriteRangeExpr expr with
2739+
| Some rewrittenRange ->
2740+
if hasBuilderMethod "YieldFrom" ceenv.cenv ceenv.env ceenv.ad ceenv.builderTy m then
2741+
``yield!`` rewrittenRange
2742+
else
2743+
``yield`` rewrittenRange
2744+
| None -> ``yield`` expr
27552745

27562746
and TranslateComputationExpression (ceenv: ComputationExpressionContext<'a>) firstTry q varSpace comp translatedCtxt =
27572747

src/Compiler/Checking/Expressions/CheckExpressionsOps.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ let inline mkOptionalParamTyBasedOnAttribute (g: TcGlobals.TcGlobals) tyarg attr
397397

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

403403
let ``yield!`` rewritten (orig: SynExpr) =

src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
472472
delayedExpr, tpenv
473473

474474
let private TcMixedSequencesWithRanges cenv env tpenv overallTy elems m =
475-
let transformedBody = transformMixedListWithRangesToSeqExpr elems m
475+
let transformedBody = insertImplicitYieldsAndYieldBangs elems m
476476
TcSequenceExpression cenv env tpenv transformedBody overallTy m
477477

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

0 commit comments

Comments
 (0)