git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge master with feature branch
commit679c93c3551a74c753c6270efda7dd60cfea7cb6 authorPhil Freeman <paf31@cantab.net> dateTue 13 Oct 2015, 17:20 (11 years ago) parent56214498758966
27 files changed+627−645
.gitignore+1 INSTALL.md+12−2 psci/PSCi.hs+2−2 src/Language/PureScript/Errors.hs+327−333 src/Language/PureScript/Linter.hs+4−4 src/Language/PureScript/Linter/Exhaustive.hs+29−20 src/Language/PureScript/Make.hs+3−3 src/Language/PureScript/Names.hs+4 src/Language/PureScript/Parser/Declarations.hs+1−1 src/Language/PureScript/Pretty/Common.hs+11 src/Language/PureScript/Pretty/Kinds.hs+19−15 src/Language/PureScript/Pretty/Types.hs+56−34 src/Language/PureScript/Pretty/Values.hs+92−152 src/Language/PureScript/Sugar/BindingGroups.hs+1−1 src/Language/PureScript/Sugar/CaseDeclarations.hs+1−1 src/Language/PureScript/Sugar/Names.hs+1−1 src/Language/PureScript/Sugar/Names/Exports.hs+2−2 src/Language/PureScript/Sugar/Names/Imports.hs+1−1 src/Language/PureScript/Sugar/Operators.hs+1−1 src/Language/PureScript/Sugar/TypeClasses.hs+1−1 src/Language/PureScript/Sugar/TypeDeclarations.hs+37−33 src/Language/PureScript/TypeChecker.hs+8−8 src/Language/PureScript/TypeChecker/Kinds.hs+2−2 src/Language/PureScript/TypeChecker/Skolems.hs+1−1 src/Language/PureScript/TypeChecker/Subsumption.hs+1−1 src/Language/PureScript/TypeChecker/Types.hs+8−25 src/Language/PureScript/TypeChecker/Unify.hs+1−1
.gitignore+1
@@ -15,3 +15,4 @@ node_modules
1515tmp/
1616.stack-work/
1717tests/support/flattened/
18+output
INSTALL.md+12−2
@@ -24,15 +24,25 @@ requirements.
2424## Compiling from source
2525
2626GHC 7.6.1 or newer is required to compile from source. The easiest way is to
27−use `cabal-install`:
27+use stack:
2828
2929```
30−$ cabal update && cabal install purescript
30+$ stack install purescript
3131```
3232
33+This will then copy the compiler and utilities into `~/.local/bin`.
34+
35+
36+If you don't have stack installed yet there are install instructions
37+[here](https://github.com/commercialhaskell/stack/blob/master/doc/install_and_upgrade.md).
38+
39+If you don't have ghc installed yet, stack will prompt you to run `stack setup`
40+which will install ghc for you.
41+
3342The PureScript compiler has been known to run on OS X 10.6 when built with GHC
34437.6.
3544
45+
3646## The "curses" library
3747
3848`psci` depends on the `curses` library (via the Haskell package `terminfo`). If
psci/PSCi.hs+2−2
@@ -464,7 +464,7 @@ handleCommand (LoadFile filePath) = whenFileExists filePath $ \absPath -> do
464464 Right mods -> PSCI . lift $ modify (updateModules (map ((,) (Right absPath)) mods))
465465handleCommand (LoadForeign filePath) = whenFileExists filePath $ \absPath -> do
466466 foreignsOrError <- psciIO . runMake $ do
467− foreignFile <- makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile absPath)) (readFile absPath)
467+ foreignFile <- makeIO (const (P.ErrorMessage [] $ P.CannotReadFile absPath)) (readFile absPath)
468468 P.parseForeignModulesFromFiles [(absPath, foreignFile)]
469469 case foreignsOrError of
470470 Left err -> PSCI $ outputStrLn $ P.prettyPrintMultipleErrors False err
@@ -533,7 +533,7 @@ loop PSCiOptions{..} = do
533533 historyFilename <- getHistoryFilename
534534 let settings = defaultSettings { historyFile = Just historyFilename }
535535 foreignsOrError <- runMake $ do
536− foreignFilesContent <- forM foreignFiles (\inFile -> (inFile,) <$> makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile inFile)) (readFile inFile))
536+ foreignFilesContent <- forM foreignFiles (\inFile -> (inFile,) <$> makeIO (const (P.ErrorMessage [] $ P.CannotReadFile inFile)) (readFile inFile))
537537 P.parseForeignModulesFromFiles foreignFilesContent
538538 case foreignsOrError of
539539 Left errs -> putStrLn (P.prettyPrintMultipleErrors False errs) >> exitFailure
src/Language/PureScript/Errors.hs+327−333
@@ -20,10 +20,11 @@
2020module Language.PureScript.Errors where
2121
2222import Data.Either (lefts, rights)
23−import Data.List (intercalate, transpose, nub)
23+import Data.List (intercalate, transpose, nub, nubBy, partition)
2424import Data.Function (on)
2525#if __GLASGOW_HASKELL__ < 710
2626import Data.Foldable (fold, foldMap)
27+import Data.Traversable (traverse)
2728#else
2829import Data.Foldable (fold)
2930#endif
@@ -53,9 +54,7 @@ import qualified Text.Parsec as P
5354import qualified Text.Parsec.Error as PE
5455import Text.Parsec.Error (Message(..))
5556
56−-- |
57−-- A type of error messages
58−--
57+-- | A type of error messages
5958data SimpleErrorMessage
6059 = ErrorParsingExterns P.ParseError
6160 | ErrorParsingFFIModule FilePath
@@ -143,45 +142,54 @@ data SimpleErrorMessage
143142 | ShadowedTypeVar String
144143 | UnusedTypeVar String
145144 | WildcardInferredType Type
145+ | MissingTypeDeclaration Ident
146146 | NotExhaustivePattern [[Binder]] Bool
147147 | OverlappingPattern [[Binder]] Bool
148148 | IncompleteExhaustivityCheck
149149 | ClassOperator ProperName Ident
150150 | MisleadingEmptyTypeImport ModuleName ProperName
151151 | ImportHidingModule ModuleName
152− deriving (Show)
153−
154−-- |
155−-- Wrapper of simpler errors
156−--
157−data ErrorMessage
158− = NotYetDefined [Ident] ErrorMessage
159− | ErrorUnifyingTypes Type Type ErrorMessage
160− | ErrorInExpression Expr ErrorMessage
161− | ErrorInModule ModuleName ErrorMessage
162− | ErrorInInstance (Qualified ProperName) [Type] ErrorMessage
163− | ErrorInSubsumption Type Type ErrorMessage
164− | ErrorCheckingType Expr Type ErrorMessage
165− | ErrorCheckingKind Type ErrorMessage
166− | ErrorInferringType Expr ErrorMessage
167− | ErrorInApplication Expr Type Expr ErrorMessage
168− | ErrorInDataConstructor ProperName ErrorMessage
169− | ErrorInTypeConstructor ProperName ErrorMessage
170− | ErrorInBindingGroup [Ident] ErrorMessage
171− | ErrorInDataBindingGroup ErrorMessage
172− | ErrorInTypeSynonym ProperName ErrorMessage
173− | ErrorInValueDeclaration Ident ErrorMessage
174− | ErrorInTypeDeclaration Ident ErrorMessage
175− | ErrorInForeignImport Ident ErrorMessage
176− | PositionedError SourceSpan ErrorMessage
177− | SimpleErrorWrapper SimpleErrorMessage
178− deriving (Show)
152+ deriving Show
153+
154+-- | Error message hints, providing more detailed information about failure.
155+data ErrorMessageHint
156+ = NotYetDefined [Ident]
157+ | ErrorUnifyingTypes Type Type
158+ | ErrorInExpression Expr
159+ | ErrorInModule ModuleName
160+ | ErrorInInstance (Qualified ProperName) [Type]
161+ | ErrorInSubsumption Type Type
162+ | ErrorCheckingType Expr Type
163+ | ErrorCheckingKind Type
164+ | ErrorInferringType Expr
165+ | ErrorInApplication Expr Type Expr
166+ | ErrorInDataConstructor ProperName
167+ | ErrorInTypeConstructor ProperName
168+ | ErrorInBindingGroup [Ident]
169+ | ErrorInDataBindingGroup
170+ | ErrorInTypeSynonym ProperName
171+ | ErrorInValueDeclaration Ident
172+ | ErrorInTypeDeclaration Ident
173+ | ErrorInForeignImport Ident
174+ | PositionedError SourceSpan
175+ deriving Show
176+
177+-- | Categories of hints
178+data HintCategory
179+ = ExprHint
180+ | KindHint
181+ | CheckHint
182+ | PositionHint
183+ | OtherHint
184+ deriving (Show, Eq)
185+
186+data ErrorMessage = ErrorMessage [ErrorMessageHint] SimpleErrorMessage deriving (Show)
179187
180188instance UnificationError Type ErrorMessage where
181− occursCheckFailed t = SimpleErrorWrapper $ InfiniteType t
189+ occursCheckFailed t = ErrorMessage [] $ InfiniteType t
182190
183191instance UnificationError Kind ErrorMessage where
184− occursCheckFailed k = SimpleErrorWrapper $ InfiniteKind k
192+ occursCheckFailed k = ErrorMessage [] $ InfiniteKind k
185193
186194-- |
187195-- Get the error code for a particular error type
@@ -274,6 +282,7 @@ errorCode em = case unwrapErrorMessage em of
274282 ShadowedTypeVar{} -> "ShadowedTypeVar"
275283 UnusedTypeVar{} -> "UnusedTypeVar"
276284 WildcardInferredType{} -> "WildcardInferredType"
285+ MissingTypeDeclaration{} -> "MissingTypeDeclaration"
277286 NotExhaustivePattern{} -> "NotExhaustivePattern"
278287 OverlappingPattern{} -> "OverlappingPattern"
279288 IncompleteExhaustivityCheck{} -> "IncompleteExhaustivityCheck"
@@ -301,7 +310,7 @@ nonEmpty = not . null . runMultipleErrors
301310-- Create an error set from a single simple error message
302311--
303312errorMessage :: SimpleErrorMessage -> MultipleErrors
304−errorMessage err = MultipleErrors [SimpleErrorWrapper err]
313+errorMessage err = MultipleErrors [ErrorMessage [] err]
305314
306315
307316-- |
@@ -310,12 +319,14 @@ errorMessage err = MultipleErrors [SimpleErrorWrapper err]
310319singleError :: ErrorMessage -> MultipleErrors
311320singleError = MultipleErrors . pure
312321
313−-- |
314−-- Lift a function on ErrorMessage to a function on MultipleErrors
315−--
322+-- | Lift a function on ErrorMessage to a function on MultipleErrors
316323onErrorMessages :: (ErrorMessage -> ErrorMessage) -> MultipleErrors -> MultipleErrors
317324onErrorMessages f = MultipleErrors . map f . runMultipleErrors
318325
326+-- | Add a hint to an error message
327+addHint :: ErrorMessageHint -> MultipleErrors -> MultipleErrors
328+addHint hint = onErrorMessages $ \(ErrorMessage hints se) -> ErrorMessage (hint : hints) se
329+
319330-- | The various types of things which might need to be relabelled in errors messages.
320331data LabelType = TypeLabel | SkolemLabel String deriving (Show, Read, Eq, Ord)
321332
@@ -329,27 +340,7 @@ data Level = Error | Warning deriving Show
329340-- Extract nested error messages from wrapper errors
330341--
331342unwrapErrorMessage :: ErrorMessage -> SimpleErrorMessage
332−unwrapErrorMessage em = case em of
333− (ErrorCheckingKind _ err) -> unwrapErrorMessage err
334− (ErrorCheckingType _ _ err) -> unwrapErrorMessage err
335− (ErrorInApplication _ _ _ err) -> unwrapErrorMessage err
336− (ErrorInBindingGroup _ err) -> unwrapErrorMessage err
337− (ErrorInDataBindingGroup err) -> unwrapErrorMessage err
338− (ErrorInDataConstructor _ err) -> unwrapErrorMessage err
339− (ErrorInExpression _ err) -> unwrapErrorMessage err
340− (ErrorInForeignImport _ err) -> unwrapErrorMessage err
341− (ErrorInInstance _ _ err) -> unwrapErrorMessage err
342− (ErrorInModule _ err) -> unwrapErrorMessage err
343− (ErrorInSubsumption _ _ err) -> unwrapErrorMessage err
344− (ErrorInTypeConstructor _ err) -> unwrapErrorMessage err
345− (ErrorInTypeSynonym _ err) -> unwrapErrorMessage err
346− (ErrorInValueDeclaration _ err) -> unwrapErrorMessage err
347− (ErrorInTypeDeclaration _ err) -> unwrapErrorMessage err
348− (ErrorInferringType _ err) -> unwrapErrorMessage err
349− (ErrorUnifyingTypes _ _ err) -> unwrapErrorMessage err
350− (NotYetDefined _ err) -> unwrapErrorMessage err
351− (PositionedError _ err) -> unwrapErrorMessage err
352− (SimpleErrorWrapper sem) -> sem
343+unwrapErrorMessage (ErrorMessage _ se) = se
353344
354345replaceUnknowns :: Type -> State UnknownMap Type
355346replaceUnknowns = everywhereOnTypesM replaceTypes
@@ -365,7 +356,7 @@ replaceUnknowns = everywhereOnTypesM replaceTypes
365356 replaceTypes other = return other
366357
367358onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
368−onTypesInErrorMessageM f = g
359+onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse gHint hints <*> gSimple simple
369360 where
370361 gSimple (InfiniteType t) = InfiniteType <$> f t
371362 gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> f t1 <*> f t2
@@ -375,396 +366,396 @@ onTypesInErrorMessageM f = g
375366 gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
376367 gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
377368 gSimple other = pure other
378− g (ErrorInSubsumption t1 t2 em) = ErrorInSubsumption <$> f t1 <*> f t2 <*> g em
379− g (ErrorUnifyingTypes t1 t2 e) = ErrorUnifyingTypes <$> f t1 <*> f t2 <*> g e
380− g (ErrorCheckingType e t em) = ErrorCheckingType e <$> f t <*> g em
381− g (ErrorCheckingKind t em) = ErrorCheckingKind <$> f t <*> g em
382− g (ErrorInApplication e1 t1 e2 em) = ErrorInApplication e1 <$> f t1 <*> pure e2 <*> g em
383− g (NotYetDefined x e) = NotYetDefined x <$> g e
384− g (ErrorInExpression x e) = ErrorInExpression x <$> g e
385− g (ErrorInModule x e) = ErrorInModule x <$> g e
386− g (ErrorInInstance x y e) = ErrorInInstance x y <$> g e
387− g (ErrorInferringType x e) = ErrorInferringType x <$> g e
388− g (ErrorInDataConstructor x e) = ErrorInDataConstructor x <$> g e
389− g (ErrorInTypeConstructor x e) = ErrorInTypeConstructor x <$> g e
390− g (ErrorInBindingGroup x e) = ErrorInBindingGroup x <$> g e
391− g (ErrorInDataBindingGroup e) = ErrorInDataBindingGroup <$> g e
392− g (ErrorInTypeSynonym x e) = ErrorInTypeSynonym x <$> g e
393− g (ErrorInValueDeclaration x e) = ErrorInValueDeclaration x <$> g e
394− g (ErrorInTypeDeclaration x e) = ErrorInTypeDeclaration x <$> g e
395− g (ErrorInForeignImport x e) = ErrorInForeignImport x <$> g e
396− g (PositionedError x e) = PositionedError x <$> g e
397− g (SimpleErrorWrapper sem) = SimpleErrorWrapper <$> gSimple sem
369+ gHint (ErrorInSubsumption t1 t2) = ErrorInSubsumption <$> f t1 <*> f t2
370+ gHint (ErrorUnifyingTypes t1 t2) = ErrorUnifyingTypes <$> f t1 <*> f t2
371+ gHint (ErrorCheckingType e t) = ErrorCheckingType e <$> f t
372+ gHint (ErrorCheckingKind t) = ErrorCheckingKind <$> f t
373+ gHint (ErrorInApplication e1 t1 e2) = ErrorInApplication e1 <$> f t1 <*> pure e2
374+ gHint other = pure other
398375
399376-- |
400377-- Pretty print a single error, simplifying if necessary
401378--
402379prettyPrintSingleError :: Bool -> Level -> ErrorMessage -> State UnknownMap Box.Box
403−prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
380+prettyPrintSingleError full level e = prettyPrintErrorMessage . positionHintsFirst . reverseHints <$> onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
404381 where
405− -- |
382+
406383 -- Pretty print an ErrorMessage
407− --
408384 prettyPrintErrorMessage :: ErrorMessage -> Box.Box
409− prettyPrintErrorMessage em =
385+ prettyPrintErrorMessage (ErrorMessage hints simple) =
410386 paras $
411− go em:suggestions em ++
387+ map renderHint hints ++
388+ renderSimpleErrorMessage simple :
389+ suggestions simple ++
412390 [line $ "See " ++ wikiUri ++ " for more information, or to contribute content related to this " ++ levelText ++ "."]
413391 where
414392 wikiUri :: String
415393 wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
416394
417− go :: ErrorMessage -> Box.Box
418− goSimple (CannotGetFileInfo path) =
395+ renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
396+ renderSimpleErrorMessage (CannotGetFileInfo path) =
419397 paras [ line "Unable to read file info: "
420398 , indent . line $ path
421399 ]
422− goSimple (CannotReadFile path) =
400+ renderSimpleErrorMessage (CannotReadFile path) =
423401 paras [ line "Unable to read file: "
424402 , indent . line $ path
425403 ]
426− goSimple (CannotWriteFile path) =
404+ renderSimpleErrorMessage (CannotWriteFile path) =
427405 paras [ line "Unable to write file: "
428406 , indent . line $ path
429407 ]
430− goSimple (ErrorParsingExterns err) =
408+ renderSimpleErrorMessage (ErrorParsingExterns err) =
431409 paras [ lineWithLevel "parsing externs files: "
432− , indent . prettyPrintParseError $ err
410+ , prettyPrintParseError err
433411 ]
434− goSimple (ErrorParsingFFIModule path) =
412+ renderSimpleErrorMessage (ErrorParsingFFIModule path) =
435413 paras [ line "Unable to parse module from FFI file: "
436414 , indent . line $ path
437415 ]
438− goSimple (ErrorParsingModule err) =
416+ renderSimpleErrorMessage (ErrorParsingModule err) =
439417 paras [ line "Unable to parse module: "
440− , indent . prettyPrintParseError $ err
418+ , prettyPrintParseError err
441419 ]
442− goSimple (MissingFFIModule mn) =
420+ renderSimpleErrorMessage (MissingFFIModule mn) =
443421 line $ "Missing FFI implementations for module " ++ runModuleName mn
444− goSimple (UnnecessaryFFIModule mn path) =
422+ renderSimpleErrorMessage (UnnecessaryFFIModule mn path) =
445423 paras [ line $ "Unnecessary FFI implementations have been provided for module " ++ runModuleName mn ++ ": "
446424 , indent . line $ path
447425 ]
448− goSimple (MultipleFFIModules mn paths) =
449− paras $ [ line $ "Multiple FFI implementations have been provided for module " ++ runModuleName mn ++ ": " ]
450− ++ map (indent . line) paths
451− goSimple (InvalidExternsFile path) =
426+ renderSimpleErrorMessage (MultipleFFIModules mn paths) =
427+ paras [ line $ "Multiple FFI implementations have been provided for module " ++ runModuleName mn ++ ": "
428+ , indent . paras $ map line paths
429+ ]
430+ renderSimpleErrorMessage (InvalidExternsFile path) =
452431 paras [ line "Externs file is invalid: "
453432 , indent . line $ path
454433 ]
455− goSimple InvalidDoBind =
434+ renderSimpleErrorMessage InvalidDoBind =
456435 line "Bind statement cannot be the last statement in a do block. The last statement must be an expression."
457− goSimple InvalidDoLet =
436+ renderSimpleErrorMessage InvalidDoLet =
458437 line "Let statement cannot be the last statement in a do block. The last statement must be an expression."
459− goSimple CannotReorderOperators =
438+ renderSimpleErrorMessage CannotReorderOperators =
460439 line "Unable to reorder operators"
461− goSimple UnspecifiedSkolemScope =
440+ renderSimpleErrorMessage UnspecifiedSkolemScope =
462441 line "Skolem variable scope is unspecified"
463− goSimple OverlappingNamesInLet =
442+ renderSimpleErrorMessage OverlappingNamesInLet =
464443 line "Overlapping names in let binding."
465− goSimple (InfiniteType ty) =
444+ renderSimpleErrorMessage (InfiniteType ty) =
466445 paras [ line "An infinite type was inferred for an expression: "
467− , indent $ line $ prettyPrintType ty
446+ , indent $ typeAsBox ty
468447 ]
469− goSimple (InfiniteKind ki) =
448+ renderSimpleErrorMessage (InfiniteKind ki) =
470449 paras [ line "An infinite kind was inferred for a type: "
471− , indent $ line $ prettyPrintKind ki
450+ , indent $ kindAsBox ki
472451 ]
473− goSimple (MultipleFixities name) =
452+ renderSimpleErrorMessage (MultipleFixities name) =
474453 line $ "Multiple fixity declarations for " ++ showIdent name
475− goSimple (OrphanTypeDeclaration nm) =
454+ renderSimpleErrorMessage (OrphanTypeDeclaration nm) =
476455 line $ "Orphan type declaration for " ++ showIdent nm
477− goSimple (OrphanFixityDeclaration op) =
456+ renderSimpleErrorMessage (OrphanFixityDeclaration op) =
478457 line $ "Orphan fixity declaration for " ++ show op
479− goSimple (RedefinedModule name filenames) =
480− paras $ line ("Module " ++ runModuleName name ++ " has been defined multiple times:")
481− : map (indent . line . displaySourceSpan) filenames
482− goSimple (RedefinedIdent name) =
458+ renderSimpleErrorMessage (RedefinedModule name filenames) =
459+ paras [ line ("Module " ++ runModuleName name ++ " has been defined multiple times:")
460+ , indent . paras $ map (line . displaySourceSpan) filenames
461+ ]
462+ renderSimpleErrorMessage (RedefinedIdent name) =
483463 line $ "Name " ++ showIdent name ++ " has been defined multiple times"
484− goSimple (UnknownModule mn) =
464+ renderSimpleErrorMessage (UnknownModule mn) =
485465 line $ "Unknown module " ++ runModuleName mn
486− goSimple (UnknownType name) =
466+ renderSimpleErrorMessage (UnknownType name) =
487467 line $ "Unknown type " ++ showQualified runProperName name
488− goSimple (UnknownTypeClass name) =
468+ renderSimpleErrorMessage (UnknownTypeClass name) =
489469 line $ "Unknown type class " ++ showQualified runProperName name
490− goSimple (UnknownValue name) =
470+ renderSimpleErrorMessage (UnknownValue name) =
491471 line $ "Unknown value " ++ showQualified showIdent name
492− goSimple (UnknownTypeConstructor name) =
472+ renderSimpleErrorMessage (UnknownTypeConstructor name) =
493473 line $ "Unknown type constructor " ++ showQualified runProperName name
494− goSimple (UnknownDataConstructor dc tc) =
474+ renderSimpleErrorMessage (UnknownDataConstructor dc tc) =
495475 line $ "Unknown data constructor " ++ showQualified runProperName dc ++ foldMap ((" for type constructor " ++) . showQualified runProperName) tc
496− goSimple (UnknownImportType mn name) =
476+ renderSimpleErrorMessage (UnknownImportType mn name) =
497477 line $ "Module " ++ runModuleName mn ++ " does not export type " ++ runProperName name
498− goSimple (UnknownExportType name) =
478+ renderSimpleErrorMessage (UnknownExportType name) =
499479 line $ "Cannot export unknown type " ++ runProperName name
500− goSimple (UnknownImportTypeClass mn name) =
480+ renderSimpleErrorMessage (UnknownImportTypeClass mn name) =
501481 line $ "Module " ++ runModuleName mn ++ " does not export type class " ++ runProperName name
502− goSimple (UnknownExportTypeClass name) =
482+ renderSimpleErrorMessage (UnknownExportTypeClass name) =
503483 line $ "Cannot export unknown type class " ++ runProperName name
504− goSimple (UnknownImportValue mn name) =
484+ renderSimpleErrorMessage (UnknownImportValue mn name) =
505485 line $ "Module " ++ runModuleName mn ++ " does not export value " ++ showIdent name
506− goSimple (UnknownExportValue name) =
486+ renderSimpleErrorMessage (UnknownExportValue name) =
507487 line $ "Cannot export unknown value " ++ showIdent name
508− goSimple (UnknownExportModule name) =
488+ renderSimpleErrorMessage (UnknownExportModule name) =
509489 line $ "Cannot export unknown module " ++ runModuleName name ++ ", it either does not exist or has not been imported by the current module"
510− goSimple (UnknownImportDataConstructor mn tcon dcon) =
490+ renderSimpleErrorMessage (UnknownImportDataConstructor mn tcon dcon) =
511491 line $ "Module " ++ runModuleName mn ++ " does not export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon
512− goSimple (UnknownExportDataConstructor tcon dcon) =
492+ renderSimpleErrorMessage (UnknownExportDataConstructor tcon dcon) =
513493 line $ "Cannot export data constructor " ++ runProperName dcon ++ " for type " ++ runProperName tcon ++ " as it has not been declared"
514− goSimple (ConflictingImport nm mn) =
494+ renderSimpleErrorMessage (ConflictingImport nm mn) =
515495 line $ "Cannot declare " ++ show nm ++ " since another declaration of that name was imported from " ++ runModuleName mn
516− goSimple (ConflictingImports nm m1 m2) =
496+ renderSimpleErrorMessage (ConflictingImports nm m1 m2) =
517497 line $ "Conflicting imports for " ++ nm ++ " from modules " ++ runModuleName m1 ++ " and " ++ runModuleName m2
518− goSimple (ConflictingTypeDecls nm) =
498+ renderSimpleErrorMessage (ConflictingTypeDecls nm) =
519499 line $ "Conflicting type declarations for " ++ runProperName nm
520− goSimple (ConflictingCtorDecls nm) =
500+ renderSimpleErrorMessage (ConflictingCtorDecls nm) =
521501 line $ "Conflicting data constructor declarations for " ++ runProperName nm
522− goSimple (TypeConflictsWithClass nm) =
502+ renderSimpleErrorMessage (TypeConflictsWithClass nm) =
523503 line $ "Type " ++ runProperName nm ++ " conflicts with type class declaration of the same name"
524− goSimple (CtorConflictsWithClass nm) =
504+ renderSimpleErrorMessage (CtorConflictsWithClass nm) =
525505 line $ "Data constructor " ++ runProperName nm ++ " conflicts with type class declaration of the same name"
526− goSimple (ClassConflictsWithType nm) =
506+ renderSimpleErrorMessage (ClassConflictsWithType nm) =
527507 line $ "Type class " ++ runProperName nm ++ " conflicts with type declaration of the same name"
528− goSimple (ClassConflictsWithCtor nm) =
508+ renderSimpleErrorMessage (ClassConflictsWithCtor nm) =
529509 line $ "Type class " ++ runProperName nm ++ " conflicts with data constructor declaration of the same name"
530− goSimple (DuplicateModuleName mn) =
510+ renderSimpleErrorMessage (DuplicateModuleName mn) =
531511 line $ "Module " ++ runModuleName mn ++ " has been defined multiple times."
532− goSimple (DuplicateClassExport nm) =
512+ renderSimpleErrorMessage (DuplicateClassExport nm) =
533513 line $ "Duplicate export declaration for type class " ++ runProperName nm
534− goSimple (DuplicateValueExport nm) =
514+ renderSimpleErrorMessage (DuplicateValueExport nm) =
535515 line $ "Duplicate export declaration for value " ++ showIdent nm
536− goSimple (CycleInDeclaration nm) =
516+ renderSimpleErrorMessage (CycleInDeclaration nm) =
537517 line $ "Cycle in declaration of " ++ showIdent nm
538− goSimple (CycleInModules mns) =
518+ renderSimpleErrorMessage (CycleInModules mns) =
539519 line $ "Cycle in module dependencies: " ++ intercalate ", " (map runModuleName mns)
540− goSimple (CycleInTypeSynonym pn) =
520+ renderSimpleErrorMessage (CycleInTypeSynonym pn) =
541521 line $ "Cycle in type synonym" ++ foldMap ((" " ++) . runProperName) pn
542− goSimple (NameIsUndefined ident) =
522+ renderSimpleErrorMessage (NameIsUndefined ident) =
543523 line $ showIdent ident ++ " is undefined"
544− goSimple (NameNotInScope ident) =
524+ renderSimpleErrorMessage (NameNotInScope ident) =
545525 line $ showIdent ident ++ " may not be defined in the current scope"
546− goSimple (UndefinedTypeVariable name) =
526+ renderSimpleErrorMessage (UndefinedTypeVariable name) =
547527 line $ "Type variable " ++ runProperName name ++ " is undefined"
548− goSimple (PartiallyAppliedSynonym name) =
528+ renderSimpleErrorMessage (PartiallyAppliedSynonym name) =
549529 paras [ line $ "Partially applied type synonym " ++ showQualified runProperName name
550530 , line "Type synonyms must be applied to all of their type arguments."
551531 ]
552− goSimple (EscapedSkolem binding) =
532+ renderSimpleErrorMessage (EscapedSkolem binding) =
553533 paras $ [ line "A type variable has escaped its scope." ]
554534 <> foldMap (\expr -> [ line "Relevant expression: "
555− , indent $ line $ prettyPrintValue expr
535+ , indent $ prettyPrintValue expr
556536 ]) binding
557− goSimple (TypesDoNotUnify t1 t2)
537+ renderSimpleErrorMessage (TypesDoNotUnify t1 t2)
558538 = paras [ line "Cannot unify type"
559− , indent $ line $ prettyPrintType t1
539+ , indent $ typeAsBox t1
560540 , line "with type"
561− , indent $ line $ prettyPrintType t2
541+ , indent $ typeAsBox t2
562542 ]
563− goSimple (KindsDoNotUnify k1 k2) =
543+ renderSimpleErrorMessage (KindsDoNotUnify k1 k2) =
564544 paras [ line "Cannot unify kind"
565− , indent $ line $ prettyPrintKind k1
545+ , indent $ kindAsBox k1
566546 , line "with kind"
567− , indent $ line $ prettyPrintKind k2
547+ , indent $ kindAsBox k2
568548 ]
569− goSimple (ConstrainedTypeUnified t1 t2) =
549+ renderSimpleErrorMessage (ConstrainedTypeUnified t1 t2) =
570550 paras [ line "Cannot unify constrained type"
571− , indent $ line $ prettyPrintType t1
551+ , indent $ typeAsBox t1
572552 , line "with type"
573− , indent $ line $ prettyPrintType t2
574− ]
575− goSimple (OverlappingInstances nm ts (d : ds)) =
576− paras [ line $ "Overlapping instances found for " ++ showQualified runProperName nm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ ":"
553+ , indent $ typeAsBox t2
554+ ]
555+ renderSimpleErrorMessage (OverlappingInstances nm ts (d : ds)) =
556+ paras [ line "Overlapping instances found for"
557+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
558+ , Box.vcat Box.left (map typeAtomAsBox ts)
559+ ]
560+ , line "The following instances were found:"
577561 , indent $ paras (line (showQualified showIdent d ++ " (chosen)") : map (line . showQualified showIdent) ds)
578562 ]
579− goSimple OverlappingInstances{} = error "OverlappingInstances: empty instance list"
580− goSimple (NoInstanceFound nm ts) =
581− line $ "No instance found for " ++ showQualified runProperName nm ++ " " ++ unwords (map prettyPrintTypeAtom ts)
582− goSimple (PossiblyInfiniteInstance nm ts) =
583− line $ "Instance for " ++ showQualified runProperName nm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ " is possibly infinite."
584− goSimple (CannotDerive nm ts) =
585− line $ "Cannot derive " ++ showQualified runProperName nm ++ " instance for " ++ unwords (map prettyPrintTypeAtom ts)
586− goSimple (CannotFindDerivingType nm) =
563+ renderSimpleErrorMessage OverlappingInstances{} = error "OverlappingInstances: empty instance list"
564+ renderSimpleErrorMessage (NoInstanceFound nm ts) =
565+ paras [ line "No instance found for"
566+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
567+ , Box.vcat Box.left (map typeAtomAsBox ts)
568+ ]
569+ ]
570+ renderSimpleErrorMessage (PossiblyInfiniteInstance nm ts) =
571+ paras [ line "Instance for"
572+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
573+ , Box.vcat Box.left (map typeAtomAsBox ts)
574+ ]
575+ , line "is possibly infinite."
576+ ]
577+ renderSimpleErrorMessage (CannotDerive nm ts) =
578+ paras [ line "Cannot derive an instance for"
579+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
580+ , Box.vcat Box.left (map typeAtomAsBox ts)
581+ ]
582+ ]
583+ renderSimpleErrorMessage (CannotFindDerivingType nm) =
587584 line $ "Cannot derive instance, because the type declaration for " ++ runProperName nm ++ " could not be found."
588− goSimple (DuplicateLabel l expr) =
585+ renderSimpleErrorMessage (DuplicateLabel l expr) =
589586 paras $ [ line $ "Duplicate label " ++ show l ++ " in row." ]
590587 <> foldMap (\expr' -> [ line "Relevant expression: "
591− , indent $ line $ prettyPrintValue expr'
588+ , indent $ prettyPrintValue expr'
592589 ]) expr
593− goSimple (DuplicateTypeArgument name) =
590+ renderSimpleErrorMessage (DuplicateTypeArgument name) =
594591 line $ "Duplicate type argument " ++ show name
595− goSimple (DuplicateValueDeclaration nm) =
592+ renderSimpleErrorMessage (DuplicateValueDeclaration nm) =
596593 line $ "Duplicate value declaration for " ++ showIdent nm
597− goSimple (ArgListLengthsDiffer ident) =
594+ renderSimpleErrorMessage (ArgListLengthsDiffer ident) =
598595 line $ "Argument list lengths differ in declaration " ++ showIdent ident
599− goSimple (OverlappingArgNames ident) =
596+ renderSimpleErrorMessage (OverlappingArgNames ident) =
600597 line $ "Overlapping names in function/binder" ++ foldMap ((" in declaration" ++) . showIdent) ident
601− goSimple (MissingClassMember ident) =
598+ renderSimpleErrorMessage (MissingClassMember ident) =
602599 line $ "Member " ++ showIdent ident ++ " has not been implemented"
603− goSimple (ExtraneousClassMember ident) =
600+ renderSimpleErrorMessage (ExtraneousClassMember ident) =
604601 line $ "Member " ++ showIdent ident ++ " is not a member of the class being instantiated"
605− goSimple (ExpectedType ty kind) =
602+ renderSimpleErrorMessage (ExpectedType ty kind) =
606603 paras [ line "In a type-annotated expression x :: t, the type t must have kind *."
607− , line $ "The error arises from the type " ++ prettyPrintType ty ++ " having the kind " ++ prettyPrintKind kind ++ " instead."
604+ , line "The error arises from the type"
605+ , indent $ typeAsBox ty
606+ , line "having the kind"
607+ , indent $ kindAsBox kind
608+ , line "instead."
608609 ]
609− goSimple (IncorrectConstructorArity nm) =
610+ renderSimpleErrorMessage (IncorrectConstructorArity nm) =
610611 line $ "Wrong number of arguments to constructor " ++ showQualified runProperName nm
611− goSimple SubsumptionCheckFailed = line "Unable to check type subsumption"
612− goSimple (ExprDoesNotHaveType expr ty) =
612+ renderSimpleErrorMessage SubsumptionCheckFailed = line "Unable to check type subsumption"
613+ renderSimpleErrorMessage (ExprDoesNotHaveType expr ty) =
613614 paras [ line "Expression"
614− , indent $ line $ prettyPrintValue expr
615+ , indent $ prettyPrintValue expr
615616 , line "does not have type"
616− , indent $ line $ prettyPrintType ty
617+ , indent $ typeAsBox ty
617618 ]
618− goSimple (PropertyIsMissing prop row) =
619− line $ "Row " ++ prettyPrintRow row ++ " lacks required property " ++ show prop
620− goSimple (CannotApplyFunction fn arg) =
619+ renderSimpleErrorMessage (PropertyIsMissing prop row) =
620+ paras [ line "Row"
621+ , indent $ prettyPrintRowWith '(' ')' row
622+ , line $ "lacks required property " ++ show prop
623+ ]
624+ renderSimpleErrorMessage (CannotApplyFunction fn arg) =
621625 paras [ line "Cannot apply function of type"
622− , indent $ line $ prettyPrintType fn
626+ , indent $ typeAsBox fn
623627 , line "to argument"
624− , indent $ line $ prettyPrintValue arg
628+ , indent $ prettyPrintValue arg
625629 ]
626− goSimple TypeSynonymInstance =
630+ renderSimpleErrorMessage TypeSynonymInstance =
627631 line "Type synonym instances are disallowed"
628− goSimple (OrphanInstance nm cnm ts) =
629− paras [ line $ "Instance " ++ showIdent nm ++ " for " ++ showQualified runProperName cnm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ " is an orphan instance."
632+ renderSimpleErrorMessage (OrphanInstance nm cnm ts) =
633+ paras [ line $ "Instance " ++ showIdent nm ++ " for "
634+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName cnm)
635+ , Box.vcat Box.left (map typeAtomAsBox ts)
636+ ]
637+ , line "is an orphan instance."
630638 , line "An orphan instance is an instance which is defined in neither the class module nor the data type module."
631639 , line "Consider moving the instance, if possible, or using a newtype wrapper."
632640 ]
633− goSimple InvalidNewtype =
641+ renderSimpleErrorMessage InvalidNewtype =
634642 line "Newtypes must define a single constructor with a single argument"
635− goSimple (InvalidInstanceHead ty) =
643+ renderSimpleErrorMessage (InvalidInstanceHead ty) =
636644 paras [ line "Invalid type in class instance head:"
637− , indent $ line $ prettyPrintType ty
645+ , indent $ typeAsBox ty
638646 ]
639− goSimple (TransitiveExportError x ys) =
647+ renderSimpleErrorMessage (TransitiveExportError x ys) =
640648 paras $ line ("An export for " ++ prettyPrintExport x ++ " requires the following to also be exported: ")
641649 : map (line . prettyPrintExport) ys
642− goSimple (ShadowedName nm) =
650+ renderSimpleErrorMessage (ShadowedName nm) =
643651 line $ "Name '" ++ showIdent nm ++ "' was shadowed"
644− goSimple (ShadowedTypeVar tv) =
652+ renderSimpleErrorMessage (ShadowedTypeVar tv) =
645653 line $ "Type variable '" ++ tv ++ "' was shadowed"
646− goSimple (UnusedTypeVar tv) =
654+ renderSimpleErrorMessage (UnusedTypeVar tv) =
647655 line $ "Type variable '" ++ tv ++ "' was declared but not used"
648− goSimple (ClassOperator className opName) =
656+ renderSimpleErrorMessage (ClassOperator className opName) =
649657 paras [ line $ "Class '" ++ runProperName className ++ "' declares operator " ++ showIdent opName ++ "."
650− , indent $ line "This may be disallowed in the future - consider declaring a named member in the class and making the operator an alias:"
651− , indent $ line $ showIdent opName ++ " = someMember"
658+ , line "This may be disallowed in the future - consider declaring a named member in the class and making the operator an alias:"
659+ , indent . line $ showIdent opName ++ " = someMember"
652660 ]
653− goSimple (MisleadingEmptyTypeImport mn name) =
661+ renderSimpleErrorMessage (MisleadingEmptyTypeImport mn name) =
654662 line $ "Importing type " ++ runProperName name ++ "(..) from " ++ runModuleName mn ++ " is misleading as it has no exported data constructors"
655− goSimple (ImportHidingModule name) =
663+ renderSimpleErrorMessage (ImportHidingModule name) =
656664 line $ "Attempted to hide module " ++ runModuleName name ++ " in import expression, this is not permitted"
657− goSimple (WildcardInferredType ty) =
658− line $ "The wildcard type definition has the inferred type " ++ prettyPrintType ty
659− goSimple (NotExhaustivePattern bs b) =
665+ renderSimpleErrorMessage (WildcardInferredType ty) =
666+ paras [ line "The wildcard type definition has the inferred type "
667+ , indent $ typeAsBox ty
668+ ]
669+ renderSimpleErrorMessage (MissingTypeDeclaration ident) =
670+ paras [ line $ "No type declaration was provided for the top-level declaration of " ++ showIdent ident ++ "."
671+ , line "It is good practice to provide type declarations as a form of documentation."
672+ , line "Consider using a type wildcard to display the inferred type:"
673+ , indent $ line $ showIdent ident ++ " :: _"
674+ ]
675+ renderSimpleErrorMessage (NotExhaustivePattern bs b) =
660676 paras $ [ line "A case expression could not be determined to cover all inputs."
661677 , line "The following additional cases are required to cover all inputs:\n"
662678 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
663679 ] ++
664680 [ line "..." | not b ]
665− goSimple (OverlappingPattern bs b) =
681+ renderSimpleErrorMessage (OverlappingPattern bs b) =
666682 paras $ [ line "A case expression contains unreachable cases:\n"
667683 , Box.hsep 1 Box.left (map (paras . map (line . prettyPrintBinderAtom)) (transpose bs))
668684 ] ++
669685 [ line "..." | not b ]
670− goSimple IncompleteExhaustivityCheck =
686+ renderSimpleErrorMessage IncompleteExhaustivityCheck =
671687 paras [ line "An exhaustivity check was abandoned due to too many possible cases."
672688 , line "You may want to decomposing your data types into smaller types."
673689 ]
674− go (NotYetDefined names err) =
675− paras [ line $ "The following are not yet defined here: " ++ intercalate ", " (map showIdent names) ++ ":"
676− , indent $ go err
677− ]
678− go (ErrorUnifyingTypes t1 t2 err) =
690+
691+ renderHint :: ErrorMessageHint -> Box.Box
692+ renderHint (NotYetDefined names) =
693+ line $ "The following are not yet defined here: " ++ intercalate ", " (map showIdent names) ++ ":"
694+ renderHint (ErrorUnifyingTypes t1 t2) =
679695 paras [ lineWithLevel "unifying type "
680− , indent $ line $ prettyPrintType t1
696+ , indent $ typeAsBox t1
681697 , line "with type"
682− , indent $ line $ prettyPrintType t2
683− , go err
698+ , indent $ typeAsBox t2
684699 ]
685− go (ErrorInExpression expr err) =
700+ renderHint (ErrorInExpression expr) =
686701 paras [ lineWithLevel "in expression:"
687− , indent $ line $ prettyPrintValue expr
688− , go err
702+ , indent $ prettyPrintValue expr
689703 ]
690− go (ErrorInModule mn err) =
704+ renderHint (ErrorInModule mn) =
691705 paras [ lineWithLevel $ "in module " ++ runModuleName mn ++ ":"
692− , go err
693706 ]
694− go (ErrorInSubsumption t1 t2 err) =
707+ renderHint (ErrorInSubsumption t1 t2) =
695708 paras [ lineWithLevel "checking that type "
696− , indent $ line $ prettyPrintType t1
709+ , indent $ typeAsBox t1
697710 , line "subsumes type"
698− , indent $ line $ prettyPrintType t2
699− , go err
711+ , indent $ typeAsBox t2
700712 ]
701− go (ErrorInInstance name ts err) =
702− paras [ lineWithLevel $ "in type class instance " ++ showQualified runProperName name ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ ":"
703− , go err
713+ renderHint (ErrorInInstance nm ts) =
714+ paras [ lineWithLevel "in type class instance"
715+ , indent $ Box.hsep 1 Box.left [ line (showQualified runProperName nm)
716+ , Box.vcat Box.left (map typeAtomAsBox ts)
717+ ]
704718 ]
705− go (ErrorCheckingKind ty err) =
719+ renderHint (ErrorCheckingKind ty) =
706720 paras [ lineWithLevel "checking kind of type "
707− , indent $ line $ prettyPrintType ty
708− , go err
721+ , indent $ typeAsBox ty
709722 ]
710− go (ErrorInferringType expr err) =
723+ renderHint (ErrorInferringType expr) =
711724 paras [ lineWithLevel "inferring type of value "
712− , indent $ line $ prettyPrintValue expr
713− , go err
725+ , indent $ prettyPrintValue expr
714726 ]
715− go (ErrorCheckingType expr ty err) =
727+ renderHint (ErrorCheckingType expr ty) =
716728 paras [ lineWithLevel "checking that value "
717− , indent $ line $ prettyPrintValue expr
729+ , indent $ prettyPrintValue expr
718730 , line "has type"
719− , indent $ line $ prettyPrintType ty
720− , go err
731+ , indent $ typeAsBox ty
721732 ]
722− go (ErrorInApplication f t a err) =
733+ renderHint (ErrorInApplication f t a) =
723734 paras [ lineWithLevel "applying function"
724− , indent $ line $ prettyPrintValue f
735+ , indent $ prettyPrintValue f
725736 , line "of type"
726− , indent $ line $ prettyPrintType t
737+ , indent $ typeAsBox t
727738 , line "to argument"
728− , indent $ line $ prettyPrintValue a
729− , go err
730− ]
731− go (ErrorInDataConstructor nm err) =
732− paras [ lineWithLevel $ "in data constructor " ++ runProperName nm ++ ":"
733− , go err
734− ]
735− go (ErrorInTypeConstructor nm err) =
736− paras [ lineWithLevel $ "in type constructor " ++ runProperName nm ++ ":"
737− , go err
738− ]
739− go (ErrorInBindingGroup nms err) =
740− paras [ lineWithLevel $ "in binding group " ++ intercalate ", " (map showIdent nms) ++ ":"
741− , go err
742− ]
743− go (ErrorInDataBindingGroup err) =
744− paras [ lineWithLevel "in data binding group:"
745− , go err
746− ]
747− go (ErrorInTypeSynonym name err) =
748− paras [ lineWithLevel $ "in type synonym " ++ runProperName name ++ ":"
749− , go err
750− ]
751− go (ErrorInValueDeclaration n err) =
752− paras [ lineWithLevel $ "in value declaration " ++ showIdent n ++ ":"
753− , go err
754− ]
755− go (ErrorInTypeDeclaration n err) =
756− paras [ lineWithLevel $ "in type declaration for " ++ showIdent n ++ ":"
757− , go err
758− ]
759− go (ErrorInForeignImport nm err) =
760− paras [ lineWithLevel $ "in foreign import " ++ showIdent nm ++ ":"
761− , go err
762− ]
763− go (PositionedError srcSpan err) =
764− paras [ lineWithLevel $ "at " ++ displaySourceSpan srcSpan ++ ":"
765− , indent $ go err
766− ]
767− go (SimpleErrorWrapper sem) = goSimple sem
739+ , indent $ prettyPrintValue a
740+ ]
741+ renderHint (ErrorInDataConstructor nm) =
742+ lineWithLevel $ "in data constructor " ++ runProperName nm ++ ":"
743+ renderHint (ErrorInTypeConstructor nm) =
744+ lineWithLevel $ "in type constructor " ++ runProperName nm ++ ":"
745+ renderHint (ErrorInBindingGroup nms) =
746+ lineWithLevel $ "in binding group " ++ intercalate ", " (map showIdent nms) ++ ":"
747+ renderHint ErrorInDataBindingGroup =
748+ lineWithLevel "in data binding group:"
749+ renderHint (ErrorInTypeSynonym name) =
750+ lineWithLevel $ "in type synonym " ++ runProperName name ++ ":"
751+ renderHint (ErrorInValueDeclaration n) =
752+ lineWithLevel $ "in value declaration " ++ showIdent n ++ ":"
753+ renderHint (ErrorInTypeDeclaration n) =
754+ lineWithLevel $ "in type declaration for " ++ showIdent n ++ ":"
755+ renderHint (ErrorInForeignImport nm) =
756+ lineWithLevel $ "in foreign import " ++ showIdent nm ++ ":"
757+ renderHint (PositionedError srcSpan) =
758+ lineWithLevel $ "at " ++ displaySourceSpan srcSpan ++ ":"
768759
769760 lineWithLevel :: String -> Box.Box
770761 lineWithLevel text = line $ show level ++ " " ++ text
@@ -774,23 +765,19 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
774765 Error -> "error"
775766 Warning -> "warning"
776767
777− suggestions :: ErrorMessage -> [Box.Box]
778− suggestions = suggestions' . unwrapErrorMessage
779− where
780− suggestions' (ConflictingImport nm im) = [ line $ "Possible fix: hide " ++ show nm ++ " when importing " ++ runModuleName im ++ ":"
768+ suggestions :: SimpleErrorMessage -> [Box.Box]
769+ suggestions (ConflictingImport nm im) = [ line $ "Possible fix: hide " ++ show nm ++ " when importing " ++ runModuleName im ++ ":"
781770 , indent . line $ "import " ++ runModuleName im ++ " hiding (" ++ nm ++ ")"
782771 ]
783− suggestions' (TypesDoNotUnify t1 t2)
784− | isObject t1 && isFunction t2 = [line "Note that function composition in PureScript is defined using (<<<)"]
785− | otherwise = []
786− suggestions' _ = []
772+ suggestions (TypesDoNotUnify t1 t2)
773+ | isObject t1 && isFunction t2 = [line "Note that function composition in PureScript is defined using (<<<)"]
774+ | otherwise = []
775+ suggestions _ = []
787776
788777 paras :: [Box.Box] -> Box.Box
789778 paras = Box.vcat Box.left
790779
791− -- |
792780 -- Pretty print and export declaration
793− --
794781 prettyPrintExport :: DeclarationRef -> String
795782 prettyPrintExport (TypeRef pn _) = runProperName pn
796783 prettyPrintExport (ValueRef ident) = showIdent ident
@@ -799,38 +786,44 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
799786 prettyPrintExport (ModuleRef name) = "module " ++ runModuleName name
800787 prettyPrintExport (PositionedDeclarationRef _ _ ref) = prettyPrintExport ref
801788
802− -- |
803− -- Simplify an error message
804− --
805− simplifyErrorMessage :: ErrorMessage -> ErrorMessage
806− simplifyErrorMessage = unwrap Nothing
789+ -- Hints get added at the front, so we need to reverse them before rendering
790+ reverseHints :: ErrorMessage -> ErrorMessage
791+ reverseHints (ErrorMessage hints simple) = ErrorMessage (reverse hints) simple
792+
793+ -- | Put positional hints at the front of the list
794+ positionHintsFirst :: ErrorMessage -> ErrorMessage
795+ positionHintsFirst (ErrorMessage hints simple) = ErrorMessage (uncurry (++) $ partition (isPositionHint . hintCategory) hints) simple
807796 where
808− unwrap :: Maybe SourceSpan -> ErrorMessage -> ErrorMessage
809− unwrap pos (ErrorInExpression _ err) = unwrap pos err
810− unwrap pos (ErrorInInstance name ts err) = ErrorInInstance name ts (unwrap pos err)
811− unwrap pos (ErrorInSubsumption t1 t2 err) = ErrorInSubsumption t1 t2 (unwrap pos err)
812− unwrap pos (ErrorUnifyingTypes _ _ err) = unwrap pos err
813− unwrap pos (ErrorInferringType _ err) = unwrap pos err
814− unwrap pos (ErrorCheckingType _ _ err) = unwrap pos err
815− unwrap pos (ErrorCheckingKind ty err) = ErrorCheckingKind ty (unwrap pos err)
816− unwrap pos (ErrorInModule mn err) = ErrorInModule mn (unwrap pos err)
817− unwrap pos (ErrorInApplication _ _ _ err) = unwrap pos err
818− unwrap pos (ErrorInDataConstructor nm err) = ErrorInDataConstructor nm (unwrap pos err)
819− unwrap pos (ErrorInTypeConstructor nm err) = ErrorInTypeConstructor nm (unwrap pos err)
820− unwrap pos (ErrorInBindingGroup nms err) = ErrorInBindingGroup nms (unwrap pos err)
821− unwrap pos (ErrorInDataBindingGroup err) = ErrorInDataBindingGroup (unwrap pos err)
822− unwrap pos (ErrorInTypeSynonym nm err) = ErrorInTypeSynonym nm (unwrap pos err)
823− unwrap pos (ErrorInValueDeclaration nm err) = ErrorInValueDeclaration nm (unwrap pos err)
824− unwrap pos (ErrorInTypeDeclaration nm err) = ErrorInTypeDeclaration nm (unwrap pos err)
825− unwrap pos (ErrorInForeignImport nm err) = ErrorInForeignImport nm (unwrap pos err)
826− unwrap pos (NotYetDefined ns err) = NotYetDefined ns (unwrap pos err)
827− unwrap _ (PositionedError pos err) = unwrap (Just pos) err
828− unwrap pos other = wrap pos other
829−
830− wrap :: Maybe SourceSpan -> ErrorMessage -> ErrorMessage
831− wrap Nothing = id
832− wrap (Just pos) = PositionedError pos
797+ isPositionHint :: HintCategory -> Bool
798+ isPositionHint PositionHint = True
799+ isPositionHint OtherHint = True
800+ isPositionHint _ = False
833801
802+ -- | Simplify an error message
803+ simplifyErrorMessage :: ErrorMessage -> ErrorMessage
804+ simplifyErrorMessage (ErrorMessage hints simple) = ErrorMessage (simplifyHints hints) simple
805+ where
806+ -- Take the last instance of each "hint category"
807+ simplifyHints :: [ErrorMessageHint] -> [ErrorMessageHint]
808+ simplifyHints = reverse . nubBy categoriesEqual . reverse
809+
810+ -- Don't remove hints in the "other" category
811+ categoriesEqual :: ErrorMessageHint -> ErrorMessageHint -> Bool
812+ categoriesEqual x y =
813+ case (hintCategory x, hintCategory y) of
814+ (OtherHint, _) -> False
815+ (_, OtherHint) -> False
816+ (c1, c2) -> c1 == c2
817+
818+ hintCategory :: ErrorMessageHint -> HintCategory
819+ hintCategory ErrorCheckingType{} = ExprHint
820+ hintCategory ErrorInferringType{} = ExprHint
821+ hintCategory ErrorInExpression{} = ExprHint
822+ hintCategory ErrorUnifyingTypes{} = CheckHint
823+ hintCategory ErrorInSubsumption{} = CheckHint
824+ hintCategory ErrorInApplication{} = CheckHint
825+ hintCategory PositionedError{} = PositionHint
826+ hintCategory _ = OtherHint
834827
835828-- |
836829-- Pretty print multiple errors
@@ -846,11 +839,11 @@ prettyPrintMultipleWarnings full = renderBox . prettyPrintMultipleWarningsBox fu
846839
847840-- | Pretty print warnings as a Box
848841prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> Box.Box
849−prettyPrintMultipleWarningsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Warning "Warning found:" "Multiple warnings found:" full
842+prettyPrintMultipleWarningsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Warning "Warning found:" "Warning" full
850843
851844-- | Pretty print errors as a Box
852845prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> Box.Box
853−prettyPrintMultipleErrorsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Error "Error found:" "Multiple errors found:" full
846+prettyPrintMultipleErrorsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Error "Error found:" "Error" full
854847
855848prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> State UnknownMap Box.Box
856849prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
@@ -860,11 +853,12 @@ prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
860853 , result
861854 ]
862855prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
863− result <- forM es $ liftM (Box.moveRight 2) . prettyPrintSingleError full level
864− return $
865− Box.vcat Box.left [ Box.text intro
866− , Box.vsep 1 Box.left result
867− ]
856+ result <- forM es $ prettyPrintSingleError full level
857+ return $ Box.vsep 1 Box.left $ concat $ zipWith withIntro [1 :: Int ..] result
858+ where
859+ withIntro i err = [ Box.text (intro ++ " " ++ show i ++ " of " ++ show (length es) ++ ":")
860+ , Box.moveRight 2 err
861+ ]
868862
869863-- | Pretty print a Parsec ParseError as a Box
870864prettyPrintParseError :: P.ParseError -> Box.Box
@@ -914,8 +908,9 @@ prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEnd
914908
915909 clean = nub . filter (not . null)
916910
911+-- | Indent to the right, and pad on top and bottom.
917912indent :: Box.Box -> Box.Box
918−indent = Box.moveRight 2
913+indent = Box.moveUp 1 . Box.moveDown 1 . Box.moveRight 2
919914
920915line :: String -> Box.Box
921916line = Box.text
@@ -955,8 +950,7 @@ warnAndRethrowWithPosition :: (MonadError MultipleErrors m, MonadWriter Multiple
955950warnAndRethrowWithPosition pos = rethrowWithPosition pos . warnWithPosition pos
956951
957952withPosition :: SourceSpan -> ErrorMessage -> ErrorMessage
958−withPosition _ (PositionedError pos err) = withPosition pos err
959−withPosition pos err = PositionedError pos err
953+withPosition pos (ErrorMessage hints se) = ErrorMessage (PositionedError pos : hints) se
960954
961955-- |
962956-- Collect errors in in parallel
src/Language/PureScript/Linter.hs+4−4
@@ -40,7 +40,7 @@ import Language.PureScript.Linter.Exhaustive as L
4040-- |
4141-- | Right now, this pass only performs a shadowing check.
4242lint :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Module -> m ()
43−lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_ lintDeclaration ds
43+lint (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ mapM_ lintDeclaration ds
4444 where
4545 moduleNames :: S.Set Ident
4646 moduleNames = S.fromList (nub (mapMaybe getDeclIdent ds))
@@ -58,9 +58,9 @@ lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_
5858 let (f, _, _, _, _) = everythingWithContextOnValues moduleNames mempty mappend stepD stepE stepB def def
5959
6060 f' :: Declaration -> MultipleErrors
61− f' (PositionedDeclaration pos _ dec) = onErrorMessages (PositionedError pos) (f' dec)
62− f' dec@(ValueDeclaration name _ _ _) = onErrorMessages (ErrorInValueDeclaration name) (f dec <> checkTypeVarsInDecl dec)
63− f' (TypeDeclaration name ty) = onErrorMessages (ErrorInTypeDeclaration name) (checkTypeVars ty)
61+ f' (PositionedDeclaration pos _ dec) = addHint (PositionedError pos) (f' dec)
62+ f' dec@(ValueDeclaration name _ _ _) = addHint (ErrorInValueDeclaration name) (f dec <> checkTypeVarsInDecl dec)
63+ f' (TypeDeclaration name ty) = addHint (ErrorInTypeDeclaration name) (checkTypeVars ty)
6464 f' dec = f dec <> checkTypeVarsInDecl dec
6565
6666 in tell (f' d)
src/Language/PureScript/Linter/Exhaustive.hs+29−20
@@ -46,8 +46,6 @@ import Language.PureScript.Kinds
4646import Language.PureScript.Types as P
4747import Language.PureScript.Errors
4848
49−import Language.PureScript.AST.Traversals (everywhereOnValuesTopDownM)
50−
5149-- | There are two modes of failure for the redudancy check:
5250--
5351-- 1. Exhaustivity was incomeplete due to too many cases, so we couldn't determine redundancy.
@@ -273,28 +271,39 @@ checkExhaustive env mn numArgs cas = makeResult . first nub $ foldl' step ([init
273271-- Exhaustivity checking over a list of declarations
274272--
275273checkExhaustiveDecls :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> ModuleName -> [Declaration] -> m ()
276−checkExhaustiveDecls env mn ds =
277− let (f, _, _) = everywhereOnValuesTopDownM return checkExpr return
274+checkExhaustiveDecls env mn = mapM_ onDecl
275+ where
276+ onDecl :: Declaration -> m ()
277+ onDecl (BindingGroupDeclaration bs) = mapM_ (onDecl . convert) bs
278+ where
279+ convert :: (Ident, NameKind, Expr) -> Declaration
280+ convert (name, nk, e) = ValueDeclaration name nk [] (Right e)
281+ onDecl (ValueDeclaration name _ _ (Right e)) = censor (addHint (ErrorInValueDeclaration name)) (onExpr e)
282+ onDecl (PositionedDeclaration pos _ dec) = censor (addHint (PositionedError pos)) (onDecl dec)
283+ onDecl _ = return ()
278284
279− f' :: Declaration -> m Declaration
280− f' d@(BindingGroupDeclaration bs) = mapM_ (f' . convert) bs >> return d
281− where
282− convert :: (Ident, NameKind, Expr) -> Declaration
283− convert (name, nk, e) = ValueDeclaration name nk [] (Right e)
284− f' d@(ValueDeclaration name _ _ _) = censor (onErrorMessages (ErrorInValueDeclaration name)) $ f d
285− f' (PositionedDeclaration pos com dec) = PositionedDeclaration pos com <$> censor (onErrorMessages (PositionedError pos)) (f' dec)
286− -- Don't generate two warnings for desugared dictionaries.
287− f' d@TypeInstanceDeclaration{} = return d
288− f' d = f d
285+ onExpr :: Expr -> m ()
286+ onExpr (UnaryMinus e) = onExpr e
287+ onExpr (ArrayLiteral es) = mapM_ onExpr es
288+ onExpr (ObjectLiteral es) = mapM_ (onExpr . snd) es
289+ onExpr (TypeClassDictionaryConstructorApp _ e) = onExpr e
290+ onExpr (Accessor _ e) = onExpr e
291+ onExpr (ObjectUpdate o es) = onExpr o >> mapM_ (onExpr . snd) es
292+ onExpr (Abs _ e) = onExpr e
293+ onExpr (App e1 e2) = onExpr e1 >> onExpr e2
294+ onExpr (IfThenElse e1 e2 e3) = onExpr e1 >> onExpr e2 >> onExpr e3
295+ onExpr (Case es cas) = checkExhaustive env mn (length es) cas >> mapM_ onExpr es >> mapM_ onCaseAlternative cas
296+ onExpr (TypedValue _ e _) = onExpr e
297+ onExpr (Let ds e) = mapM_ onDecl ds >> onExpr e
298+ onExpr (PositionedValue pos _ e) = censor (addHint (PositionedError pos)) (onExpr e)
299+ onExpr _ = return ()
289300
290− in mapM_ f' ds
291− where
292− checkExpr :: Expr -> m Expr
293− checkExpr c@(Case expr cas) = checkExhaustive env mn (length expr) cas >> return c
294− checkExpr other = return other
301+ onCaseAlternative :: CaseAlternative -> m ()
302+ onCaseAlternative (CaseAlternative _ (Left es)) = mapM_ (\(e, g) -> onExpr e >> onExpr g) es
303+ onCaseAlternative (CaseAlternative _ (Right e)) = onExpr e
295304
296305-- |
297306-- Exhaustivity checking over a single module
298307--
299308checkExhaustiveModule :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> Module -> m ()
300−checkExhaustiveModule env (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds
309+checkExhaustiveModule env (Module _ _ mn ds _) = censor (addHint (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds
src/Language/PureScript/Make.hs+3−3
@@ -365,15 +365,15 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
365365 requiresForeign = not . null . CF.moduleForeign
366366
367367 getTimestamp :: FilePath -> Make (Maybe UTCTime)
368− getTimestamp path = makeIO (const (SimpleErrorWrapper $ CannotGetFileInfo path)) $ do
368+ getTimestamp path = makeIO (const (ErrorMessage [] $ CannotGetFileInfo path)) $ do
369369 exists <- doesFileExist path
370370 traverse (const $ getModificationTime path) $ guard exists
371371
372372 readTextFile :: FilePath -> Make B.ByteString
373− readTextFile path = makeIO (const (SimpleErrorWrapper $ CannotReadFile path)) $ B.readFile path
373+ readTextFile path = makeIO (const (ErrorMessage [] $ CannotReadFile path)) $ B.readFile path
374374
375375 writeTextFile :: FilePath -> B.ByteString -> Make ()
376− writeTextFile path text = makeIO (const (SimpleErrorWrapper $ CannotWriteFile path)) $ do
376+ writeTextFile path text = makeIO (const (ErrorMessage [] $ CannotWriteFile path)) $ do
377377 mkdirp path
378378 B.writeFile path text
379379 where
src/Language/PureScript/Names.hs+4
@@ -104,6 +104,10 @@ qualify _ (Qualified (Just m) a) = (m, a)
104104mkQualified :: a -> ModuleName -> Qualified a
105105mkQualified name mn = Qualified (Just mn) name
106106
107+-- | Remove the module name from a qualified name
108+disqualify :: Qualified a -> a
109+disqualify (Qualified _ a) = a
110+
107111-- |
108112-- Checks whether a qualified value is actually qualified with a module reference
109113--
src/Language/PureScript/Parser/Declarations.hs+1−1
@@ -293,7 +293,7 @@ parseModulesFromFiles toFilePath input = do
293293 collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ]
294294
295295toPositionedError :: P.ParseError -> ErrorMessage
296−toPositionedError perr = PositionedError (SourceSpan name start end) (SimpleErrorWrapper (ErrorParsingModule perr))
296+toPositionedError perr = ErrorMessage [ PositionedError (SourceSpan name start end) ] (ErrorParsingModule perr)
297297 where
298298 name = (P.sourceName . P.errorPos) perr
299299 start = (toSourcePos . P.errorPos) perr
src/Language/PureScript/Pretty/Common.hs+11
@@ -17,8 +17,11 @@ module Language.PureScript.Pretty.Common where
1717
1818import Control.Monad.State
1919import Data.List (intercalate)
20+
2021import Language.PureScript.Parser.Lexer (reservedPsNames, opChars)
2122
23+import Text.PrettyPrint.Boxes
24+
2225-- |
2326-- Wrap a string in parentheses
2427--
@@ -67,3 +70,11 @@ prettyPrintObjectKey :: String -> String
6770prettyPrintObjectKey s | s `elem` reservedPsNames = show s
6871 | any (`elem` opChars) s = show s
6972 | otherwise = s
73+
74+-- | Place a box before another, vertically when the first box takes up multiple lines.
75+before :: Box -> Box -> Box
76+before b1 b2 | rows b1 > 1 = b1 // b2
77+ | otherwise = b1 <> b2
78+
79+beforeWithSpace :: Box -> Box -> Box
80+beforeWithSpace b1 = before (b1 <> text " ")
src/Language/PureScript/Pretty/Kinds.hs+19−15
@@ -14,7 +14,8 @@
1414-----------------------------------------------------------------------------
1515
1616module Language.PureScript.Pretty.Kinds (
17− prettyPrintKind
17+ prettyPrintKind,
18+ kindAsBox
1819) where
1920
2021import Data.Maybe (fromMaybe)
@@ -23,14 +24,15 @@ import Control.Arrow (ArrowPlus(..))
2324import Control.PatternArrows
2425
2526import Language.PureScript.Kinds
26−import Language.PureScript.Pretty.Common
2727
28−typeLiterals :: Pattern () Kind String
28+import Text.PrettyPrint.Boxes (Box(), text, render, (<>))
29+
30+typeLiterals :: Pattern () Kind Box
2931typeLiterals = mkPattern match
3032 where
31− match Star = Just "*"
32− match Bang = Just "!"
33− match (KUnknown u) = Just $ 'u' : show u
33+ match Star = Just $ text "*"
34+ match Bang = Just $ text "!"
35+ match (KUnknown u) = Just $ text $ 'u' : show u
3436 match _ = Nothing
3537
3638matchRow :: Pattern () Kind ((), Kind)
@@ -45,15 +47,17 @@ funKind = mkPattern match
4547 match (FunKind arg ret) = Just (arg, ret)
4648 match _ = Nothing
4749
48−-- |
49−-- Generate a pretty-printed string representing a Kind
50−--
50+-- | Generate a pretty-printed string representing a Kind
5151prettyPrintKind :: Kind -> String
52−prettyPrintKind = fromMaybe (error "Incomplete pattern") . pattern matchKind ()
52+prettyPrintKind = render . kindAsBox
53+
54+kindAsBox :: Kind -> Box
55+kindAsBox = fromMaybe (error "Incomplete pattern") . pattern matchKind ()
5356 where
54− matchKind :: Pattern () Kind String
55− matchKind = buildPrettyPrinter operators (typeLiterals <+> fmap parens matchKind)
56− operators :: OperatorTable () Kind String
57+ matchKind :: Pattern () Kind Box
58+ matchKind = buildPrettyPrinter operators (typeLiterals <+> fmap ((text "(" <>) . (<> text ")")) matchKind)
59+
60+ operators :: OperatorTable () Kind Box
5761 operators =
58− OperatorTable [ [ Wrap matchRow $ \_ k -> "# " ++ k]
59− , [ AssocR funKind $ \arg ret -> arg ++ " -> " ++ ret ] ]
62+ OperatorTable [ [ Wrap matchRow $ \_ k -> text "# " <> k]
63+ , [ AssocR funKind $ \arg ret -> arg <> text " -> " <> ret ] ]
src/Language/PureScript/Pretty/Types.hs+56−34
@@ -14,13 +14,15 @@
1414-----------------------------------------------------------------------------
1515
1616module Language.PureScript.Pretty.Types (
17+ typeAsBox,
1718 prettyPrintType,
19+ typeAtomAsBox,
1820 prettyPrintTypeAtom,
21+ prettyPrintRowWith,
1922 prettyPrintRow
2023) where
2124
2225import Data.Maybe (fromMaybe)
23−import Data.List (intercalate)
2426
2527import Control.Arrow ((<+>))
2628import Control.PatternArrows
@@ -32,35 +34,54 @@ import Language.PureScript.Pretty.Common
3234import Language.PureScript.Pretty.Kinds
3335import Language.PureScript.Environment
3436
35−typeLiterals :: Pattern () Type String
37+import Text.PrettyPrint.Boxes hiding ((<+>))
38+
39+typeLiterals :: Pattern () Type Box
3640typeLiterals = mkPattern match
3741 where
38− match TypeWildcard = Just "_"
39− match (TypeVar var) = Just var
40− match (PrettyPrintObject row) = Just $ "{ " ++ prettyPrintRow row ++ " }"
41− match (TypeConstructor ctor) = Just $ showQualified runProperName ctor
42− match (TUnknown u) = Just $ '_' : show u
43− match (Skolem name s _) = Just $ name ++ show s
44− match (ConstrainedType deps ty) = Just $ "(" ++ intercalate ", " (map (\(pn, ty') -> showQualified runProperName pn ++ " " ++ unwords (map prettyPrintTypeAtom ty')) deps) ++ ") => " ++ prettyPrintType ty
45− match REmpty = Just "()"
46− match row@RCons{} = Just $ '(' : prettyPrintRow row ++ ")"
42+ match TypeWildcard = Just $ text "_"
43+ match (TypeVar var) = Just $ text var
44+ match (PrettyPrintObject row) = Just $ prettyPrintRowWith '{' '}' row
45+ match (TypeConstructor ctor) = Just $ text $ runProperName $ disqualify ctor
46+ match (TUnknown u) = Just $ text $ '_' : show u
47+ match (Skolem name s _) = Just $ text $ name ++ show s
48+ match (ConstrainedType deps ty) = Just $ constraintsAsBox deps `before` (text ") => " <> typeAsBox ty)
49+ match REmpty = Just $ text "()"
50+ match row@RCons{} = Just $ prettyPrintRowWith '(' ')' row
4751 match _ = Nothing
4852
53+constraintsAsBox :: [(Qualified ProperName, [Type])] -> Box
54+constraintsAsBox = vcat left . zipWith (\i (pn, tys) -> text (if i == 0 then "( " else ", ") <> constraintAsBox pn tys) [0 :: Int ..]
55+ where
56+ constraintAsBox pn tys = hsep 1 left (text (runProperName (disqualify pn)) : map typeAtomAsBox tys)
57+
4958-- |
5059-- Generate a pretty-printed string representing a Row
5160--
52−prettyPrintRow :: Type -> String
53−prettyPrintRow = (\(tys, rest) -> intercalate ", " (map (uncurry nameAndTypeToPs) tys) ++ tailToPs rest) . toList []
61+prettyPrintRowWith :: Char -> Char -> Type -> Box
62+prettyPrintRowWith open close = uncurry listToBox . toList []
5463 where
55− nameAndTypeToPs :: String -> Type -> String
56− nameAndTypeToPs name ty = prettyPrintObjectKey name ++ " :: " ++ prettyPrintType ty
57− tailToPs :: Type -> String
58− tailToPs REmpty = ""
59− tailToPs other = " | " ++ prettyPrintType other
64+ nameAndTypeToPs :: Char -> String -> Type -> Box
65+ nameAndTypeToPs start name ty = text (start : ' ' : prettyPrintObjectKey name ++ " :: ") <> typeAsBox ty
66+
67+ tailToPs :: Type -> Box
68+ tailToPs REmpty = nullBox
69+ tailToPs other = text "| " <> typeAsBox other
70+
71+ listToBox :: [(String, Type)] -> Type -> Box
72+ listToBox [] REmpty = text [open, close]
73+ listToBox [] rest = text [ open, ' ' ] <> tailToPs rest <> text [ ' ', close ]
74+ listToBox ts rest = vcat left $
75+ zipWith (\(nm, ty) i -> nameAndTypeToPs (if i == 0 then open else ',') nm ty) ts [0 :: Int ..] ++
76+ [ tailToPs rest, text [close] ]
77+
6078 toList :: [(String, Type)] -> Type -> ([(String, Type)], Type)
6179 toList tys (RCons name ty row) = toList ((name, ty):tys) row
6280 toList tys r = (tys, r)
6381
82+prettyPrintRow :: Type -> String
83+prettyPrintRow = render . prettyPrintRowWith '(' ')'
84+
6485typeApp :: Pattern () Type (Type, Type)
6586typeApp = mkPattern match
6687 where
@@ -91,19 +112,19 @@ insertPlaceholders = everywhereOnTypesTopDown convertForAlls . everywhereOnTypes
91112 go idents other = PrettyPrintForAll idents other
92113 convertForAlls other = other
93114
94−matchTypeAtom :: Pattern () Type String
95−matchTypeAtom = typeLiterals <+> fmap parens matchType
115+matchTypeAtom :: Pattern () Type Box
116+matchTypeAtom = typeLiterals <+> fmap ((`before` text ")") . (text "(" <>)) matchType
96117
97−matchType :: Pattern () Type String
118+matchType :: Pattern () Type Box
98119matchType = buildPrettyPrinter operators matchTypeAtom
99120 where
100− operators :: OperatorTable () Type String
121+ operators :: OperatorTable () Type Box
101122 operators =
102− OperatorTable [ [ AssocL typeApp $ \f x -> f ++ " " ++ x ]
103− , [ AssocR appliedFunction $ \arg ret -> arg ++ " -> " ++ ret
123+ OperatorTable [ [ AssocL typeApp $ \f x -> f `beforeWithSpace` x ]
124+ , [ AssocR appliedFunction $ \arg ret -> (arg <> text " ") `before` (text "-> " <> ret)
104125 ]
105− , [ Wrap forall_ $ \idents ty -> "forall " ++ unwords idents ++ ". " ++ ty ]
106− , [ Wrap kinded $ \k ty -> ty ++ " :: " ++ prettyPrintKind k ]
126+ , [ Wrap forall_ $ \idents ty -> text ("forall " ++ unwords idents ++ ". ") <> ty ]
127+ , [ Wrap kinded $ \k ty -> ty `before` (text " :: " <> kindAsBox k) ]
107128 ]
108129
109130forall_ :: Pattern () Type ([String], Type)
@@ -112,15 +133,16 @@ forall_ = mkPattern match
112133 match (PrettyPrintForAll idents ty) = Just (idents, ty)
113134 match _ = Nothing
114135
115−-- |
116−-- Generate a pretty-printed string representing a Type, as it should appear inside parentheses
117−--
136+typeAtomAsBox :: Type -> Box
137+typeAtomAsBox = fromMaybe (error "Incomplete pattern") . pattern matchTypeAtom () . insertPlaceholders
138+
139+-- | Generate a pretty-printed string representing a Type, as it should appear inside parentheses
118140prettyPrintTypeAtom :: Type -> String
119−prettyPrintTypeAtom = fromMaybe (error "Incomplete pattern") . pattern matchTypeAtom () . insertPlaceholders
141+prettyPrintTypeAtom = render . typeAtomAsBox
120142
143+typeAsBox :: Type -> Box
144+typeAsBox = fromMaybe (error "Incomplete pattern") . pattern matchType () . insertPlaceholders
121145
122−-- |
123−-- Generate a pretty-printed string representing a Type
124−--
146+-- | Generate a pretty-printed string representing a Type
125147prettyPrintType :: Type -> String
126−prettyPrintType = fromMaybe (error "Incomplete pattern") . pattern matchType () . insertPlaceholders
148+prettyPrintType = render . typeAsBox
src/Language/PureScript/Pretty/Values.hs+92−152
@@ -21,173 +21,113 @@ module Language.PureScript.Pretty.Values (
2121 prettyPrintBinderAtom
2222) where
2323
24−import Data.Maybe (fromMaybe)
2524import Data.List (intercalate)
2625
27−import Control.Arrow ((<+>), runKleisli, second)
28−import Control.PatternArrows
29−import Control.Monad.State
30−#if __GLASGOW_HASKELL__ < 710
31−import Control.Applicative
32−#endif
26+import Control.Arrow (second)
3327
3428import Language.PureScript.AST
3529import Language.PureScript.Names
3630import Language.PureScript.Pretty.Common
37−import Language.PureScript.Pretty.Types (prettyPrintType, prettyPrintTypeAtom)
31+import Language.PureScript.Pretty.Types (typeAsBox, typeAtomAsBox)
3832
39−literals :: Pattern PrinterState Expr String
40−literals = mkPattern' match
33+import Text.PrettyPrint.Boxes
34+
35+-- | Render an aligned list of items separated with commas
36+list :: Char -> Char -> (a -> Box) -> [a] -> Box
37+list open close _ [] = text [open, close]
38+list open close f xs = vcat left (zipWith toLine [0 :: Int ..] xs ++ [ text [ close ] ])
4139 where
42− match :: Expr -> StateT PrinterState Maybe String
43− match (NumericLiteral n) = return $ either show show n
44− match (StringLiteral s) = return $ show s
45− match (CharLiteral c) = return $ show c
46− match (BooleanLiteral True) = return "true"
47− match (BooleanLiteral False) = return "false"
48− match (ArrayLiteral xs) = return $ "[" ++ intercalate ", " (map prettyPrintValue xs) ++ "]"
49− match (ObjectLiteral ps) = prettyPrintObject' $ second Just `map` ps
50− match (ObjectConstructor ps) = prettyPrintObject' ps
51− match (ObjectGetter prop) = return $ "(." ++ prop ++ ")"
52− match (TypeClassDictionaryConstructorApp className ps) = concat <$> sequence
53− [ return (showQualified runProperName className ++ "(\n")
54− , match ps
55− , return ")"
56− ]
57− match (Constructor name) = return $ showQualified runProperName name
58− match (Case values binders) = concat <$> sequence
59− [ return "case "
60− , unwords <$> forM values prettyPrintValue'
61− , return " of\n"
62− , withIndent $ prettyPrintMany prettyPrintCaseAlternative binders
63− , currentIndent
64− ]
65− match (Let ds val) = concat <$> sequence
66− [ return "let\n"
67− , withIndent $ prettyPrintMany prettyPrintDeclaration ds
68− , return "\n"
69− , currentIndent
70− , return "in "
71− , prettyPrintValue' val
72− ]
73− match (Var ident) = return $ showQualified showIdent ident
74− match (Do els) = concat <$> sequence
75− [ return "do\n"
76− , withIndent $ prettyPrintMany prettyPrintDoNotationElement els
77− , currentIndent
78− ]
79− match (OperatorSection op (Right val)) = return $ "(" ++ prettyPrintValue op ++ " " ++ prettyPrintValue val ++ ")"
80− match (OperatorSection op (Left val)) = return $ "(" ++ prettyPrintValue val ++ " " ++ prettyPrintValue op ++ ")"
81− match (TypeClassDictionary (name, tys) _) = return $ "<<dict " ++ showQualified runProperName name ++ " " ++ unwords (map prettyPrintTypeAtom tys) ++ ">>"
82− match (SuperClassDictionary name _) = return $ "<<superclass dict " ++ showQualified runProperName name ++ ">>"
83− match (TypedValue _ val _) = prettyPrintValue' val
84− match (PositionedValue _ _ val) = prettyPrintValue' val
85− match _ = mzero
86−
87−prettyPrintDeclaration :: Declaration -> StateT PrinterState Maybe String
88−prettyPrintDeclaration (TypeDeclaration ident ty) = return $ showIdent ident ++ " :: " ++ prettyPrintType ty
89−prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) = concat <$> sequence
90− [ return $ showIdent ident ++ " = "
91− , prettyPrintValue' val
92− ]
40+ toLine i a = text [ if i == 0 then open else ',', ' ' ] <> f a
41+
42+prettyPrintObject :: [(String, Maybe Expr)] -> Box
43+prettyPrintObject = list '{' '}' prettyPrintObjectProperty
44+ where
45+ prettyPrintObjectProperty :: (String, Maybe Expr) -> Box
46+ prettyPrintObjectProperty (key, value) = text (prettyPrintObjectKey key ++ ": ") <> maybe (text "_") prettyPrintValue value
47+
48+-- | Pretty-print an expression
49+prettyPrintValue :: Expr -> Box
50+prettyPrintValue (IfThenElse cond th el) =
51+ (text "if " <> prettyPrintValueAtom cond)
52+ // moveRight 2 (vcat left [ text "then " <> prettyPrintValueAtom th
53+ , text "else " <> prettyPrintValueAtom el
54+ ])
55+prettyPrintValue (Accessor prop val) = prettyPrintValueAtom val <> text ("." ++ show prop)
56+prettyPrintValue (ObjectUpdate o ps) = prettyPrintValueAtom o <> text " " <> list '{' '}' (\(key, val) -> text (key ++ " = ") <> prettyPrintValue val) ps
57+prettyPrintValue (ObjectUpdater o ps) = maybe (text "_") prettyPrintValueAtom o <> text " " <> list '{' '}' (\(key, val) -> text (key ++ " = ") <> maybe (text "_") prettyPrintValue val) ps
58+prettyPrintValue (App val arg) = prettyPrintValueAtom val `beforeWithSpace` prettyPrintValueAtom arg
59+prettyPrintValue (Abs (Left arg) val) = text ('\\' : showIdent arg ++ " -> ") // moveRight 2 (prettyPrintValue val)
60+prettyPrintValue (TypeClassDictionaryConstructorApp className ps) =
61+ text (runProperName (disqualify className) ++ " ") <> prettyPrintValueAtom ps
62+prettyPrintValue (Case values binders) =
63+ (text "case " <> foldl1 beforeWithSpace (map prettyPrintValueAtom values) <> text " of") //
64+ moveRight 2 (vcat left (map prettyPrintCaseAlternative binders))
65+prettyPrintValue (Let ds val) =
66+ text "let" //
67+ moveRight 2 (vcat left (map prettyPrintDeclaration ds)) //
68+ (text "in " <> prettyPrintValue val)
69+prettyPrintValue (Do els) =
70+ text "do " <> vcat left (map prettyPrintDoNotationElement els)
71+prettyPrintValue (TypeClassDictionary (name, tys) _) = foldl1 beforeWithSpace $ text ("#dict " ++ runProperName (disqualify name)) : map typeAtomAsBox tys
72+prettyPrintValue (SuperClassDictionary name _) = text $ "#dict " ++ runProperName (disqualify name)
73+prettyPrintValue (TypedValue _ val _) = prettyPrintValue val
74+prettyPrintValue (PositionedValue _ _ val) = prettyPrintValue val
75+prettyPrintValue expr = prettyPrintValueAtom expr
76+
77+-- | Pretty-print an atomic expression, adding parentheses if necessary.
78+prettyPrintValueAtom :: Expr -> Box
79+prettyPrintValueAtom (NumericLiteral n) = text $ either show show n
80+prettyPrintValueAtom (StringLiteral s) = text $ show s
81+prettyPrintValueAtom (CharLiteral c) = text $ show c
82+prettyPrintValueAtom (BooleanLiteral True) = text "true"
83+prettyPrintValueAtom (BooleanLiteral False) = text "false"
84+prettyPrintValueAtom (ArrayLiteral xs) = list '[' ']' prettyPrintValue xs
85+prettyPrintValueAtom (ObjectLiteral ps) = prettyPrintObject $ second Just `map` ps
86+prettyPrintValueAtom (ObjectConstructor ps) = prettyPrintObject ps
87+prettyPrintValueAtom (ObjectGetter prop) = text $ "_." ++ show prop
88+prettyPrintValueAtom (Constructor name) = text $ runProperName (disqualify name)
89+prettyPrintValueAtom (Var ident) = text $ showIdent (disqualify ident)
90+prettyPrintValueAtom (OperatorSection op (Right val)) = ((text "(" <> prettyPrintValue op) `beforeWithSpace` prettyPrintValue val) `before` text ")"
91+prettyPrintValueAtom (OperatorSection op (Left val)) = ((text "(" <> prettyPrintValue val) `beforeWithSpace` prettyPrintValue op) `before` text ")"
92+prettyPrintValueAtom (TypedValue _ val _) = prettyPrintValueAtom val
93+prettyPrintValueAtom (PositionedValue _ _ val) = prettyPrintValueAtom val
94+prettyPrintValueAtom expr = (text "(" <> prettyPrintValue expr) `before` text ")"
95+
96+prettyPrintDeclaration :: Declaration -> Box
97+prettyPrintDeclaration (TypeDeclaration ident ty) =
98+ text (showIdent ident ++ " :: ") <> typeAsBox ty
99+prettyPrintDeclaration (ValueDeclaration ident _ [] (Right val)) =
100+ text (showIdent ident ++ " = ") <> prettyPrintValue val
93101prettyPrintDeclaration (PositionedDeclaration _ _ d) = prettyPrintDeclaration d
94102prettyPrintDeclaration _ = error "Invalid argument to prettyPrintDeclaration"
95103
96−prettyPrintCaseAlternative :: CaseAlternative -> StateT PrinterState Maybe String
104+prettyPrintCaseAlternative :: CaseAlternative -> Box
97105prettyPrintCaseAlternative (CaseAlternative binders result) =
98− concat <$> sequence
99− [ return (unwords (map prettyPrintBinderAtom binders))
100− , prettyPrintResult result
101− ]
106+ text (unwords (map prettyPrintBinderAtom binders)) <> prettyPrintResult result
102107 where
103− prettyPrintResult (Left gs) = concat <$> sequence
104− [ return "\n"
105− , withIndent $ prettyPrintMany prettyPrintGuardedValue gs
106− ]
107− prettyPrintResult (Right v) = (" -> " ++) <$> prettyPrintValue' v
108−
109− prettyPrintGuardedValue (grd, val) =
110− concat <$> sequence
111− [ return "| "
112− , prettyPrintValue' grd
113− , return " -> "
114− , prettyPrintValue' val
115− ]
116−
117−prettyPrintDoNotationElement :: DoNotationElement -> StateT PrinterState Maybe String
108+ prettyPrintResult :: Either [(Guard, Expr)] Expr -> Box
109+ prettyPrintResult (Left gs) =
110+ vcat left (map prettyPrintGuardedValue gs)
111+ prettyPrintResult (Right v) = text " -> " <> prettyPrintValue v
112+
113+ prettyPrintGuardedValue :: (Guard, Expr) -> Box
114+ prettyPrintGuardedValue (grd, val) = foldl1 before
115+ [ text " | "
116+ , prettyPrintValue grd
117+ , text " -> "
118+ , prettyPrintValue val
119+ ]
120+
121+prettyPrintDoNotationElement :: DoNotationElement -> Box
118122prettyPrintDoNotationElement (DoNotationValue val) =
119− prettyPrintValue' val
123+ prettyPrintValue val
120124prettyPrintDoNotationElement (DoNotationBind binder val) =
121− concat <$> sequence
122− [ return (prettyPrintBinder binder)
123− , return " <- "
124− , prettyPrintValue' val
125− ]
125+ text (prettyPrintBinder binder ++ " <- ") <> prettyPrintValue val
126126prettyPrintDoNotationElement (DoNotationLet ds) =
127− concat <$> sequence
128− [ return "let "
129− , withIndent $ prettyPrintMany prettyPrintDeclaration ds
130− ]
127+ text "let" //
128+ moveRight 2 (vcat left (map prettyPrintDeclaration ds))
131129prettyPrintDoNotationElement (PositionedDoNotationElement _ _ el) = prettyPrintDoNotationElement el
132130
133−prettyPrintObject' :: [(String, Maybe Expr)] -> StateT PrinterState Maybe String
134−prettyPrintObject' [] = return "{}"
135−prettyPrintObject' ps = return $ "{ " ++ intercalate ", " (map prettyPrintObjectProperty ps) ++ "}"
136− where
137− prettyPrintObjectProperty :: (String, Maybe Expr) -> String
138− prettyPrintObjectProperty (key, value) = prettyPrintObjectKey key ++ ": " ++ maybe "_" prettyPrintValue value
139−
140−ifThenElse :: Pattern PrinterState Expr ((Expr, Expr), Expr)
141−ifThenElse = mkPattern match
142− where
143− match (IfThenElse cond th el) = Just ((th, el), cond)
144− match _ = Nothing
145−
146−accessor :: Pattern PrinterState Expr (String, Expr)
147−accessor = mkPattern match
148− where
149− match (Accessor prop val) = Just (prop, val)
150− match _ = Nothing
151−
152−objectUpdate :: Pattern PrinterState Expr ([String], Expr)
153−objectUpdate = mkPattern match
154− where
155− match (ObjectUpdate o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ prettyPrintValue val, o)
156− match (ObjectUpdater o ps) = Just (flip map ps $ \(key, val) -> key ++ " = " ++ maybe "_" prettyPrintValue val, fromMaybe (Var (Qualified Nothing $ Ident "_")) o)
157− match _ = Nothing
158−
159−app :: Pattern PrinterState Expr (String, Expr)
160−app = mkPattern match
161− where
162− match (App val arg) = Just (prettyPrintValue arg, val)
163− match _ = Nothing
164−
165−lam :: Pattern PrinterState Expr (String, Expr)
166−lam = mkPattern match
167− where
168− match (Abs (Left arg) val) = Just (showIdent arg, val)
169− match _ = Nothing
170−
171−-- |
172−-- Generate a pretty-printed string representing an expression
173−--
174−prettyPrintValue :: Expr -> String
175−prettyPrintValue = fromMaybe (error "Incomplete pattern") . flip evalStateT (PrinterState 0) . prettyPrintValue'
176−
177−prettyPrintValue' :: Expr -> StateT PrinterState Maybe String
178−prettyPrintValue' = runKleisli $ runPattern matchValue
179− where
180− matchValue :: Pattern PrinterState Expr String
181− matchValue = buildPrettyPrinter operators (literals <+> fmap parens matchValue)
182− operators :: OperatorTable PrinterState Expr String
183− operators =
184− OperatorTable [ [ Wrap accessor $ \prop val -> val ++ "." ++ prop ]
185− , [ Wrap objectUpdate $ \ps val -> val ++ "{ " ++ intercalate ", " ps ++ " }" ]
186− , [ Wrap app $ \arg val -> val ++ "(" ++ arg ++ ")" ]
187− , [ Split lam $ \arg val -> "\\" ++ arg ++ " -> " ++ prettyPrintValue val ]
188− , [ Wrap ifThenElse $ \(th, el) cond -> "if " ++ cond ++ " then " ++ prettyPrintValue th ++ " else " ++ prettyPrintValue el ]
189− ]
190−
191131prettyPrintBinderAtom :: Binder -> String
192132prettyPrintBinderAtom NullBinder = "_"
193133prettyPrintBinderAtom (StringBinder str) = show str
@@ -196,7 +136,7 @@ prettyPrintBinderAtom (NumberBinder num) = either show show num
196136prettyPrintBinderAtom (BooleanBinder True) = "true"
197137prettyPrintBinderAtom (BooleanBinder False) = "false"
198138prettyPrintBinderAtom (VarBinder ident) = showIdent ident
199−prettyPrintBinderAtom (ConstructorBinder ctor []) = showQualified runProperName ctor
139+prettyPrintBinderAtom (ConstructorBinder ctor []) = runProperName (disqualify ctor)
200140prettyPrintBinderAtom (ObjectBinder bs) =
201141 "{ "
202142 ++ intercalate ", " (map prettyPrintObjectPropertyBinder bs)
@@ -216,7 +156,7 @@ prettyPrintBinderAtom b = parens (prettyPrintBinder b)
216156-- Generate a pretty-printed string representing a Binder
217157--
218158prettyPrintBinder :: Binder -> String
219−prettyPrintBinder (ConstructorBinder ctor []) = showQualified runProperName ctor
220−prettyPrintBinder (ConstructorBinder ctor args) = showQualified runProperName ctor ++ " " ++ unwords (map prettyPrintBinderAtom args)
159+prettyPrintBinder (ConstructorBinder ctor []) = runProperName (disqualify ctor)
160+prettyPrintBinder (ConstructorBinder ctor args) = runProperName (disqualify ctor) ++ " " ++ unwords (map prettyPrintBinderAtom args)
221161prettyPrintBinder (PositionedBinder _ _ binder) = prettyPrintBinder binder
222162prettyPrintBinder b = prettyPrintBinderAtom b
src/Language/PureScript/Sugar/BindingGroups.hs+1−1
@@ -184,7 +184,7 @@ toBindingGroup moduleName (CyclicSCC ds') =
184184 cycleError :: (MonadError MultipleErrors m) => Declaration -> [Declaration] -> m a
185185 cycleError (PositionedDeclaration p _ d) ds = rethrowWithPosition p $ cycleError d ds
186186 cycleError (ValueDeclaration n _ _ (Right _)) [] = throwError . errorMessage $ CycleInDeclaration n
187− cycleError d ds@(_:_) = rethrow (onErrorMessages (NotYetDefined (map getIdent ds))) $ cycleError d []
187+ cycleError d ds@(_:_) = rethrow (addHint (NotYetDefined (map getIdent ds))) $ cycleError d []
188188 cycleError _ _ = error "Expected ValueDeclaration"
189189
190190toDataBindingGroup :: (MonadError MultipleErrors m) => SCC Declaration -> m Declaration
src/Language/PureScript/Sugar/CaseDeclarations.hs+1−1
@@ -50,7 +50,7 @@ isLeft (Right _) = False
5050--
5151desugarCasesModule :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Module] -> m [Module]
5252desugarCasesModule ms = forM ms $ \(Module ss coms name ds exps) ->
53− rethrow (onErrorMessages (ErrorInModule name)) $
53+ rethrow (addHint (ErrorInModule name)) $
5454 Module ss coms name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps
5555
5656desugarAbs :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Declaration] -> m [Declaration]
src/Language/PureScript/Sugar/Names.hs+1−1
@@ -98,7 +98,7 @@ desugarImports externs modules = do
9898
9999 renameInModule' :: Env -> Module -> m Module
100100 renameInModule' env m@(Module _ _ mn _ _) =
101− rethrow (onErrorMessages (ErrorInModule mn)) $ do
101+ rethrow (addHint (ErrorInModule mn)) $ do
102102 let (_, imps, exps) = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn env
103103 elaborateImports imps <$> renameInModule env imps (elaborateExports exps m)
104104
src/Language/PureScript/Sugar/Names/Exports.hs+2−2
@@ -43,7 +43,7 @@ import Language.PureScript.Sugar.Names.Env
4343--
4444findExportable :: forall m. (Applicative m, MonadError MultipleErrors m) => Module -> m Exports
4545findExportable (Module _ _ mn ds _) =
46− rethrow (onErrorMessages (ErrorInModule mn)) $ foldM updateExports nullExports ds
46+ rethrow (addHint (ErrorInModule mn)) $ foldM updateExports nullExports ds
4747 where
4848 updateExports :: Exports -> Declaration -> m Exports
4949 updateExports exps (TypeClassDeclaration tcn _ _ ds') = do
@@ -67,7 +67,7 @@ findExportable (Module _ _ mn ds _) =
6767--
6868resolveExports :: forall m. (Applicative m, MonadError MultipleErrors m) => Env -> ModuleName -> Imports -> Exports -> [DeclarationRef] -> m Exports
6969resolveExports env mn imps exps refs =
70− rethrow (onErrorMessages (ErrorInModule mn)) $ do
70+ rethrow (addHint (ErrorInModule mn)) $ do
7171 filtered <- filterModule mn exps refs
7272 foldM elaborateModuleExports filtered refs
7373
src/Language/PureScript/Sugar/Names/Imports.hs+1−1
@@ -64,7 +64,7 @@ findImports = foldM (go Nothing) M.empty
6464--
6565resolveImports :: (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Env -> Module -> m Imports
6666resolveImports env (Module _ _ currentModule decls _) =
67− censor (onErrorMessages (ErrorInModule currentModule)) $ do
67+ censor (addHint (ErrorInModule currentModule)) $ do
6868 scope <- M.insert currentModule [(Nothing, Implicit, Nothing)] <$> findImports decls
6969 foldM (resolveModuleImport currentModule env) nullImports (M.toList scope)
7070
src/Language/PureScript/Sugar/Operators.hs+1−1
@@ -102,7 +102,7 @@ ensureNoDuplicates m = go $ sortBy (compare `on` fst) m
102102 go [] = return ()
103103 go [_] = return ()
104104 go ((x@(Qualified (Just mn) name), _) : (y, pos) : _) | x == y =
105− rethrow (onErrorMessages (ErrorInModule mn)) $
105+ rethrow (addHint (ErrorInModule mn)) $
106106 rethrowWithPosition pos $
107107 throwError . errorMessage $ MultipleFixities name
108108 go (_ : rest) = go rest
src/Language/PureScript/Sugar/TypeClasses.hs+1−1
@@ -243,7 +243,7 @@ unit = TypeApp tyObject REmpty
243243
244244typeInstanceDictionaryDeclaration :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => Ident -> ModuleName -> [Constraint] -> Qualified ProperName -> [Type] -> [Declaration] -> Desugar m Declaration
245245typeInstanceDictionaryDeclaration name mn deps className tys decls =
246− rethrow (onErrorMessages (ErrorInInstance className tys)) $ do
246+ rethrow (addHint (ErrorInInstance className tys)) $ do
247247 m <- get
248248
249249 -- Lookup the type arguments and member types for the type class
src/Language/PureScript/Sugar/TypeDeclarations.hs+37−33
@@ -15,18 +15,19 @@
1515-----------------------------------------------------------------------------
1616
1717{-# LANGUAGE FlexibleContexts #-}
18+{-# LANGUAGE ScopedTypeVariables #-}
1819{-# LANGUAGE CPP #-}
1920
2021module Language.PureScript.Sugar.TypeDeclarations (
21− desugarTypeDeclarations,
2222 desugarTypeDeclarationsModule
2323) where
2424
2525#if __GLASGOW_HASKELL__ < 710
2626import Control.Applicative
2727#endif
28−import Control.Monad (forM)
28+import Control.Monad (forM, when)
2929import Control.Monad.Error.Class (MonadError(..))
30+import Control.Monad.Writer.Class (MonadWriter(tell))
3031
3132import Language.PureScript.AST
3233import Language.PureScript.Names
@@ -37,36 +38,39 @@ import Language.PureScript.Traversals
3738-- |
3839-- Replace all top level type declarations in a module with type annotations
3940--
40−desugarTypeDeclarationsModule :: (Functor m, Applicative m, MonadError MultipleErrors m) => [Module] -> m [Module]
41+desugarTypeDeclarationsModule :: forall m. (Functor m, Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => [Module] -> m [Module]
4142desugarTypeDeclarationsModule ms = forM ms $ \(Module ss coms name ds exps) ->
42− rethrow (onErrorMessages (ErrorInModule name)) $
43− Module ss coms name <$> desugarTypeDeclarations ds <*> pure exps
44−
45−-- |
46−-- Replace all top level type declarations with type annotations
47−--
48−desugarTypeDeclarations :: (Functor m, Applicative m, MonadError MultipleErrors m) => [Declaration] -> m [Declaration]
49−desugarTypeDeclarations (PositionedDeclaration pos com d : ds) = do
50− (d' : ds') <- rethrowWithPosition pos $ desugarTypeDeclarations (d : ds)
51− return (PositionedDeclaration pos com d' : ds')
52−desugarTypeDeclarations (TypeDeclaration name ty : d : rest) = do
53− (_, nameKind, val) <- fromValueDeclaration d
54− desugarTypeDeclarations (ValueDeclaration name nameKind [] (Right (TypedValue True val ty)) : rest)
43+ rethrow (addHint (ErrorInModule name)) $
44+ Module ss coms name <$> desugarTypeDeclarations True ds <*> pure exps
5545 where
56− fromValueDeclaration :: (Functor m, Applicative m, MonadError MultipleErrors m) => Declaration -> m (Ident, NameKind, Expr)
57− fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
58− fromValueDeclaration (PositionedDeclaration pos com d') = do
59− (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
60− return (ident, nameKind, PositionedValue pos com val)
61− fromValueDeclaration _ = throwError . errorMessage $ OrphanTypeDeclaration name
62−desugarTypeDeclarations [TypeDeclaration name _] = throwError . errorMessage $ OrphanTypeDeclaration name
63−desugarTypeDeclarations (ValueDeclaration name nameKind bs val : rest) = do
64− let (_, f, _) = everywhereOnValuesTopDownM return go return
65− f' (Left gs) = Left <$> mapM (pairM return f) gs
66− f' (Right v) = Right <$> f v
67− (:) <$> (ValueDeclaration name nameKind bs <$> f' val) <*> desugarTypeDeclarations rest
68− where
69− go (Let ds val') = Let <$> desugarTypeDeclarations ds <*> pure val'
70− go other = return other
71−desugarTypeDeclarations (d:ds) = (:) d <$> desugarTypeDeclarations ds
72−desugarTypeDeclarations [] = return []
46+
47+ desugarTypeDeclarations :: Bool -> [Declaration] -> m [Declaration]
48+ desugarTypeDeclarations reqd (PositionedDeclaration pos com d : ds) = do
49+ (d' : ds') <- rethrowWithPosition pos $ desugarTypeDeclarations reqd (d : ds)
50+ return (PositionedDeclaration pos com d' : ds')
51+ desugarTypeDeclarations reqd (TypeDeclaration name ty : d : rest) = do
52+ (_, nameKind, val) <- fromValueDeclaration d
53+ desugarTypeDeclarations reqd (ValueDeclaration name nameKind [] (Right (TypedValue True val ty)) : rest)
54+ where
55+ fromValueDeclaration :: Declaration -> m (Ident, NameKind, Expr)
56+ fromValueDeclaration (ValueDeclaration name' nameKind [] (Right val)) | name == name' = return (name', nameKind, val)
57+ fromValueDeclaration (PositionedDeclaration pos com d') = do
58+ (ident, nameKind, val) <- rethrowWithPosition pos $ fromValueDeclaration d'
59+ return (ident, nameKind, PositionedValue pos com val)
60+ fromValueDeclaration _ = throwError . errorMessage $ OrphanTypeDeclaration name
61+ desugarTypeDeclarations _ [TypeDeclaration name _] = throwError . errorMessage $ OrphanTypeDeclaration name
62+ desugarTypeDeclarations reqd (ValueDeclaration name nameKind bs val : rest) = do
63+ -- At the top level, match a type signature or emit a warning.
64+ when reqd $ case val of
65+ Right TypedValue{} -> return ()
66+ Left _ -> error "desugarTypeDeclarations: cases were not desugared"
67+ _ -> tell (addHint (ErrorInValueDeclaration name) $ errorMessage $ MissingTypeDeclaration name)
68+ let (_, f, _) = everywhereOnValuesTopDownM return go return
69+ f' (Left gs) = Left <$> mapM (pairM return f) gs
70+ f' (Right v) = Right <$> f v
71+ (:) <$> (ValueDeclaration name nameKind bs <$> f' val) <*> desugarTypeDeclarations reqd rest
72+ where
73+ go (Let ds val') = Let <$> desugarTypeDeclarations False ds <*> pure val'
74+ go other = return other
75+ desugarTypeDeclarations reqd (d:ds) = (:) d <$> desugarTypeDeclarations reqd ds
76+ desugarTypeDeclarations _ [] = return []
src/Language/PureScript/TypeChecker.hs+8−8
@@ -51,7 +51,7 @@ addDataType moduleName dtype name args dctors ctorKind = do
5151 env <- getEnv
5252 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (ctorKind, DataType args dctors) (types env) }
5353 forM_ dctors $ \(dctor, tys) ->
54− warnAndRethrow (onErrorMessages (ErrorInDataConstructor dctor)) $
54+ warnAndRethrow (addHint (ErrorInDataConstructor dctor)) $
5555 addDataConstructor moduleName dtype name (map fst args) dctor tys
5656
5757addDataConstructor :: ModuleName -> DataDeclType -> ProperName -> [String] -> ProperName -> [Type] -> Check ()
@@ -137,7 +137,7 @@ typeCheckAll moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
137137 where
138138 go :: Declaration -> Check Declaration
139139 go (DataDeclaration dtype name args dctors) = do
140− warnAndRethrow (onErrorMessages (ErrorInTypeConstructor name)) $ do
140+ warnAndRethrow (addHint (ErrorInTypeConstructor name)) $ do
141141 when (dtype == Newtype) $ checkNewtype dctors
142142 checkDuplicateTypeArguments $ map fst args
143143 ctorKind <- kindsOf True moduleName name args (concatMap snd dctors)
@@ -150,7 +150,7 @@ typeCheckAll moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
150150 checkNewtype [(_, _)] = throwError . errorMessage $ InvalidNewtype
151151 checkNewtype _ = throwError . errorMessage $ InvalidNewtype
152152 go (d@(DataBindingGroupDeclaration tys)) = do
153− warnAndRethrow (onErrorMessages ErrorInDataBindingGroup) $ do
153+ warnAndRethrow (addHint ErrorInDataBindingGroup) $ do
154154 let syns = mapMaybe toTypeSynonym tys
155155 let dataDecls = mapMaybe toDataDecl tys
156156 (syn_ks, data_ks) <- kindsOfAll moduleName syns (map (\(_, name, args, dctors) -> (name, args, concatMap snd dctors)) dataDecls)
@@ -171,7 +171,7 @@ typeCheckAll moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
171171 toDataDecl (PositionedDeclaration _ _ d') = toDataDecl d'
172172 toDataDecl _ = Nothing
173173 go (TypeSynonymDeclaration name args ty) = do
174− warnAndRethrow (onErrorMessages (ErrorInTypeSynonym name)) $ do
174+ warnAndRethrow (addHint (ErrorInTypeSynonym name)) $ do
175175 checkDuplicateTypeArguments $ map fst args
176176 kind <- kindsOf False moduleName name args [ty]
177177 let args' = args `withKinds` kind
@@ -179,14 +179,14 @@ typeCheckAll moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
179179 return $ TypeSynonymDeclaration name args ty
180180 go (TypeDeclaration{}) = error "Type declarations should have been removed"
181181 go (ValueDeclaration name nameKind [] (Right val)) =
182− warnAndRethrow (onErrorMessages (ErrorInValueDeclaration name)) $ do
182+ warnAndRethrow (addHint (ErrorInValueDeclaration name)) $ do
183183 valueIsNotDefined moduleName name
184184 [(_, (val', ty))] <- typesOf moduleName [(name, val)]
185185 addValue moduleName name ty nameKind
186186 return $ ValueDeclaration name nameKind [] $ Right val'
187187 go (ValueDeclaration{}) = error "Binders were not desugared"
188188 go (BindingGroupDeclaration vals) =
189− warnAndRethrow (onErrorMessages (ErrorInBindingGroup (map (\(ident, _, _) -> ident) vals))) $ do
189+ warnAndRethrow (addHint (ErrorInBindingGroup (map (\(ident, _, _) -> ident) vals))) $ do
190190 forM_ (map (\(ident, _, _) -> ident) vals) $ \name ->
191191 valueIsNotDefined moduleName name
192192 tys <- typesOf moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals
@@ -203,7 +203,7 @@ typeCheckAll moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
203203 putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (kind, ExternData) (types env) }
204204 return d
205205 go (d@(ExternDeclaration name ty)) = do
206− warnAndRethrow (onErrorMessages (ErrorInForeignImport name)) $ do
206+ warnAndRethrow (addHint (ErrorInForeignImport name)) $ do
207207 env <- getEnv
208208 kind <- kindOf moduleName ty
209209 guardWith (errorMessage (ExpectedType ty kind)) $ kind == Star
@@ -269,7 +269,7 @@ typeCheckAll moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds
269269--
270270typeCheckModule :: Module -> Check Module
271271typeCheckModule (Module _ _ _ _ Nothing) = error "exports should have been elaborated"
272−typeCheckModule (Module ss coms mn decls (Just exps)) = warnAndRethrow (onErrorMessages (ErrorInModule mn)) $ do
272+typeCheckModule (Module ss coms mn decls (Just exps)) = warnAndRethrow (addHint (ErrorInModule mn)) $ do
273273 modify (\s -> s { checkCurrentModule = Just mn })
274274 decls' <- typeCheckAll mn exps decls
275275 forM_ exps $ \e -> do
src/Language/PureScript/TypeChecker/Kinds.hs+2−2
@@ -83,7 +83,7 @@ kindOf _ ty = fst <$> kindOfWithScopedVars ty
8383--
8484kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])
8585kindOfWithScopedVars ty =
86− rethrow (onErrorMessages (ErrorCheckingKind ty)) $
86+ rethrow (addHint (ErrorCheckingKind ty)) $
8787 fmap tidyUp . liftUnify $ infer ty
8888 where
8989 tidyUp ((k, args), sub) = ( starIfUnknown (sub $? k)
@@ -161,7 +161,7 @@ starIfUnknown k = k
161161-- Infer a kind for a type
162162--
163163infer :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
164−infer ty = rethrow (onErrorMessages (ErrorCheckingKind ty)) $ infer' ty
164+infer ty = rethrow (addHint (ErrorCheckingKind ty)) $ infer' ty
165165
166166infer' :: Type -> UnifyT Kind Check (Kind, [(String, Kind)])
167167infer' (ForAll ident ty _) = do
src/Language/PureScript/TypeChecker/Skolems.hs+1−1
@@ -92,7 +92,7 @@ skolemEscapeCheck root@TypedValue{} =
9292 let (_, f, _, _, _) = everythingWithContextOnValues [] [] (++) def go def def def
9393 in case f root of
9494 [] -> return ()
95− ((binding, val) : _) -> throwError . singleError $ ErrorInExpression val $ SimpleErrorWrapper $ EscapedSkolem binding
95+ ((binding, val) : _) -> throwError . singleError $ ErrorMessage [ ErrorInExpression val ] $ EscapedSkolem binding
9696 where
9797 def s _ = (s, [])
9898
src/Language/PureScript/TypeChecker/Subsumption.hs+1−1
@@ -35,7 +35,7 @@ import Language.PureScript.Types
3535-- Check whether one type subsumes another, rethrowing errors to provide a better error message
3636--
3737subsumes :: Maybe Expr -> Type -> Type -> UnifyT Type Check (Maybe Expr)
38−subsumes val ty1 ty2 = rethrow (onErrorMessages (ErrorInSubsumption ty1 ty2)) $ subsumes' val ty1 ty2
38+subsumes val ty1 ty2 = rethrow (addHint (ErrorInSubsumption ty1 ty2)) $ subsumes' val ty1 ty2
3939
4040-- |
4141-- Check whether one type subsumes another
src/Language/PureScript/TypeChecker/Types.hs+8−25
@@ -92,7 +92,7 @@ typesOf moduleName vals = do
9292 -- Apply the substitution that was returned from runUnify to both types and (type-annotated) values
9393 tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (sub $?) val, sub $? ty))) ts
9494 -- Replace all the wildcards types with their inferred types
95− replace sub (SimpleErrorWrapper (WildcardInferredType ty)) = SimpleErrorWrapper $ WildcardInferredType (sub $? ty)
95+ replace sub (ErrorMessage hints (WildcardInferredType ty)) = ErrorMessage hints $ WildcardInferredType (sub $? ty)
9696 replace _ em = em
9797
9898type TypeData = M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
@@ -197,7 +197,7 @@ instantiatePolyTypeWithUnknowns val ty = return (val, ty)
197197-- Infer a type for a value, rethrowing any error to provide a more useful error message
198198--
199199infer :: Expr -> UnifyT Type Check Expr
200−infer val = rethrow (onErrorMessages (ErrorInferringType val)) $ infer' val
200+infer val = rethrow (addHint (ErrorInferringType val)) $ infer' val
201201
202202-- |
203203-- Infer a type for a value
@@ -229,15 +229,10 @@ infer' (ObjectUpdate o ps) = do
229229 o' <- TypedValue True <$> check o oldTy <*> pure oldTy
230230 return $ TypedValue True (ObjectUpdate o' newVals) $ TypeApp tyObject $ rowFromList (newTys, row)
231231infer' (Accessor prop val) = do
232− typed@(TypedValue _ _ objTy) <- infer val
233− propTy <- inferProperty objTy prop
234− case propTy of
235− Nothing -> do
236− field <- fresh
237− rest <- fresh
238− _ <- subsumes Nothing objTy (TypeApp tyObject (RCons prop field rest))
239− return $ TypedValue True (Accessor prop typed) field
240− Just ty -> return $ TypedValue True (Accessor prop typed) ty
232+ field <- fresh
233+ rest <- fresh
234+ typed <- check val (TypeApp tyObject (RCons prop field rest))
235+ return $ TypedValue True (Accessor prop typed) field
241236infer' (Abs (Left arg) ret) = do
242237 ty <- fresh
243238 Just moduleName <- checkCurrentModule <$> get
@@ -322,18 +317,6 @@ inferLetBinding seen (PositionedDeclaration pos com d : ds) ret j = warnAndRethr
322317 return (PositionedDeclaration pos com d' : ds', val')
323318inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding"
324319
325−-- |
326−-- Infer the type of a property inside a record with a given type
327−--
328−inferProperty :: Type -> String -> UnifyT Type Check (Maybe Type)
329−inferProperty (TypeApp obj row) prop | obj == tyObject = do
330− let (props, _) = rowToList row
331− return $ lookup prop props
332−inferProperty (ForAll ident ty _) prop = do
333− replaced <- replaceVarWithUnknown ident ty
334− inferProperty replaced prop
335−inferProperty _ _ = return Nothing
336−
337320-- |
338321-- Infer the types of variables brought into scope by a binder
339322--
@@ -437,7 +420,7 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
437420-- Check the type of a value, rethrowing errors to provide a better error message
438421--
439422check :: Expr -> Type -> UnifyT Type Check Expr
440−check val ty = rethrow (onErrorMessages (ErrorCheckingType val ty)) $ check' val ty
423+check val ty = rethrow (addHint (ErrorCheckingType val ty)) $ check' val ty
441424
442425-- |
443426-- Check the type of a value
@@ -623,7 +606,7 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
623606-- Check the type of a function application, rethrowing errors to provide a better error message
624607--
625608checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
626−checkFunctionApplication fn fnTy arg ret = rethrow (onErrorMessages (ErrorInApplication fn fnTy arg)) $ do
609+checkFunctionApplication fn fnTy arg ret = rethrow (addHint (ErrorInApplication fn fnTy arg)) $ do
627610 subst <- unifyCurrentSubstitution <$> UnifyT get
628611 checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
629612
src/Language/PureScript/TypeChecker/Unify.hs+1−1
@@ -61,7 +61,7 @@ instance Unifiable Check Type where
6161-- Unify two types, updating the current substitution
6262--
6363unifyTypes :: Type -> Type -> UnifyT Type Check ()
64−unifyTypes t1 t2 = rethrow (onErrorMessages (ErrorUnifyingTypes t1 t2)) $
64+unifyTypes t1 t2 = rethrow (addHint (ErrorUnifyingTypes t1 t2)) $
6565 unifyTypes' t1 t2
6666 where
6767 unifyTypes' (TUnknown u1) (TUnknown u2) | u1 == u2 = return ()