diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md index 17ccb2f4019..e4f784a1045 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.400.md @@ -14,3 +14,7 @@ ### Added * Generate new `Equals` overload to avoid boxing for structural comparison ([PR #16857](https://github.com/dotnet/fsharp/pull/16857)) + +### Changed + +* Improve error of Active Pattern case Argument Count Not Match ([PR #16846](https://github.com/dotnet/fsharp/pull/16846)) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 16e46ae706b..5d42f2fd416 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -5119,22 +5119,77 @@ and TcPatLongIdentActivePatternCase warnOnUpper (cenv: cenv) (env: TcEnv) vFlags let vExprTy = vExpr.Type let activePatArgsAsSynPats, patArg = - match args with - | [] -> [], SynPat.Const(SynConst.Unit, m) - | _ -> - // This bit of type-directed analysis ensures that parameterized partial active patterns returning unit do not need to take an argument - let dtys, retTy = stripFunTy g vExprTy - - if dtys.Length = args.Length + 1 && - ((isOptionTy g retTy && isUnitTy g (destOptionTy g retTy)) || - (isValueOptionTy g retTy && isUnitTy g (destValueOptionTy g retTy))) || - // `bool` partial AP always be treated as `unit option` - // For `val (|P|_|) : _ -> bool`, only allow `match x with | P -> ...` - // For `val (|P|_|) : _ -> _ -> bool`, only allow `match x with | P parameter -> ...` - (not apinfo.IsTotal && isBoolTy g retTy) then + let rec IsNotSolved ty = + match ty with + | TType_var(v, _) when v.IsSolved -> + match v.Solution with + | Some t -> IsNotSolved t + | None -> false + | TType_var _ -> true + | _ -> false + + // only cases which return unit or unresolved type (in AP definition) can omit output arg + let canOmit retTy = isUnitTy g retTy || IsNotSolved retTy + + // This bit of type-directed analysis ensures that parameterized partial active patterns returning unit do not need to take an argument + let dtys, retTy = stripFunTy g vExprTy + let paramCount = if dtys.Length = 0 then 0 else dtys.Length - 1 + + let showErrMsg returnCount = + let fmtExprArgs paramCount = + let rec loop i (sb: Text.StringBuilder) = + let cutoff = 10 + if i > paramCount then sb.ToString() + elif i > cutoff then sb.Append("...").ToString() + else loop (i + 1) (sb.Append(" e").Append i) + + loop 1 (Text.StringBuilder()) + + let caseName = apinfo.ActiveTags[idx] + let msg = + match paramCount, returnCount with + | 0, 0 -> FSComp.SR.tcActivePatternArgsCountNotMatchNoArgsNoPat(caseName, caseName) + | 0, _ -> FSComp.SR.tcActivePatternArgsCountNotMatchOnlyPat(caseName) + | _, 0 -> FSComp.SR.tcActivePatternArgsCountNotMatchArgs(paramCount, caseName, fmtExprArgs paramCount) + | _, _ -> FSComp.SR.tcActivePatternArgsCountNotMatchArgsAndPat(paramCount, caseName, fmtExprArgs paramCount) + error(Error(msg, m)) + + // partial active pattern (returning bool) doesn't have output arg + if (not apinfo.IsTotal && isBoolTy g retTy) then + checkLanguageFeatureError g.langVersion LanguageFeature.BooleanReturningAndReturnTypeDirectedPartialActivePattern m + if paramCount = List.length args then args, SynPat.Const(SynConst.Unit, m) else - List.frontAndBack args + showErrMsg 0 + + // for single case active pattern, if not all parameter provided, output will be a function + // that takes the remaining parameter as input + elif apinfo.IsTotal && apinfo.ActiveTags.Length = 1 && dtys.Length >= args.Length && not args.IsEmpty then + List.frontAndBack args + + // active pattern cases returning unit or unknown things (in AP definition) can omit output arg + elif paramCount = args.Length then + let caseRetTy = + if isOptionTy g retTy then destOptionTy g retTy + elif isValueOptionTy g retTy then destValueOptionTy g retTy + elif isChoiceTy g retTy then destChoiceTy g retTy idx + else retTy + + // only cases which return unit or unresolved type (in AP definition) can omit output arg + if canOmit caseRetTy then + args, SynPat.Const(SynConst.Unit, m) + else + showErrMsg 1 + + // active pattern in function param (e.g. let f (|P|_|) = ...) + elif IsNotSolved vExprTy then + List.frontAndBack args + + // args count should equal to AP function params count + elif dtys.Length <> args.Length then + showErrMsg 1 + else + List.frontAndBack args if not (isNil activePatArgsAsSynPats) && apinfo.ActiveTags.Length <> 1 then errorR (Error (FSComp.SR.tcRequireActivePatternWithOneResult (), m)) diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index d7dfe371f3e..25047f08e39 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1747,4 +1747,8 @@ featureReuseSameFieldsInStructUnions,"Share underlying fields in a [] di 3864,tooManyMethodsInDotNetTypeWritingAssembly,"The type '%s' has too many methods. Found: '%d', maximum: '%d'" 3865,parsOnlySimplePatternsAreAllowedInConstructors,"Only simple patterns are allowed in primary constructors" 3866,chkStaticAbstractInterfaceMembers,"A static abstract non-virtual interface member should only be called via type parameter (for example: 'T.%s)." -3867,chkStaticAbstractMembersOnClasses,"Classes cannot contain static abstract members." \ No newline at end of file +3867,chkStaticAbstractMembersOnClasses,"Classes cannot contain static abstract members." +3868,tcActivePatternArgsCountNotMatchNoArgsNoPat,"This active pattern does not expect any arguments, i.e., it should be used like '%s' instead of '%s x'." +3868,tcActivePatternArgsCountNotMatchOnlyPat,"This active pattern expects exactly one pattern argument, e.g., '%s pat'." +3868,tcActivePatternArgsCountNotMatchArgs,"This active pattern expects %d expression argument(s), e.g., '%s%s'." +3868,tcActivePatternArgsCountNotMatchArgsAndPat,"This active pattern expects %d expression argument(s) and a pattern argument, e.g., '%s%s pat'." diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index eb2ceb9a6aa..02a5497cbb1 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -3689,6 +3689,17 @@ let isOptionTy (g: TcGlobals) ty = | ValueNone -> false | ValueSome tcref -> tyconRefEq g g.option_tcr_canon tcref +let isChoiceTy (g: TcGlobals) ty = + match tryTcrefOfAppTy g ty with + | ValueNone -> false + | ValueSome tcref -> + tyconRefEq g g.choice2_tcr tcref || + tyconRefEq g g.choice3_tcr tcref || + tyconRefEq g g.choice4_tcr tcref || + tyconRefEq g g.choice5_tcr tcref || + tyconRefEq g g.choice6_tcr tcref || + tyconRefEq g g.choice7_tcr tcref + let tryDestOptionTy g ty = match argsOfAppTy g ty with | [ty1] when isOptionTy g ty -> ValueSome ty1 @@ -3699,6 +3710,11 @@ let tryDestValueOptionTy g ty = | [ty1] when isValueOptionTy g ty -> ValueSome ty1 | _ -> ValueNone +let tryDestChoiceTy g ty idx = + match argsOfAppTy g ty with + | ls when isChoiceTy g ty && ls.Length > idx -> ValueSome ls[idx] + | _ -> ValueNone + let destOptionTy g ty = match tryDestOptionTy g ty with | ValueSome ty -> ty @@ -3709,6 +3725,11 @@ let destValueOptionTy g ty = | ValueSome ty -> ty | ValueNone -> failwith "destValueOptionTy: not a value option type" +let destChoiceTy g ty idx = + match tryDestChoiceTy g ty idx with + | ValueSome ty -> ty + | ValueNone -> failwith "destChoiceTy: not a Choice type" + let isNullableTy (g: TcGlobals) ty = match tryTcrefOfAppTy g ty with | ValueNone -> false diff --git a/src/Compiler/TypedTree/TypedTreeOps.fsi b/src/Compiler/TypedTree/TypedTreeOps.fsi index 258cf320bc8..1740cbb530d 100755 --- a/src/Compiler/TypedTree/TypedTreeOps.fsi +++ b/src/Compiler/TypedTree/TypedTreeOps.fsi @@ -1547,6 +1547,9 @@ val isValueOptionTy: TcGlobals -> TType -> bool /// Determine if a type is an option type val isOptionTy: TcGlobals -> TType -> bool +/// Determine if a type is an Choice type +val isChoiceTy: TcGlobals -> TType -> bool + /// Take apart an option type val destOptionTy: TcGlobals -> TType -> TType @@ -1556,6 +1559,12 @@ val tryDestOptionTy: TcGlobals -> TType -> TType voption /// Try to take apart an option type val destValueOptionTy: TcGlobals -> TType -> TType +/// Take apart an Choice type +val tryDestChoiceTy: TcGlobals -> TType -> int -> TType voption + +/// Try to take apart an Choice type +val destChoiceTy: TcGlobals -> TType -> int -> TType + /// Determine is a type is a System.Nullable type val isNullableTy: TcGlobals -> TType -> bool diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 1e331ca0c1e..a4e8e281866 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -1122,6 +1122,26 @@ (Navržený název) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. Význam _ je tady nejednoznačný. Nelze ho použít pro proměnnou typu discard a zkratku funkce ve stejném oboru. diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index cb5bb611c16..f920991d5f4 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -1122,6 +1122,26 @@ (Empfohlener Name) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. Die Bedeutung von "_" ist hier mehrdeutig. Dieses Zeichen kann nicht in demselben Bereich für eine verworfene Variable und ein Funktionskürzel verwendet werden. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 5a5520af8d0..f6054605ffa 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -1122,6 +1122,26 @@ (Nombre sugerido) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. El significado de _ es ambiguo aquí. No se puede usar para una variable descartada y una función abreviada en el mismo ámbito. diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 95f24fd7db2..5e9349ac3ae 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -1122,6 +1122,26 @@ (Nom suggéré) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. La signification de _ est ici ambiguë. Il ne peut pas être utilisé pour une variable ignorée et un raccourci de fonction dans la même portée. diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index a4468df7f8e..b936cdc3642 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -1122,6 +1122,26 @@ (Nome consigliato) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. Il significato di _ è ambiguo in questo contesto. Non può essere utilizzato per una variabile eliminata e una sintassi abbreviata di funzione nello stesso ambito. diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 358cf700cf0..add97ebcbee 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -1122,6 +1122,26 @@ (推奨される名前) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + 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 5784d4264e1..005109642a3 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -1122,6 +1122,26 @@ (제안된 이름) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + 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 f2858d49504..b11a525807f 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -1122,6 +1122,26 @@ (Sugerowana nazwa) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. Znaczenie elementu _ jest tutaj niejednoznaczne. Nie można go użyć dla odrzuconej zmiennej i skrótu funkcji w tym samym zakresie. diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index cdff3ed5b34..78b23fc160d 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -1122,6 +1122,26 @@ (Nome sugerido) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. O significado de _ é ambíguo aqui. Ele não pode ser usado para uma variável descartada e uma abreviação de função no mesmo escopo. diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 9d1790e8dc9..670b03ce32a 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -1122,6 +1122,26 @@ (предложенное имя) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + 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 b8bdd5e9cc6..e0552438c26 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -1122,6 +1122,26 @@ (Önerilen ad) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + The meaning of _ is ambiguous here. It cannot be used for a discarded variable and a function shorthand in the same scope. _ öğesinin anlamı burada belirsiz. Aynı kapsamda, atılan bir değişken ve işlev kısaltması için kullanılamaz. diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index f06487e86bd..f53a45b0200 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -1122,6 +1122,26 @@ (建议名称) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + 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 f80470220b3..a80e8852c30 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -1122,6 +1122,26 @@ (建議的名稱) + + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + This active pattern expects {0} expression argument(s), e.g., '{1}{2}'. + + + + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + This active pattern expects {0} expression argument(s) and a pattern argument, e.g., '{1}{2} pat'. + + + + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + This active pattern does not expect any arguments, i.e., it should be used like '{0}' instead of '{1} x'. + + + + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + This active pattern expects exactly one pattern argument, e.g., '{0} pat'. + + 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/ErrorMessages/ActivePatternArgCountMismatchTest.fs b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ActivePatternArgCountMismatchTest.fs new file mode 100644 index 00000000000..77fd98449b0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/ErrorMessages/ActivePatternArgCountMismatchTest.fs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +namespace ErrorMessages + +open Xunit +open FSharp.Test.Compiler + +module ``Active Pattern argument count mismatch test`` = + + [] + let ``test``() = + FSharp """ +let (|IsEven|_|) x = x % 2 = 0 +match 1 with +| IsEven xxx -> () +| _ -> printfn "Odd!" + +let (|Ignore|) x = () +match 1 with +| Ignore () () -> printfn "Ignored!" +| _ -> () + +let (|Equals|_|) z y x = x = y +match 1 with +| Equals "" 2 xxx -> () +| _ -> printfn "Not Equal" + +let (|A|) a b c d = d +match 1 with +| A -> () +| _ -> () + """ |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3868, Line 4, Col 3, Line 4, Col 13, "This active pattern does not expect any arguments, i.e., it should be used like 'IsEven' instead of 'IsEven x'.") + (Error 3868, Line 9, Col 3, Line 9, Col 15, "This active pattern expects exactly one pattern argument, e.g., 'Ignore pat'.") + (Error 3868, Line 14, Col 3, Line 14, Col 18, "This active pattern expects 2 expression argument(s), e.g., 'Equals e1 e2'.") + (Error 3868, Line 19, Col 3, Line 19, Col 4, "This active pattern expects 3 expression argument(s) and a pattern argument, e.g., 'A e1 e2 e3 pat'.") + ] diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 6924b94f448..fec09aa52d9 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -208,6 +208,7 @@ + @@ -331,6 +332,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/BooleanReturningAndReturnTypeDirectedPartialActivePatternTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/BooleanReturningAndReturnTypeDirectedPartialActivePatternTests.fs index 26461598a5b..c8ba6fba856 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/BooleanReturningAndReturnTypeDirectedPartialActivePatternTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/BooleanReturningAndReturnTypeDirectedPartialActivePatternTests.fs @@ -75,7 +75,8 @@ let (|OddVOption|_|) x = if x % 2 = 1 then ValueSome() else ValueNone [] let ``Can not receive result from bool active pattern`` () = - FSharp """let (|IsA|_|) x = x = "A" + FSharp """#nowarn "20" +let (|IsA|_|) x = x = "A" match "A" with | IsA result -> "A" @@ -93,34 +94,9 @@ match "A" with |> typecheck |> shouldFail |> withDiagnostics [ - (Error 1, Line 4, Col 3, Line 4, Col 13, - "This expression was expected to have type - 'string -> bool' -but here has type - 'bool' ") - (Error 39, Line 4, Col 7, Line 4, Col 13, - "The value or constructor 'result' is not defined. Maybe you want one of the following: + (Error 3868, Line 5, Col 3, Line 5, Col 13, "This active pattern does not expect any arguments, i.e., it should be used like 'IsA' instead of 'IsA x'.") + (Error 3868, Line 9, Col 3, Line 9, Col 13, "This active pattern does not expect any arguments, i.e., it should be used like 'IsA' instead of 'IsA x'.") + (Error 0039, Line 9, Col 17, Line 9, Col 23, "The value or constructor 'result' is not defined. Maybe you want one of the following: Result") - (Warning 20, Line 3, Col 1, Line 5, Col 15, - "The result of this expression has type 'string' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'."); - (Error 1, Line 8, Col 3, Line 8, Col 13, - "This expression was expected to have type - 'string -> bool' -but here has type - 'bool' ") - (Error 39, Line 8, Col 7, Line 8, Col 13, - "The value or constructor 'result' is not defined. Maybe you want one of the following: - Result"); - (Error 39, Line 8, Col 17, Line 8, Col 23, - "The value or constructor 'result' is not defined. Maybe you want one of the following: - Result") - (Warning 20, Line 7, Col 1, Line 9, Col 15, - "The result of this expression has type 'string' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'."); - (Error 1, Line 12, Col 3, Line 12, Col 30, - "This expression was expected to have type - 'string -> bool' -but here has type - 'bool' ") - (Warning 20, Line 11, Col 1, Line 13, Col 21, - "The result of this expression has type 'string' and is implicitly ignored. Consider using 'ignore' to discard this value explicitly, e.g. 'expr |> ignore', or 'let' to bind the result to a name, e.g. 'let result = expr'.") + (Error 3868, Line 13, Col 3, Line 13, Col 30, "This active pattern does not expect any arguments, i.e., it should be used like 'IsA' instead of 'IsA x'.") ]