Skip to content

Commit

Permalink
allow _ in use bindings by checking for special case of TPat_wild i…
Browse files Browse the repository at this point in the history
…n TcLetBinding

implements fsharp/fslang-suggestions#881
and https://github.com/fsharp/fslang-design/blob/6c1ba3425c6129f1b6cf22ac8ddec30761136a12/RFCs/FS-1102-discards-on-use-bindings.md

has basic test UseBindingDiscard01, that ensures, that `use _ = new Disposable()` type checks
  • Loading branch information
lostmsu committed Jun 4, 2021
1 parent afe8830 commit a96d7ce
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/fsharp/CheckExpressions.fs
Expand Up @@ -9770,7 +9770,12 @@ 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
if not isDiscarded then
errorR(Error(FSComp.SR.tcInvalidUseBinding(), m))

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 +9803,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
@@ -0,0 +1,18 @@
// 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 =

//<Expects status="success"></Expects>
[<Theory; Directory(__SOURCE_DIRECTORY__ + "/../../../resources/tests/Conformance/DeclarationElements/LetBindings", Includes=[|"UseBindingDiscard01.fs"|])>]
let ``UseBindings - UseBindingDiscard01.fs - `` compilation =
compilation
|> asFsx
|> compile
|> shouldSucceed
|> ignore
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

0 comments on commit a96d7ce

Please sign in to comment.