diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index 87a5a209c51..dfd7f877714 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -1,5 +1,5 @@ ### Fixed - +* Fix extension methods support for non-reference system assemblies ([PR #17799](https://github.com/dotnet/fsharp/pull/17799)) * Ensure `frameworkTcImportsCache` mutations are threadsafe. ([PR #17795](https://github.com/dotnet/fsharp/pull/17795)) ### Added @@ -10,5 +10,6 @@ * Make ILTypeDef interface impls calculation lazy. ([PR #17392](https://github.com/dotnet/fsharp/pull/17392)) * Better ranges for CE `let!` and `use!` error reporting. ([PR #17712](https://github.com/dotnet/fsharp/pull/17712)) * Better ranges for CE `do!` error reporting. ([PR #17779](https://github.com/dotnet/fsharp/pull/17779)) +* Better ranges for CE `match!`. ([PR #17789](https://github.com/dotnet/fsharp/pull/17789)) ### Breaking Changes diff --git a/src/Compiler/AbstractIL/ilread.fs b/src/Compiler/AbstractIL/ilread.fs index 7ffa71feeee..5bedfe05752 100644 --- a/src/Compiler/AbstractIL/ilread.fs +++ b/src/Compiler/AbstractIL/ilread.fs @@ -2144,11 +2144,6 @@ and typeDefReader ctxtH : ILTypeDefStored = else let mutable attrIdx = attrsStartIdx - let looksLikeSystemAssembly = - ctxt.fileName.EndsWith("System.Runtime.dll") - || ctxt.fileName.EndsWith("mscorlib.dll") - || ctxt.fileName.EndsWith("netstandard.dll") - while attrIdx <= attrsEndIdx && not containsExtensionMethods do let mutable addr = ctxt.rowAddr TableNames.CustomAttribute attrIdx // skip parentIndex to read typeIndex @@ -2159,12 +2154,9 @@ and typeDefReader ctxtH : ILTypeDefStored = let name = if attrTypeIndex.tag = cat_MethodDef then // the ExtensionAttribute constructor can be cat_MethodDef if the metadata is read from the assembly - // in which the corresponding attribute is defined -- from the system library - if not looksLikeSystemAssembly then - "" - else - let _, (_, nameIdx, namespaceIdx, _, _, _) = seekMethodDefParent ctxt attrCtorIdx - readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) + // in which the corresponding attribute is defined + let _, (_, nameIdx, namespaceIdx, _, _, _) = seekMethodDefParent ctxt attrCtorIdx + readBlobHeapAsTypeName ctxt (nameIdx, namespaceIdx) else let mutable addr = ctxt.rowAddr TableNames.MemberRef attrCtorIdx let mrpTag = seekReadMemberRefParentIdx ctxt mdv &addr diff --git a/src/Compiler/Checking/Expressions/CheckExpressions.fs b/src/Compiler/Checking/Expressions/CheckExpressions.fs index d0f758967de..d2df1aff642 100644 --- a/src/Compiler/Checking/Expressions/CheckExpressions.fs +++ b/src/Compiler/Checking/Expressions/CheckExpressions.fs @@ -6004,7 +6004,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE error(Error(FSComp.SR.tcConstructRequiresSequenceOrComputations(), m)) | SynExpr.DoBang (trivia = { DoBangKeyword = m }) - | SynExpr.MatchBang (range = m) + | SynExpr.MatchBang (trivia = { MatchBangKeyword = m }) | SynExpr.WhileBang (range = m) | SynExpr.LetOrUseBang (trivia = { LetOrUseBangKeyword = m }) -> error(Error(FSComp.SR.tcConstructRequiresComputationExpression(), m)) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs index 027ad51ee4c..319d79aa8ea 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/ComputationExpressionTests.fs @@ -442,4 +442,55 @@ query { |> shouldFail |> withDiagnostics [ (Error 3143, Line 4, Col 5, Line 4, Col 9, "'let!', 'use!' and 'do!' expressions may not be used in queries") + ] + + [] + let ``This control construct may only be used if the computation expression builder defines a 'Bind' method(match!)`` () = + Fsx """ +module Result = + let zip x1 x2 = + match x1,x2 with + | Ok x1res, Ok x2res -> Ok (x1res, x2res) + | Error e, _ -> Error e + | _, Error e -> Error e + +type ResultBuilder() = + member _.MergeSources(t1: Result<'T,'U>, t2: Result<'T1,'U>) = Result.zip t1 t2 + member _.BindReturn(x: Result<'T,'U>, f) = Result.map f x + member _.Delay(f) = f() + + member _.TryWith(r: Result<'T,'U>, f) = + match r with + | Ok x -> Ok x + | Error e -> f e + +let result = ResultBuilder() + +let run r2 r3 = + result { + match! r2 with + | Ok x -> return x + | Error e -> return e + } + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 708, Line 23, Col 9, Line 23, Col 15, "This control construct may only be used if the computation expression builder defines a 'Bind' method") + ] + + [] + let ``This construct may only be used within computation expressions(match!)`` () = + Fsx """ +let run r2 r3 = + match! r2 with + | Ok x -> x + | Error e -> e + """ + |> ignoreWarnings + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 750, Line 3, Col 5, Line 3, Col 11, "This construct may only be used within computation expressions") ] \ No newline at end of file diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs index 50c354da629..08fa3ec324d 100644 --- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs @@ -352,6 +352,22 @@ tInput.Length let value = opt.Value Assert.Equal(4L, downcast value.ReflectionValue) + [] // usessdkrefs is not a valid option for desktop compiler + member _.``ML - use assembly with ref dependencies and without refing SMemory``() = + let code = """ +#r "nuget:Microsoft.ML.OnnxTransformer,1.4.0" + +open System +open System.Numerics.Tensors +let inputValues = [| 12.0; 10.0; 17.0; 5.0 |] +let tInput = new DenseTensor(inputValues.AsMemory(), new ReadOnlySpan([|4|])) +tInput.Length +""" + use script = new FSharpScript(additionalArgs=[| "/usesdkrefs-" |]) + let opt = script.Eval(code) |> getValue + let value = opt.Value + Assert.Equal(4L, downcast value.ReflectionValue) + [] member _.``System.Device.Gpio - Ensure we reference the runtime version of the assembly``() = let code = """ diff --git a/tests/fsharp/typecheck/sigs/neg104.vsbsl b/tests/fsharp/typecheck/sigs/neg104.vsbsl index 12c1c451d3e..8a6059aa128 100644 --- a/tests/fsharp/typecheck/sigs/neg104.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg104.vsbsl @@ -19,9 +19,9 @@ neg104.fs(35,19,35,20): parse error FS0010: Unexpected symbol '}' in definition. neg104.fs(36,1,36,1): parse error FS0010: Incomplete structured construct at or before this point in implementation file -neg104.fs(8,9,8,30): typecheck error FS0750: This construct may only be used within computation expressions +neg104.fs(8,9,8,15): typecheck error FS0750: This construct may only be used within computation expressions -neg104.fs(10,9,10,30): typecheck error FS0750: This construct may only be used within computation expressions +neg104.fs(10,9,10,15): typecheck error FS0750: This construct may only be used within computation expressions neg104.fs(20,9,20,15): typecheck error FS0025: Incomplete pattern matches on this expression.