diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 36e2c65b0a6..f013628404d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,9 +1,9 @@ - + https://github.com/dotnet/source-build-reference-packages - 05ffbf9df6c1dc621665ee1864874c4fe6de874c + 8a2f652b1f23d493fcce31b73e829de56df38d5f diff --git a/global.json b/global.json index 1ffce949700..365652e8f7e 100644 --- a/global.json +++ b/global.json @@ -1,10 +1,10 @@ { "sdk": { - "version": "8.0.100-rc.1.23455.8", + "version": "8.0.100-rc.1.23463.5", "allowPrerelease": true }, "tools": { - "dotnet": "8.0.100-rc.1.23455.8", + "dotnet": "8.0.100-rc.1.23463.5", "vs": { "version": "17.6", "components": [ diff --git a/src/Compiler/Checking/CheckComputationExpressions.fs b/src/Compiler/Checking/CheckComputationExpressions.fs index 82403341f7d..f9887d625f3 100644 --- a/src/Compiler/Checking/CheckComputationExpressions.fs +++ b/src/Compiler/Checking/CheckComputationExpressions.fs @@ -229,7 +229,10 @@ let TcComputationExpression (cenv: cenv) env (overallTy: OverallTy) tpenv (mWhol // Give bespoke error messages for the FSharp.Core "query" builder let isQuery = match stripDebugPoints interpExpr with - | Expr.Val (vref, _, m) -> + // 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)) -> 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/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 452e9d5c7c2..496081df39d 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -10788,6 +10788,7 @@ and TcAttributeEx canFail (cenv: cenv) (env: TcEnv) attrTgt attrEx (synAttr: Syn let mAttr = synAttr.Range let typath, tyid = List.frontAndBack tycon let tpenv = emptyUnscopedTyparEnv + let ad = env.eAccessRights // if we're checking an attribute that was applied directly to a getter or a setter, then // what we're really checking against is a method, not a property @@ -10796,13 +10797,12 @@ and TcAttributeEx canFail (cenv: cenv) (env: TcEnv) attrTgt attrEx (synAttr: Syn let try1 n = let tyid = mkSynId tyid.idRange n let tycon = (typath @ [tyid]) - let ad = env.eAccessRights + match ResolveTypeLongIdent cenv.tcSink cenv.nameResolver ItemOccurence.UseInAttribute OpenQualified env.eNameResEnv ad tycon TypeNameResolutionStaticArgsInfo.DefiniteEmpty PermitDirectReferenceToGeneratedType.No with | Exception err -> raze err - | _ -> success(TcTypeAndRecover cenv NoNewTypars CheckCxs ItemOccurence.UseInAttribute WarnOnIWSAM.Yes env tpenv (SynType.App(SynType.LongIdent(SynLongIdent(tycon, [], List.replicate tycon.Length None)), None, [], [], None, false, mAttr)) ) - ForceRaise ((try1 (tyid.idText + "Attribute")) |> otherwise (fun () -> (try1 tyid.idText))) + | Result(tinstEnclosing, tcref) -> success(TcTypeApp cenv NoNewTypars CheckCxs ItemOccurence.UseInAttribute env tpenv mAttr tcref tinstEnclosing []) - let ad = env.eAccessRights + ForceRaise ((try1 (tyid.idText + "Attribute")) |> otherwise (fun () -> (try1 tyid.idText))) if not (IsTypeAccessible g cenv.amap mAttr ad ty) then errorR(Error(FSComp.SR.tcTypeIsInaccessible(), mAttr)) diff --git a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/CommonWorkflows.fs b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/CommonWorkflows.fs index d13efc2169a..ce9846a0ee5 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharpChecker/CommonWorkflows.fs +++ b/tests/FSharp.Compiler.ComponentTests/FSharpChecker/CommonWorkflows.fs @@ -165,4 +165,4 @@ let GetAllUsesOfAllSymbols() = traceProvider.ForceFlush() |> ignore traceProvider.Dispose() - Assert.Equal(80, result.Length) + Assert.Equal(79, result.Length) diff --git a/tests/service/EditorTests.fs b/tests/service/EditorTests.fs index 8b495da8865..0c88b9cfbc8 100644 --- a/tests/service/EditorTests.fs +++ b/tests/service/EditorTests.fs @@ -781,7 +781,6 @@ type Class1() = su.Symbol.ToString(), (r.StartLine, r.StartColumn, r.EndLine, r.EndColumn)) |> shouldEqual [|("LiteralAttribute", (3, 10, 3, 17)) - ("LiteralAttribute", (3, 10, 3, 17)) ("member .ctor", (3, 10, 3, 17)) ("val ModuleValue", (3, 20, 3, 31)) ("val op_Addition", (6, 26, 6, 27)) @@ -793,11 +792,9 @@ type Class1() = ("Class1", (10, 5, 10, 11)) ("member .ctor", (10, 5, 10, 11)) ("LiteralAttribute", (11, 10, 11, 17)) - ("LiteralAttribute", (11, 10, 11, 17)) ("member .ctor", (11, 10, 11, 17)) ("val ClassValue", (11, 20, 11, 30)) ("LiteralAttribute", (12, 17, 12, 24)) - ("LiteralAttribute", (12, 17, 12, 24)) ("member .ctor", (12, 17, 12, 24)) ("val StaticClassValue", (12, 27, 12, 43)) ("val ClassValue", (14, 12, 14, 22)) diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs index 6fa72b4398f..156b2bd879e 100644 --- a/tests/service/ProjectAnalysisTests.fs +++ b/tests/service/ProjectAnalysisTests.fs @@ -2349,7 +2349,6 @@ let ``Test Project14 all symbols`` () = allUsesOfAllSymbols |> shouldEqual [|("StructAttribute", "StructAttribute", "file1", ((4, 2), (4, 8)), ["attribute"]); - ("StructAttribute", "StructAttribute", "file1", ((4, 2), (4, 8)), ["type"]); ("member .ctor", "StructAttribute", "file1", ((4, 2), (4, 8)), []); ("int", "int", "file1", ((5, 9), (5, 12)), ["type"]); ("int", "int", "file1", ((5, 9), (5, 12)), ["type"]); @@ -2504,14 +2503,10 @@ let ``Test Project16 all symbols`` () = allUsesOfAllSymbols |> shouldEqual [|("ClassAttribute", "ClassAttribute", "sig1", ((8, 6), (8, 11)), ["attribute"], ["class"]); - ("ClassAttribute", "ClassAttribute", "sig1", ((8, 6), (8, 11)), ["type"], - ["class"]); ("member .ctor", "ClassAttribute", "sig1", ((8, 6), (8, 11)), [], ["member"]); ("ClassAttribute", "ClassAttribute", "sig1", ((12, 6), (12, 11)), ["attribute"], ["class"]); - ("ClassAttribute", "ClassAttribute", "sig1", ((12, 6), (12, 11)), ["type"], - ["class"]); ("member .ctor", "ClassAttribute", "sig1", ((12, 6), (12, 11)), [], ["member"]); ("int", "int", "sig1", ((16, 19), (16, 22)), ["type"], ["abbrev"]); @@ -5085,7 +5080,6 @@ let ``Test Project40 all symbols`` () = ("IsNone", ((4, 33), (4, 41)), ["member"; "prop"; "funky"]); ("f", ((4, 4), (4, 5)), ["val"]); ("CompilationRepresentationAttribute", ((6, 2), (6, 27)), ["class"]); - ("CompilationRepresentationAttribute", ((6, 2), (6, 27)), ["class"]); ("CompilationRepresentationAttribute", ((6, 2), (6, 27)), ["member"]); ("CompilationRepresentationFlags", ((6, 28), (6, 58)), ["enum"; "valuetype"]); diff --git a/tests/service/Symbols.fs b/tests/service/Symbols.fs index 59ac5b9b84f..bd8f138ef48 100644 --- a/tests/service/Symbols.fs +++ b/tests/service/Symbols.fs @@ -951,4 +951,127 @@ let nestedFunc (a: RecordA) = { a with Zoo.Foo = 1; Zoo.Zoo.Bar = 2; Zoo.Ba Assert.AreEqual ("RecordA`1", field.DeclaringEntity.Value.CompiledName) assertRange (4, 87) (4, 90) fieldSymbolUse.Range - | _ -> Assert.Fail "Symbol was not FSharpField" \ No newline at end of file + | _ -> Assert.Fail "Symbol was not FSharpField" + +module ComputationExpressions = + [] + let ``IsFromComputationExpression only returns true for 'builder' in 'builder { … }'`` () = + let _, checkResults = getParseAndCheckResults """ +type Builder () = + member _.Return x = x + member _.Run x = x + +let builder = Builder () + +let x = builder { return 3 } +let y = builder +let z = Builder () { return 3 } +""" + + shouldEqual + [ + // type Builder () = + (2, 5), false + + // … = Builder () + (6, 14), false + + // let builder = … + (6, 4), false + + // let x = builder { return 3 } + (8, 8), false // Item.Value _ + (8, 8), true // Item.CustomBuilder _ + + // let y = builder + (9, 8), false + + // let z = Builder () { return 3 } + (10, 8), false + ] + [ + for symbolUse in checkResults.GetAllUsesOfAllSymbolsInFile() do + match symbolUse.Symbol.DisplayName with + | "Builder" | "builder" -> (symbolUse.Range.StartLine, symbolUse.Range.StartColumn), symbolUse.IsFromComputationExpression + | _ -> () + ] + + [] + let ``IsFromComputationExpression only returns true for 'builder' in 'builder<…> { … }'`` () = + let _, checkResults = getParseAndCheckResults """ +type Builder<'T> () = + member _.Return x = x + member _.Run x = x + +let builder<'T> = Builder<'T> () + +let x = builder { return 3 } +let y = builder { return 3 } +let z = builder<_> { return 3 } +let p = builder +let q<'T> = builder<'T> +""" + + shouldEqual + [ + // let builder<'T> = Builder<'T> () + (6, 4), false + + // let x = builder { return 3 } + (8, 8), false // Item.Value _ + (8, 8), true // Item.CustomBuilder _ + + // let y = builder { return 3 } + (9, 8), false // Item.Value _ + (9, 8), true // Item.CustomBuilder _ + + // let z = builder<_> { return 3 } + (10, 8), false // Item.Value _ + (10, 8), true // Item.CustomBuilder _ + + // let p = builder + (11, 8), false + + // let q<'T> = builder<'T> + (12, 12), false + ] + [ + for symbolUse in checkResults.GetAllUsesOfAllSymbolsInFile() do + if symbolUse.Symbol.DisplayName = "builder" then + (symbolUse.Range.StartLine, symbolUse.Range.StartColumn), symbolUse.IsFromComputationExpression + ] + + [] + let ``IsFromComputationExpression only returns true for 'builder' in 'builder () { … }'`` () = + let _, checkResults = getParseAndCheckResults """ +type Builder () = + member _.Return x = x + member _.Run x = x + +let builder () = Builder () + +let x = builder () { return 3 } +let y = builder () +let z = builder +""" + + shouldEqual + [ + // let builder () = Builder () + (6, 4), false + + // let x = builder () { return 3 } + (8, 8), false // Item.Value _ + (8, 8), true // Item.CustomBuilder _ + + // let y = builder () + (9, 8), false + + // let z = builder + (10, 8), false + ] + [ + for symbolUse in checkResults.GetAllUsesOfAllSymbolsInFile() do + if symbolUse.Symbol.DisplayName = "builder" then + (symbolUse.Range.StartLine, symbolUse.Range.StartColumn), symbolUse.IsFromComputationExpression + ]