From 276fc42fa8004a1d3c3e26080e964bac9bc14e04 Mon Sep 17 00:00:00 2001 From: Tomas Grosup Date: Tue, 23 Jan 2024 15:59:43 +0100 Subject: [PATCH] Align DU case augmentation with previous behavior in EraseUnions (#16571) * Align DU case augment with previous behavior in EraseUnions * Update 8.0.300.md * modify tests --- .../.FSharp.Compiler.Service/8.0.300.md | 1 + src/Compiler/Checking/CheckDeclarations.fs | 3 ++- src/Compiler/SyntaxTree/ParseHelpers.fs | 2 +- .../Language/DiscriminatedUnionTests.fs | 14 ++++++++++++++ tests/service/ExprTests.fs | 1 - tests/service/ProjectAnalysisTests.fs | 10 ++++------ 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md index dce836b32be..1c70a67edc6 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md +++ b/docs/release-notes/.FSharp.Compiler.Service/8.0.300.md @@ -11,6 +11,7 @@ ### Changed +* Autogenerated .Is* members for unions skipped for single-case unions. ([PR 16571](https://github.com/dotnet/fsharp/pull/16571)) * `implicitCtorSynPats` in `SynTypeDefnSimpleRepr.General` is now `SynPat option` instead of `SynSimplePats option`. ([PR #16425](https://github.com/dotnet/fsharp/pull/16425)) * `SyntaxVisitorBase<'T>.VisitSimplePats` now takes `SynPat` instead of `SynSimplePat list`. ([PR #16425](https://github.com/dotnet/fsharp/pull/16425)) * Reduce allocations in compiler checking via `ValueOption` usage ([PR #16323](https://github.com/dotnet/fsharp/pull/16323)) diff --git a/src/Compiler/Checking/CheckDeclarations.fs b/src/Compiler/Checking/CheckDeclarations.fs index 95fc034c4c7..c5e21e744cd 100644 --- a/src/Compiler/Checking/CheckDeclarations.fs +++ b/src/Compiler/Checking/CheckDeclarations.fs @@ -866,7 +866,8 @@ module AddAugmentationDeclarations = let ShouldAugmentUnion (g: TcGlobals) (tycon: Tycon) = g.langVersion.SupportsFeature LanguageFeature.UnionIsPropertiesVisible && - HasDefaultAugmentationAttribute g (mkLocalTyconRef tycon) + HasDefaultAugmentationAttribute g (mkLocalTyconRef tycon) && + tycon.UnionCasesArray.Length > 1 let AddUnionAugmentationValues (cenv: cenv) (env: TcEnv) tycon = let tcref = mkLocalTyconRef tycon diff --git a/src/Compiler/SyntaxTree/ParseHelpers.fs b/src/Compiler/SyntaxTree/ParseHelpers.fs index bb2e7755767..cd4b41787e1 100644 --- a/src/Compiler/SyntaxTree/ParseHelpers.fs +++ b/src/Compiler/SyntaxTree/ParseHelpers.fs @@ -1159,7 +1159,7 @@ let mkSynField let mType, mStart = idOpt - |> Option.map _.idRange + |> Option.map (fun x -> x.idRange) |> Option.orElseWith (fun _ -> vis |> Option.map (fun v -> v.Range)) |> Option.orElse isMutable |> Option.orElseWith (fun _ -> leadingKeyword |> Option.map (fun k -> k.Range)) diff --git a/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs index abd5fb6e3b6..d7de4c35cd2 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/DiscriminatedUnionTests.fs @@ -17,6 +17,20 @@ if foo.IsBar then failwith "Should not be Bar" |> compileExeAndRun |> shouldSucceed + [] + let ``Simple Is* discriminated union properties are not visible for a single case union`` () = + Fsx """ +type Foo = Bar of string +let foo = Foo.Bar "hi" +if not foo.IsBar then failwith "Should be Bar" + + """ + |> withLangVersionPreview + |> typecheck + |> shouldFail + |> withDiagnostics [Error 39, Line 4, Col 12, Line 4, Col 17, "The type 'Foo' does not define the field, constructor or member 'IsBar'. Maybe you want one of the following: + Bar"] + [] let ``Simple Is* discriminated union property satisfies SRTP constraint`` () = Fsx """ diff --git a/tests/service/ExprTests.fs b/tests/service/ExprTests.fs index 113931e62ed..7b35568e38d 100644 --- a/tests/service/ExprTests.fs +++ b/tests/service/ExprTests.fs @@ -3442,7 +3442,6 @@ let ``Test ProjectForWitnesses2`` useTransparentCompiler = "member Neg(p) = {x = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),p.x); y = Operators.op_UnaryNegation (fun arg0_0 -> LanguagePrimitives.UnaryNegationDynamic (arg0_0),p.y)} @ (7,34--7,56)"; "member op_Addition(p1,p2) = {x = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),p1.x,p2.x); y = Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),p1.y,p2.y)} @ (8,33--8,68)"; "type MyNumber"; - "member get_IsMyNumber(this) (unitArg) = (if this.IsMyNumber then True else False) @ (10,5--10,13)"; "member get_Zero(unitVar0) = MyNumber(0) @ (12,25--12,35)"; "member op_Addition(_arg1,_arg2) = let x: Microsoft.FSharp.Core.int = _arg1.Item in let y: Microsoft.FSharp.Core.int = _arg2.Item in MyNumber(Operators.op_Addition (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.AdditionDynamic (arg0_0,arg1_0),x,y)) @ (13,23--13,33)"; "member DivideByInt(_arg3,i) = let x: Microsoft.FSharp.Core.int = _arg3.Item in MyNumber(Operators.op_Division (fun arg0_0 -> fun arg1_0 -> LanguagePrimitives.DivisionDynamic (arg0_0,arg1_0),x,i)) @ (15,31--15,41)"; diff --git a/tests/service/ProjectAnalysisTests.fs b/tests/service/ProjectAnalysisTests.fs index 93b746e7d24..a1a58a709b2 100644 --- a/tests/service/ProjectAnalysisTests.fs +++ b/tests/service/ProjectAnalysisTests.fs @@ -714,11 +714,11 @@ let ``Test project2 all symbols in signature`` () = "DUWithNormalFields"; "member get_IsD"; "member get_IsDU1"; "member get_IsDU2"; "property IsD"; "property IsDU1"; "property IsDU2"; "DU1"; "field Item1"; "field Item2"; "DU2"; "field Item1"; "field Item2"; "D"; "field Item1"; - "field Item2"; "DUWithNamedFields"; "member get_IsDU"; "property IsDU"; "DU"; + "field Item2"; "DUWithNamedFields"; "DU"; "field x"; "field y"; "GenericClass`1"; "generic parameter T"; "member .ctor"; "member GenericMethod"; "generic parameter U"] |> List.sort - shouldEqual e r + shouldPairwiseEqual e r [] let ``Test project2 all uses of all signature symbols`` () = @@ -736,12 +736,10 @@ let ``Test project2 all uses of all signature symbols`` () = ("generic parameter T", [("file1", ((22, 23), (22, 25))); ("file1", ((22, 30), (22, 32))); ("file1", ((22, 45), (22, 47))); ("file1", ((22, 50), (22, 52)))]); - ("member get_IsD", []); - ("member get_IsDU", []); + ("member get_IsD", []); ("member get_IsDU1", []); ("member get_IsDU2", []); - ("property IsD", []); - ("property IsDU", []); + ("property IsD", []); ("property IsDU1", []); ("property IsDU2", []); ("DUWithNormalFields", [("file1", ((3, 5), (3, 23)))]);