@@ -31,7 +31,7 @@ import Control.Arrow (second)
31import Control.Monad
31import Control.Monad
32import Control.Monad.Error.Class (MonadError(..))
32import Control.Monad.Error.Class (MonadError(..))
33import Control.Monad.State.Class (MonadState(..), gets)
33import Control.Monad.State.Class (MonadState(..), gets)
34−import Control.Monad.Supply.Class (MonadSupply)
34+import Control.Monad.Supply.Class (MonadSupply, peek)
35import Control.Monad.Writer.Class (MonadWriter(..))
35import Control.Monad.Writer.Class (MonadWriter(..))
37import Data.Bifunctor (bimap)
37import Data.Bifunctor (bimap)
@@ -55,9 +55,11 @@ import Language.PureScript.TypeChecker.Rows
55import Language.PureScript.TypeChecker.Skolems
55import Language.PureScript.TypeChecker.Skolems
56import Language.PureScript.TypeChecker.Subsumption
56import Language.PureScript.TypeChecker.Subsumption
57import Language.PureScript.TypeChecker.Synonyms
57import Language.PureScript.TypeChecker.Synonyms
58+import Language.PureScript.TypeChecker.TypeSearch
58import Language.PureScript.TypeChecker.Unify
59import Language.PureScript.TypeChecker.Unify
59import Language.PureScript.Types
60import Language.PureScript.Types
61data BindingGroupType
63data BindingGroupType
62 = RecursiveBindingGroup
64 = RecursiveBindingGroup
63 | NonRecursiveBindingGroup
65 | NonRecursiveBindingGroup
@@ -72,6 +74,10 @@ typesOf
72 -> [(Ident, Expr)]
74 -> [(Ident, Expr)]
73 -> m [(Ident, (Expr, Type))]
75 -> m [(Ident, (Expr, Type))]
74typesOf bindingGroupType moduleName vals = withFreshSubstitution $ do
76typesOf bindingGroupType moduleName vals = withFreshSubstitution $ do
77+ -- TODO: If we push withoutWarnings into the do block we can differentiate
78+ -- between ds1 and ds2 warnings and capture shouldGeneralize and the unsolved
80+ -- Careful: We need to make sure the capturingSubstitution still does the right thing
75 (tys, w) <- withoutWarnings . capturingSubstitution tidyUp $ do
81 (tys, w) <- withoutWarnings . capturingSubstitution tidyUp $ do
76 (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup (Just moduleName) vals
82 (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup (Just moduleName) vals
77 ds1 <- parU typed $ \e -> checkTypedBindingGroupElement moduleName e dict
83 ds1 <- parU typed $ \e -> checkTypedBindingGroupElement moduleName e dict
@@ -106,8 +112,9 @@ typesOf bindingGroupType moduleName vals = withFreshSubstitution $ do
106 TypeClassData{ typeClassDependencies } <- gets (findClass . typeClasses . checkEnv)
112 TypeClassData{ typeClassDependencies } <- gets (findClass . typeClasses . checkEnv)
107 let solved = foldMap (S.fromList . fdDetermined) typeClassDependencies
113 let solved = foldMap (S.fromList . fdDetermined) typeClassDependencies
108 let constraintTypeVars = nub . foldMap (unknownsInType . fst) . filter ((`notElem` solved) . snd) $ zip (constraintArgs con) [0..]
114 let constraintTypeVars = nub . foldMap (unknownsInType . fst) . filter ((`notElem` solved) . snd) $ zip (constraintArgs con) [0..]
109− when (any (`notElem` unsolvedTypeVars) constraintTypeVars) $
115+ when (any (`notElem` unsolvedTypeVars) constraintTypeVars) $ do
110− throwError . onErrorMessages (replaceTypes currentSubst) . errorMessage $ NoInstanceFound con
117+ throwError . onErrorMessages (replaceTypes (not shouldGeneralize) currentSubst nextVar) . errorMessage $ NoInstanceFound con
112 -- Check skolem variables did not escape their scope
119 -- Check skolem variables did not escape their scope
113 skolemEscapeCheck val'
120 skolemEscapeCheck val'
@@ -118,11 +125,24 @@ typesOf bindingGroupType moduleName vals = withFreshSubstitution $ do
118 -- Show warnings here, since types in wildcards might have been solved during
125 -- Show warnings here, since types in wildcards might have been solved during
119 -- instance resolution (by functional dependencies).
126 -- instance resolution (by functional dependencies).
120 finalSubst <- gets checkSubstitution
127 finalSubst <- gets checkSubstitution
129+ -- TODO: We should only do type search for Typed Holes which we inferred
130+ -- without generalizing type class constraints
131+ -- eg. foldMap ?x [1, 2, 3] finds `negate` right now, which is wrong
121− escalateWarningWhen isHoleError . tell . onErrorMessages (replaceTypes finalSubst) $ w
134+ escalateWarningWhen isHoleError . tell . onErrorMessages (replaceTypes True finalSubst nextVar) $ w
123 return inferred
136 return inferred
138+ replaceTypes shouldRunTypeSearch subst nextVar =
139+ (if shouldRunTypeSearch then runTypeSearch else id)
125− replaceTypes subst = onTypesInErrorMessage (substituteType subst)
140+ . onTypesInErrorMessage (substituteType subst)
142+ runTypeSearch (ErrorMessage hints (HoleInferredType x ty y (TSBefore env))) =
143+ ErrorMessage hints (HoleInferredType x ty y $ TSAfter $
144+ fmap (substituteType subst) <$> M.toList (typeSearch env nextVar (substituteType subst ty)))
127 -- | Generalize type vars using forall and add inferred constraints
147 -- | Generalize type vars using forall and add inferred constraints
128 generalize unsolved = varIfUnknown . constrain unsolved
148 generalize unsolved = varIfUnknown . constrain unsolved
@@ -207,17 +227,6 @@ isTyped (name, PositionedValue pos c value) =
207 (isTyped (name, value))
227 (isTyped (name, value))
208isTyped (name, value) = Left (name, value)
228isTyped (name, value) = Left (name, value)
211−-- Map a function over type annotations appearing inside a value
213−overTypes :: (Type -> Type) -> Expr -> Expr
214−overTypes f = let (_, f', _) = everywhereOnValues id g id in f'
217− g (TypedValue checkTy val t) = TypedValue checkTy val (f t)
218− g (TypeClassDictionary c sco hints) = TypeClassDictionary (mapConstraintArgs (map f) c) sco hints
221-- | Check the kind of a type, failing if it is not of kind *.
230-- | Check the kind of a type, failing if it is not of kind *.
222checkTypeKind ::
231checkTypeKind ::
223 (MonadError MultipleErrors m) =>
232 (MonadError MultipleErrors m) =>
@@ -345,7 +354,8 @@ infer' (TypedValue checkType val ty) = do
345infer' (Hole name) = do
354infer' (Hole name) = do
346 ty <- freshType
355 ty <- freshType
347 ctx <- getLocalContext
356 ctx <- getLocalContext
348− tell . errorMessage $ HoleInferredType name ty ctx
358+ tell . errorMessage $ HoleInferredType name ty ctx (TSBefore env)
349 return $ TypedValue True (Hole name) ty
359 return $ TypedValue True (Hole name) ty
350infer' (PositionedValue pos c val) = warnAndRethrowWithPositionTC pos $ do
360infer' (PositionedValue pos c val) = warnAndRethrowWithPositionTC pos $ do
351 TypedValue t v ty <- infer' val
361 TypedValue t v ty <- infer' val