Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Experiment] type resolved arr[idx] #11749

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 65 additions & 18 deletions src/fsharp/CheckComputationExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,10 @@ let TcComputationExpression cenv env overallTy tpenv (mWhole, interpExpr: Expr,


| SynExpr.ForEach (spForLoop, SeqExprOnly _seqExprOnly, isFromSource, pat, sourceExpr, innerComp, _) ->
let sourceExpr =
match RewriteRangeExpr sourceExpr with
| Some e -> e
| None -> sourceExpr
let wrappedSourceExpr = mkSourceExprConditional isFromSource sourceExpr
let mFor = match spForLoop with DebugPointAtFor.Yes m -> m.NoteDebugPoint(RangeDebugPointKind.For) | _ -> pat.Range
let mPat = pat.Range
Expand Down Expand Up @@ -1726,6 +1730,10 @@ let TcSequenceExpression (cenv: cenv) env tpenv comp overallTy m =
let rec tryTcSequenceExprBody env genOuterTy tpenv comp =
match comp with
| SynExpr.ForEach (spFor, SeqExprOnly _seqExprOnly, _isFromSource, pat, pseudoEnumExpr, innerComp, m) ->
let pseudoEnumExpr =
match RewriteRangeExpr pseudoEnumExpr with
| Some e -> e
| None -> pseudoEnumExpr
// This expression is not checked with the knowledge it is an IEnumerable, since we permit other enumerable types with GetEnumerator/MoveNext methods, as does C#
let pseudoEnumExpr, arb_ty, tpenv = TcExprOfUnknownType cenv env tpenv pseudoEnumExpr
let enumExpr, enumElemTy = ConvertArbitraryExprToEnumerable cenv arb_ty env pseudoEnumExpr
Expand Down Expand Up @@ -1931,31 +1939,70 @@ let TcSequenceExpression (cenv: cenv) env tpenv comp overallTy m =
let delayedExpr = mkDelayedExpr coreExpr.Range coreExpr
delayedExpr, tpenv

let TcSequenceExpressionEntry (cenv: cenv) env overallTy tpenv (isArrayOrList, isNotNakedRefCell, comp) m =
let TcSequenceExpressionEntry (cenv: cenv) env overallTy tpenv (hasBuilder, comp) m =
match RewriteRangeExpr comp with
| Some replacementExpr ->
TcExpr cenv overallTy env tpenv replacementExpr
| None ->

let implicitYieldEnabled = cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield
let validateObjectSequenceOrRecordExpression = not implicitYieldEnabled
if not isArrayOrList then
match comp with
| SynExpr.New _ ->
errorR(Error(FSComp.SR.tcInvalidObjectExpressionSyntaxForm(), m))
| SimpleSemicolonSequence cenv false _ when validateObjectSequenceOrRecordExpression ->
errorR(Error(FSComp.SR.tcInvalidObjectSequenceOrRecordExpression(), m))
| _ ->
()
if not !isNotNakedRefCell && not cenv.g.compilingFslib then
match comp with
| SynExpr.New _ ->
errorR(Error(FSComp.SR.tcInvalidObjectExpressionSyntaxForm(), m))
| SimpleSemicolonSequence cenv false _ when validateObjectSequenceOrRecordExpression ->
errorR(Error(FSComp.SR.tcInvalidObjectSequenceOrRecordExpression(), m))
| _ ->
()
if not hasBuilder && not cenv.g.compilingFslib then
error(Error(FSComp.SR.tcInvalidSequenceExpressionSyntaxForm(), m))

TcSequenceExpression cenv env tpenv comp overallTy m

let TcArrayOrListSequenceExpression (cenv: cenv) env overallTy tpenv (isArray, comp) m =
let TcArrayOrListComputedExpression (cenv: cenv) env overallTy tpenv (isArray, comp) m =
// The syntax '[ n .. m ]' and '[ n .. step .. m ]' is not really part of array or list syntax.
// It could be in the future, e.g. '[ 1; 2..30; 400 ]'
//
// The elaborated form of '[ n .. m ]' is 'List.ofSeq (seq (op_Range n m))' and this shouldn't change
match RewriteRangeExpr comp with
| Some replacementExpr ->
let genCollElemTy = NewInferenceType ()

let genCollTy = (if isArray then mkArrayType else mkListTy) cenv.g genCollElemTy

UnifyTypes cenv env m overallTy genCollTy

let exprTy = mkSeqTy cenv.g genCollElemTy

let expr, tpenv = TcExpr cenv exprTy env tpenv replacementExpr
let expr =
if cenv.g.compilingFslib then
//warning(Error(FSComp.SR.fslibUsingComputedListOrArray(), expr.Range))
expr
else
// We add a call to 'seq ... ' to make sure sequence expression compilation gets applied to the contents of the
// comprehension. But don't do this in FSharp.Core.dll since 'seq' may not yet be defined.
mkCallSeq cenv.g m genCollElemTy expr

let expr = mkCoerceExpr(expr, exprTy, expr.Range, overallTy)

let expr =
if isArray then
mkCallSeqToArray cenv.g m genCollElemTy expr
else
mkCallSeqToList cenv.g m genCollElemTy expr
expr, tpenv

| None ->

// LanguageFeatures.ImplicitYield do not require this validation
let implicitYieldEnabled = cenv.g.langVersion.SupportsFeature LanguageFeature.ImplicitYield
let validateExpressionWithIfRequiresParenthesis = not implicitYieldEnabled
let acceptDeprecatedIfThenExpression = not implicitYieldEnabled

match comp with
| SynExpr.CompExpr (_, _, (SimpleSemicolonSequence cenv acceptDeprecatedIfThenExpression elems as body), _) ->
match body with
| SimpleSemicolonSequence cenv acceptDeprecatedIfThenExpression elems ->
match comp with
| SimpleSemicolonSequence cenv false _ -> ()
| _ when validateExpressionWithIfRequiresParenthesis -> errorR(Deprecated(FSComp.SR.tcExpressionWithIfRequiresParenthesis(), m))
| _ -> ()
Expand Down Expand Up @@ -1983,12 +2030,12 @@ let TcArrayOrListSequenceExpression (cenv: cenv) env overallTy tpenv (isArray, c

UnifyTypes cenv env m overallTy genCollTy

let exprty = mkSeqTy cenv.g genCollElemTy
let exprTy = mkSeqTy cenv.g genCollElemTy

// Check the comprehension
let expr, tpenv = TcExpr cenv exprty env tpenv comp
// Check the comprehension as a sequence
let expr, tpenv = TcSequenceExpression cenv env tpenv comp exprTy m

let expr = mkCoerceIfNeeded cenv.g exprty (tyOfExpr cenv.g expr) expr
let expr = mkCoerceIfNeeded cenv.g exprTy (tyOfExpr cenv.g expr) expr

let expr =
if cenv.g.compilingFslib then
Expand All @@ -1999,7 +2046,7 @@ let TcArrayOrListSequenceExpression (cenv: cenv) env overallTy tpenv (isArray, c
// comprehension. But don't do this in FSharp.Core.dll since 'seq' may not yet be defined.
mkCallSeq cenv.g m genCollElemTy expr

let expr = mkCoerceExpr(expr, exprty, expr.Range, overallTy)
let expr = mkCoerceExpr(expr, exprTy, expr.Range, overallTy)

let expr =
if isArray then
Expand Down
4 changes: 2 additions & 2 deletions src/fsharp/CheckComputationExpressions.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ open FSharp.Compiler.Syntax
open FSharp.Compiler.Text
open FSharp.Compiler.TypedTree

val TcSequenceExpressionEntry: cenv:TcFileState -> env:TcEnv -> overallTy:TType -> tpenv:UnscopedTyparEnv -> isArrayOrList:bool * isNotNakedRefCell:bool ref * comp:SynExpr -> m:range -> Expr * UnscopedTyparEnv
val TcSequenceExpressionEntry: cenv:TcFileState -> env:TcEnv -> overallTy:TType -> tpenv:UnscopedTyparEnv -> hasBuilder:bool * comp:SynExpr -> m:range -> Expr * UnscopedTyparEnv

val TcArrayOrListSequenceExpression: cenv:TcFileState -> env:TcEnv -> overallTy:TType -> tpenv:UnscopedTyparEnv -> isArray:bool * comp:SynExpr -> m:range -> Expr * UnscopedTyparEnv
val TcArrayOrListComputedExpression: cenv:TcFileState -> env:TcEnv -> overallTy:TType -> tpenv:UnscopedTyparEnv -> isArray:bool * comp:SynExpr -> m:range -> Expr * UnscopedTyparEnv

val TcComputationExpression: cenv:TcFileState -> env:TcEnv -> overallTy:TType -> tpenv:UnscopedTyparEnv -> mWhole:range * interpExpr:Expr * builderTy:TType * comp:SynExpr -> Expr * UnscopedTyparEnv

4 changes: 2 additions & 2 deletions src/fsharp/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5806,7 +5806,7 @@ let TypeCheckOneImplFile
cenv.Create (g, isScript, niceNameGen, amap, topCcu, false, Option.isSome rootSigOpt,
conditionalDefines, tcSink, (LightweightTcValForUsingInBuildMethodCall g), isInternalTestSpanStackReferring,
tcSequenceExpressionEntry=TcSequenceExpressionEntry,
tcArrayOrListSequenceExpression=TcArrayOrListSequenceExpression,
tcArrayOrListSequenceExpression=TcArrayOrListComputedExpression,
tcComputationExpression=TcComputationExpression)

let envinner, mtypeAcc = MakeInitialEnv env
Expand Down Expand Up @@ -5913,7 +5913,7 @@ let TypeCheckOneSigFile (g, niceNameGen, amap, topCcu, checkForErrors, condition
(g, false, niceNameGen, amap, topCcu, true, false, conditionalDefines, tcSink,
(LightweightTcValForUsingInBuildMethodCall g), isInternalTestSpanStackReferring,
tcSequenceExpressionEntry=TcSequenceExpressionEntry,
tcArrayOrListSequenceExpression=TcArrayOrListSequenceExpression,
tcArrayOrListSequenceExpression=TcArrayOrListComputedExpression,
tcComputationExpression=TcComputationExpression)

let envinner, mtypeAcc = MakeInitialEnv tcEnv
Expand Down
Loading