diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 85a72fa3222..7ee34cb5cd8 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -579,15 +579,13 @@ module TcRecdUnionAndEnumDeclarations = | SynExpr.Const (synConst, _) -> let konst = TcConst cenv fieldTy valueRange env synConst MakeEnumCaseSpec cenv env parent attrs thisTy caseRange id xmldoc konst - | _ when cenv.g.langVersion.SupportsFeature LanguageFeature.ArithmeticInLiterals -> + | _ -> let expr, actualTy, _ = TcExprOfUnknownType cenv env tpenv valueExpr UnifyTypes cenv env valueRange fieldTy actualTy match EvalLiteralExprOrAttribArg cenv.g expr with | Expr.Const (konst, _, _) -> MakeEnumCaseSpec cenv env parent attrs thisTy caseRange id xmldoc konst | _ -> error(Error(FSComp.SR.tcInvalidEnumerationLiteral(), valueRange)) - | _ -> - error(Error(FSComp.SR.tcInvalidEnumerationLiteral(), valueRange)) let TcEnumDecls (cenv: cenv) env tpenv parent thisTy enumCases = let g = cenv.g diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index d17728dccf8..e4b20477ffd 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1559,7 +1559,7 @@ featureMatchNotAllowedForUnionCaseWithNoData,"Pattern match discard is not allow featureCSharpExtensionAttributeNotRequired,"Allow implicit Extension attribute on declaring types, modules" featureErrorForNonVirtualMembersOverrides,"Raises errors for non-virtual members overrides" featureWarningWhenInliningMethodImplNoInlineMarkedFunction,"Raises warnings when 'let inline ... =' is used together with [] attribute. Function is not getting inlined." -featureArithmeticInLiterals,"Allow arithmetic and logical operations in literals" +featureArithmeticInLiterals,"Arithmetic and logical operations in literals, enum definitions and attributes" featureErrorReportingOnStaticClasses,"Error reporting on static classes" featureTryWithInSeqExpressions,"Support for try-with in sequence expressions" featureWarningWhenCopyAndUpdateRecordChangesAllFields,"Raises warnings when an copy-and-update record expression changes all fields of a record." diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fs b/src/Compiler/Facilities/DiagnosticsLogger.fs index 83f59e52162..4f94d6b4fbb 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fs +++ b/src/Compiler/Facilities/DiagnosticsLogger.fs @@ -810,6 +810,13 @@ let NormalizeErrorString (text: string MaybeNull) = buf.ToString() +/// Indicates whether a language feature check should be skipped. Typically used in recursive functions +/// where we don't want repeated recursive calls to raise the same diagnostic multiple times. +[] +type internal SuppressLanguageFeatureCheck = + | Yes + | No + let private tryLanguageFeatureErrorAux (langVersion: LanguageVersion) (langFeature: LanguageFeature) (m: range) = if not (langVersion.SupportsFeature langFeature) then let featureStr = LanguageVersion.GetFeatureString langFeature diff --git a/src/Compiler/Facilities/DiagnosticsLogger.fsi b/src/Compiler/Facilities/DiagnosticsLogger.fsi index 8357c003321..03b27b922a0 100644 --- a/src/Compiler/Facilities/DiagnosticsLogger.fsi +++ b/src/Compiler/Facilities/DiagnosticsLogger.fsi @@ -425,6 +425,13 @@ val NewlineifyErrorString: message: string -> string /// which is decoded by the IDE with 'NewlineifyErrorString' back into newlines, so that multi-line errors can be displayed in QuickInfo val NormalizeErrorString: text: string -> string +/// Indicates whether a language feature check should be skipped. Typically used in recursive functions +/// where we don't want repeated recursive calls to raise the same diagnostic multiple times. +[] +type SuppressLanguageFeatureCheck = + | Yes + | No + val checkLanguageFeatureError: langVersion: LanguageVersion -> langFeature: LanguageFeature -> m: range -> unit val checkLanguageFeatureAndRecover: langVersion: LanguageVersion -> langFeature: LanguageFeature -> m: range -> unit diff --git a/src/Compiler/TypedTree/TypedTreeOps.fs b/src/Compiler/TypedTree/TypedTreeOps.fs index a6ce02a1c29..7021a523e88 100644 --- a/src/Compiler/TypedTree/TypedTreeOps.fs +++ b/src/Compiler/TypedTree/TypedTreeOps.fs @@ -9659,11 +9659,13 @@ let EvalArithBinOp (opInt8, opInt16, opInt32, opInt64, opUInt8, opUInt16, opUInt with :? System.OverflowException -> error (Error ( FSComp.SR.tastConstantExpressionOverflow(), m)) // See also PostTypeCheckSemanticChecks.CheckAttribArgExpr, which must match this precisely -let rec EvalAttribArgExpr (g: TcGlobals) x = +let rec EvalAttribArgExpr suppressLangFeatureCheck (g: TcGlobals) (x: Expr) = let ignore (_x: 'a) = Unchecked.defaultof<'a> let ignore2 (_x: 'a) (_y: 'a) = Unchecked.defaultof<'a> - let arithmeticInLiteralsEnabled = g.langVersion.SupportsFeature LanguageFeature.ArithmeticInLiterals + let inline checkFeature() = + if suppressLangFeatureCheck = SuppressLanguageFeatureCheck.No then + checkLanguageFeatureAndRecover g.langVersion LanguageFeature.ArithmeticInLiterals x.Range match x with @@ -9693,61 +9695,68 @@ let rec EvalAttribArgExpr (g: TcGlobals) x = | TypeOfExpr g _ -> x | TypeDefOfExpr g _ -> x | Expr.Op (TOp.Coerce, _, [arg], _) -> - EvalAttribArgExpr g arg + EvalAttribArgExpr suppressLangFeatureCheck g arg | EnumExpr g arg1 -> - EvalAttribArgExpr g arg1 + EvalAttribArgExpr suppressLangFeatureCheck g arg1 // Detect bitwise or of attribute flags | AttribBitwiseOrExpr g (arg1, arg2) -> - let v1 = EvalAttribArgExpr g arg1 + let v1 = EvalAttribArgExpr suppressLangFeatureCheck g arg1 match v1 with | IntegerConstExpr -> - EvalArithBinOp ((|||), (|||), (|||), (|||), (|||), (|||), (|||), (|||), ignore2, ignore2) v1 (EvalAttribArgExpr g arg2) + EvalArithBinOp ((|||), (|||), (|||), (|||), (|||), (|||), (|||), (|||), ignore2, ignore2) v1 (EvalAttribArgExpr suppressLangFeatureCheck g arg2) | _ -> errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range)) x | SpecificBinopExpr g g.unchecked_addition_vref (arg1, arg2) -> - // At compile-time we check arithmetic - let v1, v2 = EvalAttribArgExpr g arg1, EvalAttribArgExpr g arg2 + let v1, v2 = EvalAttribArgExpr suppressLangFeatureCheck g arg1, EvalAttribArgExpr suppressLangFeatureCheck g arg2 + match v1, v2 with | Expr.Const (Const.String x1, m, ty), Expr.Const (Const.String x2, _, _) -> Expr.Const (Const.String (x1 + x2), m, ty) - | Expr.Const (Const.Char x1, m, ty), Expr.Const (Const.Char x2, _, _) when arithmeticInLiteralsEnabled -> + | Expr.Const (Const.Char x1, m, ty), Expr.Const (Const.Char x2, _, _) -> + checkFeature() Expr.Const (Const.Char (x1 + x2), m, ty) | _ -> - if arithmeticInLiteralsEnabled then - EvalArithBinOp (Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+)) v1 v2 - else - errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range)) - x - | SpecificBinopExpr g g.unchecked_subtraction_vref (arg1, arg2) when arithmeticInLiteralsEnabled -> - let v1, v2 = EvalAttribArgExpr g arg1, EvalAttribArgExpr g arg2 + checkFeature() + EvalArithBinOp (Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+), Checked.(+)) v1 v2 + | SpecificBinopExpr g g.unchecked_subtraction_vref (arg1, arg2) -> + checkFeature() + let v1, v2 = EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1, EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2 + match v1, v2 with | Expr.Const (Const.Char x1, m, ty), Expr.Const (Const.Char x2, _, _) -> Expr.Const (Const.Char (x1 - x2), m, ty) | _ -> EvalArithBinOp (Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-), Checked.(-)) v1 v2 - | SpecificBinopExpr g g.unchecked_multiply_vref (arg1, arg2) when arithmeticInLiteralsEnabled -> - EvalArithBinOp (Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*)) (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) - | SpecificBinopExpr g g.unchecked_division_vref (arg1, arg2) when arithmeticInLiteralsEnabled -> - EvalArithBinOp ((/), (/), (/), (/), (/), (/), (/), (/), (/), (/)) (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) - | SpecificBinopExpr g g.unchecked_modulus_vref (arg1, arg2) when arithmeticInLiteralsEnabled -> - EvalArithBinOp ((%), (%), (%), (%), (%), (%), (%), (%), (%), (%)) (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) - | SpecificBinopExpr g g.bitwise_shift_left_vref (arg1, arg2) when arithmeticInLiteralsEnabled -> - EvalArithShiftOp ((<<<), (<<<), (<<<), (<<<), (<<<), (<<<), (<<<), (<<<)) (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) - | SpecificBinopExpr g g.bitwise_shift_right_vref (arg1, arg2) when arithmeticInLiteralsEnabled -> - EvalArithShiftOp ((>>>), (>>>), (>>>), (>>>), (>>>), (>>>), (>>>), (>>>)) (EvalAttribArgExpr g arg1) (EvalAttribArgExpr g arg2) - | SpecificBinopExpr g g.bitwise_and_vref (arg1, arg2) when arithmeticInLiteralsEnabled -> - let v1 = EvalAttribArgExpr g arg1 + | SpecificBinopExpr g g.unchecked_multiply_vref (arg1, arg2) -> + checkFeature() + EvalArithBinOp (Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*), Checked.(*)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2) + | SpecificBinopExpr g g.unchecked_division_vref (arg1, arg2) -> + checkFeature() + EvalArithBinOp ((/), (/), (/), (/), (/), (/), (/), (/), (/), (/)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2) + | SpecificBinopExpr g g.unchecked_modulus_vref (arg1, arg2) -> + checkFeature() + EvalArithBinOp ((%), (%), (%), (%), (%), (%), (%), (%), (%), (%)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2) + | SpecificBinopExpr g g.bitwise_shift_left_vref (arg1, arg2) -> + checkFeature() + EvalArithShiftOp ((<<<), (<<<), (<<<), (<<<), (<<<), (<<<), (<<<), (<<<)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2) + | SpecificBinopExpr g g.bitwise_shift_right_vref (arg1, arg2) -> + checkFeature() + EvalArithShiftOp ((>>>), (>>>), (>>>), (>>>), (>>>), (>>>), (>>>), (>>>)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2) + | SpecificBinopExpr g g.bitwise_and_vref (arg1, arg2) -> + checkFeature() + let v1 = EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1 match v1 with | IntegerConstExpr -> - EvalArithBinOp ((&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), ignore2, ignore2) v1 (EvalAttribArgExpr g arg2) + EvalArithBinOp ((&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), (&&&), ignore2, ignore2) v1 (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg2) | _ -> errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range)) x - | SpecificUnopExpr g g.unchecked_unary_minus_vref arg1 when arithmeticInLiteralsEnabled -> - let v1 = EvalAttribArgExpr g arg1 + | SpecificUnopExpr g g.unchecked_unary_minus_vref arg1 -> + checkFeature() + let v1 = EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1 match v1 with | SignedConstExpr -> @@ -9755,18 +9764,23 @@ let rec EvalAttribArgExpr (g: TcGlobals) x = | _ -> errorR (Error ( FSComp.SR.tastNotAConstantExpression(), v1.Range)) x - | SpecificUnopExpr g g.unchecked_unary_plus_vref arg1 when arithmeticInLiteralsEnabled -> - EvalArithUnOp ((~+), (~+), (~+), (~+), (~+), (~+), (~+), (~+), (~+), (~+)) (EvalAttribArgExpr g arg1) - | SpecificUnopExpr g g.unchecked_unary_not_vref arg1 when arithmeticInLiteralsEnabled -> - match EvalAttribArgExpr g arg1 with + | SpecificUnopExpr g g.unchecked_unary_plus_vref arg1 -> + checkFeature() + EvalArithUnOp ((~+), (~+), (~+), (~+), (~+), (~+), (~+), (~+), (~+), (~+)) (EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1) + | SpecificUnopExpr g g.unchecked_unary_not_vref arg1 -> + checkFeature() + + match EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g arg1 with | Expr.Const (Const.Bool value, m, ty) -> Expr.Const (Const.Bool (not value), m, ty) | expr -> errorR (Error ( FSComp.SR.tastNotAConstantExpression(), expr.Range)) x // Detect logical operations on booleans, which are represented as a match expression - | Expr.Match (decision = TDSwitch (input = input; cases = [ TCase (DecisionTreeTest.Const (Const.Bool test), TDSuccess ([], targetNum)) ]); targets = [| TTarget (_, t0, _); TTarget (_, t1, _) |]) when arithmeticInLiteralsEnabled -> - match EvalAttribArgExpr g (stripDebugPoints input) with + | Expr.Match (decision = TDSwitch (input = input; cases = [ TCase (DecisionTreeTest.Const (Const.Bool test), TDSuccess ([], targetNum)) ]); targets = [| TTarget (_, t0, _); TTarget (_, t1, _) |]) -> + checkFeature() + + match EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g (stripDebugPoints input) with | Expr.Const (Const.Bool value, _, _) -> let pass, fail = if targetNum = 0 then @@ -9775,9 +9789,9 @@ let rec EvalAttribArgExpr (g: TcGlobals) x = t1, t0 if value = test then - EvalAttribArgExpr g (stripDebugPoints pass) + EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g (stripDebugPoints pass) else - EvalAttribArgExpr g (stripDebugPoints fail) + EvalAttribArgExpr SuppressLanguageFeatureCheck.Yes g (stripDebugPoints fail) | _ -> errorR (Error ( FSComp.SR.tastNotAConstantExpression(), x.Range)) x @@ -9814,10 +9828,10 @@ let EvalLiteralExprOrAttribArg g x = match x with | Expr.Op (TOp.Coerce, _, [Expr.Op (TOp.Array, [elemTy], args, m)], _) | Expr.Op (TOp.Array, [elemTy], args, m) -> - let args = args |> List.map (EvalAttribArgExpr g) + let args = args |> List.map (EvalAttribArgExpr SuppressLanguageFeatureCheck.No g) Expr.Op (TOp.Array, [elemTy], args, m) | _ -> - EvalAttribArgExpr g x + EvalAttribArgExpr SuppressLanguageFeatureCheck.No g x // Take into account the fact that some "instance" members are compiled as static // members when using CompilationRepresentation.Static, or any non-virtual instance members diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index da1d76c755b..00c237c56e0 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - Povolit aritmetické a logické operace v literálech + Arithmetic and logical operations in literals, enum definitions and attributes + Povolit aritmetické a logické operace v literálech diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 186ce458734..d872cb7505c 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - Arithmetische und logische Vorgänge in Literalen zulassen + Arithmetic and logical operations in literals, enum definitions and attributes + Arithmetische und logische Vorgänge in Literalen zulassen diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index f15aea23087..c4b91ebe5c0 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - Permitir operaciones aritméticas y lógicas en literales + Arithmetic and logical operations in literals, enum definitions and attributes + Permitir operaciones aritméticas y lógicas en literales diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 3643c1aa164..fa0097685f7 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - Autoriser les opérations arithmétiques et logiques dans les littéraux + Arithmetic and logical operations in literals, enum definitions and attributes + Autoriser les opérations arithmétiques et logiques dans les littéraux diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index 0e7df41a2a9..b78a447ef64 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - Consentire operazioni aritmetiche e logiche in valori letterali + Arithmetic and logical operations in literals, enum definitions and attributes + Consentire operazioni aritmetiche e logiche in valori letterali diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index 284b52c46d5..1cb3a65dcbe 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - リテラルで算術演算と論理演算を許可する + Arithmetic and logical operations in literals, enum definitions and attributes + リテラルで算術演算と論理演算を許可する diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index dc86b3fea82..e1ec9213dba 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - 리터럴에서 산술 및 논리 연산 허용 + Arithmetic and logical operations in literals, enum definitions and attributes + 리터럴에서 산술 및 논리 연산 허용 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 31ffd49b289..6b2e7974b61 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - Zezwalaj na operacje arytmetyczne i logiczne w literałach + Arithmetic and logical operations in literals, enum definitions and attributes + Zezwalaj na operacje arytmetyczne i logiczne w literałach diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 95e059af656..1c8aac92852 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - Permitir operações aritméticas e lógicas em literais + Arithmetic and logical operations in literals, enum definitions and attributes + Permitir operações aritméticas e lógicas em literais diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index c0103a792b6..d2008f0795f 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - Разрешить арифметические и логические операции в литералах + Arithmetic and logical operations in literals, enum definitions and attributes + Разрешить арифметические и логические операции в литералах diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 122ef5f06c9..87b66eb5815 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - Sabit değerlerle aritmetik ve mantıksal işlemlere izin ver + Arithmetic and logical operations in literals, enum definitions and attributes + Sabit değerlerle aritmetik ve mantıksal işlemlere izin ver diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index c304296d55d..43a052c80b2 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - 允许在文本中进行算术和逻辑运算 + Arithmetic and logical operations in literals, enum definitions and attributes + 允许在文本中进行算术和逻辑运算 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index a5a3e73039b..e21a616c5a7 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -188,8 +188,8 @@ - Allow arithmetic and logical operations in literals - 允許常值中的算術和邏輯運算 + Arithmetic and logical operations in literals, enum definitions and attributes + 允許常值中的算術和邏輯運算 diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs index c168d88fba4..b1614c07ac9 100644 --- a/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/Literals.fs @@ -228,4 +228,31 @@ let [] x = 1 + System.DateTime.Now.Hour EndLine = 4 EndColumn = 49 } Message = "This is not a valid constant expression or custom attribute value" } - ] \ No newline at end of file + ] + + [] + let ``Arithmetic cannot be used in enums, literals and attributes in lang version70``() = + FSharp """ +module LiteralArithmetic + +open System.Runtime.CompilerServices + +[] +let x () = 3 + +let [] lit = 1 <<< (7 * 10) + +type E = + | A = (1 <<< 2) + | B = 1 + | C = (5 / 3 * 4) + """ + |> withLangVersion70 + |> typecheck + |> shouldFail + |> withDiagnostics [ + (Error 3350, Line 6, Col 19, Line 6, Col 30, "Feature 'Arithmetic and logical operations in literals, enum definitions and attributes' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.") + (Error 3350, Line 9, Col 23, Line 9, Col 37, "Feature 'Arithmetic and logical operations in literals, enum definitions and attributes' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.") + (Error 3350, Line 12, Col 12, Line 12, Col 19, "Feature 'Arithmetic and logical operations in literals, enum definitions and attributes' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.") + (Error 3350, Line 14, Col 12, Line 14, Col 21, "Feature 'Arithmetic and logical operations in literals, enum definitions and attributes' is not available in F# 7.0. Please use language version 'PREVIEW' or greater.") + ] diff --git a/tests/fsharp/core/nameof/version46/test.fsx b/tests/fsharp/core/nameof/version46/test.fsx index 214bb498d90..0652ca028eb 100644 --- a/tests/fsharp/core/nameof/version46/test.fsx +++ b/tests/fsharp/core/nameof/version46/test.fsx @@ -32,7 +32,7 @@ //The value or constructor 'nameof' is not defined. //The value or constructor 'nameof' is not defined. //This is not a valid constant expression or custom attribute value -//This is not a valid constant expression or custom attribute value +//Feature 'Arithmetic and logical operations in literals, enum definitions and attributes' is not available in F# 4.6. Please use language version 'PREVIEW' or greater. //The value or constructor 'nameof' is not defined. //This is not a valid constant expression or custom attribute value //This is not a valid constant expression or custom attribute value