@@ -19,7 +19,7 @@
20module Language.PureScript.Linter (lint, module L) where
20module Language.PureScript.Linter (lint, module L) where
22−import Data.List (mapAccumL, nub)
22+import Data.List (mapAccumL, nub, (\\))
23import Data.Maybe (mapMaybe)
23import Data.Maybe (mapMaybe)
24import Data.Monoid
24import Data.Monoid
@@ -60,7 +60,7 @@ lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_
61 f' :: Declaration -> MultipleErrors
61 f' :: Declaration -> MultipleErrors
62 f' (PositionedDeclaration pos _ dec) = onErrorMessages (PositionedError pos) (f' dec)
62 f' (PositionedDeclaration pos _ dec) = onErrorMessages (PositionedError pos) (f' dec)
63− f' dec = f dec <> checkShadowedTypeVars dec
63+ f' dec = f dec <> checkTypeVars dec
65 in tell (f' d)
65 in tell (f' d)
@@ -90,17 +90,27 @@ lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_
90 bindName :: S.Set Ident -> Ident -> (S.Set Ident, MultipleErrors)
90 bindName :: S.Set Ident -> Ident -> (S.Set Ident, MultipleErrors)
91 bindName = bind ShadowedName
91 bindName = bind ShadowedName
93− checkShadowedTypeVars :: Declaration -> MultipleErrors
93+ checkTypeVars :: Declaration -> MultipleErrors
94− checkShadowedTypeVars d =
94+ checkTypeVars d =
95− let (f, _, _, _, _) = accumTypes go in f d
95+ let (checkShadow, _, _, _, _) = accumTypes (everythingWithContextOnTypes S.empty mempty mappend step)
96+ (checkUnused, _, _, _, _) = accumTypes findUnused
97+ in checkShadow d <> checkUnused d
97− go :: Type -> MultipleErrors
98− go = everythingWithContextOnTypes S.empty mempty mappend step
99 step :: S.Set String -> Type -> (S.Set String, MultipleErrors)
99 step :: S.Set String -> Type -> (S.Set String, MultipleErrors)
100 step s (ForAll tv _ _) = bindVar s tv
100 step s (ForAll tv _ _) = bindVar s tv
101 step s _ = (s, mempty)
101 step s _ = (s, mempty)
102 bindVar :: S.Set String -> String -> (S.Set String, MultipleErrors)
102 bindVar :: S.Set String -> String -> (S.Set String, MultipleErrors)
103 bindVar = bind ShadowedTypeVar
103 bindVar = bind ShadowedTypeVar
104+ findUnused :: Type -> MultipleErrors
106+ let used = usedTypeVariables ty
107+ declared = everythingOnTypes (++) go ty
108+ unused = nub declared \\ nub used
109+ in foldl (<>) mempty $ map (errorMessage . UnusedTypeVar) unused
111+ go :: Type -> [String]
112+ go (ForAll tv _ _) = [tv]
105 bind :: (Ord a) => (a -> SimpleErrorMessage) -> S.Set a -> a -> (S.Set a, MultipleErrors)
115 bind :: (Ord a) => (a -> SimpleErrorMessage) -> S.Set a -> a -> (S.Set a, MultipleErrors)
106 bind mkError s name | name `S.member` s = (s, errorMessage (mkError name))
116 bind mkError s name | name `S.member` s = (s, errorMessage (mkError name))