@@ -5,7 +5,6 @@ module Type.Error
5 , Super(..)
5 , Super(..)
6 , Extension(..)
6 , Extension(..)
7 , iteratedDealias
7 , iteratedDealias
10 , toDiffDocs
9 , toDiffDocs
11 , Problem(..)
10 , Problem(..)
@@ -20,13 +19,13 @@ module Type.Error
21import qualified Data.Map as Map
20import qualified Data.Map as Map
22import qualified Data.Maybe as Maybe
21import qualified Data.Maybe as Maybe
23−import Data.Monoid ((<>))
25import qualified AST.Module.Name as ModuleName
23import qualified AST.Module.Name as ModuleName
26import qualified Data.Bag as Bag
24import qualified Data.Bag as Bag
27import qualified Elm.Name as N
25import qualified Elm.Name as N
28import qualified Reporting.Doc as D
26import qualified Reporting.Doc as D
29import qualified Reporting.Render.Type as RT
27import qualified Reporting.Render.Type as RT
28+import qualified Reporting.Render.Type.Localizer as L
@@ -75,27 +74,19 @@ iteratedDealias tipe =
78−type Localizer = Map.Map (ModuleName.Canonical, N.Name) String
77+nameToDoc :: L.Localizer -> ModuleName.Canonical -> N.Name -> D.Doc
78+nameToDoc localizer (ModuleName.Canonical _ home) name =
79+ L.toDoc localizer home name
81−nameToDoc :: Localizer -> ModuleName.Canonical -> N.Name -> D.Doc
82−nameToDoc dict home@(ModuleName.Canonical _ moduleName) name =
83− case Map.lookup (home, name) dict of
85− D.fromName moduleName <> "." <> D.fromName name
91−toDoc :: Localizer -> RT.Context -> Type -> D.Doc
82+toDoc :: L.Localizer -> RT.Context -> Type -> D.Doc
92−toDoc dict ctx tipe =
83+toDoc localizer ctx tipe =
93 case tipe of
84 case tipe of
94 Lambda a b cs ->
85 Lambda a b cs ->
95 RT.lambda ctx
86 RT.lambda ctx
96− (toDoc dict RT.Func a)
87+ (toDoc localizer RT.Func a)
97− (toDoc dict RT.Func b)
88+ (toDoc localizer RT.Func b)
98− (map (toDoc dict RT.Func) cs)
89+ (map (toDoc localizer RT.Func) cs)
100 Infinite ->
91 Infinite ->
@@ -117,13 +108,13 @@ toDoc dict ctx tipe =
118 Type home name args ->
109 Type home name args ->
119 RT.apply ctx
110 RT.apply ctx
120− (nameToDoc dict home name)
111+ (nameToDoc localizer home name)
121− (map (toDoc dict RT.App) args)
112+ (map (toDoc localizer RT.App) args)
123 Record fields ext ->
114 Record fields ext ->
125 entryToDocs (fieldName, fieldType) =
116 entryToDocs (fieldName, fieldType) =
126− ( D.fromName fieldName, toDoc dict RT.None fieldType )
117+ ( D.fromName fieldName, toDoc localizer RT.None fieldType )
128 fieldDocs =
119 fieldDocs =
129 map entryToDocs (Map.toList fields)
120 map entryToDocs (Map.toList fields)
@@ -139,23 +130,23 @@ toDoc dict ctx tipe =
140 Tuple a b maybeC ->
131 Tuple a b maybeC ->
142− (toDoc dict RT.None a)
133+ (toDoc localizer RT.None a)
143− (toDoc dict RT.None b)
134+ (toDoc localizer RT.None b)
144− (map (toDoc dict RT.None) (Maybe.maybeToList maybeC))
135+ (map (toDoc localizer RT.None) (Maybe.maybeToList maybeC))
146 Alias home name args _ ->
137 Alias home name args _ ->
147 RT.apply ctx
138 RT.apply ctx
148− (nameToDoc dict home name)
139+ (nameToDoc localizer home name)
149− (map (toDoc dict RT.App . snd) args)
140+ (map (toDoc localizer RT.App . snd) args)
156−toDiffDocs :: Localizer -> Type -> Type -> (D.Doc, D.Doc, [Problem])
147+toDiffDocs :: L.Localizer -> Type -> Type -> (D.Doc, D.Doc, [Problem])
157−toDiffDocs dict a b =
148+toDiffDocs localizer a b =
158− case diff dict RT.None a b of
149+ case diff localizer RT.None a b of
159 Similar aDoc bDoc ->
150 Similar aDoc bDoc ->
160 (aDoc, bDoc, [])
151 (aDoc, bDoc, [])
@@ -217,8 +208,8 @@ data Problem
217-- COMPUTE DIFF
208-- COMPUTE DIFF
220−diff :: Localizer -> RT.Context -> Type -> Type -> Diff D.Doc
211+diff :: L.Localizer -> RT.Context -> Type -> Type -> Diff D.Doc
221−diff dict ctx tipe1 tipe2 =
212+diff localizer ctx tipe1 tipe2 =
222 case (tipe1, tipe2) of
213 case (tipe1, tipe2) of
223 (FlexVar x, FlexVar y) | x == y -> pure (D.fromName x)
214 (FlexVar x, FlexVar y) | x == y -> pure (D.fromName x)
224 (FlexSuper _ x, FlexSuper _ y) | x == y -> pure (D.fromName x)
215 (FlexSuper _ x, FlexSuper _ y) | x == y -> pure (D.fromName x)
@@ -231,45 +222,45 @@ diff dict ctx tipe1 tipe2 =
232 (Tuple a b maybeC, Tuple x y maybeZ) ->
223 (Tuple a b maybeC, Tuple x y maybeZ) ->
234− <$> diff dict RT.None a x
225+ <$> diff localizer RT.None a x
235− <*> diff dict RT.None b y
226+ <*> diff localizer RT.None b y
237 case (maybeC, maybeZ) of
228 case (maybeC, maybeZ) of
238 (Nothing, Nothing) -> pure []
229 (Nothing, Nothing) -> pure []
239− (Just c , Nothing) -> Different [D.dullyellow (toDoc dict RT.None c)] [] Bag.empty
230+ (Just c , Nothing) -> Different [D.dullyellow (toDoc localizer RT.None c)] [] Bag.empty
240− (Nothing, Just z ) -> Different [] [D.dullyellow (toDoc dict RT.None z)] Bag.empty
231+ (Nothing, Just z ) -> Different [] [D.dullyellow (toDoc localizer RT.None z)] Bag.empty
241− (Just c , Just z ) -> (:[]) <$> diff dict RT.None c z
232+ (Just c , Just z ) -> (:[]) <$> diff localizer RT.None c z
243− (Record fields1 ext1, Record fields2 ext2) -> diffRecord dict fields1 ext1 fields2 ext2
234+ (Record fields1 ext1, Record fields2 ext2) -> diffRecord localizer fields1 ext1 fields2 ext2
245 (Type home1 name1 args1, Type home2 name2 args2) | home1 == home2 && name1 == name2 ->
236 (Type home1 name1 args1, Type home2 name2 args2) | home1 == home2 && name1 == name2 ->
246− RT.apply ctx (nameToDoc dict home1 name1) <$>
237+ RT.apply ctx (nameToDoc localizer home1 name1) <$>
247− sequenceA (zipWith (diff dict RT.App) args1 args2)
238+ sequenceA (zipWith (diff localizer RT.App) args1 args2)
249 (Alias home1 name1 args1 _, Alias home2 name2 args2 _) | home1 == home2 && name1 == name2 ->
240 (Alias home1 name1 args1 _, Alias home2 name2 args2 _) | home1 == home2 && name1 == name2 ->
250− RT.apply ctx (nameToDoc dict home1 name1) <$>
241+ RT.apply ctx (nameToDoc localizer home1 name1) <$>
251− sequenceA (zipWith (diff dict RT.App) (map snd args1) (map snd args2))
242+ sequenceA (zipWith (diff localizer RT.App) (map snd args1) (map snd args2))
253− (Alias _ _ _ alias1, other) -> diff dict ctx alias1 other
244+ (Alias _ _ _ alias1, other) -> diff localizer ctx alias1 other
254− (other, Alias _ _ _ alias2) -> diff dict ctx other alias2
245+ (other, Alias _ _ _ alias2) -> diff localizer ctx other alias2
256− (Lambda a b cs, Lambda x y zs) -> diffLambda dict ctx (a:b:cs) (x:y:zs)
247+ (Lambda a b cs, Lambda x y zs) -> diffLambda localizer ctx (a:b:cs) (x:y:zs)
258− (FlexVar x, other) -> Similar (D.fromName x) (toDoc dict ctx other)
249+ (FlexVar x, other) -> Similar (D.fromName x) (toDoc localizer ctx other)
259− (other, FlexVar x) -> Similar (toDoc dict ctx other) (D.fromName x)
250+ (other, FlexVar x) -> Similar (toDoc localizer ctx other) (D.fromName x)
262 case pair of
253 case pair of
263 (Type home name [t1], t2) | isMaybe home name && isSimilar t1 t2 ->
254 (Type home name [t1], t2) | isMaybe home name && isSimilar t1 t2 ->
264− Different (yellowApply dict ctx home name t1) (toDoc dict ctx t2) (Bag.one AnythingFromMaybe)
255+ Different (yellowApply localizer ctx home name t1) (toDoc localizer ctx t2) (Bag.one AnythingFromMaybe)
266 (t1, Type home name [t2]) | isList home name && isSimilar t1 t2 ->
257 (t1, Type home name [t2]) | isList home name && isSimilar t1 t2 ->
267− Different (toDoc dict ctx t1) (yellowApply dict ctx home name t2) (Bag.one AnythingToList)
258+ Different (toDoc localizer ctx t1) (yellowApply localizer ctx home name t2) (Bag.one AnythingToList)
271− doc1 = D.dullyellow (toDoc dict ctx tipe1)
262+ doc1 = D.dullyellow (toDoc localizer ctx tipe1)
272− doc2 = D.dullyellow (toDoc dict ctx tipe2)
263+ doc2 = D.dullyellow (toDoc localizer ctx tipe2)
274 Different doc1 doc2 $
265 Different doc1 doc2 $
275 case pair of
266 case pair of
@@ -329,16 +320,16 @@ isList home name =
330isSimilar :: Type -> Type -> Bool
321isSimilar :: Type -> Type -> Bool
331isSimilar tipe1 tipe2 =
322isSimilar tipe1 tipe2 =
332− case diff Map.empty RT.None tipe1 tipe2 of
323+ case diff L.empty RT.None tipe1 tipe2 of
333 Similar _ _ -> True
324 Similar _ _ -> True
334 Different _ _ _ -> False
325 Different _ _ _ -> False
337−yellowApply :: Localizer -> RT.Context -> ModuleName.Canonical -> N.Name -> Type -> D.Doc
328+yellowApply :: L.Localizer -> RT.Context -> ModuleName.Canonical -> N.Name -> Type -> D.Doc
338−yellowApply dict ctx home name tipe =
329+yellowApply localizer ctx home name tipe =
339 RT.apply ctx
330 RT.apply ctx
340− (D.dullyellow (nameToDoc dict home name))
331+ (D.dullyellow (nameToDoc localizer home name))
341− [toDoc dict RT.App tipe]
332+ [toDoc localizer RT.App tipe]
@@ -348,8 +339,8 @@ yellowApply dict ctx home name tipe =
349-- INVARIANT: length types1 >= 2 && length types2 >= 2
340-- INVARIANT: length types1 >= 2 && length types2 >= 2
351−diffLambda :: Localizer -> RT.Context -> [Type] -> [Type] -> Diff D.Doc
342+diffLambda :: L.Localizer -> RT.Context -> [Type] -> [Type] -> Diff D.Doc
352−diffLambda dict ctx types1 types2 =
343+diffLambda localizer ctx types1 types2 =
354 (result1:revArgs1) = reverse types1
345 (result1:revArgs1) = reverse types1
355 (result2:revArgs2) = reverse types2
346 (result2:revArgs2) = reverse types2
@@ -357,7 +348,7 @@ diffLambda dict ctx types1 types2 =
357 numArgs1 = length revArgs1
348 numArgs1 = length revArgs1
358 numArgs2 = length revArgs2
349 numArgs2 = length revArgs2
360− resultDiff = diff dict RT.Func result1 result2
351+ resultDiff = diff localizer RT.Func result1 result2
362 case resultDiff of
353 case resultDiff of
363 Similar resultDoc1 resultDoc2 ->
354 Similar resultDoc1 resultDoc2 ->
@@ -367,18 +358,18 @@ diffLambda dict ctx types1 types2 =
367 RT.lambda ctx x y zs
358 RT.lambda ctx x y zs
369 <$> resultDiff
360 <$> resultDiff
370− <*> sequenceA (zipWith (diff dict RT.Func) revArgs1 revArgs2)
361+ <*> sequenceA (zipWith (diff localizer RT.Func) revArgs1 revArgs2)
372 else if numArgs1 < numArgs2 then
363 else if numArgs1 < numArgs2 then
373− diffArgMismatch dict ctx revArgs1 resultDoc1 revArgs2 resultDoc2
364+ diffArgMismatch localizer ctx revArgs1 resultDoc1 revArgs2 resultDoc2
376− diffArgMismatch dict ctx revArgs2 resultDoc2 revArgs1 resultDoc1
367+ diffArgMismatch localizer ctx revArgs2 resultDoc2 revArgs1 resultDoc1
378 Different resultDoc1 resultDoc2 problems ->
369 Different resultDoc1 resultDoc2 problems ->
380− (x1:y1:zs1) = reverse (resultDoc1 : map (toDoc dict RT.Func) revArgs1)
371+ (x1:y1:zs1) = reverse (resultDoc1 : map (toDoc localizer RT.Func) revArgs1)
381− (x2:y2:zs2) = reverse (resultDoc2 : map (toDoc dict RT.Func) revArgs2)
372+ (x2:y2:zs2) = reverse (resultDoc2 : map (toDoc localizer RT.Func) revArgs2)
383 Different
374 Different
384 (RT.lambda ctx x1 y1 zs1)
375 (RT.lambda ctx x1 y1 zs1)
@@ -389,9 +380,9 @@ diffLambda dict ctx types1 types2 =
390-- INVARIANT: length shortRevArgs >= 2 && length longRevArgs >= 2
381-- INVARIANT: length shortRevArgs >= 2 && length longRevArgs >= 2
392−diffArgMismatch :: Localizer -> RT.Context -> [Type] -> D.Doc -> [Type] -> D.Doc -> Diff D.Doc
383+diffArgMismatch :: L.Localizer -> RT.Context -> [Type] -> D.Doc -> [Type] -> D.Doc -> Diff D.Doc
393−diffArgMismatch dict ctx shortRevArgs shortResult longRevArgs longResult =
384+diffArgMismatch localizer ctx shortRevArgs shortResult longRevArgs longResult =
394− case toGreedyMatch dict shortRevArgs longRevArgs of
385+ case toGreedyMatch localizer shortRevArgs longRevArgs of
395 Just (GreedyMatch shortRevArgDocs longRevArgDocs) ->
386 Just (GreedyMatch shortRevArgDocs longRevArgDocs) ->
397 (a:b:cs) = reverse (shortResult:shortRevArgDocs)
388 (a:b:cs) = reverse (shortResult:shortRevArgDocs)
@@ -403,7 +394,7 @@ diffArgMismatch dict ctx shortRevArgs shortResult longRevArgs longResult =
403 (Bag.one (MissingArgs (length longRevArgs - length shortRevArgs)))
394 (Bag.one (MissingArgs (length longRevArgs - length shortRevArgs)))
405 Nothing ->
396 Nothing ->
406− case toGreedyMatch dict (reverse shortRevArgs) (reverse longRevArgs) of
397+ case toGreedyMatch localizer (reverse shortRevArgs) (reverse longRevArgs) of
407 Just (GreedyMatch shortArgDocs longArgDocs) ->
398 Just (GreedyMatch shortArgDocs longArgDocs) ->
409 (a:b:cs) = shortArgDocs ++ [shortResult]
400 (a:b:cs) = shortArgDocs ++ [shortResult]
@@ -417,7 +408,7 @@ diffArgMismatch dict ctx shortRevArgs shortResult longRevArgs longResult =
417 Nothing ->
408 Nothing ->
419 toYellowDoc tipe =
410 toYellowDoc tipe =
420− D.dullyellow (toDoc dict RT.Func tipe)
411+ D.dullyellow (toDoc localizer RT.Func tipe)
422 (a:b:cs) = reverse (shortResult : map toYellowDoc shortRevArgs)
413 (a:b:cs) = reverse (shortResult : map toYellowDoc shortRevArgs)
423 (x:y:zs) = reverse (longResult : map toYellowDoc longRevArgs )
414 (x:y:zs) = reverse (longResult : map toYellowDoc longRevArgs )
@@ -439,26 +430,26 @@ data GreedyMatch =
440-- INVARIANT: length shorterArgs < length longerArgs
431-- INVARIANT: length shorterArgs < length longerArgs
442−toGreedyMatch :: Localizer -> [Type] -> [Type] -> Maybe GreedyMatch
433+toGreedyMatch :: L.Localizer -> [Type] -> [Type] -> Maybe GreedyMatch
443−toGreedyMatch dict shorterArgs longerArgs =
434+toGreedyMatch localizer shorterArgs longerArgs =
444− toGreedyMatchHelp dict shorterArgs longerArgs (GreedyMatch [] [])
435+ toGreedyMatchHelp localizer shorterArgs longerArgs (GreedyMatch [] [])
447−toGreedyMatchHelp :: Localizer -> [Type] -> [Type] -> GreedyMatch -> Maybe GreedyMatch
438+toGreedyMatchHelp :: L.Localizer -> [Type] -> [Type] -> GreedyMatch -> Maybe GreedyMatch
448−toGreedyMatchHelp dict shorterArgs longerArgs match@(GreedyMatch shorterDocs longerDocs) =
439+toGreedyMatchHelp localizer shorterArgs longerArgs match@(GreedyMatch shorterDocs longerDocs) =
450 toYellowDoc tipe =
441 toYellowDoc tipe =
451− D.dullyellow (toDoc dict RT.Func tipe)
442+ D.dullyellow (toDoc localizer RT.Func tipe)
453 case (shorterArgs, longerArgs) of
444 case (shorterArgs, longerArgs) of
454 (x:xs, y:ys) ->
445 (x:xs, y:ys) ->
455− case diff dict RT.Func x y of
446+ case diff localizer RT.Func x y of
456 Similar a b ->
447 Similar a b ->
457− toGreedyMatchHelp dict xs ys $
448+ toGreedyMatchHelp localizer xs ys $
458 GreedyMatch (a:shorterDocs) (b:longerDocs)
449 GreedyMatch (a:shorterDocs) (b:longerDocs)
460 Different _ _ _ ->
451 Different _ _ _ ->
461− toGreedyMatchHelp dict shorterArgs ys $
452+ toGreedyMatchHelp localizer shorterArgs ys $
462 GreedyMatch shorterDocs (toYellowDoc y : longerDocs)
453 GreedyMatch shorterDocs (toYellowDoc y : longerDocs)
464 ([], []) ->
455 ([], []) ->
@@ -475,14 +466,14 @@ toGreedyMatchHelp dict shorterArgs longerArgs match@(GreedyMatch shorterDocs lon
475-- RECORD DIFFS
466-- RECORD DIFFS
478−diffRecord :: Localizer -> Map.Map N.Name Type -> Extension -> Map.Map N.Name Type -> Extension -> Diff D.Doc
469+diffRecord :: L.Localizer -> Map.Map N.Name Type -> Extension -> Map.Map N.Name Type -> Extension -> Diff D.Doc
479−diffRecord dict fields1 ext1 fields2 ext2 =
470+diffRecord localizer fields1 ext1 fields2 ext2 =
481 only1 = Map.keys (Map.difference fields1 fields2)
472 only1 = Map.keys (Map.difference fields1 fields2)
482 only2 = Map.keys (Map.difference fields2 fields1)
473 only2 = Map.keys (Map.difference fields2 fields1)
484 if null only1 && null only2 then
475 if null only1 && null only2 then
485− case findBadOverlaps dict fields1 fields2 of
476+ case findBadOverlaps localizer fields1 fields2 of
487 case diffExt ext1 ext2 of
478 case diffExt ext1 ext2 of
488 Similar _ _ ->
479 Similar _ _ ->
@@ -602,10 +593,10 @@ data BadOverlap =
605−findBadOverlaps :: Localizer -> Map.Map N.Name Type -> Map.Map N.Name Type -> [BadOverlap]
596+findBadOverlaps :: L.Localizer -> Map.Map N.Name Type -> Map.Map N.Name Type -> [BadOverlap]
606−findBadOverlaps dict fields1 fields2 =
597+findBadOverlaps localizer fields1 fields2 =
607 findBadOverlapsHelp [] $ Map.toList $
598 findBadOverlapsHelp [] $ Map.toList $
608− Map.intersectionWith (diff dict RT.None) fields1 fields2
599+ Map.intersectionWith (diff localizer RT.None) fields1 fields2
611findBadOverlapsHelp :: [BadOverlap] -> [(N.Name, Diff D.Doc)] -> [BadOverlap]
602findBadOverlapsHelp :: [BadOverlap] -> [(N.Name, Diff D.Doc)] -> [BadOverlap]