git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Warn on unused type variable
commit3ba23c75226e06b5ed62e967ab03df73621eb79c authorGary Burgess <gary.burgess@gmail.com> dateSun 13 Sep 2015, 13:32 (11 years ago) parent0888ada
2 files changed+21−7
src/Language/PureScript/Errors.hs+4 src/Language/PureScript/Linter.hs+17−7
src/Language/PureScript/Errors.hs+4
@@ -141,6 +141,7 @@ data SimpleErrorMessage
141141 | TransitiveExportError DeclarationRef [DeclarationRef]
142142 | ShadowedName Ident
143143 | ShadowedTypeVar String
144+ | UnusedTypeVar String
144145 | WildcardInferredType Type
145146 | NotExhaustivePattern [[Binder]] Bool
146147 | OverlappingPattern [[Binder]] Bool
@@ -268,6 +269,7 @@ errorCode em = case unwrapErrorMessage em of
268269 TransitiveExportError{} -> "TransitiveExportError"
269270 ShadowedName{} -> "ShadowedName"
270271 ShadowedTypeVar{} -> "ShadowedTypeVar"
272+ UnusedTypeVar{} -> "UnusedTypeVar"
271273 WildcardInferredType{} -> "WildcardInferredType"
272274 NotExhaustivePattern{} -> "NotExhaustivePattern"
273275 OverlappingPattern{} -> "OverlappingPattern"
@@ -633,6 +635,8 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
633635 line $ "Name '" ++ showIdent nm ++ "' was shadowed"
634636 goSimple (ShadowedTypeVar tv) =
635637 line $ "Type variable '" ++ tv ++ "' was shadowed"
638+ goSimple (UnusedTypeVar tv) =
639+ line $ "Type variable '" ++ tv ++ "' was declared but not used"
636640 goSimple (ClassOperator className opName) =
637641 paras [ line $ "Class '" ++ runProperName className ++ "' declares operator " ++ showIdent opName ++ "."
638642 , indent $ line "This may be disallowed in the future - consider declaring a named member in the class and making the operator an alias:"
src/Language/PureScript/Linter.hs+17−7
@@ -19,7 +19,7 @@
1919
2020module Language.PureScript.Linter (lint, module L) where
2121
22−import Data.List (mapAccumL, nub)
22+import Data.List (mapAccumL, nub, (\\))
2323import Data.Maybe (mapMaybe)
2424import Data.Monoid
2525
@@ -60,7 +60,7 @@ lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_
6060
6161 f' :: Declaration -> MultipleErrors
6262 f' (PositionedDeclaration pos _ dec) = onErrorMessages (PositionedError pos) (f' dec)
63− f' dec = f dec <> checkShadowedTypeVars dec
63+ f' dec = f dec <> checkTypeVars dec
6464
6565 in tell (f' d)
6666 where
@@ -90,17 +90,27 @@ lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_
9090 bindName :: S.Set Ident -> Ident -> (S.Set Ident, MultipleErrors)
9191 bindName = bind ShadowedName
9292
93− checkShadowedTypeVars :: Declaration -> MultipleErrors
94− checkShadowedTypeVars d =
95− let (f, _, _, _, _) = accumTypes go in f d
93+ checkTypeVars :: Declaration -> MultipleErrors
94+ checkTypeVars d =
95+ let (checkShadow, _, _, _, _) = accumTypes (everythingWithContextOnTypes S.empty mempty mappend step)
96+ (checkUnused, _, _, _, _) = accumTypes findUnused
97+ in checkShadow d <> checkUnused d
9698 where
97− go :: Type -> MultipleErrors
98− go = everythingWithContextOnTypes S.empty mempty mappend step
9999 step :: S.Set String -> Type -> (S.Set String, MultipleErrors)
100100 step s (ForAll tv _ _) = bindVar s tv
101101 step s _ = (s, mempty)
102102 bindVar :: S.Set String -> String -> (S.Set String, MultipleErrors)
103103 bindVar = bind ShadowedTypeVar
104+ findUnused :: Type -> MultipleErrors
105+ findUnused ty =
106+ let used = usedTypeVariables ty
107+ declared = everythingOnTypes (++) go ty
108+ unused = nub declared \\ nub used
109+ in foldl (<>) mempty $ map (errorMessage . UnusedTypeVar) unused
110+ where
111+ go :: Type -> [String]
112+ go (ForAll tv _ _) = [tv]
113+ go _ = []
104114
105115 bind :: (Ord a) => (a -> SimpleErrorMessage) -> S.Set a -> a -> (S.Set a, MultipleErrors)
106116 bind mkError s name | name `S.member` s = (s, errorMessage (mkError name))