Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd2cb414

Browse files
forkiKevinRansom
authored andcommitted
Keep context information over parens and sequence expressions (#3763)
* Failing tests for else in parens* ShrinkContext* Show that we still don't report error in last line* Show that longer expressions don't take context* ShrinkContext along Sequence expressions
1 parent8861075 commitd2cb414

File tree

5 files changed

+72
-1
lines changed

5 files changed

+72
-1
lines changed

‎src/fsharp/TypeChecker.fs‎

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,36 @@ let ImplicitlyOpenOwnNamespace tcSink g amap scopem enclosingNamespacePath env =
699699
// Helpers for unification
700700
//-------------------------------------------------------------------------
701701

702+
/// When the context is matching the oldRange then this function shrinks it to newRange.
703+
/// This can be used to change context over no-op expressions like parens.
704+
let ShrinkContext env oldRange newRange =
705+
match env.eContextInfo with
706+
| ContextInfo.NoContext
707+
| ContextInfo.RecordFields
708+
| ContextInfo.TupleInRecordFields
709+
| ContextInfo.ReturnInComputationExpression
710+
| ContextInfo.YieldInComputationExpression
711+
| ContextInfo.RuntimeTypeTest _
712+
| ContextInfo.DowncastUsedInsteadOfUpcast _ ->
713+
env
714+
| ContextInfo.CollectionElement (b,m) ->
715+
if m <> oldRange then env else
716+
{ env with eContextInfo = ContextInfo.CollectionElement(b,newRange) }
717+
| ContextInfo.FollowingPatternMatchClause m ->
718+
if m <> oldRange then env else
719+
{ env with eContextInfo = ContextInfo.FollowingPatternMatchClause newRange }
720+
| ContextInfo.PatternMatchGuard m ->
721+
if m <> oldRange then env else
722+
{ env with eContextInfo = ContextInfo.PatternMatchGuard newRange }
723+
| ContextInfo.IfExpression m ->
724+
if m <> oldRange then env else
725+
{ env with eContextInfo = ContextInfo.IfExpression newRange }
726+
| ContextInfo.OmittedElseBranch m ->
727+
if m <> oldRange then env else
728+
{ env with eContextInfo = ContextInfo.OmittedElseBranch newRange }
729+
| ContextInfo.ElseBranchResult m ->
730+
if m <> oldRange then env else
731+
{ env with eContextInfo = ContextInfo.ElseBranchResult newRange }
702732

703733
/// Optimized unification routine that avoids creating new inference
704734
/// variables unnecessarily
@@ -5610,6 +5640,7 @@ and TcExprUndelayed cenv overallTy env tpenv (expr: SynExpr) =
56105640
// We invoke CallExprHasTypeSink for every construct which is atomic in the syntax, i.e. where a '.' immediately following the
56115641
// construct is a dot-lookup for the result of the construct.
56125642
CallExprHasTypeSink cenv.tcSink (mWholeExprIncludingParentheses, env.NameEnv, overallTy, env.DisplayEnv, env.eAccessRights)
5643+
let env = ShrinkContext env mWholeExprIncludingParentheses expr2.Range
56135644
TcExpr cenv overallTy env tpenv expr2
56145645

56155646
| SynExpr.DotIndexedGet _ | SynExpr.DotIndexedSet _
@@ -10077,11 +10108,11 @@ and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr expr cont =
1007710108
| SynExpr.Sequential (sp, true, e1, e2, m) when not isCompExpr ->
1007810109
let e1', _ = TcStmtThatCantBeCtorBody cenv env tpenv e1
1007910110
// tailcall
10111+
let env = ShrinkContext env m e2.Range
1008010112
TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr e2 (fun (e2', tpenv) ->
1008110113
cont (Expr.Sequential(e1', e2', NormalSeq, sp, m), tpenv))
1008210114

1008310115
| SynExpr.LetOrUse (isRec, isUse, binds, body, m) when not (isUse && isCompExpr) ->
10084-
1008510116
if isRec then
1008610117
// TcLinearExprs processes at most one recursive binding, this is not tailcalling
1008710118
CheckRecursiveBindingIds binds
@@ -10094,6 +10125,7 @@ and TcLinearExprs bodyChecker cenv env overallTy tpenv isCompExpr expr cont =
1009410125
else
1009510126
// TcLinearExprs processes multiple 'let' bindings in a tail recursive way
1009610127
let mkf, envinner, tpenv = TcLetBinding cenv isUse env ExprContainerInfo ExpressionBinding tpenv (binds, m, body.Range)
10128+
let envinner = ShrinkContext envinner m body.Range
1009710129
TcLinearExprs bodyChecker cenv envinner overallTy tpenv isCompExpr body (fun (x, tpenv) ->
1009810130
cont (fst (mkf (x, overallTy)), tpenv))
1009910131
| _ ->
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// #Warnings
2+
//<Expects status="Error" id="FS0001">All branches of an 'if' expression must have the same type. This expression was expected to have type 'string', but here has type 'int'.</Expects>
3+
4+
letf x= x+4
5+
6+
lety=
7+
iftruethen
8+
""
9+
else
10+
""|> ignore
11+
(f5)
12+
13+
exit0
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// #Warnings
2+
//<Expects status="Error" id="FS0001">All branches of an 'if' expression must have the same type. This expression was expected to have type 'string', but here has type 'int'.</Expects>
3+
4+
letf x= x+4
5+
6+
lety=
7+
iftruethen
8+
""
9+
else
10+
""|> ignore
11+
letz= f4
12+
leta=3* z
13+
(f a)
14+
15+
exit0
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// #Warnings
2+
//<Expects status="Error" id="FS0001">The 'if' expression is missing an 'else' branch. The 'then' branch has type 'string'. Because 'if' is an expression, and not a statement, add an 'else' branch which returns a value of the same type.</Expects>
3+
4+
letx=10
5+
lety=
6+
if x>10then("test")
7+
8+
exit0

‎tests/fsharpqa/Source/Warnings/env.lst‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
SOURCE=WrongNumericLiteral.fs # WrongNumericLiteral.fs
22
SOURCE=WarnIfMissingElseBranch.fs # WarnIfMissingElseBranch.fs
33
SOURCE=WarnIfMissingElseBranch2.fs # WarnIfMissingElseBranch2.fs
4+
SOURCE=WarnIfMissingElseBranch3.fs # WarnIfMissingElseBranch3.fs
45
SOURCE=ReturnInsteadOfReturnBang.fs # ReturnInsteadOfReturnBang.fs
56
SOURCE=YieldInsteadOfYieldBang.fs # YieldInsteadOfYieldBang.fs
67
SOURCE=TupleInAbstractMethod.fs # TupleInAbstractMethod.fs
@@ -46,6 +47,8 @@
4647
SOURCE=GuardHasWrongType.fs # GuardHasWrongType.fs
4748
SOURCE=ElseBranchHasWrongType.fs # ElseBranchHasWrongType.fs
4849
SOURCE=ElseBranchHasWrongType2.fs # ElseBranchHasWrongType2.fs
50+
SOURCE=ElseBranchHasWrongType3.fs # ElseBranchHasWrongType3.fs
51+
SOURCE=ElseBranchHasWrongType4.fs # ElseBranchHasWrongType4.fs
4952
SOURCE=NestedElseBranchHasWrongType.fs # NestedElseBranchHasWrongType.fs
5053
SOURCE=ElseBranchHasWrongContextType.fs # ElseBranchHasWrongContextType.fs
5154
SOURCE=ElseBranchContextDoesntPropagateInAppl.fs # ElseBranchContextDoesntPropagateInAppl.fs

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp