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 use bindings #11630

Merged
merged 2 commits into from Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/fsharp/CheckExpressions.fs
Expand Up @@ -9770,7 +9770,14 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (synBinds, synBinds

let tmp, _ = mkCompGenLocal m "patternInput" (generalizedTypars +-> tauTy)

if isUse || isFixed then
if isUse then
let isDiscarded = match checkedPat with TPat_wild _ -> true | _ -> false
lostmsu marked this conversation as resolved.
Show resolved Hide resolved
if not isDiscarded then
errorR(Error(FSComp.SR.tcInvalidUseBinding(), m))
else
ErrorLogger.checkLanguageFeatureError cenv.g.langVersion Features.LanguageFeature.UseBindingValueDiscard checkedPat.Range

elif isFixed then
errorR(Error(FSComp.SR.tcInvalidUseBinding(), m))

// If the overall declaration is declaring statics or a module value, then force the patternInputTmp to also
Expand Down Expand Up @@ -9798,6 +9805,8 @@ and TcLetBinding cenv isUse env containerInfo declKind tpenv (synBinds, synBinds
// Add the dispose of any "use x = ..." to bodyExpr
let mkCleanup (bodyExpr, bodyExprTy) =
if isUse && not isFixed then
let isDiscarded = match checkedPat2 with TPat_wild _ -> true | _ -> false
let allValsDefinedByPattern = if isDiscarded then [patternInputTmp] else allValsDefinedByPattern
(allValsDefinedByPattern, (bodyExpr, bodyExprTy)) ||> List.foldBack (fun v (bodyExpr, bodyExprTy) ->
AddCxTypeMustSubsumeType ContextInfo.NoContext denv cenv.css v.Range NoTrace cenv.g.system_IDisposable_ty v.Type
let cleanupE = BuildDisposableCleanup cenv env m v
Expand Down
1 change: 1 addition & 0 deletions src/fsharp/FSComp.txt
Expand Up @@ -1231,6 +1231,7 @@ invalidFullNameForProvidedType,"invalid full name for provided type"
featureOverloadsForCustomOperations,"overloads for custom operations"
featureExpandedMeasurables,"more types support units of measure"
featurePrintfBinaryFormat,"binary formatting for integers"
featureDiscardUseValue,"discard pattern in use binding"
3090,tcIfThenElseMayNotBeUsedWithinQueries,"An if/then/else expression may not be used within queries. Consider using either an if/then expression, or use a sequence expression instead."
3091,ilxgenUnexpectedArgumentToMethodHandleOfDuringCodegen,"Invalid argument to 'methodhandleof' during codegen"
3092,etProvidedTypeReferenceMissingArgument,"A reference to a provided type was missing a value for the static parameter '%s'. You may need to recompile one or more referenced assemblies."
Expand Down
3 changes: 3 additions & 0 deletions src/fsharp/LanguageFeatures.fs
Expand Up @@ -37,6 +37,7 @@ type LanguageFeature =
| OverloadsForCustomOperations
| ExpandedMeasurables
| PrintfBinaryFormat
| UseBindingValueDiscard

/// LanguageVersion management
type LanguageVersion (specifiedVersionAsString) =
Expand Down Expand Up @@ -79,6 +80,7 @@ type LanguageVersion (specifiedVersionAsString) =
LanguageFeature.ExpandedMeasurables, previewVersion
LanguageFeature.FromEndSlicing, previewVersion
LanguageFeature.PrintfBinaryFormat, previewVersion
LanguageFeature.UseBindingValueDiscard, previewVersion
]

let specified =
Expand Down Expand Up @@ -153,6 +155,7 @@ type LanguageVersion (specifiedVersionAsString) =
| LanguageFeature.OverloadsForCustomOperations -> FSComp.SR.featureOverloadsForCustomOperations()
| LanguageFeature.ExpandedMeasurables -> FSComp.SR.featureExpandedMeasurables()
| LanguageFeature.PrintfBinaryFormat -> FSComp.SR.featurePrintfBinaryFormat()
| LanguageFeature.UseBindingValueDiscard -> FSComp.SR.featureDiscardUseValue()

/// Get a version string associated with the given feature.
member _.GetFeatureVersionString feature =
Expand Down
1 change: 1 addition & 0 deletions src/fsharp/LanguageFeatures.fsi
Expand Up @@ -25,6 +25,7 @@ type LanguageFeature =
| OverloadsForCustomOperations
| ExpandedMeasurables
| PrintfBinaryFormat
| UseBindingValueDiscard

/// LanguageVersion management
type LanguageVersion =
Expand Down
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.cs.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">využití člena výchozího rozhraní</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">literál float32 bez tečky</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.de.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">standardmäßige Schnittstellenmembernutzung</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">punktloses float32-Literal</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.es.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">consumo de miembros de interfaz predeterminados</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">literal float32 sin punto</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.fr.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">consommation par défaut des membres d'interface</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">littéral float32 sans point</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.it.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">utilizzo predefinito dei membri di interfaccia</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">valore letterale float32 senza punti</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.ja.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">既定のインターフェイス メンバーの消費</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">ドットなしの float32 リテラル</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.ko.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">기본 인터페이스 멤버 사용</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">점이 없는 float32 리터럴</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.pl.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">domyślne użycie składowej interfejsu</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">bezkropkowy literał float32</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.pt-BR.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">consumo de membro da interface padrão</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">literal float32 sem ponto</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.ru.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">использование элемента интерфейса по умолчанию</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">литерал float32 без точки</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.tr.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">varsayılan arabirim üyesi tüketimi</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">noktasız float32 sabit değeri</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.zh-Hans.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">默认接口成员消耗</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">无点 float32 文本</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
7 changes: 6 additions & 1 deletion src/fsharp/xlf/FSComp.txt.zh-Hant.xlf
Expand Up @@ -97,6 +97,11 @@
<target state="translated">預設介面成員使用</target>
<note />
</trans-unit>
<trans-unit id="featureDiscardUseValue">
<source>discard pattern in use binding</source>
<target state="new">discard pattern in use binding</target>
<note />
</trans-unit>
<trans-unit id="featureDotlessFloat32Literal">
<source>dotless float32 literal</source>
<target state="translated">無點號的 float32 常值</target>
Expand Down Expand Up @@ -7659,4 +7664,4 @@
</trans-unit>
</body>
</file>
</xliff>
</xliff>
@@ -0,0 +1,62 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace FSharp.Compiler.ComponentTests.Conformance.DeclarationElements.LetBindings

open Xunit
open FSharp.Test.Utilities.Compiler
open FSharp.Test.Utilities.Xunit.Attributes

module UseBindings =

[<Theory; Directory(__SOURCE_DIRECTORY__ + "/../../../resources/tests/Conformance/DeclarationElements/LetBindings", Includes=[|"UseBindingDiscard01.fs"|])>]
let ``UseBindings - UseBindingDiscard01.fs - Compiles`` compilation =
compilation
|> asFsx
|> withOptions ["--langversion:preview"]
|> compile
|> shouldSucceed
|> ignore

[<Theory; Directory(__SOURCE_DIRECTORY__ + "/../../../resources/tests/Conformance/DeclarationElements/LetBindings", Includes=[|"UseBindingDiscard01.fs"|])>]
let ``UseBindings - UseBindingDiscard01.fs - Bad LangVersion`` compilation =
compilation
|> asFsx
|> withOptions ["--langversion:5.0"]
|> compile
|> shouldFail
|> withErrorCode 3350
|> withDiagnosticMessageMatches "Feature 'discard pattern in use binding' is not available.*"

[<Fact>]
let ``Dispose called for discarded value of use binding`` () =
Fsx """
type private Disposable() =
[<DefaultValue>] static val mutable private disposedTimes: int
[<DefaultValue>] static val mutable private constructedTimes: int

do Disposable.constructedTimes <- Disposable.constructedTimes + 1

static member DisposeCallCount() = Disposable.disposedTimes
static member ConsturctorCallCount() = Disposable.constructedTimes

interface System.IDisposable with
member _.Dispose() =
Disposable.disposedTimes <- Disposable.disposedTimes + 1

let _scope =
use _ = new Disposable()
()

let disposeCalls = Disposable.DisposeCallCount()
if disposeCalls <> 1 then
failwith "was not disposed or disposed too many times"

let ctorCalls = Disposable.ConsturctorCallCount()
if ctorCalls <> 1 then
failwithf "unexpected constructor call count: %i" ctorCalls

"""
|> asExe
|> withLangVersionPreview
|> compileAndRun
|> shouldSucceed
Expand Up @@ -66,6 +66,7 @@
<Compile Include="Conformance\BasicTypeAndModuleDefinitions\RecordTypes.fs" />
<Compile Include="Conformance\BasicTypeAndModuleDefinitions\UnionTypes.fs" />
<Compile Include="Conformance\DeclarationElements\LetBindings\TypeFunctions.fs" />
<Compile Include="Conformance\DeclarationElements\LetBindings\UseBindings.fs" />
<Compile Include="Conformance\Expressions\ApplicationExpressions\BasicApplication.fs" />
<Compile Include="Conformance\Expressions\ControlFlowExpressions\PatternMatching.fs" />
<Compile Include="Conformance\Expressions\ControlFlowExpressions\SequenceIteration.fs" />
Expand Down
@@ -0,0 +1,6 @@
// #DeclarationElements #LetBindings
//<Expects status="success"></Expects>

let answer =
use _ = new System.IO.MemoryStream()
42