@@ -1,6 +1,5 @@
11{-# LANGUAGE GeneralizedNewtypeDeriving #-}
22{-# LANGUAGE FlexibleContexts #-}
3−{-# LANGUAGE RecordWildCards #-}
43{-# LANGUAGE MultiParamTypeClasses #-}
54
65module Language.PureScript.Errors where
@@ -9,6 +8,7 @@ import Prelude ()
98import Prelude.Compat
109
1110import Data.Ord (comparing)
11+import Data.Char (isSpace)
1212import Data.Either (lefts, rights)
1313import Data.List (intercalate, transpose, nub, nubBy, sortBy)
1414import Data.Foldable (fold)
@@ -24,6 +24,7 @@ import Control.Arrow ((&&&))
2424import Language.PureScript.Crash
2525import Language.PureScript.AST
2626import Language.PureScript.Pretty
27+import Language.PureScript.Pretty.Common (before)
2728import Language.PureScript.Types
2829import Language.PureScript.Names
2930import Language.PureScript.Kinds
@@ -53,65 +54,67 @@ data SimpleErrorMessage
5354 | RedefinedIdent Ident
5455 | OverlappingNamesInLet
5556 | UnknownModule ModuleName
56− | UnknownType (Qualified ProperName)
57− | UnknownTypeClass (Qualified ProperName)
57+ | UnknownType (Qualified (ProperName 'TypeName))
58+ | UnknownTypeClass (Qualified (ProperName 'ClassName))
5859 | UnknownValue (Qualified Ident)
59− | UnknownDataConstructor (Qualified ProperName) (Maybe (Qualified ProperName))
60− | UnknownTypeConstructor (Qualified ProperName)
61− | UnknownImportType ModuleName ProperName
62− | UnknownExportType ProperName
63− | UnknownImportTypeClass ModuleName ProperName
64− | UnknownExportTypeClass ProperName
60+ | UnknownDataConstructor (Qualified (ProperName 'ConstructorName)) (Maybe (Qualified (ProperName 'ConstructorName)))
61+ | UnknownTypeConstructor (Qualified (ProperName 'TypeName))
62+ | UnknownImportType ModuleName (ProperName 'TypeName)
63+ | UnknownExportType (ProperName 'TypeName)
64+ | UnknownImportTypeClass ModuleName (ProperName 'ClassName)
65+ | UnknownExportTypeClass (ProperName 'ClassName)
6566 | UnknownImportValue ModuleName Ident
6667 | UnknownExportValue Ident
6768 | UnknownExportModule ModuleName
68− | UnknownImportDataConstructor ModuleName ProperName ProperName
69− | UnknownExportDataConstructor ProperName ProperName
69+ | UnknownImportDataConstructor ModuleName (ProperName 'TypeName) (ProperName 'ConstructorName)
70+ | UnknownExportDataConstructor (ProperName 'TypeName) (ProperName 'ConstructorName)
7071 | ScopeConflict String [ModuleName]
71− | ConflictingTypeDecls ProperName
72− | ConflictingCtorDecls ProperName
73− | TypeConflictsWithClass ProperName
74− | CtorConflictsWithClass ProperName
75− | ClassConflictsWithType ProperName
76− | ClassConflictsWithCtor ProperName
72+ | ScopeShadowing String (Maybe ModuleName) [ModuleName]
73+ | ConflictingTypeDecls (ProperName 'TypeName)
74+ | ConflictingCtorDecls (ProperName 'ConstructorName)
75+ | TypeConflictsWithClass (ProperName 'TypeName)
76+ | CtorConflictsWithClass (ProperName 'ConstructorName)
77+ | ClassConflictsWithType (ProperName 'ClassName)
78+ | ClassConflictsWithCtor (ProperName 'ClassName)
7779 | DuplicateModuleName ModuleName
78− | DuplicateClassExport ProperName
80+ | DuplicateClassExport (ProperName 'ClassName)
7981 | DuplicateValueExport Ident
8082 | DuplicateTypeArgument String
8183 | InvalidDoBind
8284 | InvalidDoLet
8385 | CycleInDeclaration Ident
84− | CycleInTypeSynonym (Maybe ProperName)
86+ | CycleInTypeSynonym (Maybe (ProperName 'TypeName))
8587 | CycleInModules [ModuleName]
8688 | NameIsUndefined Ident
87− | UndefinedTypeVariable ProperName
88− | PartiallyAppliedSynonym (Qualified ProperName)
89+ | UndefinedTypeVariable (ProperName 'TypeName)
90+ | PartiallyAppliedSynonym (Qualified (ProperName 'TypeName))
8991 | EscapedSkolem (Maybe Expr)
9092 | TypesDoNotUnify Type Type
9193 | KindsDoNotUnify Kind Kind
9294 | ConstrainedTypeUnified Type Type
93− | OverlappingInstances (Qualified ProperName) [Type] [Qualified Ident]
94− | NoInstanceFound (Qualified ProperName) [Type]
95− | PossiblyInfiniteInstance (Qualified ProperName) [Type]
96− | CannotDerive (Qualified ProperName) [Type]
97− | CannotFindDerivingType ProperName
95+ | OverlappingInstances (Qualified (ProperName 'ClassName)) [Type] [Qualified Ident]
96+ | NoInstanceFound (Qualified (ProperName 'ClassName)) [Type]
97+ | PossiblyInfiniteInstance (Qualified (ProperName 'ClassName)) [Type]
98+ | CannotDerive (Qualified (ProperName 'ClassName)) [Type]
99+ | CannotFindDerivingType (ProperName 'TypeName)
98100 | DuplicateLabel String (Maybe Expr)
99101 | DuplicateValueDeclaration Ident
100102 | ArgListLengthsDiffer Ident
101103 | OverlappingArgNames (Maybe Ident)
102104 | MissingClassMember Ident
103− | ExtraneousClassMember Ident (Qualified ProperName)
105+ | ExtraneousClassMember Ident (Qualified (ProperName 'ClassName))
104106 | ExpectedType Type Kind
105− | IncorrectConstructorArity (Qualified ProperName)
107+ | IncorrectConstructorArity (Qualified (ProperName 'ConstructorName))
106108 | ExprDoesNotHaveType Expr Type
107109 | PropertyIsMissing String
108110 | AdditionalProperty String
109111 | CannotApplyFunction Type Expr
110112 | TypeSynonymInstance
111− | OrphanInstance Ident (Qualified ProperName) [Type]
112− | InvalidNewtype ProperName
113+ | OrphanInstance Ident (Qualified (ProperName 'ClassName)) [Type]
114+ | InvalidNewtype (ProperName 'TypeName)
113115 | InvalidInstanceHead Type
114116 | TransitiveExportError DeclarationRef [DeclarationRef]
117+ | TransitiveDctorExportError DeclarationRef (ProperName 'ConstructorName)
115118 | ShadowedName Ident
116119 | ShadowedTypeVar String
117120 | UnusedTypeVar String
@@ -120,17 +123,18 @@ data SimpleErrorMessage
120123 | NotExhaustivePattern [[Binder]] Bool
121124 | OverlappingPattern [[Binder]] Bool
122125 | IncompleteExhaustivityCheck
123− | ClassOperator ProperName Ident
124− | MisleadingEmptyTypeImport ModuleName ProperName
126+ | ClassOperator (ProperName 'ClassName) Ident
127+ | MisleadingEmptyTypeImport ModuleName (ProperName 'TypeName)
125128 | ImportHidingModule ModuleName
126129 | UnusedImport ModuleName
127− | UnusedExplicitImport ModuleName [String]
128− | UnusedDctorImport ProperName
129− | UnusedDctorExplicitImport ProperName [ProperName]
130+ | UnusedExplicitImport ModuleName [String] (Maybe ModuleName) [DeclarationRef]
131+ | UnusedDctorImport (ProperName 'TypeName)
132+ | UnusedDctorExplicitImport (ProperName 'TypeName) [ProperName 'ConstructorName]
130133 | DeprecatedOperatorDecl String
134+ | DeprecatedOperatorSection Expr (Either Expr Expr)
131135 | DeprecatedQualifiedSyntax ModuleName ModuleName
132− | DeprecatedClassImport ModuleName ProperName
133− | DeprecatedClassExport ProperName
136+ | DeprecatedClassImport ModuleName (ProperName 'ClassName)
137+ | DeprecatedClassExport (ProperName 'ClassName)
134138 | RedundantUnqualifiedImport ModuleName ImportDeclarationType
135139 | DuplicateSelectiveImport ModuleName
136140 | DuplicateImport ModuleName ImportDeclarationType (Maybe ModuleName)
@@ -138,8 +142,12 @@ data SimpleErrorMessage
138142 | DuplicateExportRef String
139143 | IntOutOfRange Integer String Integer Integer
140144 | RedundantEmptyHidingImport ModuleName
145+ | ImplicitQualifiedImport ModuleName ModuleName [DeclarationRef]
141146 | ImplicitImport ModuleName [DeclarationRef]
147+ | HidingImport ModuleName [DeclarationRef]
142148 | CaseBinderLengthDiffers Int [Binder]
149+ | IncorrectAnonymousArgument
150+ | InvalidOperatorInBinder Ident Ident
143151 deriving (Show)
144152
145153-- | Error message hints, providing more detailed information about failure.
@@ -147,7 +155,7 @@ data ErrorMessageHint
147155 = ErrorUnifyingTypes Type Type
148156 | ErrorInExpression Expr
149157 | ErrorInModule ModuleName
150− | ErrorInInstance (Qualified ProperName) [Type]
158+ | ErrorInInstance (Qualified (ProperName 'ClassName)) [Type]
151159 | ErrorInSubsumption Type Type
152160 | ErrorCheckingAccessor Expr String
153161 | ErrorCheckingType Expr Type
@@ -155,11 +163,11 @@ data ErrorMessageHint
155163 | ErrorCheckingGuard
156164 | ErrorInferringType Expr
157165 | ErrorInApplication Expr Type Expr
158− | ErrorInDataConstructor ProperName
159− | ErrorInTypeConstructor ProperName
166+ | ErrorInDataConstructor (ProperName 'ConstructorName)
167+ | ErrorInTypeConstructor (ProperName 'TypeName)
160168 | ErrorInBindingGroup [Ident]
161169 | ErrorInDataBindingGroup
162− | ErrorInTypeSynonym ProperName
170+ | ErrorInTypeSynonym (ProperName 'TypeName)
163171 | ErrorInValueDeclaration Ident
164172 | ErrorInTypeDeclaration Ident
165173 | ErrorInForeignImport Ident
@@ -177,6 +185,8 @@ data HintCategory
177185
178186data ErrorMessage = ErrorMessage [ErrorMessageHint] SimpleErrorMessage deriving (Show)
179187
188+newtype ErrorSuggestion = ErrorSuggestion String
189+
180190-- | Get the source span for an error
181191errorSpan :: ErrorMessage -> Maybe SourceSpan
182192errorSpan = findHint matchSpan
@@ -239,6 +249,7 @@ errorCode em = case unwrapErrorMessage em of
239249 UnknownImportDataConstructor{} -> "UnknownImportDataConstructor"
240250 UnknownExportDataConstructor{} -> "UnknownExportDataConstructor"
241251 ScopeConflict{} -> "ScopeConflict"
252+ ScopeShadowing{} -> "ScopeShadowing"
242253 ConflictingTypeDecls{} -> "ConflictingTypeDecls"
243254 ConflictingCtorDecls{} -> "ConflictingCtorDecls"
244255 TypeConflictsWithClass{} -> "TypeConflictsWithClass"
@@ -283,6 +294,7 @@ errorCode em = case unwrapErrorMessage em of
283294 InvalidNewtype{} -> "InvalidNewtype"
284295 InvalidInstanceHead{} -> "InvalidInstanceHead"
285296 TransitiveExportError{} -> "TransitiveExportError"
297+ TransitiveDctorExportError{} -> "TransitiveDctorExportError"
286298 ShadowedName{} -> "ShadowedName"
287299 ShadowedTypeVar{} -> "ShadowedTypeVar"
288300 UnusedTypeVar{} -> "UnusedTypeVar"
@@ -299,6 +311,7 @@ errorCode em = case unwrapErrorMessage em of
299311 UnusedDctorImport{} -> "UnusedDctorImport"
300312 UnusedDctorExplicitImport{} -> "UnusedDctorExplicitImport"
301313 DeprecatedOperatorDecl{} -> "DeprecatedOperatorDecl"
314+ DeprecatedOperatorSection{} -> "DeprecatedOperatorSection"
302315 DeprecatedQualifiedSyntax{} -> "DeprecatedQualifiedSyntax"
303316 DeprecatedClassImport{} -> "DeprecatedClassImport"
304317 DeprecatedClassExport{} -> "DeprecatedClassExport"
@@ -309,8 +322,12 @@ errorCode em = case unwrapErrorMessage em of
309322 DuplicateExportRef{} -> "DuplicateExportRef"
310323 IntOutOfRange{} -> "IntOutOfRange"
311324 RedundantEmptyHidingImport{} -> "RedundantEmptyHidingImport"
325+ ImplicitQualifiedImport{} -> "ImplicitQualifiedImport"
312326 ImplicitImport{} -> "ImplicitImport"
327+ HidingImport{} -> "HidingImport"
313328 CaseBinderLengthDiffers{} -> "CaseBinderLengthDiffers"
329+ IncorrectAnonymousArgument -> "IncorrectAnonymousArgument"
330+ InvalidOperatorInBinder{} -> "InvalidOperatorInBinder"
314331
315332-- |
316333-- A stack trace for an error
@@ -412,14 +429,48 @@ onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse
412429 gHint (ErrorInInstance cl ts) = ErrorInInstance cl <$> traverse f ts
413430 gHint other = pure other
414431
415−prettyPrintSingleError' :: Bool -> Level -> ErrorMessage ->Box.Box
416−prettyPrintSingleError' full level = flip evalState defaultUnknownMap . prettyPrintSingleError full level
432+wikiUri :: ErrorMessage -> String
433+wikiUri e = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
434+
435+-- TODO Other possible suggestions:
436+-- WildcardInferredType - source span not small enough
437+-- DuplicateSelectiveImport - would require 2 ranges to remove and 1 insert
438+-- DeprecatedClassExport, DeprecatedClassImport, DeprecatedOperatorSection, would want to replace smaller span?
439+errorSuggestion :: SimpleErrorMessage -> Maybe ErrorSuggestion
440+errorSuggestion err = case err of
441+ UnusedImport{} -> emptySuggestion
442+ RedundantEmptyHidingImport{} -> emptySuggestion
443+ DuplicateImport{} -> emptySuggestion
444+ RedundantUnqualifiedImport{} -> emptySuggestion
445+ DeprecatedQualifiedSyntax name qualName -> suggest $
446+ "import " ++ runModuleName name ++ " as " ++ runModuleName qualName
447+ UnusedExplicitImport mn _ qual refs -> suggest $ importSuggestion mn refs qual
448+ ImplicitImport mn refs -> suggest $ importSuggestion mn refs Nothing
449+ ImplicitQualifiedImport mn asModule refs -> suggest $ importSuggestion mn refs (Just asModule)
450+ _ -> Nothing
451+
452+ where
453+ emptySuggestion = Just $ ErrorSuggestion ""
454+ suggest = Just . ErrorSuggestion
455+
456+ importSuggestion :: ModuleName -> [ DeclarationRef ] -> Maybe ModuleName -> String
457+ importSuggestion mn refs qual =
458+ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")" ++ qstr qual
459+
460+ qstr :: Maybe ModuleName -> String
461+ qstr (Just mn) = " as " ++ runModuleName mn
462+ qstr Nothing = ""
463+
464+showSuggestion :: SimpleErrorMessage -> String
465+showSuggestion suggestion = case errorSuggestion suggestion of
466+ Just (ErrorSuggestion x) -> x
467+ _ -> ""
417468
418469-- |
419470-- Pretty print a single error, simplifying if necessary
420471--
421−prettyPrintSingleError :: Bool -> Level -> ErrorMessage -> State TypeMap Box.Box
422−prettyPrintSingleError full level e = do
472+prettyPrintSingleError :: Bool -> Level -> Bool -> ErrorMessage -> Box.Box
473+prettyPrintSingleError full level showWiki e = flip evalState defaultUnknownMap $ do
423474 em <- onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
424475 um <- get
425476 return (prettyPrintErrorMessage um em)
@@ -428,20 +479,19 @@ prettyPrintSingleError full level e = do
428479 -- Pretty print an ErrorMessage
429480 prettyPrintErrorMessage :: TypeMap -> ErrorMessage -> Box.Box
430481 prettyPrintErrorMessage typeMap (ErrorMessage hints simple) =
431− paras
482+ paras $
432483 [ foldr renderHint (indent (renderSimpleErrorMessage simple)) hints
433− , Box.moveDown 1 typeInformation
434− , Box.moveDown 1 $ paras [ line $ "See " ++ wikiUri ++ " for more information, "
435− , line $ "or to contribute content related to this " ++ levelText ++ "."
436− ]
484+ ] ++
485+ maybe [] (return . Box.moveDown 1) typeInformation ++
486+ [ Box.moveDown 1 $ paras [ line $ "See " ++ wikiUri e ++ " for more information, "
487+ , line $ "or to contribute content related to this " ++ levelText ++ "."
488+ ]
489+ | showWiki
437490 ]
438491 where
439− wikiUri :: String
440− wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
441−
442− typeInformation :: Box.Box
443− typeInformation | not (null types) = Box.hsep 1 Box.left [ line "where", paras types]
444− | otherwise = Box.emptyBox 0 0
492+ typeInformation :: Maybe Box.Box
493+ typeInformation | not (null types) = Just $ Box.hsep 1 Box.left [ line "where", paras types ]
494+ | otherwise = Nothing
445495 where
446496 types :: [Box.Box]
447497 types = map skolemInfo (M.elems (umSkolemMap typeMap)) ++
@@ -556,6 +606,13 @@ prettyPrintSingleError full level e = do
556606 paras [ line $ "Conflicting definitions are in scope for " ++ nm ++ " from the following modules:"
557607 , indent $ paras $ map (line . runModuleName) ms
558608 ]
609+ renderSimpleErrorMessage (ScopeShadowing nm exmn ms) =
610+ paras [ line $ "Shadowed definitions are in scope for " ++ nm ++ " from the following open imports:"
611+ , indent $ paras $ map (line . ("import " ++) . runModuleName) ms
612+ , line $ "These will be ignored and the " ++ case exmn of
613+ Just exmn' -> "declaration from " ++ runModuleName exmn' ++ " will be used."
614+ Nothing -> "local declaration will be used."
615+ ]
559616 renderSimpleErrorMessage (ConflictingTypeDecls nm) =
560617 line $ "Conflicting type declarations for " ++ runProperName nm
561618 renderSimpleErrorMessage (ConflictingCtorDecls nm) =
@@ -745,6 +802,10 @@ prettyPrintSingleError full level e = do
745802 paras [ line $ "An export for " ++ prettyPrintExport x ++ " requires the following to also be exported: "
746803 , indent $ paras $ map (line . prettyPrintExport) ys
747804 ]
805+ renderSimpleErrorMessage (TransitiveDctorExportError x ctor) =
806+ paras [ line $ "An export for " ++ prettyPrintExport x ++ " requires the following data constructor to also be exported: "
807+ , indent $ line $ runProperName ctor
808+ ]
748809 renderSimpleErrorMessage (ShadowedName nm) =
749810 line $ "Name '" ++ showIdent nm ++ "' was shadowed."
750811 renderSimpleErrorMessage (ShadowedTypeVar tv) =
@@ -759,7 +820,7 @@ prettyPrintSingleError full level e = do
759820 renderSimpleErrorMessage (MisleadingEmptyTypeImport mn name) =
760821 line $ "Importing type " ++ runProperName name ++ "(..) from " ++ runModuleName mn ++ " is misleading as it has no exported data constructors."
761822 renderSimpleErrorMessage (ImportHidingModule name) =
762− paras [ line $ "'hiding' imports cannot be used to hide modules."
823+ paras [ line "'hiding' imports cannot be used to hide modules."
763824 , line $ "An attempt was made to hide the import of " ++ runModuleName name
764825 ]
765826 renderSimpleErrorMessage (WildcardInferredType ty) =
@@ -773,14 +834,14 @@ prettyPrintSingleError full level e = do
773834 , indent $ typeAsBox ty
774835 ]
775836 renderSimpleErrorMessage (NotExhaustivePattern bs b) =
776− paras $ [ line "A case expression could not be determined to cover all inputs."
777− , line "The following additional cases are required to cover all inputs:\n"
778− , indent $ paras $
779− [ Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs)) ]
780− ++ [ line "..." | not b ]
781− , line "Or alternatively, add a Partial constraint to the type of the enclosing value."
782− , line "Non-exhaustive patterns for values without a `Partial` constraint will be disallowed in PureScript 0.9."
783− ]
837+ paras [ line "A case expression could not be determined to cover all inputs."
838+ , line "The following additional cases are required to cover all inputs:\n"
839+ , indent $ paras $
840+ [ Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs)) ]
841+ ++ [ line "..." | not b ]
842+ , line "Or alternatively, add a Partial constraint to the type of the enclosing value."
843+ , line "Non-exhaustive patterns for values without a `Partial` constraint will be disallowed in PureScript 0.9."
844+ ]
784845 renderSimpleErrorMessage (OverlappingPattern bs b) =
785846 paras $ [ line "A case expression contains unreachable cases:\n"
786847 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
@@ -793,9 +854,11 @@ prettyPrintSingleError full level e = do
793854 renderSimpleErrorMessage (UnusedImport name) =
794855 line $ "The import of module " ++ runModuleName name ++ " is redundant"
795856
796− renderSimpleErrorMessage (UnusedExplicitImport name names) =
797− paras [ line $ "The import of module " ++ runModuleName name ++ " contains the following unused references:"
798− , indent $ paras $ map line names ]
857+ renderSimpleErrorMessage msg@(UnusedExplicitImport mn names _ _) =
858+ paras [ line $ "The import of module " ++ runModuleName mn ++ " contains the following unused references:"
859+ , indent $ paras $ map line names
860+ , line "It could be replaced with:"
861+ , indent $ line $ showSuggestion msg ]
799862
800863 renderSimpleErrorMessage (UnusedDctorImport name) =
801864 line $ "The import of type " ++ runProperName name ++ " includes data constructors but only the type is used"
@@ -808,15 +871,39 @@ prettyPrintSingleError full level e = do
808871 paras [ line $ "The operator (" ++ name ++ ") was declared as a value rather than an alias for a named function."
809872 , line "Operator aliases are declared by using a fixity declaration, for example:"
810873 , indent $ line $ "infixl 9 someFunction as " ++ name
811− , line $ "Support for value-declared operators will be removed in PureScript 0.9."
874+ , line "Support for value-declared operators will be removed in PureScript 0.9."
812875 ]
813876
877+ renderSimpleErrorMessage (DeprecatedOperatorSection op val) =
878+ paras [ line "An operator section uses legacy syntax. Operator sections are now written using anonymous function syntax:"
879+ , indent $ foldr1 before $
880+ case val of
881+ Left l ->
882+ [ line "("
883+ , prettyPrintValue valueDepth l
884+ , line " "
885+ , renderOperator op
886+ , line " _)"
887+ ]
888+ Right r ->
889+ [ line "(_ "
890+ , renderOperator op
891+ , line " "
892+ , prettyPrintValue valueDepth r
893+ , line ")"
894+ ]
895+ , line "Support for legacy operator sections will be removed in PureScript 0.9."
896+ ]
897+ where
898+ renderOperator (PositionedValue _ _ ex) = renderOperator ex
899+ renderOperator (Var (Qualified _ (Op ident))) = line ident
900+ renderOperator other = Box.hcat Box.top [ line "`", prettyPrintValue valueDepth other, line "`" ]
814901 renderSimpleErrorMessage (DeprecatedQualifiedSyntax name qualName) =
815− paras [ line $ "Import uses the deprecated 'qualified' syntax:"
902+ paras [ line "Import uses the deprecated 'qualified' syntax:"
816903 , indent $ line $ "import qualified " ++ runModuleName name ++ " as " ++ runModuleName qualName
817904 , line "Should instead use the form:"
818905 , indent $ line $ "import " ++ runModuleName name ++ " as " ++ runModuleName qualName
819− , line $ "The deprecated syntax will be removed in PureScript 0.9."
906+ , line "The deprecated syntax will be removed in PureScript 0.9."
820907 ]
821908
822909 renderSimpleErrorMessage (DeprecatedClassImport mn name) =
@@ -824,15 +911,15 @@ prettyPrintSingleError full level e = do
824911 , indent $ line $ runProperName name
825912 , line "Should instead use the form:"
826913 , indent $ line $ "class " ++ runProperName name
827− , line $ "The deprecated syntax will be removed in PureScript 0.9."
914+ , line "The deprecated syntax will be removed in PureScript 0.9."
828915 ]
829916
830917 renderSimpleErrorMessage (DeprecatedClassExport name) =
831− paras [ line $ "Class export uses deprecated syntax that omits the 'class' keyword:"
918+ paras [ line "Class export uses deprecated syntax that omits the 'class' keyword:"
832919 , indent $ line $ runProperName name
833920 , line "Should instead use the form:"
834921 , indent $ line $ "class " ++ runProperName name
835− , line $ "The deprecated syntax will be removed in PureScript 0.9."
922+ , line "The deprecated syntax will be removed in PureScript 0.9."
836923 ]
837924
838925 renderSimpleErrorMessage (RedundantUnqualifiedImport name imp) =
@@ -857,15 +944,35 @@ prettyPrintSingleError full level e = do
857944 renderSimpleErrorMessage (RedundantEmptyHidingImport mn) =
858945 line $ "The import for module " ++ runModuleName mn ++ " is redundant as all members have been explicitly hidden."
859946
860− renderSimpleErrorMessage (ImplicitImport mn refs) =
947+ renderSimpleErrorMessage msg@(ImplicitQualifiedImport importedModule asModule _) =
948+ paras [ line $ "Module " ++ runModuleName importedModule ++ " was imported as " ++ runModuleName asModule ++ " with unspecified imports."
949+ , line $ "As there are multiple modules being imported as " ++ runModuleName asModule ++ ", consider using the explicit form:"
950+ , indent $ line $ showSuggestion msg
951+ ]
952+
953+ renderSimpleErrorMessage msg@(ImplicitImport mn _) =
861954 paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the explicit form: "
955+ , indent $ line $ showSuggestion msg
956+ ]
957+
958+ renderSimpleErrorMessage (HidingImport mn refs) =
959+ paras [ line $ "Module " ++ runModuleName mn ++ " has unspecified imports, consider using the inclusive form: "
862960 , indent $ line $ "import " ++ runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
863961 ]
864962
865963 renderSimpleErrorMessage (CaseBinderLengthDiffers l bs) =
866− paras $ [ line $ "Binder list length differs in case alternative:"
867− , indent $ line $ intercalate ", " $ fmap prettyPrintBinderAtom bs
868− , line $ "Expecting " ++ show l ++ " binder" ++ (if l == 1 then "" else "s") ++ "." ]
964+ paras [ line "Binder list length differs in case alternative:"
965+ , indent $ line $ intercalate ", " $ fmap prettyPrintBinderAtom bs
966+ , line $ "Expecting " ++ show l ++ " binder" ++ (if l == 1 then "" else "s") ++ "."
967+ ]
968+
969+ renderSimpleErrorMessage IncorrectAnonymousArgument =
970+ line "An anonymous function argument appears in an invalid context."
971+
972+ renderSimpleErrorMessage (InvalidOperatorInBinder op fn) =
973+ paras $ [ line $ "Operator " ++ showIdent op ++ " cannot be used in a pattern as it is an alias for function " ++ showIdent fn ++ "."
974+ , line "Only aliases for data constructors may be used in patterns."
975+ ]
869976
870977 renderHint :: ErrorMessageHint -> Box.Box -> Box.Box
871978 renderHint (ErrorUnifyingTypes t1 t2) detail =
@@ -995,38 +1102,13 @@ prettyPrintSingleError full level e = do
9951102 paras :: [Box.Box] -> Box.Box
9961103 paras = Box.vcat Box.left
9971104
998− -- Pretty print and export declaration
999− prettyPrintExport :: DeclarationRef -> String
1000− prettyPrintExport (TypeRef pn _) = runProperName pn
1001− prettyPrintExport ref = prettyPrintRef ref
1002−
1003− prettyPrintRef :: DeclarationRef -> String
1004− prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
1005− prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
1006− prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1007− prettyPrintRef (ValueRef ident) = showIdent ident
1008− prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
1009− prettyPrintRef (ProperRef pn) = runProperName pn
1010− prettyPrintRef (TypeInstanceRef ident) = showIdent ident
1011− prettyPrintRef (ModuleRef name) = "module " ++ runModuleName name
1012− prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
1013−
1014− prettyPrintImport :: ModuleName -> ImportDeclarationType -> Maybe ModuleName -> String
1015− prettyPrintImport mn idt qual =
1016− let i = case idt of
1017− Implicit True -> runModuleName mn ++ " (..)"
1018− Implicit False -> runModuleName mn
1019− Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
1020− Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (map prettyPrintRef refs) ++ ")"
1021− in i ++ maybe "" (\q -> " as " ++ runModuleName q) qual
1022−
10231105 -- | Simplify an error message
10241106 simplifyErrorMessage :: ErrorMessage -> ErrorMessage
10251107 simplifyErrorMessage (ErrorMessage hints simple) = ErrorMessage (simplifyHints hints) simple
10261108 where
10271109 -- Take the last instance of each "hint category"
10281110 simplifyHints :: [ErrorMessageHint] -> [ErrorMessageHint]
1029− simplifyHints = reverse . nubBy categoriesEqual . reverse
1111+ simplifyHints = reverse . nubBy categoriesEqual . stripRedudantHints simple . reverse
10301112
10311113 -- Don't remove hints in the "other" category
10321114 categoriesEqual :: ErrorMessageHint -> ErrorMessageHint -> Bool
@@ -1036,6 +1118,30 @@ prettyPrintSingleError full level e = do
10361118 (_, OtherHint) -> False
10371119 (c1, c2) -> c1 == c2
10381120
1121+ -- | See https://github.com/purescript/purescript/issues/1802
1122+ stripRedudantHints :: SimpleErrorMessage -> [ErrorMessageHint] -> [ErrorMessageHint]
1123+ stripRedudantHints CannotApplyFunction{} = stripFirst isApplicationHint
1124+ where
1125+ isApplicationHint ErrorInApplication{} = True
1126+ isApplicationHint _ = False
1127+ stripRedudantHints ExprDoesNotHaveType{} = stripFirst isCheckHint
1128+ where
1129+ isCheckHint ErrorCheckingType{} = True
1130+ isCheckHint _ = False
1131+ stripRedudantHints TypesDoNotUnify{} = stripFirst isUnifyHint
1132+ where
1133+ isUnifyHint ErrorUnifyingTypes{} = True
1134+ isUnifyHint _ = False
1135+ stripRedudantHints _ = id
1136+
1137+ stripFirst :: (ErrorMessageHint -> Bool) -> [ErrorMessageHint] -> [ErrorMessageHint]
1138+ stripFirst p (PositionedError pos : hs) = PositionedError pos : stripFirst p hs
1139+ stripFirst p (ErrorInModule mn : hs) = ErrorInModule mn : stripFirst p hs
1140+ stripFirst p (hint : hs)
1141+ | p hint = hs
1142+ | otherwise = hint : hs
1143+ stripFirst _ [] = []
1144+
10391145 hintCategory :: ErrorMessageHint -> HintCategory
10401146 hintCategory ErrorCheckingType{} = ExprHint
10411147 hintCategory ErrorInferringType{} = ExprHint
@@ -1047,36 +1153,60 @@ prettyPrintSingleError full level e = do
10471153 hintCategory PositionedError{} = PositionHint
10481154 hintCategory _ = OtherHint
10491155
1156+-- Pretty print and export declaration
1157+prettyPrintExport :: DeclarationRef -> String
1158+prettyPrintExport (TypeRef pn _) = runProperName pn
1159+prettyPrintExport ref = prettyPrintRef ref
1160+
1161+prettyPrintImport :: ModuleName -> ImportDeclarationType -> Maybe ModuleName -> String
1162+prettyPrintImport mn idt qual =
1163+ let i = case idt of
1164+ Implicit -> runModuleName mn
1165+ Explicit refs -> runModuleName mn ++ " (" ++ intercalate ", " (map prettyPrintRef refs) ++ ")"
1166+ Hiding refs -> runModuleName mn ++ " hiding (" ++ intercalate "," (map prettyPrintRef refs) ++ ")"
1167+ in i ++ maybe "" (\q -> " as " ++ runModuleName q) qual
1168+
1169+prettyPrintRef :: DeclarationRef -> String
1170+prettyPrintRef (TypeRef pn Nothing) = runProperName pn ++ "(..)"
1171+prettyPrintRef (TypeRef pn (Just [])) = runProperName pn
1172+prettyPrintRef (TypeRef pn (Just dctors)) = runProperName pn ++ "(" ++ intercalate ", " (map runProperName dctors) ++ ")"
1173+prettyPrintRef (ValueRef ident) = showIdent ident
1174+prettyPrintRef (TypeClassRef pn) = "class " ++ runProperName pn
1175+prettyPrintRef (ProperRef name) = name
1176+prettyPrintRef (TypeInstanceRef ident) = showIdent ident
1177+prettyPrintRef (ModuleRef name) = "module " ++ runModuleName name
1178+prettyPrintRef (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
1179+
10501180-- |
10511181-- Pretty print multiple errors
10521182--
10531183prettyPrintMultipleErrors :: Bool -> MultipleErrors -> String
1054−prettyPrintMultipleErrors full = renderBox . prettyPrintMultipleErrorsBox full
1184+prettyPrintMultipleErrors full = unlines . map renderBox . prettyPrintMultipleErrorsBox full
10551185
10561186-- |
10571187-- Pretty print multiple warnings
10581188--
1059−prettyPrintMultipleWarnings :: Bool -> MultipleErrors -> String
1060−prettyPrintMultipleWarnings full = renderBox . prettyPrintMultipleWarningsBox full
1189+prettyPrintMultipleWarnings :: Bool -> MultipleErrors -> String
1190+prettyPrintMultipleWarnings full = unlines . map renderBox . prettyPrintMultipleWarningsBox full
10611191
10621192-- | Pretty print warnings as a Box
1063−prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> Box.Box
1064−prettyPrintMultipleWarningsBox full = flip evalState defaultUnknownMap . prettyPrintMultipleErrorsWith Warning "Warning found:" "Warning" full
1193+prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> [Box.Box]
1194+prettyPrintMultipleWarningsBox full = prettyPrintMultipleErrorsWith Warning "Warning found:" "Warning" full
10651195
10661196-- | Pretty print errors as a Box
1067−prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> Box.Box
1068−prettyPrintMultipleErrorsBox full = flip evalState defaultUnknownMap . prettyPrintMultipleErrorsWith Error "Error found:" "Error" full
1069−
1070−prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> State TypeMap Box.Box
1071−prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
1072− result <- prettyPrintSingleError full level e
1073− return $
1074− Box.vcat Box.left [ Box.text intro
1075− , result
1076− ]
1077−prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
1078− result <- forM es $ prettyPrintSingleError full level
1079− return $ Box.vsep 1 Box.left $ concat $ zipWith withIntro [1 :: Int ..] result
1197+prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> [Box.Box]
1198+prettyPrintMultipleErrorsBox full = prettyPrintMultipleErrorsWith Error "Error found:" "Error" full
1199+
1200+prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> [Box.Box]
1201+prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) =
1202+ let result = prettyPrintSingleError full level True e
1203+ in [ Box.vcat Box.left [ Box.text intro
1204+ , result
1205+ ]
1206+ ]
1207+prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) =
1208+ let result = map (prettyPrintSingleError full level True) es
1209+ in concat $ zipWith withIntro [1 :: Int ..] result
10801210 where
10811211 withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
10821212 , Box.moveRight 2 err
@@ -1138,9 +1268,15 @@ line :: String -> Box.Box
11381268line = Box.text
11391269
11401270renderBox :: Box.Box -> String
1141−renderBox = unlines . map trimEnd . lines . Box.render
1271+renderBox = unlines
1272+ . map (dropWhileEnd isSpace)
1273+ . dropWhile whiteSpace
1274+ . dropWhileEnd whiteSpace
1275+ . lines
1276+ . Box.render
11421277 where
1143− trimEnd = reverse . dropWhile (== ' ') . reverse
1278+ dropWhileEnd p = reverse . dropWhile p . reverse
1279+ whiteSpace = all isSpace
11441280
11451281-- |
11461282-- Rethrow an error with a more detailed error message in the case of failure
@@ -1148,7 +1284,7 @@ renderBox = unlines . map trimEnd . lines . Box.render
11481284rethrow :: (MonadError e m) => (e -> e) -> m a -> m a
11491285rethrow f = flip catchError $ \e -> throwError (f e)
11501286
1151−reifyErrors :: (Functor m, MonadError e m) => m a -> m (Either e a)
1287+reifyErrors :: (MonadError e m) => m a -> m (Either e a)
11521288reifyErrors ma = catchError (fmap Right ma) (return . Left)
11531289
11541290reflectErrors :: (MonadError e m) => m (Either e a) -> m a
@@ -1175,13 +1311,13 @@ withPosition pos (ErrorMessage hints se) = ErrorMessage (PositionedError pos : h
11751311-- |
11761312-- Collect errors in in parallel
11771313--
1178−parU :: (MonadError MultipleErrors m, Functor m) => [a] -> (a -> m b) -> m [b]
1314+parU :: (MonadError MultipleErrors m) => [a] -> (a -> m b) -> m [b]
11791315parU xs f = forM xs (withError . f) >>= collectErrors
11801316 where
1181− withError :: (MonadError MultipleErrors m, Functor m) => m a -> m (Either MultipleErrors a)
1317+ withError :: (MonadError MultipleErrors m) => m a -> m (Either MultipleErrors a)
11821318 withError u = catchError (Right <$> u) (return . Left)
11831319
1184− collectErrors :: (MonadError MultipleErrors m, Functor m) => [Either MultipleErrors a] -> m [a]
1320+ collectErrors :: (MonadError MultipleErrors m) => [Either MultipleErrors a] -> m [a]
11851321 collectErrors es = case lefts es of
11861322 [] -> return $ rights es
11871323 errs -> throwError $ fold errs