From 69fb04e4dc7332408bb760ddb7a892faea639864 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Sat, 20 Aug 2022 09:01:33 +0100 Subject: [PATCH 01/42] Add test --- .../BasicApplication/ThomasTest.fs | 45 +++++++++++++++++++ .../FSharp.Compiler.ComponentTests.fsproj | 1 + 2 files changed, 46 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs new file mode 100644 index 00000000000..31ed8df4689 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs @@ -0,0 +1,45 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Language + +open System +open Xunit +open FSharp.Test.Compiler + +module ThomasTests = + + [] + let ``Passes`` () = + Fsx """ let x = 1 """ + |> compile + |> shouldSucceed + + [] + let ``Fails`` () = + Fsx """ let x = "a" in a |> _.Length""" + |> compile + |> shouldSucceed +// [] +// let ``Regression: Empty Interpolated String properly typechecks with explicit type on binding`` () = +// Fsx """ let a:byte = $"string" """ +// |> compile +// |> shouldFail +// |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 24, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") +// +// [] +// let ``Interpolated String with hole properly typechecks with explicit type on binding`` () = +// Fsx """ let a:byte = $"strin{'g'}" """ +// |> compile +// |> shouldFail +// |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 28, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") +// +// [] +// let ``Interpolated String without holes properly typeckecks with explicit type on binding`` () = +// Fsx """ +// let a: obj = $"string" +// let b: System.IComparable = $"string" +// let c: System.IFormattable = $"string" +// """ +// |> compile +// |> shouldSucceed +// diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 4acda7d0cd7..00a05ac265f 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -69,6 +69,7 @@ + From 9b1a18ad17c5e4ccad1b59755dcf56be24b78d60 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Sat, 20 Aug 2022 13:54:55 +0100 Subject: [PATCH 02/42] Initial extra type --- src/Compiler/Checking/CheckExpressions.fs | 2 ++ src/Compiler/Service/FSharpParseFileResults.fs | 1 + src/Compiler/Service/ServiceParseTreeWalk.fs | 2 ++ src/Compiler/SyntaxTree/SyntaxTree.fs | 3 +++ src/Compiler/SyntaxTree/SyntaxTree.fsi | 3 +++ src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 1 + src/Compiler/pars.fsy | 4 ++++ 7 files changed, 16 insertions(+) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 6aade43c55f..e5925ea76d0 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5449,6 +5449,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE | SynExpr.LongIdent _ | SynExpr.App _ | SynExpr.Dynamic _ + | SynExpr.DotLambda _ | SynExpr.DotGet _ -> error(Error(FSComp.SR.tcExprUndelayed(), synExpr.Range)) @@ -8586,6 +8587,7 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed = | SynExpr.TypeTest (synExpr, _, _) | SynExpr.Upcast (synExpr, _, _) | SynExpr.DotGet (synExpr, _, _, _) + | SynExpr.DotLambda (synExpr, _, _, _) | SynExpr.Downcast (synExpr, _, _) | SynExpr.InferredUpcast (synExpr, _) | SynExpr.InferredDowncast (synExpr, _) diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index de8d6ae60da..4fe98737b50 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -627,6 +627,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, | SynExpr.Assert (e, _) | SynExpr.Fixed (e, _) | SynExpr.DotGet (e, _, _, _) + | SynExpr.DotLambda (e, _, _, _) | SynExpr.LongIdentSet (_, e, _) | SynExpr.New (_, _, e, _) | SynExpr.TypeApp (e, _, _, _, _, _, _) diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index 08c89d969f9..883116fa290 100755 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -655,6 +655,8 @@ module SyntaxTraversal = | SynExpr.DotGet (synExpr, _dotm, _longIdent, _range) -> traverseSynExpr synExpr + | SynExpr.DotLambda (synExpr, _dotm, _longIdent, _range) -> traverseSynExpr synExpr + | SynExpr.Set (synExpr, synExpr2, _) | SynExpr.DotSet (synExpr, _, synExpr2, _) -> diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index 40fc5852cf7..1dd545907a8 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -610,6 +610,8 @@ type SynExpr = | LongIdentSet of longDotId: SynLongIdent * expr: SynExpr * range: range | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range + + | DotLambda of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range @@ -748,6 +750,7 @@ type SynExpr = | SynExpr.DotIndexedGet (range = m) | SynExpr.DotIndexedSet (range = m) | SynExpr.DotGet (range = m) + | SynExpr.DotLambda (range=m) | SynExpr.DotSet (range = m) | SynExpr.Set (range = m) | SynExpr.DotNamedIndexedPropertySet (range = m) diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index b1538eaa489..5c7ee89bc70 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -766,6 +766,9 @@ type SynExpr = /// F# syntax: expr.ident.ident | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range + /// F# syntax: _.ident.ident + | DotLambda of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range + /// F# syntax: expr.ident...ident <- expr | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index b36ec372a78..bb97e5fb18c 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -894,6 +894,7 @@ let rec synExprContainsError inpExpr = | SynExpr.Do (e, _) | SynExpr.Assert (e, _) | SynExpr.DotGet (e, _, _, _) + | SynExpr.DotLambda (e, _, _, _) | SynExpr.LongIdentSet (_, e, _) | SynExpr.New (_, _, e, _) | SynExpr.TypeApp (e, _, _, _, _, _, _) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index d7bbdaaf68e..1cfeccea2ec 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4332,6 +4332,10 @@ atomicExpr: let lhsm = rhs2 parseState 1 2 SynExpr.Typar(typar, lhsm), false } + | UNDERSCORE DOT atomicExprQualification + { let arg1 = SynExpr.Ident (ident("a", rhs parseState 1)) + $3 arg1 (lhs parseState) (rhs parseState 2), false } + | atomicExpr DOT atomicExprQualification { let arg1, hpa1 = $1 $3 arg1 (lhs parseState) (rhs parseState 2), hpa1 } From 4b07e0ac6d993a4357037db278890ef16ced7c87 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Sat, 20 Aug 2022 17:56:15 +0100 Subject: [PATCH 03/42] WIP --- src/Compiler/Checking/CheckExpressions.fs | 12 ++++-- .../Service/FSharpParseFileResults.fs | 2 +- src/Compiler/Service/ServiceParseTreeWalk.fs | 2 +- src/Compiler/SyntaxTree/SyntaxTree.fs | 2 +- src/Compiler/SyntaxTree/SyntaxTree.fsi | 2 +- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 7 +++- src/Compiler/pars.fsy | 2 +- .../BasicApplication/ThomasTest.fs | 40 ++++++++++++++++++- .../SyntaxTreeTests/ExpressionTests.fs | 6 +++ 9 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index e5925ea76d0..344cf37e9c9 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5449,7 +5449,6 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE | SynExpr.LongIdent _ | SynExpr.App _ | SynExpr.Dynamic _ - | SynExpr.DotLambda _ | SynExpr.DotGet _ -> error(Error(FSComp.SR.tcExprUndelayed(), synExpr.Range)) @@ -5468,7 +5467,14 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE TcNonControlFlowExpr env <| fun env -> CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) TcConstExpr cenv overallTy env m tpenv synConst - + | SynExpr.DotLambda (SynLongIdent(lid, dots, trivia), m) -> + + let svar = mkSynCompGenSimplePatVar (mkSynId m "unitVar") + let longIdent = SynExpr.LongIdent(false, SynLongIdent((mkSynId m "unitVar")::lid, dots, None::trivia), None, m) + let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ], m), longIdent, None, m, SynExprLambdaTrivia.Zero) + + TcIteratedLambdas cenv true env overallTy Set.empty tpenv lambda + // TcIteratedLambda | SynExpr.Lambda _ -> TcIteratedLambdas cenv true env overallTy Set.empty tpenv synExpr @@ -8587,7 +8593,6 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed = | SynExpr.TypeTest (synExpr, _, _) | SynExpr.Upcast (synExpr, _, _) | SynExpr.DotGet (synExpr, _, _, _) - | SynExpr.DotLambda (synExpr, _, _, _) | SynExpr.Downcast (synExpr, _, _) | SynExpr.InferredUpcast (synExpr, _) | SynExpr.InferredDowncast (synExpr, _) @@ -8601,6 +8606,7 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed = | SynExpr.Const _ | SynExpr.Typar _ | SynExpr.LongIdent _ + | SynExpr.DotLambda _ | SynExpr.Dynamic _ -> true | SynExpr.Tuple (_, synExprs, _, _) diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index 4fe98737b50..ebdbf255943 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -605,6 +605,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, match expr with | SynExpr.ArbitraryAfterError _ | SynExpr.LongIdent _ + | SynExpr.DotLambda _ | SynExpr.LibraryOnlyILAssembly _ | SynExpr.LibraryOnlyStaticOptimization _ | SynExpr.Null _ @@ -627,7 +628,6 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, | SynExpr.Assert (e, _) | SynExpr.Fixed (e, _) | SynExpr.DotGet (e, _, _, _) - | SynExpr.DotLambda (e, _, _, _) | SynExpr.LongIdentSet (_, e, _) | SynExpr.New (_, _, e, _) | SynExpr.TypeApp (e, _, _, _, _, _, _) diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index 883116fa290..7ca44ded455 100755 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -655,7 +655,7 @@ module SyntaxTraversal = | SynExpr.DotGet (synExpr, _dotm, _longIdent, _range) -> traverseSynExpr synExpr - | SynExpr.DotLambda (synExpr, _dotm, _longIdent, _range) -> traverseSynExpr synExpr + | SynExpr.DotLambda _ -> None | SynExpr.Set (synExpr, synExpr2, _) diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index 1dd545907a8..8ae1b7b8c1e 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -611,7 +611,7 @@ type SynExpr = | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range - | DotLambda of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range + | DotLambda of longDotId: SynLongIdent * range: range | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index 5c7ee89bc70..096c2145958 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -767,7 +767,7 @@ type SynExpr = | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range /// F# syntax: _.ident.ident - | DotLambda of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range + | DotLambda of longDotId: SynLongIdent * range: range /// F# syntax: expr.ident...ident <- expr | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index bb97e5fb18c..7ce3e07ecd3 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -457,6 +457,11 @@ let mkSynDot mDot m l (SynIdent (r, rTrivia)) = | SynExpr.LongIdent (isOpt, SynLongIdent (lid, dots, trivia), None, _) -> // REVIEW: MEMORY PERFORMANCE: This list operation is memory intensive (we create a lot of these list nodes) SynExpr.LongIdent(isOpt, SynLongIdent(lid @ [ r ], dots @ [ mDot ], trivia @ [ rTrivia ]), None, m) + | SynExpr.Ident id when id.idText = "a" -> + let inner = SynLongIdent([r], [mDot], [None; rTrivia]) + SynExpr.DotLambda (inner, m) + | SynExpr.DotLambda (SynLongIdent(lid, dots, trivia), dm) -> + SynExpr.DotLambda (SynLongIdent(lid @ [ r ], dots @ [ mDot ], trivia @ [ rTrivia ]), dm) | SynExpr.Ident id -> SynExpr.LongIdent(false, SynLongIdent([ id; r ], [ mDot ], [ None; rTrivia ]), None, m) | SynExpr.DotGet (e, dm, SynLongIdent (lid, dots, trivia), _) -> // REVIEW: MEMORY PERFORMANCE: This is memory intensive (we create a lot of these list nodes) @@ -874,6 +879,7 @@ let rec synExprContainsError inpExpr = | SynExpr.ArbitraryAfterError _ -> true | SynExpr.LongIdent _ + | SynExpr.DotLambda _ | SynExpr.Quote _ | SynExpr.LibraryOnlyILAssembly _ | SynExpr.LibraryOnlyStaticOptimization _ @@ -894,7 +900,6 @@ let rec synExprContainsError inpExpr = | SynExpr.Do (e, _) | SynExpr.Assert (e, _) | SynExpr.DotGet (e, _, _, _) - | SynExpr.DotLambda (e, _, _, _) | SynExpr.LongIdentSet (_, e, _) | SynExpr.New (_, _, e, _) | SynExpr.TypeApp (e, _, _, _, _, _, _) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 1cfeccea2ec..0c9cd9f3e2d 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4332,7 +4332,7 @@ atomicExpr: let lhsm = rhs2 parseState 1 2 SynExpr.Typar(typar, lhsm), false } - | UNDERSCORE DOT atomicExprQualification + | UNDERSCORE DOT atomicExprQualification { let arg1 = SynExpr.Ident (ident("a", rhs parseState 1)) $3 arg1 (lhs parseState) (rhs parseState 2), false } diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs index 31ed8df4689..f0b3876a61c 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs @@ -16,9 +16,47 @@ module ThomasTests = [] let ``Fails`` () = - Fsx """ let x = "a" in a |> _.Length""" + Fsx """ let x = "a" in x |> _.Length""" |> compile |> shouldSucceed + + [] + let ``Types`` () = + Fsx """ +let a : (string -> _) = _.Length +let b = _.ToString() +let c = _.ToString().Length +//let c = _.ToString()[0] +""" + |> compile + |> shouldSucceed + + [] + let ``Failing`` () = + Fsx """ + let rec GenericHashParamObj (iec : IEqualityComparer) (x: obj) : int = + match x with + | null -> 0 + | (:? System.Array as a) -> + match a with + | :? (obj[]) as oa -> GenericHashObjArray iec oa + | :? (byte[]) as ba -> GenericHashByteArray ba + | :? (int[]) as ba -> GenericHashInt32Array ba + | :? (int64[]) as ba -> GenericHashInt64Array ba + | _ -> GenericHashArbArray iec a + | :? IStructuralEquatable as a -> + a.GetHashCode(iec) + | _ -> + x.GetHashCode() + """ |> compile |> shouldSucceed + + + // + // [] + // let ``Fails2`` () = + // + // """ let x = "a" in a |> _.Length""" + // |> getParseResults // [] // let ``Regression: Empty Interpolated String properly typechecks with explicit type on binding`` () = // Fsx """ let a:byte = $"string" """ diff --git a/tests/service/SyntaxTreeTests/ExpressionTests.fs b/tests/service/SyntaxTreeTests/ExpressionTests.fs index a7f1dcbb8df..de937217931 100644 --- a/tests/service/SyntaxTreeTests/ExpressionTests.fs +++ b/tests/service/SyntaxTreeTests/ExpressionTests.fs @@ -5,6 +5,12 @@ open FSharp.Compiler.Syntax open FSharp.Compiler.SyntaxTrivia open NUnit.Framework +open Xunit +[] +let ``Thomas`` () = + let ast = """_.ToString.ToString "b" """ |> getParseResults + Assert.Fail (ast.ToString()) + [] let ``SynExpr.Do contains the range of the do keyword`` () = let ast = """let a = From ffde01858b0d3a4ffb739f9242aeb56271b600bb Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Fri, 2 Sep 2022 08:46:32 +0100 Subject: [PATCH 04/42] Workaround --- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 2 +- src/Compiler/pars.fsy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 7ce3e07ecd3..7cd1b76747c 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -457,7 +457,7 @@ let mkSynDot mDot m l (SynIdent (r, rTrivia)) = | SynExpr.LongIdent (isOpt, SynLongIdent (lid, dots, trivia), None, _) -> // REVIEW: MEMORY PERFORMANCE: This list operation is memory intensive (we create a lot of these list nodes) SynExpr.LongIdent(isOpt, SynLongIdent(lid @ [ r ], dots @ [ mDot ], trivia @ [ rTrivia ]), None, m) - | SynExpr.Ident id when id.idText = "a" -> + | SynExpr.Ident id when id.idText = "abcabcabc" -> let inner = SynLongIdent([r], [mDot], [None; rTrivia]) SynExpr.DotLambda (inner, m) | SynExpr.DotLambda (SynLongIdent(lid, dots, trivia), dm) -> diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 0c9cd9f3e2d..51af4c2789f 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4333,7 +4333,7 @@ atomicExpr: SynExpr.Typar(typar, lhsm), false } | UNDERSCORE DOT atomicExprQualification - { let arg1 = SynExpr.Ident (ident("a", rhs parseState 1)) + { let arg1 = SynExpr.Ident (ident("abcabcabc", rhs parseState 1)) $3 arg1 (lhs parseState) (rhs parseState 2), false } | atomicExpr DOT atomicExprQualification From 5217eb5934f9cb309a3bbb470bc5cdbad3334f47 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Sat, 10 Sep 2022 11:26:58 +0100 Subject: [PATCH 05/42] WIP underscore --- src/Compiler/Checking/CheckExpressions.fs | 2 ++ src/Compiler/Service/FSharpParseFileResults.fs | 1 + src/Compiler/Service/ServiceParseTreeWalk.fs | 2 ++ src/Compiler/SyntaxTree/SyntaxTree.fs | 3 +++ src/Compiler/SyntaxTree/SyntaxTree.fsi | 2 ++ src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 3 ++- src/Compiler/pars.fsy | 2 +- 7 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 344cf37e9c9..7f0c0fd4669 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5449,6 +5449,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE | SynExpr.LongIdent _ | SynExpr.App _ | SynExpr.Dynamic _ + | SynExpr.Underscore _ | SynExpr.DotGet _ -> error(Error(FSComp.SR.tcExprUndelayed(), synExpr.Range)) @@ -8607,6 +8608,7 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed = | SynExpr.Typar _ | SynExpr.LongIdent _ | SynExpr.DotLambda _ + | SynExpr.Underscore _ | SynExpr.Dynamic _ -> true | SynExpr.Tuple (_, synExprs, _, _) diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index ebdbf255943..26da263f6d7 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -613,6 +613,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, | SynExpr.Ident _ | SynExpr.ImplicitZero _ | SynExpr.Const _ + | SynExpr.Underscore _ | SynExpr.Dynamic _ -> () | SynExpr.Quote (_, _, e, _, _) diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index 7ca44ded455..d831dd8860d 100755 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -657,6 +657,8 @@ module SyntaxTraversal = | SynExpr.DotLambda _ -> None + | SynExpr.Underscore _ -> None + | SynExpr.Set (synExpr, synExpr2, _) | SynExpr.DotSet (synExpr, _, synExpr2, _) -> diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index 8ae1b7b8c1e..698db223f52 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -612,6 +612,8 @@ type SynExpr = | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range | DotLambda of longDotId: SynLongIdent * range: range + + | Underscore of range: range | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range @@ -751,6 +753,7 @@ type SynExpr = | SynExpr.DotIndexedSet (range = m) | SynExpr.DotGet (range = m) | SynExpr.DotLambda (range=m) + | SynExpr.Underscore (range=m) | SynExpr.DotSet (range = m) | SynExpr.Set (range = m) | SynExpr.DotNamedIndexedPropertySet (range = m) diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index 096c2145958..a9968ca0393 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -769,6 +769,8 @@ type SynExpr = /// F# syntax: _.ident.ident | DotLambda of longDotId: SynLongIdent * range: range + | Underscore of range: range + /// F# syntax: expr.ident...ident <- expr | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 7cd1b76747c..dadccd19be9 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -457,7 +457,7 @@ let mkSynDot mDot m l (SynIdent (r, rTrivia)) = | SynExpr.LongIdent (isOpt, SynLongIdent (lid, dots, trivia), None, _) -> // REVIEW: MEMORY PERFORMANCE: This list operation is memory intensive (we create a lot of these list nodes) SynExpr.LongIdent(isOpt, SynLongIdent(lid @ [ r ], dots @ [ mDot ], trivia @ [ rTrivia ]), None, m) - | SynExpr.Ident id when id.idText = "abcabcabc" -> + | SynExpr.Underscore (m) -> let inner = SynLongIdent([r], [mDot], [None; rTrivia]) SynExpr.DotLambda (inner, m) | SynExpr.DotLambda (SynLongIdent(lid, dots, trivia), dm) -> @@ -880,6 +880,7 @@ let rec synExprContainsError inpExpr = | SynExpr.LongIdent _ | SynExpr.DotLambda _ + | SynExpr.Underscore _ | SynExpr.Quote _ | SynExpr.LibraryOnlyILAssembly _ | SynExpr.LibraryOnlyStaticOptimization _ diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 51af4c2789f..d2b2a123a4d 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4333,7 +4333,7 @@ atomicExpr: SynExpr.Typar(typar, lhsm), false } | UNDERSCORE DOT atomicExprQualification - { let arg1 = SynExpr.Ident (ident("abcabcabc", rhs parseState 1)) + { let arg1 = SynExpr.Underscore (rhs parseState 1) $3 arg1 (lhs parseState) (rhs parseState 2), false } | atomicExpr DOT atomicExprQualification From ae44f723a3b69bfcf96a85aab7951f639e03f6dc Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Sat, 10 Sep 2022 16:07:37 +0100 Subject: [PATCH 06/42] Some progress, swap to properly wrapping the whole thing --- src/Compiler/Checking/CheckExpressions.fs | 9 ++------- src/Compiler/Service/FSharpParseFileResults.fs | 1 - src/Compiler/Service/ServiceParseTreeWalk.fs | 2 -- src/Compiler/SyntaxTree/SyntaxTree.fs | 5 +---- src/Compiler/SyntaxTree/SyntaxTree.fsi | 4 +--- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 6 ------ src/Compiler/pars.fsy | 10 +++++++--- .../BasicApplication/ThomasTest.fs | 2 +- tests/service/SyntaxTreeTests/ExpressionTests.fs | 10 ++++++---- 9 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 7f0c0fd4669..d4990b71995 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5449,7 +5449,6 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE | SynExpr.LongIdent _ | SynExpr.App _ | SynExpr.Dynamic _ - | SynExpr.Underscore _ | SynExpr.DotGet _ -> error(Error(FSComp.SR.tcExprUndelayed(), synExpr.Range)) @@ -5468,12 +5467,9 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE TcNonControlFlowExpr env <| fun env -> CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) TcConstExpr cenv overallTy env m tpenv synConst - | SynExpr.DotLambda (SynLongIdent(lid, dots, trivia), m) -> - + | SynExpr.DotLambda (synExpr, m) -> let svar = mkSynCompGenSimplePatVar (mkSynId m "unitVar") - let longIdent = SynExpr.LongIdent(false, SynLongIdent((mkSynId m "unitVar")::lid, dots, None::trivia), None, m) - let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ], m), longIdent, None, m, SynExprLambdaTrivia.Zero) - + let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ], m), synExpr, None, m, SynExprLambdaTrivia.Zero) TcIteratedLambdas cenv true env overallTy Set.empty tpenv lambda // TcIteratedLambda | SynExpr.Lambda _ -> @@ -8608,7 +8604,6 @@ and TcImplicitOpItemThen (cenv: cenv) overallTy env id sln tpenv mItem delayed = | SynExpr.Typar _ | SynExpr.LongIdent _ | SynExpr.DotLambda _ - | SynExpr.Underscore _ | SynExpr.Dynamic _ -> true | SynExpr.Tuple (_, synExprs, _, _) diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index 26da263f6d7..ebdbf255943 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -613,7 +613,6 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, | SynExpr.Ident _ | SynExpr.ImplicitZero _ | SynExpr.Const _ - | SynExpr.Underscore _ | SynExpr.Dynamic _ -> () | SynExpr.Quote (_, _, e, _, _) diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index d831dd8860d..7ca44ded455 100755 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -657,8 +657,6 @@ module SyntaxTraversal = | SynExpr.DotLambda _ -> None - | SynExpr.Underscore _ -> None - | SynExpr.Set (synExpr, synExpr2, _) | SynExpr.DotSet (synExpr, _, synExpr2, _) -> diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index 698db223f52..6928dbcae12 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -611,10 +611,8 @@ type SynExpr = | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range - | DotLambda of longDotId: SynLongIdent * range: range + | DotLambda of expr: SynExpr * range: range - | Underscore of range: range - | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range | Set of targetExpr: SynExpr * rhsExpr: SynExpr * range: range @@ -753,7 +751,6 @@ type SynExpr = | SynExpr.DotIndexedSet (range = m) | SynExpr.DotGet (range = m) | SynExpr.DotLambda (range=m) - | SynExpr.Underscore (range=m) | SynExpr.DotSet (range = m) | SynExpr.Set (range = m) | SynExpr.DotNamedIndexedPropertySet (range = m) diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index a9968ca0393..b3e95ad0e26 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -767,9 +767,7 @@ type SynExpr = | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range /// F# syntax: _.ident.ident - | DotLambda of longDotId: SynLongIdent * range: range - - | Underscore of range: range + | DotLambda of expr: SynExpr * range: range /// F# syntax: expr.ident...ident <- expr | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index dadccd19be9..8e4cdbfa3ba 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -457,11 +457,6 @@ let mkSynDot mDot m l (SynIdent (r, rTrivia)) = | SynExpr.LongIdent (isOpt, SynLongIdent (lid, dots, trivia), None, _) -> // REVIEW: MEMORY PERFORMANCE: This list operation is memory intensive (we create a lot of these list nodes) SynExpr.LongIdent(isOpt, SynLongIdent(lid @ [ r ], dots @ [ mDot ], trivia @ [ rTrivia ]), None, m) - | SynExpr.Underscore (m) -> - let inner = SynLongIdent([r], [mDot], [None; rTrivia]) - SynExpr.DotLambda (inner, m) - | SynExpr.DotLambda (SynLongIdent(lid, dots, trivia), dm) -> - SynExpr.DotLambda (SynLongIdent(lid @ [ r ], dots @ [ mDot ], trivia @ [ rTrivia ]), dm) | SynExpr.Ident id -> SynExpr.LongIdent(false, SynLongIdent([ id; r ], [ mDot ], [ None; rTrivia ]), None, m) | SynExpr.DotGet (e, dm, SynLongIdent (lid, dots, trivia), _) -> // REVIEW: MEMORY PERFORMANCE: This is memory intensive (we create a lot of these list nodes) @@ -880,7 +875,6 @@ let rec synExprContainsError inpExpr = | SynExpr.LongIdent _ | SynExpr.DotLambda _ - | SynExpr.Underscore _ | SynExpr.Quote _ | SynExpr.LibraryOnlyILAssembly _ | SynExpr.LibraryOnlyStaticOptimization _ diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index d2b2a123a4d..5c9c9cb420b 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -525,6 +525,7 @@ let rangeOfLongIdent(lid:LongIdent) = %left pat_app %left pat_args %left PREFIX_OP +%right dot_lambda %left DOT QMARK %left HIGH_PRECEDENCE_BRACK_APP %left HIGH_PRECEDENCE_PAREN_APP @@ -4305,6 +4306,11 @@ argExpr: arg } atomicExpr: + | UNDERSCORE DOT atomicExpr %prec dot_lambda + { let arg1 = lhs parseState + let arg2, hpa = $3 + SynExpr.DotLambda(arg2, arg2.Range), hpa } + | atomicExpr HIGH_PRECEDENCE_BRACK_APP atomicExpr { let arg1, _ = $1 let arg2, hpa = $3 @@ -4332,9 +4338,7 @@ atomicExpr: let lhsm = rhs2 parseState 1 2 SynExpr.Typar(typar, lhsm), false } - | UNDERSCORE DOT atomicExprQualification - { let arg1 = SynExpr.Underscore (rhs parseState 1) - $3 arg1 (lhs parseState) (rhs parseState 2), false } + | atomicExpr DOT atomicExprQualification { let arg1, hpa1 = $1 diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs index f0b3876a61c..1ae2217c7e5 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs @@ -16,7 +16,7 @@ module ThomasTests = [] let ``Fails`` () = - Fsx """ let x = "a" in x |> _.Length""" + Fsx """let x = "a" in x |> _.ToString()""" |> compile |> shouldSucceed diff --git a/tests/service/SyntaxTreeTests/ExpressionTests.fs b/tests/service/SyntaxTreeTests/ExpressionTests.fs index de937217931..5a44f95c013 100644 --- a/tests/service/SyntaxTreeTests/ExpressionTests.fs +++ b/tests/service/SyntaxTreeTests/ExpressionTests.fs @@ -6,10 +6,12 @@ open FSharp.Compiler.SyntaxTrivia open NUnit.Framework open Xunit -[] -let ``Thomas`` () = - let ast = """_.ToString.ToString "b" """ |> getParseResults - Assert.Fail (ast.ToString()) +// [] +// let ``Thomas`` () = + // let ast = """_.ToString.ToString "b" """ |> getParseResults + // let ast = """_.x""" |> getParseResults + // let ast = """_.x()""" |> getParseResults + // Assert.Fail (ast.ToString()) [] let ``SynExpr.Do contains the range of the do keyword`` () = From e8e01f796ec6f5abfeed3c8164e467c02dd90d72 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Sat, 10 Sep 2022 17:04:07 +0100 Subject: [PATCH 07/42] Working by walking the whole dotlambda and inserting the ident --- src/Compiler/Checking/CheckExpressions.fs | 6 ++++-- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 18 ++++++++++++++++++ src/Compiler/SyntaxTree/SyntaxTreeOps.fsi | 2 ++ .../BasicApplication/ThomasTest.fs | 2 +- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index d4990b71995..8423093037e 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5468,8 +5468,10 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) TcConstExpr cenv overallTy env m tpenv synConst | SynExpr.DotLambda (synExpr, m) -> - let svar = mkSynCompGenSimplePatVar (mkSynId m "unitVar") - let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ], m), synExpr, None, m, SynExprLambdaTrivia.Zero) + let unitVar = mkSynId m "unitVar" + let svar = mkSynCompGenSimplePatVar unitVar + let pushedExpr = pushUnitArg synExpr unitVar + let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ], m), pushedExpr, None, m, SynExprLambdaTrivia.Zero) TcIteratedLambdas cenv true env overallTy Set.empty tpenv lambda // TcIteratedLambda | SynExpr.Lambda _ -> diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 8e4cdbfa3ba..b9e03e22494 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -63,6 +63,24 @@ let mkSynSimplePatVar isOpt id = let mkSynCompGenSimplePatVar id = SynSimplePat.Id(id, None, true, false, false, id.idRange) +let rec pushUnitArg expr arg = + match expr with + | SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.Ident ident, x1, m1) + -> SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.LongIdent(false, SynLongIdent(arg::ident::[], [ident.idRange], [None]), None, ident.idRange), x1, m1) + | SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.LongIdent(isOptional, SynLongIdent(id, dotRanges, trivia), altNameRefCell, range), x1, m1) + -> SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.LongIdent(isOptional, SynLongIdent(arg::id, dotRanges, trivia), altNameRefCell, range), x1, m1) + | SynExpr.App(ExprAtomicFlag.Atomic, infix, (SynExpr.App(_) as innerApp), x1, m1) + -> SynExpr.App(ExprAtomicFlag.Atomic, infix, (pushUnitArg innerApp arg), x1, m1) + | SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet(synExpr, rangeOfDot, synLongIdent, range), x1, m1) + -> SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet((pushUnitArg synExpr arg), rangeOfDot, synLongIdent, range), x1, m1) + | SynExpr.Ident ident -> + SynExpr.LongIdent(false, SynLongIdent(arg::ident::[], [ident.idRange], [None]), None, ident.idRange) + | SynExpr.LongIdent(isOptional, SynLongIdent(id, dotRanges, trivia), altNameRefCell, range) + -> SynExpr.LongIdent(isOptional, SynLongIdent(arg::id, dotRanges, trivia), altNameRefCell, range) + | SynExpr.DotGet(synExpr, rangeOfDot, synLongIdent, range) -> + SynExpr.DotGet(pushUnitArg synExpr arg, rangeOfDot, synLongIdent, range) + | _ -> expr + // | SynExpr.App(ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) let (|SynSingleIdent|_|) x = match x with | SynLongIdent ([ id ], _, _) -> Some id diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi index 5af8180d05e..d5ab4b6b6fc 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi @@ -41,6 +41,8 @@ val mkSynSimplePatVar: isOpt: bool -> id: Ident -> SynSimplePat val mkSynCompGenSimplePatVar: id: Ident -> SynSimplePat +val pushUnitArg: expr: SynExpr -> arg: Ident -> SynExpr + /// Match a long identifier, including the case for single identifiers which gets a more optimized node in the syntax tree. val (|LongOrSingleIdent|_|): inp: SynExpr -> (bool * SynLongIdent * SynSimplePatAlternativeIdInfo ref option * range) option diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs index 1ae2217c7e5..b55b2373eb6 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs @@ -23,7 +23,7 @@ module ThomasTests = [] let ``Types`` () = Fsx """ -let a : (string -> _) = _.Length +let a : (string array -> _) = _.Length let b = _.ToString() let c = _.ToString().Length //let c = _.ToString()[0] From 669c365094a387328d9dd9b8aae103dad3a6bc12 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Thu, 15 Sep 2022 12:56:51 +0100 Subject: [PATCH 08/42] Temp remove tests --- .../FSharp.Compiler.ComponentTests.fsproj | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 00a05ac265f..4acda7d0cd7 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -69,7 +69,6 @@ - From 2c1b6b1c86b8973c842db98aebdea8a707a86a4e Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Wed, 21 Sep 2022 14:34:08 +0100 Subject: [PATCH 09/42] Fix hpa? --- src/Compiler/pars.fsy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 5c9c9cb420b..51ec58e5f21 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4309,7 +4309,7 @@ atomicExpr: | UNDERSCORE DOT atomicExpr %prec dot_lambda { let arg1 = lhs parseState let arg2, hpa = $3 - SynExpr.DotLambda(arg2, arg2.Range), hpa } + SynExpr.DotLambda(arg2, arg2.Range), false } | atomicExpr HIGH_PRECEDENCE_BRACK_APP atomicExpr { let arg1, _ = $1 From 8970bc550b0f132277938bed12b8adb70e6a32cc Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Wed, 21 Sep 2022 14:48:18 +0100 Subject: [PATCH 10/42] Add indexed get handling --- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index b9e03e22494..e8d5d854652 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -79,6 +79,8 @@ let rec pushUnitArg expr arg = -> SynExpr.LongIdent(isOptional, SynLongIdent(arg::id, dotRanges, trivia), altNameRefCell, range) | SynExpr.DotGet(synExpr, rangeOfDot, synLongIdent, range) -> SynExpr.DotGet(pushUnitArg synExpr arg, rangeOfDot, synLongIdent, range) + | SynExpr.DotIndexedGet(objectExpr, indexArgs, dotRange, range) -> + SynExpr.DotIndexedGet(pushUnitArg objectExpr arg, indexArgs, dotRange, range) | _ -> expr // | SynExpr.App(ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) let (|SynSingleIdent|_|) x = From 5448563f77b4981c022b780cbde06388cf6c5e7d Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Wed, 21 Sep 2022 14:58:06 +0100 Subject: [PATCH 11/42] Catch all case --- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index e8d5d854652..6a09ba5199a 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -73,6 +73,8 @@ let rec pushUnitArg expr arg = -> SynExpr.App(ExprAtomicFlag.Atomic, infix, (pushUnitArg innerApp arg), x1, m1) | SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet(synExpr, rangeOfDot, synLongIdent, range), x1, m1) -> SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet((pushUnitArg synExpr arg), rangeOfDot, synLongIdent, range), x1, m1) + | SynExpr.App(ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) -> + SynExpr.App(ExprAtomicFlag.Atomic, infix, pushUnitArg innerExpr arg, x1, m1) | SynExpr.Ident ident -> SynExpr.LongIdent(false, SynLongIdent(arg::ident::[], [ident.idRange], [None]), None, ident.idRange) | SynExpr.LongIdent(isOptional, SynLongIdent(id, dotRanges, trivia), altNameRefCell, range) From f373a84775a0eedaf5f97aa7f35f4934660aa68b Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Wed, 21 Sep 2022 14:59:30 +0100 Subject: [PATCH 12/42] Formatting --- src/Compiler/Service/ServiceParseTreeWalk.fs | 2 +- src/Compiler/SyntaxTree/SyntaxTree.fs | 6 +-- src/Compiler/SyntaxTree/SyntaxTree.fsi | 2 +- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 48 +++++++++++++------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index 7ca44ded455..47d8871972e 100755 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -656,7 +656,7 @@ module SyntaxTraversal = | SynExpr.DotGet (synExpr, _dotm, _longIdent, _range) -> traverseSynExpr synExpr | SynExpr.DotLambda _ -> None - + | SynExpr.Set (synExpr, synExpr2, _) | SynExpr.DotSet (synExpr, _, synExpr2, _) -> diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index 6928dbcae12..36d2f245c1b 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -610,9 +610,9 @@ type SynExpr = | LongIdentSet of longDotId: SynLongIdent * expr: SynExpr * range: range | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range - + | DotLambda of expr: SynExpr * range: range - + | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range | Set of targetExpr: SynExpr * rhsExpr: SynExpr * range: range @@ -750,7 +750,7 @@ type SynExpr = | SynExpr.DotIndexedGet (range = m) | SynExpr.DotIndexedSet (range = m) | SynExpr.DotGet (range = m) - | SynExpr.DotLambda (range=m) + | SynExpr.DotLambda (range = m) | SynExpr.DotSet (range = m) | SynExpr.Set (range = m) | SynExpr.DotNamedIndexedPropertySet (range = m) diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index b3e95ad0e26..b8075eef8d3 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -768,7 +768,7 @@ type SynExpr = /// F# syntax: _.ident.ident | DotLambda of expr: SynExpr * range: range - + /// F# syntax: expr.ident...ident <- expr | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 6a09ba5199a..2c7839167ac 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -65,26 +65,40 @@ let mkSynCompGenSimplePatVar id = let rec pushUnitArg expr arg = match expr with - | SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.Ident ident, x1, m1) - -> SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.LongIdent(false, SynLongIdent(arg::ident::[], [ident.idRange], [None]), None, ident.idRange), x1, m1) - | SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.LongIdent(isOptional, SynLongIdent(id, dotRanges, trivia), altNameRefCell, range), x1, m1) - -> SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.LongIdent(isOptional, SynLongIdent(arg::id, dotRanges, trivia), altNameRefCell, range), x1, m1) - | SynExpr.App(ExprAtomicFlag.Atomic, infix, (SynExpr.App(_) as innerApp), x1, m1) - -> SynExpr.App(ExprAtomicFlag.Atomic, infix, (pushUnitArg innerApp arg), x1, m1) - | SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet(synExpr, rangeOfDot, synLongIdent, range), x1, m1) - -> SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet((pushUnitArg synExpr arg), rangeOfDot, synLongIdent, range), x1, m1) - | SynExpr.App(ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) -> + | SynExpr.App (ExprAtomicFlag.Atomic, infix, SynExpr.Ident ident, x1, m1) -> + SynExpr.App( + ExprAtomicFlag.Atomic, + infix, + SynExpr.LongIdent(false, SynLongIdent(arg :: ident :: [], [ ident.idRange ], [ None ]), None, ident.idRange), + x1, + m1 + ) + | SynExpr.App (ExprAtomicFlag.Atomic, + infix, + SynExpr.LongIdent (isOptional, SynLongIdent (id, dotRanges, trivia), altNameRefCell, range), + x1, + m1) -> + SynExpr.App( + ExprAtomicFlag.Atomic, + infix, + SynExpr.LongIdent(isOptional, SynLongIdent(arg :: id, dotRanges, trivia), altNameRefCell, range), + x1, + m1 + ) + | SynExpr.App (ExprAtomicFlag.Atomic, infix, (SynExpr.App (_) as innerApp), x1, m1) -> + SynExpr.App(ExprAtomicFlag.Atomic, infix, (pushUnitArg innerApp arg), x1, m1) + | SynExpr.App (ExprAtomicFlag.Atomic, infix, SynExpr.DotGet (synExpr, rangeOfDot, synLongIdent, range), x1, m1) -> + SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet((pushUnitArg synExpr arg), rangeOfDot, synLongIdent, range), x1, m1) + | SynExpr.App (ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) -> SynExpr.App(ExprAtomicFlag.Atomic, infix, pushUnitArg innerExpr arg, x1, m1) - | SynExpr.Ident ident -> - SynExpr.LongIdent(false, SynLongIdent(arg::ident::[], [ident.idRange], [None]), None, ident.idRange) - | SynExpr.LongIdent(isOptional, SynLongIdent(id, dotRanges, trivia), altNameRefCell, range) - -> SynExpr.LongIdent(isOptional, SynLongIdent(arg::id, dotRanges, trivia), altNameRefCell, range) - | SynExpr.DotGet(synExpr, rangeOfDot, synLongIdent, range) -> - SynExpr.DotGet(pushUnitArg synExpr arg, rangeOfDot, synLongIdent, range) - | SynExpr.DotIndexedGet(objectExpr, indexArgs, dotRange, range) -> + | SynExpr.Ident ident -> SynExpr.LongIdent(false, SynLongIdent(arg :: ident :: [], [ ident.idRange ], [ None ]), None, ident.idRange) + | SynExpr.LongIdent (isOptional, SynLongIdent (id, dotRanges, trivia), altNameRefCell, range) -> + SynExpr.LongIdent(isOptional, SynLongIdent(arg :: id, dotRanges, trivia), altNameRefCell, range) + | SynExpr.DotGet (synExpr, rangeOfDot, synLongIdent, range) -> SynExpr.DotGet(pushUnitArg synExpr arg, rangeOfDot, synLongIdent, range) + | SynExpr.DotIndexedGet (objectExpr, indexArgs, dotRange, range) -> SynExpr.DotIndexedGet(pushUnitArg objectExpr arg, indexArgs, dotRange, range) | _ -> expr - // | SynExpr.App(ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) +// | SynExpr.App(ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) let (|SynSingleIdent|_|) x = match x with | SynLongIdent ([ id ], _, _) -> Some id From 1cde708c6b625e5b36e06d20cdfca7643b1e68fc Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Wed, 21 Sep 2022 15:11:54 +0100 Subject: [PATCH 13/42] Fixup tests --- ...erService.SurfaceArea.netstandard.expected | 33 ++++++++++--------- .../E_StaticCoercion_hole_as_left_arg.fsx | 7 ++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected index 6f38d493913..ca77b232a2d 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected @@ -1982,7 +1982,7 @@ FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FShar FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] GetDisplayContextForPos(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] ImplementationFile FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] get_ImplementationFile() -FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.ISourceText] GenerateSignature(Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.ISourceText] GenerateSignature() FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]] GetMethodsAsSymbols(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[System.String] GetF1Keyword(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: System.Collections.Generic.IEnumerable`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetAllUsesOfAllSymbolsInFile(Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) @@ -6342,6 +6342,10 @@ FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_lef FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range leftOfSetRange FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynLongIdent get_longDotId() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynLongIdent longDotId +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr argExpr FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_argExpr() FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_rhsExpr() @@ -6702,6 +6706,7 @@ FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DoBang FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotGet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotIndexedGet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotIndexedSet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotLambda FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotSet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Downcast @@ -6750,6 +6755,7 @@ FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Typar FSharp.Compiler.Syntax.SynExpr+Tags: Int32 TypeApp FSharp.Compiler.Syntax.SynExpr+Tags: Int32 TypeTest FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Typed +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Underscore FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Upcast FSharp.Compiler.Syntax.SynExpr+Tags: Int32 While FSharp.Compiler.Syntax.SynExpr+Tags: Int32 YieldOrReturn @@ -6824,6 +6830,8 @@ FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Syntax.SynType get_targetT FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Syntax.SynType targetType FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+Underscore: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+Underscore: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynExpr expr FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynExpr get_expr() FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynType get_targetType() @@ -6867,6 +6875,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean IsDoBang FSharp.Compiler.Syntax.SynExpr: Boolean IsDotGet FSharp.Compiler.Syntax.SynExpr: Boolean IsDotIndexedGet FSharp.Compiler.Syntax.SynExpr: Boolean IsDotIndexedSet +FSharp.Compiler.Syntax.SynExpr: Boolean IsDotLambda FSharp.Compiler.Syntax.SynExpr: Boolean IsDotNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr: Boolean IsDotSet FSharp.Compiler.Syntax.SynExpr: Boolean IsDowncast @@ -6915,6 +6924,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean IsTypar FSharp.Compiler.Syntax.SynExpr: Boolean IsTypeApp FSharp.Compiler.Syntax.SynExpr: Boolean IsTypeTest FSharp.Compiler.Syntax.SynExpr: Boolean IsTyped +FSharp.Compiler.Syntax.SynExpr: Boolean IsUnderscore FSharp.Compiler.Syntax.SynExpr: Boolean IsUpcast FSharp.Compiler.Syntax.SynExpr: Boolean IsWhile FSharp.Compiler.Syntax.SynExpr: Boolean IsYieldOrReturn @@ -6936,6 +6946,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDoBang() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotGet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotIndexedGet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotIndexedSet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotLambda() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotNamedIndexedPropertySet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotSet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDowncast() @@ -6984,6 +6995,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTypar() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTypeApp() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTypeTest() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTyped() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsUnderscore() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsUpcast() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsWhile() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsYieldOrReturn() @@ -7004,6 +7016,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp. FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotLambda(FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotNamedIndexedPropertySet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDowncast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) @@ -7052,6 +7065,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTypar(FSharp.C FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTypeApp(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTypeTest(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTyped(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewUnderscore(FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewUpcast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhile(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) @@ -7072,6 +7086,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DoBang FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotGet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotIndexedGet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotIndexedSet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotLambda FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotSet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Downcast @@ -7121,6 +7136,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Typar FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+TypeApp FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+TypeTest FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Typed +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Underscore FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Upcast FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+While FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+YieldOrReturn @@ -8517,16 +8533,6 @@ FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Syntax.SynType get_innerTy FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Syntax.SynType innerType FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Text.Range range -FSharp.Compiler.Syntax.SynType+SignatureParameter: Boolean get_optional() -FSharp.Compiler.Syntax.SynType+SignatureParameter: Boolean optional -FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Syntax.SynType get_usedType() -FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Syntax.SynType usedType -FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Text.Range get_range() -FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Text.Range range -FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes -FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() -FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_id() -FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] id FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Syntax.SynConst constant FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Syntax.SynConst get_constant() FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Text.Range get_range() @@ -8552,7 +8558,6 @@ FSharp.Compiler.Syntax.SynType+Tags: Int32 LongIdentApp FSharp.Compiler.Syntax.SynType+Tags: Int32 MeasureDivide FSharp.Compiler.Syntax.SynType+Tags: Int32 MeasurePower FSharp.Compiler.Syntax.SynType+Tags: Int32 Paren -FSharp.Compiler.Syntax.SynType+Tags: Int32 SignatureParameter FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstant FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantExpr FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantNamed @@ -8586,7 +8591,6 @@ FSharp.Compiler.Syntax.SynType: Boolean IsLongIdentApp FSharp.Compiler.Syntax.SynType: Boolean IsMeasureDivide FSharp.Compiler.Syntax.SynType: Boolean IsMeasurePower FSharp.Compiler.Syntax.SynType: Boolean IsParen -FSharp.Compiler.Syntax.SynType: Boolean IsSignatureParameter FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstant FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantExpr FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantNamed @@ -8604,7 +8608,6 @@ FSharp.Compiler.Syntax.SynType: Boolean get_IsLongIdentApp() FSharp.Compiler.Syntax.SynType: Boolean get_IsMeasureDivide() FSharp.Compiler.Syntax.SynType: Boolean get_IsMeasurePower() FSharp.Compiler.Syntax.SynType: Boolean get_IsParen() -FSharp.Compiler.Syntax.SynType: Boolean get_IsSignatureParameter() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstant() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantExpr() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantNamed() @@ -8622,7 +8625,6 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewLongIdentApp(F FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewMeasureDivide(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewMeasurePower(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynRationalConst, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewParen(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) -FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewSignatureParameter(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstant(FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantExpr(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantNamed(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) @@ -8640,7 +8642,6 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+LongIdentApp FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+MeasureDivide FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+MeasurePower FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Paren -FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+SignatureParameter FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstant FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantExpr FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantNamed diff --git a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_StaticCoercion_hole_as_left_arg.fsx b/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_StaticCoercion_hole_as_left_arg.fsx index d2c2dbf1fd0..6dc34ad1e0a 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_StaticCoercion_hole_as_left_arg.fsx +++ b/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_StaticCoercion_hole_as_left_arg.fsx @@ -2,11 +2,10 @@ // Negative tests on :> // Using _ as left argument -//Unexpected symbol '_' in expression$ -//Unmatched '\('$ -//Unexpected symbol '_' in binding$ +//Unexpected symbol ')' in expression. Expected '.' or other token.$ +//Unexpected symbol ':>' in expression. Expected '.' or other token.$ //Unmatched '\('$ -//Unexpected symbol '_' in binding$ +//Unexpected symbol ':>' in expression. Expected '.' or other token.$ //Unmatched '\('$ From 44abcb24d83a9a9f4b77e404a5a059135128c72f Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Wed, 21 Sep 2022 15:38:46 +0100 Subject: [PATCH 14/42] Fix area --- ...erService.SurfaceArea.netstandard.expected | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected index ca77b232a2d..9f4bffccbfb 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected @@ -1982,7 +1982,7 @@ FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FShar FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpDisplayContext] GetDisplayContextForPos(FSharp.Compiler.Text.Position) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] ImplementationFile FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Symbols.FSharpImplementationFileContents] get_ImplementationFile() -FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.ISourceText] GenerateSignature() +FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.ISourceText] GenerateSignature(Microsoft.FSharp.Core.FSharpOption`1[System.Int32]) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse]] GetMethodsAsSymbols(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: Microsoft.FSharp.Core.FSharpOption`1[System.String] GetF1Keyword(Int32, Int32, System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String]) FSharp.Compiler.CodeAnalysis.FSharpCheckFileResults: System.Collections.Generic.IEnumerable`1[FSharp.Compiler.CodeAnalysis.FSharpSymbolUse] GetAllUsesOfAllSymbolsInFile(Microsoft.FSharp.Core.FSharpOption`1[System.Threading.CancellationToken]) @@ -6342,8 +6342,8 @@ FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_lef FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range leftOfSetRange FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range range -FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynLongIdent get_longDotId() -FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynLongIdent longDotId +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynExpr get_expr() FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr argExpr @@ -6755,7 +6755,6 @@ FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Typar FSharp.Compiler.Syntax.SynExpr+Tags: Int32 TypeApp FSharp.Compiler.Syntax.SynExpr+Tags: Int32 TypeTest FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Typed -FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Underscore FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Upcast FSharp.Compiler.Syntax.SynExpr+Tags: Int32 While FSharp.Compiler.Syntax.SynExpr+Tags: Int32 YieldOrReturn @@ -6830,8 +6829,6 @@ FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Syntax.SynType get_targetT FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Syntax.SynType targetType FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynExpr+Typed: FSharp.Compiler.Text.Range range -FSharp.Compiler.Syntax.SynExpr+Underscore: FSharp.Compiler.Text.Range get_range() -FSharp.Compiler.Syntax.SynExpr+Underscore: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynExpr expr FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynExpr get_expr() FSharp.Compiler.Syntax.SynExpr+Upcast: FSharp.Compiler.Syntax.SynType get_targetType() @@ -6924,7 +6921,6 @@ FSharp.Compiler.Syntax.SynExpr: Boolean IsTypar FSharp.Compiler.Syntax.SynExpr: Boolean IsTypeApp FSharp.Compiler.Syntax.SynExpr: Boolean IsTypeTest FSharp.Compiler.Syntax.SynExpr: Boolean IsTyped -FSharp.Compiler.Syntax.SynExpr: Boolean IsUnderscore FSharp.Compiler.Syntax.SynExpr: Boolean IsUpcast FSharp.Compiler.Syntax.SynExpr: Boolean IsWhile FSharp.Compiler.Syntax.SynExpr: Boolean IsYieldOrReturn @@ -6995,7 +6991,6 @@ FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTypar() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTypeApp() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTypeTest() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsTyped() -FSharp.Compiler.Syntax.SynExpr: Boolean get_IsUnderscore() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsUpcast() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsWhile() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsYieldOrReturn() @@ -7016,7 +7011,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp. FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) -FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotLambda(FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotLambda(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotNamedIndexedPropertySet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDowncast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) @@ -7065,7 +7060,6 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTypar(FSharp.C FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTypeApp(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynType], Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Text.Range], Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range], FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTypeTest(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewTyped(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) -FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewUnderscore(FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewUpcast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewWhile(FSharp.Compiler.Syntax.DebugPointAtWhile, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewYieldOrReturn(System.Tuple`2[System.Boolean,System.Boolean], FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) @@ -7136,7 +7130,6 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Typar FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+TypeApp FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+TypeTest FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Typed -FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Underscore FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Upcast FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+While FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+YieldOrReturn @@ -8533,6 +8526,16 @@ FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Syntax.SynType get_innerTy FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Syntax.SynType innerType FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynType+Paren: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+SignatureParameter: Boolean get_optional() +FSharp.Compiler.Syntax.SynType+SignatureParameter: Boolean optional +FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Syntax.SynType get_usedType() +FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Syntax.SynType usedType +FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynType+SignatureParameter: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] attributes +FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList] get_attributes() +FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] get_id() +FSharp.Compiler.Syntax.SynType+SignatureParameter: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident] id FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Syntax.SynConst constant FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Syntax.SynConst get_constant() FSharp.Compiler.Syntax.SynType+StaticConstant: FSharp.Compiler.Text.Range get_range() @@ -8558,6 +8561,7 @@ FSharp.Compiler.Syntax.SynType+Tags: Int32 LongIdentApp FSharp.Compiler.Syntax.SynType+Tags: Int32 MeasureDivide FSharp.Compiler.Syntax.SynType+Tags: Int32 MeasurePower FSharp.Compiler.Syntax.SynType+Tags: Int32 Paren +FSharp.Compiler.Syntax.SynType+Tags: Int32 SignatureParameter FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstant FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantExpr FSharp.Compiler.Syntax.SynType+Tags: Int32 StaticConstantNamed @@ -8591,6 +8595,7 @@ FSharp.Compiler.Syntax.SynType: Boolean IsLongIdentApp FSharp.Compiler.Syntax.SynType: Boolean IsMeasureDivide FSharp.Compiler.Syntax.SynType: Boolean IsMeasurePower FSharp.Compiler.Syntax.SynType: Boolean IsParen +FSharp.Compiler.Syntax.SynType: Boolean IsSignatureParameter FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstant FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantExpr FSharp.Compiler.Syntax.SynType: Boolean IsStaticConstantNamed @@ -8608,6 +8613,7 @@ FSharp.Compiler.Syntax.SynType: Boolean get_IsLongIdentApp() FSharp.Compiler.Syntax.SynType: Boolean get_IsMeasureDivide() FSharp.Compiler.Syntax.SynType: Boolean get_IsMeasurePower() FSharp.Compiler.Syntax.SynType: Boolean get_IsParen() +FSharp.Compiler.Syntax.SynType: Boolean get_IsSignatureParameter() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstant() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantExpr() FSharp.Compiler.Syntax.SynType: Boolean get_IsStaticConstantNamed() @@ -8625,6 +8631,7 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewLongIdentApp(F FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewMeasureDivide(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewMeasurePower(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynRationalConst, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewParen(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewSignatureParameter(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.Syntax.SynAttributeList], Boolean, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Syntax.Ident], FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstant(FSharp.Compiler.Syntax.SynConst, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantExpr(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType NewStaticConstantNamed(FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) @@ -8642,6 +8649,7 @@ FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+LongIdentApp FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+MeasureDivide FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+MeasurePower FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+Paren +FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+SignatureParameter FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstant FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantExpr FSharp.Compiler.Syntax.SynType: FSharp.Compiler.Syntax.SynType+StaticConstantNamed From e25f16fb8df214c962630b4f089feb217e6d7cf7 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Thu, 22 Sep 2022 12:10:28 +0100 Subject: [PATCH 15/42] Tidy a little --- src/Compiler/Checking/CheckExpressions.fs | 7 +++---- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 12 ++++++------ src/Compiler/SyntaxTree/SyntaxTreeOps.fsi | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 8423093037e..b08b9632f10 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5468,12 +5468,11 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) TcConstExpr cenv overallTy env m tpenv synConst | SynExpr.DotLambda (synExpr, m) -> - let unitVar = mkSynId m "unitVar" - let svar = mkSynCompGenSimplePatVar unitVar - let pushedExpr = pushUnitArg synExpr unitVar + let unaryArg = mkSynId m (cenv.synArgNameGenerator.New()) + let svar = mkSynCompGenSimplePatVar unaryArg + let pushedExpr = pushUnaryArg synExpr unaryArg let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ], m), pushedExpr, None, m, SynExprLambdaTrivia.Zero) TcIteratedLambdas cenv true env overallTy Set.empty tpenv lambda - // TcIteratedLambda | SynExpr.Lambda _ -> TcIteratedLambdas cenv true env overallTy Set.empty tpenv synExpr diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 2c7839167ac..34bea67cda7 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -63,7 +63,7 @@ let mkSynSimplePatVar isOpt id = let mkSynCompGenSimplePatVar id = SynSimplePat.Id(id, None, true, false, false, id.idRange) -let rec pushUnitArg expr arg = +let rec pushUnaryArg expr arg = match expr with | SynExpr.App (ExprAtomicFlag.Atomic, infix, SynExpr.Ident ident, x1, m1) -> SynExpr.App( @@ -86,17 +86,17 @@ let rec pushUnitArg expr arg = m1 ) | SynExpr.App (ExprAtomicFlag.Atomic, infix, (SynExpr.App (_) as innerApp), x1, m1) -> - SynExpr.App(ExprAtomicFlag.Atomic, infix, (pushUnitArg innerApp arg), x1, m1) + SynExpr.App(ExprAtomicFlag.Atomic, infix, (pushUnaryArg innerApp arg), x1, m1) | SynExpr.App (ExprAtomicFlag.Atomic, infix, SynExpr.DotGet (synExpr, rangeOfDot, synLongIdent, range), x1, m1) -> - SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet((pushUnitArg synExpr arg), rangeOfDot, synLongIdent, range), x1, m1) + SynExpr.App(ExprAtomicFlag.Atomic, infix, SynExpr.DotGet((pushUnaryArg synExpr arg), rangeOfDot, synLongIdent, range), x1, m1) | SynExpr.App (ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) -> - SynExpr.App(ExprAtomicFlag.Atomic, infix, pushUnitArg innerExpr arg, x1, m1) + SynExpr.App(ExprAtomicFlag.Atomic, infix, pushUnaryArg innerExpr arg, x1, m1) | SynExpr.Ident ident -> SynExpr.LongIdent(false, SynLongIdent(arg :: ident :: [], [ ident.idRange ], [ None ]), None, ident.idRange) | SynExpr.LongIdent (isOptional, SynLongIdent (id, dotRanges, trivia), altNameRefCell, range) -> SynExpr.LongIdent(isOptional, SynLongIdent(arg :: id, dotRanges, trivia), altNameRefCell, range) - | SynExpr.DotGet (synExpr, rangeOfDot, synLongIdent, range) -> SynExpr.DotGet(pushUnitArg synExpr arg, rangeOfDot, synLongIdent, range) + | SynExpr.DotGet (synExpr, rangeOfDot, synLongIdent, range) -> SynExpr.DotGet(pushUnaryArg synExpr arg, rangeOfDot, synLongIdent, range) | SynExpr.DotIndexedGet (objectExpr, indexArgs, dotRange, range) -> - SynExpr.DotIndexedGet(pushUnitArg objectExpr arg, indexArgs, dotRange, range) + SynExpr.DotIndexedGet(pushUnaryArg objectExpr arg, indexArgs, dotRange, range) | _ -> expr // | SynExpr.App(ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) let (|SynSingleIdent|_|) x = diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi index d5ab4b6b6fc..755a03bf082 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fsi @@ -41,7 +41,7 @@ val mkSynSimplePatVar: isOpt: bool -> id: Ident -> SynSimplePat val mkSynCompGenSimplePatVar: id: Ident -> SynSimplePat -val pushUnitArg: expr: SynExpr -> arg: Ident -> SynExpr +val pushUnaryArg: expr: SynExpr -> arg: Ident -> SynExpr /// Match a long identifier, including the case for single identifiers which gets a more optimized node in the syntax tree. val (|LongOrSingleIdent|_|): From 6dbd7494a223fd904e557e2bcaf553b8cdcaff55 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Thu, 22 Sep 2022 15:19:51 +0100 Subject: [PATCH 16/42] Add a simple test --- .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../Language/DotLambdaTests.fs | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 4acda7d0cd7..1fe2f3628fb 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -169,6 +169,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs new file mode 100644 index 00000000000..e46fbd4aa89 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace FSharp.Compiler.ComponentTests.Language + +open Xunit +open FSharp.Test.Compiler + +module DotLambdaTests = + + [] + let ``Script: _.ToString()`` () = + Fsx "_.ToString()" + |> compile + |> shouldSucceed + + let ``Simple anonymous unary function shorthands compile`` () = + FSharp """ +module One +let a1 : {| Foo : {| Bar : string |}|} -> string = _.Foo.Bar +let a2 : {| Foo : int array |} -> int = _.Foo.[5] +let a3 : {| Foo : int array |} -> int = _.Foo[5] +let a4 : {| Foo : unit -> string |} -> string = _.Foo() +let a5 : {| Foo : int -> {| X : string |} |} -> string = _.Foo(5).X + +open System +let a6 = [1] |> List.map _.ToString() + """ + |> compile + |> shouldSucceed From ad0743b51badc2de911d6fa5907499c07f419aa7 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Thu, 22 Sep 2022 16:51:49 +0100 Subject: [PATCH 17/42] Add trivia and service test --- src/Compiler/Checking/CheckExpressions.fs | 2 +- src/Compiler/SyntaxTree/SyntaxTree.fs | 2 +- src/Compiler/SyntaxTree/SyntaxTree.fsi | 2 +- src/Compiler/SyntaxTree/SyntaxTrivia.fs | 7 ++++ src/Compiler/SyntaxTree/SyntaxTrivia.fsi | 8 +++++ src/Compiler/pars.fsy | 8 +++-- .../SyntaxTreeTests/ExpressionTests.fs | 35 ++++++++++++++----- 7 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index b08b9632f10..72e8448e62c 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5467,7 +5467,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE TcNonControlFlowExpr env <| fun env -> CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) TcConstExpr cenv overallTy env m tpenv synConst - | SynExpr.DotLambda (synExpr, m) -> + | SynExpr.DotLambda (synExpr, m, _) -> let unaryArg = mkSynId m (cenv.synArgNameGenerator.New()) let svar = mkSynCompGenSimplePatVar unaryArg let pushedExpr = pushUnaryArg synExpr unaryArg diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fs b/src/Compiler/SyntaxTree/SyntaxTree.fs index 36d2f245c1b..f75e92b47b5 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fs +++ b/src/Compiler/SyntaxTree/SyntaxTree.fs @@ -611,7 +611,7 @@ type SynExpr = | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range - | DotLambda of expr: SynExpr * range: range + | DotLambda of expr: SynExpr * range: range * trivia: SynExprDotLambdaTrivia | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range diff --git a/src/Compiler/SyntaxTree/SyntaxTree.fsi b/src/Compiler/SyntaxTree/SyntaxTree.fsi index b8075eef8d3..18dc34af44a 100644 --- a/src/Compiler/SyntaxTree/SyntaxTree.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTree.fsi @@ -767,7 +767,7 @@ type SynExpr = | DotGet of expr: SynExpr * rangeOfDot: range * longDotId: SynLongIdent * range: range /// F# syntax: _.ident.ident - | DotLambda of expr: SynExpr * range: range + | DotLambda of expr: SynExpr * range: range * trivia: SynExprDotLambdaTrivia /// F# syntax: expr.ident...ident <- expr | DotSet of targetExpr: SynExpr * longDotId: SynLongIdent * rhsExpr: SynExpr * range: range diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs index 1b03d20b615..cee917e457b 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs @@ -75,6 +75,13 @@ type SynExprLambdaTrivia = static member Zero: SynExprLambdaTrivia = { ArrowRange = None } +[] +type SynExprDotLambdaTrivia = + { + UnderscoreRange : range + DotRange : range + } + [] type SynExprLetOrUseTrivia = { InKeyword: range option } diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi index fbdf8ecf30e..bb9cfc307e7 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi @@ -119,6 +119,14 @@ type SynExprLambdaTrivia = static member Zero: SynExprLambdaTrivia +/// Represents additional information for SynExpr.DotLambda +[] +type SynExprDotLambdaTrivia = + { + UnderscoreRange : range + DotRange : range + } + /// Represents additional information for SynExpr.LetOrUse [] type SynExprLetOrUseTrivia = diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 51ec58e5f21..f9748cf0d5d 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4307,9 +4307,11 @@ argExpr: atomicExpr: | UNDERSCORE DOT atomicExpr %prec dot_lambda - { let arg1 = lhs parseState - let arg2, hpa = $3 - SynExpr.DotLambda(arg2, arg2.Range), false } + { let arg1 = rhs parseState 1 + let arg2 = rhs parseState 2 + let arg3, hpa = $3 + let trivia: SynExprDotLambdaTrivia = { UnderscoreRange = arg1; DotRange = arg2 } + SynExpr.DotLambda(arg3, unionRanges arg1 arg3.Range, trivia), false } | atomicExpr HIGH_PRECEDENCE_BRACK_APP atomicExpr { let arg1, _ = $1 diff --git a/tests/service/SyntaxTreeTests/ExpressionTests.fs b/tests/service/SyntaxTreeTests/ExpressionTests.fs index 5a44f95c013..965ebc13326 100644 --- a/tests/service/SyntaxTreeTests/ExpressionTests.fs +++ b/tests/service/SyntaxTreeTests/ExpressionTests.fs @@ -4,15 +4,6 @@ open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Syntax open FSharp.Compiler.SyntaxTrivia open NUnit.Framework - -open Xunit -// [] -// let ``Thomas`` () = - // let ast = """_.ToString.ToString "b" """ |> getParseResults - // let ast = """_.x""" |> getParseResults - // let ast = """_.x()""" |> getParseResults - // Assert.Fail (ast.ToString()) - [] let ``SynExpr.Do contains the range of the do keyword`` () = let ast = """let a = @@ -502,3 +493,29 @@ type CFoo() = assertRange (7,4) (7, 67) m | _ -> Assert.Fail $"Could not get valid AST, got {ast}" +[] +let ``SynExpr.DotLambda has correct ranges and trivia`` () = + let ast = + getParseResults """ +let e1 : obj [] -> string = _(*test*).(*test*)[5].ToString() +""" + + match ast with + | ParsedInput.ImplFile(ParsedImplFileInput(contents = [ + SynModuleOrNamespace.SynModuleOrNamespace(decls = [ + SynModuleDecl.Let(bindings = + [SynBinding.SynBinding(expr = + SynExpr.Typed(expr = + SynExpr.DotLambda( + SynExpr.App(range = innerRange), + dlRange, + { UnderscoreRange = urange; DotRange = dRange } + )))]) + ]) + ])) -> + assertRange (2, 28) (2, 60) dlRange + assertRange (2, 28) (2, 29) urange + assertRange (2, 37) (2, 38) dRange + assertRange (2, 46) (2, 60) innerRange + Assert.Pass() + | _ -> Assert.Fail $"Could not get valid AST, got {ast}" From 605d228631f38c60f258b3440731074b509bd783 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Fri, 23 Sep 2022 10:37:21 +0100 Subject: [PATCH 18/42] Update and add test --- .../Language/DotLambdaTests.fs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index e46fbd4aa89..6e5f664327d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -13,6 +13,7 @@ module DotLambdaTests = |> compile |> shouldSucceed + [] let ``Simple anonymous unary function shorthands compile`` () = FSharp """ module One @@ -27,3 +28,12 @@ let a6 = [1] |> List.map _.ToString() """ |> compile |> shouldSucceed + + [] + let ``Nested anonymous unary function shorthands compile`` () = + FSharp """ +module One +let a : string = {| Inner = (fun x -> x.ToString()) |} |> _.Inner([5] |> _.[0]) + """ + |> compile + |> shouldSucceed \ No newline at end of file From e6087a06f71bb8fc4456d6d9d92f833bef4a3df5 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Fri, 23 Sep 2022 14:47:11 +0100 Subject: [PATCH 19/42] Add a warning for wildcard conflicts --- src/Compiler/Checking/CheckExpressions.fs | 5 ++++- src/Compiler/FSComp.txt | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 +++++ .../Language/DotLambdaTests.fs | 13 ++++++++++++- 16 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 72e8448e62c..4426e5ab246 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5467,7 +5467,10 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE TcNonControlFlowExpr env <| fun env -> CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) TcConstExpr cenv overallTy env m tpenv synConst - | SynExpr.DotLambda (synExpr, m, _) -> + | SynExpr.DotLambda (synExpr, m, trivia) -> + if env.NameEnv.eUnqualifiedItems |> Map.exists(fun _ itemValue -> itemValue |> function |Item.Value _ when itemValue.DisplayNameCore.StartsWith("_") -> true |_ -> false) + then + warning(Error(FSComp.SR.tcAmbiguousDiscardDotLambda(), trivia.UnderscoreRange)) let unaryArg = mkSynId m (cenv.synArgNameGenerator.New()) let svar = mkSynCompGenSimplePatVar unaryArg let pushedExpr = pushUnaryArg synExpr unaryArg diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 64f0876b61d..dae2f3a9b05 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1653,3 +1653,4 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form" 3536,tcUsingInterfaceWithStaticAbstractMethodAsType,"'%s' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'." 3537,tcTraitHasMultipleSupportTypes,"The trait '%s' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance." 3545,tcMissingRequiredMembers,"The following required properties have to be initalized:%s" +3546,tcAmbiguousDiscardDotLambda,"Discard is ambiguous" \ No newline at end of file diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 8a1853a380f..5512bfff5cf 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -702,6 +702,11 @@ Sadu .NET SDK pro tento skript nešlo určit. Pokud se skript nachází v adresáři používajícím global.json, zkontrolujte, jestli je nainstalovaná odpovídající sada .NET SDK. Neočekávaná chyba {0}. + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Tento výraz má typ {0} a je kompatibilní pouze s typem {1} prostřednictvím nejednoznačného implicitního převodu. Zvažte použití explicitního volání op_Implicit. Použitelnými implicitními převody jsou: {2} diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index e96c8e1d3b2..8adb6511822 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -702,6 +702,11 @@ Das .NET SDK für dieses Skript konnte nicht ermittelt werden. Wenn sich das Skript in einem Verzeichnis mit "global.json" befindet, stellen Sie sicher, dass das entsprechende .NET SDK installiert ist. Unerwarteter Fehler: {0}. + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Dieser Ausdruck weist den Typ "{0}" auf und wird nur durch eine mehrdeutige implizite Konvertierung mit dem Typ "{1}" kompatibel gemacht. Erwägen Sie die Verwendung eines expliziten Aufrufs an "op_Implicit". Die anwendbaren impliziten Konvertierungen sind: {2} diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 8c034062331..aa83d79517a 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -702,6 +702,11 @@ No se pudo determinar el SDK de .NET para este script. Si el script está en un directorio que usa una instancia de "global.json", asegúrese de que el SDK de .NET pertinente esté instalado. Error inesperado: "{0}". + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Esta expresión tiene el tipo "{0}" y solo se hace compatible con el tipo "{1}" mediante una conversión implícita ambigua. Considere la posibilidad de usar una llamada explícita a 'op_Implicit'. Las conversiones implícitas aplicables son:{2} diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index ab6345e8e0c..128f5040c1c 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -702,6 +702,11 @@ Le kit SDK .NET de ce script n'a pas pu être déterminé. Si le script se trouve dans un répertoire utilisant un fichier 'global.json', vérifiez que le kit SDK .NET approprié est installé. Erreur inattendue '{0}'. + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Cette expression a le type « {0} » et est uniquement compatible avec le type « {1} » via une conversion implicite ambiguë. Envisagez d’utiliser un appel explicite à’op_Implicit'. Les conversions implicites applicables sont : {2} diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 85a4a4cd333..dc4799e46a3 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -702,6 +702,11 @@ Non è stato possibile determinare la versione di .NET SDK per questo script. Se lo script si trova in una directory che usa un file 'global.json', assicurarsi che sia installata la versione pertinente di .NET SDK. Errore imprevisto: '{0}'. + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Questa espressione di tipo '{0}' è resa compatibile con il tipo '{1}' solo tramite una conversione implicita ambigua. Provare a usare una chiamata esplicita a 'op_Implicit'. Le conversioni implicite applicabili sono: {2} diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 1a49a44350e..91669d8e551 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -702,6 +702,11 @@ このスクリプトの .NET SDK を特定できませんでした。このスクリプトが、'global.json' が使用されているディレクトリにある場合は、関連する .NET SDK がインストールされていることを確認してください。予期しないエラー '{0}'。 + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} この式の型は '{0}' であり、あいまいで暗黙的な変換によってのみ、型 '{1}' と互換性を持たせることが可能です。' op_Implicit' の明示的な呼び出しを使用することを検討してください。該当する暗黙的な変換は次のとおりです: {2} diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 1a4cb6964d8..a97d81ba8c8 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -702,6 +702,11 @@ 이 스크립트에 대한 .NET SDK를 확인할 수 없습니다. 스크립트가 'global.json'을 사용하는 디렉터리에 있는 경우 관련 .NET SDK가 설치되어 있는지 확인하세요. 예기치 않은 오류 '{0}'. + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} 이 식은 ‘{0}’ 형식이며 모호한 암시적 변환을 통해 ‘{1}’ 형식하고만 호환됩니다. ‘op_Implicit’에 대한 명시적 호출을 사용하십시오. 해당하는 암시적 변환은 ‘{2}’입니다. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 1cc8dfb88f1..de043b79117 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -702,6 +702,11 @@ Nie można określić zestawu .NET SDK dla tego skryptu. Jeśli skrypt znajduje się w katalogu korzystającym z pliku „global.json”, upewnij się, że zainstalowano odpowiedni zestaw .NET SDK. Nieoczekiwany błąd: „{0}”. + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} To wyrażenie ma typ "{0}" i jest zgodne tylko z typem "{1}" za pośrednictwem niejednoznacznie bezwarunkowej konwersji. Rozważ użycie jednoznacznego wywołania elementu "op_Implicit". Odpowiednimi jednoznacznymi konwersjami są: {2} diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 1c898a6234e..680b285a3e1 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -702,6 +702,11 @@ Não foi possível determinar o SDK do .NET deste script. Se o script estiver em um diretório que usa um 'global.json', verifique se o SDK do .NET relevante está instalado. Erro inesperado '{0}'. + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Essa expressão possui o tipo '{0}' e só é compatível com o tipo '{1}' por uma conversão implícita ambígua. Considere usar uma chamada explícita para 'op_Implicit'. As conversões implícitas aplicáveis são:{2} diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index b9094d89e3f..3a19a553e4c 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -702,6 +702,11 @@ Не удалось определить пакет SDK .NET для этого скрипта. Если сценарий находится в каталоге с использованием файла "global.json", убедитесь, что установлен соответствующий пакет SDK .NET. Непредвиденная ошибка "{0}". + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Это выражение имеет тип "{0}" и совместимо только с типом "{1}" посредством неоднозначного неявного преобразования. Рассмотрите возможность использования явного вызова "op_Implicit". Применимые неявные преобразования: {2} diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 7ee5a8cb3bc..f5ec4b7f1ee 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -702,6 +702,11 @@ Bu betik için .NET SDK belirlenemedi. Betik 'global.json' kullanan bir dizindeyse, ilgili .NET SDK'nın yüklü olduğundan emin olun. Beklenmeyen hata '{0}'. + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} Bu ifade '{0}' türüne sahip ve yalnızca belirsiz bir örtük dönüştürme aracılığıyla ’{1}' türüyle uyumlu hale getirilir. 'op_Implicit' için açık bir çağrı kullanmayı düşünün. Uygulanabilir örtük dönüştürmeler şunlardır: {2} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 2659f03165a..62c8290d77d 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -702,6 +702,11 @@ 无法确定此脚本的 .NET SDK。如果脚本在使用 "global.json" 的目录中,请确保已安装相关的 .NET SDK。出现意外错误“{0}”。 + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} 此表达式的类型为“{0}”,仅可通过不明确的隐式转换使其与类型“{1}”兼容。请考虑使用显式调用“op_Implicit”。适用的隐式转换为: {2} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index f7f06f543fc..29766e55593 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -702,6 +702,11 @@ 無法判斷這個指令碼的 .NET SDK。如果指令碼位於使用 'global.json' 的目錄中,請確認已安裝相關的 .NET SDK。未預期的錯誤 '{0}'。 + + Discard is ambiguous + Discard is ambiguous + + This expression has type '{0}' and is only made compatible with type '{1}' through an ambiguous implicit conversion. Consider using an explicit call to 'op_Implicit'. The applicable implicit conversions are:{2} 此運算式的類型為 '{0}',僅可透過不明確的隱含轉換使其與類型 '{1}' 相容。請考慮使用明確呼叫 'op_Implicit'。適用的隱含轉換為: {2} diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index 6e5f664327d..d1bd1c00dd9 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -36,4 +36,15 @@ module One let a : string = {| Inner = (fun x -> x.ToString()) |} |> _.Inner([5] |> _.[0]) """ |> compile - |> shouldSucceed \ No newline at end of file + |> shouldSucceed + + [] + let ``Anonymous unary function shorthand with conflicting wild argument`` () = + FSharp """ +module One +let a : string -> string = (fun _ -> 5 |> _.ToString()) +let b : int -> int -> string = function |5 -> (fun _ -> "Five") |_ -> _.ToString() + """ + |> compile + |> shouldFail + |> withSingleDiagnostic (Warning 3546, Line 3, Col 43, Line 3, Col 44, "Discard is ambiguous") \ No newline at end of file From 7b397684a9f7347fd739deabb6434b37f0185320 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Fri, 23 Sep 2022 14:48:16 +0100 Subject: [PATCH 20/42] Format --- src/Compiler/SyntaxTree/SyntaxTrivia.fs | 4 ++-- src/Compiler/SyntaxTree/SyntaxTrivia.fsi | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fs b/src/Compiler/SyntaxTree/SyntaxTrivia.fs index cee917e457b..161403a1f09 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fs +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fs @@ -78,8 +78,8 @@ type SynExprLambdaTrivia = [] type SynExprDotLambdaTrivia = { - UnderscoreRange : range - DotRange : range + UnderscoreRange: range + DotRange: range } [] diff --git a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi index bb9cfc307e7..c481af5689b 100644 --- a/src/Compiler/SyntaxTree/SyntaxTrivia.fsi +++ b/src/Compiler/SyntaxTree/SyntaxTrivia.fsi @@ -122,11 +122,9 @@ type SynExprLambdaTrivia = /// Represents additional information for SynExpr.DotLambda [] type SynExprDotLambdaTrivia = - { - UnderscoreRange : range - DotRange : range - } - + { UnderscoreRange: range + DotRange: range } + /// Represents additional information for SynExpr.LetOrUse [] type SynExprLetOrUseTrivia = From 927df170001e7801dddef06311f940e819e71dc2 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Fri, 23 Sep 2022 15:28:11 +0100 Subject: [PATCH 21/42] Update tests --- .../Language/DotLambdaTests.fs | 4 +++- ...p.CompilerService.SurfaceArea.netstandard.expected | 11 ++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index d1bd1c00dd9..f84df73692d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -36,7 +36,8 @@ module One let a : string = {| Inner = (fun x -> x.ToString()) |} |> _.Inner([5] |> _.[0]) """ |> compile - |> shouldSucceed + |> shouldFail + |> withSingleDiagnostic (Warning 3546, Line 3, Col 75, Line 3, Col 76, "Discard is ambiguous") [] let ``Anonymous unary function shorthand with conflicting wild argument`` () = @@ -44,6 +45,7 @@ let a : string = {| Inner = (fun x -> x.ToString()) |} |> _.Inner([5] |> _.[0]) module One let a : string -> string = (fun _ -> 5 |> _.ToString()) let b : int -> int -> string = function |5 -> (fun _ -> "Five") |_ -> _.ToString() +let c : string = let _ = "test" in "asd" |> _.ToString() """ |> compile |> shouldFail diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected index 9f4bffccbfb..f67a7b01ea2 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected @@ -6344,6 +6344,8 @@ FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range leftOfS FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynExpr expr FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia get_trivia() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia trivia FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr argExpr @@ -7011,7 +7013,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp. FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) -FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotLambda(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotLambda(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotNamedIndexedPropertySet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDowncast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) @@ -9429,6 +9431,13 @@ FSharp.Compiler.SyntaxTrivia.SynExprAndBangTrivia: Microsoft.FSharp.Core.FSharpO FSharp.Compiler.SyntaxTrivia.SynExprAndBangTrivia: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range] get_InKeyword() FSharp.Compiler.SyntaxTrivia.SynExprAndBangTrivia: System.String ToString() FSharp.Compiler.SyntaxTrivia.SynExprAndBangTrivia: Void .ctor(FSharp.Compiler.Text.Range, Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.Text.Range]) +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range DotRange +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range UnderscoreRange +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range get_DotRange() +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range get_UnderscoreRange() +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: System.String ToString() +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: Void .ctor(FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.SyntaxTrivia.SynExprIfThenElseTrivia FSharp.Compiler.SyntaxTrivia.SynExprIfThenElseTrivia: Boolean IsElif FSharp.Compiler.SyntaxTrivia.SynExprIfThenElseTrivia: Boolean get_IsElif() From deab1b6d1e379b0b4482412f6c28bc3f54536573 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Sat, 24 Sep 2022 15:33:23 +0100 Subject: [PATCH 22/42] Try and add lang feature --- src/Compiler/FSComp.txt | 3 ++- src/Compiler/Facilities/LanguageFeatures.fs | 3 +++ src/Compiler/Facilities/LanguageFeatures.fsi | 1 + src/Compiler/pars.fsy | 5 ++++- src/Compiler/xlf/FSComp.txt.cs.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.de.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.es.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.fr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.it.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ja.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ko.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pl.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.ru.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.tr.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 5 +++++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 5 +++++ .../Language/DotLambdaTests.fs | 7 +++++++ 18 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index dae2f3a9b05..ec00a65e1a9 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1653,4 +1653,5 @@ reprStateMachineInvalidForm,"The state machine has an unexpected form" 3536,tcUsingInterfaceWithStaticAbstractMethodAsType,"'%s' is normally used as a type constraint in generic code, e.g. \"'T when ISomeInterface<'T>\" or \"let f (x: #ISomeInterface<_>)\". See https://aka.ms/fsharp-iwsams for guidance. You can disable this warning by using '#nowarn \"3536\"' or '--nowarn:3536'." 3537,tcTraitHasMultipleSupportTypes,"The trait '%s' invoked by this call has multiple support types. This invocation syntax is not permitted for such traits. See https://aka.ms/fsharp-srtp for guidance." 3545,tcMissingRequiredMembers,"The following required properties have to be initalized:%s" -3546,tcAmbiguousDiscardDotLambda,"Discard is ambiguous" \ No newline at end of file +3546,tcAmbiguousDiscardDotLambda,"Discard is ambiguous" +featureAccessorFunctionShorthand,"underscore dot shorthand for accessor only function" \ No newline at end of file diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 07bcca57870..bfbf325c65a 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -54,6 +54,7 @@ type LanguageFeature = | LowercaseDUWhenRequireQualifiedAccess | InterfacesWithAbstractStaticMembers | SelfTypeConstraints + | AccessorFunctionShorthand /// LanguageVersion management type LanguageVersion(versionText) = @@ -124,6 +125,7 @@ type LanguageVersion(versionText) = // F# preview LanguageFeature.FromEndSlicing, previewVersion + LanguageFeature.AccessorFunctionShorthand, previewVersion ] static let defaultLanguageVersion = LanguageVersion("default") @@ -230,6 +232,7 @@ type LanguageVersion(versionText) = | LanguageFeature.LowercaseDUWhenRequireQualifiedAccess -> FSComp.SR.featureLowercaseDUWhenRequireQualifiedAccess () | LanguageFeature.InterfacesWithAbstractStaticMembers -> FSComp.SR.featureInterfacesWithAbstractStaticMembers () | LanguageFeature.SelfTypeConstraints -> FSComp.SR.featureSelfTypeConstraints () + | LanguageFeature.AccessorFunctionShorthand -> FSComp.SR.featureAccessorFunctionShorthand () /// Get a version string associated with the given feature. static member GetFeatureVersionString feature = diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index cb7991392c1..70b8e6a3edc 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -44,6 +44,7 @@ type LanguageFeature = | LowercaseDUWhenRequireQualifiedAccess | InterfacesWithAbstractStaticMembers | SelfTypeConstraints + | AccessorFunctionShorthand /// LanguageVersion management type LanguageVersion = diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index f9748cf0d5d..e429551f1f1 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4307,7 +4307,10 @@ argExpr: atomicExpr: | UNDERSCORE DOT atomicExpr %prec dot_lambda - { let arg1 = rhs parseState 1 + { parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AccessorFunctionShorthand (rhs parseState 2) + //{ if not (parseState.LexBuffer.SupportsFeature LanguageFeature.AccessorFunctionShorthand) then + // raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedSymbolDot()) + let arg1 = rhs parseState 1 let arg2 = rhs parseState 2 let arg3, hpa = $3 let trivia: SynExprDotLambdaTrivia = { UnderscoreRange = arg1; DotRange = arg2 } diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 5512bfff5cf..2fff0ed28e0 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -117,6 +117,11 @@ Atribut sestavení {0} odkazuje na navržené sestavení {1}, které se nedá načíst nebo neexistuje. Ohlášená výjimka: {2} – {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions další převody orientované na typ diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 8adb6511822..9dbd3499b35 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -117,6 +117,11 @@ Das Assemblyattribut "{0}" verweist auf eine Designerassembly "{1}", die entweder nicht geladen werden kann oder nicht vorhanden ist. Gemeldete Ausnahme: {2} – {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions zusätzliche typgesteuerte Konvertierungen diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index aa83d79517a..7fd6b4f7780 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -117,6 +117,11 @@ El atributo de ensamblado "{0}" hace referencia a un ensamblado de diseñador "{1}" que no se puede cargar o no existe. Se notificó la excepción: {2} - {3}. + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions conversiones adicionales dirigidas a tipos diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 128f5040c1c..249e5a3f50d 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -117,6 +117,11 @@ L'attribut d'assembly '{0}' fait référence à un assembly de concepteur '{1}' qui ne peut pas être chargé ou qui n'existe pas. Exception signalée : {2} - {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions conversions supplémentaires dirigées vers le type diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index dc4799e46a3..12b42fad29e 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -117,6 +117,11 @@ L'attributo di assembly '{0}' fa riferimento a un assembly '{1}' della finestra di progettazione che non è stato caricato o non esiste. L'eccezione restituita è {2} - {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions conversioni aggiuntive dirette ai tipi diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 91669d8e551..df39c58f63e 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -117,6 +117,11 @@ アセンブリ属性 '{0}' は、デザイナー アセンブリ '{1}' を参照していますが、これは読み込むことができないか、存在していません。報告された例外: {2} - {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions その他の型指定された変換 diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index a97d81ba8c8..be75afa444b 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -117,6 +117,11 @@ '{0}' 어셈블리 특성이 로드할 수 없거나 존재하지 않는 디자이너 어셈블리'{1}'을(를) 참조합니다. 보고된 예외: {2} - {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions 추가 형식-디렉션 변환 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index de043b79117..2c1b0fbffaa 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -117,6 +117,11 @@ Atrybut zestawu „{0}” odwołuje się do zestawu projektanta „{1}”, którego nie można załadować lub który nie istnieje. Zgłoszony wyjątek: {2} — {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions dodatkowe konwersje ukierunkowane na typ diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 680b285a3e1..175e5d7dd4f 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -117,6 +117,11 @@ O atributo de assembly '{0}' refere-se a um assembly de designer '{1}' que não pode ser carregado ou que não existe. A exceção relatada foi {2} – {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions conversões direcionadas por tipos adicionais diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 3a19a553e4c..9957778a1a9 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -117,6 +117,11 @@ Атрибут сборки "{0}" ссылается на сборку конструктора "{1}", которая не может быть загружена или не существует. Получено исключение: {2} — {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions дополнительные преобразования на основе типа diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index f5ec4b7f1ee..a98472ee9d3 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -117,6 +117,11 @@ '{0}' bütünleştirilmiş kod özniteliği, yüklenemeyen veya mevcut olmayan '{1}' tasarımcı bütünleştirilmiş koduna başvuruyor. Bildirilen özel durum: {2} - {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions ek tür ile yönlendirilen dönüştürmeler diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 62c8290d77d..7816ab0b3f1 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -117,6 +117,11 @@ 程序集属性“{0}”引用了无法加载或不存在的设计器程序集“{1}”。报告的异常是: {2} - {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions 附加类型定向转换 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 29766e55593..8d738c0029f 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -117,6 +117,11 @@ 無法載入組件屬性 '{0}' 參考的設計工具組件 '{1}' 或其不存在。回報的例外狀況: {2} - {3} + + underscore dot shorthand for accessor only function + underscore dot shorthand for accessor only function + + additional type-directed conversions 其他類型導向轉換 diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index f84df73692d..fc3bb821428 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -13,6 +13,13 @@ module DotLambdaTests = |> compile |> shouldSucceed + [] + let ``Script: _.ToString(), old lang version`` () = + Fsx "_.ToString()" + |> withLangVersion70 + |> compile + |> shouldSucceed + [] let ``Simple anonymous unary function shorthands compile`` () = FSharp """ From f1e627e3d0cbd82a08bc02313857fdcdfc2cb1e5 Mon Sep 17 00:00:00 2001 From: Thomas Boby Date: Sat, 24 Sep 2022 16:30:21 +0100 Subject: [PATCH 23/42] Fix tests and improve diagnostic range --- src/Compiler/pars.fsy | 6 ++---- .../Language/DotLambdaTests.fs | 7 ++++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index e429551f1f1..5e30ebd6309 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4307,11 +4307,9 @@ argExpr: atomicExpr: | UNDERSCORE DOT atomicExpr %prec dot_lambda - { parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AccessorFunctionShorthand (rhs parseState 2) - //{ if not (parseState.LexBuffer.SupportsFeature LanguageFeature.AccessorFunctionShorthand) then - // raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnexpectedSymbolDot()) - let arg1 = rhs parseState 1 + { let arg1 = rhs parseState 1 let arg2 = rhs parseState 2 + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AccessorFunctionShorthand (unionRanges arg1 arg2) let arg3, hpa = $3 let trivia: SynExprDotLambdaTrivia = { UnderscoreRange = arg1; DotRange = arg2 } SynExpr.DotLambda(arg3, unionRanges arg1 arg3.Range, trivia), false } diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index fc3bb821428..45892f6e35e 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -10,6 +10,7 @@ module DotLambdaTests = [] let ``Script: _.ToString()`` () = Fsx "_.ToString()" + |> withLangVersionPreview |> compile |> shouldSucceed @@ -18,7 +19,8 @@ module DotLambdaTests = Fsx "_.ToString()" |> withLangVersion70 |> compile - |> shouldSucceed + |> shouldFail + |> withSingleDiagnostic (Error 3350, Line 1, Col 1, Line 1, Col 3, "Feature 'underscore dot shorthand for accessor only function' is not available in F# 7.0. Please use language version 'PREVIEW' or greater." ) [] let ``Simple anonymous unary function shorthands compile`` () = @@ -33,6 +35,7 @@ let a5 : {| Foo : int -> {| X : string |} |} -> string = _.Foo(5).X open System let a6 = [1] |> List.map _.ToString() """ + |> withLangVersionPreview |> compile |> shouldSucceed @@ -42,6 +45,7 @@ let a6 = [1] |> List.map _.ToString() module One let a : string = {| Inner = (fun x -> x.ToString()) |} |> _.Inner([5] |> _.[0]) """ + |> withLangVersionPreview |> compile |> shouldFail |> withSingleDiagnostic (Warning 3546, Line 3, Col 75, Line 3, Col 76, "Discard is ambiguous") @@ -54,6 +58,7 @@ let a : string -> string = (fun _ -> 5 |> _.ToString()) let b : int -> int -> string = function |5 -> (fun _ -> "Five") |_ -> _.ToString() let c : string = let _ = "test" in "asd" |> _.ToString() """ + |> withLangVersionPreview |> compile |> shouldFail |> withSingleDiagnostic (Warning 3546, Line 3, Col 43, Line 3, Col 44, "Discard is ambiguous") \ No newline at end of file From 799ba5ddee3d77e6b53b2f79b3bddb4c53fe0436 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jun 2023 11:16:22 +0200 Subject: [PATCH 24/42] Initial revival commit --- src/Compiler/Checking/CheckExpressions.fs | 2 +- .../Driver/GraphChecking/FileContentMapping.fs | 1 + src/Compiler/FSComp.txt | 3 +-- ....Service.SurfaceArea.netstandard20.debug.bsl | 17 +++++++++++++++++ ...ervice.SurfaceArea.netstandard20.release.bsl | 17 +++++++++++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 400cdae8ff7..eeefed9c393 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5526,7 +5526,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE let unaryArg = mkSynId m (cenv.synArgNameGenerator.New()) let svar = mkSynCompGenSimplePatVar unaryArg let pushedExpr = pushUnaryArg synExpr unaryArg - let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ], m), pushedExpr, None, m, SynExprLambdaTrivia.Zero) + let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ],[], m), pushedExpr, None, m, SynExprLambdaTrivia.Zero) TcIteratedLambdas cenv true env overallTy Set.empty tpenv lambda | SynExpr.Lambda _ -> TcIteratedLambdas cenv true env overallTy Set.empty tpenv synExpr diff --git a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs index b0b44e941fb..e4cf512ed80 100644 --- a/src/Compiler/Driver/GraphChecking/FileContentMapping.fs +++ b/src/Compiler/Driver/GraphChecking/FileContentMapping.fs @@ -362,6 +362,7 @@ let visitSynExpr (e: SynExpr) : FileContentEntry list = | SynExpr.IndexFromEnd (expr, _) -> visit expr continuation | SynExpr.ComputationExpr (expr = expr) -> visit expr continuation | SynExpr.Lambda (args = args; body = body) -> visit body (fun bodyNodes -> visitSynSimplePats args @ bodyNodes |> continuation) + | SynExpr.DotLambda (expr = expr) -> visit expr continuation | SynExpr.MatchLambda (matchClauses = clauses) -> List.collect visitSynMatchClause clauses |> continuation | SynExpr.Match (expr = expr; clauses = clauses) -> visit expr (fun exprNodes -> diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 042e33af0e2..997ab9515ed 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1699,5 +1699,4 @@ featureInformationalObjInferenceDiagnostic,"Diagnostic 3559 (warn when obj infer 3566,tcMultipleRecdTypeChoice,"Multiple type matches were found:\n%s\nThe type '%s' was used. Due to the overlapping field names\n%s\nconsider using type annotations or change the order of open statements." 3567,parsMissingMemberBody,"Expecting member body" 3570,tcAmbiguousDiscardDotLambda,"Discard is ambiguous" -featureAccessorFunctionShorthand,"underscore dot shorthand for accessor only function" - +featureAccessorFunctionShorthand,"underscore dot shorthand for accessor only function" \ No newline at end of file diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl index 5ba81eb678d..46b90763781 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.debug.bsl @@ -6318,6 +6318,12 @@ FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_lef FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range leftOfSetRange FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia get_trivia() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia trivia +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr argExpr FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_argExpr() FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_rhsExpr() @@ -6678,6 +6684,7 @@ FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DoBang FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotGet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotIndexedGet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotIndexedSet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotLambda FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotSet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Downcast @@ -6843,6 +6850,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean IsDoBang FSharp.Compiler.Syntax.SynExpr: Boolean IsDotGet FSharp.Compiler.Syntax.SynExpr: Boolean IsDotIndexedGet FSharp.Compiler.Syntax.SynExpr: Boolean IsDotIndexedSet +FSharp.Compiler.Syntax.SynExpr: Boolean IsDotLambda FSharp.Compiler.Syntax.SynExpr: Boolean IsDotNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr: Boolean IsDotSet FSharp.Compiler.Syntax.SynExpr: Boolean IsDowncast @@ -6912,6 +6920,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDoBang() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotGet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotIndexedGet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotIndexedSet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotLambda() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotNamedIndexedPropertySet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotSet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDowncast() @@ -6980,6 +6989,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp. FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotLambda(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotNamedIndexedPropertySet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDowncast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) @@ -7048,6 +7058,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DoBang FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotGet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotIndexedGet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotIndexedSet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotLambda FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotSet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Downcast @@ -9395,6 +9406,12 @@ FSharp.Compiler.SyntaxTrivia.SynExprAnonRecdTrivia: FSharp.Compiler.Text.Range O FSharp.Compiler.SyntaxTrivia.SynExprAnonRecdTrivia: FSharp.Compiler.Text.Range get_OpeningBraceRange() FSharp.Compiler.SyntaxTrivia.SynExprAnonRecdTrivia: System.String ToString() FSharp.Compiler.SyntaxTrivia.SynExprAnonRecdTrivia: Void .ctor(FSharp.Compiler.Text.Range) +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range DotRange +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range UnderscoreRange +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range get_DotRange() +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range get_UnderscoreRange() +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: System.String ToString() +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: Void .ctor(FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.SyntaxTrivia.SynExprIfThenElseTrivia: Boolean IsElif FSharp.Compiler.SyntaxTrivia.SynExprIfThenElseTrivia: Boolean get_IsElif() FSharp.Compiler.SyntaxTrivia.SynExprIfThenElseTrivia: FSharp.Compiler.Text.Range IfKeyword diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl index d464f63b50f..10ab5ac5e53 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.SurfaceArea.netstandard20.release.bsl @@ -6318,6 +6318,12 @@ FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_lef FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range get_range() FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range leftOfSetRange FSharp.Compiler.Syntax.SynExpr+DotIndexedSet: FSharp.Compiler.Text.Range range +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynExpr expr +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Syntax.SynExpr get_expr() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia get_trivia() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia trivia +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range get_range() +FSharp.Compiler.Syntax.SynExpr+DotLambda: FSharp.Compiler.Text.Range range FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr argExpr FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_argExpr() FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet: FSharp.Compiler.Syntax.SynExpr get_rhsExpr() @@ -6678,6 +6684,7 @@ FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DoBang FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotGet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotIndexedGet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotIndexedSet +FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotLambda FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 DotSet FSharp.Compiler.Syntax.SynExpr+Tags: Int32 Downcast @@ -6843,6 +6850,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean IsDoBang FSharp.Compiler.Syntax.SynExpr: Boolean IsDotGet FSharp.Compiler.Syntax.SynExpr: Boolean IsDotIndexedGet FSharp.Compiler.Syntax.SynExpr: Boolean IsDotIndexedSet +FSharp.Compiler.Syntax.SynExpr: Boolean IsDotLambda FSharp.Compiler.Syntax.SynExpr: Boolean IsDotNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr: Boolean IsDotSet FSharp.Compiler.Syntax.SynExpr: Boolean IsDowncast @@ -6912,6 +6920,7 @@ FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDoBang() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotGet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotIndexedGet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotIndexedSet() +FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotLambda() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotNamedIndexedPropertySet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDotSet() FSharp.Compiler.Syntax.SynExpr: Boolean get_IsDowncast() @@ -6980,6 +6989,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDoBang(FSharp. FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedGet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotIndexedSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotLambda(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range, FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotNamedIndexedPropertySet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDotSet(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynLongIdent, FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Text.Range) FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr NewDowncast(FSharp.Compiler.Syntax.SynExpr, FSharp.Compiler.Syntax.SynType, FSharp.Compiler.Text.Range) @@ -7048,6 +7058,7 @@ FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DoBang FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotGet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotIndexedGet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotIndexedSet +FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotLambda FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotNamedIndexedPropertySet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+DotSet FSharp.Compiler.Syntax.SynExpr: FSharp.Compiler.Syntax.SynExpr+Downcast @@ -9395,6 +9406,12 @@ FSharp.Compiler.SyntaxTrivia.SynExprAnonRecdTrivia: FSharp.Compiler.Text.Range O FSharp.Compiler.SyntaxTrivia.SynExprAnonRecdTrivia: FSharp.Compiler.Text.Range get_OpeningBraceRange() FSharp.Compiler.SyntaxTrivia.SynExprAnonRecdTrivia: System.String ToString() FSharp.Compiler.SyntaxTrivia.SynExprAnonRecdTrivia: Void .ctor(FSharp.Compiler.Text.Range) +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range DotRange +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range UnderscoreRange +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range get_DotRange() +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: FSharp.Compiler.Text.Range get_UnderscoreRange() +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: System.String ToString() +FSharp.Compiler.SyntaxTrivia.SynExprDotLambdaTrivia: Void .ctor(FSharp.Compiler.Text.Range, FSharp.Compiler.Text.Range) FSharp.Compiler.SyntaxTrivia.SynExprIfThenElseTrivia: Boolean IsElif FSharp.Compiler.SyntaxTrivia.SynExprIfThenElseTrivia: Boolean get_IsElif() FSharp.Compiler.SyntaxTrivia.SynExprIfThenElseTrivia: FSharp.Compiler.Text.Range IfKeyword From bec03ed8e7dbe1c781a6cb4e0298b290cfc2d9d2 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jun 2023 11:38:14 +0200 Subject: [PATCH 25/42] revive with failing tests --- .../BasicApplication/ThomasTest.fs | 133 +++++++++--------- .../FSharp.Compiler.ComponentTests.fsproj | 1 + .../Language/DotLambdaTests.fs | 2 +- 3 files changed, 68 insertions(+), 68 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs index b55b2373eb6..8cf3948ba84 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs @@ -1,83 +1,82 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.ComponentTests.Language +module Conformance.ThomasTests.UntilThingsAreFixed open System open Xunit open FSharp.Test.Compiler -module ThomasTests = - [] - let ``Passes`` () = - Fsx """ let x = 1 """ - |> compile - |> shouldSucceed +[] +let ``Passes`` () = + Fsx """ let x = 1 """ + |> typecheck + |> shouldSucceed - [] - let ``Fails`` () = - Fsx """let x = "a" in x |> _.ToString()""" - |> compile - |> shouldSucceed +[] +let ``Fails`` () = + Fsx """let x = "a" in x |> _.ToString()""" + |> typecheck + |> shouldSucceed - [] - let ``Types`` () = - Fsx """ +[] +let ``Types`` () = + Fsx """ let a : (string array -> _) = _.Length let b = _.ToString() let c = _.ToString().Length -//let c = _.ToString()[0] -""" - |> compile - |> shouldSucceed +//let c = _.ToString()[0] """ + |> typecheck + |> shouldSucceed - [] - let ``Failing`` () = - Fsx """ - let rec GenericHashParamObj (iec : IEqualityComparer) (x: obj) : int = - match x with - | null -> 0 - | (:? System.Array as a) -> - match a with - | :? (obj[]) as oa -> GenericHashObjArray iec oa - | :? (byte[]) as ba -> GenericHashByteArray ba - | :? (int[]) as ba -> GenericHashInt32Array ba - | :? (int64[]) as ba -> GenericHashInt64Array ba - | _ -> GenericHashArbArray iec a - | :? IStructuralEquatable as a -> - a.GetHashCode(iec) - | _ -> - x.GetHashCode() - """ |> compile |> shouldSucceed +[] +let ``Failing`` () = + Fsx """ + let rec GenericHashParamObj (iec : IEqualityComparer) (x: obj) : int = + match x with + | null -> 0 + | (:? System.Array as a) -> + match a with + | :? (obj[]) as oa -> GenericHashObjArray iec oa + | :? (byte[]) as ba -> GenericHashByteArray ba + | :? (int[]) as ba -> GenericHashInt32Array ba + | :? (int64[]) as ba -> GenericHashInt64Array ba + | _ -> GenericHashArbArray iec a + | :? IStructuralEquatable as a -> + a.GetHashCode(iec) + | _ -> + x.GetHashCode() + """ |> typecheck |> shouldSucceed - // - // [] - // let ``Fails2`` () = - // - // """ let x = "a" in a |> _.Length""" - // |> getParseResults -// [] -// let ``Regression: Empty Interpolated String properly typechecks with explicit type on binding`` () = -// Fsx """ let a:byte = $"string" """ -// |> compile -// |> shouldFail -// |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 24, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") -// -// [] -// let ``Interpolated String with hole properly typechecks with explicit type on binding`` () = -// Fsx """ let a:byte = $"strin{'g'}" """ -// |> compile -// |> shouldFail -// |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 28, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") -// -// [] -// let ``Interpolated String without holes properly typeckecks with explicit type on binding`` () = -// Fsx """ -// let a: obj = $"string" -// let b: System.IComparable = $"string" -// let c: System.IFormattable = $"string" -// """ -// |> compile -// |> shouldSucceed -// + +[] +let ``Fails2`` () = + Fsx """ let x = "a" in a |> _.Length""" + |> typecheck + |> shouldSucceed + +[] +let ``Regression: Empty Interpolated String properly typechecks with explicit type on binding`` () = + Fsx """ let a:byte = $"string" """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 24, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") + +[] +let ``Interpolated String with hole properly typechecks with explicit type on binding`` () = + Fsx """ let a:byte = $"strin{'g'}" """ + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 28, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") + +[] +let ``Interpolated String without holes properly typeckecks with explicit type on binding`` () = + Fsx """ +let a: obj = $"string" +let b: System.IComparable = $"string" +let c: System.IFormattable = $"string" + """ + |> typecheck + |> shouldSucceed + diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index b0e4501e6d7..51ab40fa248 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -70,6 +70,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index 45892f6e35e..17759d2b171 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -1,6 +1,6 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace FSharp.Compiler.ComponentTests.Language +namespace Language open Xunit open FSharp.Test.Compiler From d5be20b82fb797612c73ebb9a79a6fb967632cdd Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jun 2023 13:50:07 +0200 Subject: [PATCH 26/42] ambigous discard - 3570 error --- .../Language/DotLambdaTests.fs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index 17759d2b171..f24746d4748 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -11,14 +11,14 @@ module DotLambdaTests = let ``Script: _.ToString()`` () = Fsx "_.ToString()" |> withLangVersionPreview - |> compile + |> typecheck |> shouldSucceed [] let ``Script: _.ToString(), old lang version`` () = Fsx "_.ToString()" |> withLangVersion70 - |> compile + |> typecheck |> shouldFail |> withSingleDiagnostic (Error 3350, Line 1, Col 1, Line 1, Col 3, "Feature 'underscore dot shorthand for accessor only function' is not available in F# 7.0. Please use language version 'PREVIEW' or greater." ) @@ -36,7 +36,7 @@ open System let a6 = [1] |> List.map _.ToString() """ |> withLangVersionPreview - |> compile + |> typecheck |> shouldSucceed [] @@ -46,9 +46,9 @@ module One let a : string = {| Inner = (fun x -> x.ToString()) |} |> _.Inner([5] |> _.[0]) """ |> withLangVersionPreview - |> compile + |> typecheck |> shouldFail - |> withSingleDiagnostic (Warning 3546, Line 3, Col 75, Line 3, Col 76, "Discard is ambiguous") + |> withSingleDiagnostic (Warning 3570, Line 3, Col 75, Line 3, Col 76, "Discard is ambiguous") [] let ``Anonymous unary function shorthand with conflicting wild argument`` () = @@ -59,6 +59,6 @@ let b : int -> int -> string = function |5 -> (fun _ -> "Five") |_ -> _.ToString let c : string = let _ = "test" in "asd" |> _.ToString() """ |> withLangVersionPreview - |> compile + |> typecheck |> shouldFail - |> withSingleDiagnostic (Warning 3546, Line 3, Col 43, Line 3, Col 44, "Discard is ambiguous") \ No newline at end of file + |> withSingleDiagnostic (Warning 3570, Line 3, Col 43, Line 3, Col 44, "Discard is ambiguous") \ No newline at end of file From 5c3b26eb2562504bde61ca74e0002ff54a20c33c Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jun 2023 14:18:48 +0200 Subject: [PATCH 27/42] getting tests in shape --- .../BasicApplication/ThomasTest.fs | 51 +++++++++---------- .../Language/DotLambdaTests.fs | 4 +- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs index 8cf3948ba84..75784adf984 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs @@ -5,17 +5,13 @@ module Conformance.ThomasTests.UntilThingsAreFixed open System open Xunit open FSharp.Test.Compiler - - -[] -let ``Passes`` () = - Fsx """ let x = 1 """ - |> typecheck - |> shouldSucceed [] -let ``Fails`` () = - Fsx """let x = "a" in x |> _.ToString()""" +let ``Underscore Dot ToString`` () = + Fsx """ +let x = "a" |> _.ToString() +printfn "%s" x""" + |> withLangVersionPreview |> typecheck |> shouldSucceed @@ -26,39 +22,36 @@ let a : (string array -> _) = _.Length let b = _.ToString() let c = _.ToString().Length //let c = _.ToString()[0] """ + |> withLangVersionPreview |> typecheck |> shouldSucceed [] -let ``Failing`` () = +let ``Regression with an underscore using pattern match`` () = Fsx """ - let rec GenericHashParamObj (iec : IEqualityComparer) (x: obj) : int = - match x with - | null -> 0 - | (:? System.Array as a) -> - match a with - | :? (obj[]) as oa -> GenericHashObjArray iec oa - | :? (byte[]) as ba -> GenericHashByteArray ba - | :? (int[]) as ba -> GenericHashInt32Array ba - | :? (int64[]) as ba -> GenericHashInt64Array ba - | _ -> GenericHashArbArray iec a - | :? IStructuralEquatable as a -> - a.GetHashCode(iec) - | _ -> - x.GetHashCode() - """ |> typecheck |> shouldSucceed - +type MyDU = A | B +let process x = + match x with + | A -> 42 + | _ -> 43""" + |> typecheck + |> shouldSucceed [] -let ``Fails2`` () = - Fsx """ let x = "a" in a |> _.Length""" +let ``Underscore Dot Length on string`` () = + Fsx """ +let x = "a" |> _.Length +printfn "%i" x +""" + |> withLangVersionPreview |> typecheck |> shouldSucceed [] let ``Regression: Empty Interpolated String properly typechecks with explicit type on binding`` () = Fsx """ let a:byte = $"string" """ + |> withLangVersionPreview |> typecheck |> shouldFail |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 24, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") @@ -66,6 +59,7 @@ let ``Regression: Empty Interpolated String properly typechecks with explicit ty [] let ``Interpolated String with hole properly typechecks with explicit type on binding`` () = Fsx """ let a:byte = $"strin{'g'}" """ + |> withLangVersionPreview |> typecheck |> shouldFail |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 28, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") @@ -77,6 +71,7 @@ let a: obj = $"string" let b: System.IComparable = $"string" let c: System.IFormattable = $"string" """ + |> withLangVersionPreview |> typecheck |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index f24746d4748..eda99b5dff9 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -8,14 +8,14 @@ open FSharp.Test.Compiler module DotLambdaTests = [] - let ``Script: _.ToString()`` () = + let ``ToString with preview version`` () = Fsx "_.ToString()" |> withLangVersionPreview |> typecheck |> shouldSucceed [] - let ``Script: _.ToString(), old lang version`` () = + let ``ToString with old lang version`` () = Fsx "_.ToString()" |> withLangVersion70 |> typecheck From 3148d74853a0d3c19c0ceff26dc108635466e68e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jun 2023 14:19:49 +0200 Subject: [PATCH 28/42] tests --- .../ApplicationExpressions/BasicApplication/ThomasTest.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs index 75784adf984..7a143741fc2 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs @@ -30,7 +30,7 @@ let c = _.ToString().Length let ``Regression with an underscore using pattern match`` () = Fsx """ type MyDU = A | B -let process x = +let getnumberOutOfDU x = match x with | A -> 42 | _ -> 43""" From acd09b25eb007c16cb14fd9f9d8686b81e22b728 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 22 Jun 2023 16:06:14 +0200 Subject: [PATCH 29/42] tests --- .../BasicApplication/ThomasTest.fs | 1 + .../Language/DotLambdaTests.fs | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs index 7a143741fc2..c3c59f83e12 100644 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs +++ b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs @@ -34,6 +34,7 @@ let getnumberOutOfDU x = match x with | A -> 42 | _ -> 43""" + |> withLangVersionPreview |> typecheck |> shouldSucceed diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index eda99b5dff9..d16a92c5859 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -7,15 +7,30 @@ open FSharp.Test.Compiler module DotLambdaTests = + [] + let ``DotLambda does NOT generalize automatically to a member based SRTP`` () = + Fsx "let inline myFunc x = x |> _.WhatANiceProperty" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [(Error 72, Line 1, Col 28, Line 1, Col 47, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.")] + + [] + let ``DotLambda does allow member based SRTP if labelled explicitely`` () = + Fsx "let inline myFunc<'a when 'a:(member WhatANiceProperty: int)> (x: 'a) = x |> _.WhatANiceProperty " + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + [] let ``ToString with preview version`` () = - Fsx "_.ToString()" + Fsx "let myFunc = _.ToString()" |> withLangVersionPreview |> typecheck |> shouldSucceed [] - let ``ToString with old lang version`` () = + let ``ToString with F# 7`` () = Fsx "_.ToString()" |> withLangVersion70 |> typecheck From 90c1ee8a6ff13fce8796e9e6f19875b2661935e4 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 26 Jun 2023 10:41:21 +0200 Subject: [PATCH 30/42] Test migrated --- .../Language/DotLambdaTests.fs | 16 ++++++++++++++++ .../E_StaticCoercion_hole_as_left_arg.fsx | 14 -------------- .../Expressions/Type-relatedExpressions/env.lst | 1 - 3 files changed, 16 insertions(+), 15 deletions(-) delete mode 100644 tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_StaticCoercion_hole_as_left_arg.fsx diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index d16a92c5859..c01f90397b0 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -28,6 +28,22 @@ module DotLambdaTests = |> withLangVersionPreview |> typecheck |> shouldSucceed + + [] + let ``Regression in neg typecheck hole as left arg`` () = + Fsx """ +let a = ( upcast _ ) : obj +let b = ( _ :> _ ) : obj +let c = ( _ :> obj) """ + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 10, Line 2, Col 20, Line 2, Col 21, "Unexpected symbol ')' in expression. Expected '.' or other token." + Error 10, Line 3, Col 13, Line 3, Col 15, "Unexpected symbol ':>' in expression. Expected '.' or other token." + Error 583, Line 3, Col 9, Line 3, Col 10, "Unmatched '('" + Error 10, Line 4, Col 13, Line 4, Col 15, "Unexpected symbol ':>' in expression. Expected '.' or other token." + Error 583, Line 4, Col 9, Line 4, Col 10, "Unmatched '('"] [] let ``ToString with F# 7`` () = diff --git a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_StaticCoercion_hole_as_left_arg.fsx b/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_StaticCoercion_hole_as_left_arg.fsx deleted file mode 100644 index 6dc34ad1e0a..00000000000 --- a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/E_StaticCoercion_hole_as_left_arg.fsx +++ /dev/null @@ -1,14 +0,0 @@ -// #Regression #Conformance #TypeRelatedExpressions #TypeAnnotations -// Negative tests on :> -// Using _ as left argument - -//Unexpected symbol ')' in expression. Expected '.' or other token.$ -//Unexpected symbol ':>' in expression. Expected '.' or other token.$ -//Unmatched '\('$ -//Unexpected symbol ':>' in expression. Expected '.' or other token.$ -//Unmatched '\('$ - - -let a = ( upcast _ ) : obj -let b = ( _ :> _ ) : obj -let c = ( _ :> obj) diff --git a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/env.lst index fe2f99b812b..d6a3fed8253 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/Type-relatedExpressions/env.lst @@ -1,6 +1,5 @@ SOURCE=E_StaticCoercion_class_not_impl_iface.fsx SCFLAGS="--test:ErrorRanges" # E_StaticCoercion_class_not_impl_iface.fsx SOURCE=E_StaticCoercion_class_not_subclass.fsx SCFLAGS="--test:ErrorRanges" # E_StaticCoercion_class_not_subclass.fsx - SOURCE=E_StaticCoercion_hole_as_left_arg.fsx SCFLAGS="--test:ErrorRanges" # E_StaticCoercion_hole_as_left_arg.fsx SOURCE=StaticCoercion_class01.fsx # StaticCoercion_class01.fsx SOURCE=StaticCoercion_interface01.fsx # StaticCoercion_interface01.fsx SOURCE=StaticCoercion_interface02.fsx # StaticCoercion_interface02.fsx From 06a6335ff60053ea5f3170be31bd6aeb30c45553 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 28 Jun 2023 13:00:59 +0200 Subject: [PATCH 31/42] tests --- .../BasicApplication/ThomasTest.fs | 78 -------- .../FSharp.Compiler.ComponentTests.fsproj | 1 - .../Language/DotLambdaTests.fs | 167 +++++++++++------- 3 files changed, 104 insertions(+), 142 deletions(-) delete mode 100644 tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs diff --git a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs b/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs deleted file mode 100644 index c3c59f83e12..00000000000 --- a/tests/FSharp.Compiler.ComponentTests/Conformance/Expressions/ApplicationExpressions/BasicApplication/ThomasTest.fs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. - -module Conformance.ThomasTests.UntilThingsAreFixed - -open System -open Xunit -open FSharp.Test.Compiler - -[] -let ``Underscore Dot ToString`` () = - Fsx """ -let x = "a" |> _.ToString() -printfn "%s" x""" - |> withLangVersionPreview - |> typecheck - |> shouldSucceed - -[] -let ``Types`` () = - Fsx """ -let a : (string array -> _) = _.Length -let b = _.ToString() -let c = _.ToString().Length -//let c = _.ToString()[0] """ - |> withLangVersionPreview - |> typecheck - |> shouldSucceed - -[] -let ``Regression with an underscore using pattern match`` () = - Fsx """ -type MyDU = A | B -let getnumberOutOfDU x = - match x with - | A -> 42 - | _ -> 43""" - |> withLangVersionPreview - |> typecheck - |> shouldSucceed - - -[] -let ``Underscore Dot Length on string`` () = - Fsx """ -let x = "a" |> _.Length -printfn "%i" x -""" - |> withLangVersionPreview - |> typecheck - |> shouldSucceed - -[] -let ``Regression: Empty Interpolated String properly typechecks with explicit type on binding`` () = - Fsx """ let a:byte = $"string" """ - |> withLangVersionPreview - |> typecheck - |> shouldFail - |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 24, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") - -[] -let ``Interpolated String with hole properly typechecks with explicit type on binding`` () = - Fsx """ let a:byte = $"strin{'g'}" """ - |> withLangVersionPreview - |> typecheck - |> shouldFail - |> withSingleDiagnostic (Error 1, Line 1, Col 15, Line 1, Col 28, "This expression was expected to have type" + Environment.NewLine + " 'byte' " + Environment.NewLine + "but here has type" + Environment.NewLine + " 'string' ") - -[] -let ``Interpolated String without holes properly typeckecks with explicit type on binding`` () = - Fsx """ -let a: obj = $"string" -let b: System.IComparable = $"string" -let c: System.IFormattable = $"string" - """ - |> withLangVersionPreview - |> typecheck - |> shouldSucceed - diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index bca552720dd..65ccf9395de 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -70,7 +70,6 @@ - diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index c01f90397b0..375226ee8a3 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -1,61 +1,102 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -namespace Language +module Language.DotLambdaTests open Xunit open FSharp.Test.Compiler -module DotLambdaTests = - [] - let ``DotLambda does NOT generalize automatically to a member based SRTP`` () = - Fsx "let inline myFunc x = x |> _.WhatANiceProperty" - |> withLangVersionPreview - |> typecheck - |> shouldFail - |> withDiagnostics [(Error 72, Line 1, Col 28, Line 1, Col 47, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.")] +[] +let ``Underscore Dot ToString`` () = + Fsx """ +let x = "a" |> _.ToString() +printfn "%s" x""" + |> withLangVersionPreview + |> typecheck + |> shouldSucceed - [] - let ``DotLambda does allow member based SRTP if labelled explicitely`` () = - Fsx "let inline myFunc<'a when 'a:(member WhatANiceProperty: int)> (x: 'a) = x |> _.WhatANiceProperty " - |> withLangVersionPreview - |> typecheck - |> shouldSucceed +[] +let ``Underscore Dot Length on string`` () = + Fsx """ +let x = "a" |> _.Length +printfn "%i" x +""" + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + +[] +let ``Types`` () = + Fsx """ +let a : (string array -> _) = _.Length +let b = _.ToString() +let c = _.ToString().Length +//let c = _.ToString()[0] """ + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + +[] +let ``Regression with an underscore using pattern match`` () = + Fsx """ +type MyDU = A | B +let getnumberOutOfDU x = + match x with + | A -> 42 + | _ -> 43""" + |> withLangVersionPreview + |> typecheck + |> shouldSucceed + +[] +let ``DotLambda does NOT generalize automatically to a member based SRTP`` () = + Fsx "let inline myFunc x = x |> _.WhatANiceProperty" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [(Error 72, Line 1, Col 28, Line 1, Col 47, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.")] + +[] +let ``DotLambda does allow member based SRTP if labelled explicitely`` () = + Fsx "let inline myFunc<'a when 'a:(member WhatANiceProperty: int)> (x: 'a) = x |> _.WhatANiceProperty " + |> withLangVersionPreview + |> typecheck + |> shouldSucceed - [] - let ``ToString with preview version`` () = - Fsx "let myFunc = _.ToString()" - |> withLangVersionPreview - |> typecheck - |> shouldSucceed +[] +let ``ToString with preview version`` () = + Fsx "let myFunc = _.ToString()" + |> withLangVersionPreview + |> typecheck + |> shouldSucceed - [] - let ``Regression in neg typecheck hole as left arg`` () = - Fsx """ +[] +let ``Regression in neg typecheck hole as left arg`` () = + Fsx """ let a = ( upcast _ ) : obj let b = ( _ :> _ ) : obj let c = ( _ :> obj) """ - |> withLangVersionPreview - |> typecheck - |> shouldFail - |> withDiagnostics [ - Error 10, Line 2, Col 20, Line 2, Col 21, "Unexpected symbol ')' in expression. Expected '.' or other token." - Error 10, Line 3, Col 13, Line 3, Col 15, "Unexpected symbol ':>' in expression. Expected '.' or other token." - Error 583, Line 3, Col 9, Line 3, Col 10, "Unmatched '('" - Error 10, Line 4, Col 13, Line 4, Col 15, "Unexpected symbol ':>' in expression. Expected '.' or other token." - Error 583, Line 4, Col 9, Line 4, Col 10, "Unmatched '('"] + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + Error 10, Line 2, Col 20, Line 2, Col 21, "Unexpected symbol ')' in expression. Expected '.' or other token." + Error 10, Line 3, Col 13, Line 3, Col 15, "Unexpected symbol ':>' in expression. Expected '.' or other token." + Error 583, Line 3, Col 9, Line 3, Col 10, "Unmatched '('" + Error 10, Line 4, Col 13, Line 4, Col 15, "Unexpected symbol ':>' in expression. Expected '.' or other token." + Error 583, Line 4, Col 9, Line 4, Col 10, "Unmatched '('"] - [] - let ``ToString with F# 7`` () = - Fsx "_.ToString()" - |> withLangVersion70 - |> typecheck - |> shouldFail - |> withSingleDiagnostic (Error 3350, Line 1, Col 1, Line 1, Col 3, "Feature 'underscore dot shorthand for accessor only function' is not available in F# 7.0. Please use language version 'PREVIEW' or greater." ) +[] +let ``ToString with F# 7`` () = + Fsx "_.ToString()" + |> withLangVersion70 + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Error 3350, Line 1, Col 1, Line 1, Col 3, "Feature 'underscore dot shorthand for accessor only function' is not available in F# 7.0. Please use language version 'PREVIEW' or greater." ) - [] - let ``Simple anonymous unary function shorthands compile`` () = - FSharp """ +[] +let ``Simple anonymous unary function shorthands compile`` () = + FSharp """ module One let a1 : {| Foo : {| Bar : string |}|} -> string = _.Foo.Bar let a2 : {| Foo : int array |} -> int = _.Foo.[5] @@ -65,31 +106,31 @@ let a5 : {| Foo : int -> {| X : string |} |} -> string = _.Foo(5).X open System let a6 = [1] |> List.map _.ToString() - """ - |> withLangVersionPreview - |> typecheck - |> shouldSucceed + """ + |> withLangVersionPreview + |> typecheck + |> shouldSucceed - [] - let ``Nested anonymous unary function shorthands compile`` () = - FSharp """ +[] +let ``Nested anonymous unary function shorthands compile`` () = + FSharp """ module One let a : string = {| Inner = (fun x -> x.ToString()) |} |> _.Inner([5] |> _.[0]) - """ - |> withLangVersionPreview - |> typecheck - |> shouldFail - |> withSingleDiagnostic (Warning 3570, Line 3, Col 75, Line 3, Col 76, "Discard is ambiguous") + """ + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 3570, Line 3, Col 75, Line 3, Col 76, "Discard is ambiguous") - [] - let ``Anonymous unary function shorthand with conflicting wild argument`` () = - FSharp """ +[] +let ``Anonymous unary function shorthand with conflicting wild argument`` () = + FSharp """ module One let a : string -> string = (fun _ -> 5 |> _.ToString()) let b : int -> int -> string = function |5 -> (fun _ -> "Five") |_ -> _.ToString() let c : string = let _ = "test" in "asd" |> _.ToString() - """ - |> withLangVersionPreview - |> typecheck - |> shouldFail - |> withSingleDiagnostic (Warning 3570, Line 3, Col 43, Line 3, Col 44, "Discard is ambiguous") \ No newline at end of file + """ + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withSingleDiagnostic (Warning 3570, Line 3, Col 43, Line 3, Col 44, "Discard is ambiguous") \ No newline at end of file From 6da867f38c08ed56cf8f555658a95d37858beb39 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 29 Jun 2023 12:21:14 +0200 Subject: [PATCH 32/42] Service operations + range adjustment --- src/Compiler/Checking/CheckExpressions.fs | 4 ++-- src/Compiler/Checking/MethodCalls.fs | 1 + src/Compiler/Service/FSharpParseFileResults.fs | 6 ++++++ src/Compiler/Service/ServiceInterfaceStubGenerator.fs | 2 ++ src/Compiler/Service/ServiceParseTreeWalk.fs | 2 ++ src/Compiler/Service/ServiceParsedInputOps.fs | 3 +++ .../Language/DotLambdaTests.fs | 3 +++ 7 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index fc7ef483a8a..56b5788ab5f 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5524,10 +5524,10 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE if env.NameEnv.eUnqualifiedItems |> Map.exists(fun _ itemValue -> itemValue |> function |Item.Value _ when itemValue.DisplayNameCore.StartsWith("_") -> true |_ -> false) then warning(Error(FSComp.SR.tcAmbiguousDiscardDotLambda(), trivia.UnderscoreRange)) - let unaryArg = mkSynId m (cenv.synArgNameGenerator.New()) + let unaryArg = mkSynId trivia.UnderscoreRange (cenv.synArgNameGenerator.New()) let svar = mkSynCompGenSimplePatVar unaryArg let pushedExpr = pushUnaryArg synExpr unaryArg - let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ],[], m), pushedExpr, None, m, SynExprLambdaTrivia.Zero) + let lambda = SynExpr.Lambda(false, false, SynSimplePats.SimplePats([ svar ],[], svar.Range), pushedExpr, None, m, SynExprLambdaTrivia.Zero) TcIteratedLambdas cenv true env overallTy Set.empty tpenv lambda | SynExpr.Lambda _ -> TcIteratedLambdas cenv true env overallTy Set.empty tpenv synExpr diff --git a/src/Compiler/Checking/MethodCalls.fs b/src/Compiler/Checking/MethodCalls.fs index 67b3a61fd5c..d7e09b86aeb 100644 --- a/src/Compiler/Checking/MethodCalls.fs +++ b/src/Compiler/Checking/MethodCalls.fs @@ -841,6 +841,7 @@ let InferLambdaArgsForLambdaPropagation origRhsExpr = match e with | SynExpr.Lambda (body = rest) -> 1 + loop rest | SynExpr.MatchLambda _ -> 1 + | SynExpr.DotLambda _ -> 1 | _ -> 0 loop origRhsExpr diff --git a/src/Compiler/Service/FSharpParseFileResults.fs b/src/Compiler/Service/FSharpParseFileResults.fs index e771f60a11b..e50d3815e79 100644 --- a/src/Compiler/Service/FSharpParseFileResults.fs +++ b/src/Compiler/Service/FSharpParseFileResults.fs @@ -277,6 +277,8 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, // Capture the body of a lambda, often nested in a call to a collection function | SynExpr.Lambda (body = body) when rangeContainsPos body.Range pos -> getIdentRangeForFuncExprInApp traverseSynExpr body pos + | SynExpr.DotLambda (expr = body) when rangeContainsPos body.Range pos -> getIdentRangeForFuncExprInApp traverseSynExpr body pos + | SynExpr.Do (expr, range) when rangeContainsPos range pos -> getIdentRangeForFuncExprInApp traverseSynExpr expr pos | SynExpr.Assert (expr, range) when rangeContainsPos range pos -> getIdentRangeForFuncExprInApp traverseSynExpr expr pos @@ -410,6 +412,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, override _.VisitBinding(_path, defaultTraverse, binding) = match binding with | SynBinding(expr = SynExpr.Lambda _) when skipLambdas -> defaultTraverse binding + | SynBinding(expr = SynExpr.DotLambda _) when skipLambdas -> defaultTraverse binding // Skip manually type-annotated bindings | SynBinding(returnInfo = Some (SynBindingReturnInfo _)) -> defaultTraverse binding @@ -500,6 +503,7 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, | SynBinding.SynBinding (expr = expr; range = range) when Position.posEq range.Start pos -> match expr with | SynExpr.Lambda _ -> Some range + | SynExpr.DotLambda _ -> Some range | _ -> None | _ -> defaultTraverse binding } @@ -796,6 +800,8 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput, | SynExpr.Lambda (body = bodyExpr) -> yield! walkExpr true bodyExpr + | SynExpr.DotLambda (expr = bodyExpr) -> yield! walkExpr true bodyExpr + | SynExpr.Match (matchDebugPoint = spBind; expr = inpExpr; clauses = cl) -> yield! walkBindSeqPt spBind yield! walkExpr false inpExpr diff --git a/src/Compiler/Service/ServiceInterfaceStubGenerator.fs b/src/Compiler/Service/ServiceInterfaceStubGenerator.fs index e0e31850e33..7e5851cb329 100644 --- a/src/Compiler/Service/ServiceInterfaceStubGenerator.fs +++ b/src/Compiler/Service/ServiceInterfaceStubGenerator.fs @@ -880,6 +880,8 @@ module InterfaceStubGenerator = | SynExpr.Lambda (body = synExpr) -> walkExpr synExpr + | SynExpr.DotLambda (expr = synExpr) -> walkExpr synExpr + | SynExpr.MatchLambda (_isExnMatch, _argm, synMatchClauseList, _spBind, _wholem) -> synMatchClauseList |> List.tryPick (fun (SynMatchClause (resultExpr = e)) -> walkExpr e) diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index ae0defdd9fc..2d581f63f66 100644 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -561,6 +561,8 @@ module SyntaxTraversal = | None -> traverseSynExpr synExpr | x -> x + | SynExpr.DotLambda (expr = e) -> traverseSynExpr e + | SynExpr.MatchLambda (_isExnMatch, _argm, synMatchClauseList, _spBind, _wholem) -> synMatchClauseList |> List.map (fun x -> dive x x.Range (traverseSynMatchClause path)) diff --git a/src/Compiler/Service/ServiceParsedInputOps.fs b/src/Compiler/Service/ServiceParsedInputOps.fs index a0f8a810ccb..9ff2f89120e 100644 --- a/src/Compiler/Service/ServiceParsedInputOps.fs +++ b/src/Compiler/Service/ServiceParsedInputOps.fs @@ -752,6 +752,8 @@ module ParsedInput = | SynExpr.Lambda (body = e) -> walkExprWithKind parentKind e + | SynExpr.DotLambda (expr = e) -> walkExprWithKind parentKind e + | SynExpr.MatchLambda (_, _, synMatchClauseList, _, _) -> List.tryPick walkClause synMatchClauseList | SynExpr.Match (expr = e; clauses = synMatchClauseList) -> @@ -1733,6 +1735,7 @@ module ParsedInput = | SynExpr.Lambda (args = pats; body = e) -> walkSimplePats pats walkExpr e + | SynExpr.DotLambda (expr = e) -> walkExpr e | SynExpr.New (_, t, e, _) | SynExpr.TypeTest (e, t, _) | SynExpr.Upcast (e, t, _) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index 375226ee8a3..cc159bab112 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -6,6 +6,9 @@ open Xunit open FSharp.Test.Compiler + +// range test for _.ExistingProperty.NonExistingProperty + [] let ``Underscore Dot ToString`` () = Fsx """ From 74a63ba58499f78f81ea9ff57a3a1fb4436e6492 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 29 Jun 2023 12:33:42 +0200 Subject: [PATCH 33/42] Nested _. usages should fail, as it makes the "I_" character ambigous --- tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index cc159bab112..ea84538b00d 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -115,7 +115,7 @@ let a6 = [1] |> List.map _.ToString() |> shouldSucceed [] -let ``Nested anonymous unary function shorthands compile`` () = +let ``Nested anonymous unary function shorthands fails because of ambigous discard`` () = FSharp """ module One let a : string = {| Inner = (fun x -> x.ToString()) |} |> _.Inner([5] |> _.[0]) From 26fcabab421fc383a59bf4591a38c62f5d377aed Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 29 Jun 2023 14:31:38 +0200 Subject: [PATCH 34/42] fix --- src/Compiler/Service/ServiceParseTreeWalk.fs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Compiler/Service/ServiceParseTreeWalk.fs b/src/Compiler/Service/ServiceParseTreeWalk.fs index 2d581f63f66..5f0d189c3be 100644 --- a/src/Compiler/Service/ServiceParseTreeWalk.fs +++ b/src/Compiler/Service/ServiceParseTreeWalk.fs @@ -662,8 +662,6 @@ module SyntaxTraversal = | SynExpr.DotGet (synExpr, _dotm, _longIdent, _range) -> traverseSynExpr synExpr - | SynExpr.DotLambda _ -> None - | SynExpr.Set (synExpr, synExpr2, _) | SynExpr.DotSet (synExpr, _, synExpr2, _) -> From 71e83be300efbd41b9b70ee877efe25e99d4ffd1 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 29 Jun 2023 14:42:51 +0200 Subject: [PATCH 35/42] pars.fsy rename --- src/Compiler/pars.fsy | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 38c39a3ad7e..6ac7abeb107 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4790,12 +4790,12 @@ argExpr: atomicExpr: | UNDERSCORE DOT atomicExpr %prec dot_lambda - { let arg1 = rhs parseState 1 - let arg2 = rhs parseState 2 - parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AccessorFunctionShorthand (unionRanges arg1 arg2) - let arg3, hpa = $3 - let trivia: SynExprDotLambdaTrivia = { UnderscoreRange = arg1; DotRange = arg2 } - SynExpr.DotLambda(arg3, unionRanges arg1 arg3.Range, trivia), false } + { let mUnderscore = rhs parseState 1 + let mDot = rhs parseState 2 + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AccessorFunctionShorthand (unionRanges mUnderscore mDot ) + let expr, hpa = $3 + let trivia: SynExprDotLambdaTrivia = { UnderscoreRange = mUnderscore ; DotRange = mDot } + SynExpr.DotLambda(expr, unionRanges mUnderscore expr.Range, trivia), false } | atomicExpr HIGH_PRECEDENCE_BRACK_APP atomicExpr { let arg1, _ = $1 From 5230bd68fa4429d8ef7885358a1498dc6c6846f6 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 29 Jun 2023 14:59:25 +0200 Subject: [PATCH 36/42] clean --- src/Compiler/SyntaxTree/SyntaxTreeOps.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs index 7bf666b6818..73cf3f25063 100644 --- a/src/Compiler/SyntaxTree/SyntaxTreeOps.fs +++ b/src/Compiler/SyntaxTree/SyntaxTreeOps.fs @@ -98,7 +98,7 @@ let rec pushUnaryArg expr arg = | SynExpr.DotIndexedGet (objectExpr, indexArgs, dotRange, range) -> SynExpr.DotIndexedGet(pushUnaryArg objectExpr arg, indexArgs, dotRange, range) | _ -> expr -// | SynExpr.App(ExprAtomicFlag.Atomic, infix, innerExpr, x1, m1) + let (|SynSingleIdent|_|) x = match x with | SynLongIdent ([ id ], _, _) -> Some id From 335349f309dea41e6f777bcd1fa29e6d0bd6318e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 29 Jun 2023 16:14:00 +0200 Subject: [PATCH 37/42] completion tests --- tests/service/CompletionTests.fs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tests/service/CompletionTests.fs b/tests/service/CompletionTests.fs index 9aca58a6b5b..349647e0fa3 100644 --- a/tests/service/CompletionTests.fs +++ b/tests/service/CompletionTests.fs @@ -4,7 +4,7 @@ open FSharp.Compiler.EditorServices open NUnit.Framework let getCompletionInfo lineText (line, column) source = - let parseResults, checkResults = getParseAndCheckResults source + let parseResults, checkResults = getParseAndCheckResultsPreview source let plid = QuickParse.GetPartialLongNameEx(lineText, column) checkResults.GetDeclarationListInfo(Some parseResults, line, lineText, plid) @@ -15,7 +15,7 @@ let assertHasItemWithNames names (completionInfo: DeclarationListInfo) = let itemNames = getCompletionItemNames completionInfo |> set for name in names do - Assert.That(Set.contains name itemNames, name) + Assert.That(Set.contains name itemNames, $"{name} not found in {itemNames}") [] let ``Expr - record - field 01 - anon module`` () = @@ -55,4 +55,20 @@ let record = { Field = 1 } { } """ - assertHasItemWithNames ["Field"; "record"] info \ No newline at end of file + assertHasItemWithNames ["Field"; "record"] info + +[] +let ``Underscore dot lambda - completion`` () = + let info = getCompletionInfo " |> _.Len" (4, 11) """ +let myFancyFunc (x:string) = + x + |> _.Len""" + assertHasItemWithNames ["Length"] info + +[] +let ``Underscore dot lambda - method completion`` () = + let info = getCompletionInfo " |> _.ToL" (4, 11) """ +let myFancyFunc (x:string) = + x + |> _.ToL""" + assertHasItemWithNames ["ToLower"] info \ No newline at end of file From 8cb5d60d7150f5503345221b48bfd90df8df6161 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 7 Jul 2023 16:56:58 +0200 Subject: [PATCH 38/42] sigdata roundtrip tests, parse tree tests --- .../underscore_dot_lambda.fsx | 9 +++++ .../FunctionWithUnderscoreDotLambda.fs | 1 + .../FunctionWithUnderscoreDotLambda.fs.bsl | 25 ++++++++++++++ .../NestedPropertiesAfterUnderscore.fs | 1 + .../NestedPropertiesAfterUnderscore.fs.bsl | 29 ++++++++++++++++ ...FunctionNallWithSpaceAndUnitApplication.fs | 1 + ...tionNallWithSpaceAndUnitApplication.fs.bsl | 31 +++++++++++++++++ .../DotLambda/UnderscoreToString.fs | 1 + .../DotLambda/UnderscoreToString.fs.bsl | 16 +++++++++ .../DotLambda/WithNonTupledFunctionCall.fs | 1 + .../WithNonTupledFunctionCall.fs.bsl | 33 +++++++++++++++++++ .../data/SyntaxTree/DotLambda/WithoutDot.fs | 1 + .../SyntaxTree/DotLambda/WithoutDot.fs.bsl | 13 ++++++++ .../SyntaxTree/DotLambda/WithoutUnderscore.fs | 1 + .../DotLambda/WithoutUnderscore.fs.bsl | 11 +++++++ 15 files changed, 174 insertions(+) create mode 100644 tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/underscore_dot_lambda.fsx create mode 100644 tests/service/data/SyntaxTree/DotLambda/FunctionWithUnderscoreDotLambda.fs create mode 100644 tests/service/data/SyntaxTree/DotLambda/FunctionWithUnderscoreDotLambda.fs.bsl create mode 100644 tests/service/data/SyntaxTree/DotLambda/NestedPropertiesAfterUnderscore.fs create mode 100644 tests/service/data/SyntaxTree/DotLambda/NestedPropertiesAfterUnderscore.fs.bsl create mode 100644 tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs create mode 100644 tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs.bsl create mode 100644 tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs create mode 100644 tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs.bsl create mode 100644 tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs create mode 100644 tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs.bsl create mode 100644 tests/service/data/SyntaxTree/DotLambda/WithoutDot.fs create mode 100644 tests/service/data/SyntaxTree/DotLambda/WithoutDot.fs.bsl create mode 100644 tests/service/data/SyntaxTree/DotLambda/WithoutUnderscore.fs create mode 100644 tests/service/data/SyntaxTree/DotLambda/WithoutUnderscore.fs.bsl diff --git a/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/underscore_dot_lambda.fsx b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/underscore_dot_lambda.fsx new file mode 100644 index 00000000000..b346d4e04bd --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/Signatures/TestCasesForGenerationRoundTrip/underscore_dot_lambda.fsx @@ -0,0 +1,9 @@ +module MyTests + +let printerFunc = _.ToString() + +let processString (x:string) = x |> _.Length + +type MyRecord = {ThisIsFieldOfMyRecord : string} + +let extractProp = _.ThisIsFieldOfMyRecord \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/DotLambda/FunctionWithUnderscoreDotLambda.fs b/tests/service/data/SyntaxTree/DotLambda/FunctionWithUnderscoreDotLambda.fs new file mode 100644 index 00000000000..8f07a966861 --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/FunctionWithUnderscoreDotLambda.fs @@ -0,0 +1 @@ +let myFunc = _.MyProperty \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/DotLambda/FunctionWithUnderscoreDotLambda.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/FunctionWithUnderscoreDotLambda.fs.bsl new file mode 100644 index 00000000000..761e4d10bf1 --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/FunctionWithUnderscoreDotLambda.fs.bsl @@ -0,0 +1,25 @@ +ImplFile + (ParsedImplFileInput + ("/root/DotLambda/FunctionWithUnderscoreDotLambda.fs", false, + QualifiedNameOfFile FunctionWithUnderscoreDotLambda, [], [], + [SynModuleOrNamespace + ([FunctionWithUnderscoreDotLambda], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (myFunc, None), false, None, (1,4--1,10)), + None, + DotLambda + (Ident MyProperty, (1,13--1,25), + { UnderscoreRange = (1,13--1,14) + DotRange = (1,14--1,15) }), (1,4--1,10), Yes (1,0--1,25), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,11--1,12) })], (1,0--1,25))], + PreXmlDocEmpty, [], None, (1,0--1,25), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/DotLambda/NestedPropertiesAfterUnderscore.fs b/tests/service/data/SyntaxTree/DotLambda/NestedPropertiesAfterUnderscore.fs new file mode 100644 index 00000000000..c98363d7506 --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/NestedPropertiesAfterUnderscore.fs @@ -0,0 +1 @@ +let myFunc = _.MyProperty.MyOtherProperty \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/DotLambda/NestedPropertiesAfterUnderscore.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/NestedPropertiesAfterUnderscore.fs.bsl new file mode 100644 index 00000000000..2f6ac46b18d --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/NestedPropertiesAfterUnderscore.fs.bsl @@ -0,0 +1,29 @@ +ImplFile + (ParsedImplFileInput + ("/root/DotLambda/NestedPropertiesAfterUnderscore.fs", false, + QualifiedNameOfFile NestedPropertiesAfterUnderscore, [], [], + [SynModuleOrNamespace + ([NestedPropertiesAfterUnderscore], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (myFunc, None), false, None, (1,4--1,10)), + None, + DotLambda + (LongIdent + (false, + SynLongIdent + ([MyProperty; MyOtherProperty], [(1,25--1,26)], + [None; None]), None, (1,15--1,41)), (1,13--1,41), + { UnderscoreRange = (1,13--1,14) + DotRange = (1,14--1,15) }), (1,4--1,10), Yes (1,0--1,41), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,11--1,12) })], (1,0--1,41))], + PreXmlDocEmpty, [], None, (1,0--1,41), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs new file mode 100644 index 00000000000..76174f54c6f --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs @@ -0,0 +1 @@ +let myFunc = _.MyMethodCall () \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs.bsl new file mode 100644 index 00000000000..26fc387ed22 --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs.bsl @@ -0,0 +1,31 @@ +ImplFile + (ParsedImplFileInput + ("/root/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs", + false, + QualifiedNameOfFile UnderscoreToFunctionNallWithSpaceAndUnitApplication, + [], [], + [SynModuleOrNamespace + ([UnderscoreToFunctionNallWithSpaceAndUnitApplication], false, + AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (myFunc, None), false, None, (1,4--1,10)), + None, + App + (NonAtomic, false, + DotLambda + (Ident MyMethodCall, (1,13--1,27), + { UnderscoreRange = (1,13--1,14) + DotRange = (1,14--1,15) }), Const (Unit, (1,28--1,30)), + (1,13--1,30)), (1,4--1,10), Yes (1,0--1,30), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,11--1,12) })], (1,0--1,30))], + PreXmlDocEmpty, [], None, (1,0--1,30), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs new file mode 100644 index 00000000000..afe271dc2b7 --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs @@ -0,0 +1 @@ +_.ToString() \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs.bsl new file mode 100644 index 00000000000..e39acb856a8 --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs.bsl @@ -0,0 +1,16 @@ +ImplFile + (ParsedImplFileInput + ("/root/DotLambda/UnderscoreToString.fs", false, + QualifiedNameOfFile UnderscoreToString, [], [], + [SynModuleOrNamespace + ([UnderscoreToString], false, AnonModule, + [Expr + (DotLambda + (App + (Atomic, false, Ident ToString, Const (Unit, (1,10--1,12)), + (1,2--1,12)), (1,0--1,12), { UnderscoreRange = (1,0--1,1) + DotRange = (1,1--1,2) }), + (1,0--1,12))], PreXmlDocEmpty, [], None, (1,0--1,12), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs b/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs new file mode 100644 index 00000000000..b546f9b55de --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs @@ -0,0 +1 @@ +let myFunc = _.ThisIsMyFunction a b c \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs.bsl new file mode 100644 index 00000000000..6ab669c73fd --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs.bsl @@ -0,0 +1,33 @@ +ImplFile + (ParsedImplFileInput + ("/root/DotLambda/WithNonTupledFunctionCall.fs", false, + QualifiedNameOfFile WithNonTupledFunctionCall, [], [], + [SynModuleOrNamespace + ([WithNonTupledFunctionCall], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([], SynArgInfo ([], false, None)), None), + Named (SynIdent (myFunc, None), false, None, (1,4--1,10)), + None, + App + (NonAtomic, false, + App + (NonAtomic, false, + App + (NonAtomic, false, + DotLambda + (Ident ThisIsMyFunction, (1,13--1,31), + { UnderscoreRange = (1,13--1,14) + DotRange = (1,14--1,15) }), Ident a, + (1,13--1,33)), Ident b, (1,13--1,35)), Ident c, + (1,13--1,37)), (1,4--1,10), Yes (1,0--1,37), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,11--1,12) })], (1,0--1,37))], + PreXmlDocEmpty, [], None, (1,0--1,37), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/DotLambda/WithoutDot.fs b/tests/service/data/SyntaxTree/DotLambda/WithoutDot.fs new file mode 100644 index 00000000000..6bfa010ed2d --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/WithoutDot.fs @@ -0,0 +1 @@ +_ToString() \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/DotLambda/WithoutDot.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/WithoutDot.fs.bsl new file mode 100644 index 00000000000..ebfb0fc358b --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/WithoutDot.fs.bsl @@ -0,0 +1,13 @@ +ImplFile + (ParsedImplFileInput + ("/root/DotLambda/WithoutDot.fs", false, QualifiedNameOfFile WithoutDot, [], + [], + [SynModuleOrNamespace + ([WithoutDot], false, AnonModule, + [Expr + (App + (Atomic, false, Ident _ToString, Const (Unit, (1,9--1,11)), + (1,0--1,11)), (1,0--1,11))], PreXmlDocEmpty, [], None, + (1,0--1,11), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/DotLambda/WithoutUnderscore.fs b/tests/service/data/SyntaxTree/DotLambda/WithoutUnderscore.fs new file mode 100644 index 00000000000..340a7bc7001 --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/WithoutUnderscore.fs @@ -0,0 +1 @@ +.ToString() \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/DotLambda/WithoutUnderscore.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/WithoutUnderscore.fs.bsl new file mode 100644 index 00000000000..6d432926d6b --- /dev/null +++ b/tests/service/data/SyntaxTree/DotLambda/WithoutUnderscore.fs.bsl @@ -0,0 +1,11 @@ +ImplFile + (ParsedImplFileInput + ("/root/DotLambda/WithoutUnderscore.fs", false, + QualifiedNameOfFile WithoutUnderscore, [], [], + [SynModuleOrNamespace + ([WithoutUnderscore], false, AnonModule, [], PreXmlDocEmpty, [], None, + (1,0--1,1), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(1,0)-(1,1) parse error Unexpected symbol '.' in implementation file From 21a64571bd71155a13663ab948cc91440fb12569 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 7 Jul 2023 17:12:44 +0200 Subject: [PATCH 39/42] Negative tests for incorrect feature usage - also shows what the OOB messages would be --- .../Language/DotLambdaTests.fs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index ea84538b00d..b630bd5a830 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -18,6 +18,30 @@ printfn "%s" x""" |> typecheck |> shouldSucceed +[] +let ``Underscore Dot ToString With Space Before Paranthesis`` () = + Fsx """ +let x = "a" |> _.ToString () """ + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [Error 1, Line 2, Col 16, Line 2, Col 29, "Type mismatch. Expecting a + 'string -> 'a' +but given a + 'unit -> string' +The type 'string' does not match the type 'unit'"] + +[] +let ``Underscore Dot Curried Function With Arguments`` () = + Fsx """ +type MyRecord = {MyRecordField:string} + with member x.DoStuff a b c = $"%s{x.MyRecordField} %i{a} %i{b} %i{c}" +let myFunction (x:MyRecord) = x |> _.DoStuff 1 2 3""" + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [Error 72, Line 4, Col 36, Line 4, Col 45, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved."] + [] let ``Underscore Dot Length on string`` () = Fsx """ From 952e1e4e153fc5506189d98b3aaa696bc24fa2c2 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 17 Jul 2023 16:08:27 +0200 Subject: [PATCH 40/42] message rename to make it more explicit --- src/Compiler/FSComp.txt | 2 +- .../FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 9912f659a52..8d832e89c16 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1701,7 +1701,7 @@ featureInformationalObjInferenceDiagnostic,"Diagnostic 3559 (warn when obj infer 3566,tcMultipleRecdTypeChoice,"Multiple type matches were found:\n%s\nThe type '%s' was used. Due to the overlapping field names\n%s\nconsider using type annotations or change the order of open statements." 3567,parsMissingMemberBody,"Expecting member body" 3568,parsMissingKeyword,"Missing keyword '%s'" -3570,tcAmbiguousDiscardDotLambda,"Discard is ambiguous" +3570,tcAmbiguousDiscardDotLambda,"The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope." featureAccessorFunctionShorthand,"underscore dot shorthand for accessor only function" 3569,chkNotTailRecursive,"The member or function '%s' has the 'TailCallAttribute' attribute, but is not being used in a tail recursive way." 3577,tcOverrideUsesMultipleArgumentsInsteadOfTuple,"This override takes a tuple instead of multiple arguments. Try to add an additional layer of parentheses at the method definition (e.g. 'member _.Foo((x, y))'), or remove parentheses at the abstract method declaration (e.g. 'abstract member Foo: 'a * 'b -> 'c')." \ No newline at end of file diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index b630bd5a830..901b6203bb8 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -147,7 +147,7 @@ let a : string = {| Inner = (fun x -> x.ToString()) |} |> _.Inner([5] |> _.[0]) |> withLangVersionPreview |> typecheck |> shouldFail - |> withSingleDiagnostic (Warning 3570, Line 3, Col 75, Line 3, Col 76, "Discard is ambiguous") + |> withSingleDiagnostic (Warning 3570, Line 3, Col 75, Line 3, Col 76, "The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope.") [] let ``Anonymous unary function shorthand with conflicting wild argument`` () = @@ -160,4 +160,4 @@ let c : string = let _ = "test" in "asd" |> _.ToString() |> withLangVersionPreview |> typecheck |> shouldFail - |> withSingleDiagnostic (Warning 3570, Line 3, Col 43, Line 3, Col 44, "Discard is ambiguous") \ No newline at end of file + |> withSingleDiagnostic (Warning 3570, Line 3, Col 43, Line 3, Col 44, "The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope.") \ No newline at end of file From 01a8f96208f093c6540a46a704688e6ffa88852f Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 17 Jul 2023 17:45:22 +0200 Subject: [PATCH 41/42] Diagnostics for nonatomic expressions, recovery when not using _. on atomic expressions --- src/Compiler/Checking/CheckExpressions.fs | 2 +- src/Compiler/FSComp.txt | 1 + src/Compiler/pars.fsy | 9 ++++++++ src/Compiler/xlf/FSComp.txt.cs.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.de.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.es.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.fr.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.it.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.ja.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.ko.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.pl.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.ru.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.tr.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 9 ++++++-- src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 9 ++++++-- .../Language/DotLambdaTests.fs | 21 ++++++++++--------- 17 files changed, 113 insertions(+), 37 deletions(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 07af96d47ef..908d5ad63c8 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5525,7 +5525,7 @@ and TcExprUndelayed (cenv: cenv) (overallTy: OverallTy) env tpenv (synExpr: SynE CallExprHasTypeSink cenv.tcSink (m, env.NameEnv, overallTy.Commit, env.AccessRights) TcConstExpr cenv overallTy env m tpenv synConst | SynExpr.DotLambda (synExpr, m, trivia) -> - if env.NameEnv.eUnqualifiedItems |> Map.exists(fun _ itemValue -> itemValue |> function |Item.Value _ when itemValue.DisplayNameCore.StartsWith("_") -> true |_ -> false) + if env.NameEnv.eUnqualifiedItems |> Map.containsKey "_arg1" then warning(Error(FSComp.SR.tcAmbiguousDiscardDotLambda(), trivia.UnderscoreRange)) let unaryArg = mkSynId trivia.UnderscoreRange (cenv.synArgNameGenerator.New()) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index 8d832e89c16..1ba7d0a40d6 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1702,6 +1702,7 @@ featureInformationalObjInferenceDiagnostic,"Diagnostic 3559 (warn when obj infer 3567,parsMissingMemberBody,"Expecting member body" 3568,parsMissingKeyword,"Missing keyword '%s'" 3570,tcAmbiguousDiscardDotLambda,"The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope." +3571,parsUnderScoreDotLambdaNonAtomic," _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses." featureAccessorFunctionShorthand,"underscore dot shorthand for accessor only function" 3569,chkNotTailRecursive,"The member or function '%s' has the 'TailCallAttribute' attribute, but is not being used in a tail recursive way." 3577,tcOverrideUsesMultipleArgumentsInsteadOfTuple,"This override takes a tuple instead of multiple arguments. Try to add an additional layer of parentheses at the method definition (e.g. 'member _.Foo((x, y))'), or remove parentheses at the abstract method declaration (e.g. 'abstract member Foo: 'a * 'b -> 'c')." \ No newline at end of file diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 9797c79d4bc..ae58e783321 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -4803,6 +4803,15 @@ atomicExpr: let expr, hpa = $3 let trivia: SynExprDotLambdaTrivia = { UnderscoreRange = mUnderscore ; DotRange = mDot } SynExpr.DotLambda(expr, unionRanges mUnderscore expr.Range, trivia), false } + + | UNDERSCORE DOT appExpr recover %prec dot_lambda + { let mUnderscore = rhs parseState 1 + let mDot = rhs parseState 2 + parseState.LexBuffer.CheckLanguageFeatureAndRecover LanguageFeature.AccessorFunctionShorthand (unionRanges mUnderscore mDot ) + reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnderScoreDotLambdaNonAtomic()) + let expr = $3 + let trivia: SynExprDotLambdaTrivia = { UnderscoreRange = mUnderscore ; DotRange = mDot } + SynExpr.DotLambda(expr, unionRanges mUnderscore expr.Range, trivia), false } | atomicExpr HIGH_PRECEDENCE_BRACK_APP atomicExpr { let arg1, _ = $1 diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 92ddfaf3f93..fc1356f548b 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -862,6 +862,11 @@ Tento přístup člena je nejednoznačný. Při vytváření objektu použijte závorky, např. (new SomeType(args)).MemberName' + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. Neočekávaný konec vstupu ve větvi else if nebo elif podmíněného výrazu Očekávalo se elif <expr> then <expr> nebo else if <expr> then <expr>. @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 8aa2d2ada43..d58af10072a 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -862,6 +862,11 @@ Dieser Memberzugriff ist mehrdeutig. Setzen Sie Klammern um die Objekterstellung, z. B. "(new SomeType(args)). MemberName“ + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. Unerwartetes Ende der Eingabe im "else if"- oder "elif"-Branch des bedingten Ausdrucks. Erwartet wird: "elif <expr> then <expr>" oder "else if <expr> then <expr>". @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 476378c3140..21fa60eb2d9 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -862,6 +862,11 @@ Este acceso de miembro es ambiguo. Use paréntesis alrededor de la creación del objeto, por ejemplo, '(nuevo AlgúnTipo(args)).NombreMiembro' + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. Fin de entrada inesperado en la rama "else if" o "elif" de una expresión condicional. Se espera "elif <expr> then <expr>" o "else if <expr> then <expr>". @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 645798eb4b4..f38b1d1811a 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -862,6 +862,11 @@ L’accès à ce membre est ambigu. Utilisez des parenthèses autour de la création de l’objet, par exemple' (New SomeType (args)). MemberName + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. Fin d'entrée inattendue dans la branche 'else if' ou 'elif' de l'expression conditionnelle. Attendu 'elif <expr> then <expr>' ou 'else if <expr> then <expr>'. @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 925b652675a..3f70f455d25 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -862,6 +862,11 @@ L'accesso ai membri è ambiguo. Utilizzare le parentesi intorno alla creazione oggetto, ad esempio “(New SomeType (args)). MemberName” + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. Fine dell'input imprevista nel ramo 'else if' o 'elif' dell'espressione condizionale. È previsto 'elif <expr> then <expr>' o 'else if <expr> then <expr>'. @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index a8d038adf21..1b2457f470f 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -862,6 +862,11 @@ このメンバーへのアクセスはあいまいです。オブジェクト作成の前後にはかっこを使用してください。例: '(new SomeType(args)).MemberName' + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. 条件式の 'else if' または 'elif' 分岐の入力が予期しない形式で終了しています。'elif <expr> then <expr>' または 'else if <expr> then <expr>' が必要でした。 @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 85d6d63bb3f..fb91dfdaad4 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -862,6 +862,11 @@ 이 구성원 액세스가 모호합니다. 개체 생성 주위에 괄호를 사용하세요. 예: '(새로운 SomeType(인수)).MemberName' + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. 조건식의 'else if' 또는 'elif' 분기에서 입력이 예기치 않게 끝났습니다. 'elif <expr> then <expr>' 또는 'else if <expr> then <expr>'이 필요합니다. @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index a0ce2966155..045bc076c4d 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -862,6 +862,11 @@ Dostęp tego elementu członkowskiego jest niejednoznaczny. W celu utworzenia obiektu użyj nawiasów, na przykład „(nowy SomeType(args)).MemberName” + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. Nieoczekiwane zakończenie danych wejściowych w gałęzi „else” wyrażenia warunkowego. Oczekiwano konstrukcji „elif <expr> then <expr>” lub „else if <expr> then <expr>”. @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 715936a825b..ae753c51243 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -862,6 +862,11 @@ Este acesso de membro é ambíguo. Use parênteses em torno da criação do objeto, por exemplo, '(new SomeType(args)).MemberName''. + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. Fim inesperado de entrada no branch 'else if' ou 'elif' da expressão condicional. Esperado 'elif <expr> em seguida, <expr>' ou 'else if <expr> then <expr>'. @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index e80c690d86b..a8377bff10d 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -862,6 +862,11 @@ Неоднозначный доступ к этому элементу. Заключите операцию создания объекта в круглые скобки, например (new Объект(аргументы)).Элемент + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. Неожиданное завершение входных данных ветви "else if" или "elif" условного выражения. Ожидается "elif <expr> then <expr> " или "else if <expr> then <expr>" @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index fe4bd0b5ca1..44e7fee0883 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -862,6 +862,11 @@ Bu üye erişimi belirsiz. Lütfen nesne oluşturma etrafında parantez kullanın, örneğin '(yeni SomeType (args)).MemberName’ + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. Koşullu ifadenin 'else if' veya 'elif' dalında beklenmeyen giriş sonu. 'elif <expr> then <expr>' veya 'else if <expr> then <expr>' bekleniyordu. @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 576badded32..a88de13f134 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -862,6 +862,11 @@ 此成员访问权限不明确。请在对象创建周围使用括号,例如 “(new SomeType(args)).MemberName” + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. 条件表达式的 "else if" 或 "elif" 分支中的输入意外结束。应为 "elif <expr> then <expr>" 或 "else if <expr> then <expr>"。 @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 465af48b96e..fcfc8c65218 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -862,6 +862,11 @@ 此成員存取不明確。請在物件建立前後加上括弧,例如「(new SomeType(args)).MemberName」 + + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. + + Unexpected end of input in 'else if' or 'elif' branch of conditional expression. Expected 'elif <expr> then <expr>' or 'else if <expr> then <expr>'. 條件運算式的 'else if' 或 'elif' 分支中出現未預期的輸入結尾。 預期為 'elif <expr> then <expr>' 或 'else if <expr> then <expr>'. @@ -963,8 +968,8 @@ - Discard is ambiguous - Discard is ambiguous + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs index 901b6203bb8..f038fc67f10 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DotLambdaTests.fs @@ -19,20 +19,19 @@ printfn "%s" x""" |> shouldSucceed [] -let ``Underscore Dot ToString With Space Before Paranthesis`` () = +let ``Underscore Dot ToString With Space Before Paranthesis - NonAtomic`` () = Fsx """ let x = "a" |> _.ToString () """ |> withLangVersionPreview |> typecheck |> shouldFail - |> withDiagnostics [Error 1, Line 2, Col 16, Line 2, Col 29, "Type mismatch. Expecting a - 'string -> 'a' -but given a - 'unit -> string' -The type 'string' does not match the type 'unit'"] + |> withDiagnostics [ + (Error 10, Line 2, Col 1, Line 2, Col 30, "Incomplete structured construct at or before this point in expression") + (Error 3571, Line 2, Col 16, Line 2, Col 17, " _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses.")] + [] -let ``Underscore Dot Curried Function With Arguments`` () = +let ``Underscore Dot Curried Function With Arguments - NonAtomic`` () = Fsx """ type MyRecord = {MyRecordField:string} with member x.DoStuff a b c = $"%s{x.MyRecordField} %i{a} %i{b} %i{c}" @@ -40,7 +39,9 @@ let myFunction (x:MyRecord) = x |> _.DoStuff 1 2 3""" |> withLangVersionPreview |> typecheck |> shouldFail - |> withDiagnostics [Error 72, Line 4, Col 36, Line 4, Col 45, "Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved."] + |> withDiagnostics [ + (Error 10, Line 4, Col 1, Line 4, Col 51, "Incomplete structured construct at or before this point in expression") + (Error 3571, Line 4, Col 36, Line 4, Col 37, " _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses.")] [] let ``Underscore Dot Length on string`` () = @@ -115,11 +116,11 @@ let c = ( _ :> obj) """ [] let ``ToString with F# 7`` () = - Fsx "_.ToString()" + Fsx """let x = "a" |> _.ToString()""" |> withLangVersion70 |> typecheck |> shouldFail - |> withSingleDiagnostic (Error 3350, Line 1, Col 1, Line 1, Col 3, "Feature 'underscore dot shorthand for accessor only function' is not available in F# 7.0. Please use language version 'PREVIEW' or greater." ) + |> withSingleDiagnostic (Error 3350, Line 1, Col 16, Line 1, Col 18, "Feature 'underscore dot shorthand for accessor only function' is not available in F# 7.0. Please use language version 'PREVIEW' or greater." ) [] let ``Simple anonymous unary function shorthands compile`` () = From 0f59ea95abfb9859116d90169b75f78567bc5f3c Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 17 Jul 2023 19:06:10 +0200 Subject: [PATCH 42/42] syntax tree baseline updated --- ...tionNallWithSpaceAndUnitApplication.fs.bsl | 16 ++++++++------- .../DotLambda/UnderscoreToString.fs.bsl | 2 ++ .../WithNonTupledFunctionCall.fs.bsl | 20 ++++++++++--------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs.bsl index 26fc387ed22..db09884461c 100644 --- a/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs.bsl +++ b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToFunctionNallWithSpaceAndUnitApplication.fs.bsl @@ -16,16 +16,18 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), Named (SynIdent (myFunc, None), false, None, (1,4--1,10)), None, - App - (NonAtomic, false, - DotLambda - (Ident MyMethodCall, (1,13--1,27), - { UnderscoreRange = (1,13--1,14) - DotRange = (1,14--1,15) }), Const (Unit, (1,28--1,30)), - (1,13--1,30)), (1,4--1,10), Yes (1,0--1,30), + DotLambda + (App + (NonAtomic, false, Ident MyMethodCall, + Const (Unit, (1,28--1,30)), (1,15--1,30)), (1,13--1,30), + { UnderscoreRange = (1,13--1,14) + DotRange = (1,14--1,15) }), (1,4--1,10), Yes (1,0--1,30), { LeadingKeyword = Let (1,0--1,3) InlineKeyword = None EqualsRange = Some (1,11--1,12) })], (1,0--1,30))], PreXmlDocEmpty, [], None, (1,0--1,30), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) + +(1,0)-(1,30) parse error Incomplete structured construct at or before this point in expression +(1,13)-(1,14) parse error _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. diff --git a/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs.bsl index e39acb856a8..66d4159e72a 100644 --- a/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs.bsl +++ b/tests/service/data/SyntaxTree/DotLambda/UnderscoreToString.fs.bsl @@ -14,3 +14,5 @@ ImplFile { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) + +(1,0)-(1,1) parse error _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses. diff --git a/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs.bsl b/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs.bsl index 6ab669c73fd..0070d4d464c 100644 --- a/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs.bsl +++ b/tests/service/data/SyntaxTree/DotLambda/WithNonTupledFunctionCall.fs.bsl @@ -13,21 +13,23 @@ ImplFile (None, SynValInfo ([], SynArgInfo ([], false, None)), None), Named (SynIdent (myFunc, None), false, None, (1,4--1,10)), None, - App - (NonAtomic, false, - App + DotLambda + (App (NonAtomic, false, App (NonAtomic, false, - DotLambda - (Ident ThisIsMyFunction, (1,13--1,31), - { UnderscoreRange = (1,13--1,14) - DotRange = (1,14--1,15) }), Ident a, - (1,13--1,33)), Ident b, (1,13--1,35)), Ident c, - (1,13--1,37)), (1,4--1,10), Yes (1,0--1,37), + App + (NonAtomic, false, Ident ThisIsMyFunction, Ident a, + (1,15--1,33)), Ident b, (1,15--1,35)), Ident c, + (1,15--1,37)), (1,13--1,37), + { UnderscoreRange = (1,13--1,14) + DotRange = (1,14--1,15) }), (1,4--1,10), Yes (1,0--1,37), { LeadingKeyword = Let (1,0--1,3) InlineKeyword = None EqualsRange = Some (1,11--1,12) })], (1,0--1,37))], PreXmlDocEmpty, [], None, (1,0--1,37), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) + +(1,0)-(1,37) parse error Incomplete structured construct at or before this point in expression +(1,13)-(1,14) parse error _. shorthand syntax for lambda functions can only be used with atomic expressions. That means expressions with no whitespace unless enclosed in parentheses.