Skip to content

Commit 43598b7

Browse files
committed
Updated the tests, added an overlapping test. (Note: Conversion to monadic solve increased number of subgoals emitted upon failure. This does not seem to be a problem)
1 parent 59242c5 commit 43598b7

File tree

1 file changed

+84
-56
lines changed

1 file changed

+84
-56
lines changed

lambda-buffers-compiler/test/Test/TypeClassCheck.hs

Lines changed: 84 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{-# LANGUAGE PatternSynonyms #-}
22

3-
module Test.TypeClassCheck (test) where
3+
module Test.TypeClassCheck {- (test) -} where
44

55
import Control.Lens ((.~))
66
import Data.Function ((&))
@@ -19,6 +19,7 @@ import LambdaBuffers.Compiler.TypeClass.Pat (
1919
RecP,
2020
RefP,
2121
SumP,
22+
TyVarP,
2223
VarP,
2324
(:*),
2425
(:=)
@@ -31,7 +32,7 @@ import LambdaBuffers.Compiler.TypeClass.Rules (
3132
Rule ((:<=)),
3233
)
3334
import LambdaBuffers.Compiler.TypeClass.Rules qualified as R
34-
import LambdaBuffers.Compiler.TypeClass.Solve (solve)
35+
import LambdaBuffers.Compiler.TypeClass.Solve (Overlap (Overlap), solve)
3536
import LambdaBuffers.Compiler.TypeClassCheck (detectSuperclassCycles')
3637
import Proto.Compiler (ClassDef, Constraint, Kind, Kind'KindRef (Kind'KIND_REF_TYPE))
3738
import Proto.Compiler_Fields (argKind, argName, arguments, classArgs, className, classRef, kindRef, localClassRef, name, supers, tyVar, varName)
@@ -109,60 +110,77 @@ solveTests =
109110
testGroup
110111
"Solver tests"
111112
[ testCase "1: C [Maybe Int] (completeRules)" $
112-
solveTest1 @?= []
113+
solveTest1 @?= solved
113114
, testCase "2: D [Maybe Int] (partialRules)" $
114-
solveTest2 @?= [dInt]
115+
solveTest2 @?= Right [cListMaybeInt, cMaybeInt, dInt]
115116
, testCase "3: D [Maybe Int] (complete D, partial C)" $
116-
solveTest3 @?= [cInt]
117+
solveTest3 @?= Right [cInt]
117118
, testCase "4: C [[[Bool]]] (completeRules)" $
118-
solveTest4 @?= []
119+
solveTest4 @?= solved
119120
, testCase "5: C (Either (Either Int Bool) (Either Bool Int)) (completeRules)" $
120-
solveTest5 @?= []
121+
solveTest5 @?= solved
121122
, testCase "6: C (Either l x) (completeRules)" $
122-
solveTest6 @?= [cL, cX]
123+
solveTest6 @?= Right [cL, cX]
123124
, testCase "7: Sum test (completeRules)" $
124-
solveTest7 @?= []
125+
solveTest7 @?= solved
125126
, testCase "8: Sum test (partialRules)" $
126-
solveTest8 @?= [cBool, cInt]
127+
solveTest8 @?= Right [cBool, cInt]
127128
, testCase "9: Rec test (completeRules)" $
128-
solveTest9 @?= []
129+
solveTest9 @?= solved
129130
, testCase "10: Rec test (partialRules)" $
130-
solveTest10 @?= [cBool, cInt]
131+
solveTest10 @?= Right [cBool, cInt]
131132
, testCase "11: Prod test (completeRules)" $
132-
solveTest11 @?= []
133+
solveTest11 @?= solved
133134
, testCase "12: Prod test (partialRules)" $
134-
solveTest12 @?= [cBool, cInt]
135+
solveTest12 @?= Right [cBool, cInt]
135136
, testCase "13: Dec test (completeRules)" $
136-
solveTest13 @?= []
137+
solveTest13 @?= solved
137138
, testCase "14: Dec test (partialRules)" $
138-
solveTest14 @?= [cBool, cInt]
139+
solveTest14 @?= Right [cBool, cInt]
140+
, testCase "15: Overlap test (specialrules)" $
141+
solveTest15 @?= Left overlap
139142
]
140143
where
144+
solved :: Either Overlap [R.Constraint]
145+
solved = Right []
146+
cListMaybeInt = C _c (List (Maybe Int))
147+
cMaybeInt = C _c (Maybe Int)
141148
cInt = C _c Int
142149
cBool = C _c Bool
143-
cL = C _c _l
144-
cX = C _c _x
150+
cL = C _c vl
151+
cX = C _c vr
145152
dInt = C _d Int
146-
147-
-- hardcoded variables, easier to read than (VarP "blah") everywhere
148-
_x, _xs, _vars, _name, _l, _body :: Pat
149-
_x = VarP "x"
150-
_xs = VarP "xs"
151-
_vars = VarP "vars"
152-
_name = VarP "name"
153-
_l = VarP "l"
154-
_body = VarP "body"
153+
overlap =
154+
Overlap
155+
cMaybeInt
156+
[ C _c (Maybe _X) :<= [C _c _X]
157+
, C _c (Maybe Int) :<= []
158+
]
159+
160+
-- hardcoded PATTERN variables, easier to read than (VarP "blah") everywhere
161+
_X, _XS, _VARS, _NAME, _L, _BODY :: Pat
162+
_X = VarP "x"
163+
_XS = VarP "xs"
164+
_VARS = VarP "vars"
165+
_NAME = VarP "name"
166+
_L = VarP "l"
167+
_BODY = VarP "body"
168+
169+
-- hardcoded TYPE variables
170+
vl, vr :: Pat
171+
vl = TyVarP "l"
172+
vr = TyVarP "r"
155173

156174
-- TODO(@gnumonik): Import this from somewhere else when that somewhere else module exists
157175
mkStructuralRules :: Class -> [Rule]
158176
mkStructuralRules c =
159177
[ C c Nil :<= []
160-
, C c (_x :* _xs) :<= [C c _x, C c _xs]
161-
, C c (_l := _x) :<= [C c _x]
162-
, C c (RecP _xs) :<= [C c _xs]
163-
, C c (ProdP _xs) :<= [C c _xs]
164-
, C c (SumP _xs) :<= [C c _xs]
165-
, C c (DecP _name _vars _body) :<= [C c _body]
178+
, C c (_X :* _XS) :<= [C c _X, C c _XS]
179+
, C c (_L := _X) :<= [C c _X]
180+
, C c (RecP _XS) :<= [C c _XS]
181+
, C c (ProdP _XS) :<= [C c _XS]
182+
, C c (SumP _XS) :<= [C c _XS]
183+
, C c (DecP _NAME _VARS _BODY) :<= [C c _BODY]
166184
]
167185

168186
pattern (:@) :: Pat -> Pat -> Pat
@@ -196,16 +214,16 @@ userRules1 :: Class -> [Rule]
196214
userRules1 c =
197215
[ NoConstraints c Int
198216
, NoConstraints c Bool
199-
, C c (Maybe _x) :<= [C c _x]
200-
, C c (Either _l _x) :<= [C c _l, C c _x]
201-
, C c (List _x) :<= [C c _x]
217+
, C c (Maybe _X) :<= [C c _X]
218+
, C c (Either _L _X) :<= [C c _L, C c _X]
219+
, C c (List _X) :<= [C c _X]
202220
]
203221

204222
userRules2 :: Class -> [Rule]
205223
userRules2 c =
206-
[ C c (Maybe _x) :<= [C c _x]
207-
, C c (Either _l _x) :<= [C c _l, C c _x]
208-
, C c (List _x) :<= [C c _x]
224+
[ C c (Maybe _X) :<= [C c _X]
225+
, C c (Either _L _X) :<= [C c _L, C c _X]
226+
, C c (List _X) :<= [C c _X]
209227
]
210228

211229
completeRules :: Class -> [Rule]
@@ -223,49 +241,48 @@ _d :: Class
223241
_d = Class (FQClassName "D" []) [_c]
224242

225243
-- C [Maybe Int] w/ complete rules (expected: [])
226-
solveTest1 :: [R.Constraint]
244+
solveTest1 :: Either Overlap [R.Constraint]
227245
solveTest1 = solve (completeRules _c) (C _c $ List (Maybe Int))
228246

229-
-- D [Maybe Int] w/ incomplete rules (expected: [D Int])
230-
solveTest2 :: [R.Constraint]
247+
-- D [Maybe Int] w/ incomplete rules (expected: [C [Maybe Int], C (Maybe Int), D Int])
248+
solveTest2 :: Either Overlap [R.Constraint]
231249
solveTest2 = solve (partialRules _d) (C _d $ List (Maybe Int))
232250

233251
-- D [Maybe Int] w/ complete D rules & incomplete C rules (expected: [C Int])
234-
solveTest3 :: [R.Constraint]
252+
solveTest3 :: Either Overlap [R.Constraint]
235253
solveTest3 = solve rules (C _d $ List (Maybe Int))
236254
where
237255
rules = completeRules _d <> partialRules _c
238256

239257
-- C [[[Bool]]] w/ complete rules (expected: [])
240-
solveTest4 :: [R.Constraint]
258+
solveTest4 :: Either Overlap [R.Constraint]
241259
solveTest4 = solve (completeRules _c) $ C _c $ List (List (List Bool))
242260

243261
-- C (Either (Either Int Bool) (Either Bool Int)) w/ complete rules (expected: [])
244-
solveTest5 :: [R.Constraint]
262+
solveTest5 :: Either Overlap [R.Constraint]
245263
solveTest5 = solve (completeRules _c) $ C _c $ Either (Either Int Bool) (Either Bool Int)
246264

247265
-- NOTE(@bladyjoker): This one shows that we never need to "freshen" variables
248-
-- (if you study it you might also see why we never need to bind them)
249266
-- C (Either l x) w/ complete rules (expected: [C l, C x])
250-
solveTest6 :: [R.Constraint]
251-
solveTest6 = solve (completeRules _c) $ C _c $ Either _l _x
267+
solveTest6 :: Either Overlap [R.Constraint]
268+
solveTest6 = solve (completeRules _c) $ C _c $ Either vl vr
252269

253270
-- tests for structural subcomponents of types. Can't write Haskell equivalents (w/o row-types)
254271

255272
-- expected: []
256-
solveTest7 :: [R.Constraint]
273+
solveTest7 :: Either Overlap [R.Constraint]
257274
solveTest7 = solve (completeRules _c) $ C _c sumBody
258275
where
259276
sumBody = SumP $ Labeled "Ctor1" Int :* Labeled "Ctor2" (List Bool) :* Nil
260277

261278
-- expected [C Bool, C Int]
262-
solveTest8 :: [R.Constraint]
279+
solveTest8 :: Either Overlap [R.Constraint]
263280
solveTest8 = solve (partialRules _c) $ C _c sumBody
264281
where
265282
sumBody = SumP $ Labeled "Ctor1" Int :* Labeled "Ctor2" (List Bool) :* Nil
266283

267284
-- expected []
268-
solveTest9 :: [R.Constraint]
285+
solveTest9 :: Either Overlap [R.Constraint]
269286
solveTest9 = solve (completeRules _c) $ C _c recBody
270287
where
271288
recBody =
@@ -275,7 +292,7 @@ solveTest9 = solve (completeRules _c) $ C _c recBody
275292
:* Nil
276293

277294
-- expected [C Bool, C Int]
278-
solveTest10 :: [R.Constraint]
295+
solveTest10 :: Either Overlap [R.Constraint]
279296
solveTest10 = solve (partialRules _c) $ C _c recBody
280297
where
281298
recBody =
@@ -285,19 +302,19 @@ solveTest10 = solve (partialRules _c) $ C _c recBody
285302
:* Nil
286303

287304
-- expected []
288-
solveTest11 :: [R.Constraint]
305+
solveTest11 :: Either Overlap [R.Constraint]
289306
solveTest11 = solve (completeRules _c) $ C _c prodBody
290307
where
291308
prodBody = ProdP $ List Bool :* Either Int Bool :* Nil
292309

293310
-- expected [C Bool, C Int]
294-
solveTest12 :: [R.Constraint]
311+
solveTest12 :: Either Overlap [R.Constraint]
295312
solveTest12 = solve (partialRules _c) $ C _c prodBody
296313
where
297314
prodBody = ProdP $ List Bool :* Either Int Bool :* Nil
298315

299316
-- expected []
300-
solveTest13 :: [R.Constraint]
317+
solveTest13 :: Either Overlap [R.Constraint]
301318
solveTest13 = solve (completeRules _c) $ C _c testDec
302319
where
303320
testDec =
@@ -308,7 +325,7 @@ solveTest13 = solve (completeRules _c) $ C _c testDec
308325
:* Nil
309326

310327
-- expected [C Int, C Bool]
311-
solveTest14 :: [R.Constraint]
328+
solveTest14 :: Either Overlap [R.Constraint]
312329
solveTest14 = solve (partialRules _c) $ C _c testDec
313330
where
314331
testDec =
@@ -317,3 +334,14 @@ solveTest14 = solve (partialRules _c) $ C _c testDec
317334
Labeled "Ctor1" (ProdP $ Maybe Int :* Nil)
318335
:* Labeled "Ctor2" (RecP $ Labeled "field1" Bool :* Nil)
319336
:* Nil
337+
338+
-- expected overlap
339+
solveTest15 :: Either Overlap [R.Constraint]
340+
solveTest15 = solve cOverlapRules (C _c $ List (Maybe Int))
341+
where
342+
cOverlapRules =
343+
[ C _c (Maybe _X) :<= [C _c _X]
344+
, C _c (Maybe Int) :<= []
345+
, C _c Int :<= []
346+
, C _c (List _X) :<= [C _c _X]
347+
]

0 commit comments

Comments
 (0)