on master help sign in
Give hints for mismatches with rigid and super variables
20b254cEvan Czaplicki
src/Reporting/Error/Type.hs+68−22
@@ -39,10 +39,14 @@ data Mismatch = MismatchInfo
39
39
40data Reason
40data Reason
41 = MessyFields [String] [String]
41 = MessyFields [String] [String]
42− | NotRecord
42+ | NotNumber
43+ | NotComparable
44+ | NotAppendable
45+ | NotCompAppend
46+ | IntFloat
43 | TooLongComparableTuple Int
47 | TooLongComparableTuple Int
44 | Rigid (Maybe String)
48 | Rigid (Maybe String)
45− deriving (Show)
49+ | DoubleRigid
46
50
47
51
48data Hint
52data Hint
@@ -117,7 +121,7 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType maybeReason) =
117 cmpHint leftWords rightWords extraHints =
121 cmpHint leftWords rightWords extraHints =
118 comparisonHint localizer leftType rightType leftWords rightWords
122 comparisonHint localizer leftType rightType leftWords rightWords
119 ( map toHint extraHints
123 ( map toHint extraHints
120− ++ Maybe.maybeToList (fmap reasonToString maybeReason)
124+ ++ Maybe.maybeToList (reasonToString =<< maybeReason)
121 )
125 )
122 in
126 in
123 case hint of
127 case hint of
@@ -141,7 +145,10 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType maybeReason) =
141 ( "All the branches of this case-expression are consistent, but the overall\n"
145 ( "All the branches of this case-expression are consistent, but the overall\n"
142 ++ "type does not match how it is used elsewhere."
146 ++ "type does not match how it is used elsewhere."
143 )
147 )
144− ( error "TODO generic error"
148+ ( cmpHint
149+ "The `case` evaluates to something of type:"
150+ "Which is fine, but the surrounding context wants it to be:"
151+ []
145 )
152 )
146
153
147 IfCondition ->
154 IfCondition ->
@@ -340,7 +347,10 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType maybeReason) =
340 report
347 report
341 Nothing
348 Nothing
342 "There is some problem with this GLSL shader."
349 "There is some problem with this GLSL shader."
343− ( error "TODO generic error"
350+ ( cmpHint
351+ "The shader block has this type:"
352+ "Which is fine, but the surrounding context wants it to be:"
353+ []
344 )
354 )
345
355
346 Range ->
356 Range ->
@@ -425,31 +435,67 @@ funcName maybeVar =
425-- MISMTACH REASONS
435-- MISMTACH REASONS
426
436
427
437
428−reasonToString :: Reason -> Doc
438+reasonToString :: Reason -> Maybe Doc
429reasonToString reason =
439reasonToString reason =
440+ let
441+ go msg =
442+ Just (toHint msg)
443+ in
430 case reason of
444 case reason of
431 MessyFields leftOnly rightOnly ->
445 MessyFields leftOnly rightOnly ->
432− let
433− maybeMessage =
434− do let typos = RenderType.findPotentialTypos leftOnly rightOnly
446+ do let typos = RenderType.findPotentialTypos leftOnly rightOnly
435− RenderType.vetTypos typos
447+ _ <- RenderType.vetTypos typos
436− misspellingMessage typos
448+ misspellingMessage typos
437− in
449+
438− case maybeMessage of
450+ NotNumber ->
439− Just doc ->
451+ go "Valid number types include Int and Float."
440− doc
452+
453+ NotComparable ->
454+ go "Valid comparable types include Int, Float, Char, String, lists, and tuples."
441
455
442− Nothing ->
456+ NotAppendable ->
443− error "TODO"
457+ go "Valid appendable types include String, Text, and List."
444
458
445− NotRecord ->
459+ NotCompAppend ->
446− toHint "A record cannot be merged with other types of values."
460+ go "Valid `number` types include Int and Float."
461+
462+ IntFloat ->
463+ go
464+ "Elm does not automatically convert between Ints and Floats. Use\
465+ \ `toFloat` and `round` to do specific conversions.\
466+ \ <http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#toFloat>"
447
467
448 TooLongComparableTuple len ->
468 TooLongComparableTuple len ->
449− error "TODO"
469+ go $
470+ "Although tuples are comparable, this is currently only supported\
471+ \ for tuples with 6 or fewer entries, not " ++ show len ++ "."
472+
473+ Rigid (Just name) ->
474+ go $
475+ "It is very likely that a type annotation is too generic. Type variable\
476+ \ `" ++ name ++ "` is saying *many* kinds of value can be given, but the\
477+ \ actual definition needs a more specific type. I am not sure whether the\
478+ \ type annotation or the definition is \"right\" though, you may have to\
479+ \ make the annotation more specific or make the definition more generic."
480+
481+ Rigid Nothing ->
482+ go $
483+ "It is very likely that a type annotation is too generic. One type is saying\
484+ \ *many* kinds of value can be given, but the other needs a more specific type."
485+
486+ DoubleRigid ->
487+ Just $ Help.stack $
488+ [ hintDoc <> text "This usually happens when a few factors come together."
489+ , indent 4 $ vcat $
490+ [ text "1. You have a generic function with a type annotation."
491+ , text "2. In its definition, there is a `let` with generic type annotations."
492+ ]
493+ , Help.reflowParagraph
494+ "The issue is that these type variables are not actually shared between\
495+ \ outer and inner type annotations right now. You can usually fix this by\
496+ \ commenting out the inner type annotations."
497+ ]
450
498
451− Rigid maybeName ->
452− error "TODO"
453
499
454
500
455hintDoc :: Doc
501hintDoc :: Doc
src/Type/Constrain/Expression.hs+1−1
@@ -56,7 +56,7 @@ constrain env annotatedExpr@(A.A region expression) tipe =
56 uniform = makeRec Lit.uniform unif
56 uniform = makeRec Lit.uniform unif
57 varying = makeRec Lit.varying (TermN EmptyRecord1)
57 varying = makeRec Lit.varying (TermN EmptyRecord1)
58 in
58 in
59− return (CEqual Error.Shader region tipe (shaderTipe attribute uniform varying))
59+ return (CEqual Error.Shader region (shaderTipe attribute uniform varying) tipe)
60
60
61 E.Var var ->
61 E.Var var ->
62 let name = V.toString var
62 let name = V.toString var
src/Type/Unify.hs+27−26
@@ -221,7 +221,7 @@ unifyRigid context maybeSuper maybeName otherContent =
221 rigidityError context maybeName
221 rigidityError context maybeName
222
222
223 Var Rigid _ _ ->
223 Var Rigid _ _ ->
224− rigidityError context maybeName
224+ mismatch context (Just Error.DoubleRigid)
225
225
226 Atom _ ->
226 Atom _ ->
227 rigidityError context maybeName
227 rigidityError context maybeName
@@ -246,7 +246,7 @@ unifySuper context super otherContent =
246 if atomMatchesSuper super name then
246 if atomMatchesSuper super name then
247 merge context otherContent
247 merge context otherContent
248 else
248 else
249− mismatch context Nothing
249+ mismatch context (Just (superReason super))
250
250
251 Var Rigid Nothing maybeName ->
251 Var Rigid Nothing maybeName ->
252 rigidityError context maybeName
252 rigidityError context maybeName
@@ -297,6 +297,22 @@ combineSupers firstSuper secondSuper =
297 (_ , _ ) -> Nothing
297 (_ , _ ) -> Nothing
298
298
299
299
300+superReason :: Super -> Error.Reason
301+superReason super =
302+ case super of
303+ Number ->
304+ Error.NotNumber
305+
306+ Comparable ->
307+ Error.NotComparable
308+
309+ Appendable ->
310+ Error.NotAppendable
311+
312+ CompAppend ->
313+ Error.NotCompAppend
314+
315+
300isPrimitiveFrom :: [String] -> Var.Canonical -> Bool
316isPrimitiveFrom :: [String] -> Var.Canonical -> Bool
301isPrimitiveFrom prims var =
317isPrimitiveFrom prims var =
302 any (\p -> Var.isPrim p var) prims
318 any (\p -> Var.isPrim p var) prims
@@ -323,12 +339,12 @@ unifySuperStructure context super term =
323 do appStructure <- liftIO (collectApps (Structure term))
339 do appStructure <- liftIO (collectApps (Structure term))
324 case appStructure of
340 case appStructure of
325 Other ->
341 Other ->
326− mismatch context Nothing
342+ mismatch context (Just (superReason super))
327
343
328 List variable ->
344 List variable ->
329 case super of
345 case super of
330 Number ->
346 Number ->
331− mismatch context Nothing
347+ mismatch context (Just Error.NotNumber)
332
348
333 Appendable ->
349 Appendable ->
334 merge context (Structure term)
350 merge context (Structure term)
@@ -344,10 +360,10 @@ unifySuperStructure context super term =
344 Tuple entries ->
360 Tuple entries ->
345 case super of
361 case super of
346 Number ->
362 Number ->
347− mismatch context Nothing
363+ mismatch context (Just Error.NotNumber)
348
364
349 Appendable ->
365 Appendable ->
350− mismatch context Nothing
366+ mismatch context (Just Error.NotAppendable)
351
367
352 Comparable ->
368 Comparable ->
353 if length entries > 6 then
369 if length entries > 6 then
@@ -358,7 +374,7 @@ unifySuperStructure context super term =
358 mapM_ (unifyComparableRecursive (_orientation context)) entries
374 mapM_ (unifyComparableRecursive (_orientation context)) entries
359
375
360 CompAppend ->
376 CompAppend ->
361− mismatch context Nothing
377+ mismatch context (Just Error.NotCompAppend)
362
378
363
379
364unifyComparableRecursive :: Orientation -> Variable -> Unify ()
380unifyComparableRecursive :: Orientation -> Variable -> Unify ()
@@ -427,7 +443,7 @@ unifyAtom context name otherContent =
427 merge context (Atom name)
443 merge context (Atom name)
428
444
429 else
445 else
430− mismatch context Nothing
446+ mismatch context (Just (superReason super))
431
447
432 Var Rigid _ maybeName ->
448 Var Rigid _ maybeName ->
433 rigidityError context maybeName
449 rigidityError context maybeName
@@ -606,28 +622,13 @@ gatherFields context fields variable =
606 Structure (Record1 subFields subExt) ->
622 Structure (Record1 subFields subExt) ->
607 gatherFields context (Map.union fields subFields) subExt
623 gatherFields context (Map.union fields subFields) subExt
608
624
609− Structure (EmptyRecord1) ->
625+ Structure EmptyRecord1 ->
610 return (RecordStructure fields variable Empty)
626 return (RecordStructure fields variable Empty)
611
627
612− Structure (App1 _ _) ->
613− mismatch context (Just Error.NotRecord)
614−
615− Structure (Fun1 _ _) ->
616− mismatch context (Just Error.NotRecord)
617−
618− Atom _ ->
619− mismatch context (Just Error.NotRecord)
620−
621− Var _ Nothing _ ->
622− return (RecordStructure fields variable Extension)
623−
624− Var _ (Just _) _ ->
625− mismatch context (Just Error.NotRecord)
626−
627− -- TODO may be dropping useful alias info here
628 Alias _ _ var ->
628 Alias _ _ var ->
629+ -- TODO may be dropping useful alias info here
629 gatherFields context fields var
630 gatherFields context fields var
630
631
631− Error ->
632+ _ ->
632 return (RecordStructure fields variable Extension)
633 return (RecordStructure fields variable Extension)
633
634