Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Language/PureScript/AST/Declarations.hs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ data SimpleErrorMessage
| ShadowedTypeVar Text
| UnusedTypeVar Text
| WildcardInferredType SourceType Context
| HoleInferredType Text SourceType Context TypeSearch
| HoleInferredType Text SourceType Context (Maybe TypeSearch)
| MissingTypeDeclaration Ident SourceType
| OverlappingPattern [[Binder]] Bool
| IncompleteExhaustivityCheck
Expand Down
2 changes: 1 addition & 1 deletion src/Language/PureScript/Docs/Convert/Single.hs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ convertDeclaration (P.ValueDecl sa _ _ _ [P.MkUnguarded (P.TypedValue _ _ ty)])
convertDeclaration (P.ValueDecl sa _ _ _ _) title =
-- If no explicit type declaration was provided, insert a wildcard, so that
-- the actual type will be added during type checking.
basicDeclaration sa title (ValueDeclaration (P.TypeWildcard ()))
basicDeclaration sa title (ValueDeclaration (P.TypeWildcard () Nothing))
convertDeclaration (P.ExternDeclaration sa _ ty) title =
basicDeclaration sa title (ValueDeclaration (ty $> ()))
convertDeclaration (P.DataDeclaration sa dtype _ args ctors) title =
Expand Down
4 changes: 2 additions & 2 deletions src/Language/PureScript/Docs/RenderedCode/RenderType.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import Language.PureScript.Docs.RenderedCode.RenderKind (renderKind)
typeLiterals :: Pattern () PrettyPrintType RenderedCode
typeLiterals = mkPattern match
where
match PPTypeWildcard =
Just (syntax "_")
match (PPTypeWildcard name) =
Just $ maybe (syntax "_") (syntax . ("?" <>)) name
match (PPTypeVar var) =
Just (typeVar var)
match (PPRecord row) =
Expand Down
7 changes: 5 additions & 2 deletions src/Language/PureScript/Errors.hs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ onTypesInErrorMessageM f (ErrorMessage hints simple) = ErrorMessage <$> traverse
gSimple (ExpectedType ty k) = ExpectedType <$> f ty <*> pure k
gSimple (OrphanInstance nm cl noms ts) = OrphanInstance nm cl noms <$> traverse f ts
gSimple (WildcardInferredType ty ctx) = WildcardInferredType <$> f ty <*> traverse (sndM f) ctx
gSimple (HoleInferredType name ty ctx env) = HoleInferredType name <$> f ty <*> traverse (sndM f) ctx <*> onTypeSearchTypesM f env
gSimple (HoleInferredType name ty ctx env) = HoleInferredType name <$> f ty <*> traverse (sndM f) ctx <*> traverse (onTypeSearchTypesM f) env
gSimple (MissingTypeDeclaration nm ty) = MissingTypeDeclaration nm <$> f ty
gSimple (CannotGeneralizeRecursiveFunction nm ty) = CannotGeneralizeRecursiveFunction nm <$> f ty
gSimple other = pure other
Expand Down Expand Up @@ -852,7 +852,7 @@ prettyPrintSingleError (PPEOptions codeColor full level showDocs relPath) e = fl
let
maxTSResults = 15
tsResult = case ts of
(TSAfter{tsAfterIdentifiers=idents}) | not (null idents) ->
Just (TSAfter{tsAfterIdentifiers=idents}) | not (null idents) ->
let
formatTS (names, types) =
let
Expand Down Expand Up @@ -1461,6 +1461,9 @@ withPosition pos (ErrorMessage hints se) = ErrorMessage (positionedError pos : h
positionedError :: SourceSpan -> ErrorMessageHint
positionedError = PositionedError . pure

filterErrors :: (ErrorMessage -> Bool) -> MultipleErrors -> MultipleErrors
filterErrors f = MultipleErrors . filter f . runMultipleErrors

-- | Runs a computation listening for warnings and then escalating any warnings
-- that match the predicate to error status.
escalateWarningWhen
Expand Down
2 changes: 1 addition & 1 deletion src/Language/PureScript/Ide/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ encodeRebuildErrors = toJSON . map encodeRebuildError . P.runMultipleErrors
encodeRebuildError err = case err of
(P.ErrorMessage _
((P.HoleInferredType name _ _
(P.TSAfter{tsAfterIdentifiers=idents, tsAfterRecordFields=fields})))) ->
(Just (P.TSAfter{tsAfterIdentifiers=idents, tsAfterRecordFields=fields}))))) ->
insertTSCompletions name idents (fromMaybe [] fields) (toJSON (toJSONError False P.Error err))
_ ->
(toJSON . toJSONError False P.Error) err
Expand Down
5 changes: 4 additions & 1 deletion src/Language/PureScript/Parser/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ parseTypeLevelString :: TokenParser SourceType
parseTypeLevelString = withSourceAnnF $ flip TypeLevelString <$> stringLiteral

