Skip to content

Commit 8d4710b

Browse files
authored
Merge pull request #2182 from GaloisInc/type-messages-tests
Add more typechecker tests
2 parents da1cf80 + a72e7ad commit 8d4710b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+942
-2
lines changed

intTests/support/test-and-diff.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ run-tests() {
110110
/^\[[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\.[0-9][0-9][0-9]\] /{
111111
s/^..............//
112112
}
113-
s,'"$CURDIR"'/,,
113+
s,'"$CURDIR"'/,,g
114114
'
115115

116116
# Check the output against the expected version.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Loading file "err013.saw"
2+
err013.saw:9:33-9:35: Type mismatch.
3+
Occurs check failure: the type at internal:1:2-1:3: Fresh type for this term appears within the type at internal:1:2-1:3: Fresh type for this term
4+
Expected: [t.5]
5+
Found: [[t.5]]
6+
7+
within "paste" (err013.saw:9:5-9:10)
8+
9+
FAILED

intTests/test_type_errors/err013.saw

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Trigger the "occurs check failure" message
2+
//
3+
// This is produced if type inference results in a type that contains
4+
// itself.
5+
//
6+
// We can do this by doing something with a list and its element type
7+
// that require them to be the same.
8+
9+
let paste xs = concat (head xs) xs;
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Loading file "err014.saw"
2+
err014.saw:12:15-12:18: Type mismatch.
3+
Record field names mismatch.
4+
err014.saw:8:13-8:24: The type {a : Int} arises from this type annotation
5+
err014.saw:10:25-10:34: The type {b : Int} arises from the type of this term
6+
7+
Expected: {a : Int}
8+
Found: {b : Int}
9+
10+
within "baz" (err014.saw:12:5-12:8)
11+
12+
FAILED

intTests/test_type_errors/err014.saw

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Trigger the "Record field names mismatch" message.
2+
//
3+
// This is produced by trying to unify two record types with
4+
// different field names.
5+
//
6+
// Here just do a base case of that.
7+
8+
let foo (x: { a : Int }) : { a : Int } = { a = x.a };
9+
10+
let bar : { b : Int } = { b = 3 };
11+
12+
let baz = foo bar;
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
Loading file "err015.saw"
2+
Type errors:
3+
err015.saw:65:14-65:15: Type mismatch.
4+
Record field names mismatch.
5+
err015.saw:18:15-22:2: The type {amethyst : Int, moonstone : Int, obsidian : Int} arises from this type annotation
6+
err015.saw:55:14-55:74: The type {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int} arises from the type of this term
7+
8+
Expected: {amethyst : Int, moonstone : Int, obsidian : Int}
9+
Found: {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int}
10+
11+
within "y" (err015.saw:65:5-65:6)
12+
13+
err015.saw:65:21-65:22: Type mismatch.
14+
Record field names mismatch.
15+
err015.saw:25:15-31:2: The type {amethyst : Int, moonstone : Int, obsidian : Int, sapphire : Int, turquoise : Int} arises from this type annotation
16+
err015.saw:55:14-55:74: The type {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int} arises from the type of this term
17+
18+
Expected: {amethyst : Int, moonstone : Int, obsidian : Int, sapphire : Int, turquoise : Int}
19+
Found: {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int}
20+
21+
within "y" (err015.saw:65:5-65:6)
22+
23+
err015.saw:65:28-65:29: Type mismatch.
24+
Record field names mismatch.
25+
err015.saw:34:15-39:2: The type {amethyst : Int, moonstone : Int, obsidian : Int, tourmaline : Int} arises from this type annotation
26+
err015.saw:55:14-55:74: The type {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int} arises from the type of this term
27+
28+
Expected: {amethyst : Int, moonstone : Int, obsidian : Int, tourmaline : Int}
29+
Found: {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int}
30+
31+
within "y" (err015.saw:65:5-65:6)
32+
33+
err015.saw:65:35-65:36: Type mismatch.
34+
Record field names mismatch.
35+
err015.saw:42:15-45:2: The type {amethyst : Int, obsidian : Int} arises from this type annotation
36+
err015.saw:55:14-55:74: The type {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int} arises from the type of this term
37+
38+
Expected: {amethyst : Int, obsidian : Int}
39+
Found: {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int}
40+
41+
within "y" (err015.saw:65:5-65:6)
42+
43+
err015.saw:65:41-65:42: Type mismatch.
44+
Record field names mismatch.
45+
err015.saw:48:14-53:2: The type {anise : Int, cinnamon : Int, sage : Int, tarragon : Int} arises from this type annotation
46+
err015.saw:55:14-55:74: The type {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int} arises from the type of this term
47+
48+
Expected: {anise : Int, cinnamon : Int, sage : Int, tarragon : Int}
49+
Found: {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int}
50+
51+
within "y" (err015.saw:65:5-65:6)
52+
53+
54+
FAILED

intTests/test_type_errors/err015.saw

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Trigger the "Record field names mismatch" message.
2+
//
3+
// Exercise multiple more complicated cases:
4+
// - lots of record fields with one missing
5+
// - lots of record fields with one extra
6+
// - lots of record fields with one different
7+
// - lots of record fields with half missing
8+
// - lots of record fields with all of them different
9+
10+
typedef t1 = {
11+
amethyst: Int,
12+
moonstone: Int,
13+
obsidian: Int,
14+
turquoise: Int
15+
};
16+
17+
// one missing
18+
typedef t1a = {
19+
amethyst: Int,
20+
moonstone: Int,
21+
obsidian: Int
22+
};
23+
24+
// one extra
25+
typedef t1b = {
26+
amethyst: Int,
27+
moonstone: Int,
28+
obsidian: Int,
29+
sapphire: Int,
30+
turquoise: Int
31+
};
32+
33+
// one different
34+
typedef t1c = {
35+
amethyst: Int,
36+
moonstone: Int,
37+
obsidian: Int,
38+
tourmaline: Int
39+
};
40+
41+
// half missing
42+
typedef t1d = {
43+
amethyst: Int,
44+
obsidian: Int
45+
};
46+
47+
// all different
48+
typedef t2 = {
49+
anise: Int,
50+
cinnamon: Int,
51+
sage: Int,
52+
tarragon: Int
53+
};
54+
55+
let x : t1 = { amethyst = 3, moonstone = 3, obsidian = 3, turquoise = 3 };
56+
57+
let f1a (x: t1a) = x.amethyst;
58+
let f1b (x: t1b) = x.amethyst;
59+
let f1c (x: t1c) = x.amethyst;
60+
let f1d (x: t1d) = x.amethyst;
61+
let f2 (x: t2) = x.anise;
62+
63+
// produce a tuple so we get all the messages at once
64+
// (otherwise the interpreter apparently bails after one failed let)
65+
let y = (f1a x, f1b x, f1c x, f1d x, f2 x);
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Loading file "err016.saw"
2+
err016.saw:5:9-5:12: Type mismatch.
3+
Term is not a function. (Maybe a function is applied to too many arguments?)
4+
err016.saw:5:9-5:12: The type t.0 -> t.1 arises from the context of the term
5+
err016.saw:5:11-5:12: The type Int arises from the type of this term
6+
7+
Expected: t.0 -> t.1
8+
Found: Int
9+
10+
within "y" (err016.saw:5:5-5:6)
11+
12+
FAILED

intTests/test_type_errors/err016.saw

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Trigger the message "Term is not a function. (Maybe a function is
2+
// applied to too many arguments?)"
3+
4+
let f x = x;
5+
let y = f 3 4;
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Loading file "err017.saw"
2+
err017.saw:27:11-27:12: Type mismatch.
3+
Mismatch of types.
4+
err017.saw:20:13-23:2: The type {a : Int, b : Int} arises from this type annotation
5+
err017.saw:27:11-27:12: The type Int arises from the type of this term
6+
7+
Expected: {a : Int, b : Int}
8+
Found: Int
9+
10+
within "y" (err017.saw:27:5-27:6)
11+
12+
FAILED

intTests/test_type_errors/err017.saw

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Trigger the "Mismatch of types" message.
2+
//
3+
// Most type mismatches generate the "Mismatch of type constructors"
4+
// message; to fall through to the default case that produces this
5+
// message, you have to have two types where
6+
// - neither is a TyUnifyVar
7+
// - they aren't both TyRecord
8+
// - they aren't both TyCon
9+
// - they aren't the same TyVar
10+
// which leaves the following cases:
11+
// - TyRecord vs. TyCon
12+
// - TyVar vs. TyRecord or TyCon
13+
// - different TyVars
14+
//
15+
// At the moment producing arbitrary TyVars is difficult (we no
16+
// longer allow making them up just by mentioning them, but we don't
17+
// yet have a syntax for forall-binding them in decls) so use the
18+
// TyRecord vs. TyCon case
19+
20+
typedef t = {
21+
a: Int,
22+
b: Int
23+
};
24+
25+
let f (x: t) = x.a;
26+
27+
let y = f 3;
28+
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Loading file "err018.saw"
2+
err018.saw:26:11-26:12: Type mismatch.
3+
Mismatch of type constructors. Expected: String but got Int
4+
err018.saw:16:14-16:20: The type String arises from this type annotation
5+
err018.saw:23:25-23:26: The type Int arises from the type of this term
6+
7+
Expected: String
8+
Found: Int
9+
10+
Expected: {amethyst : String, moonstone : String, obsidian : String, turquoise : String}
11+
Found: {amethyst : Int, moonstone : Int, obsidian : Int, turquoise : Int}
12+
13+
within "y" (err018.saw:26:5-26:6)
14+
15+
FAILED

intTests/test_type_errors/err018.saw

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Trigger the message we get when records have the same fields
2+
// but not the same types.
3+
//
4+
// Currently this trips on the first inconsistent field and prints
5+
// "mismatch of type constructors" on it, which is not particularly
6+
// friendly.
7+
8+
typedef t1 = {
9+
amethyst: Int,
10+
moonstone: Int,
11+
obsidian: Int,
12+
turquoise: Int
13+
};
14+
15+
typedef t2 = {
16+
amethyst: String,
17+
moonstone: String,
18+
obsidian: String,
19+
turquoise: String
20+
};
21+
22+
23+
let x : t1 = { amethyst=3, moonstone=4, obsidian=5, turquoise=6 };
24+
let f (x: t2) = x.amethyst;
25+
26+
let y = f x;
27+
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Loading file "err019.saw"
2+
err019.saw:5:11-5:12: Type mismatch.
3+
Mismatch of type constructors. Expected: (,,,) but got (,,)
4+
err019.saw:4:11-4:31: The type (Int, Int, Int, Int) arises from this type annotation
5+
err019.saw:3:9-3:18: The type (Int, Int, Int) arises from the type of this term
6+
7+
Expected: (Int, Int, Int, Int)
8+
Found: (Int, Int, Int)
9+
10+
within "y" (err019.saw:5:5-5:6)
11+
12+
FAILED

intTests/test_type_errors/err019.saw

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Trigger the message we get by unifying tuples of mismatched arity.
2+
3+
let x = (1, 2, 3);
4+
let f (x: (Int, Int, Int, Int)) = x.0;
5+
let y = f x;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Loading file "err020.saw"
2+
err020.saw:3:20-3:33: Record lookup on non-record argument.
3+
Field name: nonexistent
4+
5+
FAILED

intTests/test_type_errors/err020.saw

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Trigger the "Record lookup on non-record argument" message.
2+
3+
let foo (x: Int) = x.nonexistent;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Loading file "err021.saw"
2+
err021.saw:8:18-8:31: Selecting a missing field.
3+
Field name: nonexistent
4+
5+
FAILED

intTests/test_type_errors/err021.saw

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Trigger the "Selecting a missing (record) field" message.
2+
3+
typedef t = {
4+
a: Int,
5+
b: Int
6+
};
7+
8+
let foo (x: t) = x.nonexistent;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Loading file "err022.saw"
2+
err022.saw:3:20-3:23: Tuple lookup on non-tuple argument.
3+
Given index 3
4+
5+
FAILED

intTests/test_type_errors/err022.saw

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Trigger the "Tuple lookup on non-tuple argument" message.
2+
3+
let foo (x: Int) = x.3;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Loading file "err023.saw"
2+
err023.saw:5:18-5:21: Tuple index out of bounds.
3+
Given index 3 is too large for tuple size of 2
4+
5+
FAILED

intTests/test_type_errors/err023.saw

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Trigger the "Tuple index out of bounds" message.
2+
3+
typedef t = (Int, Int);
4+
5+
let foo (x: t) = x.3;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Loading file "err024.saw"
2+
err024.saw:3:9-3:10: Unbound variable: "y" (err024.saw:3:9-3:10)
3+
Note that some built-in commands are available only after running
4+
either `enable_deprecated` or `enable_experimental`.
5+
6+
FAILED

intTests/test_type_errors/err024.saw

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Trigger the "Unbound variable" message
2+
3+
let x = y;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Loading file "err025.saw"
2+
err025.saw:3:9-3:14: do block must include at least one expression at "x" (err025.saw:3:5-3:6)
3+
FAILED

intTests/test_type_errors/err025.saw

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Trigger the "do block must include at least one expression" message
2+
3+
let x = do {};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Loading file "err026.saw"
2+
err026.saw:3:9-5:2: do block must end with expression at "x" (err026.saw:3:5-3:6)
3+
FAILED

intTests/test_type_errors/err026.saw

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Trigger the "do block must end with expression" message
2+
3+
let x = do {
4+
y <- llvm_assert {{ True }};
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Loading file "err027.saw"
2+
Parse error at err027.saw:7:10-7:11: Unexpected `]'
3+
FAILED

intTests/test_type_errors/err027.saw

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//
2+
// Not enough arguments for type constructor: arrays
3+
//
4+
// Currently this is a parser message; the kind mismatch message in
5+
// the typechecker is unreachable.
6+
7+
let x : [] = [];
8+
9+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Loading file "err028.saw"
2+
Parse error at err028.saw:7:16-7:19: Unexpected `Int'
3+
FAILED

0 commit comments

Comments
 (0)