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

Warn on uppercase identifiers in patterns. #15816

Merged
merged 69 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
60127ac
Better error for match with a patterns referring to an out of scope i…
edgarfgp Aug 16, 2023
b852634
Lets find out
edgarfgp Aug 16, 2023
f599bca
Ok now I wish I did not know about this
edgarfgp Aug 16, 2023
27f2a3c
update test
edgarfgp Aug 16, 2023
c8294ec
last one ?
edgarfgp Aug 16, 2023
5d37156
Update error message to clarify the details of the historical hack.
edgarfgp Aug 18, 2023
bef94a2
Update more tests
edgarfgp Aug 18, 2023
58834dc
update tests
edgarfgp Aug 18, 2023
48fb2ff
more tests
edgarfgp Aug 19, 2023
b927f77
Merge branch 'main' into another-pat-matching-fix
edgarfgp Aug 21, 2023
050c8c5
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 17, 2024
fea45d5
comment id.idText.Length >= 3 to see what breaks
edgarfgp Oct 17, 2024
47c287e
revert back the error message
edgarfgp Oct 17, 2024
885b5ab
update tests
edgarfgp Oct 17, 2024
bd76c9d
release notes
edgarfgp Oct 17, 2024
d68843e
Add LanguageFeature flag
edgarfgp Oct 17, 2024
110d417
release notes
edgarfgp Oct 17, 2024
869acd5
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 17, 2024
6d4af0a
Merge branch 'another-pat-matching-fix' of github.com:edgarfgp/fsharp…
edgarfgp Oct 17, 2024
7bf5163
format code
edgarfgp Oct 17, 2024
7934bf3
reduce diff
edgarfgp Oct 17, 2024
1554db9
LanguageFeature.WarnOnUppercaseIdentifiersInPatterns
edgarfgp Oct 17, 2024
5a3cf90
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 21, 2024
a3f4ae1
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 23, 2024
8f4643a
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 23, 2024
88f13a9
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 24, 2024
b01b957
simplify tests
edgarfgp Oct 25, 2024
0183998
more tests
edgarfgp Oct 25, 2024
3d4cbb3
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 25, 2024
5236633
3874,chkVariablePatternUppercase,"Variable patterns should be lowerca…
edgarfgp Oct 25, 2024
23b3a53
Merge branch 'another-pat-matching-fix' of github.com:edgarfgp/fsharp…
edgarfgp Oct 25, 2024
68039fa
hasConstructorShape
edgarfgp Oct 25, 2024
3be7320
Improve error message for match cases labels and update tests
edgarfgp Oct 27, 2024
2f5d878
update fsharpqa tests
edgarfgp Oct 27, 2024
bf5ca00
more tests
edgarfgp Oct 27, 2024
2865c6a
release notes entry
edgarfgp Oct 27, 2024
0c50d4c
reduce diff
edgarfgp Oct 27, 2024
8f69e67
update tests
edgarfgp Oct 27, 2024
d8b2f50
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 27, 2024
2f360bf
update tests
edgarfgp Oct 27, 2024
1d3402a
Merge branch 'another-pat-matching-fix' of github.com:edgarfgp/fsharp…
edgarfgp Oct 27, 2024
724dc0b
more tests
edgarfgp Oct 27, 2024
d4720cb
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 29, 2024
573a1a0
Do't want for WarnOnUpperVariablePatterns in preview
edgarfgp Oct 29, 2024
cd0521c
revert changes from MutableTuple
edgarfgp Oct 29, 2024
dd8a79c
revert changes from Query.fs
edgarfgp Oct 29, 2024
792249a
Revert remaining changes
edgarfgp Oct 29, 2024
34b42f9
format code
edgarfgp Oct 29, 2024
b8682b6
use TcTrueMatchClause instead of bool
edgarfgp Oct 29, 2024
cb71b1c
revert test changes
edgarfgp Oct 29, 2024
a294904
reverte changes on Query.fs
edgarfgp Oct 29, 2024
1cb2c74
revert changes
edgarfgp Oct 29, 2024
5597e60
allow all identifier pattern regardless its length in preview
edgarfgp Oct 30, 2024
21bd69c
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 30, 2024
2330290
Preview: Don't warn on as named pattern
edgarfgp Oct 30, 2024
7a44ead
Merge branch 'another-pat-matching-fix' of github.com:edgarfgp/fsharp…
edgarfgp Oct 30, 2024
490b665
revert error message changes
edgarfgp Oct 31, 2024
e126d0a
Revert "update tests"
edgarfgp Oct 31, 2024
1ec5c87
Revert "update fsharpqa tests"
edgarfgp Oct 31, 2024
f34f9a3
Rename LanguageFeature
edgarfgp Oct 31, 2024
8244124
format code
edgarfgp Oct 31, 2024
63c4c5d
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 31, 2024
fbcf91f
Merge branch 'main' into another-pat-matching-fix
edgarfgp Oct 31, 2024
698e3f2
Update src/Compiler/Checking/CheckPatterns.fs
edgarfgp Nov 2, 2024
3adf463
PR review
edgarfgp Nov 3, 2024
1379605
Add xml comments
edgarfgp Nov 4, 2024
7a7ac5d
Merge branch 'main' into another-pat-matching-fix
edgarfgp Nov 4, 2024
3484b51
Merge branch 'main' into another-pat-matching-fix
edgarfgp Nov 5, 2024
a4c35b9
Merge branch 'main' into another-pat-matching-fix
edgarfgp Nov 5, 2024
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
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/9.0.200.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* Better ranges for CE `use` error reporting. ([PR #17811](https://github.com/dotnet/fsharp/pull/17811))
* Better ranges for `inherit` error reporting. ([PR #17879](https://github.com/dotnet/fsharp/pull/17879))
* Better ranges for `inherit` `struct` error reporting. ([PR #17886](https://github.com/dotnet/fsharp/pull/17886))
* Warn on uppercase identifiers in patterns. ([PR #15816](https://github.com/dotnet/fsharp/pull/15816))
* Better ranges for `inherit` objects error reporting. ([PR #17893](https://github.com/dotnet/fsharp/pull/17893))
* Better ranges for #nowarn error reporting; bring back #nowarn warnings for --langVersion:80; add warnings under feature flag ([PR #17871](https://github.com/dotnet/fsharp/pull/17871))

Expand Down
2 changes: 1 addition & 1 deletion docs/release-notes/.FSharp.Core/9.0.200.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@

### Changed

### Breaking Changes
### Breaking Changes
1 change: 1 addition & 0 deletions docs/release-notes/.Language/preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
* Added type conversions cache, only enabled for compiler runs ([PR#17668](https://github.com/dotnet/fsharp/pull/17668))

### Fixed
* Warn on uppercase identifiers in patterns. ([PR #15816](https://github.com/dotnet/fsharp/pull/15816))

### Changed
22 changes: 18 additions & 4 deletions src/Compiler/Checking/CheckPatterns.fs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ let UnifyRefTupleType contextInfo (cenv: cenv) denv m ty ps =
AddCxTypeEqualsType contextInfo denv cenv.css m ty (TType_tuple (tupInfoRef, ptys))
ptys

let rec TryAdjustHiddenVarNameToCompGenName cenv env (id: Ident) altNameRefCellOpt =
let rec TryAdjustHiddenVarNameToCompGenName (cenv: cenv) env (id: Ident) altNameRefCellOpt =
match altNameRefCellOpt with
| Some ({contents = SynSimplePatAlternativeIdInfo.Undecided altId } as altNameRefCell) ->
match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver AllIdsOK false id.idRange env.eAccessRights env.eNameResEnv TypeNameResolutionInfo.Default [id] ExtraDotAfterIdentifier.No with
let supportsWarnOnUpperIdentifiersInPatterns = cenv.g.langVersion.SupportsFeature(LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns)
let warnOnUpperFlag = if supportsWarnOnUpperIdentifiersInPatterns then WarnOnUpperVariablePatterns else AllIdsOK
match ResolvePatternLongIdent cenv.tcSink cenv.nameResolver warnOnUpperFlag false id.idRange env.eAccessRights env.eNameResEnv TypeNameResolutionInfo.Default [id] ExtraDotAfterIdentifier.No with
| Item.NewDef _ ->
// The name is not in scope as a pattern identifier (e.g. union case), so do not use the alternate ID
None
Expand Down Expand Up @@ -356,6 +358,12 @@ and TcPatNamedAs warnOnUpper cenv env valReprInfo vFlags patEnv ty synInnerPat i

and TcPatUnnamedAs warnOnUpper cenv env vFlags patEnv ty pat1 pat2 m =
let pats = [pat1; pat2]
let warnOnUpper =
if cenv.g.langVersion.SupportsFeature(LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns) then
AllIdsOK
else
warnOnUpper

let patsR, patEnvR = TcPatterns warnOnUpper cenv env vFlags patEnv (List.map (fun _ -> ty) pats) pats
let phase2 values = TPat_conjs(List.map (fun f -> f values) patsR, m)
phase2, patEnvR
Expand Down Expand Up @@ -441,7 +449,7 @@ and TcPatArrayOrList warnOnUpper cenv env vFlags patEnv ty isArray args m =
else List.foldBack (mkConsListPat g argTy) argsR (mkNilListPat g m argTy)
phase2, acc

and TcRecordPat warnOnUpper cenv env vFlags patEnv ty fieldPats m =
and TcRecordPat warnOnUpper (cenv: cenv) env vFlags patEnv ty fieldPats m =
let fieldPats = fieldPats |> List.map (fun (fieldId, _, fieldPat) -> fieldId, fieldPat)
match BuildFieldMap cenv env false ty fieldPats m with
| None -> (fun _ -> TPat_error m), patEnv
Expand All @@ -458,7 +466,13 @@ and TcRecordPat warnOnUpper cenv env vFlags patEnv ty fieldPats m =
let fieldPats, patEnvR =
(patEnv, ftys) ||> List.mapFold (fun s (ty, fsp) ->
match fldsmap.TryGetValue fsp.rfield_id.idText with
| true, v -> TcPat warnOnUpper cenv env None vFlags s ty v
| true, v ->
let warnOnUpper =
if cenv.g.langVersion.SupportsFeature(LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns) then
AllIdsOK
else
warnOnUpper
TcPat warnOnUpper cenv env None vFlags s ty v
| _ -> (fun _ -> TPat_wild m), s)

let phase2 values =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -982,7 +982,7 @@ let rec TryTranslateComputationExpression
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink

let _, _, vspecs, envinner, _ =
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv firstSourcePat None
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv firstSourcePat None TcTrueMatchClause.No

vspecs, envinner)

Expand All @@ -991,7 +991,7 @@ let rec TryTranslateComputationExpression
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink

let _, _, vspecs, envinner, _ =
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv secondSourcePat None
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv secondSourcePat None TcTrueMatchClause.No

vspecs, envinner)

Expand All @@ -1002,7 +1002,7 @@ let rec TryTranslateComputationExpression
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink

let _, _, vspecs, envinner, _ =
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat3 None
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat3 None TcTrueMatchClause.No

vspecs, envinner)
| None -> varSpace
Expand Down Expand Up @@ -1231,7 +1231,7 @@ let rec TryTranslateComputationExpression
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink

let _, _, vspecs, envinner, _ =
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat None
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat None TcTrueMatchClause.No

vspecs, envinner)

Expand Down Expand Up @@ -1789,7 +1789,7 @@ let rec TryTranslateComputationExpression
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink

let _, _, vspecs, envinner, _ =
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat None
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat None TcTrueMatchClause.No

vspecs, envinner
| _ ->
Expand Down Expand Up @@ -1873,7 +1873,7 @@ let rec TryTranslateComputationExpression
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink

let _, _, vspecs, envinner, _ =
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat None
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv pat None TcTrueMatchClause.No

vspecs, envinner)

Expand Down Expand Up @@ -2066,7 +2066,7 @@ let rec TryTranslateComputationExpression
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink

let _, _, vspecs, envinner, _ =
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv consumePat None
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv consumePat None TcTrueMatchClause.No

vspecs, envinner)

Expand Down Expand Up @@ -2111,7 +2111,7 @@ let rec TryTranslateComputationExpression
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink

let _, _, vspecs, envinner, _ =
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv consumePat None
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv consumePat None TcTrueMatchClause.No

vspecs, envinner)

Expand Down Expand Up @@ -2239,7 +2239,7 @@ let rec TryTranslateComputationExpression
use _holder = TemporarilySuspendReportingTypecheckResultsToSink cenv.tcSink

let _, _, vspecs, envinner, _ =
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv consumePat None
TcMatchPattern cenv (NewInferenceType cenv.g) env ceenv.tpenv consumePat None TcTrueMatchClause.No

vspecs, envinner)

Expand Down
39 changes: 29 additions & 10 deletions src/Compiler/Checking/Expressions/CheckExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1017,6 +1017,12 @@ type TcCanFail =
| IgnoreMemberResoutionError
| IgnoreAllErrors
| ReportAllErrors

[<RequireQualifiedAccess>]
[<Struct>]
type TcTrueMatchClause =
| Yes
| No

let TcAddNullnessToType (warn: bool) (cenv: cenv) (env: TcEnv) nullness innerTyC m =
let g = cenv.g
Expand Down Expand Up @@ -2516,8 +2522,12 @@ module BindingNormalization =
match memberFlagsOpt with
| None ->
let extraDot = if synLongId.ThereIsAnExtraDotAtTheEnd then ExtraDotAfterIdentifier.Yes else ExtraDotAfterIdentifier.No

match ResolvePatternLongIdent cenv.tcSink nameResolver AllIdsOK true m ad env.NameEnv TypeNameResolutionInfo.Default longId extraDot with
let warnOnUpper =
if not args.IsEmpty then
WarnOnUpperUnionCaseLabel
else AllIdsOK

match ResolvePatternLongIdent cenv.tcSink nameResolver warnOnUpper true m ad env.NameEnv TypeNameResolutionInfo.Default longId extraDot with
| Item.NewDef id ->
if id.idText = opNameCons then
NormalizedBindingPat(pat, rhsExpr, valSynData, typars)
Expand Down Expand Up @@ -6423,10 +6433,8 @@ and TcExprILAssembly (cenv: cenv) overallTy env tpenv (ilInstrs, synTyArgs, synA
and TcIteratedLambdas (cenv: cenv) isFirst (env: TcEnv) overallTy takenNames tpenv e =
let g = cenv.g
match e with
| SynExpr.Lambda (isMember, isSubsequent, synSimplePats, bodyExpr, _, m, _) when isMember || isFirst || isSubsequent ->

| SynExpr.Lambda (isMember, isSubsequent, synSimplePats, bodyExpr, _parsedData, m, _trivia) when isMember || isFirst || isSubsequent ->
let domainTy, resultTy = UnifyFunctionType None cenv env.DisplayEnv m overallTy.Commit

let vs, (TcPatLinearEnv (tpenv, names, takenNames)) =
cenv.TcSimplePats cenv isMember CheckCxs domainTy env (TcPatLinearEnv (tpenv, Map.empty, takenNames)) synSimplePats

Expand Down Expand Up @@ -8072,7 +8080,7 @@ and TcForEachExpr cenv overallTy env tpenv (seqExprOnly, isFromSource, synPat, s

let pat, _, vspecs, envinner, tpenv =
let env = { env with eIsControlFlow = false }
TcMatchPattern cenv enumElemTy env tpenv synPat None
TcMatchPattern cenv enumElemTy env tpenv synPat None TcTrueMatchClause.No

let elemVar, pat =
// nice: don't introduce awful temporary for r.h.s. in the 99% case where we know what we're binding it to
Expand Down Expand Up @@ -10602,10 +10610,15 @@ and TcAndPatternCompileMatchClauses mExpr mMatch actionOnFailure cenv inputExprO
let matchVal, expr = CompilePatternForMatchClauses cenv env mExpr mMatch true actionOnFailure inputExprOpt inputTy resultTy.Commit clauses
matchVal, expr, tpenv

and TcMatchPattern cenv inputTy env tpenv (synPat: SynPat) (synWhenExprOpt: SynExpr option) =
and TcMatchPattern (cenv: cenv) inputTy env tpenv (synPat: SynPat) (synWhenExprOpt: SynExpr option) (tcTrueMatchClause: TcTrueMatchClause) =
let g = cenv.g
let m = synPat.Range
let patf', (TcPatLinearEnv (tpenv, names, _)) = cenv.TcPat WarnOnUpperCase cenv env None (TcPatValFlags (ValInline.Optional, permitInferTypars, noArgOrRetAttribs, false, None, false)) (TcPatLinearEnv (tpenv, Map.empty, Set.empty)) inputTy synPat
let warnOnUpperFlag =
match tcTrueMatchClause with
| TcTrueMatchClause.Yes -> WarnOnUpperUnionCaseLabel
| TcTrueMatchClause.No -> WarnOnUpperVariablePatterns

let patf', (TcPatLinearEnv (tpenv, names, _)) = cenv.TcPat warnOnUpperFlag cenv env None (TcPatValFlags (ValInline.Optional, permitInferTypars, noArgOrRetAttribs, false, None, false)) (TcPatLinearEnv (tpenv, Map.empty, Set.empty)) inputTy synPat
let envinner, values, vspecMap = MakeAndPublishSimpleValsForMergedScope cenv env m names

let whenExprOpt, tpenv =
Expand All @@ -10626,9 +10639,15 @@ and TcMatchClauses cenv inputTy (resultTy: OverallTy) env tpenv clauses =
resultList,tpEnv

and TcMatchClause cenv inputTy (resultTy: OverallTy) env isFirst tpenv synMatchClause =
let (SynMatchClause(synPat, synWhenExprOpt, synResultExpr, patm, spTgt, _)) = synMatchClause
let (SynMatchClause(synPat, synWhenExprOpt, synResultExpr, patm, spTgt, trivia)) = synMatchClause

let pat, whenExprOpt, vspecs, envinner, tpenv = TcMatchPattern cenv inputTy env tpenv synPat synWhenExprOpt
let isTrueMatchClause =
if synMatchClause.IsTrueMatchClause then
TcTrueMatchClause.Yes
else
TcTrueMatchClause.No

let pat, whenExprOpt, vspecs, envinner, tpenv = TcMatchPattern cenv inputTy env tpenv synPat synWhenExprOpt isTrueMatchClause

let resultEnv =
if isFirst then envinner
Expand Down
8 changes: 8 additions & 0 deletions src/Compiler/Checking/Expressions/CheckExpressions.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,13 @@ type TcCanFail =
| IgnoreAllErrors
| ReportAllErrors

/// Represents a pattern that is used in a true match clause e.g. | pat -> expr
[<RequireQualifiedAccess>]
[<Struct>]
type TcTrueMatchClause =
| Yes
| No

/// Represents a recursive binding after it has been both checked and generalized, but
/// before initialization recursion has been rewritten
type PreInitializationGraphEliminationBinding =
Expand Down Expand Up @@ -703,6 +710,7 @@ val TcMatchPattern:
tpenv: UnscopedTyparEnv ->
synPat: SynPat ->
synWhenExprOpt: SynExpr option ->
tcTrueMatchClause: TcTrueMatchClause ->
Pattern * Expr option * Val list * TcEnv * UnscopedTyparEnv

[<return: Struct>]
Expand Down
24 changes: 18 additions & 6 deletions src/Compiler/Checking/Expressions/CheckSequenceExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
ConvertArbitraryExprToEnumerable cenv arbitraryTy env pseudoEnumExpr

let patR, _, vspecs, envinner, tpenv =
TcMatchPattern cenv enumElemTy env tpenv pat None
TcMatchPattern cenv enumElemTy env tpenv pat None TcTrueMatchClause.No

let innerExpr, tpenv =
let envinner = { envinner with eIsControlFlow = true }
Expand Down Expand Up @@ -241,7 +241,7 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
let inputExprTy = NewInferenceType g

let pat', _, vspecs, envinner, tpenv =
TcMatchPattern cenv bindPatTy env tpenv pat None
TcMatchPattern cenv bindPatTy env tpenv pat None TcTrueMatchClause.No

UnifyTypes cenv env m inputExprTy bindPatTy

Expand Down Expand Up @@ -270,9 +270,15 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT

let tclauses, tpenv =
(tpenv, clauses)
||> List.mapFold (fun tpenv (SynMatchClause(pat, cond, innerComp, _, sp, _)) ->
||> List.mapFold (fun tpenv (SynMatchClause(pat, cond, innerComp, _, sp, trivia) as clause) ->
let isTrueMatchClause =
if clause.IsTrueMatchClause then
TcTrueMatchClause.Yes
else
TcTrueMatchClause.No

let patR, condR, vspecs, envinner, tpenv =
TcMatchPattern cenv inputTy env tpenv pat cond
TcMatchPattern cenv inputTy env tpenv pat cond isTrueMatchClause

let envinner =
match sp with
Expand Down Expand Up @@ -313,9 +319,15 @@ let TcSequenceExpression (cenv: TcFileState) env tpenv comp (overallTy: OverallT
// Compile the pattern twice, once as a filter with all succeeding targets returning "1", and once as a proper catch block.
let clauses, tpenv =
(tpenv, withList)
||> List.mapFold (fun tpenv (SynMatchClause(pat, cond, innerComp, m, sp, _)) ->
||> List.mapFold (fun tpenv (SynMatchClause(pat, cond, innerComp, m, sp, trivia) as clause) ->
let isTrueMatchClause =
if clause.IsTrueMatchClause then
TcTrueMatchClause.Yes
else
TcTrueMatchClause.No

let patR, condR, vspecs, envinner, tpenv =
TcMatchPattern cenv g.exn_ty env tpenv pat cond
TcMatchPattern cenv g.exn_ty env tpenv pat cond isTrueMatchClause

let envinner =
match sp with
Expand Down
25 changes: 18 additions & 7 deletions src/Compiler/Checking/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3369,7 +3369,10 @@ let rec ResolvePatternLongIdentInModuleOrNamespace (ncenv: NameResolver) nenv nu
exception UpperCaseIdentifierInPattern of range

/// Indicates if a warning should be given for the use of upper-case identifiers in patterns
type WarnOnUpperFlag = WarnOnUpperCase | AllIdsOK
type WarnOnUpperFlag =
| WarnOnUpperUnionCaseLabel
| WarnOnUpperVariablePatterns
| AllIdsOK

// Long ID in a pattern
let rec ResolvePatternLongIdentPrim sink (ncenv: NameResolver) fullyQualified warnOnUpper newDef m ad nenv numTyArgsOpt (id: Ident) (rest: Ident list) extraDotAtTheEnd =
Expand All @@ -3389,13 +3392,21 @@ let rec ResolvePatternLongIdentPrim sink (ncenv: NameResolver) fullyQualified wa
| true, res when not newDef -> ResolveUnqualifiedItem ncenv nenv m res
| _ ->
// Single identifiers in patterns - variable bindings
if
not newDef
&& warnOnUpper = WarnOnUpperCase
&& id.idText.Length >= 3
&& System.Char.ToLowerInvariant id.idText[0] <> id.idText[0]
let supportsDontWarnOnUppercaseIdentifiers = ncenv.g.langVersion.SupportsFeature(LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns)
let isUpperCaseIdentifier = (not newDef && System.Char.ToLowerInvariant id.idText[0] <> id.idText[0])
if (supportsDontWarnOnUppercaseIdentifiers && isUpperCaseIdentifier)
then
warning(UpperCaseIdentifierInPattern m)
match warnOnUpper with
| WarnOnUpperUnionCaseLabel -> warning(UpperCaseIdentifierInPattern m)
| WarnOnUpperVariablePatterns
| AllIdsOK -> ()
else
// HACK: This is an historical hack that seems to related the use country and language codes, which are very common in codebases
if isUpperCaseIdentifier && id.idText.Length >= 3 then
match warnOnUpper with
| WarnOnUpperUnionCaseLabel
| WarnOnUpperVariablePatterns -> warning(UpperCaseIdentifierInPattern m)
| AllIdsOK -> ()

// If there's an extra dot, we check whether the single identifier is a union, module or namespace and report it to the sink for the sake of tooling
match extraDotAtTheEnd with
Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/Checking/NameResolution.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,8 @@ type LookupKind =

/// Indicates if a warning should be given for the use of upper-case identifiers in patterns
type WarnOnUpperFlag =
| WarnOnUpperCase
| WarnOnUpperUnionCaseLabel
| WarnOnUpperVariablePatterns
| AllIdsOK

/// Indicates whether we permit a direct reference to a type generator. Only set when resolving the
Expand Down
Loading
Loading