-
Notifications
You must be signed in to change notification settings - Fork 179
Expand file tree
/
Copy pathTypeError.hs
More file actions
533 lines (519 loc) · 26.5 KB
/
TypeError.hs
File metadata and controls
533 lines (519 loc) · 26.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
module TypeError where
import Constraints
import Data.List (nub)
import Data.Maybe (fromMaybe)
import Info
import qualified Map
import Obj
import Project
import Text.EditDistance (defaultEditCosts, levenshteinDistance)
import Types
import Util
data TypeError
= SymbolMissingType XObj Env
| DefnMissingType XObj
| DefMissingType XObj
| ExpressionMissingType XObj
| SymbolNotDefined SymPath XObj Env
| InvalidObj Obj XObj
| InvalidObjExample Obj XObj String
| CantUseDerefOutsideFunctionApplication XObj
| NotAType XObj
| WrongArgCount XObj Int Int
| NotAFunction XObj
| NoStatementsInDo XObj
| TooManyFormsInBody XObj
| NoFormsInBody XObj
| LeadingColon XObj
| UnificationFailed Constraint TypeMappings [Constraint]
| CantDisambiguate XObj String Ty [(Ty, SymPath)]
| CantDisambiguateInterfaceLookup XObj String Ty [(Ty, SymPath)]
| SeveralExactMatches XObj String Ty [(Ty, SymPath)]
| NoMatchingSignature XObj String Ty [(Ty, SymPath)]
| HolesFound [(String, Ty)]
| NotAValidType XObj
| FunctionsCantReturnRefTy XObj Ty
| LetCantReturnRefTy XObj Ty
| GettingReferenceToUnownedValue XObj
| UsingUnownedValue XObj
| UsingCapturedValue XObj
| ArraysCannotContainRefs XObj
| MainCanOnlyReturnUnitOrInt XObj Ty
| MainCannotHaveArguments XObj Int
| CannotConcretize XObj
| TooManyAnnotateCalls XObj
| CannotSet XObj
| CannotSetVariableFromLambda XObj XObj
| DoesNotMatchSignatureAnnotation XObj Ty -- Not used at the moment (but should?)
| CannotMatch XObj
| InvalidSumtypeCase XObj
| InvalidMemberType Ty XObj
| InvalidMemberTypeWhenConcretizing Ty XObj TypeError
| NotAmongRegisteredTypes Ty XObj
| UnevenMembers [XObj]
| DuplicatedMembers [XObj]
| InvalidLetBinding [XObj] (XObj, XObj)
| DuplicateBinding XObj
| DefinitionsMustBeAtToplevel XObj
| UsingDeadReference XObj String
| UninhabitedConstructor Ty XObj Int Int
| InconsistentKinds String [XObj]
| FailedToAddLambdaStructToTyEnv SymPath XObj
instance Show TypeError where
show (SymbolMissingType xobj env) =
"I couldn’t find a type for the symbol '" ++ getName xobj ++ "' at "
++ prettyInfoFromXObj xobj
++ " in the environment:\n"
++ prettyEnvironment env
++ "\n\nIt might be too general. You could try adding a type hint using `the`."
show (DefnMissingType xobj) =
"I couldn’t find a type for the function definition '" ++ getName xobj
++ "' at "
++ prettyInfoFromXObj xobj
++ ".\n\nIt might be too general. You could try adding a type hint using `the`."
show (DefMissingType xobj) =
"I couldn’t find a type for the variable definition '" ++ getName xobj
++ "' at "
++ prettyInfoFromXObj xobj
++ ".\n\nIt might be too general. You could try adding a type hint using `the`."
show (ExpressionMissingType xobj) =
"I couldn’t find a type for the expression '" ++ pretty xobj ++ "' at "
++ prettyInfoFromXObj xobj
++ ".\n\nIt might be too general. You could try adding a type hint using `the`."
show (SymbolNotDefined symPath@(SymPath p _) xobj env) =
"I couldn’t find the symbol '" ++ show symPath ++ "' at "
++ prettyInfoFromXObj xobj
++ ".\n\n"
++ matches (keysInEnvEditDistance symPath env 3)
where
matches [] = "Maybe you forgot to define it?"
matches x = "Maybe you wanted one of the following?\n " ++ joinWith "\n " (map (show . SymPath p) x)
show (InvalidObj (Defn _) xobj) =
"I didn’t understand the function definition at "
++ prettyInfoFromXObj xobj
++ ".\n\nIs it valid? Every `defn` needs to follow the form `(defn name [arg] body)`."
show (CantUseDerefOutsideFunctionApplication xobj) =
"I found a `deref` / `~` that isn’t inside a function application at "
++ prettyInfoFromXObj xobj
++ ".\n\nEvery usage of `~` must be inside a function application."
show (InvalidObj If xobj) =
"I didn’t understand the `if` statement at " ++ prettyInfoFromXObj xobj
++ ".\n\nIs it valid? Every `if` needs to follow the form `(if cond iftrue iffalse)`."
show (InvalidObj o xobj) =
"I didn’t understand the form `" ++ prettyObj o ++ "` at "
++ prettyInfoFromXObj xobj
++ ".\n\nIs it valid?"
show (InvalidObjExample o xobj example) =
"I didn’t understand the form `" ++ prettyObj o ++ "` at "
++ prettyInfoFromXObj xobj
++ ".\n\nIs it valid? It needs to follow the form `"
++ example
++ "`."
show (WrongArgCount xobj expected actual) =
"You used the wrong number of arguments in '" ++ getName xobj ++ "' at "
++ prettyInfoFromXObj xobj
++ ". I expected "
++ show expected
++ ", but got "
++ show actual
++ "."
show (NotAFunction xobj) =
"You are trying to call the non-function `" ++ getName xobj ++ "` at "
++ prettyInfoFromXObj xobj
++ "."
show (NoStatementsInDo xobj) =
"There are no expressions inside of the `do` statement at "
++ prettyInfoFromXObj xobj
++ ".\n\nAll instances of `do` need to have one or more expressions in it."
show (TooManyFormsInBody xobj) =
"There are too many expressions in the body of the form at "
++ prettyInfoFromXObj xobj
++ ".\n\nTry wrapping them in a `do`."
show (NoFormsInBody xobj) =
"There are no expressions in the body of the form at "
++ prettyInfoFromXObj xobj
++ ".\n\nI need exactly one body form. For multiple forms, try using `do`."
show (UnificationFailed (Constraint a b aObj bObj ctx _) mappings _) =
"I can’t match the types `" ++ showTy a ++ "` and `" ++ showTy b ++ "`."
++ extra
++ showObj aObj
++ showObj bObj
where
-- ++ "Constraint: " ++ show constraint ++ "\n\n"
-- "All constraints:\n" ++ show constraints ++ "\n\n" ++
-- "Mappings: \n" ++ show mappings ++ "\n\n"
extra = if ctx == aObj || ctx == bObj then "" else " within `" ++ snip (pretty ctx) ++ "`"
snip s =
if length s > 25
then take 15 s ++ " ... " ++ drop (length s - 5) s
else s
beautifulTy = beautifyTy mappings . recursiveLookupTy mappings
showTy = show . beautifulTy
showObjTy = fromMaybe "Type missing" . fmap showTy . xobjTy
showObj o =
"\n\n " ++ pretty o ++ " : " ++ showObjTy o
++ "\n At "
++ prettyInfoFromXObj o
++ ""
show (CantDisambiguate xobj originalName theType options) =
"I found an ambiguous symbol `" ++ originalName ++ "` of type `"
++ show theType
++ "` at "
++ prettyInfoFromXObj xobj
++ "\nPossibilities:\n "
++ joinWith "\n " (map (\(t, p) -> show p ++ " : " ++ show t) options)
show (CantDisambiguateInterfaceLookup xobj name theType options) =
"I found an ambiguous interface `" ++ name ++ "` of type `"
++ show theType
++ "` at "
++ prettyInfoFromXObj xobj
++ "\nPossibilities:\n "
++ joinWith "\n " (map (\(t, p) -> show p ++ " : " ++ show t) options)
show (SeveralExactMatches xobj name theType options) =
"There are several exact matches for the interface `" ++ name
++ "` of type `"
++ show theType
++ "` at "
++ prettyInfoFromXObj xobj
++ "\nPossibilities:\n "
++ joinWith "\n " (map (\(t, p) -> show p ++ " : " ++ show t) options)
show (NoMatchingSignature xobj originalName theType options) =
"I can’t find any implementation for the interface `" ++ originalName
++ "` of type "
++ show theType
++ " at "
++ prettyInfoFromXObj xobj
++ ".\n\nNone of the possibilities have the correct signature:\n "
++ joinWith
"\n "
(map (\(t, p) -> show p ++ " : " ++ show t) options)
show (LeadingColon xobj) =
"I found a symbol '" ++ pretty xobj ++ "' that starts with a colon at "
++ prettyInfoFromXObj xobj
++ ".\n\nThis is disallowed."
show (HolesFound holes) =
"I found the following holes:\n\n "
++ joinWith "\n " (map (\(name, t) -> name ++ " : " ++ show t) holes)
++ "\n"
show (NotAValidType xobj) =
pretty xobj ++ "is not a valid type at " ++ prettyInfoFromXObj xobj
show (FunctionsCantReturnRefTy xobj t) =
"Functions can’t return references. " ++ getName xobj ++ " : " ++ show t
++ " at "
++ prettyInfoFromXObj xobj
++ "\n\nYou’ll have to copy the return value using `@`."
show (LetCantReturnRefTy xobj t) =
"`let` expressions can’t return references. " ++ pretty xobj ++ " : "
++ show t
++ " at "
++ prettyInfoFromXObj xobj
++ "\n\nYou’ll have to copy the return value using `@`."
show (GettingReferenceToUnownedValue xobj) =
"You’re referencing a given-away value `" ++ pretty xobj ++ "` at "
++ prettyInfoFromXObj xobj --"' (expression " ++ freshVar i ++ ") at " ++
++ "\n"
++ show xobj
++ "\n\nYou’ll have to copy the value using `@`."
show (UsingUnownedValue xobj) =
"You’re using a given-away value `" ++ pretty xobj ++ "` at "
++ prettyInfoFromXObj xobj
++ ".\n\nYou’ll have to copy the value using `@`."
show (UsingCapturedValue xobj) =
"You’re using a value `" ++ pretty xobj
++ "` that was captured by a function at "
++ prettyInfoFromXObj xobj
++ "."
show (ArraysCannotContainRefs xobj) =
"Arrays can’t contain references: `" ++ pretty xobj ++ "` at "
++ prettyInfoFromXObj xobj
++ ".\n\nYou’ll have to make a copy using `@`."
show (MainCanOnlyReturnUnitOrInt _ t) =
"The main function can only return an `Int` or a unit type (`()`), but it got `"
++ show t
++ "`."
show (MainCannotHaveArguments _ c) =
"The main function may not receive arguments, but it got " ++ show c ++ "."
show (CannotConcretize xobj) =
"I’m unable to concretize the expression '" ++ pretty xobj ++ "' at "
++ prettyInfoFromXObj xobj
++ ".\n\nIt might be too general. You could try adding a type hint using `the`."
show (TooManyAnnotateCalls xobj) =
"There were too many annotation calls when annotating `" ++ pretty xobj
++ "` at "
++ prettyInfoFromXObj xobj
++ ".\n\n I deduced it was an infinite loop."
show (NotAType xobj) =
"I don’t understand the type '" ++ pretty xobj ++ "' at "
++ prettyInfoFromXObj xobj
++ "\n\nIs it defined?"
show (CannotSet xobj) =
"I can’t `set!` the expression `" ++ pretty xobj ++ "` at "
++ prettyInfoFromXObj xobj
++ ".\n\nOnly variables can be reset using `set!`."
show (CannotSetVariableFromLambda variable _) =
"I can’t `set!` the variable `" ++ pretty variable ++ "` at "
++ prettyInfoFromXObj variable
++ " because it's defined outside the lambda."
show (DoesNotMatchSignatureAnnotation xobj sigTy) =
"The definition at " ++ prettyInfoFromXObj xobj
++ " does not match its annotation provided to `sig` as `"
++ show sigTy
++ "`, its actual type is `"
++ show (forceTy xobj)
++ "`."
show (CannotMatch xobj) =
"I can’t `match` `" ++ pretty xobj ++ "` at " ++ prettyInfoFromXObj xobj
++ ".\n\nOnly sumtypes can be matched against."
show (InvalidSumtypeCase xobj) =
"I failed to read `" ++ pretty xobj ++ "` as a sumtype case at "
++ prettyInfoFromXObj xobj
++ ".\n\nSumtype cases look like this: `(Foo [Int typevar])`"
show (InvalidMemberType t xobj) =
"I can’t use the type `" ++ show t ++ "` as a member type at "
++ prettyInfoFromXObj xobj
++ ".\n\nIs it defined and captured in the head of the type definition?"
show (InvalidMemberTypeWhenConcretizing t xobj err) =
"I can’t use the concrete type `" ++ show t ++ "` at " ++ prettyInfoFromXObj xobj ++ ": " ++ show err
show (NotAmongRegisteredTypes t xobj) =
"I can’t find a definition for the type `" ++ show t ++ "` at "
++ prettyInfoFromXObj xobj
++ ".\n\nWas it registered?"
show (UnevenMembers xobjs) =
"The number of members and types is uneven: `"
++ joinWithComma (map pretty xobjs)
++ "` at "
++ prettyInfoFromXObj (head xobjs)
++ ".\n\nBecause they are pairs of names and their types, they need to be even.\nDid you forget a name or type?"
show (DuplicatedMembers xobjs) =
"Duplicate members: `"
++ joinWithComma (map pretty xobjs)
++ "` at "
++ prettyInfoFromXObj (head xobjs)
show (InvalidLetBinding xobjs (sym, expr)) =
"The binding `[" ++ pretty sym ++ " " ++ pretty expr ++ "]` is invalid at "
++ prettyInfoFromXObj (head xobjs)
++ ". \n\n Binding names must be symbols."
show (DuplicateBinding xobj) =
"I encountered a duplicate binding `" ++ pretty xobj ++ "` inside the `let` at " ++ prettyInfoFromXObj xobj ++ "."
show (DefinitionsMustBeAtToplevel xobj) =
"I encountered a definition that was not at top level: `" ++ pretty xobj ++ "`"
show (UsingDeadReference xobj dependsOn) =
"The reference '" ++ pretty xobj ++ "' (depending on the variable '" ++ dependsOn ++ "') isn't alive at " ++ prettyInfoFromXObj xobj ++ "."
show (UninhabitedConstructor ty xobj got wanted) =
"Can't use a struct or sumtype constructor without arguments as a member type at " ++ prettyInfoFromXObj xobj ++ ". The type constructor " ++ show ty ++ " expects " ++ show wanted ++ " arguments but got " ++ show got
show (InconsistentKinds varName xobjs) =
" The type variable `" ++ varName ++ "` is used inconsistently: " ++ joinWithComma (map pretty (filter (doesTypeContainTyVarWithName varName . fromMaybe Universe . xobjToTy) xobjs)) ++ " Type variables must be applied to the same number of arguments."
show (FailedToAddLambdaStructToTyEnv path xobj) =
"Failed to add the lambda: " ++ show path ++ " represented by struct: "
++ pretty xobj
++ " to the type environment."
machineReadableErrorStrings :: FilePathPrintLength -> TypeError -> [String]
machineReadableErrorStrings fppl err =
case err of
(UnificationFailed (Constraint a b aObj bObj _ _) mappings _) ->
[ machineReadableInfoFromXObj fppl aObj ++ " Inferred " ++ showTypeFromXObj mappings aObj ++ ", can't unify with " ++ show (recursiveLookupTy mappings b) ++ ".",
machineReadableInfoFromXObj fppl bObj ++ " Inferred " ++ showTypeFromXObj mappings bObj ++ ", can't unify with " ++ show (recursiveLookupTy mappings a) ++ "."
]
(DefnMissingType xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Function definition '" ++ getName xobj ++ "' missing type."]
(DefMissingType xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Variable definition '" ++ getName xobj ++ "' missing type."]
(ExpressionMissingType xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Expression '" ++ pretty xobj ++ "' missing type."]
(SymbolNotDefined symPath xobj _) ->
[machineReadableInfoFromXObj fppl xobj ++ " Trying to refer to an undefined symbol '" ++ show symPath ++ "'."]
(SymbolMissingType xobj _) ->
[machineReadableInfoFromXObj fppl xobj ++ " Symbol '" ++ getName xobj ++ "' missing type."]
(InvalidObj (Defn _) xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Invalid function definition."]
(InvalidObj If xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Invalid if-statement."]
(InvalidObj o xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Invalid obj '" ++ show o ++ "'."]
(CantUseDerefOutsideFunctionApplication xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Can't use 'deref' / '~' outside function application."]
(WrongArgCount xobj expected actual) ->
[machineReadableInfoFromXObj fppl xobj ++ " Wrong argument count in call to '" ++ getName xobj ++ "' (expected " ++ show expected ++ ", received " ++ show actual ++ ")."]
(NotAFunction xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Trying to call non-function '" ++ getName xobj ++ "'."]
(NoStatementsInDo xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " The do-statement has no expressions inside of it."]
(TooManyFormsInBody xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Too many expressions in body position."]
(NoFormsInBody xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " No expressions in body position."]
(CantDisambiguate xobj originalName theType options) ->
[ machineReadableInfoFromXObj fppl xobj ++ " Can't disambiguate symbol '" ++ originalName ++ "' of type " ++ show theType
++ "\nPossibilities:\n "
++ joinWith "\n " (map (\(t, p) -> show p ++ " : " ++ show t) options)
]
(CantDisambiguateInterfaceLookup xobj name theType options) ->
[ machineReadableInfoFromXObj fppl xobj ++ " Can't disambiguate interface lookup symbol '" ++ name ++ "' of type " ++ show theType
++ "\nPossibilities:\n "
++ joinWith "\n " (map (\(t, p) -> show p ++ " : " ++ show t) options)
]
(SeveralExactMatches xobj name theType options) ->
[machineReadableInfoFromXObj fppl xobj ++ " Several exact matches for interface lookup symbol '" ++ name ++ "' of type " ++ show theType ++ "\nPossibilities:\n " ++ joinWith "\n " (map (\(t, p) -> show p ++ " : " ++ show t) options)]
(NoMatchingSignature xobj originalName theType options) ->
[ machineReadableInfoFromXObj fppl xobj ++ " Can't find matching lookup for symbol '" ++ originalName ++ "' of type " ++ show theType
++ "\nNone of the possibilities have the correct signature:\n "
++ joinWith
"\n "
(map (\(t, p) -> show p ++ " : " ++ show t) options)
]
(LeadingColon xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Symbol '" ++ pretty xobj ++ "' starting with a colon (reserved for REPL shortcuts)."]
-- (HolesFound holes) ->
-- (map (\(name, t) -> machineReadableInfoFromXObj fppl xobj ++ " " ++ name ++ " : " ++ show t) holes)
-- TODO: Remove overlapping errors:
(NotAValidType xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Not a valid type: " ++ pretty xobj ++ "."]
(NotAType xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Can't understand the type '" ++ pretty xobj ++ "'."]
(FunctionsCantReturnRefTy xobj t) ->
[machineReadableInfoFromXObj fppl xobj ++ " Functions can't return references. " ++ getName xobj ++ " : " ++ show t ++ "."]
(LetCantReturnRefTy xobj t) ->
[machineReadableInfoFromXObj fppl xobj ++ " Let-expressions can't return references. '" ++ pretty xobj ++ "' : " ++ show t ++ "."]
(GettingReferenceToUnownedValue xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Referencing a given-away value '" ++ pretty xobj ++ "'."]
(UsingUnownedValue xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Using a given-away value '" ++ pretty xobj ++ "'."]
(UsingCapturedValue xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Using a captured value '" ++ pretty xobj ++ "'."]
(ArraysCannotContainRefs xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Arrays can't contain references: '" ++ pretty xobj ++ "'."]
(MainCanOnlyReturnUnitOrInt xobj t) ->
[machineReadableInfoFromXObj fppl xobj ++ " Main function can only return Int or (), got " ++ show t ++ "."]
(MainCannotHaveArguments xobj c) ->
[machineReadableInfoFromXObj fppl xobj ++ " Main function can not have arguments, got " ++ show c ++ "."]
(TooManyAnnotateCalls xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Too many annotate calls (infinite loop) when annotating '" ++ pretty xobj ++ "'."]
(CannotSet xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Can't set! '" ++ pretty xobj ++ "'."]
(CannotSetVariableFromLambda variable _) ->
[machineReadableInfoFromXObj fppl variable ++ " Can't set! '" ++ pretty variable ++ "' from inside of a lambda."]
(CannotConcretize xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Unable to concretize '" ++ pretty xobj ++ "'."]
(DoesNotMatchSignatureAnnotation xobj sigTy) ->
[machineReadableInfoFromXObj fppl xobj ++ "Definition does not match 'sig' annotation " ++ show sigTy ++ ", actual type is " ++ show (forceTy xobj)]
(CannotMatch xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Can't match '" ++ pretty xobj ++ "'."]
(InvalidSumtypeCase xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Failed to convert '" ++ pretty xobj ++ "' to a sumtype case."]
(InvalidMemberType t xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Can't use '" ++ show t ++ "' as a type for a member variable."]
(NotAmongRegisteredTypes t xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " The type '" ++ show t ++ "' isn't defined."]
(UnevenMembers xobjs) ->
[machineReadableInfoFromXObj fppl (head xobjs) ++ " Uneven nr of members / types: " ++ joinWithComma (map pretty xobjs)]
(InvalidLetBinding xobjs (sym, expr)) ->
[machineReadableInfoFromXObj fppl (head xobjs) ++ "Invalid let binding `" ++ pretty sym ++ pretty expr ++ "` at " ++ joinWithComma (map pretty xobjs)]
(DuplicateBinding xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Duplicate binding `" ++ pretty xobj ++ "` inside `let`."]
(DefinitionsMustBeAtToplevel xobj) ->
[machineReadableInfoFromXObj fppl xobj ++ " Definition not at top level: `" ++ pretty xobj ++ "`"]
(UsingDeadReference xobj _) ->
[machineReadableInfoFromXObj fppl xobj ++ " The reference '" ++ pretty xobj ++ "' isn't alive."]
(UninhabitedConstructor ty xobj got wanted) ->
[machineReadableInfoFromXObj fppl xobj ++ "Can't use a struct or sumtype constructor without arguments as a member type at " ++ prettyInfoFromXObj xobj ++ ". The type constructor " ++ show ty ++ " expects " ++ show wanted ++ " arguments but got " ++ show got]
(InconsistentKinds varName xobjs) ->
[machineReadableInfoFromXObj fppl (head xobjs) ++ " The type variable `" ++ varName ++ "` is used inconsistently: " ++ joinWithComma (map pretty (filter (doesTypeContainTyVarWithName varName . fromMaybe Universe . xobjToTy) xobjs)) ++ " Type variables must be applied to the same number of arguments."]
(FailedToAddLambdaStructToTyEnv path xobj) ->
[ machineReadableInfoFromXObj fppl xobj ++ "Failed to add the lambda: " ++ show path ++ " represented by struct: "
++ pretty xobj
++ " to the type environment."
]
_ ->
[show err]
joinedMachineReadableErrorStrings :: FilePathPrintLength -> TypeError -> String
joinedMachineReadableErrorStrings fppl err = joinWith "\n\n" (machineReadableErrorStrings fppl err)
recursiveLookupTy :: TypeMappings -> Ty -> Ty
recursiveLookupTy mappings t = case t of
(VarTy v) -> fromMaybe t (recursiveNameLookup mappings v)
(RefTy r lt) -> RefTy (recursiveLookupTy mappings r) (recursiveLookupTy mappings lt)
(PointerTy p) -> PointerTy (recursiveLookupTy mappings p)
(StructTy n innerTys) -> StructTy n (map (recursiveLookupTy mappings) innerTys)
(FuncTy argTys retTy ltTy) ->
FuncTy
(map (recursiveLookupTy mappings) argTys)
(recursiveLookupTy mappings retTy)
(recursiveLookupTy mappings ltTy)
_ -> t
showTypeFromXObj :: TypeMappings -> XObj -> String
showTypeFromXObj mappings xobj =
case xobjTy xobj of
Just t -> show (recursiveLookupTy mappings t)
Nothing -> "Type missing"
evalError :: Context -> String -> Maybe Info -> (Context, Either EvalError a)
evalError ctx = makeEvalError ctx Nothing
-- | Print type errors correctly when running the compiler in 'Check' mode
makeEvalError :: Context -> Maybe TypeError -> String -> Maybe Info -> (Context, Either EvalError a)
makeEvalError ctx err msg info =
let fppl = projectFilePathPrintLength (contextProj ctx)
history = contextHistory ctx
in case contextExecMode ctx of
Check ->
let messageWhenChecking = case err of
Just okErr -> joinedMachineReadableErrorStrings fppl okErr
Nothing ->
case info of
Just okInfo -> machineReadableInfo fppl okInfo ++ " " ++ msg
Nothing -> msg
in (ctx, Left (EvalError messageWhenChecking [] fppl Nothing)) -- Passing no history to avoid appending it at the end in 'show' instance for EvalError
_ -> (ctx, Left (EvalError msg history fppl info))
-- | Converts a TypeError to a string, taking contextExecMode/fppl into account
typeErrorToString :: Context -> TypeError -> String
typeErrorToString ctx err =
let fppl = projectFilePathPrintLength (contextProj ctx)
in case contextExecMode ctx of
Check -> joinedMachineReadableErrorStrings fppl err
_ -> show err
keysInEnvEditDistance :: SymPath -> Env -> Int -> [String]
keysInEnvEditDistance (SymPath [] name) env distance =
let candidates = Map.filterWithKey (\k _ -> levenshteinDistance defaultEditCosts k name < distance) (envBindings env)
in Map.keys candidates
keysInEnvEditDistance path@(SymPath (p : ps) name) env distance =
case Map.lookup p (envBindings env) of
Just (Binder _ xobj) ->
case xobj of
(XObj (Mod modEnv _) _ _) -> keysInEnvEditDistance (SymPath ps name) modEnv distance
_ -> []
Nothing ->
case envParent env of
Just parent -> keysInEnvEditDistance path parent distance
Nothing -> []
beautifyTy :: TypeMappings -> Ty -> Ty
beautifyTy mappings = f
where
f :: Ty -> Ty
f (FuncTy argTys retTy lifetime) = FuncTy (f <$> argTys) (f retTy) (f lifetime)
f (StructTy n typeArgs) = StructTy n (f <$> typeArgs)
f (RefTy innerTy lifetime) = RefTy (f innerTy) (f lifetime)
f (PointerTy innerTy) = PointerTy $ f innerTy
f t@(VarTy n) = case Map.lookup n bmappings of
Just nn -> VarTy nn
Nothing -> t
f t = t
bmappings = beautification mappings
beautification :: TypeMappings -> Map.Map String String
beautification m =
Map.fromList $ zip (map (\(VarTy name) -> name) tys) beautList
where
tys = nub $ concat $ typeVariablesInOrderOfAppearance <$> tys'
tys' = snd <$> Map.assocs m
beautList = [c : s | s <- "" : beautList, c <- ['a' .. 'z']]
typeVariablesInOrderOfAppearance :: Ty -> [Ty]
typeVariablesInOrderOfAppearance (FuncTy argTys retTy ltTy) =
concatMap typeVariablesInOrderOfAppearance argTys ++ typeVariablesInOrderOfAppearance retTy ++ typeVariablesInOrderOfAppearance ltTy
typeVariablesInOrderOfAppearance (StructTy n typeArgs) =
case n of
t@(VarTy _) -> typeVariablesInOrderOfAppearance t ++ concatMap typeVariablesInOrderOfAppearance typeArgs
_ -> concatMap typeVariablesInOrderOfAppearance typeArgs
typeVariablesInOrderOfAppearance (RefTy innerTy lifetimeTy) =
typeVariablesInOrderOfAppearance innerTy ++ typeVariablesInOrderOfAppearance lifetimeTy
typeVariablesInOrderOfAppearance (PointerTy innerTy) =
typeVariablesInOrderOfAppearance innerTy
typeVariablesInOrderOfAppearance t@(VarTy _) =
[t]
typeVariablesInOrderOfAppearance _ =
[]