From 82ef90bbea35e995fac681a280bfab8fc2d2755c Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Tue, 2 Jul 2024 03:02:41 +0300 Subject: [PATCH 1/5] wip --- .../Checking/CheckComputationExpressions.fs | 2 +- .../Language/ComputationExpressionTests.fs | 17 +++++++ .../FSharp.Compiler.Service.Tests/Symbols.fs | 50 +++++++++++++++++-- 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/Compiler/Checking/CheckComputationExpressions.fs b/src/Compiler/Checking/CheckComputationExpressions.fs index fa56149ac7f..833c7461641 100644 --- a/src/Compiler/Checking/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/CheckComputationExpressions.fs @@ -252,7 +252,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol // An unparameterized custom builder, e.g., `query`, `async`. | Expr.Val(vref, _, m) // A parameterized custom builder, e.g., `builder<…>`, `builder ()`. - | Expr.App(funcExpr = Expr.Val(vref, _, m)) -> + | Expr.App(funcExpr = Expr.Val(vref, _, m)) when vref.IsConstructor || not (vref.IsMember || vref.IsExtensionMember) -> let item = Item.CustomBuilder(vref.DisplayName, vref) CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) valRefEq cenv.g vref cenv.g.query_value_vref diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index 21c1c0de20f..af588b04975 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -135,3 +135,20 @@ let _pythags = seqbuilder {{ |> FSharp |> typecheck |> shouldSucceed + + [] + let ``A CE returned from type member succeeds``() = + FSharp """ +module ComputationExpressionTests +type Builder () = + member _.Bind(x, f) = f x + member _.Return(x) = x + +type A = + static member Prop = Builder () + +let x = A.Prop { return 0 } + """ + |> compile + |> shouldSucceed + |> ignore diff --git a/tests/FSharp.Compiler.Service.Tests/Symbols.fs b/tests/FSharp.Compiler.Service.Tests/Symbols.fs index 2a46d5492f9..c63dca9f6de 100644 --- a/tests/FSharp.Compiler.Service.Tests/Symbols.fs +++ b/tests/FSharp.Compiler.Service.Tests/Symbols.fs @@ -1,6 +1,5 @@ module FSharp.Compiler.Service.Tests.Symbols -open System open FSharp.Compiler.CodeAnalysis open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Symbols @@ -1090,19 +1089,32 @@ let builder = Builder () let x = builder { return 3 } let y = builder let z = Builder () { return 3 } + +type A () = + let builder = Builder () + let _ = builder { return 3 } + + static member Builder = Builder () + +type System.Object with + static member Builder = Builder () + +let c = A.Builder { return 3 } +let d = System.Object.Builder { return 3 } """ + shouldEqual checkResults.Diagnostics [||] shouldEqual [ // type Builder () = (2, 5), false - // … = Builder () - (6, 14), false - // let builder = … (6, 4), false + // … = Builder () + (6, 14), false + // let x = builder { return 3 } (8, 8), false // Item.Value _ (8, 8), true // Item.CustomBuilder _ @@ -1112,9 +1124,37 @@ let z = Builder () { return 3 } // let z = Builder () { return 3 } (10, 8), false + + // let builder = … + (13, 8), false + + // … = Builder () + (13, 18), false + + // let x = builder { return 3 } + (14, 12), false // Item.Value _ + (14, 12), true // Item.CustomBuilder _ + + // static member Builder = … + (16, 18), false + + // … = Builder () + (16, 28), false + + // static member Builder = … + (19, 18), false + + // … = Builder () + (19, 28), false + + // A.Builder { return 3 } + (21, 8), false + + // System.Object.Builder { return 3 } + (22, 8), false ] [ - for symbolUse in checkResults.GetAllUsesOfAllSymbolsInFile() do + for symbolUse in checkResults.GetAllUsesOfAllSymbolsInFile() |> Seq.sortBy (fun x -> x.Range.StartLine, x.Range.StartColumn) do match symbolUse.Symbol.DisplayName with | "Builder" | "builder" -> (symbolUse.Range.StartLine, symbolUse.Range.StartColumn), symbolUse.IsFromComputationExpression | _ -> () From c31d07c61a29f89b9ca0272954375cc1b1149c16 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Tue, 2 Jul 2024 03:28:32 +0300 Subject: [PATCH 2/5] simplify --- src/Compiler/Checking/CheckComputationExpressions.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Checking/CheckComputationExpressions.fs b/src/Compiler/Checking/CheckComputationExpressions.fs index 833c7461641..6b5ba75de59 100644 --- a/src/Compiler/Checking/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/CheckComputationExpressions.fs @@ -252,7 +252,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol // An unparameterized custom builder, e.g., `query`, `async`. | Expr.Val(vref, _, m) // A parameterized custom builder, e.g., `builder<…>`, `builder ()`. - | Expr.App(funcExpr = Expr.Val(vref, _, m)) when vref.IsConstructor || not (vref.IsMember || vref.IsExtensionMember) -> + | Expr.App(funcExpr = Expr.Val(vref, _, m)) when vref.IsConstructor || not vref.IsMember -> let item = Item.CustomBuilder(vref.DisplayName, vref) CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) valRefEq cenv.g vref cenv.g.query_value_vref From c14a4352d126e423246b74feafa8dbd9266f08b5 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Tue, 2 Jul 2024 03:32:48 +0300 Subject: [PATCH 3/5] release notes --- docs/release-notes/.FSharp.Compiler.Service/8.0.400.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md index 5bda852e8f4..58c18860dcd 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md @@ -18,6 +18,7 @@ * Fix for exponential runtime in CE builders when using nested implicit yields [PR #17096](https://github.com/dotnet/fsharp/pull/17096) * Fix several AND operator parser bugs and regressions ([Issue #16447](https://github.com/dotnet/fsharp/issues/16447), [Issue #17134](https://github.com/dotnet/fsharp/issues/17134), [Issue #16309](https://github.com/dotnet/fsharp/issues/16309), [PR #17113](https://github.com/dotnet/fsharp/pull/17113)) * Treat exceptions as types in a namespace for graph based type checking ([Issue #17262](https://github.com/dotnet/fsharp/issues/17262), [PR #17268](https://github.com/dotnet/fsharp/pull/17268)) +* Fix reporting IsFromComputationExpression only for CE builder type constructors and let bindings. ([PR #17375](https://github.com/dotnet/fsharp/pull/17375)) ### Added From c98608d676651cbd064dbc70059926ee7c7411ae Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Tue, 2 Jul 2024 03:41:41 +0300 Subject: [PATCH 4/5] . --- src/Compiler/Checking/CheckComputationExpressions.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Checking/CheckComputationExpressions.fs b/src/Compiler/Checking/CheckComputationExpressions.fs index 6b5ba75de59..53de5ce5b1d 100644 --- a/src/Compiler/Checking/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/CheckComputationExpressions.fs @@ -252,7 +252,7 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol // An unparameterized custom builder, e.g., `query`, `async`. | Expr.Val(vref, _, m) // A parameterized custom builder, e.g., `builder<…>`, `builder ()`. - | Expr.App(funcExpr = Expr.Val(vref, _, m)) when vref.IsConstructor || not vref.IsMember -> + | Expr.App(funcExpr = Expr.Val(vref, _, m)) when not vref.IsMember || vref.IsConstructor -> let item = Item.CustomBuilder(vref.DisplayName, vref) CallNameResolutionSink cenv.tcSink (m, env.NameEnv, item, emptyTyparInst, ItemOccurence.Use, env.eAccessRights) valRefEq cenv.g vref cenv.g.query_value_vref From 97c88f76af3cb4f164633a21dc7b09f716174781 Mon Sep 17 00:00:00 2001 From: "Alexey.Berezhnykh" Date: Wed, 10 Jul 2024 20:15:58 +0300 Subject: [PATCH 5/5] release notes --- docs/release-notes/.FSharp.Compiler.Service/8.0.400.md | 1 - docs/release-notes/.FSharp.Compiler.Service/9.0.100.md | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md index 5ba3974ec2c..60394d22e23 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md @@ -19,7 +19,6 @@ * Fix for exponential runtime in CE builders when using nested implicit yields [PR #17096](https://github.com/dotnet/fsharp/pull/17096) * Fix several AND operator parser bugs and regressions ([Issue #16447](https://github.com/dotnet/fsharp/issues/16447), [Issue #17134](https://github.com/dotnet/fsharp/issues/17134), [Issue #16309](https://github.com/dotnet/fsharp/issues/16309), [PR #17113](https://github.com/dotnet/fsharp/pull/17113)) * Treat exceptions as types in a namespace for graph based type checking ([Issue #17262](https://github.com/dotnet/fsharp/issues/17262), [PR #17268](https://github.com/dotnet/fsharp/pull/17268)) -* Fix reporting IsFromComputationExpression only for CE builder type constructors and let bindings. ([PR #17375](https://github.com/dotnet/fsharp/pull/17375)) ### Added diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md index 165f50a443a..26c5c51e2ec 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.100.md @@ -1,4 +1,5 @@ ### Fixed +* Fix reporting IsFromComputationExpression only for CE builder type constructors and let bindings. ([PR #17375](https://github.com/dotnet/fsharp/pull/17375)) ### Added