Skip to content

Commit 5efa8a7

Browse files
forkiKevinRansom
authored andcommitted
Member constraints and PrimitiveConstraints (#7210)
1 parent d53a38c commit 5efa8a7

11 files changed

Lines changed: 171 additions & 139 deletions

File tree

tests/fsharp/Compiler/CompilerAssert.fs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,15 @@ let main argv = 0"""
173173

174174
Assert.IsEmpty(typeCheckResults.Errors, sprintf "Type Check errors: %A" typeCheckResults.Errors)
175175

176-
let TypeCheckWithErrors (source: string) expectedTypeErrors =
176+
let TypeCheckWithErrorsAndOptions options (source: string) expectedTypeErrors =
177177
lock gate <| fun () ->
178-
let parseResults, fileAnswer = checker.ParseAndCheckFileInProject("test.fs", 0, SourceText.ofString source, defaultProjectOptions) |> Async.RunSynchronously
178+
let parseResults, fileAnswer =
179+
checker.ParseAndCheckFileInProject(
180+
"test.fs",
181+
0,
182+
SourceText.ofString source,
183+
{ defaultProjectOptions with OtherOptions = Array.append options defaultProjectOptions.OtherOptions})
184+
|> Async.RunSynchronously
179185

180186
Assert.IsEmpty(parseResults.Errors, sprintf "Parse errors: %A" parseResults.Errors)
181187

@@ -198,8 +204,14 @@ let main argv = 0"""
198204
Assert.AreEqual(expectedErrorMsg, info.Message, "expectedErrorMsg")
199205
)
200206

207+
let TypeCheckWithErrors (source: string) expectedTypeErrors =
208+
TypeCheckWithErrorsAndOptions [||] source expectedTypeErrors
209+
210+
let TypeCheckSingleErrorWithOptions options (source: string) (expectedServerity: FSharpErrorSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) =
211+
TypeCheckWithErrorsAndOptions options source [| expectedServerity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]
212+
201213
let TypeCheckSingleError (source: string) (expectedServerity: FSharpErrorSeverity) (expectedErrorNumber: int) (expectedErrorRange: int * int * int * int) (expectedErrorMsg: string) =
202-
TypeCheckWithErrors (source: string) [| expectedServerity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]
214+
TypeCheckWithErrors source [| expectedServerity, expectedErrorNumber, expectedErrorRange, expectedErrorMsg |]
203215

