From 884caac0c2a6eaf56b1a29ecb563276440aad0ae Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 4 Aug 2023 09:49:37 +0200 Subject: [PATCH 01/36] basic tests created for syntaxtree --- src/Compiler/pars.fsy | 4 +- tests/service/SyntaxTreeTests.fs | 14 ++++++- .../GenericFunctionReturnTypeNotStructNull.fs | 1 + ...ericFunctionReturnTypeNotStructNull.fs.bsl | 42 +++++++++++++++++++ .../Nullness/GenericFunctionTyparNotNull.fs | 1 + .../GenericFunctionTyparNotNull.fs.bsl | 34 +++++++++++++++ .../SyntaxTree/Nullness/GenericTypeNull.fs | 1 + .../data/SyntaxTree/Nullness/IntListOrNull.fs | 1 + .../SyntaxTree/Nullness/IntListOrNull.fs.bsl | 35 ++++++++++++++++ .../data/SyntaxTree/Nullness/StringOrNull.fs | 1 + .../SyntaxTree/Nullness/StringOrNull.fs.bsl | 30 +++++++++++++ .../Nullness/StringOrNullInFunctionArg.fs | 1 + .../Nullness/StringOrNullInFunctionArg.fs.bsl | 36 ++++++++++++++++ 13 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/StringOrNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index aabd6f188df..cf985baae7d 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2576,13 +2576,11 @@ typeConstraint: | typar COLON NULL { SynTypeConstraint.WhereTyparSupportsNull($1, lhs parseState) } -/* -** TODO: This rule is not triggering, faking it with __notnull for now | typar COLON IDENT NULL { if $3 <> "not" then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier($3 + " (2)")) SynTypeConstraint.WhereTyparNotSupportsNull($1, lhs parseState) } -*/ + | typar COLON NOTNULL__ { SynTypeConstraint.WhereTyparNotSupportsNull($1, lhs parseState) } diff --git a/tests/service/SyntaxTreeTests.fs b/tests/service/SyntaxTreeTests.fs index b72b20d77d9..7b1f1353523 100644 --- a/tests/service/SyntaxTreeTests.fs +++ b/tests/service/SyntaxTreeTests.fs @@ -10,6 +10,7 @@ open FSharp.Test open NUnit.Framework let testCasesDir = Path.Combine(__SOURCE_DIRECTORY__, "data", "SyntaxTree") +let nullnessTestCasesDir = Path.Combine(__SOURCE_DIRECTORY__, "data", "SyntaxTree","Nullness") let allTestCases = Directory.EnumerateFiles(testCasesDir, "*.fs?", SearchOption.AllDirectories) @@ -19,6 +20,14 @@ let allTestCases = [| fileName :> obj |]) |> Seq.toArray +let nullnessTestCases = + Directory.EnumerateFiles(nullnessTestCasesDir, "*.fs?", SearchOption.AllDirectories) + |> Seq.map (fun f -> + let fileInfo = FileInfo(f) + let fileName = Path.Combine(fileInfo.Directory.Name, fileInfo.Name) + [| fileName :> obj |]) + |> Seq.toArray + [] let RootDirectory = @"/root" @@ -151,7 +160,8 @@ let parseSourceCode (name: string, code: string) = /// Linux/macOS: export TEST_UPDATE_BSL=1 & dotnet test --filter "ParseFile" /// /// Assuming your current directory is tests/FSharp.Compiler.Service.Tests -[] +//[] +[] let ParseFile fileName = let fullPath = Path.Combine(testCasesDir, fileName) let contents = File.ReadAllText fullPath @@ -188,7 +198,7 @@ let ParseFile fileName = "No baseline was found" let equals = expected = actual - let testUpdateBSLEnv = System.Environment.GetEnvironmentVariable("TEST_UPDATE_BSL") + let testUpdateBSLEnv = "1" //System.Environment.GetEnvironmentVariable("TEST_UPDATE_BSL") if not (isNull testUpdateBSLEnv) && testUpdateBSLEnv.Trim() = "1" then File.WriteAllText(bslPath, actual) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs new file mode 100644 index 00000000000..ea4694fc5e8 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs @@ -0,0 +1 @@ +let myFunc() : 'T when 'T : not struct and 'T:null = null diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl new file mode 100644 index 00000000000..d155f74abba --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl @@ -0,0 +1,42 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericFunctionReturnTypeNotStructNull.fs", false, + QualifiedNameOfFile GenericFunctionReturnTypeNotStructNull, [], [], + [SynModuleOrNamespace + ([GenericFunctionReturnTypeNotStructNull], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, SynValInfo ([[]], SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats [Paren (Const (Unit, (1,10--1,12)), (1,10--1,12))], + None, (1,4--1,12)), + Some + (SynBindingReturnInfo + (WithGlobalConstraints + (Var (SynTypar (T, None, false), (1,15--1,17)), + [WhereTyparIsReferenceType + (SynTypar (T, None, false), (1,23--1,38)); + WhereTyparSupportsNull + (SynTypar (T, None, false), (1,43--1,50))], + (1,15--1,50)), (1,15--1,50), [], + { ColonRange = Some (1,13--1,14) })), + Typed + (Null (1,53--1,57), + WithGlobalConstraints + (Var (SynTypar (T, None, false), (1,15--1,17)), + [WhereTyparIsReferenceType + (SynTypar (T, None, false), (1,23--1,38)); + WhereTyparSupportsNull + (SynTypar (T, None, false), (1,43--1,50))], + (1,15--1,50)), (1,53--1,57)), (1,4--1,12), NoneAtLet, + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,51--1,52) })], (1,0--1,57))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs new file mode 100644 index 00000000000..9f80e8f8ac2 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs @@ -0,0 +1 @@ +let myFunc (x: 'T when 'T: not null) = 42 diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl new file mode 100644 index 00000000000..33ae1d63a6f --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl @@ -0,0 +1,34 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericFunctionTyparNotNull.fs", false, + QualifiedNameOfFile GenericFunctionTyparNotNull, [], [], + [SynModuleOrNamespace + ([GenericFunctionTyparNotNull], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, Some x)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats + [Paren + (Typed + (Named + (SynIdent (x, None), false, None, (1,12--1,13)), + FromParseError (1,14--1,14), (1,12--1,14)), + (1,11--1,36))], None, (1,4--1,36)), None, + Const (Int32 42, (1,39--1,41)), (1,4--1,36), NoneAtLet, + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,37--1,38) })], (1,0--1,41))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(1,27)-(1,30) parse error Unexpected identifier: 'not (4)' diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs new file mode 100644 index 00000000000..220b9e370b9 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs @@ -0,0 +1 @@ +type C<'T when 'T: not null> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs new file mode 100644 index 00000000000..2f3dff3b4c8 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs @@ -0,0 +1 @@ +let x : int list | null = [] diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl new file mode 100644 index 00000000000..b0689fb4bb6 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl @@ -0,0 +1,35 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/IntListOrNull.fs", false, + QualifiedNameOfFile IntListOrNull, [], [], + [SynModuleOrNamespace + ([IntListOrNull], 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 (x, None), false, None, (1,4--1,5)), + Some + (SynBindingReturnInfo + (App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (1,8--1,16)), (1,8--1,16), [], + { ColonRange = Some (1,6--1,7) })), + Typed + (ArbitraryAfterError ("localBinding2", (1,16--1,16)), + App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], None, + true, (1,8--1,16)), (1,16--1,16)), (1,4--1,5), + Yes (1,0--1,16), { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = None })], (1,0--1,16))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(1,17)-(1,18) parse error Unexpected symbol '|' in binding. Expected '=' or other token. diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs new file mode 100644 index 00000000000..f27f3c86f09 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs @@ -0,0 +1 @@ +let x : string | null = null diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl new file mode 100644 index 00000000000..d5da8ef224c --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl @@ -0,0 +1,30 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/StringOrNull.fs", false, QualifiedNameOfFile StringOrNull, + [], [], + [SynModuleOrNamespace + ([StringOrNull], 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 (x, None), false, None, (1,4--1,5)), + Some + (SynBindingReturnInfo + (LongIdent (SynLongIdent ([string], [], [None])), + (1,8--1,14), [], { ColonRange = Some (1,6--1,7) })), + Typed + (ArbitraryAfterError ("localBinding2", (1,14--1,14)), + LongIdent (SynLongIdent ([string], [], [None])), + (1,14--1,14)), (1,4--1,5), Yes (1,0--1,14), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = None })], (1,0--1,14))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(1,15)-(1,16) parse error Unexpected symbol '|' in binding. Expected '=' or other token. diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs new file mode 100644 index 00000000000..583756d370a --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs @@ -0,0 +1 @@ +let myFunc (x: string | null) = 42 diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl new file mode 100644 index 00000000000..89e9595cc85 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl @@ -0,0 +1,36 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/StringOrNullInFunctionArg.fs", false, + QualifiedNameOfFile StringOrNullInFunctionArg, [], [], + [SynModuleOrNamespace + ([StringOrNullInFunctionArg], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats + [Paren + (Or + (Typed + (Named + (SynIdent (x, None), false, None, + (1,12--1,13)), + LongIdent (SynLongIdent ([string], [], [None])), + (1,12--1,21)), Null (1,24--1,28), (1,12--1,28), + { BarRange = (1,22--1,23) }), (1,11--1,29))], None, + (1,4--1,29)), None, Const (Int32 42, (1,32--1,34)), + (1,4--1,29), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,30--1,31) })], + (1,0--1,34))], PreXmlDocEmpty, [], None, (1,0--2,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) From 9912ae72ec05444eece6b89e286cccc4e7b4727e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 4 Aug 2023 11:00:31 +0200 Subject: [PATCH 02/36] appType BAR NULL -> rule added --- src/Compiler/pars.fsy | 6 +- .../FSharp.Compiler.Service.Tests.fsproj | 6 ++ .../Nullness/AbstractClassProperty.fs | 3 + .../Nullness/AbstractClassProperty.fs.bsl | 60 +++++++++++++++++++ .../SyntaxTree/Nullness/DuCaseStringOrNull.fs | 1 + .../Nullness/DuCaseStringOrNull.fs.bsl | 35 +++++++++++ .../Nullness/DuCaseTuplePrecedence.fs | 1 + .../Nullness/DuCaseTuplePrecedence.fs.bsl | 41 +++++++++++++ .../data/SyntaxTree/Nullness/ExplicitField.fs | 4 ++ .../SyntaxTree/Nullness/ExplicitField.fs.bsl | 11 ++++ .../SyntaxTree/Nullness/IntListOrNull.fs.bsl | 28 +++++---- .../Nullness/SignatureInAbstractMember.fs | 2 + .../Nullness/SignatureInAbstractMember.fs.bsl | 60 +++++++++++++++++++ .../SyntaxTree/Nullness/StringOrNull.fs.bsl | 23 +++---- 14 files changed, 256 insertions(+), 25 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/ExplicitField.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs.bsl diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index cf985baae7d..cfbe8cd8b62 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -342,6 +342,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %nonassoc interpolation_fill /* "...{3,N4}..." .NET style fill has higher precedence than "e COMMA e" */ %nonassoc paren_pat_colon %nonassoc paren_pat_attribs +%nonassoc typar_not_null %left OR BAR_BAR JOIN_IN %left AND %left AND_BANG @@ -2577,7 +2578,7 @@ typeConstraint: | typar COLON NULL { SynTypeConstraint.WhereTyparSupportsNull($1, lhs parseState) } - | typar COLON IDENT NULL + | typar COLON IDENT NULL %prec typar_not_null { if $3 <> "not" then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier($3 + " (2)")) SynTypeConstraint.WhereTyparNotSupportsNull($1, lhs parseState) } @@ -5871,6 +5872,9 @@ appType: | appType WITHNULL__ { SynType.WithNull($1, false, lhs parseState) } + | appType BAR NULL + { SynType.WithNull($1, false, lhs parseState) } + /* | appType QMARK { SynType.WithNull($1, false, lhs parseState) } diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index eb9294585d9..0724accc908 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -103,6 +103,12 @@ + + + SyntaxTreeTestSource\%(RecursiveDir)\%(Extension)\%(Filename)%(Extension) + + + diff --git a/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs b/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs new file mode 100644 index 00000000000..a11725eb01b --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs @@ -0,0 +1,3 @@ +[] +type AbstractBase() = + abstract Property1 : string | null with get, set diff --git a/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs.bsl b/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs.bsl new file mode 100644 index 00000000000..2bc15f69175 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/AbstractClassProperty.fs.bsl @@ -0,0 +1,60 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/AbstractClassProperty.fs", false, + QualifiedNameOfFile AbstractClassProperty, [], [], + [SynModuleOrNamespace + ([AbstractClassProperty], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([{ Attributes = + [{ TypeName = + SynLongIdent ([AbstractClass], [], [None]) + ArgExpr = Const (Unit, (1,2--1,15)) + Target = None + AppliesToGetterAndSetter = false + Range = (1,2--1,15) }] + Range = (1,0--1,17) }], None, [], [AbstractBase], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (2,5--2,17)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], SimplePats ([], [], (2,17--2,19)), None, + PreXmlDoc ((2,17), FSharp.Compiler.Xml.XmlDocCollector), + (2,5--2,17), { AsKeyword = None }); + AbstractSlot + (SynValSig + ([], SynIdent (Property1, None), + SynValTyparDecls (None, true), + WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (3,24--3,37)), + SynValInfo ([], SynArgInfo ([], false, None)), false, + false, + PreXmlDoc ((3,3), FSharp.Compiler.Xml.XmlDocCollector), + None, None, (3,3--3,51), + { LeadingKeyword = Abstract (3,3--3,11) + InlineKeyword = None + WithKeyword = Some (3,38--3,42) + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = PropertyGetSet }, (3,3--3,51), + { GetSetKeywords = + Some (GetSet ((3,43--3,46), (3,48--3,51))) })], + (3,3--3,51)), [], + Some + (ImplicitCtor + (None, [], SimplePats ([], [], (2,17--2,19)), None, + PreXmlDoc ((2,17), FSharp.Compiler.Xml.XmlDocCollector), + (2,5--2,17), { AsKeyword = None })), (1,0--3,51), + { LeadingKeyword = Type (2,0--2,4) + EqualsRange = Some (2,20--2,21) + WithKeyword = None })], (1,0--3,51))], PreXmlDocEmpty, [], + None, (1,0--4,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs new file mode 100644 index 00000000000..79479743ae3 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs @@ -0,0 +1 @@ +type DU = MyCase of string | null diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl new file mode 100644 index 00000000000..7ce2cf86cff --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl @@ -0,0 +1,35 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/DuCaseStringOrNull.fs", false, + QualifiedNameOfFile DuCaseStringOrNull, [], [], + [SynModuleOrNamespace + ([DuCaseStringOrNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [DU], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,7)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (MyCase, None), + Fields + [SynField + ([], false, None, + WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,20--1,33)), false, + PreXmlDoc ((1,20), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,20--1,33), { LeadingKeyword = None })], + PreXmlDoc ((1,10), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,10--1,33), { BarRange = None })], + (1,10--1,33)), (1,10--1,33)), [], None, (1,5--1,33), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,8--1,9) + WithKeyword = None })], (1,0--1,33))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs new file mode 100644 index 00000000000..1c79f765cb8 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs @@ -0,0 +1 @@ +type DU = MyCase of string | null * int diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl new file mode 100644 index 00000000000..c9437c8bf96 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl @@ -0,0 +1,41 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/DuCaseTuplePrecedence.fs", false, + QualifiedNameOfFile DuCaseTuplePrecedence, [], [], + [SynModuleOrNamespace + ([DuCaseTuplePrecedence], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [DU], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,7)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (MyCase, None), + Fields + [SynField + ([], false, None, + WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,20--1,33)), false, + PreXmlDoc ((1,20), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,20--1,33), { LeadingKeyword = None }); + SynField + ([], false, None, + LongIdent (SynLongIdent ([int], [], [None])), + false, + PreXmlDoc ((1,36), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,36--1,39), { LeadingKeyword = None })], + PreXmlDoc ((1,10), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,10--1,39), { BarRange = None })], + (1,10--1,39)), (1,10--1,39)), [], None, (1,5--1,39), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,8--1,9) + WithKeyword = None })], (1,0--1,39))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs new file mode 100644 index 00000000000..fd93ac6b9f5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs @@ -0,0 +1,4 @@ +type MyStruct = + struct + val mutable myString : string | null + end diff --git a/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl new file mode 100644 index 00000000000..05082edfae4 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl @@ -0,0 +1,11 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/ExplicitField.fs", false, + QualifiedNameOfFile ExplicitField, [], [], + [SynModuleOrNamespace + ([ExplicitField], false, AnonModule, [], PreXmlDocEmpty, [], None, + (5,0--5,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(3,38)-(3,39) parse error Unexpected symbol '|' in member definition diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl index b0689fb4bb6..38442d6c68e 100644 --- a/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl @@ -14,22 +14,24 @@ ImplFile Named (SynIdent (x, None), false, None, (1,4--1,5)), Some (SynBindingReturnInfo + (WithNull + (App + (LongIdent (SynLongIdent ([list], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (1,8--1,16)), false, (1,8--1,23)), + (1,8--1,23), [], { ColonRange = Some (1,6--1,7) })), + Typed + (ArrayOrList (false, [], (1,26--1,28)), + WithNull (App (LongIdent (SynLongIdent ([list], [], [None])), None, [LongIdent (SynLongIdent ([int], [], [None]))], [], - None, true, (1,8--1,16)), (1,8--1,16), [], - { ColonRange = Some (1,6--1,7) })), - Typed - (ArbitraryAfterError ("localBinding2", (1,16--1,16)), - App - (LongIdent (SynLongIdent ([list], [], [None])), None, - [LongIdent (SynLongIdent ([int], [], [None]))], [], None, - true, (1,8--1,16)), (1,16--1,16)), (1,4--1,5), - Yes (1,0--1,16), { LeadingKeyword = Let (1,0--1,3) - InlineKeyword = None - EqualsRange = None })], (1,0--1,16))], + None, true, (1,8--1,16)), false, (1,8--1,23)), + (1,26--1,28)), (1,4--1,5), Yes (1,0--1,28), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,24--1,25) })], (1,0--1,28))], PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) - -(1,17)-(1,18) parse error Unexpected symbol '|' in binding. Expected '=' or other token. diff --git a/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs b/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs new file mode 100644 index 00000000000..9839c9cd370 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs @@ -0,0 +1,2 @@ +type MyClassBase1() = + abstract member function1 : string | null -> string | null diff --git a/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs.bsl b/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs.bsl new file mode 100644 index 00000000000..b7cfdabef4f --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/SignatureInAbstractMember.fs.bsl @@ -0,0 +1,60 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/SignatureInAbstractMember.fs", false, + QualifiedNameOfFile SignatureInAbstractMember, [], [], + [SynModuleOrNamespace + ([SignatureInAbstractMember], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [MyClassBase1], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,17)), + ObjectModel + (Unspecified, + [ImplicitCtor + (None, [], SimplePats ([], [], (1,17--1,19)), None, + PreXmlDoc ((1,17), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,17), { AsKeyword = None }); + AbstractSlot + (SynValSig + ([], SynIdent (function1, None), + SynValTyparDecls (None, true), + Fun + (WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), false, + (2,31--2,44)), + WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), false, + (2,48--2,61)), (2,31--2,61), + { ArrowRange = (2,45--2,47) }), + SynValInfo + ([[SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), false, false, + PreXmlDoc ((2,3), FSharp.Compiler.Xml.XmlDocCollector), + None, None, (2,3--2,61), + { LeadingKeyword = + AbstractMember ((2,3--2,11), (2,12--2,18)) + InlineKeyword = None + WithKeyword = None + EqualsRange = None }), + { IsInstance = true + IsDispatchSlot = true + IsOverrideOrExplicitImpl = false + IsFinal = false + GetterOrSetterIsCompilerGenerated = false + MemberKind = Member }, (2,3--2,61), + { GetSetKeywords = None })], (2,3--2,61)), [], + Some + (ImplicitCtor + (None, [], SimplePats ([], [], (1,17--1,19)), None, + PreXmlDoc ((1,17), FSharp.Compiler.Xml.XmlDocCollector), + (1,5--1,17), { AsKeyword = None })), (1,5--2,61), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,20--1,21) + WithKeyword = None })], (1,0--2,61))], PreXmlDocEmpty, [], + None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl index d5da8ef224c..e803aeedb1f 100644 --- a/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl @@ -14,17 +14,18 @@ ImplFile Named (SynIdent (x, None), false, None, (1,4--1,5)), Some (SynBindingReturnInfo - (LongIdent (SynLongIdent ([string], [], [None])), - (1,8--1,14), [], { ColonRange = Some (1,6--1,7) })), + (WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (1,8--1,21)), (1,8--1,21), [], + { ColonRange = Some (1,6--1,7) })), Typed - (ArbitraryAfterError ("localBinding2", (1,14--1,14)), - LongIdent (SynLongIdent ([string], [], [None])), - (1,14--1,14)), (1,4--1,5), Yes (1,0--1,14), + (Null (1,24--1,28), + WithNull + (LongIdent (SynLongIdent ([string], [], [None])), false, + (1,8--1,21)), (1,24--1,28)), (1,4--1,5), Yes (1,0--1,28), { LeadingKeyword = Let (1,0--1,3) InlineKeyword = None - EqualsRange = None })], (1,0--1,14))], PreXmlDocEmpty, [], - None, (1,0--2,0), { LeadingKeyword = None })], (true, true), - { ConditionalDirectives = [] - CodeComments = [] }, set [])) - -(1,15)-(1,16) parse error Unexpected symbol '|' in binding. Expected '=' or other token. + EqualsRange = Some (1,22--1,23) })], (1,0--1,28))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) From 6ab42e0caea972f46b7e6f8992c27b72f4a53b64 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 4 Aug 2023 14:00:38 +0200 Subject: [PATCH 03/36] IIII am still failing... --- src/Compiler/pars.fsy | 6 ++-- .../Nullness/GenericFunctionTyparNull.fs | 1 + .../Nullness/GenericFunctionTyparNull.fs.bsl | 36 +++++++++++++++++++ .../SyntaxTree/Nullness/GenericTypeNotNull.fs | 1 + .../SyntaxTree/Nullness/GenericTypeNull.fs | 2 +- .../Nullness/GenericTypeNull.fs.bsl | 25 +++++++++++++ 6 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index cfbe8cd8b62..d9edc63be0b 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -76,7 +76,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token LESS GREATER /* here the bool indicates if the tokens are part of a type application or type parameter declaration, e.g. C, detected by the lex filter */ %token PERCENT_OP BINDER %token LQUOTE RQUOTE RQUOTE_DOT -%token BAR_BAR UPCAST DOWNCAST NULL RESERVED MODULE NAMESPACE DELEGATE CONSTRAINT BASE +%token BAR_BAR UPCAST DOWNCAST RESERVED MODULE NAMESPACE DELEGATE CONSTRAINT BASE %token AND AS ASSERT OASSERT ASR BEGIN DO DONE DOWNTO ELSE ELIF END DOT_DOT DOT_DOT_HAT %token EXCEPTION FALSE FOR FUN FUNCTION IF IN JOIN_IN FINALLY DO_BANG %token LAZY OLAZY MATCH MATCH_BANG MUTABLE NEW OF @@ -86,7 +86,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token SEMICOLON_SEMICOLON LARROW EQUALS LBRACK LBRACK_BAR LBRACE_BAR LBRACK_LESS %token BAR_RBRACK BAR_RBRACE UNDERSCORE %token BAR RBRACK RBRACE_COMING_SOON RBRACE_IS_HERE MINUS DOLLAR -%token GREATER_RBRACK STRUCT SIG +%token GREATER_RBRACK STRUCT SIG NULL %token STATIC MEMBER CLASS ABSTRACT OVERRIDE DEFAULT CONSTRUCTOR INHERIT %token EXTERN VOID PUBLIC PRIVATE INTERNAL GLOBAL %token MAYBENULL__ NOTNULL__ WITHNULL__ @@ -342,7 +342,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %nonassoc interpolation_fill /* "...{3,N4}..." .NET style fill has higher precedence than "e COMMA e" */ %nonassoc paren_pat_colon %nonassoc paren_pat_attribs -%nonassoc typar_not_null +%left typar_not_null %left OR BAR_BAR JOIN_IN %left AND %left AND_BANG diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs new file mode 100644 index 00000000000..712e2b94c49 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs @@ -0,0 +1 @@ +let myFunc (x: 'T when 'T: null) = 42 diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl new file mode 100644 index 00000000000..db83d1ddcbf --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl @@ -0,0 +1,36 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericFunctionTyparNull.fs", false, + QualifiedNameOfFile GenericFunctionTyparNull, [], [], + [SynModuleOrNamespace + ([GenericFunctionTyparNull], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, Some x)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats + [Paren + (Typed + (Named + (SynIdent (x, None), false, None, (1,12--1,13)), + WithGlobalConstraints + (Var (SynTypar (T, None, false), (1,15--1,17)), + [WhereTyparSupportsNull + (SynTypar (T, None, false), (1,23--1,31))], + (1,15--1,31)), (1,12--1,31)), (1,11--1,32))], + None, (1,4--1,32)), None, Const (Int32 42, (1,35--1,37)), + (1,4--1,32), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,33--1,34) })], + (1,0--1,37))], PreXmlDocEmpty, [], None, (1,0--2,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs new file mode 100644 index 00000000000..220b9e370b9 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs @@ -0,0 +1 @@ +type C<'T when 'T: not null> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs index 220b9e370b9..67b7b23c154 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs @@ -1 +1 @@ -type C<'T when 'T: not null> = class end +type C<'T when 'T: null> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl new file mode 100644 index 00000000000..6b130ebb3b4 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl @@ -0,0 +1,25 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeNull.fs", false, + QualifiedNameOfFile GenericTypeNull, [], [], + [SynModuleOrNamespace + ([GenericTypeNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl ([], SynTypar (T, None, false))], + [WhereTyparSupportsNull + (SynTypar (T, None, false), (1,15--1,23))], + (1,6--1,24))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,27--1,36)), [], None, (1,5--1,36), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,25--1,26) + WithKeyword = None })], (1,0--1,36))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) From 2aea264712321782914b582d9554ac3a98e3a3bd Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 4 Aug 2023 14:53:23 +0200 Subject: [PATCH 04/36] more failing cases added --- src/Compiler/pars.fsy | 2 +- .../SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs | 1 + .../Nullness/GenericTypeOtherConstraintAndThenNotNull.fs | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index d9edc63be0b..2b46f40cddb 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -342,7 +342,6 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %nonassoc interpolation_fill /* "...{3,N4}..." .NET style fill has higher precedence than "e COMMA e" */ %nonassoc paren_pat_colon %nonassoc paren_pat_attribs -%left typar_not_null %left OR BAR_BAR JOIN_IN %left AND %left AND_BANG @@ -371,6 +370,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %left HIGH_PRECEDENCE_BRACK_APP %left HIGH_PRECEDENCE_PAREN_APP %left HIGH_PRECEDENCE_TYAPP +%nonassoc typar_not_null %nonassoc prec_interaction_empty diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs new file mode 100644 index 00000000000..71d3333c057 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs @@ -0,0 +1 @@ +type C<'T when 'T: not null and 'T:equality> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs new file mode 100644 index 00000000000..634161d9288 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs @@ -0,0 +1 @@ +type C<'T when 'T:equality and 'T: not null> = class end From 173d4f6912d90bf56ae4f2ecff6dff15912c8e59 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 4 Aug 2023 17:41:20 +0200 Subject: [PATCH 05/36] typar not supports null -> new rule --- src/Compiler/pars.fsy | 14 +++----- .../GenericFunctionTyparNotNull.fs.bsl | 24 +++++++------- .../Nullness/GenericTypeNotNull.fs.bsl | 25 +++++++++++++++ ...enericTypeNotNullAndOtherConstraint.fs.bsl | 27 ++++++++++++++++ ...tructAndOtherConstraint-I_am_Still_Sane.fs | 1 + ...tAndOtherConstraint-I_am_Still_Sane.fs.bsl | 32 +++++++++++++++++++ ...icTypeOtherConstraintAndThenNotNull.fs.bsl | 27 ++++++++++++++++ 7 files changed, 129 insertions(+), 21 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 2b46f40cddb..6241f9e32ec 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -1590,22 +1590,16 @@ tyconDefn: let trivia: SynTypeDefnTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = None; WithKeyword = None } SynTypeDefn($1, SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None($1.Range), $1.Range), [], None, $1.Range, trivia) } - | typeNameInfo opt_equals tyconDefnRhsBlock - { match $2 with - | Some _ -> () - | None -> - let (SynComponentInfo(_, _, _, lid, _, _, _, _)) = $1 - // While the spec doesn't allow long idents here, the parser doesn't enforce this, so take one ident - let typeNameId = List.last lid - raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsEqualsMissingInTypeDefinition(typeNameId.ToString())) - + | typeNameInfo EQUALS tyconDefnRhsBlock + { let nameRange = rhs parseState 1 let (tcDefRepr: SynTypeDefnRepr), mWith, members = $3 nameRange let declRange = unionRanges (rhs parseState 1) tcDefRepr.Range let mWhole = (declRange, members) ||> unionRangeWithListBy (fun (mem: SynMemberDefn) -> mem.Range) + let equalsRange = rhs parseState 2 fun leadingKeyword -> - let trivia: SynTypeDefnTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = $2; WithKeyword = mWith } + let trivia: SynTypeDefnTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = Some equalsRange ; WithKeyword = mWith } SynTypeDefn($1, tcDefRepr, members, None, mWhole, trivia) } | typeNameInfo tyconDefnAugmentation diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl index 33ae1d63a6f..2989025967c 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl @@ -21,14 +21,16 @@ ImplFile (Typed (Named (SynIdent (x, None), false, None, (1,12--1,13)), - FromParseError (1,14--1,14), (1,12--1,14)), - (1,11--1,36))], None, (1,4--1,36)), None, - Const (Int32 42, (1,39--1,41)), (1,4--1,36), NoneAtLet, - { LeadingKeyword = Let (1,0--1,3) - InlineKeyword = None - EqualsRange = Some (1,37--1,38) })], (1,0--1,41))], - PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], - (true, true), { ConditionalDirectives = [] - CodeComments = [] }, set [])) - -(1,27)-(1,30) parse error Unexpected identifier: 'not (4)' + WithGlobalConstraints + (Var (SynTypar (T, None, false), (1,15--1,17)), + [WhereTyparNotSupportsNull + (SynTypar (T, None, false), (1,23--1,35))], + (1,15--1,35)), (1,12--1,35)), (1,11--1,36))], + None, (1,4--1,36)), None, Const (Int32 42, (1,39--1,41)), + (1,4--1,36), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,37--1,38) })], + (1,0--1,41))], PreXmlDocEmpty, [], None, (1,0--2,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl new file mode 100644 index 00000000000..c335c2f9d5b --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl @@ -0,0 +1,25 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeNotNull.fs", false, + QualifiedNameOfFile GenericTypeNotNull, [], [], + [SynModuleOrNamespace + ([GenericTypeNotNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl ([], SynTypar (T, None, false))], + [WhereTyparNotSupportsNull + (SynTypar (T, None, false), (1,15--1,27))], + (1,6--1,28))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,31--1,40)), [], None, (1,5--1,40), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,29--1,30) + WithKeyword = None })], (1,0--1,40))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl new file mode 100644 index 00000000000..5b1c36bce92 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl @@ -0,0 +1,27 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeNotNullAndOtherConstraint.fs", false, + QualifiedNameOfFile GenericTypeNotNullAndOtherConstraint, [], [], + [SynModuleOrNamespace + ([GenericTypeNotNullAndOtherConstraint], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl ([], SynTypar (T, None, false))], + [WhereTyparNotSupportsNull + (SynTypar (T, None, false), (1,15--1,27)); + WhereTyparIsEquatable + (SynTypar (T, None, false), (1,32--1,43))], + (1,6--1,44))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,47--1,56)), [], None, (1,5--1,56), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,45--1,46) + WithKeyword = None })], (1,0--1,56))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs new file mode 100644 index 00000000000..8b3b5793b92 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs @@ -0,0 +1 @@ +type C<'T when 'T: not struct and 'T:equality> = class end diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl new file mode 100644 index 00000000000..85b61f0e355 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl @@ -0,0 +1,32 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs", + false, + QualifiedNameOfFile GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane, + [], [], + [SynModuleOrNamespace + ([GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane], false, + AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl ([], SynTypar (T, None, false))], + [WhereTyparIsReferenceType + (SynTypar (T, None, false), (1,15--1,29)); + WhereTyparIsEquatable + (SynTypar (T, None, false), (1,34--1,45))], + (1,6--1,46))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,49--1,58)), [], None, (1,5--1,58), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,47--1,48) + WithKeyword = None })], (1,0--1,58))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(1,0)-(2,0) parse warning The declarations in this file will be placed in an implicit module 'GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane' based on the file name 'GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs'. However this is not a valid F# identifier, so the contents will not be accessible from other files. Consider renaming the file or adding a 'module' or 'namespace' declaration at the top of the file. diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl new file mode 100644 index 00000000000..0b28a943bb2 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl @@ -0,0 +1,27 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs", false, + QualifiedNameOfFile GenericTypeOtherConstraintAndThenNotNull, [], [], + [SynModuleOrNamespace + ([GenericTypeOtherConstraintAndThenNotNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl ([], SynTypar (T, None, false))], + [WhereTyparIsEquatable + (SynTypar (T, None, false), (1,15--1,26)); + WhereTyparNotSupportsNull + (SynTypar (T, None, false), (1,31--1,43))], + (1,6--1,44))), [], [C], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,6)), + ObjectModel (Class, [], (1,47--1,56)), [], None, (1,5--1,56), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,45--1,46) + WithKeyword = None })], (1,0--1,56))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) From 6d1c8adf2b0fb66cae82eed92cc15d858be8f13f Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 4 Aug 2023 17:47:38 +0200 Subject: [PATCH 06/36] put syntaxtree tests back to doing all of them --- tests/service/SyntaxTreeTests.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/service/SyntaxTreeTests.fs b/tests/service/SyntaxTreeTests.fs index 7b1f1353523..479691b6c60 100644 --- a/tests/service/SyntaxTreeTests.fs +++ b/tests/service/SyntaxTreeTests.fs @@ -160,8 +160,8 @@ let parseSourceCode (name: string, code: string) = /// Linux/macOS: export TEST_UPDATE_BSL=1 & dotnet test --filter "ParseFile" /// /// Assuming your current directory is tests/FSharp.Compiler.Service.Tests -//[] -[] +[] +//[] let ParseFile fileName = let fullPath = Path.Combine(testCasesDir, fileName) let contents = File.ReadAllText fullPath @@ -198,7 +198,7 @@ let ParseFile fileName = "No baseline was found" let equals = expected = actual - let testUpdateBSLEnv = "1" //System.Environment.GetEnvironmentVariable("TEST_UPDATE_BSL") + let testUpdateBSLEnv = System.Environment.GetEnvironmentVariable("TEST_UPDATE_BSL") if not (isNull testUpdateBSLEnv) && testUpdateBSLEnv.Trim() = "1" then File.WriteAllText(bslPath, actual) From de03a176beda6b6158649003cd4ceb044ddc56dd Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 4 Aug 2023 18:35:41 +0200 Subject: [PATCH 07/36] now it works --- src/Compiler/pars.fsy | 16 +++------- .../SyntaxTree/Nullness/ExplicitField.fs.bsl | 27 +++++++++++++--- .../Nullness/StringOrNullInFunctionArg.fs.bsl | 32 +++++++++---------- 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 6241f9e32ec..0d60d741a09 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -256,7 +256,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> /* Lower than "if a then b" */ %left prec_then_before %nonassoc prec_then_if -%left BAR + %right SEMICOLON prec_semiexpr_sep OBLOCKSEP %right prec_defn_sep @@ -290,6 +290,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %nonassoc prec_tuptyptail_prefix /* ditto */ %nonassoc prec_toptuptyptail_prefix /* ditto */ +%left BAR %right RARROW %nonassoc IDENT LBRACK @@ -371,6 +372,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %left HIGH_PRECEDENCE_PAREN_APP %left HIGH_PRECEDENCE_TYAPP %nonassoc typar_not_null +%nonassoc type_bar_null %nonassoc prec_interaction_empty @@ -5866,7 +5868,7 @@ appType: | appType WITHNULL__ { SynType.WithNull($1, false, lhs parseState) } - | appType BAR NULL + | appType BAR NULL %prec type_bar_null { SynType.WithNull($1, false, lhs parseState) } /* @@ -6524,12 +6526,6 @@ deprecated_opt_equals: | EQUALS { deprecatedWithError (FSComp.SR.parsNoEqualShouldFollowNamespace()) (lhs parseState); () } | /* EMPTY */ { } -opt_equals: - | EQUALS - { let mEquals = rhs parseState 1 - Some mEquals } - | /* EMPTY */ { None } - opt_OBLOCKSEP: | OBLOCKSEP { } | /* EMPTY */ { } @@ -6542,10 +6538,6 @@ opt_rec: | REC { true } | /* EMPTY */ { false } -opt_bar: - | BAR { } - | /* EMPTY */ { } - opt_inline: | INLINE { Some(rhs parseState 1) } | /* EMPTY */ { None } diff --git a/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl index 05082edfae4..b06e92d77eb 100644 --- a/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/ExplicitField.fs.bsl @@ -3,9 +3,28 @@ ImplFile ("/root/Nullness/ExplicitField.fs", false, QualifiedNameOfFile ExplicitField, [], [], [SynModuleOrNamespace - ([ExplicitField], false, AnonModule, [], PreXmlDocEmpty, [], None, - (5,0--5,0), { LeadingKeyword = None })], (true, true), + ([ExplicitField], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [MyStruct], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,13)), + ObjectModel + (Struct, + [ValField + (SynField + ([], false, Some myString, + WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (3,31--3,44)), true, + PreXmlDoc ((3,8), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,20--3,44), + { LeadingKeyword = Some (Val (3,8--3,11)) }), + (3,8--3,44))], (2,4--4,7)), [], None, (1,5--4,7), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,14--1,15) + WithKeyword = None })], (1,0--4,7))], PreXmlDocEmpty, [], + None, (1,0--5,0), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) - -(3,38)-(3,39) parse error Unexpected symbol '|' in member definition diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl index 89e9595cc85..e64ede7cd17 100644 --- a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl @@ -12,25 +12,23 @@ ImplFile SynValData (None, SynValInfo - ([[SynArgInfo ([], false, None)]], + ([[SynArgInfo ([], false, Some x)]], SynArgInfo ([], false, None)), None), LongIdent (SynLongIdent ([myFunc], [], [None]), None, None, Pats [Paren - (Or - (Typed - (Named - (SynIdent (x, None), false, None, - (1,12--1,13)), - LongIdent (SynLongIdent ([string], [], [None])), - (1,12--1,21)), Null (1,24--1,28), (1,12--1,28), - { BarRange = (1,22--1,23) }), (1,11--1,29))], None, - (1,4--1,29)), None, Const (Int32 42, (1,32--1,34)), - (1,4--1,29), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) - InlineKeyword = None - EqualsRange = Some (1,30--1,31) })], - (1,0--1,34))], PreXmlDocEmpty, [], None, (1,0--2,0), - { LeadingKeyword = None })], (true, true), - { ConditionalDirectives = [] - CodeComments = [] }, set [])) + (Typed + (Named + (SynIdent (x, None), false, None, (1,12--1,13)), + WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (1,15--1,28)), (1,12--1,28)), + (1,11--1,29))], None, (1,4--1,29)), None, + Const (Int32 42, (1,32--1,34)), (1,4--1,29), NoneAtLet, + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,30--1,31) })], (1,0--1,34))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) From a377b2047edb4c0526ed13c6547a9a580ab94b49 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 4 Aug 2023 18:39:21 +0200 Subject: [PATCH 08/36] remove unnecessary leftovers --- src/Compiler/pars.fsy | 6 ++---- tests/service/SyntaxTreeTests.fs | 10 ---------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 0d60d741a09..8d855ebeffb 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -371,8 +371,6 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %left HIGH_PRECEDENCE_BRACK_APP %left HIGH_PRECEDENCE_PAREN_APP %left HIGH_PRECEDENCE_TYAPP -%nonassoc typar_not_null -%nonassoc type_bar_null %nonassoc prec_interaction_empty @@ -2574,7 +2572,7 @@ typeConstraint: | typar COLON NULL { SynTypeConstraint.WhereTyparSupportsNull($1, lhs parseState) } - | typar COLON IDENT NULL %prec typar_not_null + | typar COLON IDENT NULL { if $3 <> "not" then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier($3 + " (2)")) SynTypeConstraint.WhereTyparNotSupportsNull($1, lhs parseState) } @@ -5868,7 +5866,7 @@ appType: | appType WITHNULL__ { SynType.WithNull($1, false, lhs parseState) } - | appType BAR NULL %prec type_bar_null + | appType BAR NULL { SynType.WithNull($1, false, lhs parseState) } /* diff --git a/tests/service/SyntaxTreeTests.fs b/tests/service/SyntaxTreeTests.fs index 479691b6c60..b72b20d77d9 100644 --- a/tests/service/SyntaxTreeTests.fs +++ b/tests/service/SyntaxTreeTests.fs @@ -10,7 +10,6 @@ open FSharp.Test open NUnit.Framework let testCasesDir = Path.Combine(__SOURCE_DIRECTORY__, "data", "SyntaxTree") -let nullnessTestCasesDir = Path.Combine(__SOURCE_DIRECTORY__, "data", "SyntaxTree","Nullness") let allTestCases = Directory.EnumerateFiles(testCasesDir, "*.fs?", SearchOption.AllDirectories) @@ -20,14 +19,6 @@ let allTestCases = [| fileName :> obj |]) |> Seq.toArray -let nullnessTestCases = - Directory.EnumerateFiles(nullnessTestCasesDir, "*.fs?", SearchOption.AllDirectories) - |> Seq.map (fun f -> - let fileInfo = FileInfo(f) - let fileName = Path.Combine(fileInfo.Directory.Name, fileInfo.Name) - [| fileName :> obj |]) - |> Seq.toArray - [] let RootDirectory = @"/root" @@ -161,7 +152,6 @@ let parseSourceCode (name: string, code: string) = /// /// Assuming your current directory is tests/FSharp.Compiler.Service.Tests [] -//[] let ParseFile fileName = let fullPath = Path.Combine(testCasesDir, fileName) let contents = File.ReadAllText fullPath From 70994982b17d32689abf7d2036197d21794d115a Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 22 Aug 2023 15:29:39 +0200 Subject: [PATCH 09/36] regression for Choice type (not yet fixed) caused by precedence rules --- src/Compiler/pars.fsy | 16 +++++++++------- .../SyntaxTree/Nullness/RegressionChoiceType.fs | 7 +++++++ .../Nullness/RegressionChoiceType.fs.bsl | 12 ++++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 8d855ebeffb..0fa32268715 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -236,6 +236,8 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> /* start with lowest */ +%nonassoc prec_bar_null + %nonassoc prec_args_error /* less than RPAREN */ %nonassoc prec_atomexpr_lparen_error /* less than RPAREN */ @@ -247,11 +249,6 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %right WHEN -/* prec_pat_pat_action = "pattern when expr -> expr" - * Lower than match extensions - i.e. BAR. - */ -%nonassoc prec_pat_pat_action /* lower than BAR */ - /* "a then b" as an object constructor is very low precedence */ /* Lower than "if a then b" */ %left prec_then_before @@ -291,6 +288,10 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %nonassoc prec_toptuptyptail_prefix /* ditto */ %left BAR +/* prec_pat_pat_action = "pattern when expr -> expr" + * Lower than match extensions - i.e. BAR. + */ +%nonassoc prec_pat_pat_action /* lower than BAR */ %right RARROW %nonassoc IDENT LBRACK @@ -373,6 +374,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %left HIGH_PRECEDENCE_TYAPP %nonassoc prec_interaction_empty +%right multiple_union_cases %% @@ -2637,7 +2639,7 @@ barAndgrabXmlDoc: grabXmlDoc(parseState, [], 1), mBar } attrUnionCaseDecls: - | attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls + | attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls %prec multiple_union_cases { (fun xmlDocAndBar -> $1 xmlDocAndBar :: $3 $2) } | attrUnionCaseDecl @@ -5866,7 +5868,7 @@ appType: | appType WITHNULL__ { SynType.WithNull($1, false, lhs parseState) } - | appType BAR NULL + | appType BAR NULL %prec prec_bar_null { SynType.WithNull($1, false, lhs parseState) } /* diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs new file mode 100644 index 00000000000..dde76747ac4 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs @@ -0,0 +1,7 @@ +type MyChoice<'T1,'T2> = + + /// Choice 1 of 2 choices + | MyChoice of 'T1 + + /// Choice 2 of 2 choices + | MyChoice of 'T2 diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl new file mode 100644 index 00000000000..55463dea120 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl @@ -0,0 +1,12 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionChoiceType.fs", false, + QualifiedNameOfFile RegressionChoiceType, [], [], + [SynModuleOrNamespace + ([RegressionChoiceType], false, AnonModule, [], PreXmlDocEmpty, [], + None, (8,0--8,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [LineComment (6,2--6,46)] }, set [])) + +(7,4)-(7,12) parse error Unexpected identifier in union case. Expected 'null' or other token. +(6,2)-(6,46) parse info XML comment is not placed on a valid language element. From b6e4d2c3887d48580b52dccd535a844462edb335 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 23 Aug 2023 17:02:26 +0200 Subject: [PATCH 10/36] in unions, "appType | null" has to be put in () --- src/Compiler/SyntaxTree/LexFilter.fs | 4 +- src/Compiler/pars.fsy | 10 ++-- .../SyntaxTree/Nullness/DuCaseStringOrNull.fs | 2 +- .../Nullness/DuCaseStringOrNull.fs.bsl | 18 ++++--- .../Nullness/DuCaseTuplePrecedence.fs | 2 +- .../Nullness/DuCaseTuplePrecedence.fs.bsl | 22 +++++---- .../Nullness/RegressionChoiceType.fs.bsl | 49 ++++++++++++++++--- 7 files changed, 74 insertions(+), 33 deletions(-) diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index a77b247f4a5..f82facd1c72 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -165,7 +165,7 @@ let infixTokenLength token = | COLON_GREATER -> 2 | COLON_COLON -> 2 | COLON_EQUALS -> 2 - | BAR_BAR -> 2 + | BAR_BAR -> 2 | AMP_AMP -> 2 | INFIX_BAR_OP d | INFIX_AMP_OP d @@ -2417,7 +2417,7 @@ type LexFilterImpl ( pool.Return tokenTup hwTokenFetch useBlockRule - | TRY, _ -> + | TRY, _ -> if debug then dprintf "Try, pushing CtxtTry(%a)\n" outputPos tokenStartPos pushCtxt tokenTup (CtxtTry tokenStartPos) // The ideal spec would be to push a begin/end block pair here, but we can only do that diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 0fa32268715..bc0b1b033b1 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -85,8 +85,8 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token QMARK QMARK_QMARK DOT COLON COLON_COLON COLON_GREATER COLON_QMARK_GREATER COLON_QMARK COLON_EQUALS SEMICOLON %token SEMICOLON_SEMICOLON LARROW EQUALS LBRACK LBRACK_BAR LBRACE_BAR LBRACK_LESS %token BAR_RBRACK BAR_RBRACE UNDERSCORE -%token BAR RBRACK RBRACE_COMING_SOON RBRACE_IS_HERE MINUS DOLLAR -%token GREATER_RBRACK STRUCT SIG NULL +%token NULL BAR RBRACK RBRACE_COMING_SOON RBRACE_IS_HERE MINUS DOLLAR +%token GREATER_RBRACK STRUCT SIG %token STATIC MEMBER CLASS ABSTRACT OVERRIDE DEFAULT CONSTRUCTOR INHERIT %token EXTERN VOID PUBLIC PRIVATE INTERNAL GLOBAL %token MAYBENULL__ NOTNULL__ WITHNULL__ @@ -374,7 +374,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %left HIGH_PRECEDENCE_TYAPP %nonassoc prec_interaction_empty -%right multiple_union_cases +%nonassoc multiple_union_cases %% @@ -2634,7 +2634,7 @@ unionTypeRepr: { [$1] } barAndgrabXmlDoc: - | BAR + | BAR %prec multiple_union_cases { let mBar = rhs parseState 1 grabXmlDoc(parseState, [], 1), mBar } @@ -2763,7 +2763,7 @@ unionCaseReprElement: let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc mkSynNamedField ($1, $3, xmlDoc, mWhole) } - | appType + | appType %prec IDENT { let xmlDoc = grabXmlDoc(parseState, [], 1) mkSynAnonField ($1, xmlDoc) } diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs index 79479743ae3..6f1f90d780a 100644 --- a/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs @@ -1 +1 @@ -type DU = MyCase of string | null +type DU = MyCase of (string | null) diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl index 7ce2cf86cff..ba57735a1a8 100644 --- a/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseStringOrNull.fs.bsl @@ -18,18 +18,20 @@ ImplFile Fields [SynField ([], false, None, - WithNull - (LongIdent - (SynLongIdent ([string], [], [None])), - false, (1,20--1,33)), false, + Paren + (WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,21--1,34)), (1,20--1,35)), + false, PreXmlDoc ((1,20), FSharp.Compiler.Xml.XmlDocCollector), - None, (1,20--1,33), { LeadingKeyword = None })], + None, (1,20--1,35), { LeadingKeyword = None })], PreXmlDoc ((1,10), FSharp.Compiler.Xml.XmlDocCollector), - None, (1,10--1,33), { BarRange = None })], - (1,10--1,33)), (1,10--1,33)), [], None, (1,5--1,33), + None, (1,10--1,35), { BarRange = None })], + (1,10--1,35)), (1,10--1,35)), [], None, (1,5--1,35), { LeadingKeyword = Type (1,0--1,4) EqualsRange = Some (1,8--1,9) - WithKeyword = None })], (1,0--1,33))], PreXmlDocEmpty, [], + WithKeyword = None })], (1,0--1,35))], PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs index 1c79f765cb8..dda36337883 100644 --- a/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs @@ -1 +1 @@ -type DU = MyCase of string | null * int +type DU = MyCase of (string | null) * int diff --git a/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl index c9437c8bf96..379722c41b2 100644 --- a/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/DuCaseTuplePrecedence.fs.bsl @@ -18,24 +18,26 @@ ImplFile Fields [SynField ([], false, None, - WithNull - (LongIdent - (SynLongIdent ([string], [], [None])), - false, (1,20--1,33)), false, + Paren + (WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,21--1,34)), (1,20--1,35)), + false, PreXmlDoc ((1,20), FSharp.Compiler.Xml.XmlDocCollector), - None, (1,20--1,33), { LeadingKeyword = None }); + None, (1,20--1,35), { LeadingKeyword = None }); SynField ([], false, None, LongIdent (SynLongIdent ([int], [], [None])), false, - PreXmlDoc ((1,36), FSharp.Compiler.Xml.XmlDocCollector), - None, (1,36--1,39), { LeadingKeyword = None })], + PreXmlDoc ((1,38), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,38--1,41), { LeadingKeyword = None })], PreXmlDoc ((1,10), FSharp.Compiler.Xml.XmlDocCollector), - None, (1,10--1,39), { BarRange = None })], - (1,10--1,39)), (1,10--1,39)), [], None, (1,5--1,39), + None, (1,10--1,41), { BarRange = None })], + (1,10--1,41)), (1,10--1,41)), [], None, (1,5--1,41), { LeadingKeyword = Type (1,0--1,4) EqualsRange = Some (1,8--1,9) - WithKeyword = None })], (1,0--1,39))], PreXmlDocEmpty, [], + WithKeyword = None })], (1,0--1,41))], PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl index 55463dea120..1e63c3a1b90 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl @@ -3,10 +3,47 @@ ImplFile ("/root/Nullness/RegressionChoiceType.fs", false, QualifiedNameOfFile RegressionChoiceType, [], [], [SynModuleOrNamespace - ([RegressionChoiceType], false, AnonModule, [], PreXmlDocEmpty, [], - None, (8,0--8,0), { LeadingKeyword = None })], (true, true), + ([RegressionChoiceType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl ([], SynTypar (T1, None, false)); + SynTyparDecl ([], SynTypar (T2, None, false))], [], + (1,13--1,22))), [], [MyChoice], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,13)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (MyChoice, None), + Fields + [SynField + ([], false, None, + Var (SynTypar (T1, None, false), (4,16--4,19)), + false, + PreXmlDoc ((4,16), FSharp.Compiler.Xml.XmlDocCollector), + None, (4,16--4,19), { LeadingKeyword = None })], + PreXmlDoc ((4,2), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,2--4,19), { BarRange = Some (4,2--4,3) }); + SynUnionCase + ([], SynIdent (MyChoice, None), + Fields + [SynField + ([], false, None, + Var (SynTypar (T2, None, false), (7,16--7,19)), + false, + PreXmlDoc ((7,16), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,16--7,19), { LeadingKeyword = None })], + PreXmlDoc ((7,2), FSharp.Compiler.Xml.XmlDocCollector), + None, (6,2--7,19), { BarRange = Some (7,2--7,3) })], + (3,2--7,19)), (3,2--7,19)), [], None, (1,5--7,19), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,23--1,24) + WithKeyword = None })], (1,0--7,19))], PreXmlDocEmpty, [], + None, (1,0--8,0), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] - CodeComments = [LineComment (6,2--6,46)] }, set [])) - -(7,4)-(7,12) parse error Unexpected identifier in union case. Expected 'null' or other token. -(6,2)-(6,46) parse info XML comment is not placed on a valid language element. + CodeComments = [] }, set [])) From 247b8a9150d435034821d6c44c919f092c208b1d Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 23 Aug 2023 17:24:40 +0200 Subject: [PATCH 11/36] Fix regression for DU declarations with named fields --- src/Compiler/FSharp.Compiler.Service.fsproj | 1 + src/Compiler/pars.fsy | 2 +- .../Nullness/IntListOrNullOrNullOrNull.fs | 1 + .../Nullness/IntListOrNullOrNullOrNull.fs.bsl | 45 +++++++++++++++++ .../Nullness/RegressionResultType.fs | 7 +++ .../Nullness/RegressionResultType.fs.bsl | 50 +++++++++++++++++++ 6 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl diff --git a/src/Compiler/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj index 8efd9eb3460..bd1182373c2 100644 --- a/src/Compiler/FSharp.Compiler.Service.fsproj +++ b/src/Compiler/FSharp.Compiler.Service.fsproj @@ -235,6 +235,7 @@ SyntaxTree\FsYacc\pars.fsy + PreserveNewest diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index bc0b1b033b1..03941541c72 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2758,7 +2758,7 @@ unionCaseReprElements: { [$1] } unionCaseReprElement: - | ident COLON appType + | ident COLON appType %prec IDENT { let xmlDoc = grabXmlDoc(parseState, [], 1) let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc mkSynNamedField ($1, $3, xmlDoc, mWhole) } diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs new file mode 100644 index 00000000000..f162f811711 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs @@ -0,0 +1 @@ +let x : int list | null | null | null = [] diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl new file mode 100644 index 00000000000..f766b1c2cdf --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl @@ -0,0 +1,45 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/IntListOrNullOrNullOrNull.fs", false, + QualifiedNameOfFile IntListOrNullOrNullOrNull, [], [], + [SynModuleOrNamespace + ([IntListOrNullOrNullOrNull], 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 (x, None), false, None, (1,4--1,5)), + Some + (SynBindingReturnInfo + (WithNull + (WithNull + (WithNull + (App + (LongIdent + (SynLongIdent ([list], [], [None])), None, + [LongIdent + (SynLongIdent ([int], [], [None]))], [], + None, true, (1,8--1,16)), false, (1,8--1,23)), + false, (1,8--1,30)), false, (1,8--1,37)), + (1,8--1,37), [], { ColonRange = Some (1,6--1,7) })), + Typed + (ArrayOrList (false, [], (1,40--1,42)), + WithNull + (WithNull + (WithNull + (App + (LongIdent (SynLongIdent ([list], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], + [], None, true, (1,8--1,16)), false, + (1,8--1,23)), false, (1,8--1,30)), false, + (1,8--1,37)), (1,40--1,42)), (1,4--1,5), Yes (1,0--1,42), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,38--1,39) })], (1,0--1,42))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs new file mode 100644 index 00000000000..b2974154002 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs @@ -0,0 +1,7 @@ + type MyResult<'T,'TError> = + + /// Represents an OK or a Successful result. The code succeeded with a value of 'T. + | Ok of ResultValue:'T + + /// Represents an Error or a Failure. The code failed with a value of 'TError representing what went wrong. + | Error of ErrorValue:'TError \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl new file mode 100644 index 00000000000..4f8244b93d4 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl @@ -0,0 +1,50 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionResultType.fs", false, + QualifiedNameOfFile RegressionResultType, [], [], + [SynModuleOrNamespace + ([RegressionResultType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl ([], SynTypar (T, None, false)); + SynTyparDecl ([], SynTypar (TError, None, false))], + [], (1,17--1,29))), [], [MyResult], + PreXmlDoc ((1,4), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,9--1,17)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (Ok, None), + Fields + [SynField + ([], false, Some ResultValue, + Var (SynTypar (T, None, false), (4,26--4,28)), + false, + PreXmlDoc ((4,14), FSharp.Compiler.Xml.XmlDocCollector), + None, (4,14--4,28), { LeadingKeyword = None })], + PreXmlDoc ((4,6), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,6--4,28), { BarRange = Some (4,6--4,7) }); + SynUnionCase + ([], SynIdent (Error, None), + Fields + [SynField + ([], false, Some ErrorValue, + Var + (SynTypar (TError, None, false), + (7,28--7,35)), false, + PreXmlDoc ((7,17), FSharp.Compiler.Xml.XmlDocCollector), + None, (7,17--7,35), { LeadingKeyword = None })], + PreXmlDoc ((7,6), FSharp.Compiler.Xml.XmlDocCollector), + None, (6,6--7,35), { BarRange = Some (7,6--7,7) })], + (3,6--7,35)), (3,6--7,35)), [], None, (1,9--7,35), + { LeadingKeyword = Type (1,4--1,8) + EqualsRange = Some (1,30--1,31) + WithKeyword = None })], (1,4--7,35))], PreXmlDocEmpty, [], + None, (1,4--7,35), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) From 5fcc89125eebb51e85bade391fb9a2fd8e1eeab9 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 23 Aug 2023 17:45:54 +0200 Subject: [PATCH 12/36] heavily annotated expression - test case --- src/Compiler/pars.fsy | 4 +- .../Nullness/NullAnnotatedExpression.fs | 1 + .../Nullness/NullAnnotatedExpression.fs.bsl | 68 +++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 03941541c72..14aa0c1dd92 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -76,7 +76,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token LESS GREATER /* here the bool indicates if the tokens are part of a type application or type parameter declaration, e.g. C, detected by the lex filter */ %token PERCENT_OP BINDER %token LQUOTE RQUOTE RQUOTE_DOT -%token BAR_BAR UPCAST DOWNCAST RESERVED MODULE NAMESPACE DELEGATE CONSTRAINT BASE +%token BAR_BAR UPCAST DOWNCAST NULL RESERVED MODULE NAMESPACE DELEGATE CONSTRAINT BASE %token AND AS ASSERT OASSERT ASR BEGIN DO DONE DOWNTO ELSE ELIF END DOT_DOT DOT_DOT_HAT %token EXCEPTION FALSE FOR FUN FUNCTION IF IN JOIN_IN FINALLY DO_BANG %token LAZY OLAZY MATCH MATCH_BANG MUTABLE NEW OF @@ -85,7 +85,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token QMARK QMARK_QMARK DOT COLON COLON_COLON COLON_GREATER COLON_QMARK_GREATER COLON_QMARK COLON_EQUALS SEMICOLON %token SEMICOLON_SEMICOLON LARROW EQUALS LBRACK LBRACK_BAR LBRACE_BAR LBRACK_LESS %token BAR_RBRACK BAR_RBRACE UNDERSCORE -%token NULL BAR RBRACK RBRACE_COMING_SOON RBRACE_IS_HERE MINUS DOLLAR +%token BAR RBRACK RBRACE_COMING_SOON RBRACE_IS_HERE MINUS DOLLAR %token GREATER_RBRACK STRUCT SIG %token STATIC MEMBER CLASS ABSTRACT OVERRIDE DEFAULT CONSTRUCTOR INHERIT %token EXTERN VOID PUBLIC PRIVATE INTERNAL GLOBAL diff --git a/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs new file mode 100644 index 00000000000..b824f784a61 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs @@ -0,0 +1 @@ +let x : Expression | null> | null = null diff --git a/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl new file mode 100644 index 00000000000..1457fb5155e --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl @@ -0,0 +1,68 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/NullAnnotatedExpression.fs", false, + QualifiedNameOfFile NullAnnotatedExpression, [], [], + [SynModuleOrNamespace + ([NullAnnotatedExpression], 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 (x, None), false, None, (1,4--1,5)), + Some + (SynBindingReturnInfo + (WithNull + (App + (LongIdent + (SynLongIdent ([Expression], [], [None])), + Some (1,18--1,19), + [WithNull + (App + (LongIdent + (SynLongIdent ([Func], [], [None])), + Some (1,23--1,24), + [WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,24--1,37)); + WithNull + (LongIdent + (SynLongIdent ([T], [], [None])), + false, (1,39--1,47))], [(1,37--1,38)], + Some (1,47--1,48), false, (1,19--1,48)), + false, (1,19--1,55))], [], Some (1,55--1,56), + false, (1,8--1,56)), false, (1,8--1,63)), + (1,8--1,63), [], { ColonRange = Some (1,6--1,7) })), + Typed + (Null (1,66--1,70), + WithNull + (App + (LongIdent (SynLongIdent ([Expression], [], [None])), + Some (1,18--1,19), + [WithNull + (App + (LongIdent (SynLongIdent ([Func], [], [None])), + Some (1,23--1,24), + [WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,24--1,37)); + WithNull + (LongIdent (SynLongIdent ([T], [], [None])), + false, (1,39--1,47))], [(1,37--1,38)], + Some (1,47--1,48), false, (1,19--1,48)), false, + (1,19--1,55))], [], Some (1,55--1,56), false, + (1,8--1,56)), false, (1,8--1,63)), (1,66--1,70)), + (1,4--1,5), Yes (1,0--1,70), + { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,64--1,65) })], (1,0--1,70))], + PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(1,23)-(1,48) parse warning Remove spaces between the type name and type parameter, e.g. "C<'T>", not "C <'T>". Type parameters must be placed directly adjacent to the type name. +(1,18)-(1,56) parse warning Remove spaces between the type name and type parameter, e.g. "C<'T>", not "C <'T>". Type parameters must be placed directly adjacent to the type name. From 2b68ea10ee997e7e0f36aa1dce8d264ef9e470e0 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 23 Aug 2023 19:15:44 +0200 Subject: [PATCH 13/36] precedence for fsharp.core style of SynUnionCaseKind.FullType --- 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 14aa0c1dd92..f3d4d1e64dc 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2675,7 +2675,7 @@ attrUnionCaseDecl: | opt_attributes opt_access unionCaseName OF recover { mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 4) >> Choice2Of2 } - | opt_attributes opt_access unionCaseName COLON topType + | opt_attributes opt_access unionCaseName COLON topType %prec IDENT { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.FullType $5) (rhs2 parseState 1 5) >> Choice2Of2 } From 29f5e2f5a0a35aa8c75667dd155d7e280a890b0e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Wed, 23 Aug 2023 19:30:20 +0200 Subject: [PATCH 14/36] one more time... --- 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 f3d4d1e64dc..0c82cfc88c7 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2675,7 +2675,7 @@ attrUnionCaseDecl: | opt_attributes opt_access unionCaseName OF recover { mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 4) >> Choice2Of2 } - | opt_attributes opt_access unionCaseName COLON topType %prec IDENT + | opt_attributes opt_access unionCaseName COLON topType %prec multiple_union_cases { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.FullType $5) (rhs2 parseState 1 5) >> Choice2Of2 } From 9d06c726944e2181eddf07faa77c74bf17071823 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 25 Aug 2023 16:27:55 +0200 Subject: [PATCH 15/36] Few more precedence rules, FSharp.Core only feature still failing --- src/Compiler/pars.fsy | 36 ++++++++++++------- .../SyntaxTree/Nullness/RegressionListType.fs | 3 ++ .../Nullness/RegressionOneLinerOptionType.fs | 1 + .../Nullness/RegressionOptionType.fs | 3 ++ 4 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionListType.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 0c82cfc88c7..06b201abd13 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -236,7 +236,8 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> /* start with lowest */ -%nonassoc prec_bar_null +/* for appType BAR NULL to not override DU declaration or pattern matching */ +%left prec_bar_null %nonassoc prec_args_error /* less than RPAREN */ %nonassoc prec_atomexpr_lparen_error /* less than RPAREN */ @@ -349,6 +350,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %left AND_BANG %left AMP AMP_AMP %nonassoc pat_conj +%nonassoc path_disj %nonassoc expr_not %left COLON_GREATER COLON_QMARK_GREATER %left INFIX_COMPARE_OP DOLLAR LESS GREATER EQUALS INFIX_BAR_OP INFIX_AMP_OP @@ -374,7 +376,8 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %left HIGH_PRECEDENCE_TYAPP %nonassoc prec_interaction_empty -%nonassoc multiple_union_cases +%nonassoc prec_union_case_declaration +%nonassoc prec_multiple_union_cases %% @@ -2627,22 +2630,22 @@ unionTypeRepr: | barAndgrabXmlDoc attrUnionCaseDecls { $2 $1 } - | firstUnionCaseDeclOfMany barAndgrabXmlDoc attrUnionCaseDecls + | firstUnionCaseDeclOfMany barAndgrabXmlDoc attrUnionCaseDecls %prec prec_multiple_union_cases { $1 :: $3 $2 } | firstUnionCaseDecl { [$1] } barAndgrabXmlDoc: - | BAR %prec multiple_union_cases + | BAR %prec prec_multiple_union_cases { let mBar = rhs parseState 1 grabXmlDoc(parseState, [], 1), mBar } attrUnionCaseDecls: - | attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls %prec multiple_union_cases + | attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls %prec prec_multiple_union_cases { (fun xmlDocAndBar -> $1 xmlDocAndBar :: $3 $2) } - | attrUnionCaseDecl + | attrUnionCaseDecl %prec IDENT { (fun xmlDocAndBar -> [ $1 xmlDocAndBar ]) } /* The core of a union case definition */ @@ -2675,7 +2678,7 @@ attrUnionCaseDecl: | opt_attributes opt_access unionCaseName OF recover { mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 4) >> Choice2Of2 } - | opt_attributes opt_access unionCaseName COLON topType %prec multiple_union_cases + | opt_attributes opt_access unionCaseName COLON topType { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.FullType $5) (rhs2 parseState 1 5) >> Choice2Of2 } @@ -2693,12 +2696,12 @@ unionCaseName: | nameop { $1 } - | LPAREN COLON_COLON rparen + | LPAREN COLON_COLON rparen %prec IDENT { let lpr = rhs parseState 1 let rpr = rhs parseState 3 SynIdent(ident(opNameCons, rhs parseState 2), Some(IdentTrivia.OriginalNotationWithParen(lpr, "::", rpr))) } - | LPAREN LBRACK RBRACK rparen + | LPAREN LBRACK RBRACK rparen %prec IDENT { let lpr = rhs parseState 1 let rpr = rhs parseState 3 SynIdent(ident(opNameNil, rhs2 parseState 2 3), Some(IdentTrivia.OriginalNotationWithParen(lpr, "[]", rpr))) } @@ -2727,6 +2730,13 @@ firstUnionCaseDecl: let mDecl = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc Choice2Of2(SynUnionCase([], SynIdent($1, None), SynUnionCaseKind.Fields $3, xmlDoc, None, mDecl, trivia)) } + | unionCaseName COLON topType + { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) + let trivia: SynUnionCaseTrivia = { BarRange = None } + let xmlDoc = grabXmlDoc (parseState, [], 1) + let mDecl = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc + Choice2Of2(SynUnionCase([], $1, SynUnionCaseKind.FullType $3, xmlDoc, None, mDecl, trivia)) } + | ident OF recover { let trivia: SynUnionCaseTrivia = { BarRange = None } let xmlDoc = grabXmlDoc (parseState, [], 1) @@ -3405,7 +3415,7 @@ headBindingPattern: | headBindingPattern AS constrPattern { SynPat.As($1, $3, rhs2 parseState 1 3) } - | headBindingPattern BAR headBindingPattern + | headBindingPattern BAR headBindingPattern %prec path_disj { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } @@ -3683,7 +3693,7 @@ parenPattern: | parenPattern AS constrPattern { SynPat.As($1, $3, rhs2 parseState 1 3) } - | parenPattern BAR parenPattern + | parenPattern BAR parenPattern %prec path_disj { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } @@ -4548,7 +4558,7 @@ withPatternClauses: | patternClauses { $1 None } - | BAR patternClauses + | BAR patternClauses %prec path_disj { let mBar = rhs parseState 1 |> Some $2 mBar } @@ -5644,7 +5654,7 @@ topTupleType: let path = SynTupleTypeSegment.Type ty :: SynTupleTypeSegment.Star mStar :: (List.map fst $2) mkSynTypeTuple path, List.choose snd $2 } - | topAppType + | topAppType %prec IDENT { let ty, mdata = $1 ty, [mdata] } diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs new file mode 100644 index 00000000000..265513039b5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs @@ -0,0 +1,3 @@ +type List<'T> = + | ([]): 'T list + | (::): Head: 'T * Tail: 'T list -> 'T list \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs new file mode 100644 index 00000000000..e65287d6f2d --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs @@ -0,0 +1 @@ +type MyFlatOption = None: MyFlatOption | Some: string -> MyFlatOption \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs new file mode 100644 index 00000000000..8b1018d513f --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs @@ -0,0 +1,3 @@ +type Option<'T> = + | None: 'T option + | Some: Value:'T -> 'T option \ No newline at end of file From 1dece40eb7d19d6fcfad4d901018023603f74a7b Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 28 Aug 2023 12:16:16 +0200 Subject: [PATCH 16/36] xx --- src/Compiler/pars.fsy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 06b201abd13..80704b431da 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2678,7 +2678,7 @@ attrUnionCaseDecl: | opt_attributes opt_access unionCaseName OF recover { mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 4) >> Choice2Of2 } - | opt_attributes opt_access unionCaseName COLON topType + | opt_attributes opt_access unionCaseName COLON topType %prec prec_toptuptyptail_prefix { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.FullType $5) (rhs2 parseState 1 5) >> Choice2Of2 } @@ -2730,7 +2730,7 @@ firstUnionCaseDecl: let mDecl = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc Choice2Of2(SynUnionCase([], SynIdent($1, None), SynUnionCaseKind.Fields $3, xmlDoc, None, mDecl, trivia)) } - | unionCaseName COLON topType + | unionCaseName COLON topType { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) let trivia: SynUnionCaseTrivia = { BarRange = None } let xmlDoc = grabXmlDoc (parseState, [], 1) From 2c7c76a4e48d3333df03c6927ab2efba862e73db Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 28 Aug 2023 16:40:44 +0200 Subject: [PATCH 17/36] regressions --- .../SyntaxTree/Nullness/RegressionListType.fs | 6 +- .../Nullness/RegressionListType.fs.bsl | 61 +++++++++++++++++++ .../Nullness/RegressionOneLinerOptionType.fs | 2 +- .../Nullness/RegressionOptionType.fs | 6 +- .../Nullness/RegressionOptionType.fs.bsl | 41 +++++++++++++ .../TypeAbbreviationAddingWithNull.fs | 1 + .../TypeAbbreviationAddingWithNull.fs.bsl | 24 ++++++++ 7 files changed, 134 insertions(+), 7 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs.bsl diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs index 265513039b5..fca67d8f23e 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs +++ b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs @@ -1,3 +1,3 @@ -type List<'T> = - | ([]): 'T list - | (::): Head: 'T * Tail: 'T list -> 'T list \ No newline at end of file +type List<'T> = + | ([]) + | ( :: ) of Head: 'T * Tail: 'T list \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl new file mode 100644 index 00000000000..6fa86a39437 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl @@ -0,0 +1,61 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionListType.fs", false, + QualifiedNameOfFile RegressionListType, [], [], + [SynModuleOrNamespace + ([RegressionListType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl ([], SynTypar (T, None, false))], [], + (1,9--1,13))), [], [List], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,9)), + Simple + (Union + (None, + [SynUnionCase + ([], + SynIdent + (op_Nil, + Some + (OriginalNotationWithParen + ((2,6--2,7), "[]", (2,8--2,9)))), Fields [], + PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (2,6--2,10), { BarRange = Some (2,4--2,5) }); + SynUnionCase + ([], + SynIdent + (op_ColonColon, + Some + (OriginalNotationWithParen + ((3,6--3,7), "::", (3,11--3,12)))), + Fields + [SynField + ([], false, Some Head, + Var (SynTypar (T, None, false), (3,23--3,25)), + false, + PreXmlDoc ((3,17), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,17--3,25), { LeadingKeyword = None }); + SynField + ([], false, Some Tail, + App + (LongIdent + (SynLongIdent ([list], [], [None])), None, + [Var + (SynTypar (T, None, false), (3,34--3,36))], + [], None, true, (3,34--3,41)), false, + PreXmlDoc ((3,28), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,28--3,41), { LeadingKeyword = None })], + PreXmlDoc ((3,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,6--3,41), { BarRange = Some (3,4--3,5) })], + (2,4--3,41)), (2,4--3,41)), [], None, (1,5--3,41), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,14--1,15) + WithKeyword = None })], (1,0--3,41))], PreXmlDocEmpty, [], + None, (1,0--3,41), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs index e65287d6f2d..4b54405dff0 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs @@ -1 +1 @@ -type MyFlatOption = None: MyFlatOption | Some: string -> MyFlatOption \ No newline at end of file +type MyFlatOption = None | Some of string \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs index 8b1018d513f..f7932400e88 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs @@ -1,3 +1,3 @@ -type Option<'T> = - | None: 'T option - | Some: Value:'T -> 'T option \ No newline at end of file + type Option<'T> = + | None + | Some of Value:'T \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl new file mode 100644 index 00000000000..42c258b375e --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl @@ -0,0 +1,41 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionOptionType.fs", false, + QualifiedNameOfFile RegressionOptionType, [], [], + [SynModuleOrNamespace + ([RegressionOptionType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], + Some + (PostfixList + ([SynTyparDecl ([], SynTypar (T, None, false))], [], + (1,15--1,19))), [], [Option], + PreXmlDoc ((1,4), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,9--1,15)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (None, None), Fields [], + PreXmlDoc ((2,8), FSharp.Compiler.Xml.XmlDocCollector), + None, (2,10--2,14), { BarRange = Some (2,8--2,9) }); + SynUnionCase + ([], SynIdent (Some, None), + Fields + [SynField + ([], false, Some Value, + Var (SynTypar (T, None, false), (3,24--3,26)), + false, + PreXmlDoc ((3,18), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,18--3,26), { LeadingKeyword = None })], + PreXmlDoc ((3,8), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,10--3,26), { BarRange = Some (3,8--3,9) })], + (2,8--3,26)), (2,8--3,26)), [], None, (1,9--3,26), + { LeadingKeyword = Type (1,4--1,8) + EqualsRange = Some (1,20--1,21) + WithKeyword = None })], (1,4--3,26))], PreXmlDocEmpty, [], + None, (1,4--3,26), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs b/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs new file mode 100644 index 00000000000..194814afffa --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs @@ -0,0 +1 @@ +type MyFlatOption = string | null \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs.bsl new file mode 100644 index 00000000000..1a874cb67b7 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/TypeAbbreviationAddingWithNull.fs.bsl @@ -0,0 +1,24 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/TypeAbbreviationAddingWithNull.fs", false, + QualifiedNameOfFile TypeAbbreviationAddingWithNull, [], [], + [SynModuleOrNamespace + ([TypeAbbreviationAddingWithNull], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [MyFlatOption], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,17)), + Simple + (TypeAbbrev + (Ok, + WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (1,20--1,33)), (1,20--1,33)), (1,20--1,33)), + [], None, (1,5--1,33), { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,18--1,19) + WithKeyword = None })], (1,0--1,33))], + PreXmlDocEmpty, [], None, (1,0--1,33), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) From df356d77e70839f138f3f3d2a8b3a6bc642c639c Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 28 Aug 2023 16:58:40 +0200 Subject: [PATCH 18/36] better error recovery merged in from a fresher base --- src/Compiler/pars.fsy | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 80704b431da..1efd3bacfe2 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -1595,18 +1595,6 @@ tyconDefn: let trivia: SynTypeDefnTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = None; WithKeyword = None } SynTypeDefn($1, SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None($1.Range), $1.Range), [], None, $1.Range, trivia) } - | typeNameInfo EQUALS tyconDefnRhsBlock - { - let nameRange = rhs parseState 1 - let (tcDefRepr: SynTypeDefnRepr), mWith, members = $3 nameRange - let declRange = unionRanges (rhs parseState 1) tcDefRepr.Range - let mWhole = (declRange, members) ||> unionRangeWithListBy (fun (mem: SynMemberDefn) -> mem.Range) - let equalsRange = rhs parseState 2 - - fun leadingKeyword -> - let trivia: SynTypeDefnTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = Some equalsRange ; WithKeyword = mWith } - SynTypeDefn($1, tcDefRepr, members, None, mWhole, trivia) } - | typeNameInfo tyconDefnAugmentation { let mWithKwd, classDefns = $2 let m = (rhs parseState 1, classDefns) ||> unionRangeWithListBy (fun mem -> mem.Range) @@ -1620,12 +1608,9 @@ tyconDefn: let (tcDefRepr, mWith, members) = $8 nameRange let (SynComponentInfo(_, _, _, lid, _, _, _, _)) = $1 let mEquals = rhs parseState 7 - // Gets the XML doc comments prior to the implicit constructor let xmlDoc = grabXmlDoc (parseState, $2, 2) - let m = match lid with [] -> rhs parseState 1 | _ -> rangeOfLid lid - let memberCtorPattern = spats |> Option.map (fun spats -> SynMemberDefn.ImplicitCtor(vis, $2, spats, Option.bind snd az, xmlDoc, m, { AsKeyword = Option.map fst az }) @@ -1633,24 +1618,31 @@ tyconDefn: let tcDefRepr = match tcDefRepr, memberCtorPattern with + | SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None _, m), Some ctor -> + reportParseErrorAt m (FSComp.SR.parsEmptyTypeDefinition()) + SynTypeDefnRepr.ObjectModel(SynTypeDefnKind.Unspecified, [ctor], unionRanges m mEquals) + + | SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None mName, m), _ -> + reportParseErrorAt m (FSComp.SR.parsEmptyTypeDefinition()) + tcDefRepr + | SynTypeDefnRepr.ObjectModel(k, cspec, m), Some ctor -> SynTypeDefnRepr.ObjectModel(k, ctor :: cspec, m) + | _, Some ctor -> reportParseErrorAt (rhs2 parseState 1 5) (FSComp.SR.parsOnlyClassCanTakeValueArguments ()) tcDefRepr + | _ -> match az with | Some(_, Some id) -> reportParseErrorAt (rhs parseState 6) (FSComp.SR.tcLetAndDoRequiresImplicitConstructionSequence ()) | _ -> () - tcDefRepr - let declRange = unionRanges (rhs parseState 1) tcDefRepr.Range let mWhole = (declRange, members) ||> unionRangeWithListBy (fun (mem: SynMemberDefn) -> mem.Range) |> unionRangeWithXmlDoc xmlDoc - fun leadingKeyword -> let trivia: SynTypeDefnTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = Some mEquals; WithKeyword = mWith } SynTypeDefn($1, tcDefRepr, members, memberCtorPattern, mWhole, trivia) } @@ -1667,7 +1659,6 @@ tyconDefn: | Some spats, _, _ -> let memberCtorPattern = SynMemberDefn.ImplicitCtor(vis, $2, spats, Option.bind snd az, xmlDoc, m, { AsKeyword = Option.map fst az }) [memberCtorPattern], unionRanges mName memberCtorPattern.Range - | _, _, Some(mAs, asId) -> let mAs = asId |> Option.map (fun id -> @@ -1675,19 +1666,15 @@ tyconDefn: id.idRange ) |> Option.defaultValue mAs - [], unionRanges mName mAs - | _, Some vis, _ -> [], unionRanges mName vis.Range - | _ -> [], mName fun leadingKeyword -> let trivia = { SynTypeDefnTrivia.Zero with LeadingKeyword = leadingKeyword } - SynTypeDefn($1, SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None(mName), mName), members, None, mName, trivia) } - + SynTypeDefn($1, SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None(mName), mName), members, None, mWhole, trivia) } /* The right-hand-side of a type definition */ tyconDefnRhsBlock: @@ -1716,6 +1703,10 @@ tyconDefnRhsBlock: let tcDefRepr, members = $2 nameRange (checkForMultipleAugmentations m ($4 @ optClassDefn) []) tcDefRepr, mWith, members) } + | OBLOCKBEGIN oblockend + { fun mName -> + SynTypeDefnRepr.Simple(SynTypeDefnSimpleRepr.None mName, mName), None, [] } + | tyconDefnRhs opt_classDefn { let m = rhs parseState 1 let mWith, optClassDefn = $2 @@ -1776,7 +1767,7 @@ tyconClassDefn: /* The right-hand-side of a object type definition where the class/interface/struct kind has not been specified */ classDefnBlockKindUnspecified: - | OBLOCKBEGIN classDefnMembers recover + | OBLOCKBEGIN classDefnMembersAtLeastOne recover { if not $3 then reportParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedEndOfFileTypeDefinition()) let mopt = match $2 with @@ -1784,7 +1775,7 @@ classDefnBlockKindUnspecified: | _ -> None false, $2, mopt } - | OBLOCKBEGIN classDefnMembers oblockend + | OBLOCKBEGIN classDefnMembersAtLeastOne oblockend { let mopt = match $2 with | _ :: _ -> Some((rhs parseState 1, $2) ||> unionRangeWithListBy (fun (d: SynMemberDefn) -> d.Range)) From 14f835aea644268ac328d37a2941b0d026665084 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 28 Aug 2023 18:38:17 +0200 Subject: [PATCH 19/36] separated definition --- src/Compiler/pars.fsy | 116 ++++++++++-------- .../Nullness/RegressionOptionType.fs | 6 +- 2 files changed, 69 insertions(+), 53 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 1efd3bacfe2..bf7f3c24a0d 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -288,11 +288,15 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %nonassoc prec_tuptyptail_prefix /* ditto */ %nonassoc prec_toptuptyptail_prefix /* ditto */ + +%nonassoc prec_above_bar %left BAR +%nonassoc prec_below_bar /* prec_pat_pat_action = "pattern when expr -> expr" * Lower than match extensions - i.e. BAR. */ %nonassoc prec_pat_pat_action /* lower than BAR */ +%nonassoc prec_multiple_union_cases %right RARROW %nonassoc IDENT LBRACK @@ -377,7 +381,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %nonassoc prec_interaction_empty %nonassoc prec_union_case_declaration -%nonassoc prec_multiple_union_cases + %% @@ -976,11 +980,11 @@ classMemberSpfn: let trivia: SynMemberSigMemberTrivia = { GetSetKeywords = getSetRangeOpt } SynMemberSig.Member(valSpfn, flags, mWhole, trivia) } - | opt_attributes opt_access interfaceMember appType + | opt_attributes opt_access interfaceMember appTypeWithoutNull { if Option.isSome $2 then errorR(Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier(), rhs parseState 2)) SynMemberSig.Interface($4, unionRanges (rhs parseState 3) ($4).Range) } - | opt_attributes opt_access INHERIT appType + | opt_attributes opt_access INHERIT appTypeWithoutNull { if Option.isSome $2 then errorR (Error(FSComp.SR.parsVisibilityDeclarationsShouldComePriorToIdentifier (), rhs parseState 2)) SynMemberSig.Inherit($4, unionRanges (rhs parseState 1) $4.Range) } @@ -1361,7 +1365,7 @@ openDecl: { let mOpen = rhs parseState 1 SynOpenDeclTarget.ModuleOrNamespace(SynLongIdent([], [], []), mOpen.EndRange), mOpen } - | OPEN typeKeyword appType + | OPEN typeKeyword appTypeWithoutNull { let mOpen = rhs parseState 1 let mPath = $3.Range SynOpenDeclTarget.Type($3, mPath), unionRanges mOpen mPath } @@ -1992,7 +1996,7 @@ classDefnMember: [SynMemberDefn.Member(binding, mWhole)] } - | opt_attributes opt_access interfaceMember appType opt_interfaceImplDefn + | opt_attributes opt_access interfaceMember appTypeWithoutNull opt_interfaceImplDefn { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesAreNotPermittedOnInterfaceImplementations(), rhs parseState 1)) if Option.isSome $2 then errorR(Error(FSComp.SR.parsInterfacesHaveSameVisibilityAsEnclosingType(), rhs parseState 3)) let mWithKwd, members, mWhole = @@ -2602,16 +2606,16 @@ typeConstraint: | "unmanaged" -> SynTypeConstraint.WhereTyparIsUnmanaged($1, lhs parseState) | nm -> raiseParseErrorAt (rhs parseState 3) (FSComp.SR.parsUnexpectedIdentifier(nm + " (4)")) } - | appType + | appTypeWithoutNull { SynTypeConstraint.WhereSelfConstrained($1, lhs parseState) } typeAlts: - | typeAlts OR appType + | typeAlts OR appTypeWithoutNull { let mOr = rhs parseState 2 let m = unionRanges $1.Range $3.Range SynType.Or($1, $3, m, { OrKeyword = mOr }) } - | appType + | appTypeWithoutNull { $1 } /* The core of a union type definition */ @@ -2669,7 +2673,7 @@ attrUnionCaseDecl: | opt_attributes opt_access unionCaseName OF recover { mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 4) >> Choice2Of2 } - | opt_attributes opt_access unionCaseName COLON topType %prec prec_toptuptyptail_prefix + | opt_attributes opt_access unionCaseName COLON topType %prec prec_above_bar { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.FullType $5) (rhs2 parseState 1 5) >> Choice2Of2 } @@ -2759,12 +2763,12 @@ unionCaseReprElements: { [$1] } unionCaseReprElement: - | ident COLON appType %prec IDENT + | ident COLON appTypeNullableInParens { let xmlDoc = grabXmlDoc(parseState, [], 1) let mWhole = rhs2 parseState 1 3 |> unionRangeWithXmlDoc xmlDoc mkSynNamedField ($1, $3, xmlDoc, mWhole) } - | appType %prec IDENT + | appTypeNullableInParens { let xmlDoc = grabXmlDoc(parseState, [], 1) mkSynAnonField ($1, xmlDoc) } @@ -5115,9 +5119,10 @@ typars: SynType.Paren($2, m) } typarAlts: - | typarAlts OR appType + | typarAlts OR appTypeCanBeNullable { let mOr = rhs parseState 2 - let m = unionRanges $1.Range $3.Range + let appType : SynType = $3 + let m = unionRanges $1.Range appType.Range SynType.Or($1, $3, m, { OrKeyword = mOr }) } | typar @@ -5450,7 +5455,7 @@ opt_objExprInterfaces: { (* silent recovery *) $2 } objExprInterface: - | interfaceMember appType opt_objExprBindings opt_declEnd opt_OBLOCKSEP + | interfaceMember appTypeWithoutNull opt_objExprBindings opt_declEnd opt_OBLOCKSEP { let mWithKwd, bindings, members = $3 let m = match List.tryLast members with @@ -5645,7 +5650,7 @@ topTupleType: let path = SynTupleTypeSegment.Type ty :: SynTupleTypeSegment.Star mStar :: (List.map fst $2) mkSynTypeTuple path, List.choose snd $2 } - | topAppType %prec IDENT + | topAppType %prec prec_above_bar { let ty, mdata = $1 ty, [mdata] } @@ -5667,19 +5672,19 @@ topTupleTypeElements: reportParseErrorAt mStar (FSComp.SR.parsExpectingType ()) (SynTupleTypeSegment.Type ty, None) :: (SynTupleTypeSegment.Star mStar, None) :: $2 } - | topAppType %prec prec_toptuptyptail_prefix + | topAppType %prec prec_above_bar { let t, argInfo = $1 [ SynTupleTypeSegment.Type t, Some argInfo ] } topAppType: - | attributes appType COLON appType + | attributes appTypeCanBeNullable COLON appTypeCanBeNullable %prec prec_above_bar { match $2 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let m = unionRanges (rhs parseState 1) $4.Range SynType.SignatureParameter($1, false, Some id, $4, m), SynArgInfo($1, false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | attributes appType COLON recover + | attributes appTypeCanBeNullable COLON recover %prec prec_above_bar { match $2 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let mColon = rhs parseState 2 @@ -5688,28 +5693,28 @@ topAppType: SynType.SignatureParameter($1, false, Some id, ty, m), SynArgInfo($1, false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | attributes QMARK ident COLON appType + | attributes QMARK ident COLON appTypeCanBeNullable %prec prec_above_bar { let m = unionRanges (rhs parseState 1) $5.Range SynType.SignatureParameter($1, true, Some $3, $5, m), SynArgInfo($1, true, Some $3) } - | attributes QMARK ident COLON recover + | attributes QMARK ident COLON recover %prec prec_above_bar { let mColon = rhs parseState 4 let m = unionRanges (rhs parseState 1) mColon let ty = SynType.FromParseError(mColon.EndRange) SynType.SignatureParameter($1, true, Some $3, ty, m), SynArgInfo($1, true, Some $3) } - | attributes appType + | attributes appTypeCanBeNullable %prec prec_above_bar { let m = unionRanges (rhs parseState 1) $2.Range SynType.SignatureParameter($1, false, None, $2, m), SynArgInfo($1, false, None) } - | appType COLON appType + | appTypeCanBeNullable COLON appTypeCanBeNullable %prec prec_above_bar { match $1 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let m = unionRanges (rhs parseState 1) $3.Range SynType.SignatureParameter([], false, Some id, $3, m), SynArgInfo([], false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | appType COLON recover + | appTypeCanBeNullable COLON recover %prec prec_above_bar { match $1 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let mColon = rhs parseState 2 @@ -5718,17 +5723,17 @@ topAppType: SynType.SignatureParameter([], false, Some id, ty, m), SynArgInfo([], false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | QMARK ident COLON appType + | QMARK ident COLON appTypeCanBeNullable %prec prec_above_bar { let m = unionRanges (rhs parseState 1) $4.Range SynType.SignatureParameter([], true, Some $2, $4, m), SynArgInfo([], true, Some $2) } - | QMARK ident COLON recover + | QMARK ident COLON recover %prec prec_above_bar { let mColon = rhs parseState 3 let m = unionRanges (rhs parseState 1) mColon let ty = SynType.FromParseError(mColon.EndRange) SynType.SignatureParameter([], true, Some $2, ty, m), SynArgInfo([], true, Some $2) } - | appType + | appTypeCanBeNullable %prec prec_above_bar { $1, SynArgInfo([], false, None) } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ @@ -5762,12 +5767,12 @@ typEOF: tupleType: - | appType STAR tupleOrQuotTypeElements + | appTypeCanBeNullable STAR tupleOrQuotTypeElements { let mStar = rhs parseState 2 let path = SynTupleTypeSegment.Type $1 :: SynTupleTypeSegment.Star mStar :: $3 mkSynTypeTuple path } - | appType STAR recover + | appTypeCanBeNullable STAR recover { let mStar = rhs parseState 2 let ty = SynType.FromParseError(mStar.EndRange) let path = [SynTupleTypeSegment.Type $1; SynTupleTypeSegment.Star mStar; SynTupleTypeSegment.Type ty] @@ -5793,28 +5798,28 @@ tupleType: let path = [SynTupleTypeSegment.Slash mSlash; SynTupleTypeSegment.Type ty] mkSynTypeTuple path } - | appType INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements + | appTypeCanBeNullable INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator()) let mSlash = rhs parseState 2 let path = SynTupleTypeSegment.Type $1 :: SynTupleTypeSegment.Slash mSlash :: $3 mkSynTypeTuple path } - | appType INFIX_STAR_DIV_MOD_OP recover + | appTypeCanBeNullable INFIX_STAR_DIV_MOD_OP recover { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator ()) let mSlash = rhs parseState 2 let ty = SynType.FromParseError(mSlash.EndRange) let path = [SynTupleTypeSegment.Type $1; SynTupleTypeSegment.Slash mSlash; SynTupleTypeSegment.Type ty] mkSynTypeTuple path } - | appType %prec prec_tuptyp_prefix + | appTypeCanBeNullable %prec prec_above_bar { $1 } tupleOrQuotTypeElements: - | appType STAR tupleOrQuotTypeElements + | appTypeCanBeNullable STAR tupleOrQuotTypeElements { let mStar = rhs parseState 2 SynTupleTypeSegment.Type $1 :: SynTupleTypeSegment.Star mStar :: $3 } - | appType STAR recover + | appTypeCanBeNullable STAR recover { let mStar = rhs parseState 2 let ty = SynType.FromParseError(mStar.EndRange) [SynTupleTypeSegment.Type $1; SynTupleTypeSegment.Star mStar; SynTupleTypeSegment.Type ty] } @@ -5825,12 +5830,12 @@ tupleOrQuotTypeElements: reportParseErrorAt mStar (FSComp.SR.parsExpectingType ()) SynTupleTypeSegment.Type ty :: SynTupleTypeSegment.Star mStar :: $2 } - | appType INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements + | appTypeCanBeNullable INFIX_STAR_DIV_MOD_OP tupleOrQuotTypeElements { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator ()) let mSlash = rhs parseState 2 SynTupleTypeSegment.Type $1 :: SynTupleTypeSegment.Slash mSlash :: $3 } - | appType INFIX_STAR_DIV_MOD_OP recover + | appTypeCanBeNullable INFIX_STAR_DIV_MOD_OP recover { if $2 <> "/" then reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnexpectedInfixOperator ()) let mSlash = rhs parseState 2 let ty = SynType.FromParseError(mSlash.EndRange) @@ -5843,7 +5848,7 @@ tupleOrQuotTypeElements: reportParseErrorAt mSlash (FSComp.SR.parsExpectingType ()) SynTupleTypeSegment.Type ty :: SynTupleTypeSegment.Slash mSlash :: $2 } - | appType %prec prec_tuptyptail_prefix + | appTypeCanBeNullable %prec prec_tuptyptail_prefix { [ SynTupleTypeSegment.Type $1 ] } appTypeCon: @@ -5862,28 +5867,39 @@ appTypeConPower: | appTypeCon { $1 } -appType: - | appType MAYBENULL__ - { SynType.WithNull($1, true, lhs parseState) } - - | appType WITHNULL__ +appTypeCanBeNullable: + | appTypeWithoutNull BAR NULL %prec prec_bar_null { SynType.WithNull($1, false, lhs parseState) } - | appType BAR NULL %prec prec_bar_null + | appTypeWithoutNull + { $1 } + +appTypeNullableInParens: + | appTypeWithoutNull + { $1 } + + | LPAREN appTypeCanBeNullable rparen %prec prec_bar_null + { $2 } + +appTypeWithoutNull: + | appTypeWithoutNull MAYBENULL__ + { SynType.WithNull($1, true, lhs parseState) } + + | appTypeWithoutNull WITHNULL__ { SynType.WithNull($1, false, lhs parseState) } /* - | appType QMARK + | appTypeWithoutNull QMARK { SynType.WithNull($1, false, lhs parseState) } */ - | appType arrayTypeSuffix + | appTypeWithoutNull arrayTypeSuffix { SynType.Array($2, $1, lhs parseState) } - | appType HIGH_PRECEDENCE_BRACK_APP arrayTypeSuffix /* only HPA for "name[]" allowed here */ + | appTypeWithoutNull HIGH_PRECEDENCE_BRACK_APP arrayTypeSuffix /* only HPA for "name[]" allowed here */ { SynType.Array($3, $1, lhs parseState) } - | appType appTypeConPower + | appTypeWithoutNull appTypeConPower /* note: use "rhs parseState 1" to deal with parens in "(int) list" */ { SynType.App($2, None, [$1], [], None, true, unionRanges (rhs parseState 1) $2.Range) } @@ -6076,24 +6092,24 @@ atomType: { reportParseErrorAt (rhs parseState 1) (FSComp.SR.parsUnmatchedParen ()) SynType.Paren($2, lhs parseState) } - | STRUCT LPAREN appType STAR tupleOrQuotTypeElements rparen + | STRUCT LPAREN appTypeCanBeNullable STAR tupleOrQuotTypeElements rparen { let mStar = rhs parseState 4 let path = SynTupleTypeSegment.Type $3 :: SynTupleTypeSegment.Star mStar :: $5 let m = rhs2 parseState 1 6 SynType.Tuple(true, path, m) } - | STRUCT LPAREN appType STAR tupleOrQuotTypeElements recover + | STRUCT LPAREN appTypeCanBeNullable STAR tupleOrQuotTypeElements recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) let mStar = rhs parseState 4 let path = SynTupleTypeSegment.Type $3 :: SynTupleTypeSegment.Star mStar :: $5 let m = rhs2 parseState 1 5 SynType.Tuple(true, path, m) } - | STRUCT LPAREN appType STAR recover + | STRUCT LPAREN appTypeCanBeNullable STAR recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) SynType.Anon(lhs parseState) } - | STRUCT LPAREN appType recover + | STRUCT LPAREN appTypeCanBeNullable recover { reportParseErrorAt (rhs parseState 2) (FSComp.SR.parsUnmatchedParen()) SynType.Anon(lhs parseState) } diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs index f7932400e88..8b1018d513f 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs @@ -1,3 +1,3 @@ - type Option<'T> = - | None - | Some of Value:'T \ No newline at end of file +type Option<'T> = + | None: 'T option + | Some: Value:'T -> 'T option \ No newline at end of file From dbf1332365893b00df2dc8ec7e70463c42fecf0f Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 29 Aug 2023 15:28:38 +0200 Subject: [PATCH 20/36] still not there --- src/Compiler/pars.fsy | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index bf7f3c24a0d..c8035879337 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2388,14 +2388,8 @@ tyconDefnOrSpfnSimpleRepr: { errorR(Error(FSComp.SR.parsUnexpectedQuotationOperatorInTypeAliasDidYouMeanVerbatimString(), rhs parseState 4)) SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.ErrorRecovery, SynType.LongIdent($3), unionRanges (rhs parseState 1) $3.Range) } - /* A type abbreviation */ - | opt_attributes opt_access typ - { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) - if Option.isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(), rhs parseState 2)) - SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } - /* A union type definition */ - | opt_attributes opt_access unionTypeRepr + | opt_attributes opt_access unionTypeRepr %prec prec_multiple_union_cases { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) let rangesOf3 = $3 |> List.map (function Choice1Of2 ec -> ec.Range | Choice2Of2 uc -> uc.Range) let mWhole = (rhs2 parseState 1 2, rangesOf3) ||> List.fold unionRanges @@ -2411,6 +2405,12 @@ tyconDefnOrSpfnSimpleRepr: SynTypeDefnSimpleRepr.Union($2, $3 |> List.choose (function Choice2Of2 data -> Some(data) | Choice1Of2 _ -> failwith "huh?"), mWhole) } + + /* A type abbreviation */ + | opt_attributes opt_access typ %prec IDENT + { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(), rhs parseState 2)) + SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } /* A record type definition */ | opt_attributes opt_access braceFieldDeclList @@ -2628,7 +2628,7 @@ unionTypeRepr: | firstUnionCaseDeclOfMany barAndgrabXmlDoc attrUnionCaseDecls %prec prec_multiple_union_cases { $1 :: $3 $2 } - | firstUnionCaseDecl + | firstUnionCaseDecl %prec IDENT { [$1] } barAndgrabXmlDoc: @@ -5871,15 +5871,15 @@ appTypeCanBeNullable: | appTypeWithoutNull BAR NULL %prec prec_bar_null { SynType.WithNull($1, false, lhs parseState) } - | appTypeWithoutNull + | appTypeWithoutNull %prec prec_above_bar { $1 } appTypeNullableInParens: - | appTypeWithoutNull + | appTypeWithoutNull %prec prec_above_bar { $1 } | LPAREN appTypeCanBeNullable rparen %prec prec_bar_null - { $2 } + { SynType.Paren($2, lhs parseState) } appTypeWithoutNull: | appTypeWithoutNull MAYBENULL__ @@ -6307,7 +6307,7 @@ path: | GLOBAL { SynLongIdent([ident(MangledGlobalName, rhs parseState 1)], [], [Some(IdentTrivia.OriginalNotation "global")]) } - | ident + | ident %prec IDENT { SynLongIdent([$1], [], [None]) } | path DOT ident From 80e69d3b8f31df24ab44cd791d70189bbc02c88d Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 31 Aug 2023 15:45:27 +0200 Subject: [PATCH 21/36] BAR_NULL created in LexFilter --- src/Compiler/Driver/CompilerDiagnostics.fs | 1 + src/Compiler/FSStrings.resx | 3 + src/Compiler/FSharp.Compiler.Service.fsproj | 2 +- src/Compiler/Service/ServiceLexing.fs | 1 + src/Compiler/SyntaxTree/LexFilter.fs | 3 + src/Compiler/pars.fsy | 95 ++++++++++--------- src/Compiler/xlf/FSStrings.cs.xlf | 5 + src/Compiler/xlf/FSStrings.de.xlf | 5 + src/Compiler/xlf/FSStrings.es.xlf | 5 + src/Compiler/xlf/FSStrings.fr.xlf | 5 + src/Compiler/xlf/FSStrings.it.xlf | 5 + src/Compiler/xlf/FSStrings.ja.xlf | 5 + src/Compiler/xlf/FSStrings.ko.xlf | 5 + src/Compiler/xlf/FSStrings.pl.xlf | 5 + src/Compiler/xlf/FSStrings.pt-BR.xlf | 5 + src/Compiler/xlf/FSStrings.ru.xlf | 5 + src/Compiler/xlf/FSStrings.tr.xlf | 5 + src/Compiler/xlf/FSStrings.zh-Hans.xlf | 5 + src/Compiler/xlf/FSStrings.zh-Hant.xlf | 5 + tests/service/SyntaxTreeTests.fs | 2 +- .../FunctionArgAsPatternWithNullCase.fs | 1 + .../Nullness/IntListOrNullOrNullOrNull.fs.bsl | 42 ++++---- .../SyntaxTree/Nullness/MatchWithTypeCast.fs | 2 + .../Nullness/MatchWithTypeCast.fs.bsl | 23 +++++ .../Nullness/MatchWithTypeCastParens.fs | 2 + .../Nullness/MatchWithTypeCastParens.fs.bsl | 23 +++++ ...chWithTypeCastParensAndSeparateNullCase.fs | 2 + ...thTypeCastParensAndSeparateNullCase.fs.bsl | 26 +++++ .../RegressionAnnotatedInlinePatternMatch.fs | 1 + .../RegressionOneLinerOptionType.fs.bsl | 37 ++++++++ .../Nullness/RegressionOptionType.fs.bsl | 61 ++++++++---- .../Nullness/StringOrNullInFunctionArg.fs | 2 +- .../Nullness/StringOrNullInFunctionArg.fs.bsl | 14 +-- 33 files changed, 308 insertions(+), 100 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs.bsl create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs.bsl diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 0d917c3e8e4..b6923077422 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -1286,6 +1286,7 @@ type Exception with | Parser.TOKEN_INTERP_STRING_END -> SR.GetString("Parser.TOKEN.INTERP.STRING.END") | Parser.TOKEN_WITHNULL__ -> SR.GetString("Parser.TOKEN.WITHNULL__") | Parser.TOKEN_NOTNULL__ -> SR.GetString("Parser.TOKEN.NOTNULL__") + | Parser.TOKEN_BAR_NULL -> SR.GetString("Parser.TOKEN.BAR_NULL") | unknown -> let result = sprintf "unknown token tag %+A" unknown Debug.Assert(false, result) diff --git a/src/Compiler/FSStrings.resx b/src/Compiler/FSStrings.resx index bbd5b912219..83f488845d7 100644 --- a/src/Compiler/FSStrings.resx +++ b/src/Compiler/FSStrings.resx @@ -426,6 +426,9 @@ symbol '|}' + + symbol '|' (directly before 'null') + symbol '>}' diff --git a/src/Compiler/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj index bd1182373c2..83b5bdb2e15 100644 --- a/src/Compiler/FSharp.Compiler.Service.fsproj +++ b/src/Compiler/FSharp.Compiler.Service.fsproj @@ -162,7 +162,7 @@ AbstractIL\illex.fsl - --module FSharp.Compiler.AbstractIL.AsciiParser --open FSharp.Compiler.AbstractIL.AsciiConstants --open FSharp.Compiler.AbstractIL.IL --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing --buffer-type-argument char + --module FSharp.Compiler.AbstractIL.AsciiParser --open FSharp.Compiler.AbstractIL.AsciiConstants --open FSharp.Compiler.AbstractIL.IL --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing --buffer-type-argument char -v AbstractIL\ilpars.fsy diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs index d22dea427c9..e40cb7086de 100644 --- a/src/Compiler/Service/ServiceLexing.fs +++ b/src/Compiler/Service/ServiceLexing.fs @@ -394,6 +394,7 @@ module internal TokenClassifications = | MAYBENULL__ | NOTNULL__ | WITHNULL__ + | BAR_NULL | TYPE_COMING_SOON | TYPE_IS_HERE | MODULE_COMING_SOON diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index f82facd1c72..8f2e23acf9e 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -2436,6 +2436,9 @@ type LexFilterImpl ( pool.Return tokenTup hwTokenFetch useBlockRule + | BAR, _ when (lexbuf.SupportsFeature(LanguageFeature.NullnessChecking) && match peekNextToken() with NULL -> true | _ -> false) -> + returnToken tokenLexbufState BAR_NULL + // Ordinary tokens start a vanilla block | _, CtxtSeqBlock _ :: _ -> pushCtxt tokenTup (CtxtVanilla(tokenStartPos, isLongIdentEquals token)) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index c8035879337..f8d3469e21b 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -89,7 +89,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token GREATER_RBRACK STRUCT SIG %token STATIC MEMBER CLASS ABSTRACT OVERRIDE DEFAULT CONSTRUCTOR INHERIT %token EXTERN VOID PUBLIC PRIVATE INTERNAL GLOBAL -%token MAYBENULL__ NOTNULL__ WITHNULL__ +%token MAYBENULL__ NOTNULL__ WITHNULL__ BAR_NULL /* for parser 'escape hatch' out of expression context without consuming the 'recover' token */ %token TYPE_COMING_SOON TYPE_IS_HERE MODULE_COMING_SOON MODULE_IS_HERE @@ -236,9 +236,6 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> /* start with lowest */ -/* for appType BAR NULL to not override DU declaration or pattern matching */ -%left prec_bar_null - %nonassoc prec_args_error /* less than RPAREN */ %nonassoc prec_atomexpr_lparen_error /* less than RPAREN */ @@ -288,15 +285,12 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %nonassoc prec_tuptyptail_prefix /* ditto */ %nonassoc prec_toptuptyptail_prefix /* ditto */ - -%nonassoc prec_above_bar +%nonassoc BAR_NULL %left BAR -%nonassoc prec_below_bar /* prec_pat_pat_action = "pattern when expr -> expr" * Lower than match extensions - i.e. BAR. */ %nonassoc prec_pat_pat_action /* lower than BAR */ -%nonassoc prec_multiple_union_cases %right RARROW %nonassoc IDENT LBRACK @@ -380,8 +374,6 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %left HIGH_PRECEDENCE_TYAPP %nonassoc prec_interaction_empty -%nonassoc prec_union_case_declaration - %% @@ -1651,7 +1643,7 @@ tyconDefn: let trivia: SynTypeDefnTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = Some mEquals; WithKeyword = mWith } SynTypeDefn($1, tcDefRepr, members, memberCtorPattern, mWhole, trivia) } - | typeNameInfo opt_attributes opt_access opt_HIGH_PRECEDENCE_APP opt_simplePatterns optAsSpec recover + | typeNameInfo opt_attributes opt_access opt_HIGH_PRECEDENCE_APP opt_simplePatterns optAsSpec recover { let vis, spats, az = $3, $5, $6 let (SynComponentInfo(longId = lid)) = $1 // Gets the XML doc comments prior to the implicit constructor @@ -2389,7 +2381,7 @@ tyconDefnOrSpfnSimpleRepr: SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.ErrorRecovery, SynType.LongIdent($3), unionRanges (rhs parseState 1) $3.Range) } /* A union type definition */ - | opt_attributes opt_access unionTypeRepr %prec prec_multiple_union_cases + | opt_attributes opt_access unionTypeRepr { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) let rangesOf3 = $3 |> List.map (function Choice1Of2 ec -> ec.Range | Choice2Of2 uc -> uc.Range) let mWhole = (rhs2 parseState 1 2, rangesOf3) ||> List.fold unionRanges @@ -2406,11 +2398,11 @@ tyconDefnOrSpfnSimpleRepr: $3 |> List.choose (function Choice2Of2 data -> Some(data) | Choice1Of2 _ -> failwith "huh?"), mWhole) } - /* A type abbreviation */ - | opt_attributes opt_access typ %prec IDENT + /* A type abbreviation */ + | opt_attributes opt_access typ { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) if Option.isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(), rhs parseState 2)) - SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } + SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } /* A record type definition */ | opt_attributes opt_access braceFieldDeclList @@ -2625,10 +2617,10 @@ unionTypeRepr: | barAndgrabXmlDoc attrUnionCaseDecls { $2 $1 } - | firstUnionCaseDeclOfMany barAndgrabXmlDoc attrUnionCaseDecls %prec prec_multiple_union_cases + | firstUnionCaseDeclOfMany barAndgrabXmlDoc attrUnionCaseDecls { $1 :: $3 $2 } - | firstUnionCaseDecl %prec IDENT + | firstUnionCaseDecl { [$1] } barAndgrabXmlDoc: @@ -2637,10 +2629,10 @@ barAndgrabXmlDoc: grabXmlDoc(parseState, [], 1), mBar } attrUnionCaseDecls: - | attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls %prec prec_multiple_union_cases + | attrUnionCaseDecl barAndgrabXmlDoc attrUnionCaseDecls { (fun xmlDocAndBar -> $1 xmlDocAndBar :: $3 $2) } - | attrUnionCaseDecl %prec IDENT + | attrUnionCaseDecl { (fun xmlDocAndBar -> [ $1 xmlDocAndBar ]) } /* The core of a union case definition */ @@ -2673,7 +2665,7 @@ attrUnionCaseDecl: | opt_attributes opt_access unionCaseName OF recover { mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.Fields []) (rhs2 parseState 1 4) >> Choice2Of2 } - | opt_attributes opt_access unionCaseName COLON topType %prec prec_above_bar + | opt_attributes opt_access unionCaseName COLON topType { if parseState.LexBuffer.ReportLibraryOnlyFeatures then libraryOnlyWarning(lhs parseState) mkSynUnionCase $1 $2 $3 (SynUnionCaseKind.FullType $5) (rhs2 parseState 1 5) >> Choice2Of2 } @@ -2691,12 +2683,12 @@ unionCaseName: | nameop { $1 } - | LPAREN COLON_COLON rparen %prec IDENT + | LPAREN COLON_COLON rparen { let lpr = rhs parseState 1 let rpr = rhs parseState 3 SynIdent(ident(opNameCons, rhs parseState 2), Some(IdentTrivia.OriginalNotationWithParen(lpr, "::", rpr))) } - | LPAREN LBRACK RBRACK rparen %prec IDENT + | LPAREN LBRACK RBRACK rparen { let lpr = rhs parseState 1 let rpr = rhs parseState 3 SynIdent(ident(opNameNil, rhs2 parseState 2 3), Some(IdentTrivia.OriginalNotationWithParen(lpr, "[]", rpr))) } @@ -3082,6 +3074,9 @@ cType: | cType WITHNULL__ { SynType.WithNull($1, false, lhs parseState) } + | cType BAR_NULL NULL + { SynType.WithNull($1, false, lhs parseState) } + | cType AMP { let m = lhs parseState SynType.App(SynType.LongIdent(SynLongIdent([ident("byref", m)], [], [ Some(IdentTrivia.OriginalNotation "&") ])), None, [$1], [], None, true, m) } @@ -3405,12 +3400,18 @@ simplePatterns: let simplePats, _ = SimplePatsOfPat parseState.SynArgNameGenerator pat simplePats } +barCanBeRightBeforeNull: + | BAR + { } + | BAR_NULL + { } + headBindingPattern: | headBindingPattern AS constrPattern { SynPat.As($1, $3, rhs2 parseState 1 3) } - | headBindingPattern BAR headBindingPattern %prec path_disj + | headBindingPattern barCanBeRightBeforeNull headBindingPattern %prec path_disj { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } @@ -3688,7 +3689,7 @@ parenPattern: | parenPattern AS constrPattern { SynPat.As($1, $3, rhs2 parseState 1 3) } - | parenPattern BAR parenPattern %prec path_disj + | parenPattern barCanBeRightBeforeNull parenPattern %prec path_disj { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } @@ -4553,11 +4554,11 @@ withPatternClauses: | patternClauses { $1 None } - | BAR patternClauses %prec path_disj + | barCanBeRightBeforeNull patternClauses %prec path_disj { let mBar = rhs parseState 1 |> Some $2 mBar } - | BAR error + | barCanBeRightBeforeNull error { // silent recovery let mLast = rhs parseState 1 [], mLast } @@ -4581,7 +4582,7 @@ patternClauses: fun mBar -> [SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, { ArrowRange = Some mArrow; BarRange = mBar })], mLast } - | patternAndGuard patternResult BAR patternClauses + | patternAndGuard patternResult barCanBeRightBeforeNull patternClauses { let pat, guard = $1 let mArrow, resultExpr = $2 let mNextBar = rhs parseState 3 |> Some @@ -4590,7 +4591,7 @@ patternClauses: fun mBar -> (SynMatchClause(pat, guard, resultExpr, m, DebugPointAtTarget.Yes, { ArrowRange = Some mArrow; BarRange = mBar }) :: clauses), mLast } - | patternAndGuard error BAR patternClauses + | patternAndGuard error barCanBeRightBeforeNull patternClauses { let pat, guard = $1 let mNextBar = rhs parseState 3 |> Some let clauses, mLast = $4 mNextBar @@ -4599,7 +4600,7 @@ patternClauses: fun _mBar -> (SynMatchClause(pat, guard, arbExpr ("patternClauses1", m.EndRange), m, DebugPointAtTarget.Yes, SynMatchClauseTrivia.Zero) :: clauses), mLast } - | patternAndGuard patternResult BAR recover + | patternAndGuard patternResult barCanBeRightBeforeNull recover { let pat, guard = $1 let mArrow, resultExpr = $2 let mLast = rhs parseState 3 @@ -5650,7 +5651,7 @@ topTupleType: let path = SynTupleTypeSegment.Type ty :: SynTupleTypeSegment.Star mStar :: (List.map fst $2) mkSynTypeTuple path, List.choose snd $2 } - | topAppType %prec prec_above_bar + | topAppType { let ty, mdata = $1 ty, [mdata] } @@ -5672,19 +5673,19 @@ topTupleTypeElements: reportParseErrorAt mStar (FSComp.SR.parsExpectingType ()) (SynTupleTypeSegment.Type ty, None) :: (SynTupleTypeSegment.Star mStar, None) :: $2 } - | topAppType %prec prec_above_bar + | topAppType { let t, argInfo = $1 [ SynTupleTypeSegment.Type t, Some argInfo ] } topAppType: - | attributes appTypeCanBeNullable COLON appTypeCanBeNullable %prec prec_above_bar + | attributes appTypeCanBeNullable COLON appTypeCanBeNullable { match $2 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let m = unionRanges (rhs parseState 1) $4.Range SynType.SignatureParameter($1, false, Some id, $4, m), SynArgInfo($1, false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | attributes appTypeCanBeNullable COLON recover %prec prec_above_bar + | attributes appTypeCanBeNullable COLON recover { match $2 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let mColon = rhs parseState 2 @@ -5693,28 +5694,28 @@ topAppType: SynType.SignatureParameter($1, false, Some id, ty, m), SynArgInfo($1, false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | attributes QMARK ident COLON appTypeCanBeNullable %prec prec_above_bar + | attributes QMARK ident COLON appTypeCanBeNullable { let m = unionRanges (rhs parseState 1) $5.Range SynType.SignatureParameter($1, true, Some $3, $5, m), SynArgInfo($1, true, Some $3) } - | attributes QMARK ident COLON recover %prec prec_above_bar + | attributes QMARK ident COLON recover { let mColon = rhs parseState 4 let m = unionRanges (rhs parseState 1) mColon let ty = SynType.FromParseError(mColon.EndRange) SynType.SignatureParameter($1, true, Some $3, ty, m), SynArgInfo($1, true, Some $3) } - | attributes appTypeCanBeNullable %prec prec_above_bar + | attributes appTypeCanBeNullable { let m = unionRanges (rhs parseState 1) $2.Range SynType.SignatureParameter($1, false, None, $2, m), SynArgInfo($1, false, None) } - | appTypeCanBeNullable COLON appTypeCanBeNullable %prec prec_above_bar + | appTypeCanBeNullable COLON appTypeCanBeNullable { match $1 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let m = unionRanges (rhs parseState 1) $3.Range SynType.SignatureParameter([], false, Some id, $3, m), SynArgInfo([], false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | appTypeCanBeNullable COLON recover %prec prec_above_bar + | appTypeCanBeNullable COLON recover { match $1 with | SynType.LongIdent(SynLongIdent([id], _, _)) -> let mColon = rhs parseState 2 @@ -5723,17 +5724,17 @@ topAppType: SynType.SignatureParameter([], false, Some id, ty, m), SynArgInfo([], false, Some id) | _ -> raiseParseErrorAt (rhs parseState 2) (FSComp.SR.parsSyntaxErrorInLabeledType()) } - | QMARK ident COLON appTypeCanBeNullable %prec prec_above_bar + | QMARK ident COLON appTypeCanBeNullable { let m = unionRanges (rhs parseState 1) $4.Range SynType.SignatureParameter([], true, Some $2, $4, m), SynArgInfo([], true, Some $2) } - | QMARK ident COLON recover %prec prec_above_bar + | QMARK ident COLON recover { let mColon = rhs parseState 3 let m = unionRanges (rhs parseState 1) mColon let ty = SynType.FromParseError(mColon.EndRange) SynType.SignatureParameter([], true, Some $2, ty, m), SynArgInfo([], true, Some $2) } - | appTypeCanBeNullable %prec prec_above_bar + | appTypeCanBeNullable { $1, SynArgInfo([], false, None) } /* Any tokens in this grammar must be added to the lex filter rule 'peekAdjacentTypars' */ @@ -5811,7 +5812,7 @@ tupleType: let path = [SynTupleTypeSegment.Type $1; SynTupleTypeSegment.Slash mSlash; SynTupleTypeSegment.Type ty] mkSynTypeTuple path } - | appTypeCanBeNullable %prec prec_above_bar + | appTypeCanBeNullable { $1 } tupleOrQuotTypeElements: @@ -5868,17 +5869,17 @@ appTypeConPower: { $1 } appTypeCanBeNullable: - | appTypeWithoutNull BAR NULL %prec prec_bar_null + | appTypeWithoutNull BAR_NULL NULL { SynType.WithNull($1, false, lhs parseState) } - | appTypeWithoutNull %prec prec_above_bar + | appTypeWithoutNull { $1 } appTypeNullableInParens: - | appTypeWithoutNull %prec prec_above_bar + | appTypeWithoutNull { $1 } - | LPAREN appTypeCanBeNullable rparen %prec prec_bar_null + | LPAREN appTypeCanBeNullable rparen { SynType.Paren($2, lhs parseState) } appTypeWithoutNull: @@ -6307,7 +6308,7 @@ path: | GLOBAL { SynLongIdent([ident(MangledGlobalName, rhs parseState 1)], [], [Some(IdentTrivia.OriginalNotation "global")]) } - | ident %prec IDENT + | ident { SynLongIdent([$1], [], [None]) } | path DOT ident diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf index 9243bbb1e99..60fc64f144b 100644 --- a/src/Compiler/xlf/FSStrings.cs.xlf +++ b/src/Compiler/xlf/FSStrings.cs.xlf @@ -37,6 +37,11 @@ Případy sjednocení s malými písmeny jsou povolené jenom při použití atributu RequireQualifiedAccess. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' symbol ..^ diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf index 20cd1c86b48..17c5f738b21 100644 --- a/src/Compiler/xlf/FSStrings.de.xlf +++ b/src/Compiler/xlf/FSStrings.de.xlf @@ -37,6 +37,11 @@ Diskriminierte Union-Fälle in Kleinbuchstaben sind nur zulässig, wenn das RequireQualifiedAccess-Attribut verwendet wird. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' Symbol "..^" diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf index 8090f7b2152..bf72eec7182 100644 --- a/src/Compiler/xlf/FSStrings.es.xlf +++ b/src/Compiler/xlf/FSStrings.es.xlf @@ -37,6 +37,11 @@ Los casos de unión discriminada en minúsculas solo se permiten cuando se usa el atributo RequireQualifiedAccess + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' símbolo "..^" diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf index ea985ab025e..16d1c39aecf 100644 --- a/src/Compiler/xlf/FSStrings.fr.xlf +++ b/src/Compiler/xlf/FSStrings.fr.xlf @@ -37,6 +37,11 @@ Les cas d’union discriminée en minuscules sont uniquement autorisés lors de l’utilisation de l’attribut RequireQualifiedAccess. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' symbole '..^' diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf index 94a1fff93bc..d28a6cbfd1d 100644 --- a/src/Compiler/xlf/FSStrings.it.xlf +++ b/src/Compiler/xlf/FSStrings.it.xlf @@ -37,6 +37,11 @@ I casi di unione discriminati minuscoli sono consentiti solo quando si usa l'attributo RequireQualifiedAccess + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' simbolo '..^' diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf index cffa76300ac..dfd45856835 100644 --- a/src/Compiler/xlf/FSStrings.ja.xlf +++ b/src/Compiler/xlf/FSStrings.ja.xlf @@ -37,6 +37,11 @@ 小文字で区別される和集合のケースは、RequireQualifiedAccess 属性を使用する場合にのみ許可されます + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' シンボル '..^' diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf index 83b47b3df4f..5d2d199bc09 100644 --- a/src/Compiler/xlf/FSStrings.ko.xlf +++ b/src/Compiler/xlf/FSStrings.ko.xlf @@ -37,6 +37,11 @@ 소문자로 구분된 공용 구조체 케이스는 RequireQualifiedAccess 특성을 사용하는 경우에만 허용됩니다. + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' 기호 '..^' diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf index 36829f79504..9257e43f6c3 100644 --- a/src/Compiler/xlf/FSStrings.pl.xlf +++ b/src/Compiler/xlf/FSStrings.pl.xlf @@ -37,6 +37,11 @@ Przypadki unii z dyskryminatorem z małymi literami są dozwolone tylko w przypadku używania atrybutu RequireQualifiedAccess + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' symbol „..^” diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf index ce3337d3777..c6ad13c39eb 100644 --- a/src/Compiler/xlf/FSStrings.pt-BR.xlf +++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf @@ -37,6 +37,11 @@ Os casos de união discriminados em letras minúsculas só são permitidos ao usar o atributo RequireQualifiedAccess + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' símbolo '..^' diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf index 2f8c7a32041..374e4a20d12 100644 --- a/src/Compiler/xlf/FSStrings.ru.xlf +++ b/src/Compiler/xlf/FSStrings.ru.xlf @@ -37,6 +37,11 @@ Размеченные в нижнем регистре случаи объединения разрешены только при использовании атрибута RequireQualifiedAccess + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' символ "..^" diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf index 91baa073a99..f16b62dd249 100644 --- a/src/Compiler/xlf/FSStrings.tr.xlf +++ b/src/Compiler/xlf/FSStrings.tr.xlf @@ -37,6 +37,11 @@ Küçük harf ayrımlı birleşim durumlarına yalnızca RequireQualifiedAccess özniteliği kullanılırken izin verilir + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' '..^' sembolü diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf index 66bd6b6d79d..b67c6e95782 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf @@ -37,6 +37,11 @@ 仅当使用 RequireQualifiedAccess 属性时才允许区分小写的联合事例 + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' 符号 "..^" diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf index d68f93077e8..7a691848742 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf @@ -37,6 +37,11 @@ 只有在使用 RequireQualifiedAccess 屬性時,才允許小寫區分聯結案例 + + symbol '|' (directly before 'null') + symbol '|' (directly before 'null') + + symbol '..^' 符號 '..^' diff --git a/tests/service/SyntaxTreeTests.fs b/tests/service/SyntaxTreeTests.fs index b72b20d77d9..290e3fb4001 100644 --- a/tests/service/SyntaxTreeTests.fs +++ b/tests/service/SyntaxTreeTests.fs @@ -11,7 +11,7 @@ open NUnit.Framework let testCasesDir = Path.Combine(__SOURCE_DIRECTORY__, "data", "SyntaxTree") -let allTestCases = +let allTestCases = Directory.EnumerateFiles(testCasesDir, "*.fs?", SearchOption.AllDirectories) |> Seq.map (fun f -> let fileInfo = FileInfo(f) diff --git a/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs new file mode 100644 index 00000000000..5cb343224f6 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs @@ -0,0 +1 @@ +let myFunc ("abc" | "" : string | null | "123") = 15 diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl index f766b1c2cdf..e538c6dc34b 100644 --- a/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl @@ -15,31 +15,25 @@ ImplFile Some (SynBindingReturnInfo (WithNull - (WithNull - (WithNull - (App - (LongIdent - (SynLongIdent ([list], [], [None])), None, - [LongIdent - (SynLongIdent ([int], [], [None]))], [], - None, true, (1,8--1,16)), false, (1,8--1,23)), - false, (1,8--1,30)), false, (1,8--1,37)), - (1,8--1,37), [], { ColonRange = Some (1,6--1,7) })), + (App + (LongIdent (SynLongIdent ([list], [], [None])), + None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (1,8--1,16)), false, (1,8--1,23)), + (1,8--1,23), [], { ColonRange = Some (1,6--1,7) })), Typed - (ArrayOrList (false, [], (1,40--1,42)), + (ArbitraryAfterError ("localBinding2", (1,23--1,23)), WithNull - (WithNull - (WithNull - (App - (LongIdent (SynLongIdent ([list], [], [None])), - None, - [LongIdent (SynLongIdent ([int], [], [None]))], - [], None, true, (1,8--1,16)), false, - (1,8--1,23)), false, (1,8--1,30)), false, - (1,8--1,37)), (1,40--1,42)), (1,4--1,5), Yes (1,0--1,42), + (App + (LongIdent (SynLongIdent ([list], [], [None])), None, + [LongIdent (SynLongIdent ([int], [], [None]))], [], + None, true, (1,8--1,16)), false, (1,8--1,23)), + (1,23--1,23)), (1,4--1,5), Yes (1,0--1,23), { LeadingKeyword = Let (1,0--1,3) InlineKeyword = None - EqualsRange = Some (1,38--1,39) })], (1,0--1,42))], - PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], - (true, true), { ConditionalDirectives = [] - CodeComments = [] }, set [])) + EqualsRange = None })], (1,0--1,23))], PreXmlDocEmpty, [], + None, (1,0--2,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) + +(1,24)-(1,25) parse error Unexpected symbol '|' (directly before 'null') in binding. Expected '=' or other token. diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs new file mode 100644 index 00000000000..9986cca84a6 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs @@ -0,0 +1,2 @@ +match x with +| :? string | null -> () diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs.bsl b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs.bsl new file mode 100644 index 00000000000..86094715714 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCast.fs.bsl @@ -0,0 +1,23 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/MatchWithTypeCast.fs", false, + QualifiedNameOfFile MatchWithTypeCast, [], [], + [SynModuleOrNamespace + ([MatchWithTypeCast], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (Or + (IsInst + (LongIdent (SynLongIdent ([string], [], [None])), + (2,2--2,11)), Null (2,14--2,18), (2,2--2,18), + { BarRange = (2,12--2,13) }), None, + Const (Unit, (2,22--2,24)), (2,2--2,24), Yes, + { ArrowRange = Some (2,19--2,21) + BarRange = Some (2,0--2,1) })], (1,0--2,24), + { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,24))], PreXmlDocEmpty, + [], None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs new file mode 100644 index 00000000000..180b3db96df --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs @@ -0,0 +1,2 @@ +match x with +| :? (string | null) -> () diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs.bsl b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs.bsl new file mode 100644 index 00000000000..e3a174fcf11 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParens.fs.bsl @@ -0,0 +1,23 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/MatchWithTypeCastParens.fs", false, + QualifiedNameOfFile MatchWithTypeCastParens, [], [], + [SynModuleOrNamespace + ([MatchWithTypeCastParens], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (IsInst + (Paren + (WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (2,6--2,19)), (2,5--2,20)), (2,2--2,20)), + None, Const (Unit, (2,24--2,26)), (2,2--2,26), Yes, + { ArrowRange = Some (2,21--2,23) + BarRange = Some (2,0--2,1) })], (1,0--2,26), + { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,26))], PreXmlDocEmpty, + [], None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs new file mode 100644 index 00000000000..c738f9f8fed --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs @@ -0,0 +1,2 @@ +match x with +| :? (string | null) | null -> () diff --git a/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs.bsl b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs.bsl new file mode 100644 index 00000000000..2c62cd5cd41 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs.bsl @@ -0,0 +1,26 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/MatchWithTypeCastParensAndSeparateNullCase.fs", false, + QualifiedNameOfFile MatchWithTypeCastParensAndSeparateNullCase, [], [], + [SynModuleOrNamespace + ([MatchWithTypeCastParensAndSeparateNullCase], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (Or + (IsInst + (Paren + (WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (2,6--2,19)), (2,5--2,20)), (2,2--2,20)), + Null (2,23--2,27), (2,2--2,27), + { BarRange = (2,21--2,22) }), None, + Const (Unit, (2,31--2,33)), (2,2--2,33), Yes, + { ArrowRange = Some (2,28--2,30) + BarRange = Some (2,0--2,1) })], (1,0--2,33), + { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,33))], PreXmlDocEmpty, + [], None, (1,0--3,0), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs new file mode 100644 index 00000000000..5705b1cf0f4 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs @@ -0,0 +1 @@ +match x with | "123" -> "": string | _ -> "456" \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs.bsl new file mode 100644 index 00000000000..5b785c961d5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOneLinerOptionType.fs.bsl @@ -0,0 +1,37 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionOneLinerOptionType.fs", false, + QualifiedNameOfFile RegressionOneLinerOptionType, [], [], + [SynModuleOrNamespace + ([RegressionOneLinerOptionType], false, AnonModule, + [Types + ([SynTypeDefn + (SynComponentInfo + ([], None, [], [MyFlatOption], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + false, None, (1,5--1,17)), + Simple + (Union + (None, + [SynUnionCase + ([], SynIdent (None, None), Fields [], + PreXmlDoc ((1,20), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,20--1,24), { BarRange = None }); + SynUnionCase + ([], SynIdent (Some, None), + Fields + [SynField + ([], false, None, + LongIdent + (SynLongIdent ([string], [], [None])), false, + PreXmlDoc ((1,35), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,35--1,41), { LeadingKeyword = None })], + PreXmlDoc ((1,25), FSharp.Compiler.Xml.XmlDocCollector), + None, (1,27--1,41), { BarRange = Some (1,25--1,26) })], + (1,20--1,41)), (1,20--1,41)), [], None, (1,5--1,41), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,18--1,19) + WithKeyword = None })], (1,0--1,41))], PreXmlDocEmpty, [], + None, (1,0--1,41), { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl index 42c258b375e..3a0e50c61de 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl @@ -11,31 +11,52 @@ ImplFile Some (PostfixList ([SynTyparDecl ([], SynTypar (T, None, false))], [], - (1,15--1,19))), [], [Option], - PreXmlDoc ((1,4), FSharp.Compiler.Xml.XmlDocCollector), - true, None, (1,9--1,15)), + (1,11--1,15))), [], [Option], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + true, None, (1,5--1,11)), Simple (Union (None, [SynUnionCase - ([], SynIdent (None, None), Fields [], - PreXmlDoc ((2,8), FSharp.Compiler.Xml.XmlDocCollector), - None, (2,10--2,14), { BarRange = Some (2,8--2,9) }); + ([], SynIdent (None, None), + FullType + (App + (LongIdent + (SynLongIdent ([option], [], [None])), None, + [Var (SynTypar (T, None, false), (2,18--2,20))], + [], None, true, (2,18--2,27)), + SynValInfo ([], SynArgInfo ([], false, None))), + PreXmlDoc ((2,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (2,6--2,27), { BarRange = Some (2,4--2,5) }); SynUnionCase ([], SynIdent (Some, None), - Fields - [SynField - ([], false, Some Value, - Var (SynTypar (T, None, false), (3,24--3,26)), - false, - PreXmlDoc ((3,18), FSharp.Compiler.Xml.XmlDocCollector), - None, (3,18--3,26), { LeadingKeyword = None })], - PreXmlDoc ((3,8), FSharp.Compiler.Xml.XmlDocCollector), - None, (3,10--3,26), { BarRange = Some (3,8--3,9) })], - (2,8--3,26)), (2,8--3,26)), [], None, (1,9--3,26), - { LeadingKeyword = Type (1,4--1,8) - EqualsRange = Some (1,20--1,21) - WithKeyword = None })], (1,4--3,26))], PreXmlDocEmpty, [], - None, (1,4--3,26), { LeadingKeyword = None })], (true, true), + FullType + (Fun + (SignatureParameter + ([], false, Some Value, + Var + (SynTypar (T, None, false), (3,18--3,20)), + (3,12--3,20)), + App + (LongIdent + (SynLongIdent ([option], [], [None])), + None, + [Var + (SynTypar (T, None, false), (3,24--3,26))], + [], None, true, (3,24--3,33)), (3,12--3,33), + { ArrowRange = (3,21--3,23) }), + SynValInfo + ([[SynArgInfo ([], false, Some Value)]], + SynArgInfo ([], false, None))), + PreXmlDoc ((3,4), FSharp.Compiler.Xml.XmlDocCollector), + None, (3,6--3,33), { BarRange = Some (3,4--3,5) })], + (2,4--3,33)), (2,4--3,33)), [], None, (1,5--3,33), + { LeadingKeyword = Type (1,0--1,4) + EqualsRange = Some (1,16--1,17) + WithKeyword = None })], (1,0--3,33))], PreXmlDocEmpty, [], + None, (1,0--3,34), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) + +(2,6)-(2,27) parse warning This construct is deprecated: it is only for use in the F# library +(3,6)-(3,33) parse warning This construct is deprecated: it is only for use in the F# library diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs index 583756d370a..37569d4900a 100644 --- a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs @@ -1 +1 @@ -let myFunc (x: string | null) = 42 +let myFunc (x: (string | null)) = 42 diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl index e64ede7cd17..f369e771916 100644 --- a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl @@ -21,14 +21,16 @@ ImplFile (Typed (Named (SynIdent (x, None), false, None, (1,12--1,13)), - WithNull - (LongIdent (SynLongIdent ([string], [], [None])), - false, (1,15--1,28)), (1,12--1,28)), - (1,11--1,29))], None, (1,4--1,29)), None, - Const (Int32 42, (1,32--1,34)), (1,4--1,29), NoneAtLet, + Paren + (WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,16--1,29)), (1,15--1,30)), + (1,12--1,30)), (1,11--1,31))], None, (1,4--1,31)), + None, Const (Int32 42, (1,34--1,36)), (1,4--1,31), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) InlineKeyword = None - EqualsRange = Some (1,30--1,31) })], (1,0--1,34))], + EqualsRange = Some (1,32--1,33) })], (1,0--1,36))], PreXmlDocEmpty, [], None, (1,0--2,0), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) From f6620b77e05b0f28cfd7b501900b79da5aef4dc1 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 31 Aug 2023 16:21:22 +0200 Subject: [PATCH 22/36] Renaming to BAR_RIGHT_BEFORE_NULL, because that is what it is (NULL comes then as a separate token) --- src/Compiler/Driver/CompilerDiagnostics.fs | 2 +- src/Compiler/FSStrings.resx | 2 +- src/Compiler/Service/ServiceLexing.fs | 2 +- src/Compiler/SyntaxTree/LexFilter.fs | 2 +- src/Compiler/pars.fsy | 45 +++++++++---------- src/Compiler/xlf/FSStrings.cs.xlf | 2 +- src/Compiler/xlf/FSStrings.de.xlf | 2 +- src/Compiler/xlf/FSStrings.es.xlf | 2 +- src/Compiler/xlf/FSStrings.fr.xlf | 2 +- src/Compiler/xlf/FSStrings.it.xlf | 2 +- src/Compiler/xlf/FSStrings.ja.xlf | 2 +- src/Compiler/xlf/FSStrings.ko.xlf | 2 +- src/Compiler/xlf/FSStrings.pl.xlf | 2 +- src/Compiler/xlf/FSStrings.pt-BR.xlf | 2 +- src/Compiler/xlf/FSStrings.ru.xlf | 2 +- src/Compiler/xlf/FSStrings.tr.xlf | 2 +- src/Compiler/xlf/FSStrings.zh-Hans.xlf | 2 +- src/Compiler/xlf/FSStrings.zh-Hant.xlf | 2 +- .../RegressionAnnotatedInlinePatternMatch.fs | 3 +- ...gressionAnnotatedInlinePatternMatch.fs.bsl | 28 ++++++++++++ 20 files changed, 69 insertions(+), 41 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index b6923077422..7d3b0a933ea 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -1286,7 +1286,7 @@ type Exception with | Parser.TOKEN_INTERP_STRING_END -> SR.GetString("Parser.TOKEN.INTERP.STRING.END") | Parser.TOKEN_WITHNULL__ -> SR.GetString("Parser.TOKEN.WITHNULL__") | Parser.TOKEN_NOTNULL__ -> SR.GetString("Parser.TOKEN.NOTNULL__") - | Parser.TOKEN_BAR_NULL -> SR.GetString("Parser.TOKEN.BAR_NULL") + | Parser.TOKEN_BAR_RIGHT_BEFORE_NULL -> SR.GetString("Parser.TOKEN.BAR_RIGHT_BEFORE_NULL") | unknown -> let result = sprintf "unknown token tag %+A" unknown Debug.Assert(false, result) diff --git a/src/Compiler/FSStrings.resx b/src/Compiler/FSStrings.resx index 83f488845d7..534a9f4a702 100644 --- a/src/Compiler/FSStrings.resx +++ b/src/Compiler/FSStrings.resx @@ -426,7 +426,7 @@ symbol '|}' - + symbol '|' (directly before 'null') diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs index e40cb7086de..0e24e5c4b15 100644 --- a/src/Compiler/Service/ServiceLexing.fs +++ b/src/Compiler/Service/ServiceLexing.fs @@ -394,7 +394,7 @@ module internal TokenClassifications = | MAYBENULL__ | NOTNULL__ | WITHNULL__ - | BAR_NULL + | BAR_RIGHT_BEFORE_NULL | TYPE_COMING_SOON | TYPE_IS_HERE | MODULE_COMING_SOON diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index 8f2e23acf9e..18a20ddb602 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -2437,7 +2437,7 @@ type LexFilterImpl ( hwTokenFetch useBlockRule | BAR, _ when (lexbuf.SupportsFeature(LanguageFeature.NullnessChecking) && match peekNextToken() with NULL -> true | _ -> false) -> - returnToken tokenLexbufState BAR_NULL + returnToken tokenLexbufState BAR_RIGHT_BEFORE_NULL // Ordinary tokens start a vanilla block | _, CtxtSeqBlock _ :: _ -> diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index f8d3469e21b..388ca490cfe 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -86,10 +86,10 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token SEMICOLON_SEMICOLON LARROW EQUALS LBRACK LBRACK_BAR LBRACE_BAR LBRACK_LESS %token BAR_RBRACK BAR_RBRACE UNDERSCORE %token BAR RBRACK RBRACE_COMING_SOON RBRACE_IS_HERE MINUS DOLLAR -%token GREATER_RBRACK STRUCT SIG +%token GREATER_RBRACK STRUCT SIG %token STATIC MEMBER CLASS ABSTRACT OVERRIDE DEFAULT CONSTRUCTOR INHERIT %token EXTERN VOID PUBLIC PRIVATE INTERNAL GLOBAL -%token MAYBENULL__ NOTNULL__ WITHNULL__ BAR_NULL +%token MAYBENULL__ NOTNULL__ WITHNULL__ BAR_RIGHT_BEFORE_NULL /* for parser 'escape hatch' out of expression context without consuming the 'recover' token */ %token TYPE_COMING_SOON TYPE_IS_HERE MODULE_COMING_SOON MODULE_IS_HERE @@ -247,11 +247,17 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %right WHEN +/* prec_pat_pat_action = "pattern when expr -> expr" + * Lower than match extensions - i.e. BAR. + */ +%nonassoc prec_pat_pat_action /* lower than BAR */ + /* "a then b" as an object constructor is very low precedence */ /* Lower than "if a then b" */ %left prec_then_before %nonassoc prec_then_if - +%nonassoc BAR_RIGHT_BEFORE_NULL +%left BAR %right SEMICOLON prec_semiexpr_sep OBLOCKSEP %right prec_defn_sep @@ -285,12 +291,6 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %nonassoc prec_tuptyptail_prefix /* ditto */ %nonassoc prec_toptuptyptail_prefix /* ditto */ -%nonassoc BAR_NULL -%left BAR -/* prec_pat_pat_action = "pattern when expr -> expr" - * Lower than match extensions - i.e. BAR. - */ -%nonassoc prec_pat_pat_action /* lower than BAR */ %right RARROW %nonassoc IDENT LBRACK @@ -348,7 +348,6 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %left AND_BANG %left AMP AMP_AMP %nonassoc pat_conj -%nonassoc path_disj %nonassoc expr_not %left COLON_GREATER COLON_QMARK_GREATER %left INFIX_COMPARE_OP DOLLAR LESS GREATER EQUALS INFIX_BAR_OP INFIX_AMP_OP @@ -1643,7 +1642,7 @@ tyconDefn: let trivia: SynTypeDefnTrivia = { LeadingKeyword = leadingKeyword; EqualsRange = Some mEquals; WithKeyword = mWith } SynTypeDefn($1, tcDefRepr, members, memberCtorPattern, mWhole, trivia) } - | typeNameInfo opt_attributes opt_access opt_HIGH_PRECEDENCE_APP opt_simplePatterns optAsSpec recover + | typeNameInfo opt_attributes opt_access opt_HIGH_PRECEDENCE_APP opt_simplePatterns optAsSpec recover { let vis, spats, az = $3, $5, $6 let (SynComponentInfo(longId = lid)) = $1 // Gets the XML doc comments prior to the implicit constructor @@ -2379,6 +2378,12 @@ tyconDefnOrSpfnSimpleRepr: | opt_attributes opt_access path LQUOTE STRING recover { errorR(Error(FSComp.SR.parsUnexpectedQuotationOperatorInTypeAliasDidYouMeanVerbatimString(), rhs parseState 4)) SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.ErrorRecovery, SynType.LongIdent($3), unionRanges (rhs parseState 1) $3.Range) } + + /* A type abbreviation */ + | opt_attributes opt_access typ + { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) + if Option.isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(), rhs parseState 2)) + SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } /* A union type definition */ | opt_attributes opt_access unionTypeRepr @@ -2397,12 +2402,6 @@ tyconDefnOrSpfnSimpleRepr: SynTypeDefnSimpleRepr.Union($2, $3 |> List.choose (function Choice2Of2 data -> Some(data) | Choice1Of2 _ -> failwith "huh?"), mWhole) } - - /* A type abbreviation */ - | opt_attributes opt_access typ - { if not (isNil $1) then errorR(Error(FSComp.SR.parsAttributesIllegalHere(), rhs parseState 1)) - if Option.isSome $2 then errorR(Error(FSComp.SR.parsTypeAbbreviationsCannotHaveVisibilityDeclarations(), rhs parseState 2)) - SynTypeDefnSimpleRepr.TypeAbbrev(ParserDetail.Ok, $3, unionRanges (rhs parseState 1) $3.Range) } /* A record type definition */ | opt_attributes opt_access braceFieldDeclList @@ -3074,7 +3073,7 @@ cType: | cType WITHNULL__ { SynType.WithNull($1, false, lhs parseState) } - | cType BAR_NULL NULL + | cType BAR_RIGHT_BEFORE_NULL NULL { SynType.WithNull($1, false, lhs parseState) } | cType AMP @@ -3403,7 +3402,7 @@ simplePatterns: barCanBeRightBeforeNull: | BAR { } - | BAR_NULL + | BAR_RIGHT_BEFORE_NULL { } @@ -3411,7 +3410,7 @@ headBindingPattern: | headBindingPattern AS constrPattern { SynPat.As($1, $3, rhs2 parseState 1 3) } - | headBindingPattern barCanBeRightBeforeNull headBindingPattern %prec path_disj + | headBindingPattern barCanBeRightBeforeNull headBindingPattern { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } @@ -3689,7 +3688,7 @@ parenPattern: | parenPattern AS constrPattern { SynPat.As($1, $3, rhs2 parseState 1 3) } - | parenPattern barCanBeRightBeforeNull parenPattern %prec path_disj + | parenPattern barCanBeRightBeforeNull parenPattern { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } @@ -4554,7 +4553,7 @@ withPatternClauses: | patternClauses { $1 None } - | barCanBeRightBeforeNull patternClauses %prec path_disj + | barCanBeRightBeforeNull patternClauses { let mBar = rhs parseState 1 |> Some $2 mBar } @@ -5869,7 +5868,7 @@ appTypeConPower: { $1 } appTypeCanBeNullable: - | appTypeWithoutNull BAR_NULL NULL + | appTypeWithoutNull BAR_RIGHT_BEFORE_NULL NULL { SynType.WithNull($1, false, lhs parseState) } | appTypeWithoutNull diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf index 60fc64f144b..695c6b44089 100644 --- a/src/Compiler/xlf/FSStrings.cs.xlf +++ b/src/Compiler/xlf/FSStrings.cs.xlf @@ -37,7 +37,7 @@ Případy sjednocení s malými písmeny jsou povolené jenom při použití atributu RequireQualifiedAccess. - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf index 17c5f738b21..c40f9bc84c6 100644 --- a/src/Compiler/xlf/FSStrings.de.xlf +++ b/src/Compiler/xlf/FSStrings.de.xlf @@ -37,7 +37,7 @@ Diskriminierte Union-Fälle in Kleinbuchstaben sind nur zulässig, wenn das RequireQualifiedAccess-Attribut verwendet wird. - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf index bf72eec7182..4c22c3ef779 100644 --- a/src/Compiler/xlf/FSStrings.es.xlf +++ b/src/Compiler/xlf/FSStrings.es.xlf @@ -37,7 +37,7 @@ Los casos de unión discriminada en minúsculas solo se permiten cuando se usa el atributo RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf index 16d1c39aecf..def616635f7 100644 --- a/src/Compiler/xlf/FSStrings.fr.xlf +++ b/src/Compiler/xlf/FSStrings.fr.xlf @@ -37,7 +37,7 @@ Les cas d’union discriminée en minuscules sont uniquement autorisés lors de l’utilisation de l’attribut RequireQualifiedAccess. - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf index d28a6cbfd1d..49f26553080 100644 --- a/src/Compiler/xlf/FSStrings.it.xlf +++ b/src/Compiler/xlf/FSStrings.it.xlf @@ -37,7 +37,7 @@ I casi di unione discriminati minuscoli sono consentiti solo quando si usa l'attributo RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf index dfd45856835..58e9bff2927 100644 --- a/src/Compiler/xlf/FSStrings.ja.xlf +++ b/src/Compiler/xlf/FSStrings.ja.xlf @@ -37,7 +37,7 @@ 小文字で区別される和集合のケースは、RequireQualifiedAccess 属性を使用する場合にのみ許可されます - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf index 5d2d199bc09..386d7548512 100644 --- a/src/Compiler/xlf/FSStrings.ko.xlf +++ b/src/Compiler/xlf/FSStrings.ko.xlf @@ -37,7 +37,7 @@ 소문자로 구분된 공용 구조체 케이스는 RequireQualifiedAccess 특성을 사용하는 경우에만 허용됩니다. - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf index 9257e43f6c3..500f856a1e3 100644 --- a/src/Compiler/xlf/FSStrings.pl.xlf +++ b/src/Compiler/xlf/FSStrings.pl.xlf @@ -37,7 +37,7 @@ Przypadki unii z dyskryminatorem z małymi literami są dozwolone tylko w przypadku używania atrybutu RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf index c6ad13c39eb..83dc2725182 100644 --- a/src/Compiler/xlf/FSStrings.pt-BR.xlf +++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf @@ -37,7 +37,7 @@ Os casos de união discriminados em letras minúsculas só são permitidos ao usar o atributo RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf index 374e4a20d12..f2591c3e7af 100644 --- a/src/Compiler/xlf/FSStrings.ru.xlf +++ b/src/Compiler/xlf/FSStrings.ru.xlf @@ -37,7 +37,7 @@ Размеченные в нижнем регистре случаи объединения разрешены только при использовании атрибута RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf index f16b62dd249..8b7c684427b 100644 --- a/src/Compiler/xlf/FSStrings.tr.xlf +++ b/src/Compiler/xlf/FSStrings.tr.xlf @@ -37,7 +37,7 @@ Küçük harf ayrımlı birleşim durumlarına yalnızca RequireQualifiedAccess özniteliği kullanılırken izin verilir - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf index b67c6e95782..6a1c3a351a8 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf @@ -37,7 +37,7 @@ 仅当使用 RequireQualifiedAccess 属性时才允许区分小写的联合事例 - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf index 7a691848742..676df23682a 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf @@ -37,7 +37,7 @@ 只有在使用 RequireQualifiedAccess 屬性時,才允許小寫區分聯結案例 - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs index 5705b1cf0f4..e608c5198c9 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs +++ b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs @@ -1 +1,2 @@ -match x with | "123" -> "": string | _ -> "456" \ No newline at end of file +match x with +| "123" -> "": string | null -> "456" \ No newline at end of file diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl new file mode 100644 index 00000000000..10d296c9c4b --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl @@ -0,0 +1,28 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionAnnotatedInlinePatternMatch.fs", false, + QualifiedNameOfFile RegressionAnnotatedInlinePatternMatch, [], [], + [SynModuleOrNamespace + ([RegressionAnnotatedInlinePatternMatch], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,12), Ident x, + [SynMatchClause + (Const (String ("123", Regular, (2,2--2,7)), (2,2--2,7)), + None, + Typed + (Const (String ("", Regular, (2,11--2,13)), (2,11--2,13)), + LongIdent (SynLongIdent ([string], [], [None])), + (2,11--2,21)), (2,2--2,21), Yes, + { ArrowRange = Some (2,8--2,10) + BarRange = Some (2,0--2,1) }); + SynMatchClause + (Null (3,2--3,6), None, + Const (String ("456", Regular, (3,10--3,15)), (3,10--3,15)), + (3,2--3,15), Yes, { ArrowRange = Some (3,7--3,9) + BarRange = Some (3,0--3,1) })], + (1,0--3,15), { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--3,15))], + PreXmlDocEmpty, [], None, (1,0--3,15), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) From f9c90529986ae214439f5b22cc726abbbffb6b20 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 31 Aug 2023 16:22:50 +0200 Subject: [PATCH 23/36] removing spaces --- src/Compiler/SyntaxTree/LexFilter.fs | 4 ++-- tests/service/SyntaxTreeTests.fs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index 18a20ddb602..eff9c90aa88 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -165,7 +165,7 @@ let infixTokenLength token = | COLON_GREATER -> 2 | COLON_COLON -> 2 | COLON_EQUALS -> 2 - | BAR_BAR -> 2 + | BAR_BAR -> 2 | AMP_AMP -> 2 | INFIX_BAR_OP d | INFIX_AMP_OP d @@ -2417,7 +2417,7 @@ type LexFilterImpl ( pool.Return tokenTup hwTokenFetch useBlockRule - | TRY, _ -> + | TRY, _ -> if debug then dprintf "Try, pushing CtxtTry(%a)\n" outputPos tokenStartPos pushCtxt tokenTup (CtxtTry tokenStartPos) // The ideal spec would be to push a begin/end block pair here, but we can only do that diff --git a/tests/service/SyntaxTreeTests.fs b/tests/service/SyntaxTreeTests.fs index 290e3fb4001..b72b20d77d9 100644 --- a/tests/service/SyntaxTreeTests.fs +++ b/tests/service/SyntaxTreeTests.fs @@ -11,7 +11,7 @@ open NUnit.Framework let testCasesDir = Path.Combine(__SOURCE_DIRECTORY__, "data", "SyntaxTree") -let allTestCases = +let allTestCases = Directory.EnumerateFiles(testCasesDir, "*.fs?", SearchOption.AllDirectories) |> Seq.map (fun f -> let fileInfo = FileInfo(f) From 9b662133ba565d8ef3b254a717bef2b49b9e1475 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 1 Sep 2023 10:23:12 +0200 Subject: [PATCH 24/36] baseline adjustments for recovery - it still recovers --- tests/service/data/SyntaxTree/Type/And 03.fs.bsl | 8 ++++---- tests/service/data/SyntaxTree/Type/And 06.fs.bsl | 8 ++++---- tests/service/data/SyntaxTree/Type/Primary ctor 02.fs.bsl | 6 +++--- tests/service/data/SyntaxTree/Type/Primary ctor 04.fs.bsl | 8 ++++---- tests/service/data/SyntaxTree/Type/Type 03.fs.bsl | 8 ++++---- tests/service/data/SyntaxTree/Type/Type 04.fs.bsl | 8 ++++---- tests/service/data/SyntaxTree/Type/Type 05.fs.bsl | 8 ++++---- tests/service/data/SyntaxTree/Type/Type 06.fs.bsl | 8 ++++---- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/tests/service/data/SyntaxTree/Type/And 03.fs.bsl b/tests/service/data/SyntaxTree/Type/And 03.fs.bsl index bf2b92aa99d..0334d8da564 100644 --- a/tests/service/data/SyntaxTree/Type/And 03.fs.bsl +++ b/tests/service/data/SyntaxTree/Type/And 03.fs.bsl @@ -21,10 +21,10 @@ ImplFile ([], None, [], [B], PreXmlDoc ((5,4), FSharp.Compiler.Xml.XmlDocCollector), false, None, (5,4--5,5)), - ObjectModel (Unspecified, [], (7,0--7,0)), [], None, - (5,4--7,0), { LeadingKeyword = And (5,0--5,3) - EqualsRange = Some (5,6--5,7) - WithKeyword = None }); + Simple (None (5,4--5,7), (5,4--5,7)), [], None, (5,4--5,7), + { LeadingKeyword = And (5,0--5,3) + EqualsRange = Some (5,6--5,7) + WithKeyword = None }); SynTypeDefn (SynComponentInfo ([], None, [], [C], diff --git a/tests/service/data/SyntaxTree/Type/And 06.fs.bsl b/tests/service/data/SyntaxTree/Type/And 06.fs.bsl index 6e0ad8564e5..45c17c9c934 100644 --- a/tests/service/data/SyntaxTree/Type/And 06.fs.bsl +++ b/tests/service/data/SyntaxTree/Type/And 06.fs.bsl @@ -21,10 +21,10 @@ ImplFile ([], None, [], [B], PreXmlDoc ((5,4), FSharp.Compiler.Xml.XmlDocCollector), false, None, (5,4--5,5)), - ObjectModel (Unspecified, [], (5,6--5,6)), [], None, - (5,4--5,7), { LeadingKeyword = And (5,0--5,3) - EqualsRange = Some (5,6--5,7) - WithKeyword = None })], (3,0--5,7))], + Simple (None (5,4--5,7), (5,4--5,7)), [], None, (5,4--5,7), + { LeadingKeyword = And (5,0--5,3) + EqualsRange = Some (5,6--5,7) + WithKeyword = None })], (3,0--5,7))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--5,7), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] diff --git a/tests/service/data/SyntaxTree/Type/Primary ctor 02.fs.bsl b/tests/service/data/SyntaxTree/Type/Primary ctor 02.fs.bsl index 821925690b1..a770ed3442e 100644 --- a/tests/service/data/SyntaxTree/Type/Primary ctor 02.fs.bsl +++ b/tests/service/data/SyntaxTree/Type/Primary ctor 02.fs.bsl @@ -14,15 +14,15 @@ ImplFile [ImplicitCtor (None, [], SimplePats ([], [], (3,6--3,8)), None, PreXmlDoc ((3,6), FSharp.Compiler.Xml.XmlDocCollector), - (3,5--3,6), { AsKeyword = None })], (5,0--5,0)), [], + (3,5--3,6), { AsKeyword = None })], (3,5--3,10)), [], Some (ImplicitCtor (None, [], SimplePats ([], [], (3,6--3,8)), None, PreXmlDoc ((3,6), FSharp.Compiler.Xml.XmlDocCollector), - (3,5--3,6), { AsKeyword = None })), (3,5--5,0), + (3,5--3,6), { AsKeyword = None })), (3,5--3,10), { LeadingKeyword = Type (3,0--3,4) EqualsRange = Some (3,9--3,10) - WithKeyword = None })], (3,0--5,0)); + WithKeyword = None })], (3,0--3,10)); Expr (Const (Unit, (5,0--5,2)), (5,0--5,2))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--5,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), diff --git a/tests/service/data/SyntaxTree/Type/Primary ctor 04.fs.bsl b/tests/service/data/SyntaxTree/Type/Primary ctor 04.fs.bsl index 8affb14690e..4fbcdb810b7 100644 --- a/tests/service/data/SyntaxTree/Type/Primary ctor 04.fs.bsl +++ b/tests/service/data/SyntaxTree/Type/Primary ctor 04.fs.bsl @@ -14,17 +14,17 @@ ImplFile [ImplicitCtor (None, [], SimplePats ([], [], (3,6--3,8)), None, PreXmlDoc ((3,6), FSharp.Compiler.Xml.XmlDocCollector), - (3,5--3,6), { AsKeyword = None })], (3,9--3,9)), [], + (3,5--3,6), { AsKeyword = None })], (3,5--3,10)), [], Some (ImplicitCtor (None, [], SimplePats ([], [], (3,6--3,8)), None, PreXmlDoc ((3,6), FSharp.Compiler.Xml.XmlDocCollector), - (3,5--3,6), { AsKeyword = None })), (3,5--3,9), + (3,5--3,6), { AsKeyword = None })), (3,5--3,10), { LeadingKeyword = Type (3,0--3,4) EqualsRange = Some (3,9--3,10) - WithKeyword = None })], (3,0--3,9))], + WithKeyword = None })], (3,0--3,10))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, - (1,0--3,9), { LeadingKeyword = Module (1,0--1,6) })], (true, true), + (1,0--3,10), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Type/Type 03.fs.bsl b/tests/service/data/SyntaxTree/Type/Type 03.fs.bsl index 47258d8b728..9cb15932e4c 100644 --- a/tests/service/data/SyntaxTree/Type/Type 03.fs.bsl +++ b/tests/service/data/SyntaxTree/Type/Type 03.fs.bsl @@ -9,10 +9,10 @@ ImplFile ([], None, [], [T], PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), false, None, (3,5--3,6)), - ObjectModel (Unspecified, [], (5,0--5,0)), [], None, - (3,5--5,0), { LeadingKeyword = Type (3,0--3,4) - EqualsRange = Some (3,7--3,8) - WithKeyword = None })], (3,0--5,0)); + Simple (None (3,5--3,8), (3,5--3,8)), [], None, (3,5--3,8), + { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,7--3,8) + WithKeyword = None })], (3,0--3,8)); Expr (Const (Unit, (5,0--5,2)), (5,0--5,2))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--5,2), { LeadingKeyword = Module (1,0--1,6) })], (true, true), diff --git a/tests/service/data/SyntaxTree/Type/Type 04.fs.bsl b/tests/service/data/SyntaxTree/Type/Type 04.fs.bsl index 65fc3926189..83a744a8417 100644 --- a/tests/service/data/SyntaxTree/Type/Type 04.fs.bsl +++ b/tests/service/data/SyntaxTree/Type/Type 04.fs.bsl @@ -9,10 +9,10 @@ ImplFile ([], None, [], [T1], PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), false, None, (3,5--3,7)), - ObjectModel (Unspecified, [], (5,0--5,0)), [], None, - (3,5--5,0), { LeadingKeyword = Type (3,0--3,4) - EqualsRange = Some (3,8--3,9) - WithKeyword = None })], (3,0--5,0)); + Simple (None (3,5--3,9), (3,5--3,9)), [], None, (3,5--3,9), + { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,8--3,9) + WithKeyword = None })], (3,0--3,9)); Types ([SynTypeDefn (SynComponentInfo diff --git a/tests/service/data/SyntaxTree/Type/Type 05.fs.bsl b/tests/service/data/SyntaxTree/Type/Type 05.fs.bsl index d5de1801c1c..ab92f140113 100644 --- a/tests/service/data/SyntaxTree/Type/Type 05.fs.bsl +++ b/tests/service/data/SyntaxTree/Type/Type 05.fs.bsl @@ -9,10 +9,10 @@ ImplFile ([], None, [], [T1], PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), false, None, (3,5--3,7)), - ObjectModel (Unspecified, [], (5,0--5,0)), [], None, - (3,5--5,0), { LeadingKeyword = Type (3,0--3,4) - EqualsRange = Some (3,8--3,9) - WithKeyword = None }); + Simple (None (3,5--3,9), (3,5--3,9)), [], None, (3,5--3,9), + { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,8--3,9) + WithKeyword = None }); SynTypeDefn (SynComponentInfo ([], None, [], [T2], diff --git a/tests/service/data/SyntaxTree/Type/Type 06.fs.bsl b/tests/service/data/SyntaxTree/Type/Type 06.fs.bsl index c113ea3c208..48e453af537 100644 --- a/tests/service/data/SyntaxTree/Type/Type 06.fs.bsl +++ b/tests/service/data/SyntaxTree/Type/Type 06.fs.bsl @@ -9,10 +9,10 @@ ImplFile ([], None, [], [], PreXmlDoc ((3,0), FSharp.Compiler.Xml.XmlDocCollector), false, None, (3,5--3,6)), - ObjectModel (Unspecified, [], (3,5--3,5)), [], None, - (3,5--3,6), { LeadingKeyword = Type (3,0--3,4) - EqualsRange = Some (3,5--3,6) - WithKeyword = None })], (3,0--3,6))], + Simple (None (3,5--3,6), (3,5--3,6)), [], None, (3,5--3,6), + { LeadingKeyword = Type (3,0--3,4) + EqualsRange = Some (3,5--3,6) + WithKeyword = None })], (3,0--3,6))], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), [], None, (1,0--3,6), { LeadingKeyword = Module (1,0--1,6) })], (true, true), { ConditionalDirectives = [] From beb8fbcda0d46c18174724565115435520bf242b Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 1 Sep 2023 14:36:10 +0200 Subject: [PATCH 25/36] Cases for using type annotation for an expression after a match clause --- src/Compiler/FSharp.Compiler.Service.fsproj | 3 +- src/Compiler/SyntaxTree/LexFilter.fs | 3 +- .../FunctionArgAsPatternWithNullCase.fs.bsl | 46 +++++++++++++++++++ ...gressionAnnotatedInlinePatternMatch.fs.bsl | 25 +++++----- 4 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl diff --git a/src/Compiler/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj index 83b5bdb2e15..8efd9eb3460 100644 --- a/src/Compiler/FSharp.Compiler.Service.fsproj +++ b/src/Compiler/FSharp.Compiler.Service.fsproj @@ -162,7 +162,7 @@ AbstractIL\illex.fsl - --module FSharp.Compiler.AbstractIL.AsciiParser --open FSharp.Compiler.AbstractIL.AsciiConstants --open FSharp.Compiler.AbstractIL.IL --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing --buffer-type-argument char -v + --module FSharp.Compiler.AbstractIL.AsciiParser --open FSharp.Compiler.AbstractIL.AsciiConstants --open FSharp.Compiler.AbstractIL.IL --internal --lexlib Internal.Utilities.Text.Lexing --parslib Internal.Utilities.Text.Parsing --buffer-type-argument char AbstractIL\ilpars.fsy @@ -235,7 +235,6 @@ SyntaxTree\FsYacc\pars.fsy - PreserveNewest diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index eff9c90aa88..7964f098a4c 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -1123,8 +1123,9 @@ type LexFilterImpl ( // fx // fx // fx + // fx | DEFAULT | COLON | COLON_GREATER | STRUCT | NULL | DELEGATE | AND | WHEN - | NOTNULL__ | MAYBENULL__ | WITHNULL__ + | NOTNULL__ | MAYBENULL__ | WITHNULL__ | BAR_RIGHT_BEFORE_NULL | DOT_DOT | NEW | LBRACE_BAR diff --git a/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl new file mode 100644 index 00000000000..c48b055814e --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl @@ -0,0 +1,46 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/FunctionArgAsPatternWithNullCase.fs", false, + QualifiedNameOfFile FunctionArgAsPatternWithNullCase, [], [], + [SynModuleOrNamespace + ([FunctionArgAsPatternWithNullCase], false, AnonModule, + [Let + (false, + [SynBinding + (None, Normal, false, false, [], + PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), + SynValData + (None, + SynValInfo + ([[SynArgInfo ([], false, None)]], + SynArgInfo ([], false, None)), None), + LongIdent + (SynLongIdent ([myFunc], [], [None]), None, None, + Pats + [Paren + (Or + (Const + (String ("abc", Regular, (1,12--1,17)), + (1,12--1,17)), + Or + (Typed + (Const + (String ("", Regular, (1,20--1,22)), + (1,20--1,22)), + WithNull + (LongIdent + (SynLongIdent ([string], [], [None])), + false, (1,25--1,38)), (1,20--1,38)), + Const + (String ("123", Regular, (1,41--1,46)), + (1,41--1,46)), (1,20--1,46), + { BarRange = (1,39--1,40) }), (1,12--1,46), + { BarRange = (1,18--1,19) }), (1,11--1,47))], None, + (1,4--1,47)), None, Const (Int32 15, (1,50--1,52)), + (1,4--1,47), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) + InlineKeyword = None + EqualsRange = Some (1,48--1,49) })], + (1,0--1,52))], PreXmlDocEmpty, [], None, (1,0--2,0), + { LeadingKeyword = None })], (true, true), + { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl index 10d296c9c4b..54e114c95ab 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/RegressionAnnotatedInlinePatternMatch.fs.bsl @@ -12,17 +12,18 @@ ImplFile None, Typed (Const (String ("", Regular, (2,11--2,13)), (2,11--2,13)), - LongIdent (SynLongIdent ([string], [], [None])), - (2,11--2,21)), (2,2--2,21), Yes, - { ArrowRange = Some (2,8--2,10) - BarRange = Some (2,0--2,1) }); - SynMatchClause - (Null (3,2--3,6), None, - Const (String ("456", Regular, (3,10--3,15)), (3,10--3,15)), - (3,2--3,15), Yes, { ArrowRange = Some (3,7--3,9) - BarRange = Some (3,0--3,1) })], - (1,0--3,15), { MatchKeyword = (1,0--1,5) - WithKeyword = (1,8--1,12) }), (1,0--3,15))], - PreXmlDocEmpty, [], None, (1,0--3,15), { LeadingKeyword = None })], + Fun + (WithNull + (LongIdent (SynLongIdent ([string], [], [None])), + false, (2,15--2,28)), + StaticConstant + (String ("456", Regular, (2,32--2,37)), + (2,32--2,37)), (2,15--2,37), + { ArrowRange = (2,29--2,31) }), (2,11--2,37)), + (2,2--2,37), Yes, { ArrowRange = Some (2,8--2,10) + BarRange = Some (2,0--2,1) })], + (1,0--2,37), { MatchKeyword = (1,0--1,5) + WithKeyword = (1,8--1,12) }), (1,0--2,37))], + PreXmlDocEmpty, [], None, (1,0--2,37), { LeadingKeyword = None })], (true, true), { ConditionalDirectives = [] CodeComments = [] }, set [])) From f6395905872974e56c21cfc4df5ac11877a9d9ce Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 1 Sep 2023 16:10:25 +0200 Subject: [PATCH 26/36] BAR precedence --- src/Compiler/pars.fsy | 2 +- tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 388ca490cfe..0ccfdc7fb28 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -2623,7 +2623,7 @@ unionTypeRepr: { [$1] } barAndgrabXmlDoc: - | BAR %prec prec_multiple_union_cases + | BAR { let mBar = rhs parseState 1 grabXmlDoc(parseState, [], 1), mBar } diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs new file mode 100644 index 00000000000..3fc966540f7 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs @@ -0,0 +1,4 @@ +match exn with +| InternalError (s, _) +| Failure s as exn -> () +| _ -> () \ No newline at end of file From 55174f7b1a11a80a30a0876953e29a21b25cbbde Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 4 Sep 2023 14:29:43 +0200 Subject: [PATCH 27/36] try fix "as vs. or" regression in pattern matching --- src/Compiler/pars.fsy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 0ccfdc7fb28..d04ffe7dade 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -5672,7 +5672,7 @@ topTupleTypeElements: reportParseErrorAt mStar (FSComp.SR.parsExpectingType ()) (SynTupleTypeSegment.Type ty, None) :: (SynTupleTypeSegment.Star mStar, None) :: $2 } - | topAppType + | topAppType %prec prec_toptuptyptail_prefix { let t, argInfo = $1 [ SynTupleTypeSegment.Type t, Some argInfo ] } @@ -5811,7 +5811,7 @@ tupleType: let path = [SynTupleTypeSegment.Type $1; SynTupleTypeSegment.Slash mSlash; SynTupleTypeSegment.Type ty] mkSynTypeTuple path } - | appTypeCanBeNullable + | appTypeCanBeNullable %prec prec_tuptyp_prefix { $1 } tupleOrQuotTypeElements: From f65d0b638d5195ea97790bb6b82eed6de7cd0995 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 4 Sep 2023 15:25:52 +0200 Subject: [PATCH 28/36] AS vs BAR precedence for pattern matching --- src/Compiler/pars.fsy | 8 ++++---- .../data/SyntaxTree/Nullness/RegressionOrPattern.fs | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index d04ffe7dade..d9a6a5841d9 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -3407,10 +3407,10 @@ barCanBeRightBeforeNull: headBindingPattern: - | headBindingPattern AS constrPattern + | headBindingPattern AS constrPattern %prec AS { SynPat.As($1, $3, rhs2 parseState 1 3) } - | headBindingPattern barCanBeRightBeforeNull headBindingPattern + | headBindingPattern barCanBeRightBeforeNull headBindingPattern %prec BAR { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } @@ -3685,10 +3685,10 @@ parenPatternBody: /* duplicating the entire expression grammar, or making a fairly severe breaking change */ /* to the language. */ parenPattern: - | parenPattern AS constrPattern + | parenPattern AS constrPattern %prec AS { SynPat.As($1, $3, rhs2 parseState 1 3) } - | parenPattern barCanBeRightBeforeNull parenPattern + | parenPattern barCanBeRightBeforeNull parenPattern %prec BAR { let mBar = rhs parseState 2 SynPat.Or($1, $3, rhs2 parseState 1 3, { BarRange = mBar }) } diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs index 3fc966540f7..d8374a93f90 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs @@ -1,4 +1,3 @@ match exn with | InternalError (s, _) -| Failure s as exn -> () -| _ -> () \ No newline at end of file +| Failure s as exn -> () \ No newline at end of file From a38ead9dc3d754614e6f34de94a71b0a4a675809 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 4 Sep 2023 19:30:37 +0200 Subject: [PATCH 29/36] merge resolution --- src/Compiler/Checking/CheckExpressions.fs | 2 +- src/Compiler/Checking/SignatureHash.fs | 1 + src/Compiler/xlf/FSComp.txt.cs.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.de.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.es.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.fr.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.it.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.ja.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.ko.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.pl.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.pt-BR.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.ru.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.tr.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.zh-Hans.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSComp.txt.zh-Hant.xlf | 40 +++++++++++++++++++++++ src/Compiler/xlf/FSStrings.cs.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.de.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.es.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.fr.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.it.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.ja.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.ko.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.pl.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.pt-BR.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.ru.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.tr.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.zh-Hans.xlf | 30 +++++++++++++++++ src/Compiler/xlf/FSStrings.zh-Hant.xlf | 30 +++++++++++++++++ 28 files changed, 912 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Checking/CheckExpressions.fs b/src/Compiler/Checking/CheckExpressions.fs index 86a6ef53ba2..94b3d1b016b 100644 --- a/src/Compiler/Checking/CheckExpressions.fs +++ b/src/Compiler/Checking/CheckExpressions.fs @@ -4645,7 +4645,7 @@ and TcIntersectionConstraint (cenv: cenv) env newOk checkConstraints occ tpenv s | _ -> tpenv ) tpenv - tp.AsType, tpenv + tp.AsType KnownAmbivalentToNull, tpenv and TcTypeStaticConstant kindOpt tpenv c m = match c, kindOpt with diff --git a/src/Compiler/Checking/SignatureHash.fs b/src/Compiler/Checking/SignatureHash.fs index 2193f4325b5..edd70c8bbb8 100644 --- a/src/Compiler/Checking/SignatureHash.fs +++ b/src/Compiler/Checking/SignatureHash.fs @@ -164,6 +164,7 @@ module rec HashTypes = | TyparConstraint.IsReferenceType _ -> tpHash @@ 11 | TyparConstraint.SimpleChoice (tys, _) -> tpHash @@ 12 @@ (tys |> hashListOrderIndependent (hashTType g)) | TyparConstraint.RequiresDefaultConstructor _ -> tpHash @@ 13 + | TyparConstraint.NotSupportsNull (_) -> tpHash @@ 14 /// Hash type parameter constraints let private hashConstraints (g: TcGlobals) cxs = diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 2ff15cd7a6b..139f0970f7b 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -157,6 +157,11 @@ Známý typ parametru: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match Argument na indexu {0} neodpovídá @@ -167,6 +172,16 @@ Argument {0} neodpovídá + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,11 @@ Atribut sestavení {0} odkazuje na navržené sestavení {1}, které se nedá načíst nebo neexistuje. Ohlášená výjimka: {2} – {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ nepovinný zprostředkovatel komunikace s možnou hodnotou null + + nullness checking + nullness checking + + open type declaration Otevřít deklaraci typu @@ -717,6 +742,11 @@ Vytiskněte odvozená rozhraní všech kompilovaných souborů do přidružených souborů podpisu. + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Vymazat mezipaměť výsledků správce balíčků @@ -1242,6 +1272,11 @@ Hodnota {0} není funkce a nepodporuje zápis indexu. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Syntaxe expr1[expr2] je při použití jako argument nejednoznačná. Více informací: https://aka.ms/fsharp-index-notation. Pokud plánujete indexování nebo vytváření řezů, musíte použít expr1.[expr2] na pozici argumentu. Pokud voláte funkci s vícenásobnými curryfikovanými argumenty, přidejte mezi ně mezeru, třeba someFunction expr1 [expr2]. @@ -1347,6 +1382,11 @@ Vlastnost nesmí určovat volitelné argumenty, in, out, ParamArray, CallerInfo nebo Quote. + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Neplatný interpolovaný řetězec. {0} diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 08236b18246..e798a7957f0 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -157,6 +157,11 @@ Bekannter Typparameter: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match Das Argument bei Index {0} stimmt nicht überein. @@ -167,6 +172,16 @@ Das Argument "{0}" stimmt nicht überein. + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,11 @@ Das Assemblyattribut "{0}" verweist auf eine Designerassembly "{1}", die entweder nicht geladen werden kann oder nicht vorhanden ist. Gemeldete Ausnahme: {2} – {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ Interop, NULL-Werte zulassend, optional + + nullness checking + nullness checking + + open type declaration Deklaration für offene Typen @@ -717,6 +742,11 @@ Drucken der abgeleiteten Schnittstellen aller Dateien an zugehörige Signaturdateien + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Löschen Sie den Ergebniscache des Paketmanagers @@ -1242,6 +1272,11 @@ Der Wert "{0}" ist keine Funktion und unterstützt keine Indexnotation. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Die Syntax "expr1[expr2]" ist mehrdeutig, wenn sie als Argument verwendet wird. Siehe https://aka.ms/fsharp-index-notation. Wenn Sie indizieren oder aufteilen möchten, müssen Sie "expr1.[expr2]' in Argumentposition verwenden. Wenn Sie eine Funktion mit mehreren geschweiften Argumenten aufrufen, fügen Sie ein Leerzeichen dazwischen hinzu, z. B. "someFunction expr1 [expr2]". @@ -1347,6 +1382,11 @@ Ein Merkmal darf keine Argumente für „optional“, „in“, „out“, „ParamArray“", „CallerInfo“ oder „Quote“ angeben. + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Ungültige interpolierte Zeichenfolge. {0} diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index fd837db386c..e47e7975d2e 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -157,6 +157,11 @@ Parámetro de tipo conocido: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match El argumento del índice {0} no coincide. @@ -167,6 +172,16 @@ El argumento "{0}" no coincide. + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,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}. + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ interoperabilidad opcional que admite valores NULL + + nullness checking + nullness checking + + open type declaration declaración de tipo abierto @@ -717,6 +742,11 @@ Imprimir las interfaces deducidas de todos los archivos de compilación en los archivos de signatura asociados + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Borrar la caché de resultados del administrador de paquetes @@ -1242,6 +1272,11 @@ El valor "{0}" no es una función y no admite la notación de índices. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. La sintaxis "expr1[expr2]" es ambigua cuando se usa como argumento. Vea https://aka.ms/fsharp-index-notation. Si piensa indexar o segmentar, debe usar "expr1.[expr2]" en la posición del argumento. Si se llama a una función con varios argumentos currificados, se agregará un espacio entre ellos, por ejemplo, "unaFunción expr1 [expr2]". @@ -1347,6 +1382,11 @@ Un rasgo no puede especificar argumentos opcionales, in, out, ParamArray, CallerInfo o Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Cadena interpolada no válida. {0} diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 1587b7f10e0..3e1256ec4f0 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -157,6 +157,11 @@ Paramètre de type connu : {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match L'argument à l'index {0} ne correspond pas @@ -167,6 +172,16 @@ L'argument '{0}' ne correspond pas + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,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} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ interopérabilité facultative pouvant accepter une valeur null + + nullness checking + nullness checking + + open type declaration déclaration de type ouverte @@ -717,6 +742,11 @@ Imprimer les interfaces inférées de tous les fichiers de compilation sur les fichiers de signature associés + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Effacer le cache des résultats du Gestionnaire de package @@ -1242,6 +1272,11 @@ La valeur « {0} » n’est pas une fonction et ne prend pas en charge la notation d’index. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. La syntaxe « expr1[expr2] » est ambiguë lorsqu’elle est utilisée comme argument. Voir https://aka.ms/fsharp-index-notation. Si vous avez l’intention d’indexer ou de découper, vous devez utiliser « expr1.[expr2] » en position d’argument. Si vous appelez une fonction avec plusieurs arguments codés, ajoutez un espace entre eux, par exemple « someFunction expr1 [expr2] ». @@ -1347,6 +1382,11 @@ Une caractéristique ne peut pas spécifier d’arguments facultatifs, in, out, ParamArray, CallerInfo ou Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Chaîne interpolée non valide. {0} diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index bb92fad9b00..d226edc02be 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -157,6 +157,11 @@ Parametro di tipo noto: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match L'argomento alla posizione di indice {0} non corrisponde @@ -167,6 +172,16 @@ L'argomento '{0}' non corrisponde + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,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} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ Interop facoltativo nullable + + nullness checking + nullness checking + + open type declaration dichiarazione di tipo aperto @@ -717,6 +742,11 @@ Stampare le interfacce derivate di tutti i file di compilazione nei file di firma associati + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Cancellare la cache dei risultati di Gestione pacchetti @@ -1242,6 +1272,11 @@ Questo valore '{0}' non è una funzione e non supporta la notazione degli indici. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. La sintassi 'expr1[expr2]' è ambigua se usata come argomento. Vedere https://aka.ms/fsharp-index-notation. Se si intende eseguire l'indicizzazione o il sezionamento, è necessario usare 'expr1.[expr2]' nella posizione dell'argomento. Se si chiama una funzione con più argomenti sottoposti a corsi, aggiungere uno spazio tra di essi, ad esempio 'someFunction expr1 [expr2]'. @@ -1347,6 +1382,11 @@ Un tratto non può specificare argomenti optional, in, out, ParamArray, CallerInfo o Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} La stringa interpolata non è valida. {0} diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index c59b5a2abf4..59095804d1b 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -157,6 +157,11 @@ 既知の型パラメーター: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match インデックス {0} の引数が一致しません @@ -167,6 +172,16 @@ 引数 '{0}' が一致しません + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,11 @@ アセンブリ属性 '{0}' は、デザイナー アセンブリ '{1}' を参照していますが、これは読み込むことができないか、存在していません。報告された例外: {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ Null 許容のオプションの相互運用 + + nullness checking + nullness checking + + open type declaration オープン型宣言 @@ -717,6 +742,11 @@ すべてのコンパイル ファイルの推定されたインターフェイスを関連する署名ファイルに印刷します + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache パッケージ マネージャーの結果キャッシュをクリアする @@ -1242,6 +1272,11 @@ 値 '{0}' は関数ではなく、インデックス表記をサポートしていません。 + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 構文 'expr1[expr2]' は引数として使用されている場合、あいまいです。https://aka.ms/fsharp-index-notation を参照してください。インデックス作成またはスライスを行う場合は、'expr1.[expr2]' を引数の位置に使用する必要があります。複数のカリー化された引数を持つ関数を呼び出す場合は、'expr1 [expr2]' のように間にスペースを追加します。 @@ -1347,6 +1382,11 @@ 特性では、オプションの、in 引数、out 引数、ParamArray 引数、CallerInfo 引数、または Quote 引数を指定することはできません + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} 補間された文字列が無効です。{0} diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index 782b1fe4b22..9a9e48e4abf 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -157,6 +157,11 @@ 알려진 형식 매개 변수: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match 인덱스 {0}의 인수가 일치하지 않습니다. @@ -167,6 +172,16 @@ '{0}' 인수가 일치하지 않습니다. + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,11 @@ '{0}' 어셈블리 특성이 로드할 수 없거나 존재하지 않는 디자이너 어셈블리'{1}'을(를) 참조합니다. 보고된 예외: {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ nullable 선택적 interop + + nullness checking + nullness checking + + open type declaration 개방형 형식 선언 @@ -717,6 +742,11 @@ 모든 컴파일 파일의 유추된 인터페이스를 관련 서명 파일로 인쇄합니다. + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache 패키지 관리자 결과 캐시 지우기 @@ -1242,6 +1272,11 @@ '{0}' 값은 함수가 아니며 인덱스 표기법을 지원하지 않습니다. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 'expr1[expr2]' 구문은 인수로 사용될 때 모호합니다. https://aka.ms/fsharp-index-notation을 참조하세요. 인덱싱이나 슬라이싱을 하려면 인수 위치에 'expr1.[expr2]'를 사용해야 합니다. 여러 개의 커리된 인수로 함수를 호출하는 경우 그 사이에 공백을 추가하세요(예: 'someFunction expr1 [expr2]'). @@ -1347,6 +1382,11 @@ 특성은 optional, in, out, ParamArray, CallerInfo, Quote 인수를 지정할 수 없습니다. + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} 잘못된 보간 문자열. {0} diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index 26e1c6498bc..4648566ae26 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -157,6 +157,11 @@ Parametr znanego typu: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match Argument pod indeksem {0} nie jest zgodny @@ -167,6 +172,16 @@ Argument „{0}” nie jest zgodny + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,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} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ opcjonalna międzyoperacyjność dopuszczająca wartość null + + nullness checking + nullness checking + + open type declaration deklaracja typu otwartego @@ -717,6 +742,11 @@ Drukowanie wywnioskowanych interfejsów wszystkich plików kompilacji do skojarzonych plików sygnatur + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Wyczyść pamięć podręczną wyników menedżera pakietów @@ -1242,6 +1272,11 @@ Wartość elementu „{0}” nie jest funkcją i nie obsługuje notacji indeksowej. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Składnia wyrażenia „expr1[expr2]” jest niejednoznaczna, gdy jest używana jako argument. Zobacz https://aka.ms/fsharp-index-notation. Jeśli zamierzasz indeksować lub fragmentować, to w pozycji argumentu musi być użyte wyrażenie „expr1.[expr2]”. Jeśli wywołujesz funkcję z wieloma argumentami typu curried, dodaj spację między nimi, np. „someFunction expr1 [expr2]”. @@ -1347,6 +1382,11 @@ Cecha nie może określać opcjonalnych argumentów in, out, ParamArray, CallerInfo lub Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Nieprawidłowy ciąg interpolowany. {0} diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index afe6de384ca..3d8170a7d0a 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -157,6 +157,11 @@ Parâmetro de tipo conhecido: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match O argumento no índice {0} não corresponde @@ -167,6 +172,16 @@ O argumento '{0}' não corresponde + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,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} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ interoperabilidade opcional anulável + + nullness checking + nullness checking + + open type declaration declaração de tipo aberto @@ -717,6 +742,11 @@ Imprimir as interfaces inferidas de todos os arquivos de compilação para os arquivos de assinatura associados + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Limpar o cache de resultados do gerenciador de pacotes @@ -1242,6 +1272,11 @@ O valor '{0}' não é uma função e não dá suporte à notação de índice. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. A sintaxe '[expr1][expr2]' é ambígua quando usada como um argumento. Consulte https://aka.ms/fsharp-index-notation. Se você pretende indexar ou colocar em fatias, deve usar '(expr1).[expr2]' na posição do argumento. Se chamar uma função com vários argumentos na forma curried, adicione um espaço entre eles, por exemplo, 'someFunction [expr1] [expr2]'. @@ -1347,6 +1382,11 @@ Uma característica não pode especificar os argumentos optional, in, out, ParamArray, CallerInfo ou Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Cadeia de caracteres interpolada inválida. {0} diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index a6b7ccdcfd6..398189fdce2 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -157,6 +157,11 @@ Известный параметр типа: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match Аргумент в индексе {0} не соответствует @@ -167,6 +172,16 @@ Аргумент "{0}" не соответствует + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,11 @@ Атрибут сборки "{0}" ссылается на сборку конструктора "{1}", которая не может быть загружена или не существует. Получено исключение: {2} — {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ необязательное взаимодействие, допускающее значение NULL + + nullness checking + nullness checking + + open type declaration объявление открытого типа @@ -717,6 +742,11 @@ Печать определяемых интерфейсов всех файлов компиляции в связанные файлы подписей + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Очистка кэша результатов диспетчера пакетов @@ -1242,6 +1272,11 @@ Значение {0} не является функцией и не поддерживает нотацию индекса. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Синтаксис "expr1[expr2]" неоднозначен при использовании в качестве аргумента. См. https://aka.ms/fsharp-index-notation. Если вы намереваетесь индексировать или разрезать, необходимо использовать "expr1.[expr2]" в позиции аргумента. При вызове функции с несколькими каррированными аргументами добавьте пробел между ними, например "someFunction expr1 [expr2]". @@ -1347,6 +1382,11 @@ Признак не может указывать необязательные аргументы in, out, ParamArray, CallerInfo или Quote + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Недопустимая интерполированная строка. {0} diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index f2b50c00ba5..d521d94525a 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -157,6 +157,11 @@ Bilinen tür parametresi: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match {0} dizinindeki bağımsız değişken eşleşmiyor @@ -167,6 +172,16 @@ '{0}' bağımsız değişkeni eşleşmiyor + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,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} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ null atanabilir isteğe bağlı birlikte çalışma + + nullness checking + nullness checking + + open type declaration açık tür bildirimi @@ -717,6 +742,11 @@ Tüm derleme dosyalarının çıkarsanan arabirimlerini ilişkili imza dosyalarına yazdır + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache Paket yöneticisi sonuçları önbelleğini temizle @@ -1242,6 +1272,11 @@ “{0}” değeri bir işlev değildir ve dizin gösterimini desteklemez. + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. Söz dizimi “expr1[expr2]” artık dizin oluşturma için ayrılmıştır ve bağımsız değişken olarak kullanıldığında belirsizdir. https://aka.ms/fsharp-index-notation'a bakın. Dizin oluşturmayı veya dilimlemeyi düşünüyorsanız, bağımsız değişken konumunda “expr1.[expr2]” kullanmalısınız. Birden çok curry bağımsız değişkenli bir işlev çağırıyorsanız, aralarına bir boşluk ekleyin, örn. “someFunction expr1 [expr2]”. @@ -1347,6 +1382,11 @@ Bir nitelik optional, in, out, ParamArray, CallerInfo veya Quote bağımsız değişkenlerini belirtemiyor + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} Geçersiz düz metin arasına kod eklenmiş dize. {0} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 1f63fdbae98..7547d7cb7fc 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -157,6 +157,11 @@ 已知类型参数: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match 索引 {0} 处的参数不匹配 @@ -167,6 +172,16 @@ 参数 "{0}" 不匹配 + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,11 @@ 程序集属性“{0}”引用了无法加载或不存在的设计器程序集“{1}”。报告的异常是: {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ 可以为 null 的可选互操作 + + nullness checking + nullness checking + + open type declaration 开放类型声明 @@ -717,6 +742,11 @@ 将所有编译文件的推断接口打印到关联的签名文件 + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache 清除包管理器结果缓存 @@ -1242,6 +1272,11 @@ 值 '{0}' 不是函数,不支持索引表示法。 + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 语法“expr1[expr2]”用作参数时不明确。请参阅 https://aka.ms/fsharp-index-notation。如果要索引或切片,则必须在参数位置使用“expr1.[expr2]”。如果使用多个扩充参数调用函数,请在它们之间添加空格,例如“someFunction expr1 [expr2]”。 @@ -1347,6 +1382,11 @@ 特征不能指定 option、in、out、ParamArray、CallerInfo 或 Quote 参数 + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} 内插字符串无效。{0} diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index 5771d206cfd..1dfe679886d 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -157,6 +157,11 @@ 已知的型別參數: {0} + + The constraints 'null' and 'not null' are inconsistent + The constraints 'null' and 'not null' are inconsistent + + Argument at index {0} doesn't match 位於索引 {0} 的引數不相符 @@ -167,6 +172,16 @@ 引數 '{0}' 不相符 + + The type '{0}' supports 'null' but a non-null type is expected + The type '{0}' supports 'null' but a non-null type is expected + + + + The type '{0}' uses 'null' as a representation value but a non-null type is expected + The type '{0}' uses 'null' as a representation value but a non-null type is expected + + The constraints 'unmanaged' and 'not struct' are inconsistent The constraints 'unmanaged' and 'not struct' are inconsistent @@ -192,6 +207,11 @@ 無法載入組件屬性 '{0}' 參考的設計工具組件 '{1}' 或其不存在。回報的例外狀況: {2} - {3} + + {0} for F# {1} + {0} for F# {1} + + underscore dot shorthand for accessor only function underscore dot shorthand for accessor only function @@ -372,6 +392,11 @@ 可為 Null 的選擇性 Interop + + nullness checking + nullness checking + + open type declaration 開放式類型宣告 @@ -717,6 +742,11 @@ 將所有編譯檔案的推斷介面列印至相關聯的簽章檔案 + + Enable nullness declarations and checks + Enable nullness declarations and checks + + Clear the package manager results cache 清除封裝管理員結果快取 @@ -1242,6 +1272,11 @@ 值 '{0}' 並非函式,不支援索引標記法。 + + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + The 'nullness checking' language feature is not enabled. This use of a nullness checking construct will be ignored. + + The syntax 'expr1[expr2]' is ambiguous when used as an argument. See https://aka.ms/fsharp-index-notation. If you intend indexing or slicing then you must use 'expr1.[expr2]' in argument position. If calling a function with multiple curried arguments, add a space between them, e.g. 'someFunction expr1 [expr2]'. 語法 'expr1[expr2]' 用作引數時不明確。請參閱 https://aka.ms/fsharp-index-notation。如果您要編製索引或切割,則必須在引數位置使用 'expr1.[expr2]'。如果要呼叫具有多個調用引數的函式,請在它們之間新增空格,例如 'someFunction expr1 [expr2]'。 @@ -1347,6 +1382,11 @@ 特徵不能指定選擇性、in、out、ParamArray、CallerInfo 或 Quote 引數 + + The type '{0}' does not support a nullness qualitification. + The type '{0}' does not support a nullness qualitification. + + Invalid interpolated string. {0} 插補字串無效。{0} diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf index d70c0db6974..736609e3faf 100644 --- a/src/Compiler/xlf/FSStrings.cs.xlf +++ b/src/Compiler/xlf/FSStrings.cs.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Neshoda typů Očekává se řazená kolekce členů o délce {0} typu\n {1} \nale odevzdala se řazená kolekce členů o délce {2} typu\n {3}{4}\n @@ -47,11 +67,21 @@ interpolovaný řetězec (část) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. . Viz taky {0}. diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf index 15db72c7df9..0ff555bd774 100644 --- a/src/Compiler/xlf/FSStrings.de.xlf +++ b/src/Compiler/xlf/FSStrings.de.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Typenkonflikt. Es wurde ein Tupel der Länge {0} des Typs\n {1} \nerwartet, aber ein Tupel der Länge {2} des Typs\n {3}{4}\n angegeben. @@ -47,11 +67,21 @@ Interpolierte Zeichenfolge (Teil) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. . Siehe auch "{0}". diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf index 8dcdaafe812..2ff9d08930a 100644 --- a/src/Compiler/xlf/FSStrings.es.xlf +++ b/src/Compiler/xlf/FSStrings.es.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Error de coincidencia de tipos. Se espera una tupla de longitud {0} de tipo\n {1} \nperero se ha proporcionado una tupla de longitud {2} de tipo\n {3}{4}\n @@ -47,11 +67,21 @@ cadena interpolada (parte) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. . Vea también {0}. diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf index 27fbb47d928..938b7a5f065 100644 --- a/src/Compiler/xlf/FSStrings.fr.xlf +++ b/src/Compiler/xlf/FSStrings.fr.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Incompatibilité de type. Tuple de longueur attendu {0} de type\n {1} \nmais tuple de longueur {2} de type\n {3}{4}\n @@ -47,11 +67,21 @@ chaîne interpolée (partie) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. . Voir aussi {0}. diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf index 6161bf1c482..0118a88113d 100644 --- a/src/Compiler/xlf/FSStrings.it.xlf +++ b/src/Compiler/xlf/FSStrings.it.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Tipo non corrispondente. È prevista una tupla di lunghezza {0} di tipo\n {1} \n, ma è stata specificata una tupla di lunghezza {2} di tipo\n {3}{4}\n @@ -47,11 +67,21 @@ stringa interpolata (parte) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. . Vedere anche {0}. diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf index 6ce057cfbbd..563d026e3b0 100644 --- a/src/Compiler/xlf/FSStrings.ja.xlf +++ b/src/Compiler/xlf/FSStrings.ja.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n 型が一致しません。型の長さ {0} のタプルが必要です\n {1} \nただし、型の長さ {2} のタプルが指定された場合\n {3}{4}\n @@ -47,11 +67,21 @@ 補間された文字列 (部分) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. 。{0} も参照してください。 diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf index 7f8313fec56..bf809a506eb 100644 --- a/src/Compiler/xlf/FSStrings.ko.xlf +++ b/src/Compiler/xlf/FSStrings.ko.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n 유형 불일치. 형식이 \n {1}이고 길이가 {0}인 튜플이 필요합니다. \n그러나 형식이 \n {3}이고 길이가 {2}인 튜플이 제공되었습니다.{4}\n @@ -47,11 +67,21 @@ 보간 문자열(부분) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. {0}도 참조하세요. diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf index 190ec56ac95..6d99f48ca9e 100644 --- a/src/Compiler/xlf/FSStrings.pl.xlf +++ b/src/Compiler/xlf/FSStrings.pl.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Niezgodność. Oczekiwano krotki o długości {0} typu\n {1} \nale otrzymano krotkę o długości {2} typu\n {3}{4}\n @@ -47,11 +67,21 @@ ciąg interpolowany (część) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. . Zobacz też {0}. diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf index ef6fd5de5d6..d7b0feda81b 100644 --- a/src/Compiler/xlf/FSStrings.pt-BR.xlf +++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Tipo incompatível. Esperando uma tupla de comprimento {0} do tipo\n {1} \nmas recebeu uma tupla de comprimento {2} do tipo\n {3}{4}\n @@ -47,11 +67,21 @@ cadeia de caracteres interpolada (parte) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. . Consulte também {0}. diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf index abefd0f0ec2..24032b2276f 100644 --- a/src/Compiler/xlf/FSStrings.ru.xlf +++ b/src/Compiler/xlf/FSStrings.ru.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Несоответствие типов. Ожидается кортеж длиной {0} типа\n {1}, \nно предоставлен кортеж длиной {2} типа\n {3}{4}\n @@ -47,11 +67,21 @@ интерполированная строка (часть) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. . См. также {0}. diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf index 9599b4b5e93..f6c88037039 100644 --- a/src/Compiler/xlf/FSStrings.tr.xlf +++ b/src/Compiler/xlf/FSStrings.tr.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n Tür uyuşmazlığı. {0} uzunluğunda türü\n {1} \nolan bir demet bekleniyordu ancak {2} uzunluğunda türü\n {3}{4}\nolan bir demet verildi @@ -47,11 +67,21 @@ düz metin arasına kod eklenmiş dize (parça) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. . Ayrıca bkz. {0}. diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf index de000d66458..88e96a36147 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n 类型不匹配。应为长度为 {0} 的类型的元组\n {1} \n但提供了长度为 {2} 的类型的元组\n {3}{4}\n @@ -47,11 +67,21 @@ 内插字符串(部分) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. 。请参见 {0}。 diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf index 8d6804d0d62..ef1b2217feb 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf @@ -2,6 +2,26 @@ + + Nullness warning: {0}. + Nullness warning: {0}. + + + + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + Nullness warning: The types '{0}' and '{1}' do not have equivalent nullability. + + + + Nullness warning: The type '{0}' does not support 'null'. + Nullness warning: The type '{0}' does not support 'null'. + + + + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + Nullness warning: The types '{0}' and '{1}' do not have compatible nullability. + + Type mismatch. Expecting a tuple of length {0} of type\n {1} \nbut given a tuple of length {2} of type\n {3} {4}\n 類型不符。必須是類型為\n {1} \n 的元組長度 {0},但提供的是類型為\n {3}{4}\n 的元組長度 {2} @@ -47,11 +67,21 @@ 插補字串 (部分) + + keyword '__notnull' + keyword '__notnull' + + keyword 'while!' keyword 'while!' + + keyword '__withnull' + keyword '__withnull' + + . See also {0}. 。請參閱 {0}。 From 79346a76449340e409bc1af59f9a7d18e1ef3378 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Mon, 4 Sep 2023 20:09:56 +0200 Subject: [PATCH 30/36] fix inline flags --- src/FSharp.Core/option.fs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FSharp.Core/option.fs b/src/FSharp.Core/option.fs index e44f2a8e5e9..ca3f678852d 100644 --- a/src/FSharp.Core/option.fs +++ b/src/FSharp.Core/option.fs @@ -344,13 +344,13 @@ module ValueOption = | ValueSome x -> x #else [] - let ofObj (value: 'T __withnull) : 'T voption when 'T: not struct and 'T : __notnull = + let inline ofObj (value: 'T __withnull) : 'T voption when 'T: not struct and 'T : __notnull = match value with | null -> ValueNone | _ -> ValueSome value [] - let toObj (value : 'T voption) : 'T __withnull when 'T: not struct (* and 'T : __notnull *) = + let inline toObj (value : 'T voption) : 'T __withnull when 'T: not struct (* and 'T : __notnull *) = match value with | ValueNone -> null | ValueSome x -> x From b0fa981b75cc014676184d673597a2f1c02ec5a9 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 7 Sep 2023 13:06:38 +0200 Subject: [PATCH 31/36] Fix IntegerOverflow --- src/Compiler/Driver/fsc.fs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Compiler/Driver/fsc.fs b/src/Compiler/Driver/fsc.fs index a6cd7733b98..6a537c62d64 100644 --- a/src/Compiler/Driver/fsc.fs +++ b/src/Compiler/Driver/fsc.fs @@ -908,7 +908,8 @@ let main3 use s = ilResource.GetBytes().AsStream() let sha256 = System.Security.Cryptography.SHA256.Create() sha256.ComputeHash s) - |> List.sumBy hash + |> List.sumBy (hash >> int64) + |> hash try Fsharp.Compiler.SignatureHash.calculateSignatureHashOfFiles typedImplFiles tcGlobals observer From c0830da92436262d2a0e9423d8ce44058f27694e Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 7 Sep 2023 13:23:12 +0200 Subject: [PATCH 32/36] renamed to BAR_JUST_BEFORE_NULL --- src/Compiler/Driver/CompilerDiagnostics.fs | 2 +- src/Compiler/FSStrings.resx | 2 +- src/Compiler/Service/ServiceLexing.fs | 2 +- src/Compiler/SyntaxTree/LexFilter.fs | 4 ++-- src/Compiler/pars.fsy | 10 +++++----- src/Compiler/xlf/FSStrings.cs.xlf | 2 +- src/Compiler/xlf/FSStrings.de.xlf | 2 +- src/Compiler/xlf/FSStrings.es.xlf | 2 +- src/Compiler/xlf/FSStrings.fr.xlf | 2 +- src/Compiler/xlf/FSStrings.it.xlf | 2 +- src/Compiler/xlf/FSStrings.ja.xlf | 2 +- src/Compiler/xlf/FSStrings.ko.xlf | 2 +- src/Compiler/xlf/FSStrings.pl.xlf | 2 +- src/Compiler/xlf/FSStrings.pt-BR.xlf | 2 +- src/Compiler/xlf/FSStrings.ru.xlf | 2 +- src/Compiler/xlf/FSStrings.tr.xlf | 2 +- src/Compiler/xlf/FSStrings.zh-Hans.xlf | 2 +- src/Compiler/xlf/FSStrings.zh-Hant.xlf | 2 +- 18 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 2c117283c4b..4e73860a7a0 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -1287,7 +1287,7 @@ type Exception with | Parser.TOKEN_INTERP_STRING_END -> SR.GetString("Parser.TOKEN.INTERP.STRING.END") | Parser.TOKEN_WITHNULL__ -> SR.GetString("Parser.TOKEN.WITHNULL__") | Parser.TOKEN_NOTNULL__ -> SR.GetString("Parser.TOKEN.NOTNULL__") - | Parser.TOKEN_BAR_RIGHT_BEFORE_NULL -> SR.GetString("Parser.TOKEN.BAR_RIGHT_BEFORE_NULL") + | Parser.TOKEN_BAR_RIGHT_BEFORE_NULL -> SR.GetString("Parser.TOKEN.BAR_JUST_BEFORE_NULL") | unknown -> let result = sprintf "unknown token tag %+A" unknown Debug.Assert(false, result) diff --git a/src/Compiler/FSStrings.resx b/src/Compiler/FSStrings.resx index 9338521fd41..3af0391078c 100644 --- a/src/Compiler/FSStrings.resx +++ b/src/Compiler/FSStrings.resx @@ -426,7 +426,7 @@ symbol '|}' - + symbol '|' (directly before 'null') diff --git a/src/Compiler/Service/ServiceLexing.fs b/src/Compiler/Service/ServiceLexing.fs index df5648d20b8..c8f4797021c 100644 --- a/src/Compiler/Service/ServiceLexing.fs +++ b/src/Compiler/Service/ServiceLexing.fs @@ -395,7 +395,7 @@ module internal TokenClassifications = | MAYBENULL__ | NOTNULL__ | WITHNULL__ - | BAR_RIGHT_BEFORE_NULL + | BAR_JUST_BEFORE_NULL | TYPE_COMING_SOON | TYPE_IS_HERE | MODULE_COMING_SOON diff --git a/src/Compiler/SyntaxTree/LexFilter.fs b/src/Compiler/SyntaxTree/LexFilter.fs index b98e936b2e0..d17c27d7329 100644 --- a/src/Compiler/SyntaxTree/LexFilter.fs +++ b/src/Compiler/SyntaxTree/LexFilter.fs @@ -1127,7 +1127,7 @@ type LexFilterImpl ( // fx // fx | DEFAULT | COLON | COLON_GREATER | STRUCT | NULL | DELEGATE | AND | WHEN | AMP - | NOTNULL__ | MAYBENULL__ | WITHNULL__ | BAR_RIGHT_BEFORE_NULL + | NOTNULL__ | MAYBENULL__ | WITHNULL__ | BAR_JUST_BEFORE_NULL | DOT_DOT | NEW | LBRACE_BAR @@ -2440,7 +2440,7 @@ type LexFilterImpl ( hwTokenFetch useBlockRule | BAR, _ when (lexbuf.SupportsFeature(LanguageFeature.NullnessChecking) && match peekNextToken() with NULL -> true | _ -> false) -> - returnToken tokenLexbufState BAR_RIGHT_BEFORE_NULL + returnToken tokenLexbufState BAR_JUST_BEFORE_NULL // Ordinary tokens start a vanilla block | _, CtxtSeqBlock _ :: _ -> diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 5aca2a01be7..c137d095b7a 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -89,7 +89,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> %token GREATER_RBRACK STRUCT SIG %token STATIC MEMBER CLASS ABSTRACT OVERRIDE DEFAULT CONSTRUCTOR INHERIT %token EXTERN VOID PUBLIC PRIVATE INTERNAL GLOBAL -%token MAYBENULL__ NOTNULL__ WITHNULL__ BAR_RIGHT_BEFORE_NULL +%token MAYBENULL__ NOTNULL__ WITHNULL__ BAR_JUST_BEFORE_NULL /* for parser 'escape hatch' out of expression context without consuming the 'recover' token */ %token TYPE_COMING_SOON TYPE_IS_HERE MODULE_COMING_SOON MODULE_IS_HERE @@ -256,7 +256,7 @@ let parse_error_rich = Some(fun (ctxt: ParseErrorContext<_>) -> /* Lower than "if a then b" */ %left prec_then_before %nonassoc prec_then_if -%nonassoc BAR_RIGHT_BEFORE_NULL +%nonassoc BAR_JUST_BEFORE_NULL %left BAR %right SEMICOLON prec_semiexpr_sep OBLOCKSEP @@ -3098,7 +3098,7 @@ cType: | cType WITHNULL__ { SynType.WithNull($1, false, lhs parseState) } - | cType BAR_RIGHT_BEFORE_NULL NULL + | cType BAR_JUST_BEFORE_NULL NULL { SynType.WithNull($1, false, lhs parseState) } | cType AMP @@ -3430,7 +3430,7 @@ simplePatterns: barCanBeRightBeforeNull: | BAR { } - | BAR_RIGHT_BEFORE_NULL + | BAR_JUST_BEFORE_NULL { } @@ -5947,7 +5947,7 @@ appTypeConPower: { $1 } appTypeCanBeNullable: - | appTypeWithoutNull BAR_RIGHT_BEFORE_NULL NULL + | appTypeWithoutNull BAR_JUST_BEFORE_NULL NULL { SynType.WithNull($1, false, lhs parseState) } | appTypeWithoutNull diff --git a/src/Compiler/xlf/FSStrings.cs.xlf b/src/Compiler/xlf/FSStrings.cs.xlf index 736609e3faf..0ca74e1ad6f 100644 --- a/src/Compiler/xlf/FSStrings.cs.xlf +++ b/src/Compiler/xlf/FSStrings.cs.xlf @@ -37,7 +37,7 @@ Případy sjednocení s malými písmeny jsou povolené jenom při použití atributu RequireQualifiedAccess. - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.de.xlf b/src/Compiler/xlf/FSStrings.de.xlf index 0ff555bd774..5bb910c0b93 100644 --- a/src/Compiler/xlf/FSStrings.de.xlf +++ b/src/Compiler/xlf/FSStrings.de.xlf @@ -37,7 +37,7 @@ Diskriminierte Union-Fälle in Kleinbuchstaben sind nur zulässig, wenn das RequireQualifiedAccess-Attribut verwendet wird. - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.es.xlf b/src/Compiler/xlf/FSStrings.es.xlf index 2ff9d08930a..f930cc3130e 100644 --- a/src/Compiler/xlf/FSStrings.es.xlf +++ b/src/Compiler/xlf/FSStrings.es.xlf @@ -37,7 +37,7 @@ Los casos de unión discriminada en minúsculas solo se permiten cuando se usa el atributo RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.fr.xlf b/src/Compiler/xlf/FSStrings.fr.xlf index 938b7a5f065..ee90304b65d 100644 --- a/src/Compiler/xlf/FSStrings.fr.xlf +++ b/src/Compiler/xlf/FSStrings.fr.xlf @@ -37,7 +37,7 @@ Les cas d’union discriminée en minuscules sont uniquement autorisés lors de l’utilisation de l’attribut RequireQualifiedAccess. - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.it.xlf b/src/Compiler/xlf/FSStrings.it.xlf index 0118a88113d..d533fcf3383 100644 --- a/src/Compiler/xlf/FSStrings.it.xlf +++ b/src/Compiler/xlf/FSStrings.it.xlf @@ -37,7 +37,7 @@ I casi di unione discriminati minuscoli sono consentiti solo quando si usa l'attributo RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.ja.xlf b/src/Compiler/xlf/FSStrings.ja.xlf index 563d026e3b0..3627feb9bf7 100644 --- a/src/Compiler/xlf/FSStrings.ja.xlf +++ b/src/Compiler/xlf/FSStrings.ja.xlf @@ -37,7 +37,7 @@ 小文字で区別される和集合のケースは、RequireQualifiedAccess 属性を使用する場合にのみ許可されます - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.ko.xlf b/src/Compiler/xlf/FSStrings.ko.xlf index bf809a506eb..fdb8589dc36 100644 --- a/src/Compiler/xlf/FSStrings.ko.xlf +++ b/src/Compiler/xlf/FSStrings.ko.xlf @@ -37,7 +37,7 @@ 소문자로 구분된 공용 구조체 케이스는 RequireQualifiedAccess 특성을 사용하는 경우에만 허용됩니다. - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.pl.xlf b/src/Compiler/xlf/FSStrings.pl.xlf index 6d99f48ca9e..612b025b4bc 100644 --- a/src/Compiler/xlf/FSStrings.pl.xlf +++ b/src/Compiler/xlf/FSStrings.pl.xlf @@ -37,7 +37,7 @@ Przypadki unii z dyskryminatorem z małymi literami są dozwolone tylko w przypadku używania atrybutu RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.pt-BR.xlf b/src/Compiler/xlf/FSStrings.pt-BR.xlf index d7b0feda81b..a4f48b46735 100644 --- a/src/Compiler/xlf/FSStrings.pt-BR.xlf +++ b/src/Compiler/xlf/FSStrings.pt-BR.xlf @@ -37,7 +37,7 @@ Os casos de união discriminados em letras minúsculas só são permitidos ao usar o atributo RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.ru.xlf b/src/Compiler/xlf/FSStrings.ru.xlf index 24032b2276f..1c8e749697d 100644 --- a/src/Compiler/xlf/FSStrings.ru.xlf +++ b/src/Compiler/xlf/FSStrings.ru.xlf @@ -37,7 +37,7 @@ Размеченные в нижнем регистре случаи объединения разрешены только при использовании атрибута RequireQualifiedAccess - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.tr.xlf b/src/Compiler/xlf/FSStrings.tr.xlf index f6c88037039..3a7631b488c 100644 --- a/src/Compiler/xlf/FSStrings.tr.xlf +++ b/src/Compiler/xlf/FSStrings.tr.xlf @@ -37,7 +37,7 @@ Küçük harf ayrımlı birleşim durumlarına yalnızca RequireQualifiedAccess özniteliği kullanılırken izin verilir - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.zh-Hans.xlf b/src/Compiler/xlf/FSStrings.zh-Hans.xlf index 88e96a36147..baec1f056fe 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hans.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hans.xlf @@ -37,7 +37,7 @@ 仅当使用 RequireQualifiedAccess 属性时才允许区分小写的联合事例 - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') diff --git a/src/Compiler/xlf/FSStrings.zh-Hant.xlf b/src/Compiler/xlf/FSStrings.zh-Hant.xlf index ef1b2217feb..cd9bd4799a0 100644 --- a/src/Compiler/xlf/FSStrings.zh-Hant.xlf +++ b/src/Compiler/xlf/FSStrings.zh-Hant.xlf @@ -37,7 +37,7 @@ 只有在使用 RequireQualifiedAccess 屬性時,才允許小寫區分聯結案例 - + symbol '|' (directly before 'null') symbol '|' (directly before 'null') From f1aa4aa38cd81ae45894ca4cbc7bb0ae7b0e84df Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 7 Sep 2023 13:34:58 +0200 Subject: [PATCH 33/36] missing rename --- src/Compiler/Driver/CompilerDiagnostics.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Compiler/Driver/CompilerDiagnostics.fs b/src/Compiler/Driver/CompilerDiagnostics.fs index 4e73860a7a0..e24a32ee1a1 100644 --- a/src/Compiler/Driver/CompilerDiagnostics.fs +++ b/src/Compiler/Driver/CompilerDiagnostics.fs @@ -1287,7 +1287,7 @@ type Exception with | Parser.TOKEN_INTERP_STRING_END -> SR.GetString("Parser.TOKEN.INTERP.STRING.END") | Parser.TOKEN_WITHNULL__ -> SR.GetString("Parser.TOKEN.WITHNULL__") | Parser.TOKEN_NOTNULL__ -> SR.GetString("Parser.TOKEN.NOTNULL__") - | Parser.TOKEN_BAR_RIGHT_BEFORE_NULL -> SR.GetString("Parser.TOKEN.BAR_JUST_BEFORE_NULL") + | Parser.TOKEN_BAR_JUST_BEFORE_NULL -> SR.GetString("Parser.TOKEN.BAR_JUST_BEFORE_NULL") | unknown -> let result = sprintf "unknown token tag %+A" unknown Debug.Assert(false, result) From dfe4cc3d5292d1c7b280dedf638709cbd5b6cb09 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Thu, 7 Sep 2023 21:10:11 +0200 Subject: [PATCH 34/36] Few more conflict resolutions --- src/Compiler/Checking/ConstraintSolver.fs | 95 +++++++++++++---------- src/Compiler/pars.fsy | 8 +- 2 files changed, 57 insertions(+), 46 deletions(-) diff --git a/src/Compiler/Checking/ConstraintSolver.fs b/src/Compiler/Checking/ConstraintSolver.fs index 080b36e5e3f..5f4d6918b42 100644 --- a/src/Compiler/Checking/ConstraintSolver.fs +++ b/src/Compiler/Checking/ConstraintSolver.fs @@ -1248,10 +1248,11 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull -> // SolveTyparEqualsType csenv ndeep m2 trace sty1 (TType_var (tp2, g.knownWithoutNull)) | _ -> - SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 ++ (fun () -> - let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1 - SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 nullness2 - ) + trackErrors { + do! SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 + let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 nullness2 + } | TType_var (tp1, nullness1), TType_var (tp2, nullness2) when not csenv.MatchingOnly && PreferUnifyTypar tp2 tp1 -> match nullness1.TryEvaluate(), nullness2.TryEvaluate() with @@ -1264,10 +1265,11 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr | _ -> // Unifying 'T1 ? and 'T2 % // Unifying 'T1 % and 'T2 ? - SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 ++ (fun () -> - let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 - SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2 - ) + trackErrors{ + do! SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 + let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2 + } | TType_var (tp1, nullness1), _ when not (IsRigid csenv tp1) -> match nullness1.TryEvaluate(), (nullnessOfTy g sty2).TryEvaluate() with @@ -1278,10 +1280,11 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull -> // SolveTyparEqualsType csenv ndeep m2 trace sty1 (replaceNullnessOfTy g.knownWithoutNull sty2) | _ -> - SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 ++ (fun () -> - let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1 - SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 (nullnessOfTy g sty2) - ) + trackErrors{ + do! SolveTyparEqualsType csenv ndeep m2 trace sty1 ty2 + let nullnessAfterSolution1 = combineNullness (nullnessOfTy g sty1) nullness1 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 nullnessAfterSolution1 (nullnessOfTy g sty2) + } | _, TType_var (tp2, nullness2) when not csenv.MatchingOnly && not (IsRigid csenv tp2) -> match (nullnessOfTy g sty1).TryEvaluate(), nullness2.TryEvaluate() with @@ -1292,26 +1295,30 @@ and SolveTypeEqualsType (csenv: ConstraintSolverEnv) ndeep m2 (trace: OptionalTr //| ValueSome NullnessInfo.AmbivalentToNull, ValueSome NullnessInfo.AmbivalentToNull -> // SolveTyparEqualsType csenv ndeep m2 trace sty2 (replaceNullnessOfTy g.knownWithoutNull sty1) | _ -> - SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 ++ (fun () -> - let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 - SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2 - ) + trackErrors{ + do! SolveTyparEqualsType csenv ndeep m2 trace sty2 ty1 + let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2 + } // Catch float<_>=float<1>, float32<_>=float32<1> and decimal<_>=decimal<1> | (_, TType_app (tc2, [ms2], _)) when (tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2])) -> - SolveTypeEqualsType csenv ndeep m2 trace None (TType_measure Measure.One) ms2 ++ (fun () -> - SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) - ) + trackErrors{ + do! SolveTypeEqualsType csenv ndeep m2 trace None (TType_measure Measure.One) ms2 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } | (TType_app (tc1, [ms1], _), _) when (tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1])) -> - SolveTypeEqualsType csenv ndeep m2 trace None ms1 (TType_measure Measure.One) ++ (fun () -> - SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) - ) + trackErrors{ + do! SolveTypeEqualsType csenv ndeep m2 trace None ms1 (TType_measure Measure.One) + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } | TType_app (tc1, l1, _), TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 -> - SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 ++ (fun () -> - SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) - ) + trackErrors{ + do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace None l1 l2 + do! SolveNullnessEquiv csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } | TType_app _, TType_app _ -> localAbortD @@ -1407,18 +1414,19 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional | TType_var (r2, nullness2) when typarEq tp1 r2 -> SolveNullnessEquiv csenv m2 trace ty1 ty2 nullness1 nullness2 | TType_var (r2, nullness2) when not csenv.MatchingOnly -> - SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1 ++ (fun () -> - let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 - SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2 - ) + trackErrors{ + do! SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1 + let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 nullness1 nullnessAfterSolution2 + } | _ -> SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ty1 ty2 | _, TType_var (r2, nullness2) when not csenv.MatchingOnly -> - SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1 ++ (fun () -> + trackErrors{ + do! SolveTyparSubtypeOfType csenv ndeep m2 trace r2 ty1 let nullnessAfterSolution2 = combineNullness (nullnessOfTy g sty2) nullness2 - SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2 - ) - + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) nullnessAfterSolution2 + } | TType_tuple (tupInfo1, l1), TType_tuple (tupInfo2, l2) -> if evalTupInfoIsStruct tupInfo1 <> evalTupInfoIsStruct tupInfo2 then ErrorD (ConstraintSolverError(FSComp.SR.tcTupleStructMismatch(), csenv.m, m2)) else SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 (* nb. can unify since no variance *) @@ -1438,14 +1446,16 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional // Enforce the identities float=float<1>, float32=float32<1> and decimal=decimal<1> | _, TType_app (tc2, [ms2], _) when tc2.IsMeasureableReprTycon && typeEquiv csenv.g sty1 (reduceTyconRefMeasureableOrProvided csenv.g tc2 [ms2]) -> - SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms2 (TType_measure Measure.One) ++ (fun () -> - SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) - ) + trackErrors { + do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms2 (TType_measure Measure.One) + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } | TType_app (tc1, [ms1], _), _ when tc1.IsMeasureableReprTycon && typeEquiv csenv.g sty2 (reduceTyconRefMeasureableOrProvided csenv.g tc1 [ms1]) -> - SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms1 (TType_measure Measure.One) ++ (fun () -> - SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) - ) + trackErrors { + do! SolveTypeEqualsTypeKeepAbbrevsWithCxsln csenv ndeep m2 trace cxsln ms1 (TType_measure Measure.One) + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } // Special subsumption rule for byref tags | TType_app (tc1, l1, _) , TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 && g.byref2_tcr.CanDeref && tyconRefEq g g.byref2_tcr tc1 -> @@ -1461,9 +1471,10 @@ and SolveTypeSubsumesType (csenv: ConstraintSolverEnv) ndeep m2 (trace: Optional | _ -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 | TType_app (tc1, l1, _) , TType_app (tc2, l2, _) when tyconRefEq g tc1 tc2 -> - SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 ++ (fun () -> - SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) - ) + trackErrors { + do! SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 + do! SolveNullnessSubsumesNullness csenv m2 trace ty1 ty2 (nullnessOfTy g sty1) (nullnessOfTy g sty2) + } | TType_ucase (uc1, l1), TType_ucase (uc2, l2) when g.unionCaseRefEq uc1 uc2 -> SolveTypeEqualsTypeEqns csenv ndeep m2 trace cxsln l1 l2 diff --git a/src/Compiler/pars.fsy b/src/Compiler/pars.fsy index 3a973cb0e44..0736e85b5f9 100644 --- a/src/Compiler/pars.fsy +++ b/src/Compiler/pars.fsy @@ -5822,16 +5822,16 @@ topAppType: /* Grammar rule meant for recovery scenarios */ /* For example in unionCaseReprElement where function type is not allowed */ invalidUseOfAppTypeFunction: - | appType RARROW invalidUseOfAppTypeFunction + | appTypeWithoutNull RARROW invalidUseOfAppTypeFunction { let mArrow = rhs parseState 2 let m = unionRanges (rhs2 parseState 1 2) $3.Range SynType.Fun($1, $3, m, { ArrowRange = mArrow }) } - | appType RARROW recover + | appTypeWithoutNull RARROW recover { let mArrow = rhs parseState 2 let ty = SynType.FromParseError(mArrow.EndRange) let m = rhs2 parseState 1 2 SynType.Fun($1, ty, m, { ArrowRange = mArrow }) } - | appType RARROW RARROW invalidUseOfAppTypeFunction + | appTypeWithoutNull RARROW RARROW invalidUseOfAppTypeFunction { let mArrow1 = rhs parseState 2 let mArrow2 = rhs parseState 3 reportParseErrorAt mArrow2 (FSComp.SR.parsExpectingType ()) @@ -5839,7 +5839,7 @@ invalidUseOfAppTypeFunction: let m1 = unionRanges $1.Range $4.Range let m2 = unionRanges mArrow2 $4.Range SynType.Fun($1, SynType.Fun(ty, $4, m2, { ArrowRange = mArrow2 }), m1, { ArrowRange = mArrow1 }) } - | appType RARROW appType + | appTypeWithoutNull RARROW appTypeWithoutNull { let mArrow = rhs parseState 2 let m = rhs2 parseState 1 3 SynType.Fun($1, $3, m, { ArrowRange = mArrow }) } From d24043f278c1aa5245d35069ef7bf24c0d6d25a6 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 8 Sep 2023 10:03:30 +0200 Subject: [PATCH 35/36] Syntaxtree tests updated --- .../FunctionArgAsPatternWithNullCase.fs.bsl | 22 +++++----- ...ericFunctionReturnTypeNotStructNull.fs.bsl | 3 +- .../GenericFunctionTyparNotNull.fs.bsl | 2 +- .../Nullness/GenericFunctionTyparNull.fs.bsl | 2 +- .../Nullness/GenericTypeNotNull.fs.bsl | 4 +- ...enericTypeNotNullAndOtherConstraint.fs.bsl | 4 +- ...tAndOtherConstraint-I_am_Still_Sane.fs.bsl | 4 +- .../Nullness/GenericTypeNull.fs.bsl | 4 +- ...icTypeOtherConstraintAndThenNotNull.fs.bsl | 4 +- .../SyntaxTree/Nullness/IntListOrNull.fs.bsl | 4 +- .../Nullness/IntListOrNullOrNullOrNull.fs.bsl | 4 +- .../Nullness/NullAnnotatedExpression.fs.bsl | 4 +- .../Nullness/RegressionChoiceType.fs.bsl | 10 +++-- .../Nullness/RegressionListType.fs.bsl | 6 ++- .../Nullness/RegressionOptionType.fs.bsl | 6 ++- .../Nullness/RegressionOrPattern.fs.bsl | 40 +++++++++++++++++++ .../Nullness/RegressionResultType.fs.bsl | 10 +++-- .../SyntaxTree/Nullness/StringOrNull.fs.bsl | 4 +- .../Nullness/StringOrNullInFunctionArg.fs.bsl | 2 +- 19 files changed, 101 insertions(+), 38 deletions(-) create mode 100644 tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs.bsl diff --git a/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl index c48b055814e..5a519d0f7e5 100644 --- a/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/FunctionArgAsPatternWithNullCase.fs.bsl @@ -13,17 +13,17 @@ ImplFile (None, SynValInfo ([[SynArgInfo ([], false, None)]], - SynArgInfo ([], false, None)), None), + SynArgInfo ([], false, None)), None, None), LongIdent (SynLongIdent ([myFunc], [], [None]), None, None, Pats [Paren (Or - (Const - (String ("abc", Regular, (1,12--1,17)), - (1,12--1,17)), - Or - (Typed + (Or + (Const + (String ("abc", Regular, (1,12--1,17)), + (1,12--1,17)), + Typed (Const (String ("", Regular, (1,20--1,22)), (1,20--1,22)), @@ -31,11 +31,11 @@ ImplFile (LongIdent (SynLongIdent ([string], [], [None])), false, (1,25--1,38)), (1,20--1,38)), - Const - (String ("123", Regular, (1,41--1,46)), - (1,41--1,46)), (1,20--1,46), - { BarRange = (1,39--1,40) }), (1,12--1,46), - { BarRange = (1,18--1,19) }), (1,11--1,47))], None, + (1,12--1,38), { BarRange = (1,18--1,19) }), + Const + (String ("123", Regular, (1,41--1,46)), + (1,41--1,46)), (1,12--1,46), + { BarRange = (1,39--1,40) }), (1,11--1,47))], None, (1,4--1,47)), None, Const (Int32 15, (1,50--1,52)), (1,4--1,47), NoneAtLet, { LeadingKeyword = Let (1,0--1,3) InlineKeyword = None diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl index d155f74abba..a3a42b1fb1f 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionReturnTypeNotStructNull.fs.bsl @@ -10,7 +10,8 @@ ImplFile (None, Normal, false, false, [], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), SynValData - (None, SynValInfo ([[]], SynArgInfo ([], false, None)), None), + (None, SynValInfo ([[]], SynArgInfo ([], false, None)), None, + None), LongIdent (SynLongIdent ([myFunc], [], [None]), None, None, Pats [Paren (Const (Unit, (1,10--1,12)), (1,10--1,12))], diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl index 2989025967c..e648c231c86 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNotNull.fs.bsl @@ -13,7 +13,7 @@ ImplFile (None, SynValInfo ([[SynArgInfo ([], false, Some x)]], - SynArgInfo ([], false, None)), None), + SynArgInfo ([], false, None)), None, None), LongIdent (SynLongIdent ([myFunc], [], [None]), None, None, Pats diff --git a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl index db83d1ddcbf..cf50c657f30 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/GenericFunctionTyparNull.fs.bsl @@ -13,7 +13,7 @@ ImplFile (None, SynValInfo ([[SynArgInfo ([], false, Some x)]], - SynArgInfo ([], false, None)), None), + SynArgInfo ([], false, None)), None, None), LongIdent (SynLongIdent ([myFunc], [], [None]), None, None, Pats diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl index c335c2f9d5b..e874ec38674 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNull.fs.bsl @@ -10,7 +10,9 @@ ImplFile ([], Some (PostfixList - ([SynTyparDecl ([], SynTypar (T, None, false))], + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], [WhereTyparNotSupportsNull (SynTypar (T, None, false), (1,15--1,27))], (1,6--1,28))), [], [C], diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl index 5b1c36bce92..7a53c3be066 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotNullAndOtherConstraint.fs.bsl @@ -10,7 +10,9 @@ ImplFile ([], Some (PostfixList - ([SynTyparDecl ([], SynTypar (T, None, false))], + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], [WhereTyparNotSupportsNull (SynTypar (T, None, false), (1,15--1,27)); WhereTyparIsEquatable diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl index 85b61f0e355..6ebe197154b 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNotStructAndOtherConstraint-I_am_Still_Sane.fs.bsl @@ -13,7 +13,9 @@ ImplFile ([], Some (PostfixList - ([SynTyparDecl ([], SynTypar (T, None, false))], + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], [WhereTyparIsReferenceType (SynTypar (T, None, false), (1,15--1,29)); WhereTyparIsEquatable diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl index 6b130ebb3b4..184b29d69d3 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeNull.fs.bsl @@ -10,7 +10,9 @@ ImplFile ([], Some (PostfixList - ([SynTyparDecl ([], SynTypar (T, None, false))], + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], [WhereTyparSupportsNull (SynTypar (T, None, false), (1,15--1,23))], (1,6--1,24))), [], [C], diff --git a/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl index 0b28a943bb2..14ce1cec8b7 100644 --- a/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/GenericTypeOtherConstraintAndThenNotNull.fs.bsl @@ -10,7 +10,9 @@ ImplFile ([], Some (PostfixList - ([SynTyparDecl ([], SynTypar (T, None, false))], + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], [WhereTyparIsEquatable (SynTypar (T, None, false), (1,15--1,26)); WhereTyparNotSupportsNull diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl index 38442d6c68e..3e18b8f3910 100644 --- a/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNull.fs.bsl @@ -10,8 +10,8 @@ ImplFile (None, Normal, false, false, [], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), SynValData - (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Named (SynIdent (x, None), false, None, (1,4--1,5)), + (None, SynValInfo ([], SynArgInfo ([], false, None)), None, + None), Named (SynIdent (x, None), false, None, (1,4--1,5)), Some (SynBindingReturnInfo (WithNull diff --git a/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl index e538c6dc34b..01b86c58866 100644 --- a/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/IntListOrNullOrNullOrNull.fs.bsl @@ -10,8 +10,8 @@ ImplFile (None, Normal, false, false, [], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), SynValData - (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Named (SynIdent (x, None), false, None, (1,4--1,5)), + (None, SynValInfo ([], SynArgInfo ([], false, None)), None, + None), Named (SynIdent (x, None), false, None, (1,4--1,5)), Some (SynBindingReturnInfo (WithNull diff --git a/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl index 1457fb5155e..c29a384e013 100644 --- a/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/NullAnnotatedExpression.fs.bsl @@ -10,8 +10,8 @@ ImplFile (None, Normal, false, false, [], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), SynValData - (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Named (SynIdent (x, None), false, None, (1,4--1,5)), + (None, SynValInfo ([], SynArgInfo ([], false, None)), None, + None), Named (SynIdent (x, None), false, None, (1,4--1,5)), Some (SynBindingReturnInfo (WithNull diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl index 1e63c3a1b90..3ec9bd46d66 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/RegressionChoiceType.fs.bsl @@ -10,9 +10,13 @@ ImplFile ([], Some (PostfixList - ([SynTyparDecl ([], SynTypar (T1, None, false)); - SynTyparDecl ([], SynTypar (T2, None, false))], [], - (1,13--1,22))), [], [MyChoice], + ([SynTyparDecl + ([], SynTypar (T1, None, false), [], + { AmpersandRanges = [] }); + SynTyparDecl + ([], SynTypar (T2, None, false), [], + { AmpersandRanges = [] })], [], (1,13--1,22))), + [], [MyChoice], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), true, None, (1,5--1,13)), Simple diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl index 6fa86a39437..481bbb378bc 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/RegressionListType.fs.bsl @@ -10,8 +10,10 @@ ImplFile ([], Some (PostfixList - ([SynTyparDecl ([], SynTypar (T, None, false))], [], - (1,9--1,13))), [], [List], + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], [], (1,9--1,13))), [], + [List], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), true, None, (1,5--1,9)), Simple diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl index 3a0e50c61de..5491684ccaa 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOptionType.fs.bsl @@ -10,8 +10,10 @@ ImplFile ([], Some (PostfixList - ([SynTyparDecl ([], SynTypar (T, None, false))], [], - (1,11--1,15))), [], [Option], + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] })], [], (1,11--1,15))), + [], [Option], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), true, None, (1,5--1,11)), Simple diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs.bsl new file mode 100644 index 00000000000..82fe5cb33d5 --- /dev/null +++ b/tests/service/data/SyntaxTree/Nullness/RegressionOrPattern.fs.bsl @@ -0,0 +1,40 @@ +ImplFile + (ParsedImplFileInput + ("/root/Nullness/RegressionOrPattern.fs", false, + QualifiedNameOfFile RegressionOrPattern, [], [], + [SynModuleOrNamespace + ([RegressionOrPattern], false, AnonModule, + [Expr + (Match + (Yes (1,0--1,14), Ident exn, + [SynMatchClause + (As + (Or + (LongIdent + (SynLongIdent ([InternalError], [], [None]), None, + None, + Pats + [Paren + (Tuple + (false, + [Named + (SynIdent (s, None), false, None, + (2,17--2,18)); Wild (2,20--2,21)], + [(2,18--2,19)], (2,17--2,21)), + (2,16--2,22))], None, (2,2--2,22)), + LongIdent + (SynLongIdent ([Failure], [], [None]), None, None, + Pats + [Named + (SynIdent (s, None), false, None, + (3,10--3,11))], None, (3,2--3,11)), + (2,2--3,11), { BarRange = (3,0--3,1) }), + Named (SynIdent (exn, None), false, None, (3,15--3,18)), + (2,2--3,18)), None, Const (Unit, (3,22--3,24)), + (2,2--3,24), Yes, { ArrowRange = Some (3,19--3,21) + BarRange = Some (2,0--2,1) })], + (1,0--3,24), { MatchKeyword = (1,0--1,5) + WithKeyword = (1,10--1,14) }), (1,0--3,24))], + PreXmlDocEmpty, [], None, (1,0--3,24), { LeadingKeyword = None })], + (true, true), { ConditionalDirectives = [] + CodeComments = [] }, set [])) diff --git a/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl index 4f8244b93d4..fea7c9a9a59 100644 --- a/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/RegressionResultType.fs.bsl @@ -10,9 +10,13 @@ ImplFile ([], Some (PostfixList - ([SynTyparDecl ([], SynTypar (T, None, false)); - SynTyparDecl ([], SynTypar (TError, None, false))], - [], (1,17--1,29))), [], [MyResult], + ([SynTyparDecl + ([], SynTypar (T, None, false), [], + { AmpersandRanges = [] }); + SynTyparDecl + ([], SynTypar (TError, None, false), [], + { AmpersandRanges = [] })], [], (1,17--1,29))), + [], [MyResult], PreXmlDoc ((1,4), FSharp.Compiler.Xml.XmlDocCollector), true, None, (1,9--1,17)), Simple diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl index e803aeedb1f..f73e3f6ab3a 100644 --- a/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNull.fs.bsl @@ -10,8 +10,8 @@ ImplFile (None, Normal, false, false, [], PreXmlDoc ((1,0), FSharp.Compiler.Xml.XmlDocCollector), SynValData - (None, SynValInfo ([], SynArgInfo ([], false, None)), None), - Named (SynIdent (x, None), false, None, (1,4--1,5)), + (None, SynValInfo ([], SynArgInfo ([], false, None)), None, + None), Named (SynIdent (x, None), false, None, (1,4--1,5)), Some (SynBindingReturnInfo (WithNull diff --git a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl index f369e771916..c10d17ee85f 100644 --- a/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl +++ b/tests/service/data/SyntaxTree/Nullness/StringOrNullInFunctionArg.fs.bsl @@ -13,7 +13,7 @@ ImplFile (None, SynValInfo ([[SynArgInfo ([], false, Some x)]], - SynArgInfo ([], false, None)), None), + SynArgInfo ([], false, None)), None, None), LongIdent (SynLongIdent ([myFunc], [], [None]), None, None, Pats From 267e7a2cb6964e3765594bf3ee5828e695ac79fe Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Fri, 8 Sep 2023 11:43:28 +0200 Subject: [PATCH 36/36] Fixing tests --- tests/AheadOfTime/Trimming/check.ps1 | 2 +- tests/fsharp/typecheck/sigs/neg04.bsl | 8 +++++++- tests/fsharp/typecheck/sigs/neg119b.bsl | 4 ++-- tests/fsharp/typecheck/sigs/neg29.bsl | 4 ++-- tests/fsharp/typecheck/sigs/neg69.vsbsl | 7 ++++--- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/AheadOfTime/Trimming/check.ps1 b/tests/AheadOfTime/Trimming/check.ps1 index 834c0b0aacc..bf5f29bc306 100644 --- a/tests/AheadOfTime/Trimming/check.ps1 +++ b/tests/AheadOfTime/Trimming/check.ps1 @@ -47,4 +47,4 @@ CheckTrim -root "SelfContained_Trimming_Test" -tfm "net472" -outputfile "FSharp. CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net472" -outputfile "StaticLinkedFSharpCore_Trimming_Test.exe" -expected_len -1 # Check net7.0 trimmed assemblies -CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net7.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 8821248 +CheckTrim -root "StaticLinkedFSharpCore_Trimming_Test" -tfm "net7.0" -outputfile "StaticLinkedFSharpCore_Trimming_Test.dll" -expected_len 8822272 diff --git a/tests/fsharp/typecheck/sigs/neg04.bsl b/tests/fsharp/typecheck/sigs/neg04.bsl index 88ae776c8ca..f444d1f6ca9 100644 --- a/tests/fsharp/typecheck/sigs/neg04.bsl +++ b/tests/fsharp/typecheck/sigs/neg04.bsl @@ -30,10 +30,16 @@ neg04.fs(47,30,47,51): typecheck error FS0001: Type mismatch. Expecting a ''a seq -> 'n' but given a ''o list -> 'p' -The type ''a seq' does not match the type ''n list' +The type ''a list' does not match the type ''b seq' neg04.fs(47,49,47,51): typecheck error FS0784: This numeric literal requires that a module 'NumericLiteralN' defining functions FromZero, FromOne, FromInt32, FromInt64 and FromString be in scope +neg04.fs(47,30,47,51): typecheck error FS0001: Type mismatch. Expecting a + ''a seq -> 'n' +but given a + ''o list -> 'p' +The type ''a list' does not match the type ''c seq' + neg04.fs(61,25,61,40): typecheck error FS0001: This expression was expected to have type 'ClassType1' but here has type diff --git a/tests/fsharp/typecheck/sigs/neg119b.bsl b/tests/fsharp/typecheck/sigs/neg119b.bsl index 259e2585998..414486b9017 100644 --- a/tests/fsharp/typecheck/sigs/neg119b.bsl +++ b/tests/fsharp/typecheck/sigs/neg119b.bsl @@ -6,7 +6,7 @@ Known return type: ((int -> int -> int) -> obj) Known type parameters: < obj , Applicatives.Ap > Available overloads: + - static member Applicatives.Ap.Return: 'a seq * Ap: Applicatives.Ap -> ('a -> 'a seq) // Argument at index 1 doesn't match - static member Applicatives.Ap.Return: ('r -> 'a) * Ap: Applicatives.Ap -> (('a -> 'r -> 'a2) -> 'a3 -> 'a -> 'r -> 'a2) // Argument at index 1 doesn't match - static member Applicatives.Ap.Return: System.Tuple<'a> * Ap: Applicatives.Ap -> ('a -> System.Tuple<'a>) // Argument at index 1 doesn't match - - static member Applicatives.Ap.Return: r: ^R * obj -> ('a1 -> ^R) when ^R: (static member Return: 'a1 -> ^R) // Argument 'r' doesn't match - - static member Applicatives.Ap.Return: seq<'a> * Ap: Applicatives.Ap -> ('a -> seq<'a>) // Argument at index 1 doesn't match Consider adding further type constraints + - static member Applicatives.Ap.Return: r: ^R * obj -> ('a1 -> ^R) when ^R: (static member Return: 'a1 -> ^R) // Argument 'r' doesn't match Consider adding further type constraints diff --git a/tests/fsharp/typecheck/sigs/neg29.bsl b/tests/fsharp/typecheck/sigs/neg29.bsl index dd2d49ffda1..5f75bb8cdb0 100644 --- a/tests/fsharp/typecheck/sigs/neg29.bsl +++ b/tests/fsharp/typecheck/sigs/neg29.bsl @@ -1,8 +1,8 @@ neg29.fs(5,19,6,16): parse error FS0010: Incomplete structured construct at or before this point in type name. Expected '>' or other token. -neg29.fs(9,1,9,1): parse error FS0010: Incomplete structured construct at or before this point in implementation file - neg29.fs(6,19,6,20): parse error FS0010: Unexpected symbol '(' in expression neg29.fs(6,18,6,19): parse error FS3156: Unexpected token '>' or incomplete expression + +neg29.fs(9,1,9,1): parse error FS0010: Incomplete structured construct at or before this point in implementation file diff --git a/tests/fsharp/typecheck/sigs/neg69.vsbsl b/tests/fsharp/typecheck/sigs/neg69.vsbsl index 1a0ddb7e009..45b72ad0d8f 100644 --- a/tests/fsharp/typecheck/sigs/neg69.vsbsl +++ b/tests/fsharp/typecheck/sigs/neg69.vsbsl @@ -1,6 +1,3 @@ -neg69.fsx(87,6,87,12): typecheck error FS0912: This declaration element is not permitted in an augmentation - -neg69.fsx(87,6,87,12): typecheck error FS0929: This type requires a definition neg69.fsx(88,43,88,44): parse error FS1241: Expected type argument or static argument @@ -67,3 +64,7 @@ neg69.fsx(212,1,212,4): parse error FS0058: Possible incorrect indentation: this neg69.fsx(221,1,221,4): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (212:1). Try indenting this token further or using standard formatting conventions. neg69.fsx(242,1,242,3): parse error FS0058: Possible incorrect indentation: this token is offside of context started at position (221:1). Try indenting this token further or using standard formatting conventions. + +neg69.fsx(87,6,87,12): typecheck error FS0929: This type requires a definition + +neg69.fsx(87,6,87,12): typecheck error FS0912: This declaration element is not permitted in an augmentation