parseTypeWildcard :: TokenParser SourceType
parseTypeWildcard = withSourceAnnF $ underscore $> TypeWildcard
parseTypeWildcard = withSourceAnnF $ do
name <- Just <$> holeLit
<|> Nothing <$ underscore
return $ flip TypeWildcard name

parseTypeVariable :: TokenParser SourceType
parseTypeVariable = withSourceAnnF $ do
Expand Down
6 changes: 3 additions & 3 deletions src/Language/PureScript/Pretty/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ data PrettyPrintType
= PPTUnknown Int
| PPTypeVar Text
| PPTypeLevelString PSString
| PPTypeWildcard
| PPTypeWildcard (Maybe Text)
| PPTypeConstructor (Qualified (ProperName 'TypeName))
| PPTypeOp (Qualified (OpName 'TypeOpName))
| PPSkolem Text Int
Expand All @@ -68,7 +68,7 @@ convertPrettyPrintType = go
go (TUnknown _ n) = PPTUnknown n
go (TypeVar _ t) = PPTypeVar t
go (TypeLevelString _ s) = PPTypeLevelString s
go (TypeWildcard _) = PPTypeWildcard
go (TypeWildcard _ n) = PPTypeWildcard n
go (TypeConstructor _ c) = PPTypeConstructor c
go (TypeOp _ o) = PPTypeOp o
go (Skolem _ t n _) = PPSkolem t n
Expand Down Expand Up @@ -161,7 +161,7 @@ matchTypeAtom tro@TypeRenderOptions{troSuggesting = suggesting} =
where
typeLiterals :: Pattern () PrettyPrintType Box
typeLiterals = mkPattern match where
match PPTypeWildcard = Just $ text "_"
match (PPTypeWildcard name) = Just $ maybe (text "_") (text . ('?' :) . T.unpack) name
match (PPTypeVar var) = Just $ text $ T.unpack var
match (PPTypeLevelString s) = Just $ text $ T.unpack $ prettyPrintString s
match (PPRecord row) = Just $ prettyPrintRowWith tro '{' '}' row
Expand Down
2 changes: 1 addition & 1 deletion src/Language/PureScript/Sugar/TypeClasses/Deriving.hs
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ deriveGenericRep ss mn syns ds tyConNm tyConArgs repTy = do
argument' = App (Constructor ss argument)

checkIsWildcard :: MonadError MultipleErrors m => SourceSpan -> ProperName 'TypeName -> SourceType -> m ()
checkIsWildcard _ _ (TypeWildcard _) = return ()
checkIsWildcard _ _ (TypeWildcard _ Nothing) = return ()
checkIsWildcard ss tyConNm _ =
throwError . errorMessage' ss $ ExpectedWildcard tyConNm

Expand Down
22 changes: 19 additions & 3 deletions src/Language/PureScript/TypeChecker.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import Control.Monad (when, unless, void, forM)
import Control.Monad.Error.Class (MonadError(..))
import Control.Monad.State.Class (MonadState(..), modify, gets)
import Control.Monad.Supply.Class (MonadSupply)
import Control.Monad.Writer.Class (MonadWriter(..))
import Control.Monad.Writer.Class (MonadWriter(..), censor)

import Data.Foldable (for_, traverse_, toList)
import Data.List (nub, nubBy, (\\), sort, group)
import Data.List (nub, nubBy, (\\), sort, group, intersect)
import Data.Maybe
import Data.Text (Text)
import qualified Data.List.NonEmpty as NEL
Expand Down Expand Up @@ -274,12 +274,13 @@ typeCheckAll moduleName _ = traverse go
internalError "Type declarations should have been removed before typeCheckAlld"
go (ValueDecl sa@(ss, _) name nameKind [] [MkUnguarded val]) = do
env <- getEnv
warnAndRethrow (addHint (ErrorInValueDeclaration name) . addHint (positionedError ss)) $ do
warnAndRethrow (addHint (ErrorInValueDeclaration name) . addHint (positionedError ss)) . censorLocalUnnamedWildcards val $ do
val' <- checkExhaustiveExpr ss env moduleName val
valueIsNotDefined moduleName name
[(_, (val'', ty))] <- typesOf NonRecursiveBindingGroup moduleName [((sa, name), val')]
addValue moduleName name ty nameKind
return $ ValueDecl sa name nameKind [] [MkUnguarded val'']
where
go ValueDeclaration{} = internalError "Binders were not desugared"
go BoundValueDeclaration{} = internalError "BoundValueDeclaration should be desugared"
go (BindingGroupDeclaration vals) = do
Expand Down Expand Up @@ -464,6 +465,21 @@ typeCheckAll moduleName _ = traverse go
| moduleName `S.member` nonOrphanModules = return ()
| otherwise = throwError . errorMessage $ OrphanInstance dictName className nonOrphanModules tys'

censorLocalUnnamedWildcards :: Expr -> m a -> m a
censorLocalUnnamedWildcards (TypedValue _ _ ty) = censor (filterErrors (not . isLocalUnnamedWildcardError ty))
censorLocalUnnamedWildcards _ = id

isLocalUnnamedWildcardError :: SourceType -> ErrorMessage -> Bool
isLocalUnnamedWildcardError ty err@(ErrorMessage _ (WildcardInferredType _ _)) =
let
ssWildcard (TypeWildcard (ss', _) Nothing) = [ss']
ssWildcard _ = []
sssWildcards = everythingOnTypes (<>) ssWildcard ty
sss = maybe [] NEL.toList $ errorSpan err
in
null $ intersect sss sssWildcards
isLocalUnnamedWildcardError _ _ = False

-- |
-- This function adds the argument kinds for a type constructor so that they may appear in the externs file,
-- extracted from the kind of the type constructor itself.
Expand Down
2 changes: 1 addition & 1 deletion src/Language/PureScript/TypeChecker/Kinds.hs
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ infer' other = (, []) <$> go other
k' <- go ty
unifyKinds k k'
return k'
go (TypeWildcard ann) = freshKind ann
go (TypeWildcard ann _) = freshKind ann
go (TUnknown ann _) = freshKind ann
go (TypeLevelString ann _) = return $ kindSymbol $> ann
go (TypeVar ann v) = do
Expand Down
6 changes: 3 additions & 3 deletions src/Language/PureScript/TypeChecker/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,12 @@ typesOf bindingGroupType moduleName vals = withFreshSubstitution $ do
-> ErrorMessage
-> ErrorMessage
runTypeSearch cons st = \case
ErrorMessage hints (HoleInferredType x ty y (TSBefore env)) ->
ErrorMessage hints (HoleInferredType x ty y (Just (TSBefore env))) ->
let subst = checkSubstitution st
searchResult = onTypeSearchTypes
(substituteType subst)
(uncurry TSAfter (typeSearch cons env st (substituteType subst ty)))
in ErrorMessage hints (HoleInferredType x ty y searchResult)
in ErrorMessage hints (HoleInferredType x ty y (Just searchResult))
other -> other

-- | Generalize type vars using forall and add inferred constraints
Expand Down Expand Up @@ -415,7 +415,7 @@ infer' (Hole name) = do
ty <- freshType
ctx <- getLocalContext
env <- getEnv
tell . errorMessage $ HoleInferredType name ty ctx (TSBefore env)
tell . errorMessage $ HoleInferredType name ty ctx . Just $ TSBefore env
return $ TypedValue True (Hole name) ty
infer' (PositionedValue pos c val) = warnAndRethrowWithPositionTC pos $ do
TypedValue t v ty <- infer' val
Expand Down
5 changes: 3 additions & 2 deletions src/Language/PureScript/TypeChecker/Unify.hs
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,11 @@ replaceVarWithUnknown ident ty = do
replaceTypeWildcards :: (MonadWriter MultipleErrors m, MonadState CheckState m) => SourceType -> m SourceType
replaceTypeWildcards = everywhereOnTypesM replace
where
replace (TypeWildcard ann) = do
replace (TypeWildcard ann name) = do
t <- freshType
ctx <- getLocalContext
warnWithPosition (fst ann) $ tell . errorMessage $ WildcardInferredType t ctx
let err = maybe (WildcardInferredType t ctx) (\n -> HoleInferredType n t ctx Nothing) name
warnWithPosition (fst ann) $ tell $ errorMessage err
return t
replace other = return other

Expand Down
23 changes: 12 additions & 11 deletions src/Language/PureScript/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ data Type a
-- | A type-level string
| TypeLevelString a PSString
-- | A type wildcard, as would appear in a partial type synonym
| TypeWildcard a
| TypeWildcard a (Maybe Text)
-- | A type constructor
| TypeConstructor a (Qualified (ProperName 'TypeName))
-- | A type operator. This will be desugared into a type constructor during the
Expand Down Expand Up @@ -101,7 +101,7 @@ srcTypeLevelString :: PSString -> SourceType
srcTypeLevelString = TypeLevelString NullSourceAnn

srcTypeWildcard :: SourceType
srcTypeWildcard = TypeWildcard NullSourceAnn
srcTypeWildcard = TypeWildcard NullSourceAnn Nothing

srcTypeConstructor :: Qualified (ProperName 'TypeName) -> SourceType
srcTypeConstructor = TypeConstructor NullSourceAnn
Expand Down Expand Up @@ -195,8 +195,8 @@ typeToJSON annToJSON ty =
variant "TypeVar" a b
TypeLevelString a b ->
variant "TypeLevelString" a b
TypeWildcard a ->
nullary "TypeWildcard" a
TypeWildcard a b ->
variant "TypeWildcard" a b
TypeConstructor a b ->
variant "TypeConstructor" a b
TypeOp a b ->
Expand Down Expand Up @@ -274,8 +274,9 @@ typeFromJSON defaultAnn annFromJSON = A.withObject "Type" $ \o -> do
TypeVar a <$> contents
"TypeLevelString" ->
TypeLevelString a <$> contents
"TypeWildcard" ->
pure $ TypeWildcard a
"TypeWildcard" -> do
b <- contents <|> pure Nothing
pure $ TypeWildcard a b
"TypeConstructor" ->
TypeConstructor a <$> contents
"TypeOp" ->
Expand Down Expand Up @@ -518,7 +519,7 @@ annForType :: Lens' (Type a) a
annForType k (TUnknown a b) = (\z -> TUnknown z b) <$> k a
annForType k (TypeVar a b) = (\z -> TypeVar z b) <$> k a
annForType k (TypeLevelString a b) = (\z -> TypeLevelString z b) <$> k a
annForType k (TypeWildcard a) = TypeWildcard <$> k a
annForType k (TypeWildcard a b) = (\z -> TypeWildcard z b) <$> k a
annForType k (TypeConstructor a b) = (\z -> TypeConstructor z b) <$> k a
annForType k (TypeOp a b) = (\z -> TypeOp z b) <$> k a
annForType k (TypeApp a b c) = (\z -> TypeApp z b c) <$> k a
Expand Down Expand Up @@ -547,7 +548,7 @@ eqType :: Type a -> Type b -> Bool
eqType (TUnknown _ a) (TUnknown _ a') = a == a'
eqType (TypeVar _ a) (TypeVar _ a') = a == a'
eqType (TypeLevelString _ a) (TypeLevelString _ a') = a == a'
eqType (TypeWildcard _) (TypeWildcard _) = True
eqType (TypeWildcard _ a) (TypeWildcard _ a') = a == a'
eqType (TypeConstructor _ a) (TypeConstructor _ a') = a == a'
eqType (TypeOp _ a) (TypeOp _ a') = a == a'
eqType (TypeApp _ a b) (TypeApp _ a' b') = eqType a a' && eqType b b'
Expand All @@ -573,9 +574,9 @@ compareType (TypeLevelString _ a) (TypeLevelString _ a') = compare a a'
compareType (TypeLevelString {}) _ = LT
compareType _ (TypeLevelString {}) = GT

compareType (TypeWildcard _) (TypeWildcard _) = EQ
compareType (TypeWildcard _) _ = LT
compareType _ (TypeWildcard _) = GT
compareType (TypeWildcard _ a) (TypeWildcard _ a') = compare a a'
compareType (TypeWildcard {}) _ = LT
compareType _ (TypeWildcard {}) = GT

compareType (TypeConstructor _ a) (TypeConstructor _ a') = compare a a'
compareType (TypeConstructor {}) _ = LT
Expand Down
8 changes: 8 additions & 0 deletions tests/purs/failing/TypedHole2.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-- @shouldFailWith HoleInferredType
module Main where

import Prelude
import Effect (Effect)

main :: Effect ?ummm
main = pure unit
9 changes: 0 additions & 9 deletions tests/purs/warning/WildcardInferredType.purs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
-- @shouldWarnWith WildcardInferredType
-- @shouldWarnWith WildcardInferredType
-- @shouldWarnWith WildcardInferredType
-- @shouldWarnWith WildcardInferredType
module Main where

x :: Int
x = 0 :: _

y :: _
Expand All @@ -15,9 +12,3 @@ z =
let n :: _
n = 0
in n

w :: Int
w = n
where
n :: _
n = 0
14 changes: 14 additions & 0 deletions tests/purs/warning/WildcardInferredType2.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- @shouldWarnWith WildcardInferredType
module Main where

x :: _
x = 42

y :: Int
y = 42 :: _

z :: Int
z = n
where
n :: _
n = 42