@@ -87,7 +87,7 @@ data ImportEnvironment = ImportEnvironment
87-- Updates the exports for a module from the global environment. If the module was not previously
87-- Updates the exports for a module from the global environment. If the module was not previously
88-- present in the global environment, it is created.
88-- present in the global environment, it is created.
90−updateExportedModule :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> (Exports -> m Exports) -> m ExportEnvironment
90+updateExportedModule :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> (Exports -> m Exports) -> m ExportEnvironment
91updateExportedModule env mn update = do
91updateExportedModule env mn update = do
92 let exports = fromMaybe (error "Module was undefined in updateExportedModule") $ mn `M.lookup` env
92 let exports = fromMaybe (error "Module was undefined in updateExportedModule") $ mn `M.lookup` env
93 exports' <- update exports
93 exports' <- update exports
@@ -96,61 +96,61 @@ updateExportedModule env mn update = do
97-- Adds an empty module to an ExportEnvironment.
97-- Adds an empty module to an ExportEnvironment.
99−addEmptyModule :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> m ExportEnvironment
99+addEmptyModule :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> m ExportEnvironment
100addEmptyModule env name =
100addEmptyModule env name =
101 if name `M.member` env
101 if name `M.member` env
102− then throwError $ mkErrorStack ("Module '" ++ show name ++ "' has been defined more than once") Nothing
102+ then throwError . errorMessage $ RedefinedModule name
103 else return $ M.insert name (Exports [] [] []) env
103 else return $ M.insert name (Exports [] [] []) env
106-- Adds a type belonging to a module to the export environment.
106-- Adds a type belonging to a module to the export environment.
108−addType :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> ProperName -> [ProperName] -> m ExportEnvironment
108+addType :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> ProperName -> [ProperName] -> m ExportEnvironment
109addType env mn name dctors = updateExportedModule env mn $ \m -> do
109addType env mn name dctors = updateExportedModule env mn $ \m -> do
110 let exTypes = exportedTypes m
110 let exTypes = exportedTypes m
111 let exDctors = snd `concatMap` exTypes
111 let exDctors = snd `concatMap` exTypes
112 let exClasses = exportedTypeClasses m
112 let exClasses = exportedTypeClasses m
113− when (any ((== name) . fst) exTypes) $ throwMultipleDefError "type" name
113+ when (any ((== name) . fst) exTypes) $ throwConflictError ConflictingTypeDecls name
114− when (name `elem` exClasses) $ throwConflictingDefError "Type" "type class" name
114+ when (name `elem` exClasses) $ throwConflictError TypeConflictsWithClass name
115 forM_ dctors $ \dctor -> do
115 forM_ dctors $ \dctor -> do
116− when (dctor `elem` exDctors) $ throwMultipleDefError "data constructor" dctor
116+ when (dctor `elem` exDctors) $ throwConflictError ConflictingCtorDecls dctor
117− when (dctor `elem` exClasses) $ throwConflictingDefError "Data constructor" "type class" dctor
117+ when (dctor `elem` exClasses) $ throwConflictError CtorConflictsWithClass dctor
118 return $ m { exportedTypes = (name, dctors) : exTypes }
118 return $ m { exportedTypes = (name, dctors) : exTypes }
121-- Adds a class to the export environment.
121-- Adds a class to the export environment.
123−addTypeClass :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> ProperName -> m ExportEnvironment
123+addTypeClass :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> ProperName -> m ExportEnvironment
124addTypeClass env mn name = updateExportedModule env mn $ \m -> do
124addTypeClass env mn name = updateExportedModule env mn $ \m -> do
125 let exTypes = exportedTypes m
125 let exTypes = exportedTypes m
126 let exDctors = snd `concatMap` exTypes
126 let exDctors = snd `concatMap` exTypes
127− when (any ((== name) . fst) exTypes) $ throwConflictingDefError "Type class" "type" name
127+ when (any ((== name) . fst) exTypes) $ throwConflictError ClassConflictsWithType name
128− when (name `elem` exDctors) $ throwConflictingDefError "Type class" "data constructor" name
128+ when (name `elem` exDctors) $ throwConflictError ClassConflictsWithCtor name
129− classes <- addExport "type class" (exportedTypeClasses m) name
129+ classes <- addExport DuplicateClassExport (exportedTypeClasses m) name
130 return $ m { exportedTypeClasses = classes }
130 return $ m { exportedTypeClasses = classes }
133-- Adds a class to the export environment.
133-- Adds a class to the export environment.
135−addValue :: (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> ModuleName -> Ident -> m ExportEnvironment
135+addValue :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> Ident -> m ExportEnvironment
136addValue env mn name = updateExportedModule env mn $ \m -> do
136addValue env mn name = updateExportedModule env mn $ \m -> do
137− values <- addExport "value" (exportedValues m) name
137+ values <- addExport DuplicateValueExport (exportedValues m) name
138 return $ m { exportedValues = values }
138 return $ m { exportedValues = values }
141-- Adds an entry to a list of exports unless it is already present, in which case an error is
141-- Adds an entry to a list of exports unless it is already present, in which case an error is
142-- returned.
142-- returned.
144−addExport :: (Applicative m, MonadError ErrorStack m, Eq a, Show a) => String -> [a] -> a -> m [a]
144+addExport :: (Applicative m, MonadError MultipleErrors m, Eq a, Show a) => (a -> ErrorMessage) -> [a] -> a -> m [a]
145addExport what exports name =
145addExport what exports name =
146 if name `elem` exports
146 if name `elem` exports
147− then throwMultipleDefError what name
147+ then throwConflictError what name
148 else return $ name : exports
148 else return $ name : exports
151-- Replaces all local names with qualified names within a set of modules.
151-- Replaces all local names with qualified names within a set of modules.
153−desugarImports :: forall m. (Applicative m, MonadError ErrorStack m) => [Module] -> m [Module]
153+desugarImports :: forall m. (Applicative m, MonadError MultipleErrors m) => [Module] -> m [Module]
154desugarImports modules = do
154desugarImports modules = do
155 unfilteredExports <- findExports modules
155 unfilteredExports <- findExports modules
156 exports <- foldM filterModuleExports unfilteredExports modules
156 exports <- foldM filterModuleExports unfilteredExports modules
@@ -168,7 +168,7 @@ desugarImports modules = do
168 -- the module has access to an unfiltered list of its own members.
168 -- the module has access to an unfiltered list of its own members.
169 renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> m Module
169 renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> m Module
170 renameInModule' unfilteredExports exports m@(Module _ mn _ _) =
170 renameInModule' unfilteredExports exports m@(Module _ mn _ _) =
171− rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ do
171+ rethrow (onErrorMessages (ErrorInModule mn)) $ do
172 let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports
172 let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports
173 let exps = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn exports
173 let exps = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn exports
174 imports <- resolveImports env m
174 imports <- resolveImports env m
@@ -205,7 +205,7 @@ elaborateImports (Module coms mn decls exps) = Module coms mn decls' exps
205-- Replaces all local names with qualified names within a module and checks that all existing
205-- Replaces all local names with qualified names within a module and checks that all existing
206-- qualified names are valid.
206-- qualified names are valid.
208−renameInModule :: forall m. (Applicative m, MonadError ErrorStack m) => ImportEnvironment -> ExportEnvironment -> Module -> m Module
208+renameInModule :: forall m. (Applicative m, MonadError MultipleErrors m) => ImportEnvironment -> ExportEnvironment -> Module -> m Module
209renameInModule imports exports (Module coms mn decls exps) =
209renameInModule imports exports (Module coms mn decls exps) =
210 Module coms mn <$> parU decls go <*> pure exps
210 Module coms mn <$> parU decls go <*> pure exps
@@ -236,7 +236,7 @@ renameInModule imports exports (Module coms mn decls exps) =
236 let args = mapMaybe letBoundVariable ds
236 let args = mapMaybe letBoundVariable ds
237 unless (length (nub args) == length args) $
237 unless (length (nub args) == length args) $
238 maybe id rethrowWithPosition pos $
238 maybe id rethrowWithPosition pos $
239− throwError $ mkErrorStack ("Overlapping names in let binding.") Nothing
239+ throwError . errorMessage $ OverlappingNamesInLet
240 return ((pos, args ++ bound), Let ds val')
240 return ((pos, args ++ bound), Let ds val')
242 updateValue (pos, bound) (Var name'@(Qualified Nothing ident)) | ident `notElem` bound =
242 updateValue (pos, bound) (Var name'@(Qualified Nothing ident)) | ident `notElem` bound =
@@ -271,28 +271,28 @@ renameInModule imports exports (Module coms mn decls exps) =
272 updateConstraints pos = mapM (\(name, ts) -> (,) <$> updateClassName name pos <*> mapM (updateTypesEverywhere pos) ts)
272 updateConstraints pos = mapM (\(name, ts) -> (,) <$> updateClassName name pos <*> mapM (updateTypesEverywhere pos) ts)
274− updateTypeName = update "type" importedTypes (\mes -> isJust . (`lookup` exportedTypes mes))
274+ updateTypeName = update UnknownType importedTypes (\mes -> isJust . (`lookup` exportedTypes mes))
275− updateClassName = update "type class" importedTypeClasses (flip elem . exportedTypeClasses)
275+ updateClassName = update UnknownTypeClass importedTypeClasses (flip elem . exportedTypeClasses)
276− updateValueName = update "value" importedValues (flip elem . exportedValues)
276+ updateValueName = update UnknownValue importedValues (flip elem . exportedValues)
277− updateDataConstructorName = update "data constructor" importedDataConstructors (\mes -> flip elem (join $ snd `map` exportedTypes mes))
277+ updateDataConstructorName = update (flip UnknownDataConstructor Nothing) importedDataConstructors (\mes -> flip elem (join $ snd `map` exportedTypes mes))
279 -- Update names so unqualified references become qualified, and locally qualified references
279 -- Update names so unqualified references become qualified, and locally qualified references
280 -- are replaced with their canoncial qualified names (e.g. M.Map -> Data.Map.Map)
280 -- are replaced with their canoncial qualified names (e.g. M.Map -> Data.Map.Map)
281− update :: (Ord a, Show a) => String
281+ update :: (Ord a, Show a) => (Qualified a -> ErrorMessage)
282 -> (ImportEnvironment -> M.Map (Qualified a) (Qualified a))
282 -> (ImportEnvironment -> M.Map (Qualified a) (Qualified a))
283 -> (Exports -> a -> Bool)
283 -> (Exports -> a -> Bool)
284 -> Qualified a
284 -> Qualified a
285 -> Maybe SourceSpan
285 -> Maybe SourceSpan
286 -> m (Qualified a)
286 -> m (Qualified a)
287− update t getI checkE qname@(Qualified mn' name) pos = positioned $ case (M.lookup qname imports', mn') of
287+ update unknown getI checkE qname@(Qualified mn' name) pos = positioned $ case (M.lookup qname imports', mn') of
288 (Just qname', _) -> return qname'
288 (Just qname', _) -> return qname'
289 (Nothing, Just mn'') -> do
289 (Nothing, Just mn'') -> do
290− when (isExplicitQualModule mn'') $ throwError $ mkErrorStack ("Unknown " ++ t ++ " '" ++ show qname ++ "'") Nothing
290+ when (isExplicitQualModule mn'') . throwError . errorMessage $ unknown qname
291 modExports <- getExports mn''
291 modExports <- getExports mn''
292 if checkE modExports name
292 if checkE modExports name
293 then return qname
293 then return qname
294− else throwError $ mkErrorStack ("Unknown " ++ t ++ " '" ++ show qname ++ "'") Nothing
294+ else throwError . errorMessage $ unknown qname
295− _ -> throwError $ mkErrorStack ("Unknown " ++ t ++ " '" ++ show name ++ "'") Nothing
295+ _ -> throwError . errorMessage $ unknown qname
297 isExplicitQualModule :: ModuleName -> Bool
297 isExplicitQualModule :: ModuleName -> Bool
298 isExplicitQualModule = flip elem $ mapMaybe (\(Qualified q _) -> q) (M.keys imports')
298 isExplicitQualModule = flip elem $ mapMaybe (\(Qualified q _) -> q) (M.keys imports')
@@ -303,12 +303,12 @@ renameInModule imports exports (Module coms mn decls exps) =
304 -- Gets the exports for a module, or an error message if the module doesn't exist
304 -- Gets the exports for a module, or an error message if the module doesn't exist
305 getExports :: ModuleName -> m Exports
305 getExports :: ModuleName -> m Exports
306− getExports mn' = maybe (throwError $ mkErrorStack ("Unknown module '" ++ show mn' ++ "'") Nothing) return $ M.lookup mn' exports
306+ getExports mn' = maybe (throwError . errorMessage $ UnknownModule mn') return $ M.lookup mn' exports
309-- Finds all exported declarations in a set of modules.
309-- Finds all exported declarations in a set of modules.
311−findExports :: forall m. (Applicative m, MonadError ErrorStack m) => [Module] -> m ExportEnvironment
311+findExports :: forall m. (Applicative m, MonadError MultipleErrors m) => [Module] -> m ExportEnvironment
312findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) primExports
312findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) primExports
@@ -321,7 +321,7 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
321 addModule :: ExportEnvironment -> Module -> m ExportEnvironment
321 addModule :: ExportEnvironment -> Module -> m ExportEnvironment
322 addModule env (Module _ mn ds _) = do
322 addModule env (Module _ mn ds _) = do
323 env' <- addEmptyModule env mn
323 env' <- addEmptyModule env mn
324− rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ foldM (addDecl mn) env' ds
324+ rethrow (onErrorMessages (ErrorInModule mn)) $ foldM (addDecl mn) env' ds
326 -- Add a declaration from a module to the global export environment
326 -- Add a declaration from a module to the global export environment
327 addDecl :: ModuleName -> ExportEnvironment -> Declaration -> m ExportEnvironment
327 addDecl :: ModuleName -> ExportEnvironment -> Declaration -> m ExportEnvironment
@@ -344,10 +344,10 @@ findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) pri
344-- Filters the exports for a module to ensure only explicit exports are kept in the global exports
344-- Filters the exports for a module to ensure only explicit exports are kept in the global exports
345-- environment.
345-- environment.
347−filterExports :: forall m. (Applicative m, MonadError ErrorStack m) => ModuleName -> [DeclarationRef] -> ExportEnvironment -> m ExportEnvironment
347+filterExports :: forall m. (Applicative m, MonadError MultipleErrors m) => ModuleName -> [DeclarationRef] -> ExportEnvironment -> m ExportEnvironment
348filterExports mn exps env = do
348filterExports mn exps env = do
349 let moduleExports = fromMaybe (error "Module is missing") (mn `M.lookup` env)
349 let moduleExports = fromMaybe (error "Module is missing") (mn `M.lookup` env)
350− moduleExports' <- rethrow (mkCompileError ("Error in module " ++ show mn) Nothing `combineErrors`) $ filterModule moduleExports
350+ moduleExports' <- rethrow (onErrorMessages (ErrorInModule mn)) $ filterModule moduleExports
351 return $ M.insert mn moduleExports' env
351 return $ M.insert mn moduleExports' env
@@ -364,7 +364,7 @@ filterExports mn exps env = do
364 filterTypes :: [(ProperName, [ProperName])] -> [(ProperName, [ProperName])] -> DeclarationRef -> m [(ProperName, [ProperName])]
364 filterTypes :: [(ProperName, [ProperName])] -> [(ProperName, [ProperName])] -> DeclarationRef -> m [(ProperName, [ProperName])]
365 filterTypes expTys result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterTypes expTys result r
365 filterTypes expTys result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterTypes expTys result r
366 filterTypes expTys result (TypeRef name expDcons) = do
366 filterTypes expTys result (TypeRef name expDcons) = do
367− dcons <- maybe (throwError $ mkErrorStack ("Cannot export undefined type '" ++ show name ++ "'") Nothing) return $ name `lookup` expTys
367+ dcons <- maybe (throwError . errorMessage $ UnknownType name) return $ name `lookup` expTys
368 dcons' <- maybe (return dcons) (foldM (filterDcons name dcons) []) expDcons
368 dcons' <- maybe (return dcons) (foldM (filterDcons name dcons) []) expDcons
369 return $ (name, dcons') : result
369 return $ (name, dcons') : result
370 filterTypes _ result _ = return result
370 filterTypes _ result _ = return result
@@ -374,7 +374,7 @@ filterExports mn exps env = do
374 filterDcons tcon exps' result name =
374 filterDcons tcon exps' result name =
375 if name `elem` exps'
375 if name `elem` exps'
376 then return $ name : result
376 then return $ name : result
377− else throwError $ mkErrorStack ("Cannot export undefined data constructor '" ++ show name ++ "' for type '" ++ show tcon ++ "'") Nothing
377+ else throwError . errorMessage $ UnknownDataConstructor name (Just tcon)
379 -- Ensure the exported classes exist in the module and add them to the set of exports
379 -- Ensure the exported classes exist in the module and add them to the set of exports
380 filterClasses :: [ProperName] -> [ProperName] -> DeclarationRef -> m [ProperName]
380 filterClasses :: [ProperName] -> [ProperName] -> DeclarationRef -> m [ProperName]
@@ -382,7 +382,7 @@ filterExports mn exps env = do
382 filterClasses exps' result (TypeClassRef name) =
382 filterClasses exps' result (TypeClassRef name) =
383 if name `elem` exps'
383 if name `elem` exps'
384 then return $ name : result
384 then return $ name : result
385− else throwError $ mkErrorStack ("Cannot export undefined type class '" ++ show name ++ "'") Nothing
385+ else throwError . errorMessage $ UnknownTypeClass name
386 filterClasses _ result _ = return result
386 filterClasses _ result _ = return result
388 -- Ensure the exported values exist in the module and add them to the set of exports
388 -- Ensure the exported values exist in the module and add them to the set of exports
@@ -391,7 +391,7 @@ filterExports mn exps env = do
391 filterValues exps' result (ValueRef name) =
391 filterValues exps' result (ValueRef name) =
392 if name `elem` exps'
392 if name `elem` exps'
393 then return $ name : result
393 then return $ name : result
394− else throwError $ mkErrorStack ("Cannot export undefined value '" ++ show name ++ "'") Nothing
394+ else throwError . errorMessage $ UnknownValue name
395 filterValues _ result _ = return result
395 filterValues _ result _ = return result
@@ -408,7 +408,7 @@ findImports = foldl (findImports' Nothing) M.empty
409-- Constructs a local environment for a module.
409-- Constructs a local environment for a module.
411−resolveImports :: forall m. (Applicative m, MonadError ErrorStack m) => ExportEnvironment -> Module -> m ImportEnvironment
411+resolveImports :: forall m. (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> Module -> m ImportEnvironment
412resolveImports env (Module _ currentModule decls _) =
412resolveImports env (Module _ currentModule decls _) =
413 foldM resolveImport' (ImportEnvironment M.empty M.empty M.empty M.empty) (M.toList scope)
413 foldM resolveImport' (ImportEnvironment M.empty M.empty M.empty M.empty) (M.toList scope)
@@ -421,7 +421,7 @@ resolveImports env (Module _ currentModule decls _) =
422 resolveImport' :: ImportEnvironment -> (ModuleName, (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)) -> m ImportEnvironment
422 resolveImport' :: ImportEnvironment -> (ModuleName, (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)) -> m ImportEnvironment
423 resolveImport' imp (mn, (pos, typ, impQual)) = do
423 resolveImport' imp (mn, (pos, typ, impQual)) = do
424− modExports <- positioned $ maybe (throwError $ mkErrorStack ("Cannot import unknown module '" ++ show mn ++ "'") Nothing) return $ mn `M.lookup` env
424+ modExports <- positioned $ maybe (throwError . errorMessage $ UnknownModule mn) return $ mn `M.lookup` env
425 positioned $ resolveImport currentModule mn modExports imp impQual typ
425 positioned $ resolveImport currentModule mn modExports imp impQual typ
427 positioned err = case pos of
427 positioned err = case pos of
@@ -431,7 +431,7 @@ resolveImports env (Module _ currentModule decls _) =
432-- Extends the local environment for a module by resolving an import of another module.
432-- Extends the local environment for a module by resolving an import of another module.
434−resolveImport :: forall m. (Applicative m, MonadError ErrorStack m) => ModuleName -> ModuleName -> Exports -> ImportEnvironment -> Maybe ModuleName -> ImportDeclarationType -> m ImportEnvironment
434+resolveImport :: forall m. (Applicative m, MonadError MultipleErrors m) => ModuleName -> ModuleName -> Exports -> ImportEnvironment -> Maybe ModuleName -> ImportDeclarationType -> m ImportEnvironment
435resolveImport currentModule importModule exps imps impQual =
435resolveImport currentModule importModule exps imps impQual =
436 resolveByType
436 resolveByType
@@ -492,14 +492,14 @@ resolveImport currentModule importModule exps imps impQual =
492 check (PositionedDeclarationRef pos _ r) =
492 check (PositionedDeclarationRef pos _ r) =
493 rethrowWithPosition pos $ check r
493 rethrowWithPosition pos $ check r
494 check ref@(ValueRef name) =
494 check ref@(ValueRef name) =
495− checkImportExists "value" values name >> return ref
495+ checkImportExists UnknownValue values name >> return ref
496 check ref@(TypeRef name dctors) = do
496 check ref@(TypeRef name dctors) = do
497− _ <- checkImportExists "type" availableTypes name
497+ _ <- checkImportExists UnknownType availableTypes name
498 let allDctors = allExportedDataConstructors name
498 let allDctors = allExportedDataConstructors name
499 _ <- maybe (return allDctors) (mapM $ checkDctorExists allDctors) dctors
499 _ <- maybe (return allDctors) (mapM $ checkDctorExists allDctors) dctors
500 return ref
500 return ref
501 check ref@(TypeClassRef name) =
501 check ref@(TypeClassRef name) =
502− checkImportExists "type class" classes name >> return ref
502+ checkImportExists UnknownTypeClass classes name >> return ref
503 check _ = error "Invalid argument to checkRefIsValid"
503 check _ = error "Invalid argument to checkRefIsValid"
505 -- Find all exported data constructors for a given type
505 -- Find all exported data constructors for a given type
@@ -511,11 +511,11 @@ resolveImport currentModule importModule exps imps impQual =
511 updateImports m name = case M.lookup (Qualified impQual name) m of
511 updateImports m name = case M.lookup (Qualified impQual name) m of
512 Nothing -> return $ M.insert (Qualified impQual name) (Qualified (Just importModule) name) m
512 Nothing -> return $ M.insert (Qualified impQual name) (Qualified (Just importModule) name) m
513 Just (Qualified Nothing _) -> error "Invalid state in updateImports"
513 Just (Qualified Nothing _) -> error "Invalid state in updateImports"
514− Just x@(Qualified (Just mn) _) -> throwError $ mkErrorStack err Nothing
514+ Just x@(Qualified (Just mn) _) -> throwError . errorMessage $ err
516 err = if mn == currentModule || importModule == currentModule
516 err = if mn == currentModule || importModule == currentModule
517− then "Definition '" ++ show name ++ "' conflicts with import '" ++ show (Qualified (Just mn) name) ++ "'"
517+ then ConflictingImport (show name) mn
518− else "Conflicting imports for '" ++ show name ++ "': '" ++ show x ++ "', '" ++ show (Qualified (Just importModule) name) ++ "'"
518+ else ConflictingImports (show name) mn importModule
520 -- The available values, types, and classes in the module being imported
520 -- The available values, types, and classes in the module being imported
521 values = exportedValues exps
521 values = exportedValues exps
@@ -525,27 +525,17 @@ resolveImport currentModule importModule exps imps impQual =
525 -- Ensure that an explicitly imported data constructor exists for the type it is being imported
525 -- Ensure that an explicitly imported data constructor exists for the type it is being imported
527 checkDctorExists :: [ProperName] -> ProperName -> m ProperName
527 checkDctorExists :: [ProperName] -> ProperName -> m ProperName
528− checkDctorExists = checkImportExists "data constructor"
528+ checkDctorExists = checkImportExists (flip UnknownDataConstructor Nothing)
530 -- Check that an explicitly imported item exists in the module it is being imported from
530 -- Check that an explicitly imported item exists in the module it is being imported from
531− checkImportExists :: (Eq a, Show a) => String -> [a] -> a -> m a
531+ checkImportExists :: (Eq a, Show a) => (Qualified a -> ErrorMessage) -> [a] -> a -> m a
532− checkImportExists t exports item =
532+ checkImportExists unknown exports item =
533 if item `elem` exports
533 if item `elem` exports
534 then return item
534 then return item
535− else throwError $ mkErrorStack ("Cannot import unknown " ++ t ++ " '" ++ show item ++ "' from '" ++ show importModule ++ "'") Nothing
535+ else throwError . errorMessage . unknown $ Qualified (Just importModule) item
538-- Raises an error for when there is more than one definition for something.
538-- Raises an error for when there is more than one definition for something.
540−throwMultipleDefError :: (Applicative m, MonadError ErrorStack m, Show a) => String -> a -> m b
540+throwConflictError :: (Applicative m, MonadError MultipleErrors m, Show a) => (a -> ErrorMessage) -> a -> m b
541−throwMultipleDefError what name = throwError $
541+throwConflictError conflict = throwError . errorMessage . conflict
542− mkErrorStack ("Multiple definitions for " ++ what ++ " '" ++ show name ++ "'") Nothing
545−-- Raises an error for when there is a conflicting definition for something, for example, a type
546−-- class and data constructor of the same name.
548−throwConflictingDefError :: (Applicative m, MonadError ErrorStack m, Show a) => String -> String -> a -> m b
549−throwConflictingDefError what1 what2 name = throwError $
550− mkErrorStack (what1 ++ " '" ++ show name ++ "' cannot be defined in the same module as a " ++ what2 ++ " of the same name") Nothing