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

Allow _ in async use! _ pattern (lift FS1228 restriction) #18189

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 13 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
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 @@ -19,6 +19,7 @@
* Fix a race condition in file book keeping in the compiler service ([#18008](https://github.com/dotnet/fsharp/pull/18008))
* Fix trimming '%' characters when lowering interpolated string to a concat call [PR #18123](https://github.com/dotnet/fsharp/pull/18123)
* Completion: fix qualified completion in sequence expressions [PR #18111](https://github.com/dotnet/fsharp/pull/18111)
* Allow `_` in `use! _` pattern (lift FS1228 restriction) ([PR #18189](https://github.com/dotnet/fsharp/pull/18189))
* Symbols: try to use ValReprInfoForDisplay in Mfv.CurriedParameterGroups ([PR #18124](https://github.com/dotnet/fsharp/pull/18124))
* Shim/file system: fix leaks of the shim [PR #18144](https://github.com/dotnet/fsharp/pull/18144)

Expand Down
1 change: 1 addition & 0 deletions docs/release-notes/.Language/preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
### Fixed

* Warn on uppercase identifiers in patterns. ([PR #15816](https://github.com/dotnet/fsharp/pull/15816))
* Allow `_` in `use! _` pattern (lift FS1228 restriction) ([PR #18189](https://github.com/dotnet/fsharp/pull/18189))

### Changed
225 changes: 131 additions & 94 deletions src/Compiler/Checking/Expressions/CheckComputationExpressions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1843,7 +1843,7 @@ let rec TryTranslateComputationExpression
ceenv.builderTy
)
then
error (Error(FSComp.SR.tcRequireBuilderMethod ("Using"), mBind))
error (Error(FSComp.SR.tcRequireBuilderMethod "Using", mBind))

Some(
translatedCtxt (mkSynCall "Using" mBind [ rhsExpr; consumeExpr ] ceenv.builderValName)
Expand Down Expand Up @@ -1900,105 +1900,55 @@ let rec TryTranslateComputationExpression
bindDebugPoint = spBind
isUse = true
isFromSource = isFromSource
pat = SynPat.Named(ident = SynIdent(id, _); isThisVal = false) as pat
rhs = rhsExpr
andBangs = []
body = innerComp
trivia = { LetOrUseBangKeyword = mBind })
| SynExpr.LetOrUseBang(
bindDebugPoint = spBind
isUse = true
isFromSource = isFromSource
pat = SynPat.LongIdent(longDotId = SynLongIdent(id = [ id ])) as pat
pat = pat
rhs = rhsExpr
andBangs = []
andBangs = andBangs
body = innerComp
trivia = { LetOrUseBangKeyword = mBind }) ->

if ceenv.isQuery then
error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), mBind))

if
isNil (
TryFindIntrinsicOrExtensionMethInfo
ResultCollectionSettings.AtMostOneResult
cenv
ceenv.env
mBind
ceenv.ad
"Using"
ceenv.builderTy
)
then
error (Error(FSComp.SR.tcRequireBuilderMethod ("Using"), mBind))

if
isNil (
TryFindIntrinsicOrExtensionMethInfo
ResultCollectionSettings.AtMostOneResult
match pat with
| SynPat.Named(ident = SynIdent(id, _); isThisVal = false)
| SynPat.LongIdent(longDotId = SynLongIdent(id = [ id ])) when andBangs.IsEmpty ->
TranslateComputationExpressionLetOrUseBang
cenv
ceenv
pat
(Some id)
innerComp
rhsExpr
translatedCtxt
spBind
isFromSource
mBind
| SynPat.Wild _ when cenv.g.langVersion.SupportsFeature(LanguageFeature.UseBangBindingValueDiscard) ->
if not (isNil andBangs) then
let m =
match andBangs with
| [] -> comp.Range
| h :: _ -> h.Trivia.AndBangKeyword

error (Error(FSComp.SR.tcInvalidUseBangBindingNoAndBangs (), m))
else
TranslateComputationExpressionLetOrUseBang
cenv
ceenv.env
mBind
ceenv.ad
"Bind"
ceenv.builderTy
)
then
error (Error(FSComp.SR.tcRequireBuilderMethod ("Bind"), mBind))

let bindExpr =
let consumeExpr =
SynExpr.MatchLambda(
false,
mBind,
[
SynMatchClause(
pat,
None,
TranslateComputationExpressionNoQueryOps ceenv innerComp,
innerComp.Range,
DebugPointAtTarget.Yes,
SynMatchClauseTrivia.Zero
)
],
DebugPointAtBinding.NoneAtInvisible,
mBind
)

let consumeExpr =
mkSynCall "Using" mBind [ SynExpr.Ident id; consumeExpr ] ceenv.builderValName

let consumeExpr =
SynExpr.MatchLambda(
false,
mBind,
[
SynMatchClause(pat, None, consumeExpr, id.idRange, DebugPointAtTarget.No, SynMatchClauseTrivia.Zero)
],
DebugPointAtBinding.NoneAtInvisible,
ceenv
pat
None
innerComp
rhsExpr
translatedCtxt
spBind
isFromSource
mBind
)

let rhsExpr =
mkSourceExprConditional isFromSource rhsExpr ceenv.sourceMethInfo ceenv.builderValName

mkSynCall "Bind" mBind [ rhsExpr; consumeExpr ] ceenv.builderValName
|> addBindDebugPoint spBind

Some(translatedCtxt bindExpr)

// 'use! pat = e1 ... in e2' where 'pat' is not a simple name -> error
| SynExpr.LetOrUseBang(isUse = true; andBangs = andBangs; trivia = { LetOrUseBangKeyword = mBind }) ->
if isNil andBangs then
error (Error(FSComp.SR.tcInvalidUseBangBinding (), mBind))
else
let m =
match andBangs with
| [] -> comp.Range
| h :: _ -> h.Trivia.AndBangKeyword

error (Error(FSComp.SR.tcInvalidUseBangBindingNoAndBangs (), m))
| _ ->
if isNil andBangs then
error (Error(FSComp.SR.tcInvalidUseBangBinding (), mBind))
else
let m =
match andBangs with
| [] -> comp.Range
| h :: _ -> h.Trivia.AndBangKeyword

error (Error(FSComp.SR.tcInvalidUseBangBindingNoAndBangs (), m))
// 'let! pat1 = expr1 and! pat2 = expr2 in ...' -->
// build.BindN(expr1, expr2, ...)
// or
Expand Down Expand Up @@ -2469,6 +2419,93 @@ let rec TryTranslateComputationExpression

| _ -> None

and TranslateComputationExpressionLetOrUseBang
cenv
ceenv
pat
(id: Ident option)
(innerComp: SynExpr)
rhsExpr
translatedCtxt
spBind
isFromSource
mBind
=
if ceenv.isQuery then
error (Error(FSComp.SR.tcBindMayNotBeUsedInQueries (), mBind))

if
isNil (
TryFindIntrinsicOrExtensionMethInfo
ResultCollectionSettings.AtMostOneResult
cenv
ceenv.env
mBind
ceenv.ad
"Using"
ceenv.builderTy
)
then
error (Error(FSComp.SR.tcRequireBuilderMethod "Using", mBind))

if
isNil (
TryFindIntrinsicOrExtensionMethInfo
ResultCollectionSettings.AtMostOneResult
cenv
ceenv.env
mBind
ceenv.ad
"Bind"
ceenv.builderTy
)
then
error (Error(FSComp.SR.tcRequireBuilderMethod "Bind", mBind))

let consumeExpr =
let consumeExpr =
SynExpr.MatchLambda(
false,
mBind,
[
SynMatchClause(
pat,
None,
TranslateComputationExpressionNoQueryOps ceenv innerComp,
innerComp.Range,
DebugPointAtTarget.Yes,
SynMatchClauseTrivia.Zero
)
],
DebugPointAtBinding.NoneAtInvisible,
mBind
)

match id with
| Some id ->
let consumeExpr =
mkSynCall "Using" mBind [ SynExpr.Ident id; consumeExpr ] ceenv.builderValName

SynExpr.MatchLambda(
false,
mBind,
[
SynMatchClause(pat, None, consumeExpr, id.idRange, DebugPointAtTarget.No, SynMatchClauseTrivia.Zero)
],
DebugPointAtBinding.NoneAtInvisible,
mBind
)
| None -> consumeExpr

let bindExpr =
let rhsExpr =
mkSourceExprConditional isFromSource rhsExpr ceenv.sourceMethInfo ceenv.builderValName

mkSynCall "Bind" mBind [ rhsExpr; consumeExpr ] ceenv.builderValName
|> addBindDebugPoint spBind

Some(translatedCtxt bindExpr)

and ConsumeCustomOpClauses
(ceenv: ComputationExpressionContext<'a>)
(comp: SynExpr)
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1791,3 +1791,4 @@ featureDontWarnOnUppercaseIdentifiersInBindingPatterns,"Don't warn on uppercase
3873,chkDeprecatePlacesWhereSeqCanBeOmitted,"This construct is deprecated. Sequence expressions should be of the form 'seq {{ ... }}'"
featureDeprecatePlacesWhereSeqCanBeOmitted,"Deprecate places where 'seq' can be omitted"
featureSupportValueOptionsAsOptionalParameters,"Support ValueOption as valid type for optional member parameters"
featureUseBangBindingValueDiscard,"Use 'use!' binding for value discard"
3 changes: 3 additions & 0 deletions src/Compiler/Facilities/LanguageFeatures.fs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ type LanguageFeature =
| UseTypeSubsumptionCache
| DeprecatePlacesWhereSeqCanBeOmitted
| SupportValueOptionsAsOptionalParameters
| UseBangBindingValueDiscard

/// LanguageVersion management
type LanguageVersion(versionText) =
Expand Down Expand Up @@ -227,6 +228,7 @@ type LanguageVersion(versionText) =
LanguageFeature.DontWarnOnUppercaseIdentifiersInBindingPatterns, previewVersion
LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted, previewVersion
LanguageFeature.SupportValueOptionsAsOptionalParameters, previewVersion
LanguageFeature.UseBangBindingValueDiscard, previewVersion
]

static let defaultLanguageVersion = LanguageVersion("default")
Expand Down Expand Up @@ -388,6 +390,7 @@ type LanguageVersion(versionText) =
| LanguageFeature.UseTypeSubsumptionCache -> FSComp.SR.featureUseTypeSubsumptionCache ()
| LanguageFeature.DeprecatePlacesWhereSeqCanBeOmitted -> FSComp.SR.featureDeprecatePlacesWhereSeqCanBeOmitted ()
| LanguageFeature.SupportValueOptionsAsOptionalParameters -> FSComp.SR.featureSupportValueOptionsAsOptionalParameters ()
| LanguageFeature.UseBangBindingValueDiscard -> FSComp.SR.featureUseBangBindingValueDiscard ()

/// Get a version string associated with the given feature.
static member GetFeatureVersionString feature =
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/Facilities/LanguageFeatures.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ type LanguageFeature =
| UseTypeSubsumptionCache
| DeprecatePlacesWhereSeqCanBeOmitted
| SupportValueOptionsAsOptionalParameters
| UseBangBindingValueDiscard

/// LanguageVersion management
type LanguageVersion =
Expand Down
5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions src/Compiler/xlf/FSComp.txt.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading