Skip to content

Commit

Permalink
Add cyclic check for struct tuple and tests (#10645)
Browse files Browse the repository at this point in the history
  • Loading branch information
ScottHutchinson authored Dec 8, 2020
1 parent b4cc1c8 commit c0d2aa1
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/fsharp/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4221,7 +4221,12 @@ module EstablishTypeDefinitionCores =
and accStructFieldType structTycon structTyInst fspec fieldTy (doneTypes, acc) =
let fieldTy = stripTyparEqns fieldTy
match fieldTy with
| TType_app (tcref2, tinst2) when tcref2.IsStructOrEnumTycon ->
| TType_tuple (_isStruct , tinst2) when isStructTupleTy cenv.g fieldTy ->
// The field is a struct tuple. Check each element of the tuple.
// This case was added to resolve issues/3916
((doneTypes, acc), tinst2)
||> List.fold (fun acc' x -> accStructFieldType structTycon structTyInst fspec x acc')
| TType_app (tcref2 , tinst2) when tcref2.IsStructOrEnumTycon ->
// The field is a struct.
// An edge (tycon, tycon2) should be recorded, unless it is the "static self-typed field" case.
let tycon2 = tcref2.Deref
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<Compile Include="Interop\SimpleInteropTests.fs" />
<Compile Include="Interop\VisibilityTests.fs" />
<Compile Include="Scripting\Interactive.fs" />
<Compile Include="TypeChecks\CheckDeclarationsTests.fs" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.

namespace FSharp.Compiler.ComponentTests.CheckDeclarationsTests

open Xunit
open FSharp.Test.Utilities.Compiler
open FSharp.Test.Utilities.Xunit.Attributes

module CheckDeclarationsTests =

[<Fact>]
let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Cyclic Tuple`` () =
FSharp """
namespace FSharpTest
[<Struct>]
type Tree =
| Empty
| Children of Tree * Tree
"""
|> compile
|> shouldFail
|> withErrorCode 954
|> ignore

[<Fact>]
let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Cyclic Struct Tuple`` () =
FSharp """
namespace FSharpTest
[<Struct>]
type Tree =
| Empty
| Children of struct (Tree * Tree)
"""
|> compile
|> shouldFail
|> withErrorCode 954
|> ignore

[<Fact>]
let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Cyclic Struct Tuple of int, Tree`` () =
FSharp """
namespace FSharpTest
[<Struct>]
type Tree =
| Empty
| Children of struct (int * Tree)
"""
|> compile
|> shouldFail
|> withErrorCode 954
|> ignore

[<Fact>]
let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Cyclic Tree`` () =
FSharp """
namespace FSharpTest
[<Struct>]
type Tree =
| Empty
| Children of Tree
"""
|> compile
|> shouldFail
|> withErrorCode 954
|> ignore

[<Fact>]
let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Struct DU with Non-cyclic Struct Tuple`` () =
FSharp """
namespace FSharpTest
[<Struct>]
type NotATree =
| Empty
| Children of struct (int * string)
"""
|> compile
|> shouldSucceed
|> ignore

[<Fact>]
let ``CheckingSyntacticTypes - TcTyconDefnCore_CheckForCyclicStructsAndInheritance - Non-Struct DU Tree Cyclic Tree`` () =
FSharp """
namespace FSharpTest
type Tree =
| Empty
| Children of Tree
"""
|> compile
|> shouldSucceed
|> ignore

0 comments on commit c0d2aa1

Please sign in to comment.