@@ -1,6 +1,5 @@
1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3−{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
6module Language.PureScript.Errors where
5module Language.PureScript.Errors where
@@ -9,6 +8,7 @@ import Prelude ()
9import Prelude.Compat
8import Prelude.Compat
11import Data.Ord (comparing)
10import Data.Ord (comparing)
11+import Data.Char (isSpace)
12import Data.Either (lefts, rights)
12import Data.Either (lefts, rights)
13import Data.List (intercalate, transpose, nub, nubBy, sortBy)
13import Data.List (intercalate, transpose, nub, nubBy, sortBy)
14import Data.Foldable (fold)
14import Data.Foldable (fold)
@@ -53,63 +53,63 @@ data SimpleErrorMessage
53 | RedefinedIdent Ident
53 | RedefinedIdent Ident
54 | OverlappingNamesInLet
54 | OverlappingNamesInLet
55 | UnknownModule ModuleName
55 | UnknownModule ModuleName
56− | UnknownType (Qualified ProperName)
56+ | UnknownType (Qualified (ProperName 'TypeName))
57− | UnknownTypeClass (Qualified ProperName)
57+ | UnknownTypeClass (Qualified (ProperName 'ClassName))
58 | UnknownValue (Qualified Ident)
58 | UnknownValue (Qualified Ident)
59− | UnknownDataConstructor (Qualified ProperName) (Maybe (Qualified ProperName))
59+ | UnknownDataConstructor (Qualified (ProperName 'ConstructorName)) (Maybe (Qualified (ProperName 'ConstructorName)))
60− | UnknownTypeConstructor (Qualified ProperName)
60+ | UnknownTypeConstructor (Qualified (ProperName 'TypeName))
61− | UnknownImportType ModuleName ProperName
61+ | UnknownImportType ModuleName (ProperName 'TypeName)
62− | UnknownExportType ProperName
62+ | UnknownExportType (ProperName 'TypeName)
63− | UnknownImportTypeClass ModuleName ProperName
63+ | UnknownImportTypeClass ModuleName (ProperName 'ClassName)
64− | UnknownExportTypeClass ProperName
64+ | UnknownExportTypeClass (ProperName 'ClassName)
65 | UnknownImportValue ModuleName Ident
65 | UnknownImportValue ModuleName Ident
66 | UnknownExportValue Ident
66 | UnknownExportValue Ident
67 | UnknownExportModule ModuleName
67 | UnknownExportModule ModuleName
68− | UnknownImportDataConstructor ModuleName ProperName ProperName
68+ | UnknownImportDataConstructor ModuleName (ProperName 'TypeName) (ProperName 'ConstructorName)
69− | UnknownExportDataConstructor ProperName ProperName
69+ | UnknownExportDataConstructor (ProperName 'TypeName) (ProperName 'ConstructorName)
70 | ScopeConflict String [ModuleName]
70 | ScopeConflict String [ModuleName]
71− | ConflictingTypeDecls ProperName
71+ | ConflictingTypeDecls (ProperName 'TypeName)
72− | ConflictingCtorDecls ProperName
72+ | ConflictingCtorDecls (ProperName 'ConstructorName)
73− | TypeConflictsWithClass ProperName
73+ | TypeConflictsWithClass (ProperName 'TypeName)
74− | CtorConflictsWithClass ProperName
74+ | CtorConflictsWithClass (ProperName 'ConstructorName)
75− | ClassConflictsWithType ProperName
75+ | ClassConflictsWithType (ProperName 'ClassName)
76− | ClassConflictsWithCtor ProperName
76+ | ClassConflictsWithCtor (ProperName 'ClassName)
77 | DuplicateModuleName ModuleName
77 | DuplicateModuleName ModuleName
78− | DuplicateClassExport ProperName
78+ | DuplicateClassExport (ProperName 'ClassName)
79 | DuplicateValueExport Ident
79 | DuplicateValueExport Ident
80 | DuplicateTypeArgument String
80 | DuplicateTypeArgument String
81 | InvalidDoBind
81 | InvalidDoBind
82 | InvalidDoLet
82 | InvalidDoLet
83 | CycleInDeclaration Ident
83 | CycleInDeclaration Ident
84− | CycleInTypeSynonym (Maybe ProperName)
84+ | CycleInTypeSynonym (Maybe (ProperName 'TypeName))
85 | CycleInModules [ModuleName]
85 | CycleInModules [ModuleName]
86 | NameIsUndefined Ident
86 | NameIsUndefined Ident
87− | UndefinedTypeVariable ProperName
87+ | UndefinedTypeVariable (ProperName 'TypeName)
88− | PartiallyAppliedSynonym (Qualified ProperName)
88+ | PartiallyAppliedSynonym (Qualified (ProperName 'TypeName))
89 | EscapedSkolem (Maybe Expr)
89 | EscapedSkolem (Maybe Expr)
90 | TypesDoNotUnify Type Type
90 | TypesDoNotUnify Type Type
91 | KindsDoNotUnify Kind Kind
91 | KindsDoNotUnify Kind Kind
92 | ConstrainedTypeUnified Type Type
92 | ConstrainedTypeUnified Type Type
93− | OverlappingInstances (Qualified ProperName) [Type] [Qualified Ident]
93+ | OverlappingInstances (Qualified (ProperName 'ClassName)) [Type] [Qualified Ident]
94− | NoInstanceFound (Qualified ProperName) [Type]
94+ | NoInstanceFound (Qualified (ProperName 'ClassName)) [Type]
95− | PossiblyInfiniteInstance (Qualified ProperName) [Type]
95+ | PossiblyInfiniteInstance (Qualified (ProperName 'ClassName)) [Type]
96− | CannotDerive (Qualified ProperName) [Type]
96+ | CannotDerive (Qualified (ProperName 'ClassName)) [Type]
97− | CannotFindDerivingType ProperName
97+ | CannotFindDerivingType (ProperName 'TypeName)
98 | DuplicateLabel String (Maybe Expr)
98 | DuplicateLabel String (Maybe Expr)
99 | DuplicateValueDeclaration Ident
99 | DuplicateValueDeclaration Ident
100 | ArgListLengthsDiffer Ident
100 | ArgListLengthsDiffer Ident
101 | OverlappingArgNames (Maybe Ident)
101 | OverlappingArgNames (Maybe Ident)
102 | MissingClassMember Ident
102 | MissingClassMember Ident
103− | ExtraneousClassMember Ident (Qualified ProperName)
103+ | ExtraneousClassMember Ident (Qualified (ProperName 'ClassName))
104 | ExpectedType Type Kind
104 | ExpectedType Type Kind
105− | IncorrectConstructorArity (Qualified ProperName)
105+ | IncorrectConstructorArity (Qualified (ProperName 'ConstructorName))
106 | ExprDoesNotHaveType Expr Type
106 | ExprDoesNotHaveType Expr Type
107 | PropertyIsMissing String
107 | PropertyIsMissing String
108 | AdditionalProperty String
108 | AdditionalProperty String
109 | CannotApplyFunction Type Expr
109 | CannotApplyFunction Type Expr
110 | TypeSynonymInstance
110 | TypeSynonymInstance
111− | OrphanInstance Ident (Qualified ProperName) [Type]
111+ | OrphanInstance Ident (Qualified (ProperName 'ClassName)) [Type]
112− | InvalidNewtype ProperName
112+ | InvalidNewtype (ProperName 'TypeName)
113 | InvalidInstanceHead Type
113 | InvalidInstanceHead Type
114 | TransitiveExportError DeclarationRef [DeclarationRef]
114 | TransitiveExportError DeclarationRef [DeclarationRef]
115 | ShadowedName Ident
115 | ShadowedName Ident
@@ -120,17 +120,17 @@ data SimpleErrorMessage
120 | NotExhaustivePattern [[Binder]] Bool
120 | NotExhaustivePattern [[Binder]] Bool
121 | OverlappingPattern [[Binder]] Bool
121 | OverlappingPattern [[Binder]] Bool
122 | IncompleteExhaustivityCheck
122 | IncompleteExhaustivityCheck
123− | ClassOperator ProperName Ident
123+ | ClassOperator (ProperName 'ClassName) Ident
124− | MisleadingEmptyTypeImport ModuleName ProperName
124+ | MisleadingEmptyTypeImport ModuleName (ProperName 'TypeName)
125 | ImportHidingModule ModuleName
125 | ImportHidingModule ModuleName
126 | UnusedImport ModuleName
126 | UnusedImport ModuleName
127− | UnusedExplicitImport ModuleName [String]
127+ | UnusedExplicitImport ModuleName [String] (Maybe ModuleName) [DeclarationRef]
128− | UnusedDctorImport ProperName
128+ | UnusedDctorImport (ProperName 'TypeName)
129− | UnusedDctorExplicitImport ProperName [ProperName]
129+ | UnusedDctorExplicitImport (ProperName 'TypeName) [ProperName 'ConstructorName]
130 | DeprecatedOperatorDecl String
130 | DeprecatedOperatorDecl String
131 | DeprecatedQualifiedSyntax ModuleName ModuleName
131 | DeprecatedQualifiedSyntax ModuleName ModuleName
132− | DeprecatedClassImport ModuleName ProperName
132+ | DeprecatedClassImport ModuleName (ProperName 'ClassName)
133− | DeprecatedClassExport ProperName
133+ | DeprecatedClassExport (ProperName 'ClassName)
134 | RedundantUnqualifiedImport ModuleName ImportDeclarationType
134 | RedundantUnqualifiedImport ModuleName ImportDeclarationType
135 | DuplicateSelectiveImport ModuleName
135 | DuplicateSelectiveImport ModuleName
136 | DuplicateImport ModuleName ImportDeclarationType (Maybe ModuleName)
136 | DuplicateImport ModuleName ImportDeclarationType (Maybe ModuleName)
@@ -138,7 +138,9 @@ data SimpleErrorMessage
138 | DuplicateExportRef String
138 | DuplicateExportRef String
139 | IntOutOfRange Integer String Integer Integer
139 | IntOutOfRange Integer String Integer Integer
140 | RedundantEmptyHidingImport ModuleName
140 | RedundantEmptyHidingImport ModuleName
141+ | ImplicitQualifiedImport ModuleName ModuleName [DeclarationRef]
141 | ImplicitImport ModuleName [DeclarationRef]
142 | ImplicitImport ModuleName [DeclarationRef]
143+ | HidingImport ModuleName [DeclarationRef]
142 | CaseBinderLengthDiffers Int [Binder]
144 | CaseBinderLengthDiffers Int [Binder]
143 deriving (Show)
145 deriving (Show)
@@ -147,7 +149,7 @@ data ErrorMessageHint
147 = ErrorUnifyingTypes Type Type
149 = ErrorUnifyingTypes Type Type
148 | ErrorInExpression Expr
150 | ErrorInExpression Expr
149 | ErrorInModule ModuleName
151 | ErrorInModule ModuleName
150− | ErrorInInstance (Qualified ProperName) [Type]
152+ | ErrorInInstance (Qualified (ProperName 'ClassName)) [Type]
151 | ErrorInSubsumption Type Type
153 | ErrorInSubsumption Type Type
152 | ErrorCheckingAccessor Expr String
154 | ErrorCheckingAccessor Expr String
153 | ErrorCheckingType Expr Type
155 | ErrorCheckingType Expr Type
@@ -155,11 +157,11 @@ data ErrorMessageHint
155 | ErrorCheckingGuard
157 | ErrorCheckingGuard
156 | ErrorInferringType Expr
158 | ErrorInferringType Expr
157 | ErrorInApplication Expr Type Expr
159 | ErrorInApplication Expr Type Expr
158− | ErrorInDataConstructor ProperName
160+ | ErrorInDataConstructor (ProperName 'ConstructorName)
159− | ErrorInTypeConstructor ProperName
161+ | ErrorInTypeConstructor (ProperName 'TypeName)
160 | ErrorInBindingGroup [Ident]
162 | ErrorInBindingGroup [Ident]
161 | ErrorInDataBindingGroup
163 | ErrorInDataBindingGroup
162− | ErrorInTypeSynonym ProperName
164+ | ErrorInTypeSynonym (ProperName 'TypeName)
163 | ErrorInValueDeclaration Ident
165 | ErrorInValueDeclaration Ident
164 | ErrorInTypeDeclaration Ident
166 | ErrorInTypeDeclaration Ident
165 | ErrorInForeignImport Ident
167 | ErrorInForeignImport Ident
@@ -177,6 +179,8 @@ data HintCategory
178data ErrorMessage = ErrorMessage [ErrorMessageHint] SimpleErrorMessage deriving (Show)
180data ErrorMessage = ErrorMessage [ErrorMessageHint] SimpleErrorMessage deriving (Show)
182+newtype ErrorSuggestion = ErrorSuggestion String
180-- | Get the source span for an error
184-- | Get the source span for an error
181errorSpan :: ErrorMessage -> Maybe SourceSpan
185errorSpan :: ErrorMessage -> Maybe SourceSpan
182errorSpan = findHint matchSpan
186errorSpan = findHint matchSpan
@@ -309,7 +313,9 @@ errorCode em = case unwrapErrorMessage em of
309 DuplicateExportRef{} -> "DuplicateExportRef"
313 DuplicateExportRef{} -> "DuplicateExportRef"
310 IntOutOfRange{} -> "IntOutOfRange"
314 IntOutOfRange{} -> "IntOutOfRange"
311 RedundantEmptyHidingImport{} -> "RedundantEmptyHidingImport"
315 RedundantEmptyHidingImport{} -> "RedundantEmptyHidingImport"
316+ ImplicitQualifiedImport{} -> "ImplicitQualifiedImport"
312 ImplicitImport{} -> "ImplicitImport"
317 ImplicitImport{} -> "ImplicitImport"
318+ HidingImport{} -> "HidingImport"
313 CaseBinderLengthDiffers{} -> "CaseBinderLengthDiffers"
319 CaseBinderLengthDiffers{} -> "CaseBinderLengthDiffers"
@@ -412,11 +418,48 @@ onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse
412 gHint (ErrorInInstance cl ts) = ErrorInInstance cl <$> traverse f ts
418 gHint (ErrorInInstance cl ts) = ErrorInInstance cl <$> traverse f ts
413 gHint other = pure other
419 gHint other = pure other
421+wikiUri :: ErrorMessage -> String
422+wikiUri e = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
424+-- TODO Other possible suggestions:
425+-- WildcardInferredType - source span not small enough
426+-- DuplicateSelectiveImport - would require 2 ranges to remove and 1 insert
427+-- DeprecatedClassExport, DeprecatedClassImport, would want to replace smaller span?
428+errorSuggestion :: SimpleErrorMessage -> Maybe ErrorSuggestion
429+errorSuggestion err = case err of
430+ UnusedImport{} -> emptySuggestion
431+ RedundantEmptyHidingImport{} -> emptySuggestion
432+ DuplicateImport{} -> emptySuggestion
433+ RedundantUnqualifiedImport{} -> emptySuggestion
434+ DeprecatedQualifiedSyntax name qualName -> suggest $
435+ "import " ++ runModuleName name ++ " as " ++ runModuleName qualName
436+ UnusedExplicitImport mn _ qual refs -> suggest $ importSuggestion mn refs qual
437+ ImplicitImport mn refs -> suggest $ importSuggestion mn refs Nothing
438+ ImplicitQualifiedImport mn asModule refs -> suggest $ importSuggestion mn refs (Just asModule)
442+ emptySuggestion = Just $ ErrorSuggestion ""
443+ suggest = Just . ErrorSuggestion
445+ importSuggestion :: ModuleName -> [ DeclarationRef ] -> Maybe ModuleName -> String
446+ importSuggestion mn refs qual =
447+ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")" ++ qstr qual
449+ qstr :: Maybe ModuleName -> String
450+ qstr (Just mn) = " as " ++ runModuleName mn
453+showSuggestion :: SimpleErrorMessage -> String
454+showSuggestion suggestion = case errorSuggestion suggestion of
455+ Just (ErrorSuggestion x) -> x
416-- Pretty print a single error, simplifying if necessary
459-- Pretty print a single error, simplifying if necessary
418−prettyPrintSingleError :: Bool -> Level -> ErrorMessage -> Box.Box
461+prettyPrintSingleError :: Bool -> Level -> Bool -> ErrorMessage -> Box.Box
419−prettyPrintSingleError full level e = flip evalState defaultUnknownMap $ do
462+prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap $ do
420 em <- onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
463 em <- onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
421 um <- get
464 um <- get
422 return (prettyPrintErrorMessage um em)
465 return (prettyPrintErrorMessage um em)
@@ -425,20 +468,19 @@ prettyPrintSingleError full level e = flip evalState defaultUnknownMap $ do
425 -- Pretty print an ErrorMessage
468 -- Pretty print an ErrorMessage
426 prettyPrintErrorMessage :: TypeMap -> ErrorMessage -> Box.Box
469 prettyPrintErrorMessage :: TypeMap -> ErrorMessage -> Box.Box
427 prettyPrintErrorMessage typeMap (ErrorMessage hints simple) =
470 prettyPrintErrorMessage typeMap (ErrorMessage hints simple) =
429 [ foldr renderHint (indent (renderSimpleErrorMessage simple)) hints
472 [ foldr renderHint (indent (renderSimpleErrorMessage simple)) hints
430− , Box.moveDown 1 typeInformation
474+ maybe [] (return . Box.moveDown 1) typeInformation ++
431− , Box.moveDown 1 $ paras [ line $ "See " ++ wikiUri ++ " for more information, "
475+ [ Box.moveDown 1 $ paras [ line $ "See " ++ wikiUri e ++ " for more information, "
432− , line $ "or to contribute content related to this " ++ levelText ++ "."
476+ , line $ "or to contribute content related to this " ++ levelText ++ "."
436− wikiUri :: String
481+ typeInformation :: Maybe Box.Box
437− wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
439− typeInformation :: Box.Box
440− typeInformation | not (null types) = Box.hsep 1 Box.left [ line "where", paras types]
482+ typeInformation | not (null types) = Just $ Box.hsep 1 Box.left [ line "where", paras types ]
441− | otherwise = Box.emptyBox 0 0
483+ | otherwise = Nothing
443 types :: [Box.Box]
485 types :: [Box.Box]
444 types = map skolemInfo (M.elems (umSkolemMap typeMap)) ++
486 types = map skolemInfo (M.elems (umSkolemMap typeMap)) ++
@@ -790,9 +832,11 @@ prettyPrintSingleError full level e = flip evalState defaultUnknownMap $ do
790 renderSimpleErrorMessage (UnusedImport name) =
832 renderSimpleErrorMessage (UnusedImport name) =
791 line $ "The import of module " ++ runModuleName name ++ " is redundant"
833 line $ "The import of module " ++ runModuleName name ++ " is redundant"
793− renderSimpleErrorMessage (UnusedExplicitImport name names) =
835+ renderSimpleErrorMessage msg@(UnusedExplicitImport mn names _ _) =
794− paras [ line $ "The import of module " ++ runModuleName name ++ " contains the following unused references:"
836+ paras [ line $ "The import of module " ++ runModuleName mn ++ " contains the following unused references:"
795− , indent $ paras $ map line names ]
837+ , indent $ paras $ map line names
838+ , line $ "It could be replaced with:"
839+ , indent $ line $ showSuggestion msg ]
797 renderSimpleErrorMessage (UnusedDctorImport name) =
841 renderSimpleErrorMessage (UnusedDctorImport name) =
798 line $ "The import of type " ++ runProperName name ++ " includes data constructors but only the type is used"
842 line $ "The import of type " ++ runProperName name ++ " includes data constructors but only the type is used"
@@ -854,8 +898,19 @@ prettyPrintSingleError full level e = flip evalState defaultUnknownMap $ do
854 renderSimpleErrorMessage (RedundantEmptyHidingImport mn) =
898 renderSimpleErrorMessage (RedundantEmptyHidingImport mn) =
855 line $ "The import for module " ++ runModuleName mn ++ " is redundant as all members have been explicitly hidden."
899 line $ "The import for module " ++ runModuleName mn ++ " is redundant as all members have been explicitly hidden."
857− renderSimpleErrorMessage (ImplicitImport mn refs) =
901+ renderSimpleErrorMessage msg@(ImplicitQualifiedImport importedModule asModule _) =
902+ paras [ line $ "Module " ++ runModuleName importedModule ++ " was imported as " ++ runModuleName asModule ++ " with unspecified imports."
903+ , line $ "As there are multiple modules being imported as " ++ runModuleName asModule ++ ", consider using the explicit form:"
904+ , indent $ line $ showSuggestion msg
907+ renderSimpleErrorMessage msg@(ImplicitImport mn _) =
858 paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
908 paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
909+ , indent $ line $ showSuggestion msg
912+ renderSimpleErrorMessage (HidingImport mn refs) =
913+ paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the inclusive form: "
859 , indent $ line $ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
914 , indent $ line $ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
@@ -992,37 +1047,13 @@ prettyPrintSingleError full level e = flip evalState defaultUnknownMap $ do
992 paras :: [Box.Box] -> Box.Box
1047 paras :: [Box.Box] -> Box.Box
993 paras = Box.vcat Box.left
1048 paras = Box.vcat Box.left
995− -- Pretty print and export declaration
996− prettyPrintExport :: DeclarationRef -> String
997− prettyPrintExport (TypeRef pn _) = runProperName pn
998− prettyPrintExport ref = prettyPrintRef ref
1000− prettyPrintRef :: DeclarationRef -> String
1001− prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
1002− prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
1003− prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1004− prettyPrintRef (ValueRef ident) = showIdent ident
1005− prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
1006− prettyPrintRef (ProperRef pn) = runProperName pn
1007− prettyPrintRef (TypeInstanceRef ident) = showIdent ident
1008− prettyPrintRef (ModuleRef name) = "module " ++ runModuleName name
1009− prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
1011− prettyPrintImport :: ModuleName -> ImportDeclarationType -> Maybe ModuleName -> String
1012− prettyPrintImport mn idt qual =
1013− let i = case idt of
1014− Implicit -> runModuleName mn
1015− Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
1016− Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (map prettyPrintRef refs) ++ ")"
1017− in i ++ maybe "" (\q -> " as " ++ runModuleName q) qual
1019 -- | Simplify an error message
1050 -- | Simplify an error message
1020 simplifyErrorMessage :: ErrorMessage -> ErrorMessage
1051 simplifyErrorMessage :: ErrorMessage -> ErrorMessage
1021 simplifyErrorMessage (ErrorMessage hints simple) = ErrorMessage (simplifyHints hints) simple
1052 simplifyErrorMessage (ErrorMessage hints simple) = ErrorMessage (simplifyHints hints) simple
1023 -- Take the last instance of each "hint category"
1054 -- Take the last instance of each "hint category"
1024 simplifyHints :: [ErrorMessageHint] -> [ErrorMessageHint]
1055 simplifyHints :: [ErrorMessageHint] -> [ErrorMessageHint]
1025− simplifyHints = reverse . nubBy categoriesEqual . reverse
1056+ simplifyHints = reverse . nubBy categoriesEqual . stripRedudantHints simple . reverse
1027 -- Don't remove hints in the "other" category
1058 -- Don't remove hints in the "other" category
1028 categoriesEqual :: ErrorMessageHint -> ErrorMessageHint -> Bool
1059 categoriesEqual :: ErrorMessageHint -> ErrorMessageHint -> Bool
@@ -1032,6 +1063,30 @@ prettyPrintSingleError full level e = flip evalState defaultUnknownMap $ do
1032 (_, OtherHint) -> False
1063 (_, OtherHint) -> False
1033 (c1, c2) -> c1 == c2
1064 (c1, c2) -> c1 == c2
1066+ -- | See https://github.com/purescript/purescript/issues/1802
1067+ stripRedudantHints :: SimpleErrorMessage -> [ErrorMessageHint] -> [ErrorMessageHint]
1068+ stripRedudantHints CannotApplyFunction{} = stripFirst isApplicationHint
1070+ isApplicationHint ErrorInApplication{} = True
1071+ isApplicationHint _ = False
1072+ stripRedudantHints ExprDoesNotHaveType{} = stripFirst isCheckHint
1074+ isCheckHint ErrorCheckingType{} = True
1075+ isCheckHint _ = False
1076+ stripRedudantHints TypesDoNotUnify{} = stripFirst isUnifyHint
1078+ isUnifyHint ErrorUnifyingTypes{} = True
1079+ isUnifyHint _ = False
1080+ stripRedudantHints _ = id
1082+ stripFirst :: (ErrorMessageHint -> Bool) -> [ErrorMessageHint] -> [ErrorMessageHint]
1083+ stripFirst p (PositionedError pos : hs) = PositionedError pos : stripFirst p hs
1084+ stripFirst p (ErrorInModule mn : hs) = ErrorInModule mn : stripFirst p hs
1085+ stripFirst p (hint : hs)
1087+ | otherwise = hint : hs
1088+ stripFirst _ [] = []
1035 hintCategory :: ErrorMessageHint -> HintCategory
1090 hintCategory :: ErrorMessageHint -> HintCategory
1036 hintCategory ErrorCheckingType{} = ExprHint
1091 hintCategory ErrorCheckingType{} = ExprHint
1037 hintCategory ErrorInferringType{} = ExprHint
1092 hintCategory ErrorInferringType{} = ExprHint
@@ -1043,6 +1098,30 @@ prettyPrintSingleError full level e = flip evalState defaultUnknownMap $ do
1043 hintCategory PositionedError{} = PositionHint
1098 hintCategory PositionedError{} = PositionHint
1044 hintCategory _ = OtherHint
1099 hintCategory _ = OtherHint
1101+-- Pretty print and export declaration
1102+prettyPrintExport :: DeclarationRef -> String
1103+prettyPrintExport (TypeRef pn _) = runProperName pn
1104+prettyPrintExport ref = prettyPrintRef ref
1106+prettyPrintImport :: ModuleName -> ImportDeclarationType -> Maybe ModuleName -> String
1107+prettyPrintImport mn idt qual =
1108+ let i = case idt of
1109+ Implicit -> runModuleName mn
1110+ Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
1111+ Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (map prettyPrintRef refs) ++ ")"
1112+ in i ++ maybe "" (\q -> " as " ++ runModuleName q) qual
1114+prettyPrintRef :: DeclarationRef -> String
1115+prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
1116+prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
1117+prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1118+prettyPrintRef (ValueRef ident) = showIdent ident
1119+prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
1120+prettyPrintRef (ProperRef name) = name
1121+prettyPrintRef (TypeInstanceRef ident) = showIdent ident
1122+prettyPrintRef (ModuleRef name) = "module " ++ runModuleName name
1123+prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
1047-- Pretty print multiple errors
1126-- Pretty print multiple errors
@@ -1065,12 +1144,12 @@ prettyPrintMultipleErrorsBox full = prettyPrintMultipleErrorsWith Error "Error f
1066prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> Box.Box
1145prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> Box.Box
1067prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) =
1146prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) =
1068− let result = prettyPrintSingleError full level e
1147+ let result = prettyPrintSingleError full level True e
1069 in Box.vcat Box.left [ Box.text intro
1148 in Box.vcat Box.left [ Box.text intro
1070 , result
1149 , result
1072prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) =
1151prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) =
1073− let result = map (prettyPrintSingleError full level) es
1152+ let result = map (prettyPrintSingleError full level True) es
1074 in Box.vsep 1 Box.left $ concat $ zipWith withIntro [1 :: Int ..] result
1153 in Box.vsep 1 Box.left $ concat $ zipWith withIntro [1 :: Int ..] result
1076 withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
1155 withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
@@ -1133,9 +1212,15 @@ line :: String -> Box.Box
1133line = Box.text
1212line = Box.text
1135renderBox :: Box.Box -> String
1214renderBox :: Box.Box -> String
1136−renderBox = unlines . map trimEnd . lines . Box.render
1215+renderBox = unlines
1216+ . map (dropWhileEnd isSpace)
1217+ . dropWhile whiteSpace
1218+ . dropWhileEnd whiteSpace
1138− trimEnd = reverse . dropWhile (== ' ') . reverse
1222+ dropWhileEnd p = reverse . dropWhile p . reverse
1223+ whiteSpace = all isSpace
1141-- Rethrow an error with a more detailed error message in the case of failure
1226-- Rethrow an error with a more detailed error message in the case of failure