@@ -31,7 +31,7 @@ import Control.Arrow (second)
3131import Control.Monad
3232import Control.Monad.Error.Class (MonadError(..))
3333import Control.Monad.State.Class (MonadState(..), gets)
34−import Control.Monad.Supply.Class (MonadSupply)
34+import Control.Monad.Supply.Class (MonadSupply, peek)
3535import Control.Monad.Writer.Class (MonadWriter(..))
3636
3737import Data.Bifunctor (bimap)
@@ -55,9 +55,11 @@ import Language.PureScript.TypeChecker.Rows
5555import Language.PureScript.TypeChecker.Skolems
5656import Language.PureScript.TypeChecker.Subsumption
5757import Language.PureScript.TypeChecker.Synonyms
58+import Language.PureScript.TypeChecker.TypeSearch
5859import Language.PureScript.TypeChecker.Unify
5960import Language.PureScript.Types
6061
62+
6163data BindingGroupType
6264 = RecursiveBindingGroup
6365 | NonRecursiveBindingGroup
@@ -72,6 +74,10 @@ typesOf
7274 -> [(Ident, Expr)]
7375 -> m [(Ident, (Expr, Type))]
7476typesOf 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
79+ -- dictionaries
80+ -- Careful: We need to make sure the capturingSubstitution still does the right thing
7581 (tys, w) <- withoutWarnings . capturingSubstitution tidyUp $ do
7682 (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup (Just moduleName) vals
7783 ds1 <- parU typed $ \e -> checkTypedBindingGroupElement moduleName e dict
@@ -106,8 +112,9 @@ typesOf bindingGroupType moduleName vals = withFreshSubstitution $ do
106112 TypeClassData{ typeClassDependencies } <- gets (findClass . typeClasses . checkEnv)
107113 let solved = foldMap (S.fromList . fdDetermined) typeClassDependencies
108114 let constraintTypeVars = nub . foldMap (unknownsInType . fst) . filter ((`notElem` solved) . snd) $ zip (constraintArgs con) [0..]
109− when (any (`notElem` unsolvedTypeVars) constraintTypeVars) $
110− throwError . onErrorMessages (replaceTypes currentSubst) . errorMessage $ NoInstanceFound con
115+ when (any (`notElem` unsolvedTypeVars) constraintTypeVars) $ do
116+ nextVar <- peek
117+ throwError . onErrorMessages (replaceTypes (not shouldGeneralize) currentSubst nextVar) . errorMessage $ NoInstanceFound con
111118
112119 -- Check skolem variables did not escape their scope
113120 skolemEscapeCheck val'
@@ -118,11 +125,24 @@ typesOf bindingGroupType moduleName vals = withFreshSubstitution $ do
118125 -- Show warnings here, since types in wildcards might have been solved during
119126 -- instance resolution (by functional dependencies).
120127 finalSubst <- gets checkSubstitution
121− escalateWarningWhen isHoleError . tell . onErrorMessages (replaceTypes finalSubst) $ w
128+
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
132+
133+ nextVar <- peek
134+ escalateWarningWhen isHoleError . tell . onErrorMessages (replaceTypes True finalSubst nextVar) $ w
122135
123136 return inferred
124137 where
125− replaceTypes subst = onTypesInErrorMessage (substituteType subst)
138+ replaceTypes shouldRunTypeSearch subst nextVar =
139+ (if shouldRunTypeSearch then runTypeSearch else id)
140+ . onTypesInErrorMessage (substituteType subst)
141+ where
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)))
145+ runTypeSearch x = x
126146
127147 -- | Generalize type vars using forall and add inferred constraints
128148 generalize unsolved = varIfUnknown . constrain unsolved
@@ -207,17 +227,6 @@ isTyped (name, PositionedValue pos c value) =
207227 (isTyped (name, value))
208228isTyped (name, value) = Left (name, value)
209229
210−-- |
211−-- Map a function over type annotations appearing inside a value
212−--
213−overTypes :: (Type -> Type) -> Expr -> Expr
214−overTypes f = let (_, f', _) = everywhereOnValues id g id in f'
215− where
216− g :: Expr -> Expr
217− g (TypedValue checkTy val t) = TypedValue checkTy val (f t)
218− g (TypeClassDictionary c sco hints) = TypeClassDictionary (mapConstraintArgs (map f) c) sco hints
219− g other = other
220−
221230-- | Check the kind of a type, failing if it is not of kind *.
222231checkTypeKind ::
223232 (MonadError MultipleErrors m) =>
@@ -345,7 +354,8 @@ infer' (TypedValue checkType val ty) = do
345354infer' (Hole name) = do
346355 ty <- freshType
347356 ctx <- getLocalContext
348− tell . errorMessage $ HoleInferredType name ty ctx
357+ env <- getEnv
358+ tell . errorMessage $ HoleInferredType name ty ctx (TSBefore env)
349359 return $ TypedValue True (Hole name) ty
350360infer' (PositionedValue pos c val) = warnAndRethrowWithPositionTC pos $ do
351361 TypedValue t v ty <- infer' val