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

Commitc295c0a

Browse files
forkiKevinRansom
authored andcommitted
Better error message for pattern matching (#3157)
* Better error message for pattern matching* Better error message for pattern matching guards* fix test* Test pattern match guards* s/return type/have type
1 parentd90e728 commitc295c0a

File tree

12 files changed

+47
-19
lines changed

12 files changed

+47
-19
lines changed

‎src/fsharp/CompileOps.fs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,8 @@ let OutputPhasedErrorR (os:StringBuilder) (err:PhasedDiagnostic) =
646646
os.Append(FSComp.SR.listElementHasWrongType(t1,t2))|> ignore
647647
| ContextInfo.OmittedElseBranch rangewhen range= m-> os.Append(FSComp.SR.missingElseBranch(t2))|> ignore
648648
| ContextInfo.ElseBranchResult rangewhen range= m-> os.Append(FSComp.SR.elseBranchHasWrongType(t1,t2))|> ignore
649+
| ContextInfo.FollowingPatternMatchClause rangewhen range= m-> os.Append(FSComp.SR.followingPatternMatchClauseHasWrongType(t1,t2))|> ignore
650+
| ContextInfo.PatternMatchGuard rangewhen range= m-> os.Append(FSComp.SR.patternMatchGuardIsNotBool(t2))|> ignore
649651
|_-> os.Append(ConstraintSolverTypesNotInEqualityRelation2E().Format t1 t2)|> ignore
650652
if m.StartLine<> m2.StartLinethen
651653
os.Append(SeeAlsoE().Format(stringOfRange m))|> ignore
@@ -677,6 +679,8 @@ let OutputPhasedErrorR (os:StringBuilder) (err:PhasedDiagnostic) =
677679
os.Append(FSComp.SR.listElementHasWrongType(t1,t2))|> ignore
678680
| ContextInfo.OmittedElseBranch rangewhen range= m-> os.Append(FSComp.SR.missingElseBranch(t2))|> ignore
679681
| ContextInfo.ElseBranchResult rangewhen range= m-> os.Append(FSComp.SR.elseBranchHasWrongType(t1,t2))|> ignore
682+
| ContextInfo.FollowingPatternMatchClause rangewhen range= m-> os.Append(FSComp.SR.followingPatternMatchClauseHasWrongType(t1,t2))|> ignore
683+
| ContextInfo.PatternMatchGuard rangewhen range= m-> os.Append(FSComp.SR.patternMatchGuardIsNotBool(t2))|> ignore
680684
| ContextInfo.TupleInRecordFields->
681685
os.Append(ErrorFromAddingTypeEquation1E().Format t2 t1 tpcs)|> ignore
682686
os.Append(System.Environment.NewLine+ FSComp.SR.commaInsteadOfSemicolonInRecord())|> ignore

‎src/fsharp/ConstraintSolver.fs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ type ContextInfo =
137137
| RuntimeTypeTestofbool
138138
/// The type equation comes from an downcast where a upcast could be used.
139139
| DowncastUsedInsteadOfUpcastofbool
140+
/// The type equation comes from a return type of a pattern match clause (not the first clause).
141+
| FollowingPatternMatchClauseofrange
142+
/// The type equation comes from a pattern match guard.
143+
| PatternMatchGuardofrange
140144

141145
exception ConstraintSolverTupleDiffLengthsofDisplayEnv*TTypelist*TTypelist*range*range
142146
exception ConstraintSolverInfiniteTypesofContextInfo*DisplayEnv*TType*TType*range*range

‎src/fsharp/ConstraintSolver.fsi‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ type ContextInfo =
7272
| RuntimeTypeTestofbool
7373
/// The type equation comes from an downcast where a upcast could be used.
7474
| DowncastUsedInsteadOfUpcastofbool
75+
/// The type equation comes from a return type of a pattern match clause (not the first clause).
76+
| FollowingPatternMatchClauseofrange
77+
/// The type equation comes from a pattern match guard.
78+
| PatternMatchGuardofrange
79+
7580

7681
exception ConstraintSolverTupleDiffLengthsofDisplayEnv*TTypelist*TTypelist*range*range
7782
exception ConstraintSolverInfiniteTypesofContextInfo*DisplayEnv*TType*TType*range*range

‎src/fsharp/FSComp.txt‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ listElementHasWrongType,"All elements of a list constructor expression must have
2121
arrayElementHasWrongType,"All elements of an array constructor expression must have the same type. This expression was expected to have type '%s', but here has type '%s'."
2222
missingElseBranch,"The 'if' expression is missing an 'else' branch. The 'then' branch has type '%s'. Because 'if' is an expression, and not a statement, add an 'else' branch which returns a value of the same type."
2323
ifExpression,"The 'if' expression needs to have type '%s' to satisfy context type requirements. It currently has type '%s'."
24-
elseBranchHasWrongType,"All branches of an 'if' expression must return the same type. This expression was expected to have type '%s', but here has type '%s'."
24+
elseBranchHasWrongType,"All branches of an 'if' expression must have the same type. This expression was expected to have type '%s', but here has type '%s'."
25+
followingPatternMatchClauseHasWrongType,"All branches of a pattern match expression must have the same type. This expression was expected to have type '%s', but here has type '%s'."
26+
patternMatchGuardIsNotBool,"A pattern match guard must be of type 'bool', but this 'when' expression is of type '%s'."
2527
commaInsteadOfSemicolonInRecord,"A ';' is used to separate field values in records. Consider replacing ',' with ';'."
2628
derefInsteadOfNot,"The '!' operator is used to dereference a ref cell. Consider using 'not expr' here."
2729
buildUnexpectedTypeArgs,"The non-generic type '%s' does not expect any type arguments, but here is given %d type argument(s)"

‎src/fsharp/TypeChecker.fs‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10082,15 +10082,24 @@ and TcMatchPattern cenv inputTy env tpenv (pat:SynPat,optWhenExpr) =
1008210082
let m = pat.Range
1008310083
let patf',(tpenv,names,_) = TcPat WarnOnUpperCase cenv env None (ValInline.Optional,permitInferTypars,noArgOrRetAttribs,false,None,false) (tpenv,Map.empty,Set.empty) inputTy pat
1008410084
let envinner,values,vspecMap = MakeAndPublishSimpleVals cenv env m names false
10085-
let optWhenExpr',tpenv = Option.mapFold (TcExpr cenv cenv.g.bool_ty envinner) tpenv optWhenExpr
10085+
let optWhenExpr',tpenv =
10086+
match optWhenExpr with
10087+
| Some whenExpr ->
10088+
let guardEnv = { envinner with eContextInfo = ContextInfo.PatternMatchGuard whenExpr.Range }
10089+
let whenExpr',tpenv = TcExpr cenv cenv.g.bool_ty guardEnv tpenv whenExpr
10090+
Some whenExpr',tpenv
10091+
| None -> None,tpenv
1008610092
patf' (TcPatPhase2Input (values, true)),optWhenExpr', NameMap.range vspecMap,envinner,tpenv
1008710093

1008810094
and TcMatchClauses cenv inputTy resultTy env tpenv clauses =
10089-
List.mapFold (TcMatchClause cenv inputTy resultTy env) tpenv clauses
10095+
let first = ref true
10096+
let isFirst() = if !first then first := false; true else false
10097+
List.mapFold (fun clause -> TcMatchClause cenv inputTy resultTy env (isFirst()) clause) tpenv clauses
1009010098

10091-
and TcMatchClause cenv inputTy resultTy env tpenv (Clause(pat,optWhenExpr,e,patm,spTgt)) =
10099+
and TcMatchClause cenv inputTy resultTy envisFirsttpenv (Clause(pat,optWhenExpr,e,patm,spTgt)) =
1009210100
let pat',optWhenExpr',vspecs,envinner,tpenv = TcMatchPattern cenv inputTy env tpenv (pat,optWhenExpr)
10093-
let e',tpenv = TcExprThatCanBeCtorBody cenv resultTy envinner tpenv e
10101+
let resultEnv = if isFirst then envinner else { envinner with eContextInfo = ContextInfo.FollowingPatternMatchClause e.Range }
10102+
let e',tpenv = TcExprThatCanBeCtorBody cenv resultTy resultEnv tpenv e
1009410103
TClause(pat',optWhenExpr',TTarget(vspecs, e',spTgt),patm),tpenv
1009510104

1009610105
and TcStaticOptimizationConstraint cenv env tpenv c =

‎tests/fsharp/typecheck/sigs/neg20.bsl‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,9 @@ but given a
110110
'B list'
111111
The type 'A' doesnot match the type 'B'
112112

113-
neg20.fs(83,47,83,54): typecheck error FS0001: All branches of an 'if' expression mustreturn the same type. This expression was expectedto have type 'B', but here has type 'C'.
113+
neg20.fs(83,47,83,54): typecheck error FS0001: All branches of an 'if' expression musthave the same type. This expression was expectedto have type 'B', but here has type 'C'.
114114

115-
neg20.fs(87,54,87,61): typecheck error FS0001: This expression was expectedto have type
116-
'B'
117-
but here has type
118-
'C'
115+
neg20.fs(87,54,87,61): typecheck error FS0001: All branches of a pattern match expression must have the same type. This expression was expectedto have type 'B', but here has type 'C'.
119116

120117
neg20.fs(92,19,92,26): typecheck error FS0001: This expression was expectedto have type
121118
'A'

‎tests/fsharp/typecheck/sigs/neg80.vsbsl‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ neg80.fsx(79,5,79,6): parse error FS0010: Unexpected symbol '|' in pattern match
33

44
neg80.fsx(79,5,79,6): parse error FS0010: Unexpected symbol '|' in pattern matching
55

6-
neg80.fsx(79,6,79,6): typecheck error FS0001: This expression was expected to have type
7-
'string'
8-
but here has type
9-
'unit'
6+
neg80.fsx(79,6,79,6): typecheck error FS0001: All branches of a pattern match expression must have the same type. This expression was expected to have type 'string', but here has type 'unit'.
107

118
neg80.fsx(76,11,76,13): typecheck error FS0025: Incomplete pattern matches on this expression. For example, the value 'Horizontal (_, _)' may indicate a case not covered by the pattern(s).
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// #Warnings
2-
//<Expects status="Error" span="(7,10)">All branches of an 'if' expression mustreturn the same type. This expression was expected to have type 'string', but here has type 'int'.</Expects>
2+
//<Expects status="Error" span="(7,10)">All branches of an 'if' expression musthave the same type. This expression was expected to have type 'string', but here has type 'int'.</Expects>
33

44
lettest=100
55
lety=
66
if test>10then"test"
77
else123
88

9-
exit0
9+
exit0
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// #Warnings
2-
//<Expects status="Error">All branches of an 'if' expression mustreturn the same type. This expression was expected to have type 'string', but here has type 'int'.</Expects>
2+
//<Expects status="Error">All branches of an 'if' expression musthave the same type. This expression was expected to have type 'string', but here has type 'int'.</Expects>
33

44
lettest=100
55
letf x= test
66
lety=
77
if test>10then"test"
88
else f10
99

10-
exit0
10+
exit0
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// #Warnings
2+
//<Expects status="Error" id="FS0001">A pattern match guard must be of type 'bool'</Expects>
3+
4+
letx=1
5+
match xwith
6+
|1when"s"->true
7+
|_->false
8+
9+
exit0

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp