Skip to content

Commit b16bbb5

Browse files
committed
more tests
1 parent 50114d1 commit b16bbb5

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

src/Compiler/Checking/Expressions/CheckComputationExpressions.fs

+1
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,7 @@ let rec TryTranslateComputationExpression
18021802
match pat with
18031803
| SynPat.Named(ident = SynIdent(id, _); isThisVal = false) -> id, pat
18041804
| SynPat.LongIdent(longDotId = SynLongIdent(id = [ id ])) -> id, pat
1805+
| SynPat.Typed(pat = pat) -> extractIdentifierFromPattern pat
18051806
| SynPat.Wild(m) when supportsUseBangBindingValueDiscard ->
18061807
// To properly call the Using(disposable) CE member, we need to convert the wildcard to a SynPat.Named
18071808
let tmpIdent = mkSynId m "_"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
open System
2+
3+
open System
4+
5+
type Disposable(id: int) =
6+
static let mutable disposedIds = Set.empty<int>
7+
static let mutable constructedIds = Set.empty<int>
8+
9+
do constructedIds <- constructedIds.Add(id)
10+
11+
member _.Id = id
12+
13+
static member GetDisposed() = disposedIds
14+
static member GetConstructed() = constructedIds
15+
static member Reset() =
16+
disposedIds <- Set.empty
17+
constructedIds <- Set.empty
18+
19+
interface IDisposable with
20+
member this.Dispose() = disposedIds <- disposedIds.Add(this.Id)
21+
22+
type DisposableBuilder() =
23+
member _.Using(resource: #IDisposable, f) =
24+
async {
25+
use res = resource
26+
return! f res
27+
}
28+
29+
member _.Bind(disposable: Disposable, f) = async.Bind(async.Return(disposable), f)
30+
member _.Return(x) = async.Return x
31+
member _.ReturnFrom(x) = x
32+
member _.Bind(task, f) = async.Bind(task, f)
33+
34+
let counterDisposable = DisposableBuilder()
35+
36+
let testBindingPatterns() =
37+
Disposable.Reset()
38+
39+
counterDisposable {
40+
use! res:IDisposable = new Disposable(1)
41+
use! __:IDisposable = new Disposable(2)
42+
use! (res1: IDisposable) = new Disposable(3)
43+
use! _: IDisposable = new Disposable(4)
44+
use! (_: IDisposable) = new Disposable(5)
45+
return ()
46+
} |> Async.RunSynchronously
47+
48+
let constructed = Disposable.GetConstructed()
49+
let disposed = Disposable.GetDisposed()
50+
let undisposed = constructed - disposed
51+
52+
if not undisposed.IsEmpty then
53+
printfn $"Undisposed instances: %A{undisposed}"
54+
failwithf "Not all disposables were properly disposed"
55+
else
56+
printfn $"Success! All %d{constructed.Count} disposables were properly disposed"
57+
58+
testBindingPatterns()

tests/FSharp.Compiler.ComponentTests/Conformance/BasicGrammarElements/UseBindings/UseBangBindings.fs

+20
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ module UseBangBindingsVersion9 =
5050
|> withDiagnostics [
5151
(Error 1228, Line 47, Col 14, Line 47, Col 15, "'use!' bindings must be of the form 'use! <var> = <expr>'")
5252
]
53+
54+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"UseBang05.fs"|])>]
55+
let ``UseBangBindings - UseBang05_fs - Current LangVersion`` compilation =
56+
compilation
57+
|> asFsx
58+
|> withLangVersion90
59+
|> typecheck
60+
|> shouldFail
61+
|> withDiagnostics [
62+
(Error 1228, Line 43, Col 14, Line 43, Col 15, "'use!' bindings must be of the form 'use! <var> = <expr>'")
63+
]
5364

5465
module UseBangBindingsPreview =
5566
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"UseBang01.fs"|])>]
@@ -83,4 +94,13 @@ module UseBangBindingsPreview =
8394
|> withLangVersionPreview
8495
|> compileAndRun
8596
|> shouldSucceed
97+
98+
[<Theory; Directory(__SOURCE_DIRECTORY__, Includes=[|"UseBang05.fs"|])>]
99+
let ``UseBangBindings - UseBang05_fs - Preview LangVersion`` compilation =
100+
compilation
101+
|> asExe
102+
|> withLangVersionPreview
103+
|> compileAndRun
104+
|> shouldSucceed
105+
86106

0 commit comments

Comments
 (0)