Skip to content

Commit 12efe3b

Browse files
authored
Check return type info in use! bindings (#19024)
1 parent 37d78e9 commit 12efe3b

File tree

4 files changed

+55
-9
lines changed

4 files changed

+55
-9
lines changed

src/Compiler/Checking/Expressions/CheckComputationExpressions.fs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1885,7 +1885,9 @@ let rec TryTranslateComputationExpression
18851885
match pat with
18861886
| SynPat.Named(ident = SynIdent(id, _); isThisVal = false) -> id, pat
18871887
| SynPat.LongIdent(longDotId = SynLongIdent(id = [ id ])) -> id, pat
1888-
| SynPat.Typed(pat = pat) when supportsTypedLetOrUseBang -> extractIdentifierFromPattern pat
1888+
| SynPat.Typed(innerPat, targetType, range) when supportsTypedLetOrUseBang ->
1889+
let ident, pat = extractIdentifierFromPattern innerPat
1890+
ident, SynPat.Typed(pat, targetType, unionRanges pat.Range range)
18891891
| SynPat.Wild(m) when supportsUseBangBindingValueDiscard ->
18901892
// To properly call the Using(disposable) CE member, we need to convert the wildcard to a SynPat.Named
18911893
let tmpIdent = mkSynId m "_"

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ let testBindingPatterns() =
3737
Disposable.Reset()
3838

3939
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)
40+
use! res:Disposable = new Disposable(1)
41+
use! __:Disposable = new Disposable(2)
42+
use! (res1: Disposable) = new Disposable(3)
43+
use! _: Disposable = new Disposable(4)
44+
use! (_: Disposable) = new Disposable(5)
4545
return ()
4646
} |> Async.RunSynchronously
4747

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ module UseBangBindingsVersion9 =
5959
|> typecheck
6060
|> shouldFail
6161
|> withDiagnostics [
62-
(Error 3350, Line 40, Col 18, Line 40, Col 29, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.")
63-
(Error 3350, Line 41, Col 17, Line 41, Col 28, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.")
64-
(Error 3350, Line 43, Col 17, Line 43, Col 28, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.")
62+
(Error 3350, Line 40, Col 18, Line 40, Col 28, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.")
63+
(Error 3350, Line 41, Col 17, Line 41, Col 27, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.")
64+
(Error 3350, Line 43, Col 17, Line 43, Col 27, "Feature 'Allow let! and use! type annotations without requiring parentheses' is not available in F# 9.0. Please use language version 10.0 or greater.")
6565
]
6666

6767
module UseBangBindingsPreview =

tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,6 +2031,50 @@ match test() with
20312031
|> compileAndRun
20322032
|> shouldSucceed
20332033

2034+
[<Fact>]
2035+
let ``Preview: use! unresolved return type`` () =
2036+
FSharp """
2037+
module Test
2038+
2039+
open System.IO
2040+
open System.Threading.Tasks
2041+
2042+
task {
2043+
use! x: IDisposable = Task.FromResult(new StreamReader(""))
2044+
()
2045+
}
2046+
|> ignore
2047+
"""
2048+
|> withLangVersionPreview
2049+
|> typecheck
2050+
|> shouldFail
2051+
|> withDiagnostics [
2052+
Error 39, Line 8, Col 13, Line 8, Col 24, "The type 'IDisposable' is not defined."
2053+
]
2054+
2055+
[<Fact>]
2056+
let ``Preview: use! return type mismatch error 01`` () =
2057+
FSharp """
2058+
module Test
2059+
2060+
open System
2061+
2062+
task {
2063+
use! (x: int): IDisposable = failwith ""
2064+
()
2065+
}
2066+
|> ignore
2067+
"""
2068+
|> withLangVersionPreview
2069+
|> typecheck
2070+
|> shouldFail
2071+
|> withDiagnostics [
2072+
Error 1, Line 7, Col 11, Line 7, Col 17, "This expression was expected to have type
2073+
'IDisposable'
2074+
but here has type
2075+
'int' "
2076+
]
2077+
20342078
[<Theory; FileInlineData("tailcalls.fsx")>]
20352079
let ``tail call methods work`` compilation =
20362080
compilation

0 commit comments

Comments
 (0)