204216
let CompileExe (source: string) =
205217
compile true source (fun (errors, _) ->
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace FSharp.Compiler.UnitTests
4+
5+
open NUnit.Framework
6+
open FSharp.Compiler.SourceCodeServices
7+
8+
[<TestFixture>]
9+
module MemberConstraints =
10+
11+
[<Test>]
12+
let ``we can overload operators on a type and not add all the extra jazz such as inlining and the ^ operator.``() =
13+
CompilerAssert.CompileExeAndRun
14+
"""
15+
type Foo(x : int) =
16+
member this.Val = x
17+
18+
static member (-->) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val)
19+
static member (-->) ((src : Foo), (target : int)) = new Foo(src.Val + target)
20+
21+
static member (+) ((src : Foo), (target : Foo)) = new Foo(src.Val + target.Val)
22+
static member (+) ((src : Foo), (target : int)) = new Foo(src.Val + target)
23+
24+
let x = Foo(3) --> 4
25+
let y = Foo(3) --> Foo(4)
26+
let x2 = Foo(3) + 4
27+
let y2 = Foo(3) + Foo(4)
28+
29+
if x.Val <> 7 then exit 1
30+
if y.Val <> 7 then exit 1
31+
if x2.Val <> 7 then exit 1
32+
if y2.Val <> 7 then exit 1
33+
"""
34+
35+
[<Test>]
36+
let ``Invalid member constraint with ErrorRanges``() = // Regression test for FSharp1.0:2262
37+
CompilerAssert.TypeCheckSingleErrorWithOptions
38+
[| "--test:ErrorRanges" |]
39+
"""
40+
let inline length (x: ^a) : int = (^a : (member Length : int with get, set) (x, ()))
41+
"""
42+
FSharpErrorSeverity.Error
43+
697
44+
(2, 42, 2, 75)
45+
"Invalid constraint"
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespace FSharp.Compiler.UnitTests
4+
5+
open NUnit.Framework
6+
open FSharp.Compiler.SourceCodeServices
7+
8+
[<TestFixture>]
9+
module PrimitiveConstraints =
10+
11+
[<Test>]
12+
let ``Test primitive : constraints``() =
13+
CompilerAssert.CompileExeAndRun
14+
"""
15+
#light
16+
17+
type Foo(x : int) =
18+
member this.Value = x
19+
override this.ToString() = "Foo"
20+
21+
type Bar(x : int) =
22+
inherit Foo(-1)
23+
member this.Value2 = x
24+
override this.ToString() = "Bar"
25+
26+
let test1 (x : Foo) = x.Value
27+
let test2 (x : Bar) = (x.Value, x.Value2)
28+
29+
let f = new Foo(128)
30+
let b = new Bar(256)
31+
32+
if test1 f <> 128 then exit 1
33+
if test2 b <> (-1, 256) then exit 1
34+
"""
35+
36+
[<Test>]
37+
let ``Test primitive :> constraints``() =
38+
CompilerAssert.CompileExeAndRun
39+
"""
40+
#light
41+
type Foo(x : int) =
42+
member this.Value = x
43+
override this.ToString() = "Foo"
44+
45+
type Bar(x : int) =
46+
inherit Foo(-1)
47+
member this.Value2 = x
48+
override this.ToString() = "Bar"
49+
50+
type Ram(x : int) =
51+
inherit Foo(10)
52+
member this.ValueA = x
53+
override this.ToString() = "Ram"
54+
55+
let test (x : Foo) = (x.Value, x.ToString())
56+
57+
let f = new Foo(128)
58+
let b = new Bar(256)
59+
let r = new Ram(314)
60+
61+
if test f <> (128, "Foo") then exit 1
62+
if test b <> (-1, "Bar") then exit 1
63+
if test r <> (10, "Ram") then exit 1
64+
"""
65+
66+
[<Test>]
67+
let ``Test primitive : null constraint``() =
68+
CompilerAssert.CompileExeAndRun
69+
"""
70+
let inline isNull<'a when 'a : null> (x : 'a) =
71+
match x with
72+
| null -> "is null"
73+
| _ -> (x :> obj).ToString()
74+
75+
let runTest =
76+
// Wrapping in try block to work around FSB 1989
77+
try
78+
if isNull null <> "is null" then exit 1
79+
if isNull "F#" <> "F#" then exit 1
80+
true
81+
with _ -> exit 1
82+
83+
if runTest <> true then exit 1
84+
85+
exit 0
86+
"""
87+
88+
[<Test>]
89+
/// Title: Type checking oddity
90+
///
91+
/// This suggestion was resolved as by design,
92+
/// so the test makes sure, we're emitting error message about 'not being a valid object construction expression'
93+
let ``Invalid object constructor``() = // Regression test for FSharp1.0:4189
94+
CompilerAssert.TypeCheckWithErrorsAndOptions
95+
[| "--test:ErrorRanges" |]
96+
"""
97+
type ImmutableStack<'a> private(items: 'a list) =
98+
99+
member this.Push item = ImmutableStack(item::items)
100+
member this.Pop = match items with | [] -> failwith "No elements in stack" | x::xs -> x,ImmutableStack(xs)
101+
102+
// Notice type annotation is commented out, which results in an error
103+
new(col (*: seq<'a>*)) = ImmutableStack(List.ofSeq col)
104+
105+
"""
106+
[| FSharpErrorSeverity.Error, 41, (4, 29, 4, 56), "A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : col:'b -> ImmutableStack<'a>, private new : items:'a list -> ImmutableStack<'a>"
107+
FSharpErrorSeverity.Error, 41, (5, 93, 5, 111), "A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : col:'b -> ImmutableStack<'a>, private new : items:'a list -> ImmutableStack<'a>"
108+
FSharpErrorSeverity.Error, 41, (8, 30, 8, 60), "A unique overload for method 'ImmutableStack`1' could not be determined based on type information prior to this program point. A type annotation may be needed. Candidates: new : col:'b -> ImmutableStack<'a> when 'b :> seq<'c>, private new : items:'a list -> ImmutableStack<'a>"
109+
FSharpErrorSeverity.Error, 696, (8, 30, 8, 60), "This is not a valid object construction expression. Explicit object constructors must either call an alternate constructor or initialize all fields of the object and specify a call to a super class constructor." |]

tests/fsharp/FSharpSuite.Tests.fsproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
<Compile Include="Compiler\ErrorMessages\ConstructorTests.fs" />
3636
<Compile Include="Compiler\ErrorMessages\AccessOfTypeAbbreviationTests.fs" />
3737
<Compile Include="Compiler\ErrorMessages\ElseBranchHasWrongTypeTests.fs" />
38+
<Compile Include="Compiler\ConstraintSolver\PrimitiveConstraints.fs" />
39+
<Compile Include="Compiler\ConstraintSolver\MemberConstraints.fs" />
3840
<Compile Include="Compiler\ErrorMessages\MissingElseBranch.fs" />
3941
<Compile Include="Compiler\ErrorMessages\UnitGenericAbstactType.fs" />
4042
<Compile Include="Compiler\ErrorMessages\NameResolutionTests.fs" />

tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/E_MemberConstraints01.fs

Lines changed: 0 additions & 6 deletions
This file was deleted.

tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/E_PrimConstraint04.fs

Lines changed: 0 additions & 16 deletions
This file was deleted.

tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/MemberConstraints01.fs

Lines changed: 0 additions & 24 deletions
This file was deleted.

tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/PrimConstraint01.fs

Lines changed: 0 additions & 26 deletions
This file was deleted.

tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/PrimConstraint02.fs

Lines changed: 0 additions & 33 deletions
This file was deleted.

tests/fsharpqa/Source/Conformance/InferenceProcedures/ConstraintSolving/PrimConstraint03.fs

Lines changed: 0 additions & 23 deletions
This file was deleted.

0 commit comments

Comments
 (0)