git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Add information about skolems to type errors
1209e86Phil Freeman
src/Language/PureScript/Errors.hs+70−40
@@ -14,6 +14,7 @@
14
14
15{-# LANGUAGE GeneralizedNewtypeDeriving #-}
15{-# LANGUAGE GeneralizedNewtypeDeriving #-}
16{-# LANGUAGE FlexibleContexts #-}
16{-# LANGUAGE FlexibleContexts #-}
17+{-# LANGUAGE RecordWildCards #-}
17{-# LANGUAGE MultiParamTypeClasses #-}
18{-# LANGUAGE MultiParamTypeClasses #-}
18
19
19module Language.PureScript.Errors where
20module Language.PureScript.Errors where
@@ -24,7 +25,6 @@ import Prelude.Compat
24import Data.Ord (comparing)
25import Data.Ord (comparing)
25import Data.Either (lefts, rights)
26import Data.Either (lefts, rights)
26import Data.List (intercalate, transpose, nub, nubBy, sortBy)
27import Data.List (intercalate, transpose, nub, nubBy, sortBy)
27−import Data.Function (on)
28import Data.Foldable (fold)
28import Data.Foldable (fold)
29
29
30import qualified Data.Map as M
30import qualified Data.Map as M
@@ -33,7 +33,7 @@ import Control.Monad
33import Control.Monad.Writer
33import Control.Monad.Writer
34import Control.Monad.Error.Class (MonadError(..))
34import Control.Monad.Error.Class (MonadError(..))
35import Control.Monad.Trans.State.Lazy
35import Control.Monad.Trans.State.Lazy
36−import Control.Arrow (first, (&&&))
36+import Control.Arrow ((&&&))
37
37
38import Language.PureScript.Crash
38import Language.PureScript.Crash
39import Language.PureScript.AST
39import Language.PureScript.AST
@@ -311,11 +311,16 @@ onErrorMessages f = MultipleErrors . map f . runMultipleErrors
311addHint :: ErrorMessageHint -> MultipleErrors -> MultipleErrors
311addHint :: ErrorMessageHint -> MultipleErrors -> MultipleErrors
312addHint hint = onErrorMessages $ \(ErrorMessage hints se) -> ErrorMessage (hint : hints) se
312addHint hint = onErrorMessages $ \(ErrorMessage hints se) -> ErrorMessage (hint : hints) se
313
313
314−-- | The various types of things which might need to be relabelled in errors messages.
315−data LabelType = TypeLabel | SkolemLabel String deriving (Show, Read, Eq, Ord)
316−
317-- | A map from rigid type variable name/unknown variable pairs to new variables.
314-- | A map from rigid type variable name/unknown variable pairs to new variables.
318−type UnknownMap = M.Map (LabelType, Int) Int
315+data TypeMap = TypeMap
316+ { umSkolemMap :: M.Map Int (String, Int, Maybe SourceSpan)
317+ , umNextSkolem :: Int
318+ , umUnknownMap :: M.Map Int Int
319+ , umNextUnknown :: Int
320+ } deriving Show
321+
322+defaultUnknownMap :: TypeMap
323+defaultUnknownMap = TypeMap M.empty 0 M.empty 0
319
324
320-- | How critical the issue is
325-- | How critical the issue is
321data Level = Error | Warning deriving Show
326data Level = Error | Warning deriving Show
@@ -326,56 +331,80 @@ data Level = Error | Warning deriving Show
326unwrapErrorMessage :: ErrorMessage -> SimpleErrorMessage
331unwrapErrorMessage :: ErrorMessage -> SimpleErrorMessage
327unwrapErrorMessage (ErrorMessage _ se) = se
332unwrapErrorMessage (ErrorMessage _ se) = se
328
333
329−replaceUnknowns :: Type -> State UnknownMap Type
334+replaceUnknowns :: Type -> State TypeMap Type
330replaceUnknowns = everywhereOnTypesM replaceTypes
335replaceUnknowns = everywhereOnTypesM replaceTypes
331 where
336 where
332− lookupTable :: (LabelType, Int) -> UnknownMap -> (Int, UnknownMap)
333− lookupTable x m = case M.lookup x m of
334− Nothing -> let i = length (filter (on (==) fst x) (M.keys m)) in (i, M.insert x i m)
335− Just i -> (i, m)
336−
337− replaceTypes :: Type -> State UnknownMap Type
337+ replaceTypes :: Type -> State TypeMap Type
338− replaceTypes (TUnknown u) = state $ first TUnknown . lookupTable (TypeLabel, u)
338+ replaceTypes (TUnknown u) = do
339+ m <- get
340+ case M.lookup u (umUnknownMap m) of
341+ Nothing -> do
342+ let u' = umNextUnknown m
343+ put $ m { umUnknownMap = M.insert u u' (umUnknownMap m), umNextUnknown = u' + 1 }
344+ return (TUnknown u')
345+ Just u' -> return (TUnknown u')
339− replaceTypes (Skolem name s sko) = state $ first (flip (Skolem name) sko) . lookupTable (SkolemLabel name, s)
346+ replaceTypes (Skolem name s sko ss) = do
347+ m <- get
348+ case M.lookup s (umSkolemMap m) of
349+ Nothing -> do
350+ let s' = umNextSkolem m
351+ put $ m { umSkolemMap = M.insert s (name, s', ss) (umSkolemMap m), umNextSkolem = s' + 1 }
352+ return (Skolem name s' sko ss)
353+ Just (_, s', _) -> return (Skolem name s' sko ss)
340 replaceTypes other = return other
354 replaceTypes other = return other
341
355
342onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
356onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage
343onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse gHint hints <*> gSimple simple
357onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse gHint hints <*> gSimple simple
344 where
358 where
345− gSimple (InfiniteType t) = InfiniteType <$> f t
359+ gSimple (InfiniteType t) = InfiniteType <$> f t
346− gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> f t1 <*> f t2
360+ gSimple (TypesDoNotUnify t1 t2) = TypesDoNotUnify <$> f t1 <*> f t2
347− gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> f t1 <*> f t2
361+ gSimple (ConstrainedTypeUnified t1 t2) = ConstrainedTypeUnified <$> f t1 <*> f t2
348− gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
362+ gSimple (ExprDoesNotHaveType e t) = ExprDoesNotHaveType e <$> f t
349− gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
363+ gSimple (CannotApplyFunction t e) = CannotApplyFunction <$> f t <*> pure e
350− gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
364+ gSimple (InvalidInstanceHead t) = InvalidInstanceHead <$> f t
351− gSimple other = pure other
365+ gSimple other = pure other
366+
352− gHint (ErrorInSubsumption t1 t2) = ErrorInSubsumption <$> f t1 <*> f t2
367+ gHint (ErrorInSubsumption t1 t2) = ErrorInSubsumption <$> f t1 <*> f t2
353− gHint (ErrorUnifyingTypes t1 t2) = ErrorUnifyingTypes <$> f t1 <*> f t2
368+ gHint (ErrorUnifyingTypes t1 t2) = ErrorUnifyingTypes <$> f t1 <*> f t2
354− gHint (ErrorCheckingType e t) = ErrorCheckingType e <$> f t
369+ gHint (ErrorCheckingType e t) = ErrorCheckingType e <$> f t
355− gHint (ErrorCheckingKind t) = ErrorCheckingKind <$> f t
370+ gHint (ErrorCheckingKind t) = ErrorCheckingKind <$> f t
356− gHint (ErrorInApplication e1 t1 e2) = ErrorInApplication e1 <$> f t1 <*> pure e2
371+ gHint (ErrorInApplication e1 t1 e2) = ErrorInApplication e1 <$> f t1 <*> pure e2
357− gHint other = pure other
372+ gHint other = pure other
358
373
359-- |
374-- |
360-- Pretty print a single error, simplifying if necessary
375-- Pretty print a single error, simplifying if necessary
361--
376--
362−prettyPrintSingleError :: Bool -> Level -> ErrorMessage -> State UnknownMap Box.Box
377+prettyPrintSingleError :: Bool -> Level -> ErrorMessage -> State TypeMap Box.Box
378+prettyPrintSingleError full level e = do
363−prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
379+ em <- onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)
380+ um <- get
381+ return (prettyPrintErrorMessage um em)
364 where
382 where
365
383
366 -- Pretty print an ErrorMessage
384 -- Pretty print an ErrorMessage
367− prettyPrintErrorMessage :: ErrorMessage -> Box.Box
385+ prettyPrintErrorMessage :: TypeMap -> ErrorMessage -> Box.Box
368− prettyPrintErrorMessage (ErrorMessage hints simple) =
386+ prettyPrintErrorMessage typeMap (ErrorMessage hints simple) =
369 paras $
387 paras $
370− [ foldr renderHint (indent (renderSimpleErrorMessage simple)) hints
388+ foldr renderHint (indent (renderSimpleErrorMessage simple)) hints
389+ : typeInformation
371− , Box.moveDown 1 $ paras [ line $ "See " ++ wikiUri ++ " for more information, "
390+ ++ [ Box.moveDown 1 $ paras [ line $ "See " ++ wikiUri ++ " for more information, "
372− , line $ "or to contribute content related to this " ++ levelText ++ "."
391+ , line $ "or to contribute content related to this " ++ levelText ++ "."
373− ]
392+ ]
374− ]
393+ ]
375 where
394 where
376 wikiUri :: String
395 wikiUri :: String
377 wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
396 wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e
378
397
398+ typeInformation :: [Box.Box]
399+ typeInformation = M.elems . M.mapMaybe skolemInfo . umSkolemMap $ typeMap
400+ where
401+ skolemInfo :: (String, Int, Maybe SourceSpan) -> Maybe Box.Box
402+ skolemInfo (name, s, Just ss) =
403+ Just . Box.moveDown 1 $ paras [ line $ "(" ++ name ++ show s ++ " is a rigid type variable"
404+ , line $ " bound at " ++ displayStartEndPos ss ++ ")"
405+ ]
406+ skolemInfo _ = Nothing
407+
379 renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
408 renderSimpleErrorMessage :: SimpleErrorMessage -> Box.Box
380 renderSimpleErrorMessage (CannotGetFileInfo path) =
409 renderSimpleErrorMessage (CannotGetFileInfo path) =
381 paras [ line "Unable to read file info: "
410 paras [ line "Unable to read file info: "
@@ -878,6 +907,7 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
878 hintCategory ErrorUnifyingTypes{} = CheckHint
907 hintCategory ErrorUnifyingTypes{} = CheckHint
879 hintCategory ErrorInSubsumption{} = CheckHint
908 hintCategory ErrorInSubsumption{} = CheckHint
880 hintCategory ErrorInApplication{} = CheckHint
909 hintCategory ErrorInApplication{} = CheckHint
910+ hintCategory ErrorCheckingKind{} = CheckHint
881 hintCategory PositionedError{} = PositionHint
911 hintCategory PositionedError{} = PositionHint
882 hintCategory _ = OtherHint
912 hintCategory _ = OtherHint
883
913
@@ -895,13 +925,13 @@ prettyPrintMultipleWarnings full = renderBox . prettyPrintMultipleWarningsBox fu
895
925
896-- | Pretty print warnings as a Box
926-- | Pretty print warnings as a Box
897prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> Box.Box
927prettyPrintMultipleWarningsBox :: Bool -> MultipleErrors -> Box.Box
898−prettyPrintMultipleWarningsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Warning "Warning found:" "Warning" full
928+prettyPrintMultipleWarningsBox full = flip evalState defaultUnknownMap . prettyPrintMultipleErrorsWith Warning "Warning found:" "Warning" full
899
929
900-- | Pretty print errors as a Box
930-- | Pretty print errors as a Box
901prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> Box.Box
931prettyPrintMultipleErrorsBox :: Bool -> MultipleErrors -> Box.Box
902−prettyPrintMultipleErrorsBox full = flip evalState M.empty . prettyPrintMultipleErrorsWith Error "Error found:" "Error" full
932+prettyPrintMultipleErrorsBox full = flip evalState defaultUnknownMap . prettyPrintMultipleErrorsWith Error "Error found:" "Error" full
903
933
904−prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> State UnknownMap Box.Box
934+prettyPrintMultipleErrorsWith :: Level -> String -> String -> Bool -> MultipleErrors -> State TypeMap Box.Box
905prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
935prettyPrintMultipleErrorsWith level intro _ full (MultipleErrors [e]) = do
906 result <- prettyPrintSingleError full level e
936 result <- prettyPrintSingleError full level e
907 return $
937 return $
src/Language/PureScript/Pretty/Types.hs+1−1
@@ -45,7 +45,7 @@ typeLiterals = mkPattern match
45 match (PrettyPrintObject row) = Just $ prettyPrintRowWith '{' '}' row
45 match (PrettyPrintObject row) = Just $ prettyPrintRowWith '{' '}' row
46 match (TypeConstructor ctor) = Just $ text $ runProperName $ disqualify ctor
46 match (TypeConstructor ctor) = Just $ text $ runProperName $ disqualify ctor
47 match (TUnknown u) = Just $ text $ '_' : show u
47 match (TUnknown u) = Just $ text $ '_' : show u
48− match (Skolem name s _) = Just $ text $ name ++ show s
48+ match (Skolem name s _ _) = Just $ text $ name ++ show s
49 match REmpty = Just $ text "()"
49 match REmpty = Just $ text "()"
50 match row@RCons{} = Just $ prettyPrintRowWith '(' ')' row
50 match row@RCons{} = Just $ prettyPrintRowWith '(' ')' row
51 match _ = Nothing
51 match _ = Nothing
src/Language/PureScript/TypeChecker/Entailment.hs+7−7
@@ -147,7 +147,7 @@ entails moduleName context = solve
147-- and return a substitution from type variables to types which makes the type heads unify.
147-- and return a substitution from type variables to types which makes the type heads unify.
148--
148--
149typeHeadsAreEqual :: ModuleName -> Type -> Type -> Maybe [(String, Type)]
149typeHeadsAreEqual :: ModuleName -> Type -> Type -> Maybe [(String, Type)]
150−typeHeadsAreEqual _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
150+typeHeadsAreEqual _ (Skolem _ s1 _ _) (Skolem _ s2 _ _) | s1 == s2 = Just []
151typeHeadsAreEqual _ t (TypeVar v) = Just [(v, t)]
151typeHeadsAreEqual _ t (TypeVar v) = Just [(v, t)]
152typeHeadsAreEqual _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
152typeHeadsAreEqual _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
153typeHeadsAreEqual m (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m h1 h2
153typeHeadsAreEqual m (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m h1 h2
@@ -164,12 +164,12 @@ typeHeadsAreEqual m r1@RCons{} r2@RCons{} =
164 <*> go sd1 r1' sd2 r2'
164 <*> go sd1 r1' sd2 r2'
165 where
165 where
166 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Maybe [(String, Type)]
166 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Maybe [(String, Type)]
167− go [] REmpty [] REmpty = Just []
167+ go [] REmpty [] REmpty = Just []
168− go [] (TUnknown _) _ _ = Just []
168+ go [] (TUnknown _) _ _ = Just []
169− go [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = Just []
169+ go [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = Just []
170− go [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = Just []
170+ go [] (Skolem _ s1 _ _) [] (Skolem _ s2 _ _) | s1 == s2 = Just []
171− go sd r [] (TypeVar v) = Just [(v, rowFromList (sd, r))]
171+ go sd r [] (TypeVar v) = Just [(v, rowFromList (sd, r))]
172− go _ _ _ _ = Nothing
172+ go _ _ _ _ = Nothing
173typeHeadsAreEqual _ _ _ = Nothing
173typeHeadsAreEqual _ _ _ = Nothing
174
174
175-- |
175-- |
src/Language/PureScript/TypeChecker/Kinds.hs+1−1
@@ -226,7 +226,7 @@ infer' other = (, []) <$> go other
226 go (TypeVar v) = do
226 go (TypeVar v) = do
227 Just moduleName <- checkCurrentModule <$> get
227 Just moduleName <- checkCurrentModule <$> get
228 lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
228 lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
229− go (Skolem v _ _) = do
229+ go (Skolem v _ _ _) = do
230 Just moduleName <- checkCurrentModule <$> get
230 Just moduleName <- checkCurrentModule <$> get
231 lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
231 lookupTypeVariable moduleName (Qualified Nothing (ProperName v))
232 go (TypeConstructor v) = do
232 go (TypeConstructor v) = do
src/Language/PureScript/TypeChecker/Skolems.hs+8−8
@@ -71,30 +71,30 @@ newSkolemScope = do
71-- |
71-- |
72-- Skolemize a type variable by replacing its instances with fresh skolem constants
72-- Skolemize a type variable by replacing its instances with fresh skolem constants
73--
73--
74−skolemize :: String -> Int -> SkolemScope -> Type -> Type
74+skolemize :: String -> Int -> SkolemScope -> Maybe SourceSpan -> Type -> Type
75−skolemize ident sko scope = replaceTypeVars ident (Skolem ident sko scope)
75+skolemize ident sko scope ss = replaceTypeVars ident (Skolem ident sko scope ss)
76
76
77-- |
77-- |
78-- This function has one purpose - to skolemize type variables appearing in a
78-- This function has one purpose - to skolemize type variables appearing in a
79-- SuperClassDictionary placeholder. These type variables are somewhat unique since they are the
79-- SuperClassDictionary placeholder. These type variables are somewhat unique since they are the
80-- only example of scoped type variables.
80-- only example of scoped type variables.
81--
81--
82−skolemizeTypesInValue :: String -> Int -> SkolemScope -> Expr -> Expr
82+skolemizeTypesInValue :: String -> Int -> SkolemScope -> Maybe SourceSpan -> Expr -> Expr
83−skolemizeTypesInValue ident sko scope =
83+skolemizeTypesInValue ident sko scope ss =
84 let
84 let
85 (_, f, _, _, _) = everywhereWithContextOnValuesM [] defS onExpr onBinder defS defS
85 (_, f, _, _, _) = everywhereWithContextOnValuesM [] defS onExpr onBinder defS defS
86 in runIdentity . f
86 in runIdentity . f
87 where
87 where
88 onExpr :: [String] -> Expr -> Identity ([String], Expr)
88 onExpr :: [String] -> Expr -> Identity ([String], Expr)
89 onExpr sco (SuperClassDictionary c ts)
89 onExpr sco (SuperClassDictionary c ts)
90− | ident `notElem` sco = return (sco, SuperClassDictionary c (map (skolemize ident sko scope) ts))
90+ | ident `notElem` sco = return (sco, SuperClassDictionary c (map (skolemize ident sko scope ss) ts))
91 onExpr sco (TypedValue check val ty)
91 onExpr sco (TypedValue check val ty)
92− | ident `notElem` sco = return (sco ++ peelTypeVars ty, TypedValue check val (skolemize ident sko scope ty))
92+ | ident `notElem` sco = return (sco ++ peelTypeVars ty, TypedValue check val (skolemize ident sko scope ss ty))
93 onExpr sco other = return (sco, other)
93 onExpr sco other = return (sco, other)
94
94
95 onBinder :: [String] -> Binder -> Identity ([String], Binder)
95 onBinder :: [String] -> Binder -> Identity ([String], Binder)
96 onBinder sco (TypedBinder ty b)
96 onBinder sco (TypedBinder ty b)
97− | ident `notElem` sco = return (sco ++ peelTypeVars ty, TypedBinder (skolemize ident sko scope ty) b)
97+ | ident `notElem` sco = return (sco ++ peelTypeVars ty, TypedBinder (skolemize ident sko scope ss ty) b)
98 onBinder sco other = return (sco, other)
98 onBinder sco other = return (sco, other)
99
99
100 peelTypeVars :: Type -> [String]
100 peelTypeVars :: Type -> [String]
@@ -129,7 +129,7 @@ skolemEscapeCheck root@TypedValue{} =
129 collectSkolems :: Type -> [SkolemScope]
129 collectSkolems :: Type -> [SkolemScope]
130 collectSkolems = nub . everythingOnTypes (++) collect
130 collectSkolems = nub . everythingOnTypes (++) collect
131 where
131 where
132− collect (Skolem _ _ scope) = [scope]
132+ collect (Skolem _ _ scope _) = [scope]
133 collect _ = []
133 collect _ = []
134 go scos _ = (scos, [])
134 go scos _ = (scos, [])
135 findBindingScope :: SkolemScope -> Maybe Expr
135 findBindingScope :: SkolemScope -> Maybe Expr
src/Language/PureScript/TypeChecker/Subsumption.hs+1−1
@@ -55,7 +55,7 @@ subsumes' val ty1 (ForAll ident ty2 sco) =
55 case sco of
55 case sco of
56 Just sco' -> do
56 Just sco' -> do
57 sko <- newSkolemConstant
57 sko <- newSkolemConstant
58− let sk = skolemize ident sko sco' ty2
58+ let sk = skolemize ident sko sco' Nothing ty2
59 subsumes val ty1 sk
59 subsumes val ty1 sk
60 Nothing -> internalError "subsumes: unspecified skolem scope"
60 Nothing -> internalError "subsumes: unspecified skolem scope"
61subsumes' val (TypeApp (TypeApp f1 arg1) ret1) (TypeApp (TypeApp f2 arg2) ret2) | f1 == tyFunction && f2 == tyFunction = do
61subsumes' val (TypeApp (TypeApp f1 arg1) ret1) (TypeApp (TypeApp f2 arg2) ret2) | f1 == tyFunction && f2 == tyFunction = do
src/Language/PureScript/TypeChecker/Types.hs+5−2
@@ -487,8 +487,11 @@ check' :: forall m.
487check' val (ForAll ident ty _) = do
487check' val (ForAll ident ty _) = do
488 scope <- newSkolemScope
488 scope <- newSkolemScope
489 sko <- newSkolemConstant
489 sko <- newSkolemConstant
490+ let ss = case val of
491+ PositionedValue pos _ _ -> Just pos
492+ _ -> Nothing
490− let sk = skolemize ident sko scope ty
493+ sk = skolemize ident sko scope ss ty
491− let skVal = skolemizeTypesInValue ident sko scope val
494+ skVal = skolemizeTypesInValue ident sko scope ss val
492 val' <- check skVal sk
495 val' <- check skVal sk
493 return $ TypedValue True val' (ForAll ident ty (Just scope))
496 return $ TypedValue True val' (ForAll ident ty (Just scope))
494check' val t@(ConstrainedType constraints ty) = do
497check' val t@(ConstrainedType constraints ty) = do
src/Language/PureScript/TypeChecker/Unify.hs+7−7
@@ -105,13 +105,13 @@ unifyTypes t1 t2 = do
105 case (sc1, sc2) of
105 case (sc1, sc2) of
106 (Just sc1', Just sc2') -> do
106 (Just sc1', Just sc2') -> do
107 sko <- newSkolemConstant
107 sko <- newSkolemConstant
108− let sk1 = skolemize ident1 sko sc1' ty1
108+ let sk1 = skolemize ident1 sko sc1' Nothing ty1
109− let sk2 = skolemize ident2 sko sc2' ty2
109+ let sk2 = skolemize ident2 sko sc2' Nothing ty2
110 sk1 `unifyTypes` sk2
110 sk1 `unifyTypes` sk2
111 _ -> internalError "unifyTypes: unspecified skolem scope"
111 _ -> internalError "unifyTypes: unspecified skolem scope"
112 unifyTypes' (ForAll ident ty1 (Just sc)) ty2 = do
112 unifyTypes' (ForAll ident ty1 (Just sc)) ty2 = do
113 sko <- newSkolemConstant
113 sko <- newSkolemConstant
114− let sk = skolemize ident sko sc ty1
114+ let sk = skolemize ident sko sc Nothing ty1
115 sk `unifyTypes` ty2
115 sk `unifyTypes` ty2
116 unifyTypes' ForAll{} _ = internalError "unifyTypes: unspecified skolem scope"
116 unifyTypes' ForAll{} _ = internalError "unifyTypes: unspecified skolem scope"
117 unifyTypes' ty f@ForAll{} = f `unifyTypes` ty
117 unifyTypes' ty f@ForAll{} = f `unifyTypes` ty
@@ -121,7 +121,7 @@ unifyTypes t1 t2 = do
121 unifyTypes' (TypeApp t3 t4) (TypeApp t5 t6) = do
121 unifyTypes' (TypeApp t3 t4) (TypeApp t5 t6) = do
122 t3 `unifyTypes` t5
122 t3 `unifyTypes` t5
123 t4 `unifyTypes` t6
123 t4 `unifyTypes` t6
124− unifyTypes' (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = return ()
124+ unifyTypes' (Skolem _ s1 _ _) (Skolem _ s2 _ _) | s1 == s2 = return ()
125 unifyTypes' (KindedType ty1 _) ty2 = ty1 `unifyTypes` ty2
125 unifyTypes' (KindedType ty1 _) ty2 = ty1 `unifyTypes` ty2
126 unifyTypes' ty1 (KindedType ty2 _) = ty1 `unifyTypes` ty2
126 unifyTypes' ty1 (KindedType ty2 _) = ty1 `unifyTypes` ty2
127 unifyTypes' r1@RCons{} r2 = unifyRows r1 r2
127 unifyTypes' r1@RCons{} r2 = unifyRows r1 r2
@@ -162,7 +162,7 @@ unifyRows r1 r2 =
162 solveType u2 (rowFromList (sd1, rest))
162 solveType u2 (rowFromList (sd1, rest))
163 unifyRows' [] REmpty [] REmpty = return ()
163 unifyRows' [] REmpty [] REmpty = return ()
164 unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
164 unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
165− unifyRows' [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = return ()
165+ unifyRows' [] (Skolem _ s1 _ _) [] (Skolem _ s2 _ _) | s1 == s2 = return ()
166 unifyRows' _ _ _ _ = throwError . errorMessage $ TypesDoNotUnify r1 r2
166 unifyRows' _ _ _ _ = throwError . errorMessage $ TypesDoNotUnify r1 r2
167
167
168-- |
168-- |
@@ -170,7 +170,7 @@ unifyRows r1 r2 =
170--
170--
171unifiesWith :: Type -> Type -> Bool
171unifiesWith :: Type -> Type -> Bool
172unifiesWith (TUnknown u1) (TUnknown u2) | u1 == u2 = True
172unifiesWith (TUnknown u1) (TUnknown u2) | u1 == u2 = True
173−unifiesWith (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = True
173+unifiesWith (Skolem _ s1 _ _) (Skolem _ s2 _ _) | s1 == s2 = True
174unifiesWith (TypeVar v1) (TypeVar v2) | v1 == v2 = True
174unifiesWith (TypeVar v1) (TypeVar v2) | v1 == v2 = True
175unifiesWith (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = True
175unifiesWith (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = True
176unifiesWith (TypeApp h1 t1) (TypeApp h2 t2) = h1 `unifiesWith` h2 && t1 `unifiesWith` t2
176unifiesWith (TypeApp h1 t1) (TypeApp h2 t2) = h1 `unifiesWith` h2 && t1 `unifiesWith` t2
@@ -187,7 +187,7 @@ unifiesWith r1@RCons{} r2@RCons{} =
187 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Bool
187 go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Bool
188 go [] REmpty [] REmpty = True
188 go [] REmpty [] REmpty = True
189 go [] (TypeVar v1) [] (TypeVar v2) = v1 == v2
189 go [] (TypeVar v1) [] (TypeVar v2) = v1 == v2
190− go [] (Skolem _ s1 _) [] (Skolem _ s2 _) = s1 == s2
190+ go [] (Skolem _ s1 _ _) [] (Skolem _ s2 _ _) = s1 == s2
191 go [] (TUnknown _) _ _ = True
191 go [] (TUnknown _) _ _ = True
192 go _ _ [] (TUnknown _) = True
192 go _ _ [] (TUnknown _) = True
193 go _ (TUnknown _) _ (TUnknown _) = True
193 go _ (TUnknown _) _ (TUnknown _) = True
src/Language/PureScript/Types.hs+2−1
@@ -34,6 +34,7 @@ import Control.Monad ((<=<))
34import Language.PureScript.Names
34import Language.PureScript.Names
35import Language.PureScript.Kinds
35import Language.PureScript.Kinds
36import Language.PureScript.Traversals
36import Language.PureScript.Traversals
37+import Language.PureScript.AST.SourcePos
37
38
38-- |
39-- |
39-- An identifier for the scope of a skolem variable
40-- An identifier for the scope of a skolem variable
@@ -75,7 +76,7 @@ data Type
75 -- |
76 -- |
76 -- A skolem constant
77 -- A skolem constant
77 --
78 --
78− | Skolem String Int SkolemScope
79+ | Skolem String Int SkolemScope (Maybe SourceSpan)
79 -- |
80 -- |
80 -- An empty row
81 -- An empty row
81 --
82 --