From 854f080c1fb486e53892894c95cc9351bb04be96 Mon Sep 17 00:00:00 2001 From: Diego Esmerio Date: Sat, 12 May 2018 14:53:17 -0300 Subject: [PATCH 1/3] Remove limitations on custom operation overloads - Check 1:1 by operation/method names instead of count - Remove arg count check --- src/fsharp/TypeChecker.fs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/fsharp/TypeChecker.fs b/src/fsharp/TypeChecker.fs index 79d084e2edb..29bb03c3d23 100755 --- a/src/fsharp/TypeChecker.fs +++ b/src/fsharp/TypeChecker.fs @@ -7165,17 +7165,24 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv Some (nm, maintainsVarSpaceUsingBind, maintainsVarSpace, allowInto, isLikeZip, isLikeJoin, isLikeGroupJoin, joinConditionWord, methInfo)) - let customOperationMethodsIndexedByKeyword = + let customOperationMethodsIndexedByKeyword = customOperationMethods |> Seq.groupBy (fun (nm, _, _, _, _, _, _, _, _) -> nm) - |> Seq.map (fun (nm, g) -> (nm, Seq.toList g)) + |> Seq.map (fun (nm, g) -> + (nm, + g + |> Seq.distinctBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) + |> Seq.toList)) |> dict // Check for duplicates by method name (keywords and method names must be 1:1) let customOperationMethodsIndexedByMethodName = customOperationMethods - |> Seq.groupBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) - |> Seq.map (fun (nm, g) -> (nm, Seq.toList g)) + |> Seq.groupBy (fun (_, _, _, _, _, _, _, _, methInfo) -> methInfo.LogicalName) + |> Seq.map (fun (nm, g) -> + (nm, + g + |> Seq.distinctBy (fun (nm, _, _, _, _, _, _, _, _) -> nm) |> Seq.toList )) |> dict @@ -7809,18 +7816,12 @@ and TcComputationExpression cenv env overallTy mWhole interpExpr builderTy tpenv let maintainsVarSpace = customOperationMaintainsVarSpace nm let maintainsVarSpaceUsingBind = customOperationMaintainsVarSpaceUsingBind nm - let expectedArgCount = expectedArgCountForCustomOperator nm - let dataCompAfterOp = match opExpr with | StripApps(SingleIdent nm, args) -> - if args.Length = expectedArgCount then - // Check for the [] attribute on each argument position - let args = args |> List.mapi (fun i arg -> if isCustomOperationProjectionParameter (i+1) nm then SynExpr.Lambda (false, false, varSpaceSimplePat, arg, arg.Range.MakeSynthetic()) else arg) - mkSynCall methInfo.DisplayName mClause (dataCompPrior :: args) - else - errorR(Error(FSComp.SR.tcCustomOperationHasIncorrectArgCount(nm.idText, expectedArgCount, args.Length), nm.idRange)) - mkSynCall methInfo.DisplayName mClause ([ dataCompPrior ] @ List.init expectedArgCount (fun i -> arbExpr("_arg" + string i, mClause))) + // Check for the [] attribute on each argument position + let args = args |> List.mapi (fun i arg -> if isCustomOperationProjectionParameter (i+1) nm then SynExpr.Lambda (false, false, varSpaceSimplePat, arg, arg.Range.MakeSynthetic()) else arg) + mkSynCall methInfo.DisplayName mClause (dataCompPrior :: args) | _ -> failwith "unreachable" match optionalCont with From 527eb54fc47802ed742c5fd5aa69a9b6a3d22f25 Mon Sep 17 00:00:00 2001 From: Diego Esmerio Date: Mon, 14 May 2018 23:16:37 -0300 Subject: [PATCH 2/3] Updated baselines --- tests/fsharp/typecheck/sigs/neg60.bsl | 2 -- tests/fsharp/typecheck/sigs/neg61.bsl | 10 ++++++++-- tests/fsharp/typecheck/sigs/neg87.bsl | 2 -- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/fsharp/typecheck/sigs/neg60.bsl b/tests/fsharp/typecheck/sigs/neg60.bsl index 9e05fc389f2..21e5c3951b0 100644 --- a/tests/fsharp/typecheck/sigs/neg60.bsl +++ b/tests/fsharp/typecheck/sigs/neg60.bsl @@ -55,8 +55,6 @@ neg60.fs(65,19,65,24): typecheck error FS3087: The custom operation 'where' refe neg60.fs(65,19,65,24): typecheck error FS3087: The custom operation 'where' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. -neg60.fs(65,19,65,24): typecheck error FS3087: The custom operation 'where' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. - neg60.fs(65,19,65,38): typecheck error FS0001: This expression was expected to have type 'bool' but here has type diff --git a/tests/fsharp/typecheck/sigs/neg61.bsl b/tests/fsharp/typecheck/sigs/neg61.bsl index b513bb46a9c..966fa129c22 100644 --- a/tests/fsharp/typecheck/sigs/neg61.bsl +++ b/tests/fsharp/typecheck/sigs/neg61.bsl @@ -9,7 +9,10 @@ neg61.fs(22,13,22,16): typecheck error FS3145: This is not a known query operato neg61.fs(22,13,22,16): typecheck error FS0039: The value or constructor 'zip' is not defined. -neg61.fs(26,13,26,19): typecheck error FS3099: 'select' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected 1 argument(s), but given 0. +neg61.fs(25,13,25,28): typecheck error FS0001: This expression was expected to have type + 'Linq.QuerySource<'a,'b> * ('a -> 'c)' +but here has type + 'Linq.QuerySource' neg61.fs(30,13,30,16): typecheck error FS3145: This is not a known query operator. Query operators are identifiers such as 'select', 'where', 'sortBy', 'thenBy', 'groupBy', 'groupValBy', 'join', 'groupJoin', 'sumBy' and 'averageBy', defined using corresponding methods on the 'QueryBuilder' type. @@ -81,7 +84,10 @@ neg61.fs(148,20,148,23): typecheck error FS3147: This 'let' definition may not b neg61.fs(156,21,156,22): typecheck error FS3147: This 'let' definition may not be used in a query. Only simple value definitions may be used in queries. -neg61.fs(171,13,171,18): typecheck error FS3099: 'sumBy' is used with an incorrect number of arguments. This is a custom operation in this query or computation expression. Expected 1 argument(s), but given 0. +neg61.fs(170,13,170,32): typecheck error FS0001: This expression was expected to have type + 'Linq.QuerySource<'a,'b> * ('a -> 'c)' +but here has type + 'Linq.QuerySource' neg61.fs(174,22,174,23): typecheck error FS0041: No overloads match for method 'Source'. The available overloads are shown below. neg61.fs(174,22,174,23): typecheck error FS0041: Possible overload: 'member Linq.QueryBuilder.Source : source:System.Linq.IQueryable<'T> -> Linq.QuerySource<'T,'Q>'. Type constraint mismatch. The type diff --git a/tests/fsharp/typecheck/sigs/neg87.bsl b/tests/fsharp/typecheck/sigs/neg87.bsl index 5359647ec21..20e2b49f345 100644 --- a/tests/fsharp/typecheck/sigs/neg87.bsl +++ b/tests/fsharp/typecheck/sigs/neg87.bsl @@ -36,5 +36,3 @@ neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refe neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. - -neg87.fsx(14,5,14,10): typecheck error FS3087: The custom operation 'test2' refers to a method which is overloaded. The implementations of custom operations may not be overloaded. From cdc765d231fa4b3f39681d0d43cdfeba033009b7 Mon Sep 17 00:00:00 2001 From: Diego Esmerio Date: Tue, 22 May 2018 15:37:56 -0300 Subject: [PATCH 3/3] New error messages --- .../DataExpressions/QueryExpressions/E_BadGroupValBy01.fs | 4 ++-- .../DataExpressions/QueryExpressions/E_BadGroupValBy02.fs | 2 +- .../DataExpressions/QueryExpressions/E_WhitespaceErrors01.fs | 2 +- .../Expressions/DataExpressions/QueryExpressions/env.lst | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_BadGroupValBy01.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_BadGroupValBy01.fs index 9e338f91218..9ed2865a7ea 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_BadGroupValBy01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_BadGroupValBy01.fs @@ -1,7 +1,7 @@ // #Conformance #DataExpressions #Query // DevDiv:179889, groupValBy was hard to use with poor diagnostics -//'groupValBy' is used with an incorrect number of arguments\. This is a custom operation in this query or computation expression\. Expected 2 argument\(s\), but given 0\.$ -//'groupValBy' is used with an incorrect number of arguments\. This is a custom operation in this query or computation expression\. Expected 2 argument\(s\), but given 1\.$ +//This expression was expected to have type. 'Linq\.QuerySource\<'a,'b\> \* \('a \-\> 'c\) \* \('a \-\> 'd\)' .but here has type. 'Linq\.QuerySource\' +//The member or object constructor 'GroupValBy' takes 3 argument\(s\) but is here given 2\. The required signature is 'member Linq\.QueryBuilder\.GroupValBy \: source\:Linq\.QuerySource\<'T,'Q\> \* resultSelector\:\('T \-\> 'Value\) \* keySelector\:\('T \-\> 'Key\) \-\> Linq\.QuerySource\,'Q\> when 'Key \: equality'\.$ let q1 = query { diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_BadGroupValBy02.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_BadGroupValBy02.fs index bc604c6f5ac..434230874b4 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_BadGroupValBy02.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_BadGroupValBy02.fs @@ -1,6 +1,6 @@ // #Conformance #DataExpressions #Query // DevDiv:210830, groupValBy with poor diagnostics -//This expression was expected to have type.+'System\.Linq\.IGrouping<'a,'b>'.+but here has type.+'unit' +//The member or object constructor 'GroupValBy' takes 3 argument\(s\) but is here given 4\. The required signature is 'member Linq\.QueryBuilder\.GroupValBy \: source\:Linq\.QuerySource\<'T,'Q\> \* resultSelector\:\('T \-\> 'Value\) \* keySelector\:\('T \-\> 'Key\) \-\> Linq\.QuerySource\,'Q\> when 'Key \: equality'\. let words = ["blueberry"; "chimpanzee"; ] let wordGroups = diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_WhitespaceErrors01.fs b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_WhitespaceErrors01.fs index efc3d64dbba..a9dd25f5173 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_WhitespaceErrors01.fs +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/E_WhitespaceErrors01.fs @@ -1,6 +1,6 @@ // #Conformance #DataExpressions #Query // DevDiv:188241, just baselines errors around spacing -//'where' is used with an incorrect number of arguments\. This is a custom operation in this query or computation expression\. Expected 1 argument\(s\), but given 3\.$ +//The member or object constructor 'Where' takes 2 argument\(s\) but is here given 4\. The required signature is 'member Linq\.QueryBuilder\.Where : source:Linq\.QuerySource<'T,'Q> \* predicate:\('T \-> bool\) \-> Linq\.QuerySource<'T,'Q>'\.$ let q1 = // no errors query { diff --git a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/env.lst b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/env.lst index 58c79d96417..63cfbf8bd7b 100644 --- a/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/env.lst +++ b/tests/fsharpqa/Source/Conformance/Expressions/DataExpressions/QueryExpressions/env.lst @@ -13,7 +13,7 @@ NoMT SOURCE=ForWhereJoin01.fs SCFLAGS="--test:ErrorRange NoMT SOURCE=E_WhitespaceErrors01.fs SCFLAGS="--test:ErrorRanges" # E_WhitespaceErrors01.fs NoMT SOURCE=E_WhitespaceErrors02.fs SCFLAGS="--test:ErrorRanges" # E_WhitespaceErrors02.fs NoMT SOURCE=E_WhitespaceErrors03.fs SCFLAGS="--test:ErrorRanges" # E_WhitespaceErrors03.fs -NoMT SOURCE=E_BadGroupValBy01.fs SCFLAGS="--test:ErrorRanges" # E_BadGroupValBy01.fs +NoMT SOURCE=E_BadGroupValBy01.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_BadGroupValBy01.fs NoMT SOURCE=E_BadGroupValBy02.fs SCFLAGS="--test:ErrorRanges --flaterrors" # E_BadGroupValBy02.fs NoMT SOURCE=E_FirstOrDefaultWithNulls01.fs SCFLAGS="--test:ErrorRanges -r:Utils.dll" # E_FirstOrDefaultWithNulls01.fs